From 432ecc845aa73c710f0ea5aebc657d6709b4a11a Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 17 Jan 2023 19:59:48 +0000 Subject: [PATCH 001/213] files added --- run-with-freesurfer.sh | 0 run.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 run-with-freesurfer.sh create mode 100755 run.py diff --git a/run-with-freesurfer.sh b/run-with-freesurfer.sh new file mode 100755 index 0000000000..e69de29bb2 diff --git a/run.py b/run.py new file mode 100755 index 0000000000..e69de29bb2 From 9e9503d269043b09c28b9c45f7f0a49f8dd4e8c6 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 17 Jan 2023 20:01:36 +0000 Subject: [PATCH 002/213] modified surf_preproc.py --- CPAC/seg_preproc/seg_preproc.py | 0 CPAC/surface/surf_preproc.py | 185 +++++++++++++++++++++++++++++++- 2 files changed, 181 insertions(+), 4 deletions(-) mode change 100644 => 100755 CPAC/seg_preproc/seg_preproc.py mode change 100644 => 100755 CPAC/surface/surf_preproc.py diff --git a/CPAC/seg_preproc/seg_preproc.py b/CPAC/seg_preproc/seg_preproc.py old mode 100644 new mode 100755 diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py old mode 100644 new mode 100755 index bbee1fe6e6..3a9fc0067d --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -5,6 +5,7 @@ from CPAC.pipeline import nipype_pipeline_engine as pe + def run_surface(post_freesurfer_folder, freesurfer_folder, subject, @@ -84,7 +85,7 @@ def run_surface(post_freesurfer_folder, def surface_connector(wf, cfg, strat_pool, pipe_num, opt): - + surf = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'freesurfer_folder', 'subject', @@ -107,7 +108,8 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): 'desikan_killiany_164', 'destrieux_164', 'desikan_killiany_32', - 'destrieux_32'], + 'destrieux_32', + ], function=run_surface), name=f'post_freesurfer_{pipe_num}') @@ -159,6 +161,25 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data(scout_bold) wf.connect(node, out, surf, 'scout_bold') + + falff = pe.Node(util.Function(input_names=['dtseries'], + output_names=['falff'], + function=run_surf_falff), + name=f'surf_falff_{pipe_num}') + #falff.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + + wf.connect(surf, 'dtseries', falff, 'dtseries') + + alff = pe.Node(util.Function(input_names=['dtseries'], + output_names=['alff'], + function=run_surf_alff), + name=f'surf_alff_{pipe_num}') + + + wf.connect(surf, 'dtseries', alff, 'dtseries') + outputs = { 'atlas-DesikanKilliany_space-fsLR_den-32k_dlabel': (surf, @@ -169,9 +190,102 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): 'desikan_' 'killiany_164'), 'atlas-Destrieux_space-fsLR_den-164k_dlabel': (surf, 'destrieux_164'), - 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries') + 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries'), + 'falff-surf_dscalar': (falff, 'falff'), + 'alff-surf_dscalar': (alff, 'alff') + + } + + + + # L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], + # output_names=['L_cortex_file'], + # function=run_get_cortex), + # name=f'L_surf_cortex_{pipe_num}') + + # L_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # L_cortex_file.inputs.structure = "LEFT" + # L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" + # wf.connect(surf, 'dtseries', L_cortex_file, 'dtseries') + + # R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], + # output_names=['R_cortex_file'], + # function=run_get_cortex), + # name=f'R_surf_cortex_{pipe_num}') + + # R_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # R_cortex_file.inputs.structure = "RIGHT" + # R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" + # wf.connect(surf, 'dtseries', R_cortex_file, 'dtseries') + + + # mean_timeseries = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'dtseries'], + # output_names=['mean_timeseries'], + # function=run_mean_timeseries), + # name=f'mean_timeseries_{pipe_num}') + + # mean_timeseries.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # wf.connect(surf, 'dtseries', mean_timeseries, 'dtseries') + + + # L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', + # 'post_freesurfer_folder', 'reho_filename'], + # output_names=['L_reho'], + # function=run_surf_reho), + # name=f'surf_reho{pipe_num}') + + # wf.connect(get_L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') + # wf.connect(surf, 'L_surface_file', L_reho, 'surface_file') + # wf.connect(surf, 'L_mask', L_reho, 'mask') + # wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') + # L_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # L_reho.inputs.reho_filename = L_surf_reho.dscalar.nii + + # R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', + # 'post_freesurfer_folder', 'reho_filename'], + # output_names=['R_reho'], + # function=run_surf_reho), + # name=f'surf_reho{pipe_num}') + + # wf.connect(get_R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') + # wf.connect(surf, 'R_surface_file', R_reho, 'surface_file') + # wf.connect(surf, 'R_mask', R_reho, 'mask') + # wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') + # R_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # R_reho.inputs.reho_filename = R_surf_reho.dscalar.nii + + + + # connectivity_parcellation = pe.Node(util.Function(input_names=['dtseries', 'surf_atlaslabel', + # 'post_freesurfer_folder'], + # output_names=['parcellation_file'], + # function=run_ciftiparcellate), + # name=f'connectivity_parcellation{pipe_num}') + + + # wf.connect(surf, 'dtseries', connectivity, 'dtseries') + # connectivity_parcellation.inputs.surf_atlaslabel = ## path to the label file + + # correlation_matrix = pe.Node(util.Function(input_names=['ptseries','post_freesurfer_folder'], + # output_names=['correlation_matrix'], + # function=run_cifticorrelation), + # name=f'correlation_matrix{pipe_num}') + + + # wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix 'ptseries') + return wf, outputs def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): @@ -194,8 +308,71 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): "atlas-Destrieux_space-fsLR_den-32k_dlabel", "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", "atlas-Destrieux_space-fsLR_den-164k_dlabel", - "space-fsLR_den-32k_bold-dtseries"]} + "space-fsLR_den-32k_bold-dtseries", + "falff-surf_dscalar", + "alff-surf_dscalar"]} ''' wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) return (wf, outputs) + + +def run_surf_falff(dtseries): + import os + import subprocess + falff = os.path.join(os.getcwd(), 'falff_surf.dscalar.nii.gz') + cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] + subprocess.check_output(cmd) + return falff + + +def run_surf_alff(dtseries): + import os + import subprocess + alff = os.path.join(os.getcwd(), 'alff_surf.dscalar.nii.gz') + cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] + subprocess.check_output(cmd) + return alff + +#cmd = ['ciftify_falff', dtseries , 'alff_surf.dscalar.nii', '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] +# def run_get_cortex(dtseries, structure, post_freesurfer_folder, cortex_filename): +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_filename] +# subprocess.check_output(cmd) +# cortex_file = os.path.join(post_freesurfer_folder, cortex_filename) +# return cortex_file + +# def run_mean_timeseries(dtseries,post_freesurfer_folder): + +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', 'mean.dscalar.nii'] +# subprocess.check_output(cmd) +# mean_timeseries = os.path.join(post_freesurfer_folder, mean.dscalar.nii) +# return mean_timeseries + +# def run_surf_reho(dtseries, mask, cortex_file, surface_file,mean_timeseries,post_freesurfer_folder, reho_filename): + +# import os +# import subprocess +# cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, reho_filename] +# subprocess.check_output(cmd) +# surf_reho = os.path.join(post_freesurfer_folder, reho_filename) +# return surf_reho + +# def run_ciftiparcellate(dtseries, surf_atlaslabel): +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', 'parcellation.ptseries.nii'] +# subprocess.check_output(cmd) +# parcellation_file = os.path.join(post_freesurfer_folder, 'parcellation.ptseries.nii') +# return parcellation_file + +# def run_cifticorrelation(ptseries): +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-correlation ', ptseries , 'cifti_corr.pconn.nii'] +# subprocess.check_output(cmd) +# correlation_matrix = os.path.join(post_freesurfer_folder, 'cifti_corr.pconn.nii') +# return correlation_matrix From 21911eacf9c6c3f7554a10e97446d0cd92222d05 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 1 Feb 2023 21:50:16 +0000 Subject: [PATCH 003/213] modified files outputs.tsv, cpac_pipeline.py and surf_preproc.py --- CPAC/pipeline/cpac_pipeline.py | 11 + CPAC/resources/cpac_outputs.tsv | 2 + CPAC/surface/surf_preproc.py | 1022 ++++++++++++++++++++++++++----- 3 files changed, 874 insertions(+), 161 deletions(-) mode change 100644 => 100755 CPAC/pipeline/cpac_pipeline.py mode change 100644 => 100755 CPAC/resources/cpac_outputs.tsv diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py old mode 100644 new mode 100755 index fc720966a3..f905b557b3 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -170,6 +170,10 @@ ) from CPAC.surface.surf_preproc import surface_postproc +from CPAC.surface.surf_preproc import cal_falff +from CPAC.surface.surf_preproc import cal_alff +#from CPAC.surface.surf_preproc import cal_reho +#from CPAC.surface.surf_preproc import cal_connectivity_matrix from CPAC.timeseries.timeseries_analysis import ( timeseries_extraction_AVG, @@ -1314,6 +1318,13 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if not rpool.check_rpool('space-fsLR_den-32k_bold.dtseries'): pipeline_blocks += [surface_postproc] + if not rpool.check_rpool('surf-falff'): + pipeline_blocks += [cal_falff] + + if not rpool.check_rpool('surf-alff'): + pipeline_blocks += [cal_alff] + + # Extractions and Derivatives tse_atlases, sca_atlases = gather_extraction_maps(cfg) cfg.timeseries_extraction['tse_atlases'] = tse_atlases diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv old mode 100644 new mode 100755 index ac6c1e6cb5..e717dcace8 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -218,3 +218,5 @@ space-template_label-GM_mask mask template anat NIfTI space-EPItemplate_label-CSF_mask mask template func NIfTI space-EPItemplate_label-WM_mask mask template func NIfTI space-EPItemplate_label-GM_mask mask template func NIfTI +falff surface_derived func +alff surface_derived func diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 3a9fc0067d..7d955063b4 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -5,7 +5,6 @@ from CPAC.pipeline import nipype_pipeline_engine as pe - def run_surface(post_freesurfer_folder, freesurfer_folder, subject, @@ -29,10 +28,8 @@ def run_surface(post_freesurfer_folder, ------- dtseries : str Path to the dtseries file. - desikan_killiany : str Path to the Desikan-Killiany parcellation file. - destrieux : str Path to the Destrieux parcellation file. """ @@ -42,18 +39,101 @@ def run_surface(post_freesurfer_folder, freesurfer_folder = os.path.join(freesurfer_folder, 'recon_all') - # DCAN-HCP PostFreeSurfer - # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh - cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/run.sh', '--post_freesurfer_folder', post_freesurfer_folder, \ - '--freesurfer_folder', freesurfer_folder, '--subject', subject, \ - '--t1w_restore', t1w_restore_image, '--atlas_t1w', atlas_space_t1w_image, \ - '--atlas_transform', atlas_transform, '--inverse_atlas_transform', inverse_atlas_transform, \ - '--surfatlasdir', surf_atlas_dir, '--grayordinatesdir', gray_ordinates_dir, '--grayordinatesres', gray_ordinates_res, \ - '--hiresmesh', high_res_mesh, '--lowresmesh', low_res_mesh, \ - '--subcortgraylabels', subcortical_gray_labels, '--freesurferlabels', freesurfer_labels] + # # DCAN-HCP PostFreeSurfer + # # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh + # cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/run.sh', '--post_freesurfer_folder', post_freesurfer_folder, \ + # '--freesurfer_folder', freesurfer_folder, '--subject', subject, \ + # '--t1w_restore', t1w_restore_image, '--atlas_t1w', atlas_space_t1w_image, \ + # '--atlas_transform', atlas_transform, '--inverse_atlas_transform', inverse_atlas_transform, \ + # '--surfatlasdir', surf_atlas_dir, '--grayordinatesdir', gray_ordinates_dir, '--grayordinatesres', gray_ordinates_res, \ + # '--hiresmesh', high_res_mesh, '--lowresmesh', low_res_mesh, \ + # '--subcortgraylabels', subcortical_gray_labels, '--freesurferlabels', freesurfer_labels] + + # subprocess.check_output(cmd) + + # DCAN-HCP PostFreeSurfer Block1 + + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block1.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + subprocess.check_output(cmd) + # DCAN-HCP PostFreeSurfer Block2 + + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block2.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + + subprocess.check_output(cmd) + + # DCAN-HCP PostFreeSurfer Block3 + + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block3.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + + subprocess.check_output(cmd) + + #DCAN-HCP PostFreeSurfer Block3.5 + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block3-5.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + + subprocess.check_output(cmd) + + # DCAN-HCP PostFreeSurfer Block4 + + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block4.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + + subprocess.check_output(cmd) + + # DCAN-HCP PostFreeSurfer Block5 + + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block5.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + + subprocess.check_output(cmd) + + # DCAN-HCP PostFreeSurfer Block6 + + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block6.sh', post_freesurfer_folder, \ + freesurfer_folder, subject, \ + t1w_restore_image, atlas_space_t1w_image, \ + atlas_transform, inverse_atlas_transform, \ + surf_atlas_dir, gray_ordinates_dir, gray_ordinates_res, \ + high_res_mesh, low_res_mesh, \ + subcortical_gray_labels, freesurfer_labels] + + subprocess.check_output(cmd) # DCAN-HCP fMRISurface # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRISurface/GenericfMRISurfaceProcessingPipeline.sh cmd = ['bash', '/code/CPAC/surface/fMRISurface/run.sh', @@ -62,6 +142,7 @@ def run_surface(post_freesurfer_folder, scout_bold, '--lowresmesh', low_res_mesh, '--grayordinatesres', gray_ordinates_res, '--fmrires', fmri_res, '--smoothingFWHM', smooth_fwhm] + subprocess.check_output(cmd) dtseries = os.path.join(post_freesurfer_folder, @@ -79,13 +160,302 @@ def run_surface(post_freesurfer_folder, 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', 'fsaverage_LR32k', f'{subject}.aparc.a2009s.32k_fs_LR.dlabel.nii')}} + + subcortical_atlas = os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/' + 'task-rest01_AtlasSubcortical_s2.nii.gz') - return (dtseries, aparc['desikan_killiany'][164], aparc['destrieux'][164], - aparc['desikan_killiany'][32], aparc['destrieux'][32]) + good_voxels = os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/RibbonVolumeToSurfaceMapping/' + 'goodvoxels.nii.gz') + ribbon_only = os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/RibbonVolumeToSurfaceMapping/' + 'ribbon_only.nii.gz') -def surface_connector(wf, cfg, strat_pool, pipe_num, opt): + atlas_roi = { + 'func': { + 'L': os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/', + 'task-rest01.L.atlasroi.32k_fs_LR.func.gii'), + + 'R': os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/', + 'task-rest01.R.atlasroi.32k_fs_LR.func.gii')}, + 'shape': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.atlasroi.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.atlasroi.32k_fs_LR.shape.gii')}} + task_rest = { + 'L': os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/', + 'task-rest01.L.native.func.gii'), + 'R': os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/', + 'task-rest01.R.native.func.gii')} + spec = { + 'LR_32k': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.32k_fs_LR.wb.spec'), + 'native': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.native.wb.spec')} + areal_distortion = { + 'FS': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.ArealDistortion_FS.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.ArealDistortion_FS.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.ArealDistortion_FS.32k_fs_LR.dscalar.nii')}, + + 'MSMSulc': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.ArealDistortion_MSMSulc.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.ArealDistortion_MSMSulc.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.ArealDistortion_MSMSulc.32k_fs_LR.dscalar.nii')}} + edge_distortion = { + 'FS': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.EdgeDistortion_FS.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.EdgeDistortion_FS.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.EdgeDistortion_FS.32k_fs_LR.dscalar.nii')}, + + 'MSMSulc': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.EdgeDistortion_MSMSulc.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.EdgeDistortion_MSMSulc.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.EdgeDistortion_MSMSulc.32k_fs_LR.dscalar.nii')}} + curvature = { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.curvature.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.curvature.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.curvature.32k_fs_LR.dscalar.nii')} + + flat = { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.flat.32k_fs_LR.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.flat.32k_fs_LR.surf.gii')} + + inflate_32k = { + 'inflated': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.inflated.32k_fs_LR.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.inflated.32k_fs_LR.surf.gii')}, + 'very_inflated': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.very_inflated.32k_fs_LR.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.very_inflated.32k_fs_LR.surf.gii')}} + inflate = { + 'inflated': { + 'L': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.L.inflated.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.R.inflated.native.surf.gii')}, + 'very_inflated': { + 'L': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.L.very_inflated.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.R.very_inflated.native.surf.gii')}} + midthickness = { + 'L': { + 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', + f'{subject}.L.midthickness.164k_fs_LR.surf.gii'), + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.midthickness.32k_fs_LR.surf.gii'), + 'native': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.L.midthickness.native.surf.gii')}, + 'R': { + 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', + f'{subject}.R.midthickness.164k_fs_LR.surf.gii'), + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.midthickness.32k_fs_LR.surf.gii'), + 'native': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.R.midthickness.native.surf.gii')}} + pial = { + 'L': { + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.pial.32k_fs_LR.surf.gii'), + 'native': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.L.pial.native.surf.gii')}, + 'R': { + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.pial.32k_fs_LR.surf.gii'), + 'native': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.R.pial.native.surf.gii')}} + sphere = { + '32k_fs_LR': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.sphere.32k_fs_LR.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.sphere.32k_fs_LR.surf.gii')}, + 'MSMSulc': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.L.sphere.MSMSulc.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.R.sphere.MSMSulc.native.surf.gii')}, + 'native': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.L.sphere.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.R.sphere.native.surf.gii')}, + 'reg': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.L.sphere.reg.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.R.sphere.reg.native.surf.gii')}, + 'reg_reg_LR': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.L.sphere.reg.reg_LR.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.R.sphere.reg.reg_LR.native.surf.gii')}, + 'rot': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.L.sphere.rot.native.surf.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear/Native/', + f'{subject}.R.sphere.rot.native.surf.gii')}} + StrainJ = { + 'FS': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.StrainJ_FS.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.StrainJ_FS.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.StrainJ_FS.32k_fs_LR.dscalar.nii')}, + 'MSMSulc': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.StrainJ_MSMSulc.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.StrainJ_MSMSulc.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.StrainJ_MSMSulc.32k_fs_LR.dscalar.nii')}} + StrainR = { + 'FS': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.StrainR_FS.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.StrainR_FS.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.StrainR_FS.32k_fs_LR.dscalar.nii')}, + 'MSMSulc': { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.StrainR_MSMSulc.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.StrainR_MSMSulc.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.StrainR_MSMSulc.32k_fs_LR.dscalar.nii')}} + + sulc = { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.sulc.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.sulc.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.sulc.32k_fs_LR.dscalar.nii')} + thickness = { + 'L': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.thickness.32k_fs_LR.shape.gii'), + 'R': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.thickness.32k_fs_LR.shape.gii'), + 'dscalar': os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.thickness.32k_fs_LR.dscalar.nii')} + white = { + 'L': { + 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', + f'{subject}.L.white.164k_fs_LR.surf.gii'), + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.L.white.32k_fs_LR.surf.gii'), + 'native': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.L.white.native.surf.gii')}, + 'R': { + 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', + f'{subject}.R.white.164k_fs_LR.surf.gii'), + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.R.white.32k_fs_LR.surf.gii'), + 'native': os.path.join(post_freesurfer_folder, 'T1w/Native/', + f'{subject}.R.white.native.surf.gii')}} + + return (dtseries, aparc['desikan_killiany'][164], aparc['destrieux'][164], aparc['desikan_killiany'][32], + aparc['destrieux'][32], subcortical_atlas, good_voxels, ribbon_only, atlas_roi['func']['L'], atlas_roi['func']['R'], + atlas_roi['shape']['L'], atlas_roi['shape']['R'], task_rest['L'], task_rest['R'], spec['LR_32k'], spec['native'], + areal_distortion['FS']['L'], areal_distortion['FS']['R'], areal_distortion['FS']['dscalar'], areal_distortion['MSMSulc']['L'], + areal_distortion['MSMSulc']['R'], areal_distortion['MSMSulc']['dscalar'], edge_distortion['FS']['L'], + edge_distortion['FS']['R'], edge_distortion['FS']['dscalar'], edge_distortion['MSMSulc']['L'], edge_distortion['MSMSulc']['R'], + edge_distortion['MSMSulc']['dscalar'], curvature['L'], curvature['R'], curvature['dscalar'], flat['L'], flat['R'], + inflate_32k['inflated']['L'], inflate_32k['inflated']['R'], inflate_32k['very_inflated']['L'], inflate_32k['very_inflated']['R'], + inflate['inflated']['L'], inflate['inflated']['R'], inflate['very_inflated']['L'], inflate['very_inflated']['R'], + midthickness['L'][164], midthickness['L'][32], midthickness['L']['native'], midthickness['R'][164], midthickness['R'][32], + midthickness['R']['native'], pial['L'][32], pial['L']['native'], pial['R'][32], pial['R']['native'], sphere['32k_fs_LR']['L'], + sphere['32k_fs_LR']['R'], sphere['MSMSulc']['L'], sphere['MSMSulc']['R'], sphere['native']['L'], sphere['native']['R'], + sphere['reg']['L'], sphere['reg']['R'], sphere['reg_reg_LR']['L'], sphere['reg_reg_LR']['R'], sphere['rot']['L'], sphere['rot']['R'], + StrainJ['FS']['L'], StrainJ['FS']['R'], StrainJ['FS']['dscalar'], StrainJ['MSMSulc']['L'], StrainJ['MSMSulc']['R'], + StrainJ['MSMSulc']['dscalar'], StrainR['FS']['L'], StrainR['FS']['R'], StrainR['FS']['dscalar'], StrainR['MSMSulc']['L'], + StrainR['MSMSulc']['R'], StrainR['MSMSulc']['dscalar'], sulc['L'], sulc['R'], sulc['dscalar'], thickness['L'], thickness['R'], + thickness['dscalar'], white['L'][164], white['L'][32], white['L']['native'], white['R'][164], white['R'][32], white['R']['native']) + +def surface_connector(wf, cfg, strat_pool, pipe_num, opt): + surf = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'freesurfer_folder', 'subject', @@ -109,7 +479,89 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): 'destrieux_164', 'desikan_killiany_32', 'destrieux_32', - ], + 'subcortical_atlas', + 'good_voxels', + 'ribbon_only', + 'atlas_roi_func_L', + 'atlas_roi_func_R', + 'atlas_roi_shape_L', + 'atlas_roi_shape_R', + 'native_L', + 'native_R', + 'spec_LR_32k', + 'spec_native', + 'areal_distortion_FS_L', + 'areal_distortion_FS_R', + 'areal_distortion_FS_dscalar', + 'areal_distortion_MSMSulc_L', + 'areal_distortion_MSMSulc_R', + 'areal_distortion_MSMSulc_dscalar', + 'edge_distortion_FS_L', + 'edge_distortion_FS_R', + 'edge_distortion_FS_dscalar', + 'edge_distortion_MSMSulc_L', + 'edge_distortion_MSMSulc_R', + 'edge_distortion_MSMSulc_dscalar', + 'curvature_L', + 'curvature_R', + 'curvature_dscalar', + 'flat_L', + 'flat_R', + '32k_inflated_L', + '32k_inflated_R', + '32k_very_inflated_L', + '32k_very_inflated_R', + 'inflated_L', + 'inflated_R', + 'very_inflated_L', + 'very_inflated_R', + 'midthickness_L_164', + 'midthickness_L_32', + 'midthickness_L_native', + 'midthickness_R_164', + 'midthickness_R_32', + 'midthickness_R_native', + 'pial_L_32', + 'pial_L_native', + 'pial_R_32', + 'pial_R_native', + 'sphere_32k_fs_LR_L', + 'sphere_32k_fs_LR_R', + 'sphere_MSMSulc_L', + 'sphere_MSMSulc_R', + 'sphere_native_L', + 'sphere_native_R', + 'sphere_reg_L', + 'sphere_reg_R', + 'sphere_reg_reg_LR_L', + 'sphere_reg_reg_LR_R', + 'sphere_rot_L', + 'sphere_rot_R', + 'StrainJ_FS_L', + 'StrainJ_FS_R', + 'StrainJ_FS_dscalar', + 'StrainJ_MSMSulc_L', + 'StrainJ_MSMSulc_R', + 'StrainJ_MSMSulc_dscalar', + 'StrainR_FS_L', + 'StrainR_FS_R', + 'StrainR_FS_dscalar', + 'StrainR_MSMSulc_L', + 'StrainR_MSMSulc_R', + 'StrainR_MSMSulc_dscalar', + 'sulc_L', + 'sulc_R', + 'sulc_dscalar', + 'thickness_L', + 'thickness_R', + 'thickness_dscalar', + 'white_L_164', + 'white_L_32', + 'white_L_native', + 'white_R_164', + 'white_R_32', + 'white_R_native' + ], function=run_surface), name=f'post_freesurfer_{pipe_num}') @@ -131,14 +583,14 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): surf.inputs.fmri_res = str(cfg.surface_analysis['post_freesurfer']['fmri_res']) surf.inputs.smooth_fwhm = str(cfg.surface_analysis['post_freesurfer']['smooth_fwhm']) - restore = ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"] - space_temp = ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask",] - atlas_xfm = ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"] - atlas_xfm_inv = ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"] - atlas_space_bold = ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"] - scout_bold = ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"] + restore = ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", + "space-longitudinal_desc-reorient_T1w"] + space_temp = ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask",] + atlas_xfm = ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"] + atlas_xfm_inv = ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"] + atlas_space_bold = ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"] + scout_bold = ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", + "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"] node, out = strat_pool.get_data('freesurfer-subject-dir') @@ -161,27 +613,9 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data(scout_bold) wf.connect(node, out, surf, 'scout_bold') - - falff = pe.Node(util.Function(input_names=['dtseries'], - output_names=['falff'], - function=run_surf_falff), - name=f'surf_falff_{pipe_num}') - #falff.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - - wf.connect(surf, 'dtseries', falff, 'dtseries') - - alff = pe.Node(util.Function(input_names=['dtseries'], - output_names=['alff'], - function=run_surf_alff), - name=f'surf_alff_{pipe_num}') - - - wf.connect(surf, 'dtseries', alff, 'dtseries') - outputs = { + 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries'), 'atlas-DesikanKilliany_space-fsLR_den-32k_dlabel': (surf, 'desikan_' 'killiany_32'), @@ -190,102 +624,122 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): 'desikan_' 'killiany_164'), 'atlas-Destrieux_space-fsLR_den-164k_dlabel': (surf, 'destrieux_164'), - 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries'), - 'falff-surf_dscalar': (falff, 'falff'), - 'alff-surf_dscalar': (alff, 'alff') - - + 'AtlasSubcortical_s2': (surf, 'subcortical_atlas'), + 'goodvoxels': (surf, 'good_voxels'), + 'ribbon_only': (surf, 'ribbon_only'), + 'atlasroi_hemi-L_space-fsLR_den-32k_func': (surf, + 'atlas_roi_func_' + 'L'), + 'atlasroi_hemi-R_space-fsLR_den-32k_func': (surf, + 'atlas_roi_func_' + 'R'), + 'atlasroi_hemi-L_space-fsLR_den-32k_shape': (surf, + 'atlas_roi_shape_' + 'L'), + 'atlasroi_hemi-R_space-fsLR_den-32k_shape': (surf, + 'atlas_roi_shape_' + 'R'), + 'space-native_hemi-L_func': (surf, 'native_' 'L'), + 'space-native_hemi-R_func': (surf, 'native_' 'R'), + 'space-fsLR_den-32k_wb-spec': (surf, 'spec_' 'LR_32k'), + 'space-native_wb-spec': (surf, 'spec_' 'native'), + 'arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'FS_' + 'L'), + 'arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'FS_' + 'R'), + 'arealdistortion-FS_space-fsLR_den-32k_dscalar': (surf, 'areal_distortion_' + 'FS_' + 'dscalar'), + 'arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'MSMSulc_' + 'L'), + 'arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'MSMSulc_' + 'R'), + 'arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'areal_distortion_' + 'MSMSulc_' + 'dscalar'), + 'edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'FS_' + 'L'), + 'edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'FS_' + 'R'), + 'edgedistortion-FS_space-fsLR_den-32k_dscalar': (surf, 'edge_distortion_' + 'FS_' + 'dscalar'), + 'edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'MSMSulc_' + 'L'), + 'edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'MSMSulc_' + 'R'), + 'edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'edge_distortion_' + 'MSMSulc_' + 'dscalar'), + 'hemi-L_space-fsLR_den-32k_curv_shape': (surf, 'curvature_' 'L'), + 'hemi-R_space-fsLR_den-32k_curv_shape': (surf, 'curvature_' 'R'), + 'space-fsLR_den-32k_curv_dscalar': (surf, 'curvature_' 'dscalar'), + 'hemi-L_space-fsLR_den-32k_flat_surf': (surf, 'flat_L'), + 'hemi-R_space-fsLR_den-32k_flat_surf': (surf, 'flat_R'), + 'hemi-L_space-fsLR_den-32k_inflated_surf': (surf, '32k_inflated_L'), + 'hemi-R_space-fsLR_den-32k_inflated_surf': (surf, '32k_inflated_R'), + 'hemi-L_space-fsLR_den-32k_very-inflated_surf': (surf, '32k_very_inflated_L'), + 'hemi-R_space-fsLR_den-32k_very-inflated_surf': (surf, '32k_very_inflated_R'), + 'hemi-L_space-native_inflated_surf': (surf, 'inflated_L'), + 'hemi-R_space-native_inflated_surf': (surf, 'inflated_R'), + 'hemi-L_space-native_very-inflated_surf': (surf, 'very_inflated_L'), + 'hemi-R_space-native_very-inflated_surf': (surf, 'very_inflated_R'), + 'hemi-L_space-fsLR_den-164k_midthickness_surf': (surf, 'midthickness_L_164'), + 'hemi-L_space-fsLR_den-32k_midthickness_surf': (surf, 'midthickness_L_32'), + 'hemi-L_space-native_midthickness_surf': (surf, 'midthickness_L_native'), + 'hemi-R_space-fsLR_den-164k_midthickness_surf': (surf, 'midthickness_R_164'), + 'hemi-R_space-fsLR_den-32k_midthickness_surf': (surf, 'midthickness_R_32'), + 'hemi-R_space-native_midthickness_surf': (surf, 'midthickness_R_native'), + 'hemi-L_space-fsLR_den-32k_pial_surf': (surf, 'pial_L_32'), + 'hemi-L_space-native_den-32k_pial_surf': (surf, 'pial_L_native'), + 'hemi-R_space-fsLR_den-32k_pial_surf': (surf, 'pial_R_32'), + 'hemi-R_space-native_den-32k_pial_surf': (surf, 'pial_R_native'), + 'hemi-L_space-fsLR_den-32k_sphere_surf': (surf, 'sphere_32k_fs_LR_L'), + 'hemi-R_space-fsLR_den-32k_sphere_surf': (surf, 'sphere_32k_fs_LR_R'), + 'hemi-L_MSMSulc_space-native_sphere_surf': (surf, 'sphere_MSMSulc_L'), + 'hemi-R_MSMSulc_space-native_sphere_surf': (surf, 'sphere_MSMSulc_R'), + 'hemi-L_space-native_sphere_surf': (surf, 'sphere_native_L'), + 'hemi-R_space-native_sphere_surf': (surf, 'sphere_native_R'), + 'hemi-L_space-native_sphere-reg_surf': (surf, 'sphere_reg_L'), + 'hemi-R_space-native_sphere-reg_surf': (surf, 'sphere_reg_R'), + 'hemi-L_space-native_sphere-reg-reg_surf': (surf, 'sphere_reg_reg_LR_L'), + 'hemi-R_space-native_sphere-reg-reg_surf': (surf, 'sphere_reg_reg_LR_R'), + 'hemi-L_space-native_sphere-rot_surf': (surf, 'sphere_rot_L'), + 'hemi-R_space-native_sphere-rot_surf': (surf, 'sphere_rot_R'), + 'hemi-L_strainJ-FS_space-fsLR_den-32k_shape': (surf, 'StrainJ_FS_L'), + 'hemi-R_strainJ-FS_space-fsLR_den-32k_shape': (surf, 'StrainJ_FS_R'), + 'strainJ-FS_space-fsLR_den-32k_dscalar': (surf, 'StrainJ_FS_dscalar'), + 'hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainJ_MSMSulc_L'), + 'hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainJ_MSMSulc_R'), + 'strainJ-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'StrainJ_MSMSulc_dscalar'), + 'hemi-L_strainR-FS_space-fsLR_den-32k_shape': (surf, 'StrainR_FS_L'), + 'hemi-R_strainR-FS_space-fsLR_den-32k_shape': (surf, 'StrainR_FS_R'), + 'strainR-FS_space-fsLR_den-32k_dscalar': (surf, 'StrainR_FS_dscalar'), + 'hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainR_MSMSulc_L'), + 'hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainR_MSMSulc_R'), + 'strainR-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'StrainR_MSMSulc_dscalar'), + 'hemi-L_space-fsLR_den-32k_sulc_shape': (surf, 'sulc_L'), + 'hemi-R_space-fsLR_den-32k_sulc_shape': (surf, 'sulc_R'), + 'space-fsLR_den-32k_sulc_dscalar': (surf, 'sulc_dscalar'), + 'hemi-L_space-fsLR_den-32k_thickness_shape': (surf, 'thickness_L'), + 'hemi-R_space-fsLR_den-32k_thickness_shape': (surf, 'thickness_R'), + 'space-fsLR_den-32k_thickness_dscalar': (surf, 'thickness_dscalar'), + 'hemi-L_space-fsLR_den-164k_white_surf': (surf, 'white_L_164'), + 'hemi-L_space-fsLR_den-32k_white_surf': (surf, 'white_L_32'), + 'hemi-L_space-native_white_surf': (surf, 'white_L_native'), + 'hemi-R_space-fsLR_den-164k_white_surf': (surf, 'white_R_164'), + 'hemi-R_space-fsLR_den-32k_white_surf': (surf, 'white_R_32'), + 'hemi-R_space-native_white_surf': (surf, 'white_R_native') } - - - - # L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], - # output_names=['L_cortex_file'], - # function=run_get_cortex), - # name=f'L_surf_cortex_{pipe_num}') - - # L_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # L_cortex_file.inputs.structure = "LEFT" - # L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" - # wf.connect(surf, 'dtseries', L_cortex_file, 'dtseries') - - # R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], - # output_names=['R_cortex_file'], - # function=run_get_cortex), - # name=f'R_surf_cortex_{pipe_num}') - - # R_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # R_cortex_file.inputs.structure = "RIGHT" - # R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" - # wf.connect(surf, 'dtseries', R_cortex_file, 'dtseries') - - - # mean_timeseries = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'dtseries'], - # output_names=['mean_timeseries'], - # function=run_mean_timeseries), - # name=f'mean_timeseries_{pipe_num}') - - # mean_timeseries.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # wf.connect(surf, 'dtseries', mean_timeseries, 'dtseries') - - - # L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', - # 'post_freesurfer_folder', 'reho_filename'], - # output_names=['L_reho'], - # function=run_surf_reho), - # name=f'surf_reho{pipe_num}') - - # wf.connect(get_L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') - # wf.connect(surf, 'L_surface_file', L_reho, 'surface_file') - # wf.connect(surf, 'L_mask', L_reho, 'mask') - # wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') - # L_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # L_reho.inputs.reho_filename = L_surf_reho.dscalar.nii - - # R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', - # 'post_freesurfer_folder', 'reho_filename'], - # output_names=['R_reho'], - # function=run_surf_reho), - # name=f'surf_reho{pipe_num}') - - # wf.connect(get_R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') - # wf.connect(surf, 'R_surface_file', R_reho, 'surface_file') - # wf.connect(surf, 'R_mask', R_reho, 'mask') - # wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') - # R_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # R_reho.inputs.reho_filename = R_surf_reho.dscalar.nii - - - - # connectivity_parcellation = pe.Node(util.Function(input_names=['dtseries', 'surf_atlaslabel', - # 'post_freesurfer_folder'], - # output_names=['parcellation_file'], - # function=run_ciftiparcellate), - # name=f'connectivity_parcellation{pipe_num}') - - - # wf.connect(surf, 'dtseries', connectivity, 'dtseries') - # connectivity_parcellation.inputs.surf_atlaslabel = ## path to the label file - - # correlation_matrix = pe.Node(util.Function(input_names=['ptseries','post_freesurfer_folder'], - # output_names=['correlation_matrix'], - # function=run_cifticorrelation), - # name=f'correlation_matrix{pipe_num}') - - - # wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix 'ptseries') - return wf, outputs def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): @@ -304,75 +758,321 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"]], - "outputs": ["atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", + "outputs": ["space-fsLR_den-32k_bold-dtseries", + "atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", "atlas-Destrieux_space-fsLR_den-32k_dlabel", "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", "atlas-Destrieux_space-fsLR_den-164k_dlabel", - "space-fsLR_den-32k_bold-dtseries", - "falff-surf_dscalar", - "alff-surf_dscalar"]} + "AtlasSubcortical_s2", + "goodvoxels", + "ribbon_only", + "atlasroi_hemi-L_space-fsLR_den-32k_func", + "atlasroi_hemi-R_space-fsLR_den-32k_func", + "atlasroi_hemi-L_space-fsLR_den-32k_shape", + "atlasroi_hemi-R_space-fsLR_den-32k_shape", + "space-native_hemi-L_func", + "space-native_hemi-R_func", + "space-fsLR_den-32k_wb-spec", + "space-native_wb-spec", + "arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape", + "arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape", + "arealdistortion-FS_space-fsLR_den-32k_dscalar", + "arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape", + "arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape", + "arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar", + "edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape", + "edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape", + "edgedistortion-FS_space-fsLR_den-32k_dscalar", + "edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape", + "edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape", + "edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar", + "hemi-L_space-fsLR_den-32k_curv_shape", + "hemi-R_space-fsLR_den-32k_curv_shape", + "space-fsLR_den-32k_curv_dscalar", + "hemi-L_space-fsLR_den-32k_flat_surf", + "hemi-R_space-fsLR_den-32k_flat_surf", + "hemi-L_space-fsLR_den-32k_inflated_surf", + "hemi-R_space-fsLR_den-32k_inflated_surf", + "hemi-L_space-fsLR_den-32k_very-inflated_surf", + "hemi-R_space-fsLR_den-32k_very-inflated_surf", + "hemi-L_space-native_inflated_surf", + "hemi-R_space-native_inflated_surf", + "hemi-L_space-native_very-inflated_surf", + "hemi-R_space-native_very-inflated_surf", + "hemi-L_space-fsLR_den-164k_midthickness_surf", + "hemi-R_space-fsLR_den-164k_midthickness_surf", + "hemi-L_space-fsLR_den-32k_midthickness_surf", + "hemi-R_space-fsLR_den-32k_midthickness_surf", + "hemi-L_space-native_midthickness_surf", + "hemi-R_space-native_midthickness_surf", + "hemi-L_space-fsLR_den-32k_pial_surf", + "hemi-R_space-fsLR_den-32k_pial_surf", + "hemi-L_space-native_den-32k_pial_surf", + "hemi-R_space-native_den-32k_pial_surf", + "hemi-L_space-fsLR_den-32k_sphere_surf", + "hemi-R_space-fsLR_den-32k_sphere_surf", + "hemi-L_MSMSulc_space-native_sphere_surf", + "hemi-R_MSMSulc_space-native_sphere_surf", + "hemi-L_space-native_sphere_surf", + "hemi-R_space-native_sphere_surf", + "hemi-L_space-native_sphere-reg_surf", + "hemi-R_space-native_sphere-reg_surf", + "hemi-L_space-native_sphere-reg-reg_surf", + "hemi-R_space-native_sphere-reg-reg_surf", + "hemi-L_space-native_sphere-rot_surf", + "hemi-R_space-native_sphere-rot_surf", + "hemi-L_strainJ-FS_space-fsLR_den-32k_shape", + "hemi-R_strainJ-FS_space-fsLR_den-32k_shape", + "strainJ-FS_space-fsLR_den-32k_dscalar", + "hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape", + "hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape", + "strainJ-MSMSulc_space-fsLR_den-32k_dscalar", + "hemi-L_strainR-FS_space-fsLR_den-32k_shape", + "hemi-R_strainR-FS_space-fsLR_den-32k_shape", + "strainR-FS_space-fsLR_den-32k_dscalar", + "hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape", + "hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape", + "strainR-MSMSulc_space-fsLR_den-32k_dscalar", + "hemi-L_space-fsLR_den-32k_sulc_shape", + "hemi-R_space-fsLR_den-32k_sulc_shape", + "space-fsLR_den-32k_sulc_dscalar", + "hemi-L_space-fsLR_den-32k_thickness_shape", + "hemi-R_space-fsLR_den-32k_thickness_shape", + "space-fsLR_den-32k_thickness_dscalar", + "hemi-L_space-fsLR_den-164k_white_surf", + "hemi-R_space-fsLR_den-164k_white_surf", + "hemi-L_space-fsLR_den-32k_white_surf", + "hemi-R_space-fsLR_den-32k_white_surf", + "hemi-L_space-native_white_surf", + "hemi-R_space-native_white_surf"]} ''' wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) return (wf, outputs) +def cal_falff(wf, cfg, strat_pool, pipe_num, opt): + + falff = pe.Node(util.Function(input_names=['dtseries'], + output_names=['falff'], + function=run_surf_falff), + name=f'surf_falff_{pipe_num}') + + node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') + wf.connect(node, out, falff, 'dtseries') + + outputs = { + 'surf-falff': (falff,'falff')} + return wf, outputs + +def cal_alff(wf, cfg, strat_pool, pipe_num, opt): + + alff = pe.Node(util.Function(input_names=['dtseries'], + output_names=['alff'], + function=run_surf_alff), + name=f'surf_alff_{pipe_num}') + + node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') + wf.connect(node, out,alff, 'dtseries') + outputs = { + 'surf-alff': (falff,'alff')} + return wf, outputs + +# def cal_reho(wf, cfg, strat_pool, pipe_num, opt): + +# L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], +# output_names=['L_cortex_file'], +# function=run_get_cortex), +# name=f'L_surf_cortex_{pipe_num}') + +# L_cortex_file.inputs.structure = "LEFT" +# L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" +# node, out = strat_pool.get_data(space-fsLR_den-32k_bold-dtseries) +# wf.connect(node, out, L_cortex_file, 'dtseries') + +# R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], +# output_names=['R_cortex_file'], +# function=run_get_cortex), +# name=f'R_surf_cortex_{pipe_num}') + + +# R_cortex_file.inputs.structure = "RIGHT" +# R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" +# wf.connect(node, out,R_cortex_file, 'dtseries') + + +# mean_timeseries = pe.Node(util.Function(input_names=['dtseries'], +# output_names=['mean_timeseries'], +# function=run_mean_timeseries), +# name=f'mean_timeseries_{pipe_num}') + + +# wf.connect(node, out, mean_timeseries, 'dtseries') + +# L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries','reho_filename'], +# output_names=['L_reho'], +# function=run_surf_reho), +# name=f'surf_reho{pipe_num}') + +# wf.connect(L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') +# wf.connect(surf, 'midthickness_L_32', L_reho, 'surface_file') +# wf.connect(surf,'atlas_roi_shape_L', L_reho, 'mask') +# wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') +# L_reho.inputs.reho_filename = L_surf_reho.dscalar.nii +# wf.connect(node, out, L_reho, 'dtseries') + +# R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', 'reho_filename'], +# output_names=['R_reho'], +# function=run_surf_reho), +# name=f'surf_reho{pipe_num}') + +# wf.connect(R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') +# wf.connect(surf, 'midthickness_R_32', R_reho, 'surface_file') +# wf.connect(surf,'atlas_roi_shape_R', L_reho, 'mask') +# wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') +# R_reho.inputs.reho_filename = R_surf_reho.dscalar.nii +# wf.connect(node, out, R_reho, 'dtseries') + +# outputs = { +# 'surf-L_reho': (L_reho,'L_reho'), +# 'surf-R_reho': (R_reho,'R_reho')} + +# return wf, outputs + +# def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): + +# connectivity_parcellation = pe.Node(util.Function(input_names=['dtseries', 'surf_atlaslabel'], +# output_names=['parcellation_file'], +# function=run_ciftiparcellate), +# name=f'connectivity_parcellation{pipe_num}') + +# wf.connect(node, out, connectivity, 'dtseries') +# connectivity_parcellation.inputs.surf_atlaslabel = ## path to the label file + +# correlation_matrix = pe.Node(util.Function(input_names=['ptseries'], +# output_names=['correlation_matrix'], +# function=run_cifticorrelation), +# name=f'correlation_matrix{pipe_num}') + + +# wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix 'ptseries') + +# outputs = { +# 'surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} + +# return wf, outputs + + +def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "surface_falff", + "config": ["amplitude_low_frequency_fluctuation"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["space-fsLR_den-32k_bold-dtseries"], + "outputs": ["falff"]} + ''' + wf, outputs = cal_falff(wf, cfg, strat_pool, pipe_num, opt) + + return (wf, outputs) + +def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "surface_alff", + "config": ["amplitude_low_frequency_fluctuation"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["space-fsLR_den-32k_bold-dtseries"], + "outputs": ["alff"]} + ''' + wf, outputs = cal_alff(wf, cfg, strat_pool, pipe_num, opt) + + return (wf, outputs) + +# def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): +# ''' +# {"name": "ReHo", +# "config": ["regional_homogeneity"], +# "switch": ["run"], +# "option_key": "surface_reho", +# "option_val": "None", +# "inputs": ["space-fsLR_den-32k_bold-dtseries"], +# "outputs": ["surf-L_reho", "surf-R_reho"]} +# ''' +# wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) + +# return (wf, outputs) + +# def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): +# ''' +# {"name": "surface_connectivity_matrix", +# "config": ["surface_analysis", "post_freesurfer"], +# "switch": ["run"], +# "option_key": "None", +# "option_val": "None", +# "inputs": ["space-fsLR_den-32k_bold-dtseries", +# "outputs": ["surf-correlation_matrix"} +# ''' +# wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) + +# return (wf, outputs) def run_surf_falff(dtseries): import os import subprocess - falff = os.path.join(os.getcwd(), 'falff_surf.dscalar.nii.gz') + falff = os.path.join(os.getcwd(), 'falff_surf.nii.gz') cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] subprocess.check_output(cmd) return falff - def run_surf_alff(dtseries): - import os - import subprocess - alff = os.path.join(os.getcwd(), 'alff_surf.dscalar.nii.gz') - cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] - subprocess.check_output(cmd) - return alff + import os + import subprocess + alff = os.path.join(os.getcwd(), 'alff_surf.dscalar.nii.gz') + cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] + subprocess.check_output(cmd) + return alff -#cmd = ['ciftify_falff', dtseries , 'alff_surf.dscalar.nii', '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] -# def run_get_cortex(dtseries, structure, post_freesurfer_folder, cortex_filename): +# def run_get_cortex(dtseries, structure, cortex_filename): # import os # import subprocess -# cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_filename] +# cortex_file = os.path.join(os.getcwd(), cortex_filename) +# cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_file] # subprocess.check_output(cmd) -# cortex_file = os.path.join(post_freesurfer_folder, cortex_filename) # return cortex_file # def run_mean_timeseries(dtseries,post_freesurfer_folder): # import os # import subprocess -# cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', 'mean.dscalar.nii'] +# mean_timeseries = os.path.join(os.getcwd(), mean.dscalar.nii) +# cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', mean_timeseries] # subprocess.check_output(cmd) -# mean_timeseries = os.path.join(post_freesurfer_folder, mean.dscalar.nii) # return mean_timeseries # def run_surf_reho(dtseries, mask, cortex_file, surface_file,mean_timeseries,post_freesurfer_folder, reho_filename): # import os # import subprocess -# cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, reho_filename] +# surf_reho = os.path.join(os.getcwd(), reho_filename) +# cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, surf_reho] # subprocess.check_output(cmd) -# surf_reho = os.path.join(post_freesurfer_folder, reho_filename) # return surf_reho # def run_ciftiparcellate(dtseries, surf_atlaslabel): # import os # import subprocess -# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', 'parcellation.ptseries.nii'] +# parcellation_file = os.path.join(os.getcwd(), 'parcellation.ptseries.nii') +# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] # subprocess.check_output(cmd) -# parcellation_file = os.path.join(post_freesurfer_folder, 'parcellation.ptseries.nii') + # return parcellation_file # def run_cifticorrelation(ptseries): # import os # import subprocess -# cmd = ['wb_command', '-cifti-correlation ', ptseries , 'cifti_corr.pconn.nii'] +# correlation_matrix = os.path.join(os.getcwd(), 'cifti_corr.pconn.nii') +# cmd = ['wb_command', '-cifti-correlation ', ptseries , correlation_matrix] # subprocess.check_output(cmd) -# correlation_matrix = os.path.join(post_freesurfer_folder, 'cifti_corr.pconn.nii') # return correlation_matrix From 982d44eb2c7d7b2da181097a8025465157e3864e Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 1 Feb 2023 22:00:07 +0000 Subject: [PATCH 004/213] commiting all files modified --- .circleci/config.yml | 0 .circleci/main.yml | 0 .dockerignore | 0 .flake8 | 0 ...AFNI.16.2.07.neurodocker-xenial.Dockerfile | 0 .../AFNI.20.0.04-bionic.Dockerfile | 0 ...FNI.update.afni.binaries-bionic.Dockerfile | 0 .../ANTs.2.2.0.neurodocker-bionic.Dockerfile | 0 .../ANTs.2.3.4.neurodocker-xenial.Dockerfile | 0 .../Dockerfiles/ANTs.2.3.5-bionic.Dockerfile | 0 .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 0 .../C-PAC.develop-bionic.Dockerfile | 0 ...PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 0 .../C-PAC.develop-lite-bionic.Dockerfile | 0 .../Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 0 .../FSL.5.0.9-5.neurodebian-xenial.Dockerfile | 0 .../FSL.neurodebian-bionic.Dockerfile | 0 ...er.6.0.0-min.neurodocker-bionic.Dockerfile | 0 .../FreeSurfer.6.0.1-min-xenial.Dockerfile | 0 .../FreeSurfer.6.0.1-xenial.Dockerfile | 0 .../ICA-AROMA.0.4.3-beta-bionic.Dockerfile | 0 .../ICA-AROMA.0.4.5-xenial.Dockerfile | 0 .../Ubuntu.bionic-non-free.Dockerfile | 0 .../Ubuntu.xenial-20200114.Dockerfile | 0 .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 0 .../Dockerfiles/base-fMRIPrep-LTS.Dockerfile | 0 .github/Dockerfiles/base-standard.Dockerfile | 0 .../Dockerfiles/c3d.1.0.0-bionic.Dockerfile | 0 .../Dockerfiles/c3d.1.0.0-xenial.Dockerfile | 0 ...ench.1.3.2-1.neurodebian-bionic.Dockerfile | 0 ...ench.1.3.2-2.neurodebian-xenial.Dockerfile | 0 ...kbench.1.5.0.neurodebian-bionic.Dockerfile | 0 .github/Dockerfiles/msm.2.0-bionic.Dockerfile | 0 .../neuroparc.1.0-human-bionic.Dockerfile | 0 .github/scripts/get_package_id.py | 0 .github/scripts/get_pr_base_shas.py | 0 .github/scripts/minify-freesurfer-6.0.1.sh | 0 .github/stage_requirements/ABCD-HCP.txt | 0 .github/stage_requirements/fMRIPrep-LTS.txt | 0 .github/stage_requirements/standard.txt | 0 .github/workflows/build_C-PAC.yml | 0 .github/workflows/build_and_test.yml | 0 .github/workflows/build_stages.yml | 0 .github/workflows/check_updated_version.yml | 0 .github/workflows/delete_images.yml | 0 .github/workflows/deploy_to_Docker_Hub.yml | 0 .github/workflows/smoke_test_participant.yml | 0 .pylintrc | 0 .vscode/run_nose.py | 0 .vscode/settings.json | 0 CHANGELOG.md | 0 CONTRIBUTING.md | 0 COPYING | 0 COPYING.LESSER | 0 CPAC/GUI/resources/html/_static/cpac_logo.jpg | Bin CPAC/GUI/resources/html/_static/nature.css | 0 CPAC/GUI/resources/html/_static/pygments.css | 0 CPAC/__init__.py | 0 CPAC/__main__.py | 0 CPAC/alff/__init__.py | 0 CPAC/alff/alff.py | 0 CPAC/alff/utils.py | 0 CPAC/anat_preproc/__init__.py | 0 CPAC/anat_preproc/anat_preproc.py | 0 CPAC/anat_preproc/ants.py | 0 ...ntsBrainExtractionNoLaplacian_precise.json | 0 ...ntsBrainExtractionNoLaplacian_testing.json | 0 .../data/antsBrainExtraction_precise.json | 0 .../data/antsBrainExtraction_testing.json | 0 CPAC/anat_preproc/lesion_preproc.py | 0 CPAC/anat_preproc/utils.py | 0 CPAC/aroma/__init__.py | 0 CPAC/aroma/aroma.py | 0 CPAC/aroma/aroma_test.py | 0 CPAC/connectome/__init__.py | 0 CPAC/connectome/connectivity_matrix.py | 0 CPAC/connectome/test/test_connectome.py | 0 CPAC/cwas/__init__.py | 0 CPAC/cwas/cwas.py | 0 CPAC/cwas/mdmr.py | 0 CPAC/cwas/pipeline.py | 0 CPAC/cwas/tests/X.csv | 0 CPAC/cwas/tests/Y.csv | 0 CPAC/cwas/tests/test_mdmr_cython.py | 0 CPAC/cwas/tests/test_pipeline_cwas.py | 0 CPAC/distortion_correction/__init__.py | 0 .../distortion_correction.py | 0 CPAC/distortion_correction/tests/__init__.py | 0 .../tests/test_distortion_correction.py | 0 CPAC/distortion_correction/utils.py | 0 CPAC/easy_thresh/__init__.py | 0 CPAC/easy_thresh/easy_thresh.py | 0 CPAC/func_preproc/__init__.py | 0 CPAC/func_preproc/func_ingress.py | 0 CPAC/func_preproc/func_preproc.py | 0 CPAC/func_preproc/utils.py | 0 CPAC/generate_motion_statistics/__init__.py | 0 .../generate_motion_statistics.py | 0 .../test/test_dvars.py | 0 CPAC/group_analysis/__init__.py | 0 CPAC/group_analysis/group_analysis.py | 0 CPAC/image_utils/__init__.py | 0 CPAC/image_utils/spatial_smoothing.py | 0 CPAC/image_utils/statistical_transforms.py | 0 CPAC/image_utils/tests/test_smooth.py | 0 CPAC/info.py | 0 CPAC/isc/__init__.py | 0 CPAC/isc/isc.py | 0 CPAC/isc/isfc.py | 0 CPAC/isc/pipeline.py | 0 CPAC/isc/tests/test_pipeline_isc.py | 0 CPAC/isc/utils.py | 0 .../longitudinal_preproc.py | 0 .../longitudinal_workflow.py | 0 CPAC/median_angle/median_angle.py | 0 CPAC/network_centrality/__init__.py | 0 CPAC/network_centrality/network_centrality.py | 0 CPAC/network_centrality/pipeline.py | 0 CPAC/network_centrality/utils.py | 0 CPAC/nuisance/__init__.py | 0 CPAC/nuisance/bandpass.py | 0 CPAC/nuisance/nuisance.py | 0 .../nuisance/tests/motion_statistics/DVARS.1D | 0 CPAC/nuisance/tests/motion_statistics/FD_J.1D | 0 CPAC/nuisance/tests/motion_statistics/FD_P.1D | 0 .../tests/test_nuisance_representations.py | 0 CPAC/nuisance/tests/test_utils.py | 0 CPAC/nuisance/utils/__init__.py | 0 CPAC/nuisance/utils/compcor.py | 0 CPAC/nuisance/utils/convolve.py | 0 CPAC/nuisance/utils/crc.py | 0 CPAC/pipeline/__init__.py | 0 CPAC/pipeline/check_outputs.py | 0 CPAC/pipeline/cpac_basc_pipeline.py | 0 CPAC/pipeline/cpac_cwas_pipeline.py | 0 CPAC/pipeline/cpac_group_runner.py | 0 CPAC/pipeline/cpac_randomise_pipeline.py | 0 CPAC/pipeline/cpac_runner.py | 0 CPAC/pipeline/engine.py | 5 +- .../nipype_pipeline_engine/__init__.py | 0 .../pipeline/nipype_pipeline_engine/engine.py | 0 .../plugins/__init__.py | 0 .../plugins/cpac_nipype_custom.py | 0 .../plugins/legacymultiproc.py | 0 .../plugins/multiproc.py | 0 CPAC/pipeline/random_state/__init__.py | 0 CPAC/pipeline/random_state/seed.py | 0 CPAC/pipeline/schema.py | 0 CPAC/pipeline/test/__init__.py | 0 CPAC/pipeline/test/issue_1606_data_config.yml | 0 CPAC/pipeline/test/sample_data.py | 0 CPAC/pipeline/test/test_cpac_group_runner.py | 0 CPAC/pipeline/test/test_cpac_pipeline.py | 0 CPAC/pipeline/test/test_cpac_runner.py | 0 CPAC/pipeline/test/test_engine.py | 0 .../test/test_nipype_pipeline_engine.py | 0 CPAC/pipeline/test/test_schema_validation.py | 0 CPAC/pypeer/__init__.py | 0 CPAC/pypeer/peer.py | 0 CPAC/qc/__init__.py | 0 CPAC/qc/colors/blue.txt | 0 CPAC/qc/colors/cyan_to_yellow.txt | 0 CPAC/qc/colors/green.txt | 0 CPAC/qc/colors/red.txt | 0 CPAC/qc/colors/red_to_blue.txt | 0 CPAC/qc/data/index.html | 0 CPAC/qc/pipeline.py | 0 CPAC/qc/qc.py | 0 CPAC/qc/qcmetrics.py | 0 CPAC/qc/tests/test_qc.py | 0 CPAC/qc/utils.py | 0 CPAC/qc/xcp.py | 0 CPAC/qpp/__init__.py | 0 CPAC/qpp/pipeline.py | 0 CPAC/qpp/qpp.py | 0 CPAC/qpp/tests/test_qpp.py | 0 CPAC/randomise/__init__.py | 0 CPAC/randomise/pipeline.py | 0 CPAC/randomise/randomise.py | 0 CPAC/randomise/test_randomise.py | 0 CPAC/registration/__init__.py | 0 CPAC/registration/output_func_to_standard.py | 0 CPAC/registration/registration.py | 0 CPAC/registration/tests/__init__.py | 0 CPAC/registration/tests/mocks.py | 0 .../tests/test_ants_apply_warp.py | 0 .../tests/test_apply_transform.py | 0 .../tests/test_output_func_to_standard.py | 0 CPAC/registration/utils.py | 0 CPAC/reho/__init__.py | 0 CPAC/reho/reho.py | 0 CPAC/reho/utils.py | 0 .../MSMConfig/MSMSulcStrainFinalconf | 0 .../configs/1.7-1.8-deprecations.yml | 0 .../configs/1.7-1.8-nesting-mappings.yml | 0 .../configs/data_config_S3-BIDS-ABIDE.yml | 0 .../configs/data_config_S3-BIDS-ADHD200.yml | 0 .../data_config_S3-BIDS-ADHD200_only2.yml | 0 ...data_config_S3-BIDS-NKI-RocklandSample.yml | 0 .../configs/data_config_cpac_benchmark.yml | 0 .../configs/data_settings_template.yml | 0 .../configs/group_config_template.yml | 0 .../configs/pipeline_config_abcd-options.yml | 0 .../configs/pipeline_config_anat-only.yml | 0 .../pipeline_config_benchmark-ANTS.yml | 0 .../pipeline_config_benchmark-FNIRT.yml | 0 .../configs/pipeline_config_blank.yml | 0 .../configs/pipeline_config_ccs-options.yml | 0 .../pipeline_config_fmriprep-options.yml | 0 .../configs/pipeline_config_fx-options.yml | 0 .../configs/pipeline_config_monkey-ABCD.yml | 0 .../configs/pipeline_config_monkey.yml | 0 .../configs/pipeline_config_ndmg.yml | 0 .../configs/pipeline_config_nhp-macaque.yml | 0 .../configs/pipeline_config_preproc.yml | 0 .../configs/pipeline_config_rbc-options.yml | 0 .../configs/pipeline_config_regtest-1.yml | 0 .../configs/pipeline_config_regtest-2.yml | 0 .../configs/pipeline_config_regtest-3.yml | 0 .../configs/pipeline_config_regtest-4.yml | 0 .../configs/pipeline_config_rodent.yml | 0 CPAC/resources/configs/system_config.yml | 0 .../test_configs/ADHD200_participants.csv | 0 .../test_configs/ADHD200_participants_age.tsv | 0 .../test_configs/data-test_S3-ADHD200_1.yml | 0 .../data-test_S3-ADHD200_no-params.yml | 0 .../test_configs/data-test_S3-NKI-RS_fmap.yml | 0 .../configs/test_configs/data-test_human.yml | 0 .../data_config_S3_CoRR_5only_mult-scan.yml | 0 .../data_config_S3_CoRR_5only_mult-sess.yml | 0 .../configs/test_configs/pipe-test_ABCD.yml | 0 .../pipe-test_ANTs-3dSk-AllNuis.yml | 0 .../pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 0 .../pipe-test_ANTs-3dSk-DistCorrBET.yml | 0 .../pipe-test_ANTs-BET-AllNuis.yml | 0 .../pipe-test_FNIRT-3dSk-AllNuis.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-BASC.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-ISC.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 0 .../pipe-test_FNIRT-BET-AllNuis.yml | 0 .../configs/test_configs/pipe-test_all.yml | 0 CPAC/resources/cpac_templates.csv | 0 CPAC/resources/global/scripts/log.shlib | 0 .../mni_icbm152_t1_tal_nlin_asym_09c.nii | Bin CPAC/resources/templates/ndmg_atlases.csv | 0 ...Lin2009cAsym_res-01_desc-brain_mask.nii.gz | Bin ...2009cAsym_res-01_desc-brain_probseg.nii.gz | 0 ...009cAsym_res-01_label-brain_probseg.nii.gz | Bin ...2NLin2009cAsym_res-02_T1w_reference.nii.gz | Bin ...Lin2009cAsym_res-02_desc-brain_mask.nii.gz | Bin ...9cAsym_res-02_desc-fMRIPrep_boldref.nii.gz | Bin CPAC/sca/README.txt | 0 CPAC/sca/__init__.py | 0 CPAC/sca/sca.py | 0 CPAC/sca/utils.py | 0 CPAC/scrubbing/__init__.py | 0 CPAC/scrubbing/scrubbing.py | 0 CPAC/seg_preproc/__init__.py | 0 CPAC/seg_preproc/utils.py | 0 ...Surfer2CaretConvertAndRegisterNonlinear.sh | 0 CPAC/surface/PostFreeSurfer/run.sh | 0 .../fMRISurface/CreateDenseTimeseries.sh | 0 .../RibbonVolumeToSurfaceMapping.sh | 0 .../fMRISurface/SubcorticalProcessing.sh | 0 CPAC/surface/fMRISurface/SurfaceSmoothing.sh | 0 CPAC/surface/surf_preproc_old.py | 376 ++++++++++++++++++ CPAC/surface/tests/test_config.py | 0 CPAC/timeseries/__init__.py | 0 CPAC/timeseries/timeseries_analysis.py | 0 CPAC/unet/__init__.py | 0 CPAC/unet/function.py | 0 CPAC/utils/README.txt | 0 CPAC/utils/__init__.py | 0 CPAC/utils/build_data_config.py | 0 CPAC/utils/configuration.py | 0 CPAC/utils/create_flame_model_files.py | 0 CPAC/utils/create_fsl_flame_preset.py | 0 CPAC/utils/create_fsl_model.py | 0 .../utils/create_group_analysis_info_files.py | 0 CPAC/utils/datasource.py | 0 CPAC/utils/docs.py | 0 CPAC/utils/extract_data.py | 0 CPAC/utils/extract_data_multiscan.py | 0 CPAC/utils/extract_parameters.py | 0 CPAC/utils/ga.py | 0 CPAC/utils/interfaces/__init__.py | 0 CPAC/utils/interfaces/ants.py | 0 CPAC/utils/interfaces/brickstat.py | 0 CPAC/utils/interfaces/datasink.py | 0 CPAC/utils/interfaces/fixes.py | 0 CPAC/utils/interfaces/fsl.py | 0 CPAC/utils/interfaces/function/__init__.py | 0 CPAC/utils/interfaces/function/function.py | 0 CPAC/utils/interfaces/function/seg_preproc.py | 0 CPAC/utils/interfaces/masktool.py | 0 CPAC/utils/interfaces/netcorr.py | 0 CPAC/utils/interfaces/pc.py | 0 CPAC/utils/interfaces/tests/__init__.py | 0 CPAC/utils/interfaces/tests/test_fsl.py | 0 CPAC/utils/interfaces/utils.py | 0 CPAC/utils/misc.py | 0 CPAC/utils/monitoring/__init__.py | 0 CPAC/utils/monitoring/config.py | 0 CPAC/utils/monitoring/custom_logging.py | 0 CPAC/utils/monitoring/draw_gantt_chart.py | 0 CPAC/utils/monitoring/monitoring.py | 0 CPAC/utils/ndmg_utils.py | 0 CPAC/utils/nifti_utils.py | 0 CPAC/utils/outputs.py | 0 CPAC/utils/strategy.py | 0 CPAC/utils/symlinks.py | 0 CPAC/utils/test_init.py | 0 CPAC/utils/test_mocks.py | 0 CPAC/utils/test_resources.py | 0 CPAC/utils/tests/__init__.py | 0 CPAC/utils/tests/test_bids_utils.py | 0 CPAC/utils/tests/test_crash.py | 0 CPAC/utils/tests/test_datasource.py | 0 CPAC/utils/tests/test_function.py | 0 CPAC/utils/tests/test_s3.py | 0 CPAC/utils/tests/test_symlinks-outputs.txt | 0 CPAC/utils/tests/test_symlinks.py | 0 CPAC/utils/tests/test_trimmer.py | 0 CPAC/utils/tests/test_utils.py | 0 CPAC/utils/tests/test_yaml.py | 0 CPAC/utils/trimmer.py | 0 CPAC/utils/utils.py | 0 CPAC/utils/yaml_template.py | 0 CPAC/vmhc/__init__.py | 0 CPAC/vmhc/tests/test_vmhc.py | 0 CPAC/vmhc/utils.py | 0 CPAC/vmhc/vmhc.py | 0 Dockerfile | 0 README.md | 0 dev/ami_data/setup.sh | 0 dev/ami_data/setup_cpac.sh | 0 dev/circleci_data/__init__.py | 0 ...tings_bids_examples_ds051_default_BIDS.yml | 0 dev/circleci_data/generate_run_command.py | 0 dev/circleci_data/pipe-test_ci.yml | 0 dev/circleci_data/pytest.ini | 0 dev/circleci_data/python_2_pickle.pkl | 0 dev/circleci_data/python_2_pickle.pklz | Bin dev/circleci_data/requirements.txt | 0 dev/circleci_data/test_external_utils.py | 0 dev/circleci_data/test_install.py | 0 dev/docker_data/default_pipeline.yml | 0 dev/docker_data/license.txt | 0 dev/docker_data/required_afni_pkgs.txt | 0 dev/docker_data/required_freesurfer_pkgs.txt | 0 dev/rc_tests/README.md | 0 requirements.txt | 0 scripts/cpac | 0 variant-ABCD-HCP.Dockerfile | 0 variant-fMRIPrep-LTS.Dockerfile | 0 variant-lite.Dockerfile | 0 version | 0 358 files changed, 380 insertions(+), 1 deletion(-) mode change 100644 => 100755 .circleci/config.yml mode change 100644 => 100755 .circleci/main.yml mode change 100644 => 100755 .dockerignore mode change 100644 => 100755 .flake8 mode change 100644 => 100755 .github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/AFNI.update.afni.binaries-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/C-PAC.develop-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/ICA-AROMA.0.4.3-beta-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/base-ABCD-HCP.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/base-standard.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/msm.2.0-bionic.Dockerfile mode change 100644 => 100755 .github/Dockerfiles/neuroparc.1.0-human-bionic.Dockerfile mode change 100644 => 100755 .github/scripts/get_package_id.py mode change 100644 => 100755 .github/scripts/get_pr_base_shas.py mode change 100644 => 100755 .github/scripts/minify-freesurfer-6.0.1.sh mode change 100644 => 100755 .github/stage_requirements/ABCD-HCP.txt mode change 100644 => 100755 .github/stage_requirements/fMRIPrep-LTS.txt mode change 100644 => 100755 .github/stage_requirements/standard.txt mode change 100644 => 100755 .github/workflows/build_C-PAC.yml mode change 100644 => 100755 .github/workflows/build_and_test.yml mode change 100644 => 100755 .github/workflows/build_stages.yml mode change 100644 => 100755 .github/workflows/check_updated_version.yml mode change 100644 => 100755 .github/workflows/delete_images.yml mode change 100644 => 100755 .github/workflows/deploy_to_Docker_Hub.yml mode change 100644 => 100755 .github/workflows/smoke_test_participant.yml mode change 100644 => 100755 .pylintrc mode change 100644 => 100755 .vscode/run_nose.py mode change 100644 => 100755 .vscode/settings.json mode change 100644 => 100755 CHANGELOG.md mode change 100644 => 100755 CONTRIBUTING.md mode change 100644 => 100755 COPYING mode change 100644 => 100755 COPYING.LESSER mode change 100644 => 100755 CPAC/GUI/resources/html/_static/cpac_logo.jpg mode change 100644 => 100755 CPAC/GUI/resources/html/_static/nature.css mode change 100644 => 100755 CPAC/GUI/resources/html/_static/pygments.css mode change 100644 => 100755 CPAC/__init__.py mode change 100644 => 100755 CPAC/__main__.py mode change 100644 => 100755 CPAC/alff/__init__.py mode change 100644 => 100755 CPAC/alff/alff.py mode change 100644 => 100755 CPAC/alff/utils.py mode change 100644 => 100755 CPAC/anat_preproc/__init__.py mode change 100644 => 100755 CPAC/anat_preproc/anat_preproc.py mode change 100644 => 100755 CPAC/anat_preproc/ants.py mode change 100644 => 100755 CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_precise.json mode change 100644 => 100755 CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_testing.json mode change 100644 => 100755 CPAC/anat_preproc/data/antsBrainExtraction_precise.json mode change 100644 => 100755 CPAC/anat_preproc/data/antsBrainExtraction_testing.json mode change 100644 => 100755 CPAC/anat_preproc/lesion_preproc.py mode change 100644 => 100755 CPAC/anat_preproc/utils.py mode change 100644 => 100755 CPAC/aroma/__init__.py mode change 100644 => 100755 CPAC/aroma/aroma.py mode change 100644 => 100755 CPAC/aroma/aroma_test.py mode change 100644 => 100755 CPAC/connectome/__init__.py mode change 100644 => 100755 CPAC/connectome/connectivity_matrix.py mode change 100644 => 100755 CPAC/connectome/test/test_connectome.py mode change 100644 => 100755 CPAC/cwas/__init__.py mode change 100644 => 100755 CPAC/cwas/cwas.py mode change 100644 => 100755 CPAC/cwas/mdmr.py mode change 100644 => 100755 CPAC/cwas/pipeline.py mode change 100644 => 100755 CPAC/cwas/tests/X.csv mode change 100644 => 100755 CPAC/cwas/tests/Y.csv mode change 100644 => 100755 CPAC/cwas/tests/test_mdmr_cython.py mode change 100644 => 100755 CPAC/cwas/tests/test_pipeline_cwas.py mode change 100644 => 100755 CPAC/distortion_correction/__init__.py mode change 100644 => 100755 CPAC/distortion_correction/distortion_correction.py mode change 100644 => 100755 CPAC/distortion_correction/tests/__init__.py mode change 100644 => 100755 CPAC/distortion_correction/tests/test_distortion_correction.py mode change 100644 => 100755 CPAC/distortion_correction/utils.py mode change 100644 => 100755 CPAC/easy_thresh/__init__.py mode change 100644 => 100755 CPAC/easy_thresh/easy_thresh.py mode change 100644 => 100755 CPAC/func_preproc/__init__.py mode change 100644 => 100755 CPAC/func_preproc/func_ingress.py mode change 100644 => 100755 CPAC/func_preproc/func_preproc.py mode change 100644 => 100755 CPAC/func_preproc/utils.py mode change 100644 => 100755 CPAC/generate_motion_statistics/__init__.py mode change 100644 => 100755 CPAC/generate_motion_statistics/generate_motion_statistics.py mode change 100644 => 100755 CPAC/generate_motion_statistics/test/test_dvars.py mode change 100644 => 100755 CPAC/group_analysis/__init__.py mode change 100644 => 100755 CPAC/group_analysis/group_analysis.py mode change 100644 => 100755 CPAC/image_utils/__init__.py mode change 100644 => 100755 CPAC/image_utils/spatial_smoothing.py mode change 100644 => 100755 CPAC/image_utils/statistical_transforms.py mode change 100644 => 100755 CPAC/image_utils/tests/test_smooth.py mode change 100644 => 100755 CPAC/info.py mode change 100644 => 100755 CPAC/isc/__init__.py mode change 100644 => 100755 CPAC/isc/isc.py mode change 100644 => 100755 CPAC/isc/isfc.py mode change 100644 => 100755 CPAC/isc/pipeline.py mode change 100644 => 100755 CPAC/isc/tests/test_pipeline_isc.py mode change 100644 => 100755 CPAC/isc/utils.py mode change 100644 => 100755 CPAC/longitudinal_pipeline/longitudinal_preproc.py mode change 100644 => 100755 CPAC/longitudinal_pipeline/longitudinal_workflow.py mode change 100644 => 100755 CPAC/median_angle/median_angle.py mode change 100644 => 100755 CPAC/network_centrality/__init__.py mode change 100644 => 100755 CPAC/network_centrality/network_centrality.py mode change 100644 => 100755 CPAC/network_centrality/pipeline.py mode change 100644 => 100755 CPAC/network_centrality/utils.py mode change 100644 => 100755 CPAC/nuisance/__init__.py mode change 100644 => 100755 CPAC/nuisance/bandpass.py mode change 100644 => 100755 CPAC/nuisance/nuisance.py mode change 100644 => 100755 CPAC/nuisance/tests/motion_statistics/DVARS.1D mode change 100644 => 100755 CPAC/nuisance/tests/motion_statistics/FD_J.1D mode change 100644 => 100755 CPAC/nuisance/tests/motion_statistics/FD_P.1D mode change 100644 => 100755 CPAC/nuisance/tests/test_nuisance_representations.py mode change 100644 => 100755 CPAC/nuisance/tests/test_utils.py mode change 100644 => 100755 CPAC/nuisance/utils/__init__.py mode change 100644 => 100755 CPAC/nuisance/utils/compcor.py mode change 100644 => 100755 CPAC/nuisance/utils/convolve.py mode change 100644 => 100755 CPAC/nuisance/utils/crc.py mode change 100644 => 100755 CPAC/pipeline/__init__.py mode change 100644 => 100755 CPAC/pipeline/check_outputs.py mode change 100644 => 100755 CPAC/pipeline/cpac_basc_pipeline.py mode change 100644 => 100755 CPAC/pipeline/cpac_cwas_pipeline.py mode change 100644 => 100755 CPAC/pipeline/cpac_group_runner.py mode change 100644 => 100755 CPAC/pipeline/cpac_randomise_pipeline.py mode change 100644 => 100755 CPAC/pipeline/cpac_runner.py mode change 100644 => 100755 CPAC/pipeline/engine.py mode change 100644 => 100755 CPAC/pipeline/nipype_pipeline_engine/__init__.py mode change 100644 => 100755 CPAC/pipeline/nipype_pipeline_engine/engine.py mode change 100644 => 100755 CPAC/pipeline/nipype_pipeline_engine/plugins/__init__.py mode change 100644 => 100755 CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py mode change 100644 => 100755 CPAC/pipeline/nipype_pipeline_engine/plugins/legacymultiproc.py mode change 100644 => 100755 CPAC/pipeline/nipype_pipeline_engine/plugins/multiproc.py mode change 100644 => 100755 CPAC/pipeline/random_state/__init__.py mode change 100644 => 100755 CPAC/pipeline/random_state/seed.py mode change 100644 => 100755 CPAC/pipeline/schema.py mode change 100644 => 100755 CPAC/pipeline/test/__init__.py mode change 100644 => 100755 CPAC/pipeline/test/issue_1606_data_config.yml mode change 100644 => 100755 CPAC/pipeline/test/sample_data.py mode change 100644 => 100755 CPAC/pipeline/test/test_cpac_group_runner.py mode change 100644 => 100755 CPAC/pipeline/test/test_cpac_pipeline.py mode change 100644 => 100755 CPAC/pipeline/test/test_cpac_runner.py mode change 100644 => 100755 CPAC/pipeline/test/test_engine.py mode change 100644 => 100755 CPAC/pipeline/test/test_nipype_pipeline_engine.py mode change 100644 => 100755 CPAC/pipeline/test/test_schema_validation.py mode change 100644 => 100755 CPAC/pypeer/__init__.py mode change 100644 => 100755 CPAC/pypeer/peer.py mode change 100644 => 100755 CPAC/qc/__init__.py mode change 100644 => 100755 CPAC/qc/colors/blue.txt mode change 100644 => 100755 CPAC/qc/colors/cyan_to_yellow.txt mode change 100644 => 100755 CPAC/qc/colors/green.txt mode change 100644 => 100755 CPAC/qc/colors/red.txt mode change 100644 => 100755 CPAC/qc/colors/red_to_blue.txt mode change 100644 => 100755 CPAC/qc/data/index.html mode change 100644 => 100755 CPAC/qc/pipeline.py mode change 100644 => 100755 CPAC/qc/qc.py mode change 100644 => 100755 CPAC/qc/qcmetrics.py mode change 100644 => 100755 CPAC/qc/tests/test_qc.py mode change 100644 => 100755 CPAC/qc/utils.py mode change 100644 => 100755 CPAC/qc/xcp.py mode change 100644 => 100755 CPAC/qpp/__init__.py mode change 100644 => 100755 CPAC/qpp/pipeline.py mode change 100644 => 100755 CPAC/qpp/qpp.py mode change 100644 => 100755 CPAC/qpp/tests/test_qpp.py mode change 100644 => 100755 CPAC/randomise/__init__.py mode change 100644 => 100755 CPAC/randomise/pipeline.py mode change 100644 => 100755 CPAC/randomise/randomise.py mode change 100644 => 100755 CPAC/randomise/test_randomise.py mode change 100644 => 100755 CPAC/registration/__init__.py mode change 100644 => 100755 CPAC/registration/output_func_to_standard.py mode change 100644 => 100755 CPAC/registration/registration.py mode change 100644 => 100755 CPAC/registration/tests/__init__.py mode change 100644 => 100755 CPAC/registration/tests/mocks.py mode change 100644 => 100755 CPAC/registration/tests/test_ants_apply_warp.py mode change 100644 => 100755 CPAC/registration/tests/test_apply_transform.py mode change 100644 => 100755 CPAC/registration/tests/test_output_func_to_standard.py mode change 100644 => 100755 CPAC/registration/utils.py mode change 100644 => 100755 CPAC/reho/__init__.py mode change 100644 => 100755 CPAC/reho/reho.py mode change 100644 => 100755 CPAC/reho/utils.py mode change 100644 => 100755 CPAC/resources/MSMConfig/MSMSulcStrainFinalconf mode change 100644 => 100755 CPAC/resources/configs/1.7-1.8-deprecations.yml mode change 100644 => 100755 CPAC/resources/configs/1.7-1.8-nesting-mappings.yml mode change 100644 => 100755 CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml mode change 100644 => 100755 CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml mode change 100644 => 100755 CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml mode change 100644 => 100755 CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml mode change 100644 => 100755 CPAC/resources/configs/data_config_cpac_benchmark.yml mode change 100644 => 100755 CPAC/resources/configs/data_settings_template.yml mode change 100644 => 100755 CPAC/resources/configs/group_config_template.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_abcd-options.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_anat-only.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_blank.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_ccs-options.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_fmriprep-options.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_fx-options.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_monkey-ABCD.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_monkey.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_ndmg.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_nhp-macaque.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_preproc.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_rbc-options.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_regtest-1.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_regtest-2.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_regtest-3.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_regtest-4.yml mode change 100644 => 100755 CPAC/resources/configs/pipeline_config_rodent.yml mode change 100644 => 100755 CPAC/resources/configs/system_config.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/ADHD200_participants.csv mode change 100644 => 100755 CPAC/resources/configs/test_configs/ADHD200_participants_age.tsv mode change 100644 => 100755 CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/data-test_human.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_ABCD.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml mode change 100644 => 100755 CPAC/resources/configs/test_configs/pipe-test_all.yml mode change 100644 => 100755 CPAC/resources/cpac_templates.csv mode change 100644 => 100755 CPAC/resources/global/scripts/log.shlib mode change 100644 => 100755 CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii mode change 100644 => 100755 CPAC/resources/templates/ndmg_atlases.csv mode change 100644 => 100755 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz mode change 100644 => 100755 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_probseg.nii.gz mode change 100644 => 100755 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz mode change 100644 => 100755 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz mode change 100644 => 100755 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz mode change 100644 => 100755 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz mode change 100644 => 100755 CPAC/sca/README.txt mode change 100644 => 100755 CPAC/sca/__init__.py mode change 100644 => 100755 CPAC/sca/sca.py mode change 100644 => 100755 CPAC/sca/utils.py mode change 100644 => 100755 CPAC/scrubbing/__init__.py mode change 100644 => 100755 CPAC/scrubbing/scrubbing.py mode change 100644 => 100755 CPAC/seg_preproc/__init__.py mode change 100644 => 100755 CPAC/seg_preproc/utils.py mode change 100644 => 100755 CPAC/surface/PostFreeSurfer/FreeSurfer2CaretConvertAndRegisterNonlinear.sh mode change 100644 => 100755 CPAC/surface/PostFreeSurfer/run.sh mode change 100644 => 100755 CPAC/surface/fMRISurface/CreateDenseTimeseries.sh mode change 100644 => 100755 CPAC/surface/fMRISurface/RibbonVolumeToSurfaceMapping.sh mode change 100644 => 100755 CPAC/surface/fMRISurface/SubcorticalProcessing.sh mode change 100644 => 100755 CPAC/surface/fMRISurface/SurfaceSmoothing.sh create mode 100644 CPAC/surface/surf_preproc_old.py mode change 100644 => 100755 CPAC/surface/tests/test_config.py mode change 100644 => 100755 CPAC/timeseries/__init__.py mode change 100644 => 100755 CPAC/timeseries/timeseries_analysis.py mode change 100644 => 100755 CPAC/unet/__init__.py mode change 100644 => 100755 CPAC/unet/function.py mode change 100644 => 100755 CPAC/utils/README.txt mode change 100644 => 100755 CPAC/utils/__init__.py mode change 100644 => 100755 CPAC/utils/build_data_config.py mode change 100644 => 100755 CPAC/utils/configuration.py mode change 100644 => 100755 CPAC/utils/create_flame_model_files.py mode change 100644 => 100755 CPAC/utils/create_fsl_flame_preset.py mode change 100644 => 100755 CPAC/utils/create_fsl_model.py mode change 100644 => 100755 CPAC/utils/create_group_analysis_info_files.py mode change 100644 => 100755 CPAC/utils/datasource.py mode change 100644 => 100755 CPAC/utils/docs.py mode change 100644 => 100755 CPAC/utils/extract_data.py mode change 100644 => 100755 CPAC/utils/extract_data_multiscan.py mode change 100644 => 100755 CPAC/utils/extract_parameters.py mode change 100644 => 100755 CPAC/utils/ga.py mode change 100644 => 100755 CPAC/utils/interfaces/__init__.py mode change 100644 => 100755 CPAC/utils/interfaces/ants.py mode change 100644 => 100755 CPAC/utils/interfaces/brickstat.py mode change 100644 => 100755 CPAC/utils/interfaces/datasink.py mode change 100644 => 100755 CPAC/utils/interfaces/fixes.py mode change 100644 => 100755 CPAC/utils/interfaces/fsl.py mode change 100644 => 100755 CPAC/utils/interfaces/function/__init__.py mode change 100644 => 100755 CPAC/utils/interfaces/function/function.py mode change 100644 => 100755 CPAC/utils/interfaces/function/seg_preproc.py mode change 100644 => 100755 CPAC/utils/interfaces/masktool.py mode change 100644 => 100755 CPAC/utils/interfaces/netcorr.py mode change 100644 => 100755 CPAC/utils/interfaces/pc.py mode change 100644 => 100755 CPAC/utils/interfaces/tests/__init__.py mode change 100644 => 100755 CPAC/utils/interfaces/tests/test_fsl.py mode change 100644 => 100755 CPAC/utils/interfaces/utils.py mode change 100644 => 100755 CPAC/utils/misc.py mode change 100644 => 100755 CPAC/utils/monitoring/__init__.py mode change 100644 => 100755 CPAC/utils/monitoring/config.py mode change 100644 => 100755 CPAC/utils/monitoring/custom_logging.py mode change 100644 => 100755 CPAC/utils/monitoring/draw_gantt_chart.py mode change 100644 => 100755 CPAC/utils/monitoring/monitoring.py mode change 100644 => 100755 CPAC/utils/ndmg_utils.py mode change 100644 => 100755 CPAC/utils/nifti_utils.py mode change 100644 => 100755 CPAC/utils/outputs.py mode change 100644 => 100755 CPAC/utils/strategy.py mode change 100644 => 100755 CPAC/utils/symlinks.py mode change 100644 => 100755 CPAC/utils/test_init.py mode change 100644 => 100755 CPAC/utils/test_mocks.py mode change 100644 => 100755 CPAC/utils/test_resources.py mode change 100644 => 100755 CPAC/utils/tests/__init__.py mode change 100644 => 100755 CPAC/utils/tests/test_bids_utils.py mode change 100644 => 100755 CPAC/utils/tests/test_crash.py mode change 100644 => 100755 CPAC/utils/tests/test_datasource.py mode change 100644 => 100755 CPAC/utils/tests/test_function.py mode change 100644 => 100755 CPAC/utils/tests/test_s3.py mode change 100644 => 100755 CPAC/utils/tests/test_symlinks-outputs.txt mode change 100644 => 100755 CPAC/utils/tests/test_symlinks.py mode change 100644 => 100755 CPAC/utils/tests/test_trimmer.py mode change 100644 => 100755 CPAC/utils/tests/test_utils.py mode change 100644 => 100755 CPAC/utils/tests/test_yaml.py mode change 100644 => 100755 CPAC/utils/trimmer.py mode change 100644 => 100755 CPAC/utils/utils.py mode change 100644 => 100755 CPAC/utils/yaml_template.py mode change 100644 => 100755 CPAC/vmhc/__init__.py mode change 100644 => 100755 CPAC/vmhc/tests/test_vmhc.py mode change 100644 => 100755 CPAC/vmhc/utils.py mode change 100644 => 100755 CPAC/vmhc/vmhc.py mode change 100644 => 100755 Dockerfile mode change 100644 => 100755 README.md mode change 100644 => 100755 dev/ami_data/setup.sh mode change 100644 => 100755 dev/ami_data/setup_cpac.sh mode change 100644 => 100755 dev/circleci_data/__init__.py mode change 100644 => 100755 dev/circleci_data/data_settings_bids_examples_ds051_default_BIDS.yml mode change 100644 => 100755 dev/circleci_data/generate_run_command.py mode change 100644 => 100755 dev/circleci_data/pipe-test_ci.yml mode change 100644 => 100755 dev/circleci_data/pytest.ini mode change 100644 => 100755 dev/circleci_data/python_2_pickle.pkl mode change 100644 => 100755 dev/circleci_data/python_2_pickle.pklz mode change 100644 => 100755 dev/circleci_data/requirements.txt mode change 100644 => 100755 dev/circleci_data/test_external_utils.py mode change 100644 => 100755 dev/circleci_data/test_install.py mode change 100644 => 100755 dev/docker_data/default_pipeline.yml mode change 100644 => 100755 dev/docker_data/license.txt mode change 100644 => 100755 dev/docker_data/required_afni_pkgs.txt mode change 100644 => 100755 dev/docker_data/required_freesurfer_pkgs.txt mode change 100644 => 100755 dev/rc_tests/README.md mode change 100644 => 100755 requirements.txt mode change 100644 => 100755 scripts/cpac mode change 100644 => 100755 variant-ABCD-HCP.Dockerfile mode change 100644 => 100755 variant-fMRIPrep-LTS.Dockerfile mode change 100644 => 100755 variant-lite.Dockerfile mode change 100644 => 100755 version diff --git a/.circleci/config.yml b/.circleci/config.yml old mode 100644 new mode 100755 diff --git a/.circleci/main.yml b/.circleci/main.yml old mode 100644 new mode 100755 diff --git a/.dockerignore b/.dockerignore old mode 100644 new mode 100755 diff --git a/.flake8 b/.flake8 old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile b/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile b/.github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/AFNI.update.afni.binaries-bionic.Dockerfile b/.github/Dockerfiles/AFNI.update.afni.binaries-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile b/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile b/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile b/.github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile b/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/ICA-AROMA.0.4.3-beta-bionic.Dockerfile b/.github/Dockerfiles/ICA-AROMA.0.4.3-beta-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile b/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile b/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile b/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile b/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile b/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/msm.2.0-bionic.Dockerfile b/.github/Dockerfiles/msm.2.0-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/Dockerfiles/neuroparc.1.0-human-bionic.Dockerfile b/.github/Dockerfiles/neuroparc.1.0-human-bionic.Dockerfile old mode 100644 new mode 100755 diff --git a/.github/scripts/get_package_id.py b/.github/scripts/get_package_id.py old mode 100644 new mode 100755 diff --git a/.github/scripts/get_pr_base_shas.py b/.github/scripts/get_pr_base_shas.py old mode 100644 new mode 100755 diff --git a/.github/scripts/minify-freesurfer-6.0.1.sh b/.github/scripts/minify-freesurfer-6.0.1.sh old mode 100644 new mode 100755 diff --git a/.github/stage_requirements/ABCD-HCP.txt b/.github/stage_requirements/ABCD-HCP.txt old mode 100644 new mode 100755 diff --git a/.github/stage_requirements/fMRIPrep-LTS.txt b/.github/stage_requirements/fMRIPrep-LTS.txt old mode 100644 new mode 100755 diff --git a/.github/stage_requirements/standard.txt b/.github/stage_requirements/standard.txt old mode 100644 new mode 100755 diff --git a/.github/workflows/build_C-PAC.yml b/.github/workflows/build_C-PAC.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/build_stages.yml b/.github/workflows/build_stages.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/check_updated_version.yml b/.github/workflows/check_updated_version.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/delete_images.yml b/.github/workflows/delete_images.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/deploy_to_Docker_Hub.yml b/.github/workflows/deploy_to_Docker_Hub.yml old mode 100644 new mode 100755 diff --git a/.github/workflows/smoke_test_participant.yml b/.github/workflows/smoke_test_participant.yml old mode 100644 new mode 100755 diff --git a/.pylintrc b/.pylintrc old mode 100644 new mode 100755 diff --git a/.vscode/run_nose.py b/.vscode/run_nose.py old mode 100644 new mode 100755 diff --git a/.vscode/settings.json b/.vscode/settings.json old mode 100644 new mode 100755 diff --git a/CHANGELOG.md b/CHANGELOG.md old mode 100644 new mode 100755 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100644 new mode 100755 diff --git a/COPYING b/COPYING old mode 100644 new mode 100755 diff --git a/COPYING.LESSER b/COPYING.LESSER old mode 100644 new mode 100755 diff --git a/CPAC/GUI/resources/html/_static/cpac_logo.jpg b/CPAC/GUI/resources/html/_static/cpac_logo.jpg old mode 100644 new mode 100755 diff --git a/CPAC/GUI/resources/html/_static/nature.css b/CPAC/GUI/resources/html/_static/nature.css old mode 100644 new mode 100755 diff --git a/CPAC/GUI/resources/html/_static/pygments.css b/CPAC/GUI/resources/html/_static/pygments.css old mode 100644 new mode 100755 diff --git a/CPAC/__init__.py b/CPAC/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/__main__.py b/CPAC/__main__.py old mode 100644 new mode 100755 diff --git a/CPAC/alff/__init__.py b/CPAC/alff/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/alff/alff.py b/CPAC/alff/alff.py old mode 100644 new mode 100755 diff --git a/CPAC/alff/utils.py b/CPAC/alff/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/__init__.py b/CPAC/anat_preproc/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/ants.py b/CPAC/anat_preproc/ants.py old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_precise.json b/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_precise.json old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_testing.json b/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_testing.json old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/data/antsBrainExtraction_precise.json b/CPAC/anat_preproc/data/antsBrainExtraction_precise.json old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/data/antsBrainExtraction_testing.json b/CPAC/anat_preproc/data/antsBrainExtraction_testing.json old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/lesion_preproc.py b/CPAC/anat_preproc/lesion_preproc.py old mode 100644 new mode 100755 diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/aroma/__init__.py b/CPAC/aroma/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/aroma/aroma.py b/CPAC/aroma/aroma.py old mode 100644 new mode 100755 diff --git a/CPAC/aroma/aroma_test.py b/CPAC/aroma/aroma_test.py old mode 100644 new mode 100755 diff --git a/CPAC/connectome/__init__.py b/CPAC/connectome/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/connectome/connectivity_matrix.py b/CPAC/connectome/connectivity_matrix.py old mode 100644 new mode 100755 diff --git a/CPAC/connectome/test/test_connectome.py b/CPAC/connectome/test/test_connectome.py old mode 100644 new mode 100755 diff --git a/CPAC/cwas/__init__.py b/CPAC/cwas/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/cwas/cwas.py b/CPAC/cwas/cwas.py old mode 100644 new mode 100755 diff --git a/CPAC/cwas/mdmr.py b/CPAC/cwas/mdmr.py old mode 100644 new mode 100755 diff --git a/CPAC/cwas/pipeline.py b/CPAC/cwas/pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/cwas/tests/X.csv b/CPAC/cwas/tests/X.csv old mode 100644 new mode 100755 diff --git a/CPAC/cwas/tests/Y.csv b/CPAC/cwas/tests/Y.csv old mode 100644 new mode 100755 diff --git a/CPAC/cwas/tests/test_mdmr_cython.py b/CPAC/cwas/tests/test_mdmr_cython.py old mode 100644 new mode 100755 diff --git a/CPAC/cwas/tests/test_pipeline_cwas.py b/CPAC/cwas/tests/test_pipeline_cwas.py old mode 100644 new mode 100755 diff --git a/CPAC/distortion_correction/__init__.py b/CPAC/distortion_correction/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/distortion_correction/distortion_correction.py b/CPAC/distortion_correction/distortion_correction.py old mode 100644 new mode 100755 diff --git a/CPAC/distortion_correction/tests/__init__.py b/CPAC/distortion_correction/tests/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/distortion_correction/tests/test_distortion_correction.py b/CPAC/distortion_correction/tests/test_distortion_correction.py old mode 100644 new mode 100755 diff --git a/CPAC/distortion_correction/utils.py b/CPAC/distortion_correction/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/easy_thresh/__init__.py b/CPAC/easy_thresh/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/easy_thresh/easy_thresh.py b/CPAC/easy_thresh/easy_thresh.py old mode 100644 new mode 100755 diff --git a/CPAC/func_preproc/__init__.py b/CPAC/func_preproc/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/func_preproc/func_ingress.py b/CPAC/func_preproc/func_ingress.py old mode 100644 new mode 100755 diff --git a/CPAC/func_preproc/func_preproc.py b/CPAC/func_preproc/func_preproc.py old mode 100644 new mode 100755 diff --git a/CPAC/func_preproc/utils.py b/CPAC/func_preproc/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/generate_motion_statistics/__init__.py b/CPAC/generate_motion_statistics/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/generate_motion_statistics/generate_motion_statistics.py b/CPAC/generate_motion_statistics/generate_motion_statistics.py old mode 100644 new mode 100755 diff --git a/CPAC/generate_motion_statistics/test/test_dvars.py b/CPAC/generate_motion_statistics/test/test_dvars.py old mode 100644 new mode 100755 diff --git a/CPAC/group_analysis/__init__.py b/CPAC/group_analysis/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/group_analysis/group_analysis.py b/CPAC/group_analysis/group_analysis.py old mode 100644 new mode 100755 diff --git a/CPAC/image_utils/__init__.py b/CPAC/image_utils/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/image_utils/spatial_smoothing.py b/CPAC/image_utils/spatial_smoothing.py old mode 100644 new mode 100755 diff --git a/CPAC/image_utils/statistical_transforms.py b/CPAC/image_utils/statistical_transforms.py old mode 100644 new mode 100755 diff --git a/CPAC/image_utils/tests/test_smooth.py b/CPAC/image_utils/tests/test_smooth.py old mode 100644 new mode 100755 diff --git a/CPAC/info.py b/CPAC/info.py old mode 100644 new mode 100755 diff --git a/CPAC/isc/__init__.py b/CPAC/isc/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/isc/isc.py b/CPAC/isc/isc.py old mode 100644 new mode 100755 diff --git a/CPAC/isc/isfc.py b/CPAC/isc/isfc.py old mode 100644 new mode 100755 diff --git a/CPAC/isc/pipeline.py b/CPAC/isc/pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/isc/tests/test_pipeline_isc.py b/CPAC/isc/tests/test_pipeline_isc.py old mode 100644 new mode 100755 diff --git a/CPAC/isc/utils.py b/CPAC/isc/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/longitudinal_pipeline/longitudinal_preproc.py b/CPAC/longitudinal_pipeline/longitudinal_preproc.py old mode 100644 new mode 100755 diff --git a/CPAC/longitudinal_pipeline/longitudinal_workflow.py b/CPAC/longitudinal_pipeline/longitudinal_workflow.py old mode 100644 new mode 100755 diff --git a/CPAC/median_angle/median_angle.py b/CPAC/median_angle/median_angle.py old mode 100644 new mode 100755 diff --git a/CPAC/network_centrality/__init__.py b/CPAC/network_centrality/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/network_centrality/network_centrality.py b/CPAC/network_centrality/network_centrality.py old mode 100644 new mode 100755 diff --git a/CPAC/network_centrality/pipeline.py b/CPAC/network_centrality/pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/network_centrality/utils.py b/CPAC/network_centrality/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/__init__.py b/CPAC/nuisance/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/bandpass.py b/CPAC/nuisance/bandpass.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/nuisance.py b/CPAC/nuisance/nuisance.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/tests/motion_statistics/DVARS.1D b/CPAC/nuisance/tests/motion_statistics/DVARS.1D old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/tests/motion_statistics/FD_J.1D b/CPAC/nuisance/tests/motion_statistics/FD_J.1D old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/tests/motion_statistics/FD_P.1D b/CPAC/nuisance/tests/motion_statistics/FD_P.1D old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/tests/test_nuisance_representations.py b/CPAC/nuisance/tests/test_nuisance_representations.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/tests/test_utils.py b/CPAC/nuisance/tests/test_utils.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/utils/__init__.py b/CPAC/nuisance/utils/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/utils/compcor.py b/CPAC/nuisance/utils/compcor.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/utils/convolve.py b/CPAC/nuisance/utils/convolve.py old mode 100644 new mode 100755 diff --git a/CPAC/nuisance/utils/crc.py b/CPAC/nuisance/utils/crc.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/__init__.py b/CPAC/pipeline/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/check_outputs.py b/CPAC/pipeline/check_outputs.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/cpac_basc_pipeline.py b/CPAC/pipeline/cpac_basc_pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/cpac_cwas_pipeline.py b/CPAC/pipeline/cpac_cwas_pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/cpac_group_runner.py b/CPAC/pipeline/cpac_group_runner.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/cpac_randomise_pipeline.py b/CPAC/pipeline/cpac_randomise_pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/cpac_runner.py b/CPAC/pipeline/cpac_runner.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py old mode 100644 new mode 100755 index 6613fcf557..7325c31943 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -993,7 +993,8 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): warnings.warn(str( LookupError("\n[!] No atlas ID found for " f"{out_dct['filename']}.\n"))) - + #print(resource) + #print(pipe_idx) nii_name = pe.Node(Rename(), name=f'nii_{resource_idx}_' f'{pipe_x}') nii_name.inputs.keep_ext = True @@ -1001,6 +1002,8 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): nii_name, 'format_string') node, out = self.rpool[resource][pipe_idx]['data'] + print(node) + #print(out) try: wf.connect(node, out, nii_name, 'in_file') except OSError as os_error: diff --git a/CPAC/pipeline/nipype_pipeline_engine/__init__.py b/CPAC/pipeline/nipype_pipeline_engine/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/nipype_pipeline_engine/engine.py b/CPAC/pipeline/nipype_pipeline_engine/engine.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/__init__.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/legacymultiproc.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/legacymultiproc.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/multiproc.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/multiproc.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/random_state/__init__.py b/CPAC/pipeline/random_state/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/random_state/seed.py b/CPAC/pipeline/random_state/seed.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/__init__.py b/CPAC/pipeline/test/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/issue_1606_data_config.yml b/CPAC/pipeline/test/issue_1606_data_config.yml old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/sample_data.py b/CPAC/pipeline/test/sample_data.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/test_cpac_group_runner.py b/CPAC/pipeline/test/test_cpac_group_runner.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/test_cpac_pipeline.py b/CPAC/pipeline/test/test_cpac_pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/test_cpac_runner.py b/CPAC/pipeline/test/test_cpac_runner.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/test_engine.py b/CPAC/pipeline/test/test_engine.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/test_nipype_pipeline_engine.py b/CPAC/pipeline/test/test_nipype_pipeline_engine.py old mode 100644 new mode 100755 diff --git a/CPAC/pipeline/test/test_schema_validation.py b/CPAC/pipeline/test/test_schema_validation.py old mode 100644 new mode 100755 diff --git a/CPAC/pypeer/__init__.py b/CPAC/pypeer/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/pypeer/peer.py b/CPAC/pypeer/peer.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/__init__.py b/CPAC/qc/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/colors/blue.txt b/CPAC/qc/colors/blue.txt old mode 100644 new mode 100755 diff --git a/CPAC/qc/colors/cyan_to_yellow.txt b/CPAC/qc/colors/cyan_to_yellow.txt old mode 100644 new mode 100755 diff --git a/CPAC/qc/colors/green.txt b/CPAC/qc/colors/green.txt old mode 100644 new mode 100755 diff --git a/CPAC/qc/colors/red.txt b/CPAC/qc/colors/red.txt old mode 100644 new mode 100755 diff --git a/CPAC/qc/colors/red_to_blue.txt b/CPAC/qc/colors/red_to_blue.txt old mode 100644 new mode 100755 diff --git a/CPAC/qc/data/index.html b/CPAC/qc/data/index.html old mode 100644 new mode 100755 diff --git a/CPAC/qc/pipeline.py b/CPAC/qc/pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/qc.py b/CPAC/qc/qc.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/qcmetrics.py b/CPAC/qc/qcmetrics.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/tests/test_qc.py b/CPAC/qc/tests/test_qc.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/utils.py b/CPAC/qc/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/qc/xcp.py b/CPAC/qc/xcp.py old mode 100644 new mode 100755 diff --git a/CPAC/qpp/__init__.py b/CPAC/qpp/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/qpp/pipeline.py b/CPAC/qpp/pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/qpp/qpp.py b/CPAC/qpp/qpp.py old mode 100644 new mode 100755 diff --git a/CPAC/qpp/tests/test_qpp.py b/CPAC/qpp/tests/test_qpp.py old mode 100644 new mode 100755 diff --git a/CPAC/randomise/__init__.py b/CPAC/randomise/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/randomise/pipeline.py b/CPAC/randomise/pipeline.py old mode 100644 new mode 100755 diff --git a/CPAC/randomise/randomise.py b/CPAC/randomise/randomise.py old mode 100644 new mode 100755 diff --git a/CPAC/randomise/test_randomise.py b/CPAC/randomise/test_randomise.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/__init__.py b/CPAC/registration/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/output_func_to_standard.py b/CPAC/registration/output_func_to_standard.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/registration.py b/CPAC/registration/registration.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/tests/__init__.py b/CPAC/registration/tests/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/tests/mocks.py b/CPAC/registration/tests/mocks.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/tests/test_ants_apply_warp.py b/CPAC/registration/tests/test_ants_apply_warp.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/tests/test_apply_transform.py b/CPAC/registration/tests/test_apply_transform.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/tests/test_output_func_to_standard.py b/CPAC/registration/tests/test_output_func_to_standard.py old mode 100644 new mode 100755 diff --git a/CPAC/registration/utils.py b/CPAC/registration/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/reho/__init__.py b/CPAC/reho/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/reho/reho.py b/CPAC/reho/reho.py old mode 100644 new mode 100755 diff --git a/CPAC/reho/utils.py b/CPAC/reho/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/resources/MSMConfig/MSMSulcStrainFinalconf b/CPAC/resources/MSMConfig/MSMSulcStrainFinalconf old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/1.7-1.8-deprecations.yml b/CPAC/resources/configs/1.7-1.8-deprecations.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/1.7-1.8-nesting-mappings.yml b/CPAC/resources/configs/1.7-1.8-nesting-mappings.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/ADHD200_participants.csv b/CPAC/resources/configs/test_configs/ADHD200_participants.csv old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/ADHD200_participants_age.tsv b/CPAC/resources/configs/test_configs/ADHD200_participants_age.tsv old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/data-test_human.yml b/CPAC/resources/configs/test_configs/data-test_human.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml old mode 100644 new mode 100755 diff --git a/CPAC/resources/cpac_templates.csv b/CPAC/resources/cpac_templates.csv old mode 100644 new mode 100755 diff --git a/CPAC/resources/global/scripts/log.shlib b/CPAC/resources/global/scripts/log.shlib old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii b/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/ndmg_atlases.csv b/CPAC/resources/templates/ndmg_atlases.csv old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_probseg.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_probseg.nii.gz old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz old mode 100644 new mode 100755 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz old mode 100644 new mode 100755 diff --git a/CPAC/sca/README.txt b/CPAC/sca/README.txt old mode 100644 new mode 100755 diff --git a/CPAC/sca/__init__.py b/CPAC/sca/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/sca/sca.py b/CPAC/sca/sca.py old mode 100644 new mode 100755 diff --git a/CPAC/sca/utils.py b/CPAC/sca/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/scrubbing/__init__.py b/CPAC/scrubbing/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/scrubbing/scrubbing.py b/CPAC/scrubbing/scrubbing.py old mode 100644 new mode 100755 diff --git a/CPAC/seg_preproc/__init__.py b/CPAC/seg_preproc/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/seg_preproc/utils.py b/CPAC/seg_preproc/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/surface/PostFreeSurfer/FreeSurfer2CaretConvertAndRegisterNonlinear.sh b/CPAC/surface/PostFreeSurfer/FreeSurfer2CaretConvertAndRegisterNonlinear.sh old mode 100644 new mode 100755 diff --git a/CPAC/surface/PostFreeSurfer/run.sh b/CPAC/surface/PostFreeSurfer/run.sh old mode 100644 new mode 100755 diff --git a/CPAC/surface/fMRISurface/CreateDenseTimeseries.sh b/CPAC/surface/fMRISurface/CreateDenseTimeseries.sh old mode 100644 new mode 100755 diff --git a/CPAC/surface/fMRISurface/RibbonVolumeToSurfaceMapping.sh b/CPAC/surface/fMRISurface/RibbonVolumeToSurfaceMapping.sh old mode 100644 new mode 100755 diff --git a/CPAC/surface/fMRISurface/SubcorticalProcessing.sh b/CPAC/surface/fMRISurface/SubcorticalProcessing.sh old mode 100644 new mode 100755 diff --git a/CPAC/surface/fMRISurface/SurfaceSmoothing.sh b/CPAC/surface/fMRISurface/SurfaceSmoothing.sh old mode 100644 new mode 100755 diff --git a/CPAC/surface/surf_preproc_old.py b/CPAC/surface/surf_preproc_old.py new file mode 100644 index 0000000000..982345554a --- /dev/null +++ b/CPAC/surface/surf_preproc_old.py @@ -0,0 +1,376 @@ +from logging import raiseExceptions +import os +import nipype.interfaces.utility as util +from CPAC.utils.interfaces.function import Function +from CPAC.pipeline import nipype_pipeline_engine as pe + + + +def run_surface(post_freesurfer_folder, + freesurfer_folder, + subject, + t1w_restore_image, + atlas_space_t1w_image, + atlas_transform, + inverse_atlas_transform, + atlas_space_bold, + scout_bold, + surf_atlas_dir, + gray_ordinates_dir, + gray_ordinates_res, + high_res_mesh, + low_res_mesh, + subcortical_gray_labels, + freesurfer_labels, + fmri_res, + smooth_fwhm): + """ + Returns + ------- + dtseries : str + Path to the dtseries file. + + desikan_killiany : str + Path to the Desikan-Killiany parcellation file. + + destrieux : str + Path to the Destrieux parcellation file. + """ + + import os + import subprocess + + freesurfer_folder = os.path.join(freesurfer_folder, 'recon_all') + + # DCAN-HCP PostFreeSurfer + # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/run.sh', '--post_freesurfer_folder', post_freesurfer_folder, \ + '--freesurfer_folder', freesurfer_folder, '--subject', subject, \ + '--t1w_restore', t1w_restore_image, '--atlas_t1w', atlas_space_t1w_image, \ + '--atlas_transform', atlas_transform, '--inverse_atlas_transform', inverse_atlas_transform, \ + '--surfatlasdir', surf_atlas_dir, '--grayordinatesdir', gray_ordinates_dir, '--grayordinatesres', gray_ordinates_res, \ + '--hiresmesh', high_res_mesh, '--lowresmesh', low_res_mesh, \ + '--subcortgraylabels', subcortical_gray_labels, '--freesurferlabels', freesurfer_labels] + + subprocess.check_output(cmd) + + # DCAN-HCP fMRISurface + # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRISurface/GenericfMRISurfaceProcessingPipeline.sh + cmd = ['bash', '/code/CPAC/surface/fMRISurface/run.sh', + '--post_freesurfer_folder', post_freesurfer_folder, + '--subject', subject, '--fmri', atlas_space_bold, '--scout', + scout_bold, '--lowresmesh', low_res_mesh, '--grayordinatesres', + gray_ordinates_res, '--fmrires', fmri_res, '--smoothingFWHM', + smooth_fwhm] + subprocess.check_output(cmd) + + dtseries = os.path.join(post_freesurfer_folder, + 'MNINonLinear/Results/task-rest01/' + 'task-rest01_Atlas.dtseries.nii') + aparc = {'desikan_killiany': { + 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', + f'{subject}.aparc.164k_fs_LR.dlabel.nii'), + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.aparc.32k_fs_LR.dlabel.nii')}, + 'destrieux': { + 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', + f'{subject}.aparc.a2009s.164k_fs_LR.dlabel.nii'), + 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', + 'fsaverage_LR32k', + f'{subject}.aparc.a2009s.32k_fs_LR.dlabel.nii')}} + + return (dtseries, aparc['desikan_killiany'][164], aparc['destrieux'][164], + aparc['desikan_killiany'][32], aparc['destrieux'][32]) + + +def surface_connector(wf, cfg, strat_pool, pipe_num, opt): + + surf = pe.Node(util.Function(input_names=['post_freesurfer_folder', + 'freesurfer_folder', + 'subject', + 't1w_restore_image', + 'atlas_space_t1w_image', + 'atlas_transform', + 'inverse_atlas_transform', + 'atlas_space_bold', + 'scout_bold', + 'surf_atlas_dir', + 'gray_ordinates_dir', + 'gray_ordinates_res', + 'high_res_mesh', + 'low_res_mesh', + 'subcortical_gray_labels', + 'freesurfer_labels', + 'fmri_res', + 'smooth_fwhm'], + output_names=['dtseries', + 'desikan_killiany_164', + 'destrieux_164', + 'desikan_killiany_32', + 'destrieux_32', + ], + function=run_surface), + name=f'post_freesurfer_{pipe_num}') + + surf.inputs.subject = cfg['subject_id'] + + surf.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + 'cpac_'+cfg['subject_id'], + f'post_freesurfer_{pipe_num}') + + surf.inputs.surf_atlas_dir = cfg.surface_analysis['post_freesurfer']['surf_atlas_dir'] + surf.inputs.gray_ordinates_dir = cfg.surface_analysis['post_freesurfer']['gray_ordinates_dir'] + surf.inputs.subcortical_gray_labels = cfg.surface_analysis['post_freesurfer']['subcortical_gray_labels'] + surf.inputs.freesurfer_labels = cfg.surface_analysis['post_freesurfer']['freesurfer_labels'] + + # convert integers to strings as subprocess requires string inputs + surf.inputs.gray_ordinates_res = str(cfg.surface_analysis['post_freesurfer']['gray_ordinates_res']) + surf.inputs.high_res_mesh = str(cfg.surface_analysis['post_freesurfer']['high_res_mesh']) + surf.inputs.low_res_mesh = str(cfg.surface_analysis['post_freesurfer']['low_res_mesh']) + surf.inputs.fmri_res = str(cfg.surface_analysis['post_freesurfer']['fmri_res']) + surf.inputs.smooth_fwhm = str(cfg.surface_analysis['post_freesurfer']['smooth_fwhm']) + + restore = ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", + "space-longitudinal_desc-reorient_T1w"] + space_temp = ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask",] + atlas_xfm = ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"] + atlas_xfm_inv = ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"] + atlas_space_bold = ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"] + scout_bold = ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", + "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"] + + + node, out = strat_pool.get_data('freesurfer-subject-dir') + wf.connect(node, out, surf, 'freesurfer_folder') + + node, out = strat_pool.get_data(restore) + wf.connect(node, out, surf, 't1w_restore_image') + + node, out = strat_pool.get_data(space_temp) + wf.connect(node, out, surf, 'atlas_space_t1w_image') + + node, out = strat_pool.get_data(atlas_xfm) + wf.connect(node, out, surf, 'atlas_transform') + + node, out = strat_pool.get_data(atlas_xfm_inv) + wf.connect(node, out, surf, 'inverse_atlas_transform') + + node, out = strat_pool.get_data(atlas_space_bold) + wf.connect(node, out, surf, 'atlas_space_bold') + + node, out = strat_pool.get_data(scout_bold) + wf.connect(node, out, surf, 'scout_bold') + + falff = pe.Node(util.Function(input_names=['dtseries'], + output_names=['falff'], + function=run_surf_falff), + name=f'surf_falff_{pipe_num}') + + + wf.connect(surf, 'dtseries', falff, 'dtseries') + + #alff = pe.Node(util.Function(input_names=['dtseries'], + # output_names=['alff'], + # function=run_surf_alff), + # name=f'surf_alff_{pipe_num}') + + + #wf.connect(surf, 'dtseries', alff, 'dtseries') + + + outputs = { + 'atlas-DesikanKilliany_space-fsLR_den-32k_dlabel': (surf, + 'desikan_' + 'killiany_32'), + 'atlas-Destrieux_space-fsLR_den-32k_dlabel': (surf, 'destrieux_32'), + 'atlas-DesikanKilliany_space-fsLR_den-164k_dlabel': (surf, + 'desikan_' + 'killiany_164'), + 'atlas-Destrieux_space-fsLR_den-164k_dlabel': (surf, 'destrieux_164'), + 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries'), + 'falff-surf_dscalar': (falff, 'falff'), + #'alff-surf_dscalar': (alff, 'alff') + + + } + + + + + # L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], + # output_names=['L_cortex_file'], + # function=run_get_cortex), + # name=f'L_surf_cortex_{pipe_num}') + + # L_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # L_cortex_file.inputs.structure = "LEFT" + # L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" + # wf.connect(surf, 'dtseries', L_cortex_file, 'dtseries') + + # R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], + # output_names=['R_cortex_file'], + # function=run_get_cortex), + # name=f'R_surf_cortex_{pipe_num}') + + # R_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # R_cortex_file.inputs.structure = "RIGHT" + # R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" + # wf.connect(surf, 'dtseries', R_cortex_file, 'dtseries') + + + # mean_timeseries = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'dtseries'], + # output_names=['mean_timeseries'], + # function=run_mean_timeseries), + # name=f'mean_timeseries_{pipe_num}') + + # mean_timeseries.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # wf.connect(surf, 'dtseries', mean_timeseries, 'dtseries') + + + # L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', + # 'post_freesurfer_folder', 'reho_filename'], + # output_names=['L_reho'], + # function=run_surf_reho), + # name=f'surf_reho{pipe_num}') + + # wf.connect(get_L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') + # wf.connect(surf, 'L_surface_file', L_reho, 'surface_file') + # wf.connect(surf, 'L_mask', L_reho, 'mask') + # wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') + # L_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # L_reho.inputs.reho_filename = L_surf_reho.dscalar.nii + + # R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', + # 'post_freesurfer_folder', 'reho_filename'], + # output_names=['R_reho'], + # function=run_surf_reho), + # name=f'surf_reho{pipe_num}') + + # wf.connect(get_R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') + # wf.connect(surf, 'R_surface_file', R_reho, 'surface_file') + # wf.connect(surf, 'R_mask', R_reho, 'mask') + # wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') + # R_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + # 'cpac_'+cfg['subject_id'], + # f'post_freesurfer_{pipe_num}') + # R_reho.inputs.reho_filename = R_surf_reho.dscalar.nii + + + + # connectivity_parcellation = pe.Node(util.Function(input_names=['dtseries', 'surf_atlaslabel', + # 'post_freesurfer_folder'], + # output_names=['parcellation_file'], + # function=run_ciftiparcellate), + # name=f'connectivity_parcellation{pipe_num}') + + + # wf.connect(surf, 'dtseries', connectivity, 'dtseries') + # connectivity_parcellation.inputs.surf_atlaslabel = ## path to the label file + + # correlation_matrix = pe.Node(util.Function(input_names=['ptseries','post_freesurfer_folder'], + # output_names=['correlation_matrix'], + # function=run_cifticorrelation), + # name=f'correlation_matrix{pipe_num}') + + + # wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix 'ptseries') + + return wf, outputs + +def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "surface_preproc", + "config": ["surface_analysis", "post_freesurfer"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["freesurfer-subject-dir", + ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", + "space-longitudinal_desc-reorient_T1w"], + ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask"], + ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"], + ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"], + ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], + ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", + "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"]], + "outputs": ["atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", + "atlas-Destrieux_space-fsLR_den-32k_dlabel", + "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", + "atlas-Destrieux_space-fsLR_den-164k_dlabel", + "space-fsLR_den-32k_bold-dtseries", + "falff-surf_dscalar", + "alff-surf_dscalar"]} + ''' + wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) + + return (wf, outputs) + + +def run_surf_falff(dtseries): + import os + import subprocess + falff = os.path.join(os.getcwd(), 'falff_surf.nii.gz') + cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] + subprocess.check_output(cmd) + return falff + + +#def run_surf_alff(dtseries): +# import os +# import subprocess +# alff = os.path.join(os.getcwd(), 'alff_surf.dscalar.nii.gz') +# cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] +# subprocess.check_output(cmd) +# return alff + +#cmd = ['ciftify_falff', dtseries , 'alff_surf.dscalar.nii', '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] +# def run_get_cortex(dtseries, structure, post_freesurfer_folder, cortex_filename): +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_filename] +# subprocess.check_output(cmd) +# cortex_file = os.path.join(post_freesurfer_folder, cortex_filename) +# return cortex_file + +# def run_mean_timeseries(dtseries,post_freesurfer_folder): + +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', 'mean.dscalar.nii'] +# subprocess.check_output(cmd) +# mean_timeseries = os.path.join(post_freesurfer_folder, mean.dscalar.nii) +# return mean_timeseries + +# def run_surf_reho(dtseries, mask, cortex_file, surface_file,mean_timeseries,post_freesurfer_folder, reho_filename): + +# import os +# import subprocess +# cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, reho_filename] +# subprocess.check_output(cmd) +# surf_reho = os.path.join(post_freesurfer_folder, reho_filename) +# return surf_reho + +# def run_ciftiparcellate(dtseries, surf_atlaslabel): +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', 'parcellation.ptseries.nii'] +# subprocess.check_output(cmd) +# parcellation_file = os.path.join(post_freesurfer_folder, 'parcellation.ptseries.nii') +# return parcellation_file + +# def run_cifticorrelation(ptseries): +# import os +# import subprocess +# cmd = ['wb_command', '-cifti-correlation ', ptseries , 'cifti_corr.pconn.nii'] +# subprocess.check_output(cmd) +# correlation_matrix = os.path.join(post_freesurfer_folder, 'cifti_corr.pconn.nii') +# return correlation_matrix diff --git a/CPAC/surface/tests/test_config.py b/CPAC/surface/tests/test_config.py old mode 100644 new mode 100755 diff --git a/CPAC/timeseries/__init__.py b/CPAC/timeseries/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/timeseries/timeseries_analysis.py b/CPAC/timeseries/timeseries_analysis.py old mode 100644 new mode 100755 diff --git a/CPAC/unet/__init__.py b/CPAC/unet/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/unet/function.py b/CPAC/unet/function.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/README.txt b/CPAC/utils/README.txt old mode 100644 new mode 100755 diff --git a/CPAC/utils/__init__.py b/CPAC/utils/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/build_data_config.py b/CPAC/utils/build_data_config.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/configuration.py b/CPAC/utils/configuration.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/create_flame_model_files.py b/CPAC/utils/create_flame_model_files.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/create_fsl_flame_preset.py b/CPAC/utils/create_fsl_flame_preset.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/create_fsl_model.py b/CPAC/utils/create_fsl_model.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/create_group_analysis_info_files.py b/CPAC/utils/create_group_analysis_info_files.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/datasource.py b/CPAC/utils/datasource.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/docs.py b/CPAC/utils/docs.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/extract_data.py b/CPAC/utils/extract_data.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/extract_data_multiscan.py b/CPAC/utils/extract_data_multiscan.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/extract_parameters.py b/CPAC/utils/extract_parameters.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/ga.py b/CPAC/utils/ga.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/__init__.py b/CPAC/utils/interfaces/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/ants.py b/CPAC/utils/interfaces/ants.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/brickstat.py b/CPAC/utils/interfaces/brickstat.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/datasink.py b/CPAC/utils/interfaces/datasink.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/fixes.py b/CPAC/utils/interfaces/fixes.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/fsl.py b/CPAC/utils/interfaces/fsl.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/function/__init__.py b/CPAC/utils/interfaces/function/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/function/function.py b/CPAC/utils/interfaces/function/function.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/function/seg_preproc.py b/CPAC/utils/interfaces/function/seg_preproc.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/masktool.py b/CPAC/utils/interfaces/masktool.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/netcorr.py b/CPAC/utils/interfaces/netcorr.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/pc.py b/CPAC/utils/interfaces/pc.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/tests/__init__.py b/CPAC/utils/interfaces/tests/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/tests/test_fsl.py b/CPAC/utils/interfaces/tests/test_fsl.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/interfaces/utils.py b/CPAC/utils/interfaces/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/misc.py b/CPAC/utils/misc.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/monitoring/__init__.py b/CPAC/utils/monitoring/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/monitoring/config.py b/CPAC/utils/monitoring/config.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/monitoring/custom_logging.py b/CPAC/utils/monitoring/custom_logging.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/monitoring/draw_gantt_chart.py b/CPAC/utils/monitoring/draw_gantt_chart.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/monitoring/monitoring.py b/CPAC/utils/monitoring/monitoring.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/ndmg_utils.py b/CPAC/utils/ndmg_utils.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/nifti_utils.py b/CPAC/utils/nifti_utils.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/outputs.py b/CPAC/utils/outputs.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/strategy.py b/CPAC/utils/strategy.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/symlinks.py b/CPAC/utils/symlinks.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/test_init.py b/CPAC/utils/test_init.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/test_mocks.py b/CPAC/utils/test_mocks.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/test_resources.py b/CPAC/utils/test_resources.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/__init__.py b/CPAC/utils/tests/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_bids_utils.py b/CPAC/utils/tests/test_bids_utils.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_crash.py b/CPAC/utils/tests/test_crash.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_datasource.py b/CPAC/utils/tests/test_datasource.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_function.py b/CPAC/utils/tests/test_function.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_s3.py b/CPAC/utils/tests/test_s3.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_symlinks-outputs.txt b/CPAC/utils/tests/test_symlinks-outputs.txt old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_symlinks.py b/CPAC/utils/tests/test_symlinks.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_trimmer.py b/CPAC/utils/tests/test_trimmer.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_utils.py b/CPAC/utils/tests/test_utils.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/tests/test_yaml.py b/CPAC/utils/tests/test_yaml.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/trimmer.py b/CPAC/utils/trimmer.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/utils/yaml_template.py b/CPAC/utils/yaml_template.py old mode 100644 new mode 100755 diff --git a/CPAC/vmhc/__init__.py b/CPAC/vmhc/__init__.py old mode 100644 new mode 100755 diff --git a/CPAC/vmhc/tests/test_vmhc.py b/CPAC/vmhc/tests/test_vmhc.py old mode 100644 new mode 100755 diff --git a/CPAC/vmhc/utils.py b/CPAC/vmhc/utils.py old mode 100644 new mode 100755 diff --git a/CPAC/vmhc/vmhc.py b/CPAC/vmhc/vmhc.py old mode 100644 new mode 100755 diff --git a/Dockerfile b/Dockerfile old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/dev/ami_data/setup.sh b/dev/ami_data/setup.sh old mode 100644 new mode 100755 diff --git a/dev/ami_data/setup_cpac.sh b/dev/ami_data/setup_cpac.sh old mode 100644 new mode 100755 diff --git a/dev/circleci_data/__init__.py b/dev/circleci_data/__init__.py old mode 100644 new mode 100755 diff --git a/dev/circleci_data/data_settings_bids_examples_ds051_default_BIDS.yml b/dev/circleci_data/data_settings_bids_examples_ds051_default_BIDS.yml old mode 100644 new mode 100755 diff --git a/dev/circleci_data/generate_run_command.py b/dev/circleci_data/generate_run_command.py old mode 100644 new mode 100755 diff --git a/dev/circleci_data/pipe-test_ci.yml b/dev/circleci_data/pipe-test_ci.yml old mode 100644 new mode 100755 diff --git a/dev/circleci_data/pytest.ini b/dev/circleci_data/pytest.ini old mode 100644 new mode 100755 diff --git a/dev/circleci_data/python_2_pickle.pkl b/dev/circleci_data/python_2_pickle.pkl old mode 100644 new mode 100755 diff --git a/dev/circleci_data/python_2_pickle.pklz b/dev/circleci_data/python_2_pickle.pklz old mode 100644 new mode 100755 diff --git a/dev/circleci_data/requirements.txt b/dev/circleci_data/requirements.txt old mode 100644 new mode 100755 diff --git a/dev/circleci_data/test_external_utils.py b/dev/circleci_data/test_external_utils.py old mode 100644 new mode 100755 diff --git a/dev/circleci_data/test_install.py b/dev/circleci_data/test_install.py old mode 100644 new mode 100755 diff --git a/dev/docker_data/default_pipeline.yml b/dev/docker_data/default_pipeline.yml old mode 100644 new mode 100755 diff --git a/dev/docker_data/license.txt b/dev/docker_data/license.txt old mode 100644 new mode 100755 diff --git a/dev/docker_data/required_afni_pkgs.txt b/dev/docker_data/required_afni_pkgs.txt old mode 100644 new mode 100755 diff --git a/dev/docker_data/required_freesurfer_pkgs.txt b/dev/docker_data/required_freesurfer_pkgs.txt old mode 100644 new mode 100755 diff --git a/dev/rc_tests/README.md b/dev/rc_tests/README.md old mode 100644 new mode 100755 diff --git a/requirements.txt b/requirements.txt old mode 100644 new mode 100755 diff --git a/scripts/cpac b/scripts/cpac old mode 100644 new mode 100755 diff --git a/variant-ABCD-HCP.Dockerfile b/variant-ABCD-HCP.Dockerfile old mode 100644 new mode 100755 diff --git a/variant-fMRIPrep-LTS.Dockerfile b/variant-fMRIPrep-LTS.Dockerfile old mode 100644 new mode 100755 diff --git a/variant-lite.Dockerfile b/variant-lite.Dockerfile old mode 100644 new mode 100755 diff --git a/version b/version old mode 100644 new mode 100755 From 43b929b2b42d3a1d75c03f11ef8e71b1ee3933f9 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 2 Feb 2023 14:55:17 +0000 Subject: [PATCH 005/213] modified files cpac_pipeline.py and surf_preproc.py --- CPAC/pipeline/cpac_pipeline.py | 8 ++++---- CPAC/surface/surf_preproc.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index f905b557b3..5e43375410 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -170,8 +170,8 @@ ) from CPAC.surface.surf_preproc import surface_postproc -from CPAC.surface.surf_preproc import cal_falff -from CPAC.surface.surf_preproc import cal_alff +from CPAC.surface.surf_preproc import surface_falf +from CPAC.surface.surf_preproc import surface_alff #from CPAC.surface.surf_preproc import cal_reho #from CPAC.surface.surf_preproc import cal_connectivity_matrix @@ -1319,10 +1319,10 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, pipeline_blocks += [surface_postproc] if not rpool.check_rpool('surf-falff'): - pipeline_blocks += [cal_falff] + pipeline_blocks += [surface_falff] if not rpool.check_rpool('surf-alff'): - pipeline_blocks += [cal_alff] + pipeline_blocks += [surface_alff] # Extractions and Derivatives diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 7d955063b4..8bf3241bfe 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -744,7 +744,7 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): ''' - {"name": "surface_preproc", + {"name": "surface_postproc", "config": ["surface_analysis", "post_freesurfer"], "switch": ["run"], "option_key": "None", From 0d4ebf250826ed7fe71585092342daab326880d6 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Fri, 3 Feb 2023 16:13:27 +0000 Subject: [PATCH 006/213] all modified files added --- CPAC/pipeline/cpac_pipeline.py | 6 +- CPAC/resources/cpac_outputs.tsv | 89 +++++++- CPAC/surface/PostFreeSurfer/block1.sh | 186 ++++++++++++++++ CPAC/surface/PostFreeSurfer/block2.sh | 189 ++++++++++++++++ CPAC/surface/PostFreeSurfer/block3-5.sh | 276 ++++++++++++++++++++++++ CPAC/surface/PostFreeSurfer/block3.sh | 242 +++++++++++++++++++++ CPAC/surface/PostFreeSurfer/block4.sh | 193 +++++++++++++++++ CPAC/surface/PostFreeSurfer/block5.sh | 146 +++++++++++++ CPAC/surface/PostFreeSurfer/block6.sh | 177 +++++++++++++++ CPAC/surface/surf_preproc.py | 43 ++-- 10 files changed, 1524 insertions(+), 23 deletions(-) create mode 100755 CPAC/surface/PostFreeSurfer/block1.sh create mode 100755 CPAC/surface/PostFreeSurfer/block2.sh create mode 100644 CPAC/surface/PostFreeSurfer/block3-5.sh create mode 100755 CPAC/surface/PostFreeSurfer/block3.sh create mode 100755 CPAC/surface/PostFreeSurfer/block4.sh create mode 100755 CPAC/surface/PostFreeSurfer/block5.sh create mode 100755 CPAC/surface/PostFreeSurfer/block6.sh diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index 5e43375410..294a8cd6a5 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -170,7 +170,7 @@ ) from CPAC.surface.surf_preproc import surface_postproc -from CPAC.surface.surf_preproc import surface_falf +from CPAC.surface.surf_preproc import surface_falff from CPAC.surface.surf_preproc import surface_alff #from CPAC.surface.surf_preproc import cal_reho #from CPAC.surface.surf_preproc import cal_connectivity_matrix @@ -1318,10 +1318,10 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if not rpool.check_rpool('space-fsLR_den-32k_bold.dtseries'): pipeline_blocks += [surface_postproc] - if not rpool.check_rpool('surf-falff'): + if not rpool.check_rpool('surf_falff'): pipeline_blocks += [surface_falff] - if not rpool.check_rpool('surf-alff'): + if not rpool.check_rpool('surf_alff'): pipeline_blocks += [surface_alff] diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index e717dcace8..c02d9ffc18 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -217,6 +217,89 @@ space-template_label-WM_mask mask template anat NIfTI space-template_label-GM_mask mask template anat NIfTI space-EPItemplate_label-CSF_mask mask template func NIfTI space-EPItemplate_label-WM_mask mask template func NIfTI -space-EPItemplate_label-GM_mask mask template func NIfTI -falff surface_derived func -alff surface_derived func +space-EPItemplate_label-GM_mask mask template func NIfTI +AtlasSubcortical_s2 surface_derived func +dtseries surface_derived func +goodvoxels surface_derived func +ribbon_only surface_derived func +atlasroi_hemi-L_space-fsLR_den-32k_func surface_derived func +atlasroi_hemi-R_space-fsLR_den-32k_func surface_derived func +atlasroi_hemi-L_space-fsLR_den-32k_shape surface_derived func +atlasroi_hemi-R_space-fsLR_den-32k_shape surface_derived func +space-native_hemi-L_func surface_derived func +space-native_hemi-R_func surface_derived func +space-fsLR_den-32k_wb-spec surface_derived func +space-native_wb-spec surface_derived func +arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func +arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func +arealdistortion-FS_space-fsLR_den-32k_dscalar surface_derived func +arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func +arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func +arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func +edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func +edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func +edgedistortion-FS_space-fsLR_den-32k_dscalar surface_derived func +edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func +edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func +edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func +hemi-L_space-fsLR_den-32k_curv_shape surface_derived func +hemi-R_space-fsLR_den-32k_curv_shape surface_derived func +space-fsLR_den-32k_curv_dscalar surface_derived func +hemi-L_space-fsLR_den-32k_flat_surf surface_derived func +hemi-R_space-fsLR_den-32k_flat_surf surface_derived func +hemi-L_space-fsLR_den-32k_inflated_surf surface_derived func +hemi-R_space-fsLR_den-32k_inflated_surf surface_derived func +hemi-L_space-fsLR_den-32k_very-inflated_surf surface_derived func +hemi-R_space-fsLR_den-32k_very-inflated_surf surface_derived func +hemi-L_space-native_inflated_surf surface_derived func +hemi-R_space-native_inflated_surf surface_derived func +hemi-L_space-native_very-inflated_surf surface_derived func +hemi-R_space-native_very-inflated_surf surface_derived func +hemi-L_space-fsLR_den-164k_midthickness_surf surface_derived func +hemi-R_space-fsLR_den-164k_midthickness_surf surface_derived func +hemi-L_space-fsLR_den-32k_midthickness_surf surface_derived func +hemi-R_space-fsLR_den-32k_midthickness_surf surface_derived func +hemi-L_space-native_midthickness_surf surface_derived func +hemi-R_space-native_midthickness_surf surface_derived func +hemi-L_space-fsLR_den-32k_pial_surf surface_derived func +hemi-R_space-fsLR_den-32k_pial_surf surface_derived func +hemi-L_space-native_den-32k_pial_surf surface_derived func +hemi-R_space-native_den-32k_pial_surf surface_derived func +hemi-L_space-fsLR_den-32k_sphere_surf surface_derived func +hemi-R_space-fsLR_den-32k_sphere_surf surface_derived func +hemi-L_MSMSulc_space-native_sphere_surf surface_derived func +hemi-R_MSMSulc_space-native_sphere_surf surface_derived func +hemi-L_space-native_sphere_surf surface_derived func +hemi-R_space-native_sphere_surf surface_derived func +hemi-L_space-native_sphere-reg_surf surface_derived func +hemi-R_space-native_sphere-reg_surf surface_derived func +hemi-L_space-native_sphere-reg-reg_surf surface_derived func +hemi-R_space-native_sphere-reg-reg_surf surface_derived func +hemi-L_space-native_sphere-rot_surf surface_derived func +hemi-R_space-native_sphere-rot_surf surface_derived func +hemi-L_strainJ-FS_space-fsLR_den-32k_shape surface_derived func +hemi-R_strainJ-FS_space-fsLR_den-32k_shape surface_derived func +strainJ-FS_space-fsLR_den-32k_dscalar surface_derived func +hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func +hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func +strainJ-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func +hemi-L_strainR-FS_space-fsLR_den-32k_shape surface_derived func +hemi-R_strainR-FS_space-fsLR_den-32k_shape surface_derived func +strainR-FS_space-fsLR_den-32k_dscalar surface_derived func +hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func +hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func +strainR-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func +hemi-L_space-fsLR_den-32k_sulc_shape surface_derived func +hemi-R_space-fsLR_den-32k_sulc_shape surface_derived func +space-fsLR_den-32k_sulc_dscalar surface_derived func +hemi-L_space-fsLR_den-32k_thickness_shape surface_derived func +hemi-R_space-fsLR_den-32k_thickness_shape surface_derived func +space-fsLR_den-32k_thickness_dscalar surface_derived func +hemi-L_space-fsLR_den-164k_white_surf surface_derived func +hemi-R_space-fsLR_den-164k_white_surf surface_derived func +hemi-L_space-fsLR_den-32k_white_surf surface_derived func +hemi-R_space-fsLR_den-32k_white_surf surface_derived func +hemi-L_space-native_white_surf surface_derived func +hemi-R_space-native_white_surf surface_derived func +surf_alff surface_derived func +surf_falff surface_derived func diff --git a/CPAC/surface/PostFreeSurfer/block1.sh b/CPAC/surface/PostFreeSurfer/block1.sh new file mode 100755 index 0000000000..fe3ee9aef9 --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block1.sh @@ -0,0 +1,186 @@ + +#!/bin/bash + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + + +# ------------------------------------------------------------------------------ +# Load function libraries +# ------------------------------------------------------------------------------ + + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +# Added by XL +cd $StudyFolder + +if [ ! -e "$T1wFolder" ] ; then + mkdir -p "$T1wFolder" +fi + +if [ ! -e "$AtlasSpaceFolder" ] ; then + mkdir -p "$AtlasSpaceFolder" +fi + +if [ ! -e "$AtlasSpaceFolder"/xfms ] ; then + mkdir -p "$AtlasSpaceFolder"/xfms +fi + +if [ ! -e "$T1wFolder"/"$T1wRestoreImage".nii.gz ] ; then + cp ${T1wRestoreImageCPAC} "$T1wFolder"/"$T1wRestoreImage".nii.gz +fi + +if [ ! -e "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage".nii.gz ] ; then + cp ${AtlasSpaceT1wImageCPAC} "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage".nii.gz +fi + +if [ ! -e ${AtlasTransform}.nii.gz ] ; then + cp ${AtlasTransformCPAC} ${AtlasTransform}.nii.gz +fi + +if [ ! -e ${InverseAtlasTransform}.nii.gz ] ; then + cp ${InverseAtlasTransformCPAC} ${InverseAtlasTransform}.nii.gz +fi + +echo "$StudyFolder" "$Subject" "$T1wFolder" "$AtlasSpaceFolder" "$NativeFolder" "$FreeSurferFolder" "$FreeSurferInput" "$T1wRestoreImage" "$T2wRestoreImage" "$SurfaceAtlasDIR" "$HighResMesh" "$LowResMeshes" "$AtlasTransform" "$InverseAtlasTransform" "$AtlasSpaceT1wImage" "$AtlasSpaceT2wImage" "$T1wImageBrainMask" "$FreeSurferLabels" "$GrayordinatesSpaceDIR" "$GrayordinatesResolutions" "$SubcorticalGrayLabels" "$RegName" "$InflateExtraScale" "$useT2" + + +# ------------------------------------------------------------------------------ +# Gather and show positional parameters +# ------------------------------------------------------------------------------ + +#Make some folders for this and later scripts +if [ ! -e "$T1wFolder"/"$NativeFolder" ] ; then + mkdir -p "$T1wFolder"/"$NativeFolder" +fi +if [ ! -e "$AtlasSpaceFolder"/ROIs ] ; then + mkdir -p "$AtlasSpaceFolder"/ROIs +fi +if [ ! -e "$AtlasSpaceFolder"/Results ] ; then + mkdir "$AtlasSpaceFolder"/Results +fi +if [ ! -e "$AtlasSpaceFolder"/"$NativeFolder" ] ; then + mkdir "$AtlasSpaceFolder"/"$NativeFolder" +fi +if [ ! -e "$AtlasSpaceFolder"/fsaverage ] ; then + mkdir "$AtlasSpaceFolder"/fsaverage +fi +for LowResMesh in ${LowResMeshes} ; do + if [ ! -e "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k ] ; then + mkdir "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k + fi + if [ ! -e "$T1wFolder"/fsaverage_LR"$LowResMesh"k ] ; then + mkdir "$T1wFolder"/fsaverage_LR"$LowResMesh"k + fi +done diff --git a/CPAC/surface/PostFreeSurfer/block2.sh b/CPAC/surface/PostFreeSurfer/block2.sh new file mode 100755 index 0000000000..a61ad330dc --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block2.sh @@ -0,0 +1,189 @@ + +#!/bin/bash + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +cd ${FreeSurferFolder} +#rm mri/c_ras.mat +MatrixX=$(mri_info mri/brain.finalsurfs.mgz | grep "c_r" | cut -d "=" -f 5 | sed s/" "/""/g) +MatrixY=$(mri_info mri/brain.finalsurfs.mgz | grep "c_a" | cut -d "=" -f 5 | sed s/" "/""/g) +MatrixZ=$(mri_info mri/brain.finalsurfs.mgz | grep "c_s" | cut -d "=" -f 5 | sed s/" "/""/g) +echo "1 0 0 ""$MatrixX" >> mri/c_ras.mat +echo "0 1 0 ""$MatrixY" >> mri/c_ras.mat +echo "0 0 1 ""$MatrixZ" >> mri/c_ras.mat +echo "0 0 0 1" >> mri/c_ras.mat + +cd ${StudyFolder} + +#Convert FreeSurfer Volumes +for Image in wmparc aparc.a2009s+aseg aparc+aseg ; do + if [ -e "$FreeSurferFolder"/mri/"$Image".mgz ] ; then + + mri_convert -rt nearest -rl "$T1wFolder"/"$T1wRestoreImage".nii.gz "$FreeSurferFolder"/mri/"$Image".mgz "$T1wFolder"/"$Image"_1mm.nii.gz + applywarp --rel --interp=nn -i "$T1wFolder"/"$Image"_1mm.nii.gz -r "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage" --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wFolder"/"$Image".nii.gz + applywarp --rel --interp=nn -i "$T1wFolder"/"$Image"_1mm.nii.gz -r "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage" -w "$AtlasTransform" -o "$AtlasSpaceFolder"/"$Image".nii.gz + wb_command -volume-label-import "$T1wFolder"/"$Image".nii.gz "$FreeSurferLabels" "$T1wFolder"/"$Image".nii.gz -drop-unused-labels + wb_command -volume-label-import "$AtlasSpaceFolder"/"$Image".nii.gz "$FreeSurferLabels" "$AtlasSpaceFolder"/"$Image".nii.gz -drop-unused-labels + fi +done + +# #Create FreeSurfer Brain Mask (Now done in PostFreeSurfer.sh so brainmask_fs.nii.gz exists for ANTs Registration) +fslmaths "$T1wFolder"/wmparc_1mm.nii.gz -bin -dilD -dilD -dilD -ero -ero "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz +wb_command -volume-fill-holes "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz +fslmaths "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz -bin "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz +applywarp --rel --interp=nn -i "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz -r "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage" --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wFolder"/"$T1wImageBrainMask".nii.gz +applywarp --rel --interp=nn -i "$T1wFolder"/"$T1wImageBrainMask"_1mm.nii.gz -r "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage" -w "$AtlasTransform" -o "$AtlasSpaceFolder"/"$T1wImageBrainMask".nii.gz + +#Add volume files to spec files +if $useT2; then +wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec INVALID "$T1wFolder"/"$T2wImage".nii.gz +fi +wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec INVALID "$T1wFolder"/"$T1wRestoreImage".nii.gz + +if $useT2; then +wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec INVALID "$AtlasSpaceFolder"/"$AtlasSpaceT2wImage".nii.gz +fi +wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec INVALID "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage".nii.gz + +if $useT2; then +wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec INVALID "$AtlasSpaceFolder"/"$AtlasSpaceT2wImage".nii.gz +fi +wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec INVALID "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage".nii.gz + +for LowResMesh in ${LowResMeshes} ; do + if $useT2; then + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec INVALID "$AtlasSpaceFolder"/"$AtlasSpaceT2wImage".nii.gz + fi + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec INVALID "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage".nii.gz + + if $useT2; then + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec INVALID "$T1wFolder"/"$T2wImage".nii.gz + fi + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec INVALID "$T1wFolder"/"$T1wRestoreImage".nii.gz +done + +#Import Subcortical ROIs +for GrayordinatesResolution in ${GrayordinatesResolutions} ; do + cp "$GrayordinatesSpaceDIR"/Atlas_ROIs."$GrayordinatesResolution".nii.gz "$AtlasSpaceFolder"/ROIs/Atlas_ROIs."$GrayordinatesResolution".nii.gz + applywarp --interp=nn -i "$AtlasSpaceFolder"/wmparc.nii.gz -r "$AtlasSpaceFolder"/ROIs/Atlas_ROIs."$GrayordinatesResolution".nii.gz -o "$AtlasSpaceFolder"/ROIs/wmparc."$GrayordinatesResolution".nii.gz + wb_command -volume-label-import "$AtlasSpaceFolder"/ROIs/wmparc."$GrayordinatesResolution".nii.gz "$FreeSurferLabels" "$AtlasSpaceFolder"/ROIs/wmparc."$GrayordinatesResolution".nii.gz -drop-unused-labels + applywarp --interp=nn -i "$SurfaceAtlasDIR"/Avgwmparc.nii.gz -r "$AtlasSpaceFolder"/ROIs/Atlas_ROIs."$GrayordinatesResolution".nii.gz -o "$AtlasSpaceFolder"/ROIs/Atlas_wmparc."$GrayordinatesResolution".nii.gz + wb_command -volume-label-import "$AtlasSpaceFolder"/ROIs/Atlas_wmparc."$GrayordinatesResolution".nii.gz "$FreeSurferLabels" "$AtlasSpaceFolder"/ROIs/Atlas_wmparc."$GrayordinatesResolution".nii.gz -drop-unused-labels + wb_command -volume-label-import "$AtlasSpaceFolder"/ROIs/wmparc."$GrayordinatesResolution".nii.gz ${SubcorticalGrayLabels} "$AtlasSpaceFolder"/ROIs/ROIs."$GrayordinatesResolution".nii.gz -discard-others + if $useT2; then + applywarp --interp=spline -i "$AtlasSpaceFolder"/"$AtlasSpaceT2wImage".nii.gz -r "$AtlasSpaceFolder"/ROIs/Atlas_ROIs."$GrayordinatesResolution".nii.gz -o "$AtlasSpaceFolder"/"$AtlasSpaceT2wImage"."$GrayordinatesResolution".nii.gz + fi + applywarp --interp=spline -i "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage".nii.gz -r "$AtlasSpaceFolder"/ROIs/Atlas_ROIs."$GrayordinatesResolution".nii.gz -o "$AtlasSpaceFolder"/"$AtlasSpaceT1wImage"."$GrayordinatesResolution".nii.gz +done diff --git a/CPAC/surface/PostFreeSurfer/block3-5.sh b/CPAC/surface/PostFreeSurfer/block3-5.sh new file mode 100644 index 0000000000..ad52f61cb4 --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block3-5.sh @@ -0,0 +1,276 @@ + #!/bin/bash + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +cd ${StudyFolder} + +#Loop through left and right hemispheres +for Hemisphere in L R ; do + #Set a bunch of different ways of saying left and right + if [ $Hemisphere = "L" ] ; then + hemisphere="l" + Structure="CORTEX_LEFT" + elif [ $Hemisphere = "R" ] ; then + hemisphere="r" + Structure="CORTEX_RIGHT" + fi + + #If desired, run MSMSulc folding-based registration to FS_LR initialized with FS affine + if [ ${RegName} = "MSMSulc" ] ; then + #Calculate Affine Transform and Apply + if [ ! -e "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc ] ; then + mkdir "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc + fi + wb_command -surface-affine-regression "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat + wb_command -surface-apply-affine "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii + wb_command -surface-modify-sphere "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii 100 "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii + cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii + DIR=$(pwd) + cd "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc + #Register using FreeSurfer Sulc Folding Map Using MSM Algorithm Configured for Reduced Distortion + #msm --version + #msm --levels=4 --conf=${MSMCONFIGDIR}/allparameterssulcDRconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --trans="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose + # Note: the config is mordified according to acceptable args of msm version in container - XL + msm --conf=${MSMCONFIGDIR}/MSMSulcStrainFinalconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose + cp ${MSMCONFIGDIR}/MSMSulcStrainFinalconf "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.logdir/conf + cd $DIR + #cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.HIGHRES_transformed.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii + cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere.reg.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii ${Structure} + + #Make MSMSulc Registration Areal Distortion Maps + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_MSMSulc + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii -edge-method + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -local-affine-method + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 1 + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 2 + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii + + RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii" + else + RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii" + fi + + #Ensure no zeros in atlas medial wall ROI + wb_command -metric-resample "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ${RegSphere} BARYCENTRIC "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -largest + wb_command -metric-math "(atlas + individual) > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var atlas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -var individual "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii + + + #Populate Highres fs_LR spec file. Deform surfaces and other data according to native to folding-based registration selected above. Regenerate inflated surfaces. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for high res mesh density + HighResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $HighResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii -iterations-scale $HighResInflationScale + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii + + for Map in thickness curvature ; do + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii + done + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + fi + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then + wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.label.gii -largest + fi + done + + for LowResMesh in ${LowResMeshes} ; do + #Copy Atlas Files + cp "$SurfaceAtlasDIR"/"$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii + cp "$GrayordinatesSpaceDIR"/"$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii + if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii ] ; then + cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii + fi + + #Create downsampled fs_LR spec files. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh + LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii + + for Map in sulc thickness curvature ; do + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii + done + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + fi + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then + wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.label.gii -largest + fi + done + + #Create downsampled fs_LR spec file in structural space. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh + LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii + done +done + diff --git a/CPAC/surface/PostFreeSurfer/block3.sh b/CPAC/surface/PostFreeSurfer/block3.sh new file mode 100755 index 0000000000..d340d49351 --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block3.sh @@ -0,0 +1,242 @@ + +#!/bin/bash + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +cd ${StudyFolder} + +#Loop through left and right hemispheres +for Hemisphere in L R ; do + #Set a bunch of different ways of saying left and right + if [ $Hemisphere = "L" ] ; then + hemisphere="l" + Structure="CORTEX_LEFT" + elif [ $Hemisphere = "R" ] ; then + hemisphere="r" + Structure="CORTEX_RIGHT" + fi + + #native Mesh Processing + #Convert and volumetrically register white and pial surfaces making linear and nonlinear copies, add each to the appropriate spec file + Types="ANATOMICAL@GRAY_WHITE ANATOMICAL@PIAL" + i=1 + for Surface in white pial ; do + Type=$(echo "$Types" | cut -d " " -f $i) + Secondary=$(echo "$Type" | cut -d "@" -f 2) + Type=$(echo "$Type" | cut -d "@" -f 1) + if [ ! $Secondary = $Type ] ; then + Secondary=$(echo " -surface-secondary-type ""$Secondary") + else + Secondary="" + fi + mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -set-structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type $Type$Secondary + wb_command -surface-apply-affine "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$FreeSurferFolder"/mri/c_ras.mat "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -surface-apply-warpfield "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$InverseAtlasTransform".nii.gz "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii -fnirt "$AtlasTransform".nii.gz + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + i=$(( i+1 )) + done + + + #Create midthickness by averaging white and pial surfaces and use it to make inflated surfacess + for Folder in "$T1wFolder" "$AtlasSpaceFolder" ; do + wb_command -surface-average "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".white.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".pial.native.surf.gii + wb_command -set-structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii ${Structure} -surface-type ANATOMICAL -surface-secondary-type MIDTHICKNESS + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii + + #get number of vertices from native file + NativeVerts=$(wb_command -file-information "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii | grep 'Number of Vertices:' | cut -f2 -d: | tr -d '[:space:]') + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for native mesh density + NativeInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $NativeVerts / 32492" | bc -l) + + wb_command -surface-generate-inflated "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii -iterations-scale $NativeInflationScale + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii + done + + #Convert original and registered spherical surfaces and add them to the nonlinear spec file + for Surface in sphere.reg sphere ; do + mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type SPHERICAL + done + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii + + #Add more files to the spec file and convert other FreeSurfer surface data to metric/GIFTI including sulc, curv, and thickness. + for Map in sulc@sulc@Sulc thickness@thickness@Thickness curv@curvature@Curvature ; do + fsname=$(echo $Map | cut -d "@" -f 1) + wbname=$(echo $Map | cut -d "@" -f 2) + mapname=$(echo $Map | cut -d "@" -f 3) + mris_convert -c "$FreeSurferFolder"/surf/"$hemisphere"h."$fsname" "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii ${Structure} + wb_command -metric-math "var * -1" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -map 1 "$Subject"_"$Hemisphere"_"$mapname" + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + done + #Thickness specific operations + wb_command -metric-math "abs(thickness)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false + wb_command -metric-math "thickness > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-fill-holes "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-remove-islands "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_ROI + wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -nearest + wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii -nearest + + #Label operations + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then + mris_convert --annot "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii $Structure + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii -map 1 "$Subject"_"$Hemisphere"_"$Map" + wb_command -gifti-label-add-prefix "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii "${Hemisphere}_" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii + fi + done + #End main native mesh processing + + #Copy Atlas Files + cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fsaverage."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii + cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fs_"$Hemisphere"-to-fs_LR_fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii + cp "$SurfaceAtlasDIR"/fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii + cp "$SurfaceAtlasDIR"/"$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii + cp "$SurfaceAtlasDIR"/"$Hemisphere".refsulc."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii + if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii ] ; then + cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii + fi + + #Concatenate FS registration to FS --> FS_LR registration + wb_command -surface-sphere-project-unproject "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.native.surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii + + #Make FreeSurfer Registration Areal Distortion Maps + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_FS + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii -edge-method + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -local-affine-method + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 1 + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 2 + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii + +done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block4.sh b/CPAC/surface/PostFreeSurfer/block4.sh new file mode 100755 index 0000000000..5b9ee7b046 --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block4.sh @@ -0,0 +1,193 @@ + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +for Hemisphere in L R ; do + #Set a bunch of different ways of saying left and right + if [ $Hemisphere = "L" ] ; then + hemisphere="l" + Structure="CORTEX_LEFT" + elif [ $Hemisphere = "R" ] ; then + hemisphere="r" + Structure="CORTEX_RIGHT" + fi + +cd ${StudyFolder} + +STRINGII="" +for LowResMesh in ${LowResMeshes} ; do + STRINGII=$(echo "${STRINGII}${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR@atlasroi ") +done + +#Create CIFTI Files +for STRING in "$AtlasSpaceFolder"/"$NativeFolder"@native@roi "$AtlasSpaceFolder"@"$HighResMesh"k_fs_LR@atlasroi ${STRINGII} ; do + Folder=$(echo $STRING | cut -d "@" -f 1) + Mesh=$(echo $STRING | cut -d "@" -f 2) + ROI=$(echo $STRING | cut -d "@" -f 3) + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.sulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.sulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -map 1 "${Subject}_Sulc" + wb_command -cifti-palette "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.curvature."$Mesh".shape.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.curvature."$Mesh".shape.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -map 1 "${Subject}_Curvature" + wb_command -cifti-palette "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.thickness."$Mesh".shape.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.thickness."$Mesh".shape.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -map 1 "${Subject}_Thickness" + wb_command -cifti-palette "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.ArealDistortion_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.ArealDistortion_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -map 1 "${Subject}_ArealDistortion_FS" + wb_command -cifti-palette "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.EdgeDistortion_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.EdgeDistortion_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -map 1 "${Subject}_EdgeDistortion_FS" + wb_command -cifti-palette "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainJ_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainJ_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -map 1 "${Subject}_StrainJ_FS" + wb_command -cifti-palette "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainR_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainR_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -map 1 "${Subject}_StrainR_FS" + wb_command -cifti-palette "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.ArealDistortion_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.ArealDistortion_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_ArealDistortion_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.EdgeDistortion_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.EdgeDistortion_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_EdgeDistortion_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainJ_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainJ_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_StrainJ_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainR_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainR_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_StrainR_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + fi + + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$Folder"/"$Subject".L.${Map}."$Mesh".label.gii ] ; then + wb_command -cifti-create-label "$Folder"/"$Subject".${Map}."$Mesh".dlabel.nii -left-label "$Folder"/"$Subject".L.${Map}."$Mesh".label.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-label "$Folder"/"$Subject".R.${Map}."$Mesh".label.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".${Map}."$Mesh".dlabel.nii -map 1 "$Subject"_${Map} + fi + done + done +done diff --git a/CPAC/surface/PostFreeSurfer/block5.sh b/CPAC/surface/PostFreeSurfer/block5.sh new file mode 100755 index 0000000000..25b5b04b3b --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block5.sh @@ -0,0 +1,146 @@ + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +for Hemisphere in L R ; do + #Set a bunch of different ways of saying left and right + if [ $Hemisphere = "L" ] ; then + hemisphere="l" + Structure="CORTEX_LEFT" + elif [ $Hemisphere = "R" ] ; then + hemisphere="r" + Structure="CORTEX_RIGHT" + fi + +cd ${StudyFolder} + +STRINGII="" +for LowResMesh in ${LowResMeshes} ; do + STRINGII=$(echo "${STRINGII}${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR ${T1wFolder}/fsaverage_LR${LowResMesh}k@${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR ") +done + +#Add CIFTI Maps to Spec Files +for STRING in "$T1wFolder"/"$NativeFolder"@"$AtlasSpaceFolder"/"$NativeFolder"@native "$AtlasSpaceFolder"/"$NativeFolder"@"$AtlasSpaceFolder"/"$NativeFolder"@native "$AtlasSpaceFolder"@"$AtlasSpaceFolder"@"$HighResMesh"k_fs_LR ${STRINGII} ; do + FolderI=$(echo $STRING | cut -d "@" -f 1) + FolderII=$(echo $STRING | cut -d "@" -f 2) + Mesh=$(echo $STRING | cut -d "@" -f 3) + for STRINGII in sulc@dscalar thickness@dscalar curvature@dscalar aparc@dlabel aparc.a2009s@dlabel ; do #Remove BA@dlabel because it doesn't convert properly + Map=$(echo $STRINGII | cut -d "@" -f 1) + Ext=$(echo $STRINGII | cut -d "@" -f 2) + if [ -e "$FolderII"/"$Subject"."$Map"."$Mesh"."$Ext".nii ] ; then + wb_command -add-to-spec-file "$FolderI"/"$Subject"."$Mesh".wb.spec INVALID "$FolderII"/"$Subject"."$Map"."$Mesh"."$Ext".nii + fi + done +done +done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block6.sh b/CPAC/surface/PostFreeSurfer/block6.sh new file mode 100755 index 0000000000..29e7cc564f --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block6.sh @@ -0,0 +1,177 @@ + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +# Create midthickness Vertex Area (VA) maps +echo "Create midthickness Vertex Area (VA) maps" + +for Hemisphere in L R ; do + #Set a bunch of different ways of saying left and right + if [ $Hemisphere = "L" ] ; then + hemisphere="l" + Structure="CORTEX_LEFT" + elif [ $Hemisphere = "R" ] ; then + hemisphere="r" + Structure="CORTEX_RIGHT" + fi +cd ${StudyFolder} + +for LowResMesh in ${LowResMeshes} ; do + + echo "Creating midthickness Vertex Area (VA) maps for LowResMesh: ${LowResMesh}" + + # DownSampleT1wFolder - path to folder containing downsampled T1w files + # midthickness_va_file - path to non-normalized midthickness vertex area file + # normalized_midthickness_va_file - path ot normalized midthickness vertex area file + # surface_to_measure - path to surface file on which to measure surface areas + # output_metric - path to metric file generated by -surface-vertex-areas subcommand + + DownSampleT1wFolder=${T1wFolder}/fsaverage_LR${LowResMesh}k + DownSampleFolder=${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k + midthickness_va_file=${DownSampleT1wFolder}/${Subject}.midthickness_va.${LowResMesh}k_fs_LR.dscalar.nii + normalized_midthickness_va_file=${DownSampleT1wFolder}/${Subject}.midthickness_va_norm.${LowResMesh}k_fs_LR.dscalar.nii + + for Hemisphere in L R ; do + surface_to_measure=${DownSampleT1wFolder}/${Subject}.${Hemisphere}.midthickness.${LowResMesh}k_fs_LR.surf.gii + output_metric=${DownSampleT1wFolder}/${Subject}.${Hemisphere}.midthickness_va.${LowResMesh}k_fs_LR.shape.gii + wb_command -surface-vertex-areas ${surface_to_measure} ${output_metric} + done + + # left_metric - path to left hemisphere VA metric file + # roi_left - path to file of ROI vertices to use from left surface + # right_metric - path to right hemisphere VA metric file + # roi_right - path to file of ROI vertices to use from right surface + + left_metric=${DownSampleT1wFolder}/${Subject}.L.midthickness_va.${LowResMesh}k_fs_LR.shape.gii + roi_left=${DownSampleFolder}/${Subject}.L.atlasroi.${LowResMesh}k_fs_LR.shape.gii + right_metric=${DownSampleT1wFolder}/${Subject}.R.midthickness_va.${LowResMesh}k_fs_LR.shape.gii + roi_right=${DownSampleFolder}/${Subject}.R.atlasroi.${LowResMesh}k_fs_LR.shape.gii + + wb_command -cifti-create-dense-scalar ${midthickness_va_file} \ + -left-metric ${left_metric} \ + -roi-left ${roi_left} \ + -right-metric ${right_metric} \ + -roi-right ${roi_right} + + # VAMean - mean of surface area accounted for for each vertex - used for normalization + VAMean=$(wb_command -cifti-stats ${midthickness_va_file} -reduce MEAN) + echo "VAMean: ${VAMean}" + + wb_command -cifti-math "VA / ${VAMean}" ${normalized_midthickness_va_file} -var VA ${midthickness_va_file} + + echo "Done creating midthickness Vertex Area (VA) maps for LowResMesh: ${LowResMesh}" + +done +done +echo "Done creating midthickness Vertex Area (VA) maps" diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 8bf3241bfe..1abb82c23c 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -850,31 +850,40 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -def cal_falff(wf, cfg, strat_pool, pipe_num, opt): +def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): - falff = pe.Node(util.Function(input_names=['dtseries'], - output_names=['falff'], + falff = pe.Node(util.Function(input_names=['subject','dtseries','surf_falff_folder'], + output_names=['surf_falff'], function=run_surf_falff), name=f'surf_falff_{pipe_num}') + + falff.inputs.subject = cfg['subject_id'] + falff.inputs.surf_falff_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + 'cpac_'+cfg['subject_id'], + f'surf_falff_{pipe_num}') node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') wf.connect(node, out, falff, 'dtseries') outputs = { - 'surf-falff': (falff,'falff')} + 'surf_falff': (falff,'surf_falff')} return wf, outputs -def cal_alff(wf, cfg, strat_pool, pipe_num, opt): +def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): - alff = pe.Node(util.Function(input_names=['dtseries'], - output_names=['alff'], + alff = pe.Node(util.Function(input_names=['subject','dtseries','surf_alff_folder'], + output_names=['surf_alff'], function=run_surf_alff), name=f'surf_alff_{pipe_num}') - + + alff.inputs.subject = cfg['subject_id'] + alff.inputs.surf_alff_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], + 'cpac_'+cfg['subject_id'], + f'surf_alff_{pipe_num}') node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') wf.connect(node, out,alff, 'dtseries') outputs = { - 'surf-alff': (falff,'alff')} + 'surf_alff': (alff,'surf_alff')} return wf, outputs # def cal_reho(wf, cfg, strat_pool, pipe_num, opt): @@ -970,9 +979,9 @@ def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": ["space-fsLR_den-32k_bold-dtseries"], - "outputs": ["falff"]} + "outputs": ["surf_falff"]} ''' - wf, outputs = cal_falff(wf, cfg, strat_pool, pipe_num, opt) + wf, outputs = cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt) return (wf, outputs) @@ -984,9 +993,9 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": ["space-fsLR_den-32k_bold-dtseries"], - "outputs": ["alff"]} + "outputs": ["surf_alff"]} ''' - wf, outputs = cal_alff(wf, cfg, strat_pool, pipe_num, opt) + wf, outputs = cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt) return (wf, outputs) @@ -1018,18 +1027,18 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): # return (wf, outputs) -def run_surf_falff(dtseries): +def run_surf_falff(subject,dtseries,surf_falff_folder): import os import subprocess - falff = os.path.join(os.getcwd(), 'falff_surf.nii.gz') + falff = os.path.join(surf_falff_folder, f'{subject}.falff_surf.dscalar.nii.gz') cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] subprocess.check_output(cmd) return falff -def run_surf_alff(dtseries): +def run_surf_alff(subject,dtseries,surf_alff_folder): import os import subprocess - alff = os.path.join(os.getcwd(), 'alff_surf.dscalar.nii.gz') + alff = os.path.join(surf_alff_folder, f'{subject}.alff_surf.dscalar.nii.gz') cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] subprocess.check_output(cmd) return alff From 5b8ab0193fa27661926ffaa8c48f8881adb1fa5c Mon Sep 17 00:00:00 2001 From: tergeorge Date: Fri, 3 Feb 2023 19:35:52 +0000 Subject: [PATCH 007/213] modified surf_preproc.py --- CPAC/surface/surf_preproc.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 1abb82c23c..8409f0f544 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -852,16 +852,12 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): - falff = pe.Node(util.Function(input_names=['subject','dtseries','surf_falff_folder'], + falff = pe.Node(util.Function(input_names=['subject','dtseries'], output_names=['surf_falff'], function=run_surf_falff), name=f'surf_falff_{pipe_num}') falff.inputs.subject = cfg['subject_id'] - falff.inputs.surf_falff_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - 'cpac_'+cfg['subject_id'], - f'surf_falff_{pipe_num}') - node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') wf.connect(node, out, falff, 'dtseries') @@ -871,15 +867,12 @@ def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): - alff = pe.Node(util.Function(input_names=['subject','dtseries','surf_alff_folder'], + alff = pe.Node(util.Function(input_names=['subject','dtseries'], output_names=['surf_alff'], function=run_surf_alff), name=f'surf_alff_{pipe_num}') alff.inputs.subject = cfg['subject_id'] - alff.inputs.surf_alff_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - 'cpac_'+cfg['subject_id'], - f'surf_alff_{pipe_num}') node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') wf.connect(node, out,alff, 'dtseries') outputs = { @@ -1027,18 +1020,18 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): # return (wf, outputs) -def run_surf_falff(subject,dtseries,surf_falff_folder): +def run_surf_falff(subject,dtseries): import os import subprocess - falff = os.path.join(surf_falff_folder, f'{subject}.falff_surf.dscalar.nii.gz') + falff = os.path.join(os.getcwd(), f'{subject}_falff_surf.dscalar.nii.gz') cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] subprocess.check_output(cmd) return falff -def run_surf_alff(subject,dtseries,surf_alff_folder): +def run_surf_alff(subject,dtseries): import os import subprocess - alff = os.path.join(surf_alff_folder, f'{subject}.alff_surf.dscalar.nii.gz') + alff = os.path.join(os.getcwd(), f'{subject}_alff_surf.dscalar.nii.gz') cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] subprocess.check_output(cmd) return alff From 62005c35ebc34ffbe8cf62482f9371e68cd1f7c4 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 8 Feb 2023 20:02:45 +0000 Subject: [PATCH 008/213] modified engine.py, outputs.tsv, surf_preproc.py and outputs.py --- CPAC/pipeline/engine.py | 26 +++- CPAC/resources/cpac_outputs.tsv | 170 ++++++++++++----------- CPAC/surface/surf_preproc.py | 6 +- CPAC/utils/monitoring/custom_logging.py | 175 ++++++++++++++++++++++-- CPAC/utils/outputs.py | 12 ++ 5 files changed, 280 insertions(+), 109 deletions(-) mode change 100755 => 100644 CPAC/utils/monitoring/custom_logging.py diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 7325c31943..d01f92da88 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -993,17 +993,33 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): warnings.warn(str( LookupError("\n[!] No atlas ID found for " f"{out_dct['filename']}.\n"))) - #print(resource) - #print(pipe_idx) + nii_name = pe.Node(Rename(), name=f'nii_{resource_idx}_' f'{pipe_x}') nii_name.inputs.keep_ext = True + + if resource in Outputs.ciftis: + nii_name.inputs.keep_ext = False + id_string.inputs.extension = f'{Outputs.ciftis[resource]}.nii' + raise Exception(id_string.inputs.extension) + else: + nii_name.inputs.keep_ext = True + + #raise Exception(Outputs.giftis) + if resource in Outputs.giftis: + + nii_name.inputs.keep_ext = False + id_string.inputs.extension = f'{Outputs.giftis[resource]}.gii' + + else: + nii_name.inputs.keep_ext = True + wf.connect(id_string, 'out_filename', nii_name, 'format_string') - + + node, out = self.rpool[resource][pipe_idx]['data'] - print(node) - #print(out) + try: wf.connect(node, out, nii_name, 'in_file') except OSError as os_error: diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index c02d9ffc18..ce96615e90 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -146,10 +146,10 @@ hemi-R_desc-surfaceMesh_pial surface-derived anat raw-average surface-derived anat hemi-L_desc-surfaceMesh_smoothwm surface-derived anat hemi-R_desc-surfaceMesh_smoothwm surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-32k_dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-32k_dlabel surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-164k_dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-164k_dlabel surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-32k.dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-32k.dlabel surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-164k.dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-164k.dlabel surface-derived anat space-fsLR_den-32k_bold-dtseries surface-derived func hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes @@ -219,87 +219,85 @@ space-EPItemplate_label-CSF_mask mask template func NIfTI space-EPItemplate_label-WM_mask mask template func NIfTI space-EPItemplate_label-GM_mask mask template func NIfTI AtlasSubcortical_s2 surface_derived func -dtseries surface_derived func +dtseries surface_derived func CIFTI dtseries goodvoxels surface_derived func ribbon_only surface_derived func -atlasroi_hemi-L_space-fsLR_den-32k_func surface_derived func -atlasroi_hemi-R_space-fsLR_den-32k_func surface_derived func -atlasroi_hemi-L_space-fsLR_den-32k_shape surface_derived func -atlasroi_hemi-R_space-fsLR_den-32k_shape surface_derived func -space-native_hemi-L_func surface_derived func -space-native_hemi-R_func surface_derived func -space-fsLR_den-32k_wb-spec surface_derived func -space-native_wb-spec surface_derived func -arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func -arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func -arealdistortion-FS_space-fsLR_den-32k_dscalar surface_derived func -arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func -arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func -arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func -edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func -edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func -edgedistortion-FS_space-fsLR_den-32k_dscalar surface_derived func -edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func -edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func -edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func -hemi-L_space-fsLR_den-32k_curv_shape surface_derived func -hemi-R_space-fsLR_den-32k_curv_shape surface_derived func -space-fsLR_den-32k_curv_dscalar surface_derived func -hemi-L_space-fsLR_den-32k_flat_surf surface_derived func -hemi-R_space-fsLR_den-32k_flat_surf surface_derived func -hemi-L_space-fsLR_den-32k_inflated_surf surface_derived func -hemi-R_space-fsLR_den-32k_inflated_surf surface_derived func -hemi-L_space-fsLR_den-32k_very-inflated_surf surface_derived func -hemi-R_space-fsLR_den-32k_very-inflated_surf surface_derived func -hemi-L_space-native_inflated_surf surface_derived func -hemi-R_space-native_inflated_surf surface_derived func -hemi-L_space-native_very-inflated_surf surface_derived func -hemi-R_space-native_very-inflated_surf surface_derived func -hemi-L_space-fsLR_den-164k_midthickness_surf surface_derived func -hemi-R_space-fsLR_den-164k_midthickness_surf surface_derived func -hemi-L_space-fsLR_den-32k_midthickness_surf surface_derived func -hemi-R_space-fsLR_den-32k_midthickness_surf surface_derived func -hemi-L_space-native_midthickness_surf surface_derived func -hemi-R_space-native_midthickness_surf surface_derived func -hemi-L_space-fsLR_den-32k_pial_surf surface_derived func -hemi-R_space-fsLR_den-32k_pial_surf surface_derived func -hemi-L_space-native_den-32k_pial_surf surface_derived func -hemi-R_space-native_den-32k_pial_surf surface_derived func -hemi-L_space-fsLR_den-32k_sphere_surf surface_derived func -hemi-R_space-fsLR_den-32k_sphere_surf surface_derived func -hemi-L_MSMSulc_space-native_sphere_surf surface_derived func -hemi-R_MSMSulc_space-native_sphere_surf surface_derived func -hemi-L_space-native_sphere_surf surface_derived func -hemi-R_space-native_sphere_surf surface_derived func -hemi-L_space-native_sphere-reg_surf surface_derived func -hemi-R_space-native_sphere-reg_surf surface_derived func -hemi-L_space-native_sphere-reg-reg_surf surface_derived func -hemi-R_space-native_sphere-reg-reg_surf surface_derived func -hemi-L_space-native_sphere-rot_surf surface_derived func -hemi-R_space-native_sphere-rot_surf surface_derived func -hemi-L_strainJ-FS_space-fsLR_den-32k_shape surface_derived func -hemi-R_strainJ-FS_space-fsLR_den-32k_shape surface_derived func -strainJ-FS_space-fsLR_den-32k_dscalar surface_derived func -hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func -hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func -strainJ-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func -hemi-L_strainR-FS_space-fsLR_den-32k_shape surface_derived func -hemi-R_strainR-FS_space-fsLR_den-32k_shape surface_derived func -strainR-FS_space-fsLR_den-32k_dscalar surface_derived func -hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func -hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func -strainR-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func -hemi-L_space-fsLR_den-32k_sulc_shape surface_derived func -hemi-R_space-fsLR_den-32k_sulc_shape surface_derived func -space-fsLR_den-32k_sulc_dscalar surface_derived func -hemi-L_space-fsLR_den-32k_thickness_shape surface_derived func -hemi-R_space-fsLR_den-32k_thickness_shape surface_derived func -space-fsLR_den-32k_thickness_dscalar surface_derived func -hemi-L_space-fsLR_den-164k_white_surf surface_derived func -hemi-R_space-fsLR_den-164k_white_surf surface_derived func -hemi-L_space-fsLR_den-32k_white_surf surface_derived func -hemi-R_space-fsLR_den-32k_white_surf surface_derived func -hemi-L_space-native_white_surf surface_derived func -hemi-R_space-native_white_surf surface_derived func -surf_alff surface_derived func -surf_falff surface_derived func +atlasroi_hemi-L_space-fsLR_den-32k_func surface_derived func GIFTI func +atlasroi_hemi-R_space-fsLR_den-32k_func surface_derived func GIFTI func +atlasroi_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape +atlasroi_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape +space-native_hemi-L_func surface_derived func GIFTI func +space-native_hemi-R_func surface_derived func GIFTI func +space-fsLR_den-32k_wb-spec surface_derived func GIFTI spec +space-native_wb-spec surface_derived func GIFTI spec +arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape +arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape +arealdistortion-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape +arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape +arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape +edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape +edgedistortion-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape +edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape +edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_curv_shape surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_curv_shape surface_derived func GIFTI shape +space-fsLR_den-32k_curv_dscalar surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_flat_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_flat_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_inflated_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_inflated_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_very-inflated_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_very-inflated_surf surface_derived func GIFTI surf +hemi-L_space-native_inflated_surf surface_derived func GIFTI surf +hemi-R_space-native_inflated_surf surface_derived func GIFTI surf +hemi-L_space-native_very-inflated_surf surface_derived func GIFTI surf +hemi-R_space-native_very-inflated_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-164k_midthickness_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-164k_midthickness_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_midthickness_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_midthickness_surf surface_derived func GIFTI surf +hemi-L_space-native_midthickness_surf surface_derived func GIFTI surf +hemi-R_space-native_midthickness_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_pial_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_pial_surf surface_derived func GIFTI surf +hemi-L_space-native_den-32k_pial_surf surface_derived func GIFTI surf +hemi-R_space-native_den-32k_pial_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_sphere_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_sphere_surf surface_derived func GIFTI surf +hemi-L_MSMSulc_space-native_sphere_surf surface_derived func GIFTI surf +hemi-R_MSMSulc_space-native_sphere_surf surface_derived func GIFTI surf +hemi-L_space-native_sphere_surf surface_derived func GIFTI surf +hemi-R_space-native_sphere_surf surface_derived func GIFTI surf +hemi-L_space-native_sphere-reg_surf surface_derived func GIFTI surf +hemi-R_space-native_sphere-reg_surf surface_derived func GIFTI surf +hemi-L_space-native_sphere-reg-reg_surf surface_derived func GIFTI surf +hemi-R_space-native_sphere-reg-reg_surf surface_derived func GIFTI surf +hemi-L_space-native_sphere-rot_surf surface_derived func GIFTI surf +hemi-R_space-native_sphere-rot_surf surface_derived func GIFTI surf +hemi-L_strainJ-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape +hemi-R_strainJ-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape +strainJ-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape +hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape +strainJ-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +hemi-L_strainR-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape +hemi-R_strainR-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape +strainR-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape +hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape +strainR-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_sulc_shape surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_sulc_shape surface_derived func GIFTI shape +space-fsLR_den-32k_sulc_dscalar surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_thickness_shape surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_thickness_shape surface_derived func GIFTI shape +space-fsLR_den-32k_thickness_dscalar surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-164k_white_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-164k_white_surf surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_white_surf surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_white_surf surface_derived func GIFTI surf +hemi-L_space-native_white_surf surface_derived func GIFTI surf +hemi-R_space-native_white_surf surface_derived func GIFTI surf diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 8409f0f544..74db667222 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -1023,7 +1023,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): def run_surf_falff(subject,dtseries): import os import subprocess - falff = os.path.join(os.getcwd(), f'{subject}_falff_surf.dscalar.nii.gz') + falff = os.path.join(os.getcwd(), f'{subject}_falff_surf.dscalar.nii') cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] subprocess.check_output(cmd) return falff @@ -1031,7 +1031,7 @@ def run_surf_falff(subject,dtseries): def run_surf_alff(subject,dtseries): import os import subprocess - alff = os.path.join(os.getcwd(), f'{subject}_alff_surf.dscalar.nii.gz') + alff = os.path.join(os.getcwd(), f'{subject}_alff_surf.dscalar.nii') cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] subprocess.check_output(cmd) return alff @@ -1077,4 +1077,4 @@ def run_surf_alff(subject,dtseries): # correlation_matrix = os.path.join(os.getcwd(), 'cifti_corr.pconn.nii') # cmd = ['wb_command', '-cifti-correlation ', ptseries , correlation_matrix] # subprocess.check_output(cmd) -# return correlation_matrix +# return correlation_matrix \ No newline at end of file diff --git a/CPAC/utils/monitoring/custom_logging.py b/CPAC/utils/monitoring/custom_logging.py old mode 100755 new mode 100644 index f495335d35..1199e957f5 --- a/CPAC/utils/monitoring/custom_logging.py +++ b/CPAC/utils/monitoring/custom_logging.py @@ -1,11 +1,48 @@ -'''Funtions for logging.''' +"""Funtions for logging. + +Copyright (C) 2022 C-PAC Developers + +This file is part of C-PAC. + +C-PAC is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +C-PAC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with C-PAC. If not, see .""" import logging import os - +import subprocess +from sys import exc_info as sys_exc_info +from traceback import print_exception +from nipype import logging as nipype_logging from CPAC.utils.docs import docstring_parameter from CPAC.utils.monitoring.config import MOCK_LOGGERS +def failed_to_start(log_dir, exception): + """Launch a failed-to-start logger for a run that failed to start. + Must be called from within an ``except`` block. + + Parameters + ---------- + log_dir : str + path to logging directory + + exception : Exception + """ + logger = set_up_logger('failedToStart', 'failedToStart.log', 'error', + log_dir, True) + logger.exception('C-PAC failed to start') + logger.exception(exception) + + def getLogger(name): # pylint: disable=invalid-name """Function to get a mock logger if one exists, falling back on real loggers. @@ -20,20 +57,88 @@ def getLogger(name): # pylint: disable=invalid-name """ if name in MOCK_LOGGERS: return MOCK_LOGGERS[name] - return logging.getLogger(name) + logger = nipype_logging.getLogger(name) + return logging.getLogger(name) if logger is None else logger + + +def log_failed_subprocess(cpe): + """Pass STDERR from a subprocess to the interface's logger + + Parameters + ---------- + cpe : subprocess.CalledProcessError + """ + logger = getLogger('nipype.interface') + logger.error("%s\nExit code %s", cpe.output, cpe.returncode) + + +def log_subprocess(cmd, *args, raise_error=True, **kwargs): + """Pass STDERR and STDOUT from subprocess to interface's logger. + This function is nearly a drop-in replacement for + `subprocess.check_output`. + + Caveat: if you're assigning to a variable (like + + >>> output = subprocess.check_output(cmd) # doctest: +SKIP + + ), the new function also returns the command's exit code, so you can just + assign that to a throwaway variable if you don't want it + + >>> output, _ = log_subprocess(cmd) # doctest: +SKIP + + or subscript the command like + + >>> output = log_subprocess(cmd)[0] # doctest: +SKIP + + . If you're not assigning to a variable, it doesn't matter and just + + >>> log_subprocess(cmd) # doctest: +SKIP + + should work just like + + >>> subprocess.check_output(cmd) # doctest: +SKIP + + Parameters + ---------- + cmd : str + command to run with `subprocess.check_output` + + raise_error : boolean + raise any exception after logging + + args, kwargs : any + pass-through arguments for subprocess.check_output + + Returns + ------- + output : str + + exit_code : int + """ + logger = getLogger('nipype.interface') + try: + output = subprocess.check_output(cmd, *args, stderr=subprocess.STDOUT, + universal_newlines=True, **kwargs) + logger.info(output) + except subprocess.CalledProcessError as cpe: + log_failed_subprocess(cpe) + if raise_error: + raise + return cpe.output, cpe.returncode + return output, 0 # pylint: disable=too-few-public-methods class MockHandler: - '''Handler for MockLogger.''' - def __init__(self, baseFilename): - self.baseFilename = baseFilename # pylint: disable=invalid-name + """Handler for MockLogger.""" + def __init__(self, filename): + self.baseFilename = filename # pylint: disable=invalid-name # pylint: disable=too-few-public-methods class MockLogger: - '''Mock logging.Logger to provide the same API without keeping the - logger in memory.''' + """Mock logging.Logger to provide the same API without keeping the + logger in memory.""" def __init__(self, name, filename, level, log_dir): self.name = name self.level = level @@ -43,26 +148,66 @@ def __init__(self, name, filename, level, log_dir): # set up log methods for all built-in levels setattr(self, loglevel, self._factory_log(loglevel)) + def exception(self, msg, *args, exc_info=True, **kwargs): + # pylint: disable=missing-function-docstring,no-member + return self.error(msg, *args, exc_info=exc_info, **kwargs) + + exception.__doc__ = logging.exception.__doc__ + def _factory_log(self, level): r"""Generate a log method like `self.log(message)` for a given built-in level.""" @docstring_parameter(level=level) - def _log(message): + def _log(message, *items, exc_info=False): """Log a message if logging level >= {level}. See `Logging Levels `_ for a list of levels.""" if self.level == 0 or self.level >= getattr(logging, level.upper(), logging.NOTSET): - with open(self.handlers[0].baseFilename, 'a') as log_file: - print(message, file=log_file) + with open(self.handlers[0].baseFilename, 'a', + encoding='utf-8') as log_file: + if exc_info and isinstance(message, Exception): + value, traceback = sys_exc_info()[1:] + print_exception(_lazy_sub(message, *items), value=value, + tb=traceback, file=log_file) + else: + print(_lazy_sub(message, *items), file=log_file) return _log def delete(self): - '''Delete the mock logger from memory.''' + """Delete the mock logger from memory.""" del MOCK_LOGGERS[self.name] +def _lazy_sub(message, *items): + """Given lazy-logging syntax, return string with substitutions + + Parameters + ---------- + message : str + + items : tuple + + Returns + ------- + str + + Examples + -------- + >>> _lazy_sub('no substitution') + 'no substitution' + >>> _lazy_sub('%s substitution', 'yes') + 'yes substitution' + >>> _lazy_sub('%s substitution %s', 'yes', 'again') + 'yes substitution again' + """ + try: + return str(message) % items + except (AttributeError, TypeError): + return str([message, *items]) + + def set_up_logger(name, filename=None, level=None, log_dir=None, mock=False, overwrite_existing=False): - r'''Function to initialize a logger + r"""Function to initialize a logger Parameters ---------- @@ -109,7 +254,7 @@ def set_up_logger(name, filename=None, level=None, log_dir=None, mock=False, >>> lg.delete() >>> 'third_test' in MOCK_LOGGERS False - ''' + """ if filename is None: filename = f'{name}.log' try: @@ -124,7 +269,7 @@ def set_up_logger(name, filename=None, level=None, log_dir=None, mock=False, log_file.write('') if mock: return MockLogger(name, filename, level, log_dir) - logger = logging.getLogger(name) + logger = getLogger(name) logger.setLevel(level) handler = logging.FileHandler(filepath) logger.addHandler(handler) diff --git a/CPAC/utils/outputs.py b/CPAC/utils/outputs.py index 0709bbd62b..321d156b7c 100755 --- a/CPAC/utils/outputs.py +++ b/CPAC/utils/outputs.py @@ -72,3 +72,15 @@ class Outputs(): template_raw = list( reference[all_template_filter & (reference['To z-std'] == 'Yes')]['Resource']) + + + def _is_cifti(_file_key): + return _file_key.upper().startswith('CIFTI ') + ciftis = reference[reference.File.map(_is_cifti)][['Resource', 'File']] + ciftis = {cifti.Resource: cifti.File.split(' ')[-1] for cifti in ciftis.itertuples() if ' ' in cifti.File} + + def _is_gifti(_file_key): + return _file_key.upper().startswith('GIFTI ') + giftis = reference[reference.File.map(_is_gifti)][['Resource', 'File']] + giftis = {gifti.Resource: gifti.File.split(' ')[-1] for gifti in giftis.itertuples() if ' ' in gifti.File} + From b60099106d91a3656b03d0f0b4d5412e082df2a1 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 9 Feb 2023 17:32:13 +0000 Subject: [PATCH 009/213] modified files engine.py and utils.py --- CPAC/pipeline/engine.py | 4 ++-- CPAC/utils/utils.py | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index d01f92da88..cf3ec23664 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -946,7 +946,8 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): 'resource', 'scan_id', 'atlas_id', - 'fwhm'], + 'fwhm', + 'extension'], output_names=['out_filename'], function=create_id_string), name=f'id_string_{resource_idx}_{pipe_x}') @@ -1001,7 +1002,6 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): if resource in Outputs.ciftis: nii_name.inputs.keep_ext = False id_string.inputs.extension = f'{Outputs.ciftis[resource]}.nii' - raise Exception(id_string.inputs.extension) else: nii_name.inputs.keep_ext = True diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py index 16e9b4460b..0116050d43 100755 --- a/CPAC/utils/utils.py +++ b/CPAC/utils/utils.py @@ -152,7 +152,7 @@ def read_json(json_file): def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, - fwhm=None): + fwhm=None, extension=None): """Create the unique key-value identifier string for BIDS-Derivatives compliant file names. @@ -182,6 +182,9 @@ def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, else: raise Exception('\n[!] FWHM provided but no desc-sm?\n') + if extension is not None: + out_filename = out_filename.join(extension) + return out_filename From f926535f665ad6a492a84cbc07ab9304eeee6775 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 13 Feb 2023 16:37:02 +0000 Subject: [PATCH 010/213] changes made to files engine.py, utils,py and cpac_output.tsv --- CPAC/pipeline/engine.py | 2 +- CPAC/resources/cpac_outputs.tsv | 2 ++ CPAC/utils/utils.py | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index cf3ec23664..2653fef0f9 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1005,7 +1005,7 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): else: nii_name.inputs.keep_ext = True - #raise Exception(Outputs.giftis) + if resource in Outputs.giftis: nii_name.inputs.keep_ext = False diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index ce96615e90..3312129763 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -301,3 +301,5 @@ hemi-L_space-fsLR_den-32k_white_surf surface_derived func GIFTI surf hemi-R_space-fsLR_den-32k_white_surf surface_derived func GIFTI surf hemi-L_space-native_white_surf surface_derived func GIFTI surf hemi-R_space-native_white_surf surface_derived func GIFTI surf +surf_alff surface_derived func CIFTI dscalar +surf_falff surface_derived func CIFTI dscalar diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py index 0116050d43..746c911825 100755 --- a/CPAC/utils/utils.py +++ b/CPAC/utils/utils.py @@ -181,9 +181,11 @@ def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, break else: raise Exception('\n[!] FWHM provided but no desc-sm?\n') - + + if extension is not None: - out_filename = out_filename.join(extension) + out_filename = out_filename + "." + str(extension) + raise Exception(out_filename) return out_filename From d6a9eab47ae2ce33115444bd77600fc7c0864350 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 21 Feb 2023 15:06:49 +0000 Subject: [PATCH 011/213] modified files engine.py, cpac_outputs.tsv, surf_preproc.py and utils.py --- CPAC/pipeline/engine.py | 2 +- CPAC/resources/cpac_outputs.tsv | 614 ++++++++++++++++---------------- CPAC/surface/surf_preproc.py | 342 +++++++++--------- CPAC/utils/utils.py | 6 +- 4 files changed, 486 insertions(+), 478 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 2653fef0f9..ccf157fde0 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1001,7 +1001,7 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): if resource in Outputs.ciftis: nii_name.inputs.keep_ext = False - id_string.inputs.extension = f'{Outputs.ciftis[resource]}.nii' + id_string.inputs.extension = Outputs.ciftis[resource] else: nii_name.inputs.keep_ext = True diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 3312129763..a156683ad5 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -1,305 +1,309 @@ -Resource Type Space Sub-Directory File To Smooth To z-std 4D Time Series Optional: Debugging Multi-File -alff alff functional func NIfTI Yes Yes -desc-sm_alff alff functional func NIfTI Yes -desc-sm-zstd_alff alff functional func NIfTI -desc-zstd_alff alff functional func NIfTI -space-template_alff alff template func NIfTI Yes Yes -space-template_desc-sm_alff alff template func NIfTI Yes -space-template_desc-sm-zstd_alff alff template func NIfTI -space-template_desc-zstd_alff alff template func NIfTI -desc-brain_bold bold functional func NIfTI Yes Yes -desc-cleaned_bold bold functional func NifTI Yes Yes -desc-mean_bold bold functional func NIfTI -desc-motion_bold bold functional func NIfTI Yes Yes -desc-preproc_bold bold functional func NIfTI Yes -desc-sm_bold bold functional func NIfTI Yes Yes -space-EPItemplate_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-cleaned_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-mean_bold bold EPI template func NIfTI -space-EPItemplate_desc-preproc_bold bold EPI template func NIfTI Yes -space-symtemplate_desc-sm_bold bold symmetric template func NIfTI Yes Yes -space-T1w_desc-mean_bold bold T1w func NIfTI -space-template_bold bold template func NIfTI Yes -space-template_desc-brain_bold bold template func NIfTI Yes -space-template_desc-cleaned_bold bold template func NIfTI Yes -space-template_desc-head_bold bold template func NIfTI Yes -space-template_desc-mean_bold bold template func NIfTI -space-template_desc-preproc_bold bold template func NIfTI Yes -space-template_desc-scout_bold bold template func NIfTI -desc-DualReg_correlations correlation template func NIfTI -desc-MeanSCA_correlations correlation template func NIfTI -desc-MultReg_correlations correlation template func NIfTI -desc-ndmg_correlations correlation template func NIfTI -desc-PearsonAfni_correlations correlation template func tsv -desc-PartialAfni_correlations correlation template func tsv -desc-PearsonNilearn_correlations correlation template func tsv -desc-PartialNilearn_correlations correlation template func tsv -space-template_desc-binarized_degree-centrality degree-centrality template func NIfTI Yes Yes -space-template_desc-binarized-sm_degree-centrality degree-centrality template func NIfTI Yes -space-template_desc-binarized-sm-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-binarized-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-weighted_degree-centrality degree-centrality template func NIfTI Yes Yes -space-template_desc-weighted-sm_degree-centrality degree-centrality template func NIfTI Yes -space-template_desc-weighted-sm-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-weighted-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-binarized_eigen-centrality eigen-centrality template func NIfTI Yes Yes -space-template_desc-binarized-sm_eigen-centrality eigen-centrality template func NIfTI Yes -space-template_desc-binarized-sm-zstd_eigen-centrality eigen-centrality template func NIfTI -space-template_desc-binarized-zstd_eigen-centrality eigen-centrality template func NIfTI -space-template_desc-weighted_eigen-centrality eigen-centrality template func NIfTI Yes Yes -space-template_desc-weighted-sm_eigen-centrality eigen-centrality template func NIfTI Yes -space-template_desc-weighted-sm-zstd_eigen-centrality eigen-centrality template func NIfTI -space-template_desc-weighted-zstd_eigen-centrality eigen-centrality template func NIfTI -desc-sm_falff falff functional func NIfTI Yes -desc-sm-zstd_falff falff functional func NIfTI -desc-zstd_falff falff functional func NIfTI -falff falff functional func NIfTI Yes Yes -space-template_desc-sm_falff falff template func NIfTI Yes -space-template_desc-sm-zstd_falff falff template func NIfTI -space-template_desc-zstd_falff falff template func NIfTI -space-template_falff falff template func NIfTI Yes Yes -space-template_desc-binarized_lfcd lfcd template func NIfTI Yes Yes -space-template_desc-binarized-sm_lfcd lfcd template func NIfTI Yes -space-template_desc-binarized-sm-zstd_lfcd lfcd template func NIfTI -space-template_desc-binarized-zstd_lfcd lfcd template func NIfTI -space-template_desc-weighted_lfcd lfcd template func NIfTI Yes Yes -space-template_desc-weighted-sm_lfcd lfcd template func NIfTI Yes -space-template_desc-weighted-sm-zstd_lfcd lfcd template func NIfTI -space-template_desc-weighted-zstd_lfcd lfcd template func NIfTI -space-EPItemplate_desc-bold_mask mask EPI template func NIfTI -space-EPItemplate_res-derivative_desc-bold_mask mask EPI template func NIfTI -space-bold_desc-brain_mask mask functional func NIfTI -space-bold_desc-eroded_mask mask functional func NIfTI -space-bold_label-CSF_desc-eroded_mask mask functional func NIfTI -space-bold_label-CSF_mask mask functional func NIfTI -space-bold_label-GM_desc-eroded_mask mask functional func NIfTI -space-bold_label-GM_mask mask functional func NIfTI -space-bold_label-WM_desc-eroded_mask mask functional func NIfTI -space-bold_label-WM_mask mask functional func NIfTI -space-longitudinal_desc-brain_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-CSF_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-CSF_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-GM_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-GM_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-WM_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-WM_mask mask longitudinal T1w anat NIfTI -label-CSF_desc-eroded_mask mask T1w anat NIfTI -label-CSF_desc-preproc_mask mask T1w anat NIfTI -label-CSF_mask mask T1w anat NIfTI -label-GM_desc-eroded_mask mask T1w anat NIfTI -label-GM_desc-preproc_mask mask T1w anat NIfTI -label-GM_mask mask T1w anat NIfTI -label-WM_desc-eroded_mask mask T1w anat NIfTI -label-WM_desc-preproc_mask mask T1w anat NIfTI -label-WM_mask mask T1w anat NIfTI -space-T1w_desc-acpcbrain_mask mask T1w anat NIfTI -space-T1w_desc-brain_mask mask T1w anat NIfTI -space-T1w_desc-eroded_mask mask T1w anat NIfTI -space-template_desc-bold_mask mask template func NIfTI -space-template_res-derivative_desc-bold_mask mask template func NIfTI -dvars motion func text -framewise-displacement-jenkinson motion func 1D -framewise-displacement-power motion func 1D -max-displacement motion func 1D -motion-filter-info motion func text -motion-filter-plot motion func png -motion-params motion func text -movement-parameters motion func 1D -power-params motion func text -rels-displacement motion func 1D -label-CSF_probseg probseg T1w anat NIfTI -label-GM_probseg probseg T1w anat NIfTI -label-WM_probseg probseg T1w anat NIfTI -T1w-axial-qc qc anat png -T1w-sagittal-qc qc anat png -dseg-axial-qc qc anat png -desg-sagittal-qc qc anat png -bold-axial-qc qc func png -bold-sagittal-qc qc func png -bold-carpet-qc qc func png -framewise-displacement-jenkinson-plot-qc qc func png -movement-parameters-trans-qc qc func png -movement-parameters-rot-qc qc func png -bold-snr-axial-qc qc func png -bold-snr-sagittal-qc qc func png -bold-snr-hist-qc qc func png -bold-snr-qc qc func png -space-template_desc-xcp_quality qc func tsv -regressors regressors func 1D -desc-sm_reho reho functional func NIfTI Yes -desc-sm-zstd_reho reho functional func NIfTI -desc-zstd_reho reho functional func NIfTI -reho reho functional func NIfTI Yes Yes -space-template_desc-sm_reho reho template func NIfTI Yes -space-template_desc-sm-zstd_reho reho template func NIfTI -space-template_desc-zstd_reho reho template func NIfTI -space-template_reho reho template func NIfTI Yes Yes -desc-DualReg_statmap statistic template func NIfTI -desc-MultReg_statmap statistic template func NIfTI -hemi-L_desc-surfaceMap_thickness surface-derived anat Yes -hemi-R_desc-surfaceMap_thickness surface-derived anat Yes -hemi-L_desc-surfaceMap_volume surface-derived anat Yes -hemi-R_desc-surfaceMap_volume surface-derived anat Yes -hemi-L_desc-surfaceMesh_pial surface-derived anat -hemi-R_desc-surfaceMesh_pial surface-derived anat -raw-average surface-derived anat -hemi-L_desc-surfaceMesh_smoothwm surface-derived anat -hemi-R_desc-surfaceMesh_smoothwm surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-32k.dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-32k.dlabel surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-164k.dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-164k.dlabel surface-derived anat -space-fsLR_den-32k_bold-dtseries surface-derived func -hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes -hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes -hemi-L_desc-surfaceMap_sulc surface-derived anat Yes -hemi-R_desc-surfaceMap_sulc surface-derived anat Yes -hemi-L_desc-surface_curv surface-derived anat -hemi-R_desc-surface_curv surface-derived anat -hemi-L_desc-surfaceMesh_white surface-derived anat Yes -hemi-R_desc-surfaceMesh_white surface-derived anat Yes -wmparc surface-derived anat Yes -space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI -desc-brain_T1w T1w T1w anat NIfTI -desc-preproc_T1w T1w T1w anat NIfTI -desc-reorient_T1w T1w T1w anat NIfTI -desc-restore_T1w T1w T1w anat NIfTI -desc-restore-brain_T1w T1w T1w anat NIfTI -space-template_desc-brain_T1w T1w template anat NIfTI -space-template_desc-head_T1w T1w template anat NIfTI -space-template_desc-T1w_mask mask template anat NIfTI -desc-Mean_timeseries timeseries func 1D -desc-MeanSCA_timeseries timeseries func 1D -desc-SpatReg_timeseries timeseries func 1D -desc-Voxel_timeseries timeseries func 1D -space-longitudinal_label-CSF_probseg tissue probability longitudinal T1w anat NIfTI -space-longitudinal_label-GM_probseg tissue probability longitudinal T1w anat NIfTI -space-longitudinal_label-WM_probseg tissue probability longitudinal T1w anat NIfTI -vmhc vmhc symmetric template func NIfTI -blip-warp xfm func NIfTI -from-bold_to-EPItemplate_mode-image_desc-linear_xfm xfm func NIfTI -from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm xfm func NIfTI -from-bold_to-EPItemplate_mode-image_xfm xfm func NIfTI -from-bold_to-symtemplate_mode-image_xfm xfm func NIfTI -from-bold_to-T1w_mode-image_desc-linear_xfm xfm func NIfTI -from-bold_to-template_mode-image_xfm xfm func NIfTI -from-EPItemplate_to-bold_mode-image_desc-linear_xfm xfm func NIfTI -from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm xfm func NIfTI -from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI -from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-longitudinal_to-symtemplate_mode-image_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_desc-linear_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_xfm xfm anat NIfTI -from-symtemplate_to-bold_mode-image_xfm xfm func NIfTI -from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI -from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-symtemplate_to-longitudinal_mode-image_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_desc-linear_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_xfm xfm anat NIfTI -from-template_to-bold_mode-image_xfm xfm func NIfTI -from-template_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI -from-template_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-template_to-longitudinal_mode-image_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_xfm xfm anat NIfTI -space-template_label-CSF_mask mask template anat NIfTI -space-template_label-WM_mask mask template anat NIfTI -space-template_label-GM_mask mask template anat NIfTI -space-EPItemplate_label-CSF_mask mask template func NIfTI -space-EPItemplate_label-WM_mask mask template func NIfTI -space-EPItemplate_label-GM_mask mask template func NIfTI -AtlasSubcortical_s2 surface_derived func -dtseries surface_derived func CIFTI dtseries -goodvoxels surface_derived func -ribbon_only surface_derived func -atlasroi_hemi-L_space-fsLR_den-32k_func surface_derived func GIFTI func -atlasroi_hemi-R_space-fsLR_den-32k_func surface_derived func GIFTI func -atlasroi_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape -atlasroi_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape -space-native_hemi-L_func surface_derived func GIFTI func -space-native_hemi-R_func surface_derived func GIFTI func -space-fsLR_den-32k_wb-spec surface_derived func GIFTI spec -space-native_wb-spec surface_derived func GIFTI spec -arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape -arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape -arealdistortion-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape -arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape -arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape -edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape -edgedistortion-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape surface_derived func GIFTI shape -edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape surface_derived func GIFTI shape -edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_curv_shape surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_curv_shape surface_derived func GIFTI shape -space-fsLR_den-32k_curv_dscalar surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_flat_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_flat_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_inflated_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_inflated_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_very-inflated_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_very-inflated_surf surface_derived func GIFTI surf -hemi-L_space-native_inflated_surf surface_derived func GIFTI surf -hemi-R_space-native_inflated_surf surface_derived func GIFTI surf -hemi-L_space-native_very-inflated_surf surface_derived func GIFTI surf -hemi-R_space-native_very-inflated_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-164k_midthickness_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-164k_midthickness_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_midthickness_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_midthickness_surf surface_derived func GIFTI surf -hemi-L_space-native_midthickness_surf surface_derived func GIFTI surf -hemi-R_space-native_midthickness_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_pial_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_pial_surf surface_derived func GIFTI surf -hemi-L_space-native_den-32k_pial_surf surface_derived func GIFTI surf -hemi-R_space-native_den-32k_pial_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_sphere_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_sphere_surf surface_derived func GIFTI surf -hemi-L_MSMSulc_space-native_sphere_surf surface_derived func GIFTI surf -hemi-R_MSMSulc_space-native_sphere_surf surface_derived func GIFTI surf -hemi-L_space-native_sphere_surf surface_derived func GIFTI surf -hemi-R_space-native_sphere_surf surface_derived func GIFTI surf -hemi-L_space-native_sphere-reg_surf surface_derived func GIFTI surf -hemi-R_space-native_sphere-reg_surf surface_derived func GIFTI surf -hemi-L_space-native_sphere-reg-reg_surf surface_derived func GIFTI surf -hemi-R_space-native_sphere-reg-reg_surf surface_derived func GIFTI surf -hemi-L_space-native_sphere-rot_surf surface_derived func GIFTI surf -hemi-R_space-native_sphere-rot_surf surface_derived func GIFTI surf -hemi-L_strainJ-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape -hemi-R_strainJ-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape -strainJ-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape -hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape -strainJ-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -hemi-L_strainR-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape -hemi-R_strainR-FS_space-fsLR_den-32k_shape surface_derived func GIFTI shape -strainR-FS_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape -hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape surface_derived func GIFTI shape -strainR-MSMSulc_space-fsLR_den-32k_dscalar surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_sulc_shape surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_sulc_shape surface_derived func GIFTI shape -space-fsLR_den-32k_sulc_dscalar surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_thickness_shape surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_thickness_shape surface_derived func GIFTI shape -space-fsLR_den-32k_thickness_dscalar surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-164k_white_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-164k_white_surf surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_white_surf surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_white_surf surface_derived func GIFTI surf -hemi-L_space-native_white_surf surface_derived func GIFTI surf -hemi-R_space-native_white_surf surface_derived func GIFTI surf -surf_alff surface_derived func CIFTI dscalar -surf_falff surface_derived func CIFTI dscalar +Resource Type Space Sub-Directory File To Smooth To z-std 4D Time Series Optional: Debugging Multi-File +alff alff functional func NIfTI Yes Yes +desc-sm_alff alff functional func NIfTI Yes +desc-sm-zstd_alff alff functional func NIfTI +desc-zstd_alff alff functional func NIfTI +space-template_alff alff template func NIfTI Yes Yes +space-template_desc-sm_alff alff template func NIfTI Yes +space-template_desc-sm-zstd_alff alff template func NIfTI +space-template_desc-zstd_alff alff template func NIfTI +desc-brain_bold bold functional func NIfTI Yes Yes +desc-cleaned_bold bold functional func NifTI Yes Yes +desc-mean_bold bold functional func NIfTI +desc-motion_bold bold functional func NIfTI Yes Yes +desc-preproc_bold bold functional func NIfTI Yes +desc-sm_bold bold functional func NIfTI Yes Yes +space-EPItemplate_bold bold EPI template func NIfTI Yes +space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes +space-EPItemplate_desc-cleaned_bold bold EPI template func NIfTI Yes +space-EPItemplate_desc-mean_bold bold EPI template func NIfTI +space-EPItemplate_desc-preproc_bold bold EPI template func NIfTI Yes +space-symtemplate_desc-sm_bold bold symmetric template func NIfTI Yes Yes +space-T1w_desc-mean_bold bold T1w func NIfTI +space-template_bold bold template func NIfTI Yes +space-template_desc-brain_bold bold template func NIfTI Yes +space-template_desc-cleaned_bold bold template func NIfTI Yes +space-template_desc-head_bold bold template func NIfTI Yes +space-template_desc-mean_bold bold template func NIfTI +space-template_desc-preproc_bold bold template func NIfTI Yes +space-template_desc-scout_bold bold template func NIfTI +desc-DualReg_correlations correlation template func NIfTI +desc-MeanSCA_correlations correlation template func NIfTI +desc-MultReg_correlations correlation template func NIfTI +desc-ndmg_correlations correlation template func NIfTI +desc-PearsonAfni_correlations correlation template func tsv +desc-PartialAfni_correlations correlation template func tsv +desc-PearsonNilearn_correlations correlation template func tsv +desc-PartialNilearn_correlations correlation template func tsv +space-template_desc-binarized_degree-centrality degree-centrality template func NIfTI Yes Yes +space-template_desc-binarized-sm_degree-centrality degree-centrality template func NIfTI Yes +space-template_desc-binarized-sm-zstd_degree-centrality degree-centrality template func NIfTI +space-template_desc-binarized-zstd_degree-centrality degree-centrality template func NIfTI +space-template_desc-weighted_degree-centrality degree-centrality template func NIfTI Yes Yes +space-template_desc-weighted-sm_degree-centrality degree-centrality template func NIfTI Yes +space-template_desc-weighted-sm-zstd_degree-centrality degree-centrality template func NIfTI +space-template_desc-weighted-zstd_degree-centrality degree-centrality template func NIfTI +space-template_desc-binarized_eigen-centrality eigen-centrality template func NIfTI Yes Yes +space-template_desc-binarized-sm_eigen-centrality eigen-centrality template func NIfTI Yes +space-template_desc-binarized-sm-zstd_eigen-centrality eigen-centrality template func NIfTI +space-template_desc-binarized-zstd_eigen-centrality eigen-centrality template func NIfTI +space-template_desc-weighted_eigen-centrality eigen-centrality template func NIfTI Yes Yes +space-template_desc-weighted-sm_eigen-centrality eigen-centrality template func NIfTI Yes +space-template_desc-weighted-sm-zstd_eigen-centrality eigen-centrality template func NIfTI +space-template_desc-weighted-zstd_eigen-centrality eigen-centrality template func NIfTI +desc-sm_falff falff functional func NIfTI Yes +desc-sm-zstd_falff falff functional func NIfTI +desc-zstd_falff falff functional func NIfTI +falff falff functional func NIfTI Yes Yes +space-template_desc-sm_falff falff template func NIfTI Yes +space-template_desc-sm-zstd_falff falff template func NIfTI +space-template_desc-zstd_falff falff template func NIfTI +space-template_falff falff template func NIfTI Yes Yes +space-template_desc-binarized_lfcd lfcd template func NIfTI Yes Yes +space-template_desc-binarized-sm_lfcd lfcd template func NIfTI Yes +space-template_desc-binarized-sm-zstd_lfcd lfcd template func NIfTI +space-template_desc-binarized-zstd_lfcd lfcd template func NIfTI +space-template_desc-weighted_lfcd lfcd template func NIfTI Yes Yes +space-template_desc-weighted-sm_lfcd lfcd template func NIfTI Yes +space-template_desc-weighted-sm-zstd_lfcd lfcd template func NIfTI +space-template_desc-weighted-zstd_lfcd lfcd template func NIfTI +space-EPItemplate_desc-bold_mask mask EPI template func NIfTI +space-EPItemplate_res-derivative_desc-bold_mask mask EPI template func NIfTI +space-bold_desc-brain_mask mask functional func NIfTI +space-bold_desc-eroded_mask mask functional func NIfTI +space-bold_label-CSF_desc-eroded_mask mask functional func NIfTI +space-bold_label-CSF_mask mask functional func NIfTI +space-bold_label-GM_desc-eroded_mask mask functional func NIfTI +space-bold_label-GM_mask mask functional func NIfTI +space-bold_label-WM_desc-eroded_mask mask functional func NIfTI +space-bold_label-WM_mask mask functional func NIfTI +space-longitudinal_desc-brain_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-CSF_desc-preproc_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-CSF_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-GM_desc-preproc_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-GM_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-WM_desc-preproc_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-WM_mask mask longitudinal T1w anat NIfTI +label-CSF_desc-eroded_mask mask T1w anat NIfTI +label-CSF_desc-preproc_mask mask T1w anat NIfTI +label-CSF_mask mask T1w anat NIfTI +label-GM_desc-eroded_mask mask T1w anat NIfTI +label-GM_desc-preproc_mask mask T1w anat NIfTI +label-GM_mask mask T1w anat NIfTI +label-WM_desc-eroded_mask mask T1w anat NIfTI +label-WM_desc-preproc_mask mask T1w anat NIfTI +label-WM_mask mask T1w anat NIfTI +space-T1w_desc-acpcbrain_mask mask T1w anat NIfTI +space-T1w_desc-brain_mask mask T1w anat NIfTI +space-T1w_desc-eroded_mask mask T1w anat NIfTI +space-template_desc-bold_mask mask template func NIfTI +space-template_res-derivative_desc-bold_mask mask template func NIfTI +dvars motion func text +framewise-displacement-jenkinson motion func 1D +framewise-displacement-power motion func 1D +max-displacement motion func 1D +motion-filter-info motion func text +motion-filter-plot motion func png +motion-params motion func text +movement-parameters motion func 1D +power-params motion func text +rels-displacement motion func 1D +label-CSF_probseg probseg T1w anat NIfTI +label-GM_probseg probseg T1w anat NIfTI +label-WM_probseg probseg T1w anat NIfTI +T1w-axial-qc qc anat png +T1w-sagittal-qc qc anat png +dseg-axial-qc qc anat png +desg-sagittal-qc qc anat png +bold-axial-qc qc func png +bold-sagittal-qc qc func png +bold-carpet-qc qc func png +framewise-displacement-jenkinson-plot-qc qc func png +movement-parameters-trans-qc qc func png +movement-parameters-rot-qc qc func png +bold-snr-axial-qc qc func png +bold-snr-sagittal-qc qc func png +bold-snr-hist-qc qc func png +bold-snr-qc qc func png +space-template_desc-xcp_quality qc func tsv +regressors regressors func 1D +desc-sm_reho reho functional func NIfTI Yes +desc-sm-zstd_reho reho functional func NIfTI +desc-zstd_reho reho functional func NIfTI +reho reho functional func NIfTI Yes Yes +space-template_desc-sm_reho reho template func NIfTI Yes +space-template_desc-sm-zstd_reho reho template func NIfTI +space-template_desc-zstd_reho reho template func NIfTI +space-template_reho reho template func NIfTI Yes Yes +desc-DualReg_statmap statistic template func NIfTI +desc-MultReg_statmap statistic template func NIfTI +hemi-L_desc-surfaceMap_thickness surface-derived anat Yes +hemi-R_desc-surfaceMap_thickness surface-derived anat Yes +hemi-L_desc-surfaceMap_volume surface-derived anat Yes +hemi-R_desc-surfaceMap_volume surface-derived anat Yes +hemi-L_desc-surfaceMesh_pial surface-derived anat +hemi-R_desc-surfaceMesh_pial surface-derived anat +raw-average surface-derived anat +hemi-L_desc-surfaceMesh_smoothwm surface-derived anat +hemi-R_desc-surfaceMesh_smoothwm surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-32k.dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-32k.dlabel surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-164k.dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-164k.dlabel surface-derived anat +space-fsLR_den-32k_bold-dtseries surface-derived func +hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes +hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes +hemi-L_desc-surfaceMap_sulc surface-derived anat Yes +hemi-R_desc-surfaceMap_sulc surface-derived anat Yes +hemi-L_desc-surface_curv surface-derived anat +hemi-R_desc-surface_curv surface-derived anat +hemi-L_desc-surfaceMesh_white surface-derived anat Yes +hemi-R_desc-surfaceMesh_white surface-derived anat Yes +wmparc surface-derived anat Yes +space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI +desc-brain_T1w T1w T1w anat NIfTI +desc-preproc_T1w T1w T1w anat NIfTI +desc-reorient_T1w T1w T1w anat NIfTI +desc-restore_T1w T1w T1w anat NIfTI +desc-restore-brain_T1w T1w T1w anat NIfTI +space-template_desc-brain_T1w T1w template anat NIfTI +space-template_desc-head_T1w T1w template anat NIfTI +space-template_desc-T1w_mask mask template anat NIfTI +desc-Mean_timeseries timeseries func 1D +desc-MeanSCA_timeseries timeseries func 1D +desc-SpatReg_timeseries timeseries func 1D +desc-Voxel_timeseries timeseries func 1D +space-longitudinal_label-CSF_probseg tissue probability longitudinal T1w anat NIfTI +space-longitudinal_label-GM_probseg tissue probability longitudinal T1w anat NIfTI +space-longitudinal_label-WM_probseg tissue probability longitudinal T1w anat NIfTI +vmhc vmhc symmetric template func NIfTI +blip-warp xfm func NIfTI +from-bold_to-EPItemplate_mode-image_desc-linear_xfm xfm func NIfTI +from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm xfm func NIfTI +from-bold_to-EPItemplate_mode-image_xfm xfm func NIfTI +from-bold_to-symtemplate_mode-image_xfm xfm func NIfTI +from-bold_to-T1w_mode-image_desc-linear_xfm xfm func NIfTI +from-bold_to-template_mode-image_xfm xfm func NIfTI +from-EPItemplate_to-bold_mode-image_desc-linear_xfm xfm func NIfTI +from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm xfm func NIfTI +from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI +from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-longitudinal_to-symtemplate_mode-image_xfm xfm anat NIfTI +from-longitudinal_to-template_mode-image_desc-linear_xfm xfm anat NIfTI +from-longitudinal_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-longitudinal_to-template_mode-image_xfm xfm anat NIfTI +from-symtemplate_to-bold_mode-image_xfm xfm func NIfTI +from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI +from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-symtemplate_to-longitudinal_mode-image_xfm xfm anat NIfTI +from-symtemplate_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI +from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-symtemplate_to-T1w_mode-image_xfm xfm anat NIfTI +from-T1w_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI +from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-T1w_to-symtemplate_mode-image_xfm xfm anat NIfTI +from-T1w_to-template_mode-image_desc-linear_xfm xfm anat NIfTI +from-T1w_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-T1w_to-template_mode-image_xfm xfm anat NIfTI +from-template_to-bold_mode-image_xfm xfm func NIfTI +from-template_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI +from-template_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-template_to-longitudinal_mode-image_xfm xfm anat NIfTI +from-template_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI +from-template_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-template_to-T1w_mode-image_xfm xfm anat NIfTI +space-template_label-CSF_mask mask template anat NIfTI +space-template_label-WM_mask mask template anat NIfTI +space-template_label-GM_mask mask template anat NIfTI +space-EPItemplate_label-CSF_mask mask template func NIfTI +space-EPItemplate_label-WM_mask mask template func NIfTI +space-EPItemplate_label-GM_mask mask template func NIfTI +AtlasSubcortical_s2 surface_derived func +space-fsLR_den-32k_bold surface_derived func CIFTI dtseries +goodvoxels surface_derived func +ribbon_only surface_derived func +hemi-L_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func +hemi-R_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func +hemi-L_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape +hemi-L_space-native_bold surface_derived func GIFTI func +hemi-R_space-native_bold surface_derived func GIFTI func +space-fsLR_den-32k_wb-spec surface_derived func GIFTI spec +space-native_wb-spec surface_derived func GIFTI spec +hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_curv surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_curv surface_derived func GIFTI shape +space-fsLR_den-32k_curv surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_flat surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_flat surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_inflated surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_inflated surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_veryinflated surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_veryinflated surface_derived func GIFTI surf +hemi-L_space-native_inflated surface_derived func GIFTI surf +hemi-R_space-native_inflated surface_derived func GIFTI surf +hemi-L_space-native_veryinflated surface_derived func GIFTI surf +hemi-R_space-native_veryinflated surface_derived func GIFTI surf +hemi-L_space-fsLR_den-164k_midthickness surface_derived func GIFTI surf +hemi-R_space-fsLR_den-164k_midthickness surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_midthickness surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_midthickness surface_derived func GIFTI surf +hemi-L_space-native_midthickness surface_derived func GIFTI surf +hemi-R_space-native_midthickness surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_pial surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_pial surface_derived func GIFTI surf +hemi-L_space-native_den-32k_pial surface_derived func GIFTI surf +hemi-R_space-native_den-32k_pial surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_sphere surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-MSMSulc_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-MSMSulc_sphere surface_derived func GIFTI surf +hemi-L_space-native_sphere surface_derived func GIFTI surf +hemi-R_space-native_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-reg_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-reg_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-reg-reg_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-reg-reg_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-rot_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-rot_sphere surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_desc-FS_strainJ surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_strainJ surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_strainJ surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-FS_strainR surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_strainR surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_strainR surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_sulc surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_sulc surface_derived func GIFTI shape +"space-fsLR_den-32k_sulc""" surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_thickness surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_thickness surface_derived func GIFTI shape +space-fsLR_den-32k_thickness surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-164k_white surface_derived func GIFTI surf +hemi-R_space-fsLR_den-164k_white surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_white surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_white surface_derived func GIFTI surf +hemi-L_space-native_white surface_derived func GIFTI surf +hemi-R_space-native_white surface_derived func GIFTI surf +atlas-DesikanKilliany_space-fsLR_den-32k surface_derived func CIFTI dlabel +atlas-Destrieux_space-fsLR_den-32k surface_derived func CIFTI dlabel +atlas-DesikanKilliany_space-fsLR_den-164k surface_derived func CIFTI dlabel +atlas-Destrieux_space-fsLR_den-164k surface_derived func CIFTI dlabel +surf_alff surface_derived func CIFTI dscalar +surf_falff surface_derived func CIFTI dscalar \ No newline at end of file diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 74db667222..f6f8e98962 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -615,129 +615,129 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): wf.connect(node, out, surf, 'scout_bold') outputs = { - 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries'), - 'atlas-DesikanKilliany_space-fsLR_den-32k_dlabel': (surf, + 'space-fsLR_den-32k_bold': (surf, 'dtseries'), + 'atlas-DesikanKilliany_space-fsLR_den-32k': (surf, 'desikan_' 'killiany_32'), - 'atlas-Destrieux_space-fsLR_den-32k_dlabel': (surf, 'destrieux_32'), - 'atlas-DesikanKilliany_space-fsLR_den-164k_dlabel': (surf, + 'atlas-Destrieux_space-fsLR_den-32k': (surf, 'destrieux_32'), + 'atlas-DesikanKilliany_space-fsLR_den-164k': (surf, 'desikan_' 'killiany_164'), - 'atlas-Destrieux_space-fsLR_den-164k_dlabel': (surf, 'destrieux_164'), + 'atlas-Destrieux_space-fsLR_den-164k': (surf, 'destrieux_164'), 'AtlasSubcortical_s2': (surf, 'subcortical_atlas'), 'goodvoxels': (surf, 'good_voxels'), 'ribbon_only': (surf, 'ribbon_only'), - 'atlasroi_hemi-L_space-fsLR_den-32k_func': (surf, + 'hemi-L_space-fsLR_den-32k_desc-atlasroi_bold': (surf, 'atlas_roi_func_' 'L'), - 'atlasroi_hemi-R_space-fsLR_den-32k_func': (surf, + 'hemi-R_space-fsLR_den-32k_desc-atlasroi_bold': (surf, 'atlas_roi_func_' 'R'), - 'atlasroi_hemi-L_space-fsLR_den-32k_shape': (surf, + 'hemi-L_space-fsLR_den-32k_desc-atlasroi_mask': (surf, 'atlas_roi_shape_' 'L'), - 'atlasroi_hemi-R_space-fsLR_den-32k_shape': (surf, + 'hemi-R_space-fsLR_den-32k_desc-atlasroi_mask': (surf, 'atlas_roi_shape_' 'R'), - 'space-native_hemi-L_func': (surf, 'native_' 'L'), - 'space-native_hemi-R_func': (surf, 'native_' 'R'), + 'hemi-L_space-native_bold': (surf, 'native_' 'L'), + 'hemi-R_space-native_bold': (surf, 'native_' 'R'), 'space-fsLR_den-32k_wb-spec': (surf, 'spec_' 'LR_32k'), 'space-native_wb-spec': (surf, 'spec_' 'native'), - 'arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion': (surf, 'areal_distortion_' 'FS_' 'L'), - 'arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion': (surf, 'areal_distortion_' 'FS_' 'R'), - 'arealdistortion-FS_space-fsLR_den-32k_dscalar': (surf, 'areal_distortion_' + 'space-fsLR_den-32k_desc-FS_arealdistortion': (surf, 'areal_distortion_' 'FS_' 'dscalar'), - 'arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion': (surf, 'areal_distortion_' 'MSMSulc_' 'L'), - 'arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape': (surf, 'areal_distortion_' + 'hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion': (surf, 'areal_distortion_' 'MSMSulc_' 'R'), - 'arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'areal_distortion_' + 'space-fsLR_den-32k_desc-MSMSulc_arealdistortion': (surf, 'areal_distortion_' 'MSMSulc_' 'dscalar'), - 'edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion': (surf, 'edge_distortion_' 'FS_' 'L'), - 'edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion': (surf, 'edge_distortion_' 'FS_' 'R'), - 'edgedistortion-FS_space-fsLR_den-32k_dscalar': (surf, 'edge_distortion_' + 'space-fsLR_den-32k_desc-FS_edgedistortion': (surf, 'edge_distortion_' 'FS_' 'dscalar'), - 'edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion': (surf, 'edge_distortion_' 'MSMSulc_' 'L'), - 'edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape': (surf, 'edge_distortion_' + 'hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion': (surf, 'edge_distortion_' 'MSMSulc_' 'R'), - 'edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'edge_distortion_' + 'space-fsLR_den-32k_desc-MSMSulc_edgedistortion': (surf, 'edge_distortion_' 'MSMSulc_' 'dscalar'), - 'hemi-L_space-fsLR_den-32k_curv_shape': (surf, 'curvature_' 'L'), - 'hemi-R_space-fsLR_den-32k_curv_shape': (surf, 'curvature_' 'R'), - 'space-fsLR_den-32k_curv_dscalar': (surf, 'curvature_' 'dscalar'), - 'hemi-L_space-fsLR_den-32k_flat_surf': (surf, 'flat_L'), - 'hemi-R_space-fsLR_den-32k_flat_surf': (surf, 'flat_R'), - 'hemi-L_space-fsLR_den-32k_inflated_surf': (surf, '32k_inflated_L'), - 'hemi-R_space-fsLR_den-32k_inflated_surf': (surf, '32k_inflated_R'), - 'hemi-L_space-fsLR_den-32k_very-inflated_surf': (surf, '32k_very_inflated_L'), - 'hemi-R_space-fsLR_den-32k_very-inflated_surf': (surf, '32k_very_inflated_R'), - 'hemi-L_space-native_inflated_surf': (surf, 'inflated_L'), - 'hemi-R_space-native_inflated_surf': (surf, 'inflated_R'), - 'hemi-L_space-native_very-inflated_surf': (surf, 'very_inflated_L'), - 'hemi-R_space-native_very-inflated_surf': (surf, 'very_inflated_R'), - 'hemi-L_space-fsLR_den-164k_midthickness_surf': (surf, 'midthickness_L_164'), - 'hemi-L_space-fsLR_den-32k_midthickness_surf': (surf, 'midthickness_L_32'), - 'hemi-L_space-native_midthickness_surf': (surf, 'midthickness_L_native'), - 'hemi-R_space-fsLR_den-164k_midthickness_surf': (surf, 'midthickness_R_164'), - 'hemi-R_space-fsLR_den-32k_midthickness_surf': (surf, 'midthickness_R_32'), - 'hemi-R_space-native_midthickness_surf': (surf, 'midthickness_R_native'), - 'hemi-L_space-fsLR_den-32k_pial_surf': (surf, 'pial_L_32'), - 'hemi-L_space-native_den-32k_pial_surf': (surf, 'pial_L_native'), - 'hemi-R_space-fsLR_den-32k_pial_surf': (surf, 'pial_R_32'), - 'hemi-R_space-native_den-32k_pial_surf': (surf, 'pial_R_native'), - 'hemi-L_space-fsLR_den-32k_sphere_surf': (surf, 'sphere_32k_fs_LR_L'), - 'hemi-R_space-fsLR_den-32k_sphere_surf': (surf, 'sphere_32k_fs_LR_R'), - 'hemi-L_MSMSulc_space-native_sphere_surf': (surf, 'sphere_MSMSulc_L'), - 'hemi-R_MSMSulc_space-native_sphere_surf': (surf, 'sphere_MSMSulc_R'), - 'hemi-L_space-native_sphere_surf': (surf, 'sphere_native_L'), - 'hemi-R_space-native_sphere_surf': (surf, 'sphere_native_R'), - 'hemi-L_space-native_sphere-reg_surf': (surf, 'sphere_reg_L'), - 'hemi-R_space-native_sphere-reg_surf': (surf, 'sphere_reg_R'), - 'hemi-L_space-native_sphere-reg-reg_surf': (surf, 'sphere_reg_reg_LR_L'), - 'hemi-R_space-native_sphere-reg-reg_surf': (surf, 'sphere_reg_reg_LR_R'), - 'hemi-L_space-native_sphere-rot_surf': (surf, 'sphere_rot_L'), - 'hemi-R_space-native_sphere-rot_surf': (surf, 'sphere_rot_R'), - 'hemi-L_strainJ-FS_space-fsLR_den-32k_shape': (surf, 'StrainJ_FS_L'), - 'hemi-R_strainJ-FS_space-fsLR_den-32k_shape': (surf, 'StrainJ_FS_R'), - 'strainJ-FS_space-fsLR_den-32k_dscalar': (surf, 'StrainJ_FS_dscalar'), - 'hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainJ_MSMSulc_L'), - 'hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainJ_MSMSulc_R'), - 'strainJ-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'StrainJ_MSMSulc_dscalar'), - 'hemi-L_strainR-FS_space-fsLR_den-32k_shape': (surf, 'StrainR_FS_L'), - 'hemi-R_strainR-FS_space-fsLR_den-32k_shape': (surf, 'StrainR_FS_R'), - 'strainR-FS_space-fsLR_den-32k_dscalar': (surf, 'StrainR_FS_dscalar'), - 'hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainR_MSMSulc_L'), - 'hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape': (surf, 'StrainR_MSMSulc_R'), - 'strainR-MSMSulc_space-fsLR_den-32k_dscalar': (surf, 'StrainR_MSMSulc_dscalar'), - 'hemi-L_space-fsLR_den-32k_sulc_shape': (surf, 'sulc_L'), - 'hemi-R_space-fsLR_den-32k_sulc_shape': (surf, 'sulc_R'), - 'space-fsLR_den-32k_sulc_dscalar': (surf, 'sulc_dscalar'), - 'hemi-L_space-fsLR_den-32k_thickness_shape': (surf, 'thickness_L'), - 'hemi-R_space-fsLR_den-32k_thickness_shape': (surf, 'thickness_R'), - 'space-fsLR_den-32k_thickness_dscalar': (surf, 'thickness_dscalar'), - 'hemi-L_space-fsLR_den-164k_white_surf': (surf, 'white_L_164'), - 'hemi-L_space-fsLR_den-32k_white_surf': (surf, 'white_L_32'), - 'hemi-L_space-native_white_surf': (surf, 'white_L_native'), - 'hemi-R_space-fsLR_den-164k_white_surf': (surf, 'white_R_164'), - 'hemi-R_space-fsLR_den-32k_white_surf': (surf, 'white_R_32'), - 'hemi-R_space-native_white_surf': (surf, 'white_R_native') + 'hemi-L_space-fsLR_den-32k_curv': (surf, 'curvature_' 'L'), + 'hemi-R_space-fsLR_den-32k_curv': (surf, 'curvature_' 'R'), + 'space-fsLR_den-32k_curv': (surf, 'curvature_' 'dscalar'), + 'hemi-L_space-fsLR_den-32k_flat': (surf, 'flat_L'), + 'hemi-R_space-fsLR_den-32k_flat': (surf, 'flat_R'), + 'hemi-L_space-fsLR_den-32k_inflated': (surf, '32k_inflated_L'), + 'hemi-R_space-fsLR_den-32k_inflated': (surf, '32k_inflated_R'), + 'hemi-L_space-fsLR_den-32k_veryinflated': (surf, '32k_very_inflated_L'), + 'hemi-R_space-fsLR_den-32k_veryinflated': (surf, '32k_very_inflated_R'), + 'hemi-L_space-native_inflated': (surf, 'inflated_L'), + 'hemi-R_space-native_inflated': (surf, 'inflated_R'), + 'hemi-L_space-native_veryinflated': (surf, 'very_inflated_L'), + 'hemi-R_space-native_veryinflated': (surf, 'very_inflated_R'), + 'hemi-L_space-fsLR_den-164k_midthickness': (surf, 'midthickness_L_164'), + 'hemi-L_space-fsLR_den-32k_midthickness': (surf, 'midthickness_L_32'), + 'hemi-L_space-native_midthickness': (surf, 'midthickness_L_native'), + 'hemi-R_space-fsLR_den-164k_midthickness': (surf, 'midthickness_R_164'), + 'hemi-R_space-fsLR_den-32k_midthickness': (surf, 'midthickness_R_32'), + 'hemi-R_space-native_midthickness': (surf, 'midthickness_R_native'), + 'hemi-L_space-fsLR_den-32k_pial': (surf, 'pial_L_32'), + 'hemi-L_space-native_den-32k_pial': (surf, 'pial_L_native'), + 'hemi-R_space-fsLR_den-32k_pial': (surf, 'pial_R_32'), + 'hemi-R_space-native_den-32k_pial': (surf, 'pial_R_native'), + 'hemi-L_space-fsLR_den-32k_sphere': (surf, 'sphere_32k_fs_LR_L'), + 'hemi-R_space-fsLR_den-32k_sphere': (surf, 'sphere_32k_fs_LR_R'), + 'hemi-L_space-native_desc-MSMSulc_sphere': (surf, 'sphere_MSMSulc_L'), + 'hemi-R_space-native_desc-MSMSulc_sphere': (surf, 'sphere_MSMSulc_R'), + 'hemi-L_space-native_sphere': (surf, 'sphere_native_L'), + 'hemi-R_space-native_sphere': (surf, 'sphere_native_R'), + 'hemi-L_space-native_desc-reg_sphere': (surf, 'sphere_reg_L'), + 'hemi-R_space-native_desc-reg_sphere': (surf, 'sphere_reg_R'), + 'hemi-L_space-native_desc-reg-reg_sphere': (surf, 'sphere_reg_reg_LR_L'), + 'hemi-R_space-native_desc-reg-reg_sphere': (surf, 'sphere_reg_reg_LR_R'), + 'hemi-L_space-native_desc-rot_sphere': (surf, 'sphere_rot_L'), + 'hemi-R_space-native_desc-rot_sphere': (surf, 'sphere_rot_R'), + 'hemi-L_space-fsLR_den-32k_desc-FS_strainJ': (surf, 'StrainJ_FS_L'), + 'hemi-R_space-fsLR_den-32k_desc-FS_strainJ': (surf, 'StrainJ_FS_R'), + 'space-fsLR_den-32k_desc-FS_strainJ': (surf, 'StrainJ_FS_dscalar'), + 'hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ': (surf, 'StrainJ_MSMSulc_L'), + 'hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ': (surf, 'StrainJ_MSMSulc_R'), + 'space-fsLR_den-32k_desc-FS_strainJ': (surf, 'StrainJ_MSMSulc_dscalar'), + 'hemi-L_space-fsLR_den-32k_desc-FS_strainR': (surf, 'StrainR_FS_L'), + 'hemi-R_space-fsLR_den-32k_desc-FS_strainR': (surf, 'StrainR_FS_R'), + 'space-fsLR_den-32k_desc-FS_strainR': (surf, 'StrainR_FS_dscalar'), + 'hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR': (surf, 'StrainR_MSMSulc_L'), + 'hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR': (surf, 'StrainR_MSMSulc_R'), + 'space-fsLR_den-32k_desc-MSMSulc_strainR': (surf, 'StrainR_MSMSulc_dscalar'), + 'hemi-L_space-fsLR_den-32k_sulc': (surf, 'sulc_L'), + 'hemi-R_space-fsLR_den-32k_sulc': (surf, 'sulc_R'), + 'space-fsLR_den-32k_sulc': (surf, 'sulc_dscalar'), + 'hemi-L_space-fsLR_den-32k_thickness': (surf, 'thickness_L'), + 'hemi-R_space-fsLR_den-32k_thickness': (surf, 'thickness_R'), + 'space-fsLR_den-32k_thickness': (surf, 'thickness_dscalar'), + 'hemi-L_space-fsLR_den-164k_white': (surf, 'white_L_164'), + 'hemi-L_space-fsLR_den-32k_white': (surf, 'white_L_32'), + 'hemi-L_space-native_white': (surf, 'white_L_native'), + 'hemi-R_space-fsLR_den-164k_white': (surf, 'white_R_164'), + 'hemi-R_space-fsLR_den-32k_white': (surf, 'white_R_32'), + 'hemi-R_space-native_white': (surf, 'white_R_native') } return wf, outputs @@ -758,93 +758,93 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"]], - "outputs": ["space-fsLR_den-32k_bold-dtseries", - "atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", - "atlas-Destrieux_space-fsLR_den-32k_dlabel", - "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", - "atlas-Destrieux_space-fsLR_den-164k_dlabel", + "outputs": ["space-fsLR_den-32k_bold", + "atlas-DesikanKilliany_space-fsLR_den-32k", + "atlas-Destrieux_space-fsLR_den-32k", + "atlas-DesikanKilliany_space-fsLR_den-164k", + "atlas-Destrieux_space-fsLR_den-164k", "AtlasSubcortical_s2", "goodvoxels", "ribbon_only", - "atlasroi_hemi-L_space-fsLR_den-32k_func", - "atlasroi_hemi-R_space-fsLR_den-32k_func", - "atlasroi_hemi-L_space-fsLR_den-32k_shape", - "atlasroi_hemi-R_space-fsLR_den-32k_shape", - "space-native_hemi-L_func", - "space-native_hemi-R_func", + "hemi-L_space-fsLR_den-32k_desc-atlasroi_bold", + "hemi-R_space-fsLR_den-32k_desc-atlasroi_bold", + "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", + "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask", + "hemi-L_space-native_bold", + "hemi-R_space-native_bold", "space-fsLR_den-32k_wb-spec", "space-native_wb-spec", - "arealdistortion-FS_hemi-L_space-fsLR_den-32k_shape", - "arealdistortion-FS_hemi-R_space-fsLR_den-32k_shape", - "arealdistortion-FS_space-fsLR_den-32k_dscalar", - "arealdistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape", - "arealdistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape", - "arealdistortion-MSMSulc_space-fsLR_den-32k_dscalar", - "edgedistortion-FS_hemi-L_space-fsLR_den-32k_shape", - "edgedistortion-FS_hemi-R_space-fsLR_den-32k_shape", - "edgedistortion-FS_space-fsLR_den-32k_dscalar", - "edgedistortion-MSMSulc_hemi-L_space-fsLR_den-32k_shape", - "edgedistortion-MSMSulc_hemi-R_space-fsLR_den-32k_shape", - "edgedistortion-MSMSulc_space-fsLR_den-32k_dscalar", - "hemi-L_space-fsLR_den-32k_curv_shape", - "hemi-R_space-fsLR_den-32k_curv_shape", - "space-fsLR_den-32k_curv_dscalar", - "hemi-L_space-fsLR_den-32k_flat_surf", - "hemi-R_space-fsLR_den-32k_flat_surf", - "hemi-L_space-fsLR_den-32k_inflated_surf", - "hemi-R_space-fsLR_den-32k_inflated_surf", - "hemi-L_space-fsLR_den-32k_very-inflated_surf", - "hemi-R_space-fsLR_den-32k_very-inflated_surf", - "hemi-L_space-native_inflated_surf", - "hemi-R_space-native_inflated_surf", - "hemi-L_space-native_very-inflated_surf", - "hemi-R_space-native_very-inflated_surf", - "hemi-L_space-fsLR_den-164k_midthickness_surf", - "hemi-R_space-fsLR_den-164k_midthickness_surf", - "hemi-L_space-fsLR_den-32k_midthickness_surf", - "hemi-R_space-fsLR_den-32k_midthickness_surf", - "hemi-L_space-native_midthickness_surf", - "hemi-R_space-native_midthickness_surf", - "hemi-L_space-fsLR_den-32k_pial_surf", - "hemi-R_space-fsLR_den-32k_pial_surf", - "hemi-L_space-native_den-32k_pial_surf", - "hemi-R_space-native_den-32k_pial_surf", - "hemi-L_space-fsLR_den-32k_sphere_surf", - "hemi-R_space-fsLR_den-32k_sphere_surf", - "hemi-L_MSMSulc_space-native_sphere_surf", - "hemi-R_MSMSulc_space-native_sphere_surf", - "hemi-L_space-native_sphere_surf", - "hemi-R_space-native_sphere_surf", - "hemi-L_space-native_sphere-reg_surf", - "hemi-R_space-native_sphere-reg_surf", - "hemi-L_space-native_sphere-reg-reg_surf", - "hemi-R_space-native_sphere-reg-reg_surf", - "hemi-L_space-native_sphere-rot_surf", - "hemi-R_space-native_sphere-rot_surf", - "hemi-L_strainJ-FS_space-fsLR_den-32k_shape", - "hemi-R_strainJ-FS_space-fsLR_den-32k_shape", - "strainJ-FS_space-fsLR_den-32k_dscalar", - "hemi-L_strainJ-MSMSulc_space-fsLR_den-32k_shape", - "hemi-R_strainJ-MSMSulc_space-fsLR_den-32k_shape", - "strainJ-MSMSulc_space-fsLR_den-32k_dscalar", - "hemi-L_strainR-FS_space-fsLR_den-32k_shape", - "hemi-R_strainR-FS_space-fsLR_den-32k_shape", - "strainR-FS_space-fsLR_den-32k_dscalar", - "hemi-L_strainR-MSMSulc_space-fsLR_den-32k_shape", - "hemi-R_strainR-MSMSulc_space-fsLR_den-32k_shape", - "strainR-MSMSulc_space-fsLR_den-32k_dscalar", - "hemi-L_space-fsLR_den-32k_sulc_shape", - "hemi-R_space-fsLR_den-32k_sulc_shape", - "space-fsLR_den-32k_sulc_dscalar", - "hemi-L_space-fsLR_den-32k_thickness_shape", - "hemi-R_space-fsLR_den-32k_thickness_shape", - "space-fsLR_den-32k_thickness_dscalar", - "hemi-L_space-fsLR_den-164k_white_surf", - "hemi-R_space-fsLR_den-164k_white_surf", - "hemi-L_space-fsLR_den-32k_white_surf", - "hemi-R_space-fsLR_den-32k_white_surf", - "hemi-L_space-native_white_surf", - "hemi-R_space-native_white_surf"]} + "hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion", + "hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion", + "space-fsLR_den-32k_desc-FS_arealdistortion", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion", + "space-fsLR_den-32k_desc-MSMSulc_arealdistortion", + "hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion", + "hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion", + "space-fsLR_den-32k_desc-FS_edgedistortion", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion", + "space-fsLR_den-32k_desc-MSMSulc_edgedistortion", + "hemi-L_space-fsLR_den-32k_curv", + "hemi-R_space-fsLR_den-32k_curv", + "space-fsLR_den-32k_curv", + "hemi-L_space-fsLR_den-32k_flat", + "hemi-R_space-fsLR_den-32k_flat", + "hemi-L_space-fsLR_den-32k_inflated", + "hemi-R_space-fsLR_den-32k_inflated", + "hemi-L_space-fsLR_den-32k_veryinflated", + "hemi-R_space-fsLR_den-32k_veryinflated", + "hemi-L_space-native_inflated", + "hemi-R_space-native_inflated", + "hemi-L_space-native_veryinflated", + "hemi-R_space-native_veryinflated", + "hemi-L_space-fsLR_den-164k_midthickness", + "hemi-R_space-fsLR_den-164k_midthickness", + "hemi-L_space-fsLR_den-32k_midthickness", + "hemi-R_space-fsLR_den-32k_midthickness", + "hemi-L_space-native_midthickness", + "hemi-R_space-native_midthickness", + "hemi-L_space-fsLR_den-32k_pial", + "hemi-R_space-fsLR_den-32k_pial", + "hemi-L_space-native_den-32k_pial", + "hemi-R_space-native_den-32k_pial", + "hemi-L_space-fsLR_den-32k_sphere", + "hemi-R_space-fsLR_den-32k_sphere", + "hemi-L_space-native_desc-MSMSulc_sphere", + "hemi-R_space-native_desc-MSMSulc_sphere", + "hemi-L_space-native_sphere", + "hemi-R_space-native_sphere", + "hemi-L_space-native_desc-reg_sphere", + "hemi-R_space-native_desc-reg_sphere", + "hemi-L_space-native_desc-reg-reg_sphere", + "hemi-R_space-native_desc-reg-reg_sphere", + "hemi-L_space-native_desc-rot_sphere", + "hemi-R_space-native_desc-rot_sphere", + "hemi-L_space-fsLR_den-32k_desc-FS_strainJ", + "hemi-R_space-fsLR_den-32k_desc-FS_strainJ", + "space-fsLR_den-32k_desc-FS_strainJ", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ", + "space-fsLR_den-32k_desc-MSMSulc_strainJ", + "hemi-L_space-fsLR_den-32k_desc-FS_strainR", + "hemi-R_space-fsLR_den-32k_desc-FS_strainR", + "space-fsLR_den-32k_desc-FS_strainR", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR", + "space-fsLR_den-32k_desc-MSMSulc_strainR", + "hemi-L_space-fsLR_den-32k_sulc", + "hemi-R_space-fsLR_den-32k_sulc", + "space-fsLR_den-32k_sulc", + "hemi-L_space-fsLR_den-32k_thickness", + "hemi-R_space-fsLR_den-32k_thickness", + "space-fsLR_den-32k_thickness", + "hemi-L_space-fsLR_den-164k_white", + "hemi-R_space-fsLR_den-164k_white", + "hemi-L_space-fsLR_den-32k_white", + "hemi-R_space-fsLR_den-32k_white", + "hemi-L_space-native_white", + "hemi-R_space-native_white"]} ''' wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) @@ -858,7 +858,7 @@ def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): name=f'surf_falff_{pipe_num}') falff.inputs.subject = cfg['subject_id'] - node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, falff, 'dtseries') outputs = { @@ -873,7 +873,7 @@ def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): name=f'surf_alff_{pipe_num}') alff.inputs.subject = cfg['subject_id'] - node, out = strat_pool.get_data('space-fsLR_den-32k_bold-dtseries') + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out,alff, 'dtseries') outputs = { 'surf_alff': (alff,'surf_alff')} @@ -888,7 +888,7 @@ def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): # L_cortex_file.inputs.structure = "LEFT" # L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" -# node, out = strat_pool.get_data(space-fsLR_den-32k_bold-dtseries) +# node, out = strat_pool.get_data(space-fsLR_den-32k_bold) # wf.connect(node, out, L_cortex_file, 'dtseries') # R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], @@ -971,7 +971,7 @@ def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold-dtseries"], + "inputs": ["space-fsLR_den-32k_bold"], "outputs": ["surf_falff"]} ''' wf, outputs = cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt) @@ -985,7 +985,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold-dtseries"], + "inputs": ["space-fsLR_den-32k_bold"], "outputs": ["surf_alff"]} ''' wf, outputs = cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt) @@ -999,7 +999,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): # "switch": ["run"], # "option_key": "surface_reho", # "option_val": "None", -# "inputs": ["space-fsLR_den-32k_bold-dtseries"], +# "inputs": ["space-fsLR_den-32k_bold"], # "outputs": ["surf-L_reho", "surf-R_reho"]} # ''' # wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) @@ -1013,7 +1013,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): # "switch": ["run"], # "option_key": "None", # "option_val": "None", -# "inputs": ["space-fsLR_den-32k_bold-dtseries", +# "inputs": ["space-fsLR_den-32k_bold"], # "outputs": ["surf-correlation_matrix"} # ''' # wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py index 746c911825..02ead6a778 100755 --- a/CPAC/utils/utils.py +++ b/CPAC/utils/utils.py @@ -185,7 +185,7 @@ def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, if extension is not None: out_filename = out_filename + "." + str(extension) - raise Exception(out_filename) + return out_filename @@ -193,8 +193,12 @@ def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, def write_output_json(json_data, filename, indent=3, basedir=None): if not basedir: basedir = os.getcwd() + if '.gii' in filename: + filename = os.path.splitext(filename)[0] + filename = f'{filename}.json' if '.json' not in filename: filename = f'{filename}.json' + json_file = os.path.join(basedir, filename) json_data = json.dumps(json_data, indent=indent, sort_keys=True) with open(json_file, 'wt') as f: From c505bd99c095fcaa3b817e37e8749415e2cb3e8e Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 23 Feb 2023 17:13:40 +0000 Subject: [PATCH 012/213] added surface_Reho calculation --- CPAC/pipeline/cpac_pipeline.py | 4 +- CPAC/surface/PostFreeSurfer/surf_reho.py | 94 +++++++++++++ CPAC/surface/surf_preproc.py | 170 ++++++++++++----------- 3 files changed, 187 insertions(+), 81 deletions(-) create mode 100644 CPAC/surface/PostFreeSurfer/surf_reho.py diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index 294a8cd6a5..97f752a8e8 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -172,7 +172,7 @@ from CPAC.surface.surf_preproc import surface_postproc from CPAC.surface.surf_preproc import surface_falff from CPAC.surface.surf_preproc import surface_alff -#from CPAC.surface.surf_preproc import cal_reho +from CPAC.surface.surf_preproc import surface_reho #from CPAC.surface.surf_preproc import cal_connectivity_matrix from CPAC.timeseries.timeseries_analysis import ( @@ -1324,6 +1324,8 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if not rpool.check_rpool('surf_alff'): pipeline_blocks += [surface_alff] + if not rpool.check_rpool('surf-L_reho') or not rpool.check_rpool('surf-R_reho') : + pipeline_blocks += [surface_reho] # Extractions and Derivatives tse_atlases, sca_atlases = gather_extraction_maps(cfg) diff --git a/CPAC/surface/PostFreeSurfer/surf_reho.py b/CPAC/surface/PostFreeSurfer/surf_reho.py new file mode 100644 index 0000000000..0d4039effb --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/surf_reho.py @@ -0,0 +1,94 @@ +import numpy as np +import nibabel as nb +import os +import sys + + +dtseries = sys.argv[0] # dtseries file +mask = sys.argv[1] # surface mask file +cortex_file = sys.argv[2] # cortex file +surf = sys.argv[3] # surface file +scalar_dt = sys.argv[4] # mean_timeseries +structure_name = sys.argv[5] +surf_reho = sys.argv[6] # Path to reho file + +def get_neighbours(faces, vertex_id, depth=1): + fois = np.where(faces == vertex_id)[0] + nbrs = list(np.unique(faces[fois])) + if depth > 1: + depth -= 1 + new_nbrs = [] + for n in nbrs: + new_nbrs += get_neighbours(faces, n, depth=depth) + nbrs = list(np.unique(new_nbrs)) + return nbrs + + +def ccs_ReHo(dt_file, surf_file): + + #Finding neighbors + surf = np.array(surf_file.agg_data()) # 2 separate arrays + faces = np.array(surf_file.agg_data('triangle')) + vertex = np.array(surf_file.agg_data('pointset')) + voi = range(0,(vertex.shape)[0]) + nbrs = [] + for voi in voi: + output = get_neighbours(faces, voi, depth = 1) + nbrs.append(output) + + #Ting ReHo Calculation + tsmat = np.array(dt_file.agg_data()) + nsp = (tsmat.shape)[1] #vertex + ntp = (tsmat.shape)[0] #timepoints + + tmp_ts = [] + cReHo = [] + for i in range(0,nsp): + tmp_ts = np.squeeze(tsmat[:,i]) + tmp_ts = tmp_ts.reshape(-1,1) + if np.std(tmp_ts) > 0: + tmp_nbrs = nbrs[i] + nbrs_ts = np.squeeze(tsmat[:,tmp_nbrs]) + std = np.std(nbrs_ts, axis = 0) + where = (np.where(std > 0))[0] + nbrs_ts_arr = nbrs_ts[:, where] + ts = np.concatenate((tmp_ts, nbrs_ts_arr), axis = 1) + m = (ts.shape)[1] + I = np.argsort(ts, axis = 0, kind = 'mergesort') + R = np.argsort(I, axis = 0, kind = 'mergesort') + S = (np.sum((np.sum(R, axis = 1)**2))) - (ntp*np.mean(np.sum(R,axis=1))**2) + F = m*m*(ntp*ntp*ntp-ntp) + cReHo = np.append(cReHo, (12 * (S/F))) + cReHo = cReHo.reshape(-1,1) + + return(cReHo) + +cReHo = ccs_ReHo(cortex_file, surf) + +## Axes and Header stuff ## +axes = [dtseries.header.get_axis(i) for i in range(dtseries.ndim)] +axes1 = [scalar_dt.header.get_axis(i) for i in range(scalar_dt.ndim)] + +time_axis, brain_model_axis = axes #dtseries +time_axis1, brain_axis1 = axes1 #dscalar + +# Select the structures you want +structure_names = [structure_name] # List of structure names + +brain_models = [bm for bm in brain_model_axis.iter_structures() + if bm[0] in structure_names] + +new_dataobj = np.concatenate([dtseries.dataobj[0, bm[1]] for bm in brain_models], axis=0) +new_dataobj = np.transpose(new_dataobj.reshape(-1,1)) + +new_brain_model_axis = sum( + (bm[2] for bm in brain_models[1:]), brain_models[0][2]) + +new_cifti = nb.Cifti2Image(new_dataobj, + header=(time_axis1, new_brain_model_axis), + nifti_header=dtseries.nifti_header) + +## Saving image ## +img = nb.Cifti2Image(np.transpose(cReHo), header = new_cifti.header, nifti_header=new_cifti.nifti_header) +reho_file = surf_reho +img.to_filename(reho_file) \ No newline at end of file diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index f6f8e98962..a3b8feac30 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -879,66 +879,75 @@ def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): 'surf_alff': (alff,'surf_alff')} return wf, outputs -# def cal_reho(wf, cfg, strat_pool, pipe_num, opt): +def cal_reho(wf, cfg, strat_pool, pipe_num, opt): -# L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], -# output_names=['L_cortex_file'], -# function=run_get_cortex), -# name=f'L_surf_cortex_{pipe_num}') - -# L_cortex_file.inputs.structure = "LEFT" -# L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" -# node, out = strat_pool.get_data(space-fsLR_den-32k_bold) -# wf.connect(node, out, L_cortex_file, 'dtseries') - -# R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], -# output_names=['R_cortex_file'], -# function=run_get_cortex), -# name=f'R_surf_cortex_{pipe_num}') + L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], + output_names=['L_cortex_file'], + function=run_get_cortex), + name=f'L_surf_cortex_{pipe_num}') + L_cortex_file.inputs.structure = "LEFT" + L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') + wf.connect(node, out, L_cortex_file, 'dtseries') -# R_cortex_file.inputs.structure = "RIGHT" -# R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" -# wf.connect(node, out,R_cortex_file, 'dtseries') + R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], + output_names=['R_cortex_file'], + function=run_get_cortex), + name=f'R_surf_cortex_{pipe_num}') -# mean_timeseries = pe.Node(util.Function(input_names=['dtseries'], -# output_names=['mean_timeseries'], -# function=run_mean_timeseries), -# name=f'mean_timeseries_{pipe_num}') + R_cortex_file.inputs.structure = "RIGHT" + R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" + wf.connect(node, out,R_cortex_file, 'dtseries') -# wf.connect(node, out, mean_timeseries, 'dtseries') + mean_timeseries = pe.Node(util.Function(input_names=['dtseries'], + output_names=['mean_timeseries'], + function=run_mean_timeseries), + name=f'mean_timeseries_{pipe_num}') -# L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries','reho_filename'], -# output_names=['L_reho'], -# function=run_surf_reho), -# name=f'surf_reho{pipe_num}') -# wf.connect(L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') -# wf.connect(surf, 'midthickness_L_32', L_reho, 'surface_file') -# wf.connect(surf,'atlas_roi_shape_L', L_reho, 'mask') -# wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') -# L_reho.inputs.reho_filename = L_surf_reho.dscalar.nii -# wf.connect(node, out, L_reho, 'dtseries') + wf.connect(node, out, mean_timeseries, 'dtseries') -# R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', 'reho_filename'], -# output_names=['R_reho'], -# function=run_surf_reho), -# name=f'surf_reho{pipe_num}') + L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries','reho_filename', 'structure_name'], + output_names=['L_reho'], + function=run_surf_reho), + name=f'L_surf_reho{pipe_num}') -# wf.connect(R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') -# wf.connect(surf, 'midthickness_R_32', R_reho, 'surface_file') -# wf.connect(surf,'atlas_roi_shape_R', L_reho, 'mask') -# wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') -# R_reho.inputs.reho_filename = R_surf_reho.dscalar.nii -# wf.connect(node, out, R_reho, 'dtseries') + wf.connect(L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') + node, out = strat_pool.get_data('hemi-L_space-fsLR_den-32k_midthickness') + wf.connect(node, out, L_reho, 'surface_file') + + node, out = strat_pool.get_data('hemi-L_space-fsLR_den-32k_desc-atlasroi_mask') + wf.connect(node, out, L_reho, 'mask') + wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') + L_reho.inputs.reho_filename = "L_surf_reho.dscalar.nii" + L_reho.inputs.structure_name = "CIFTI_STRUCTURE_CORTEX_LEFT" + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') + wf.connect(node, out, L_reho, 'dtseries') + + R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', 'reho_filename', 'structure_name'], + output_names=['R_reho'], + function=run_surf_reho), + name=f'R_surf_reho{pipe_num}') + + wf.connect(R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') + node, out = strat_pool.get_data('hemi-R_space-fsLR_den-32k_midthickness') + wf.connect(node, out, R_reho, 'surface_file') + L_reho.inputs.structure_name = "CIFTI_STRUCTURE_CORTEX_RIGHT" + node, out = strat_pool.get_data('hemi-R_space-fsLR_den-32k_desc-atlasroi_mask') + wf.connect(node, out, R_reho, 'mask') + wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') + R_reho.inputs.reho_filename = "R_surf_reho.dscalar.nii" + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') + wf.connect(node, out, R_reho, 'dtseries') -# outputs = { -# 'surf-L_reho': (L_reho,'L_reho'), -# 'surf-R_reho': (R_reho,'R_reho')} + outputs = { + 'surf-L_reho': (L_reho,'L_reho'), + 'surf-R_reho': (R_reho,'R_reho')} -# return wf, outputs + return wf, outputs # def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): @@ -992,19 +1001,19 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -# def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): -# ''' -# {"name": "ReHo", -# "config": ["regional_homogeneity"], -# "switch": ["run"], -# "option_key": "surface_reho", -# "option_val": "None", -# "inputs": ["space-fsLR_den-32k_bold"], -# "outputs": ["surf-L_reho", "surf-R_reho"]} -# ''' -# wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) +def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "ReHo", + "config": ["regional_homogeneity"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["space-fsLR_den-32k_bold"], + "outputs": ["surf-L_reho", "surf-R_reho"]} + ''' + wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) -# return (wf, outputs) + return (wf, outputs) # def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): # ''' @@ -1036,31 +1045,32 @@ def run_surf_alff(subject,dtseries): subprocess.check_output(cmd) return alff -# def run_get_cortex(dtseries, structure, cortex_filename): -# import os -# import subprocess -# cortex_file = os.path.join(os.getcwd(), cortex_filename) -# cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_file] -# subprocess.check_output(cmd) -# return cortex_file +def run_get_cortex(subject, dtseries, structure, cortex_filename): + import os + import subprocess + cortex_file = os.path.join(os.getcwd(), f'{subject}_{cortex_filename}') + cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_file] + subprocess.check_output(cmd) + return cortex_file -# def run_mean_timeseries(dtseries,post_freesurfer_folder): +def run_mean_timeseries(subject, dtseries): -# import os -# import subprocess -# mean_timeseries = os.path.join(os.getcwd(), mean.dscalar.nii) -# cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', mean_timeseries] -# subprocess.check_output(cmd) -# return mean_timeseries + import os + import subprocess + mean_timeseries = os.path.join(os.getcwd(), f'{subject}_mean.dscalar.nii') + cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', mean_timeseries] + subprocess.check_output(cmd) + return mean_timeseries -# def run_surf_reho(dtseries, mask, cortex_file, surface_file,mean_timeseries,post_freesurfer_folder, reho_filename): +def run_surf_reho(subject, dtseries, mask, cortex_file, surface_file,mean_timeseries,reho_filename,structure_name): -# import os -# import subprocess -# surf_reho = os.path.join(os.getcwd(), reho_filename) -# cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, surf_reho] -# subprocess.check_output(cmd) -# return surf_reho + import os + import subprocess + + surf_reho = os.path.join(os.getcwd(), f'{subject}_{reho_filename}') + cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, structure_name, surf_reho] + subprocess.check_output(cmd) + return surf_reho # def run_ciftiparcellate(dtseries, surf_atlaslabel): # import os From d5f698352d16ed87eeb47994a927e3e471f4cd26 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 28 Feb 2023 14:52:56 +0000 Subject: [PATCH 013/213] added node to calculate surface based reho --- CPAC/surface/PostFreeSurfer/surf_reho.py | 20 +++++----- CPAC/surface/surf_preproc.py | 47 ++++++++++++++---------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/CPAC/surface/PostFreeSurfer/surf_reho.py b/CPAC/surface/PostFreeSurfer/surf_reho.py index 0d4039effb..3e0f09dc52 100644 --- a/CPAC/surface/PostFreeSurfer/surf_reho.py +++ b/CPAC/surface/PostFreeSurfer/surf_reho.py @@ -4,13 +4,14 @@ import sys -dtseries = sys.argv[0] # dtseries file -mask = sys.argv[1] # surface mask file -cortex_file = sys.argv[2] # cortex file -surf = sys.argv[3] # surface file -scalar_dt = sys.argv[4] # mean_timeseries -structure_name = sys.argv[5] -surf_reho = sys.argv[6] # Path to reho file +dtseries = nb.load(sys.argv[1]) # dtseries file +mask = nb.load(sys.argv[2]) # surface mask file +cortex_file = nb.load(sys.argv[3]) # cortex file +surf_file = nb.load(sys.argv[4]) # surface file +scalar_dt = nb.load(sys.argv[5]) # mean_timeseries +structure_name = sys.argv[6] #structure name +surf_reho = sys.argv[7] # Path to reho file + def get_neighbours(faces, vertex_id, depth=1): fois = np.where(faces == vertex_id)[0] @@ -27,7 +28,8 @@ def get_neighbours(faces, vertex_id, depth=1): def ccs_ReHo(dt_file, surf_file): #Finding neighbors - surf = np.array(surf_file.agg_data()) # 2 separate arrays + print(surf_file) + #surf = np.array(surf_file.agg_data()) # 2 separate arrays faces = np.array(surf_file.agg_data('triangle')) vertex = np.array(surf_file.agg_data('pointset')) voi = range(0,(vertex.shape)[0]) @@ -63,7 +65,7 @@ def ccs_ReHo(dt_file, surf_file): return(cReHo) -cReHo = ccs_ReHo(cortex_file, surf) +cReHo = ccs_ReHo(cortex_file, surf_file) ## Axes and Header stuff ## axes = [dtseries.header.get_axis(i) for i in range(dtseries.ndim)] diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index a3b8feac30..f7973a4056 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -881,40 +881,42 @@ def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): def cal_reho(wf, cfg, strat_pool, pipe_num, opt): - L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], + L_cortex_file = pe.Node(util.Function(input_names=['subject', 'dtseries', 'structure', 'cortex_filename'], output_names=['L_cortex_file'], function=run_get_cortex), name=f'L_surf_cortex_{pipe_num}') - - L_cortex_file.inputs.structure = "LEFT" + + L_cortex_file.inputs.subject = cfg['subject_id'] + L_cortex_file.inputs.structure = "CORTEX_LEFT" L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, L_cortex_file, 'dtseries') - R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'cortex_filename'], + R_cortex_file = pe.Node(util.Function(input_names=['subject', 'dtseries', 'structure', 'cortex_filename'], output_names=['R_cortex_file'], function=run_get_cortex), name=f'R_surf_cortex_{pipe_num}') - - R_cortex_file.inputs.structure = "RIGHT" + R_cortex_file.inputs.subject = cfg['subject_id'] + R_cortex_file.inputs.structure = "CORTEX_RIGHT" R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" wf.connect(node, out,R_cortex_file, 'dtseries') - mean_timeseries = pe.Node(util.Function(input_names=['dtseries'], + mean_timeseries = pe.Node(util.Function(input_names=['subject', 'dtseries'], output_names=['mean_timeseries'], function=run_mean_timeseries), name=f'mean_timeseries_{pipe_num}') - + mean_timeseries.inputs.subject = cfg['subject_id'] wf.connect(node, out, mean_timeseries, 'dtseries') - L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries','reho_filename', 'structure_name'], + L_reho = pe.Node(util.Function(input_names=['subject', 'dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries','reho_filename', 'structure_name'], output_names=['L_reho'], function=run_surf_reho), name=f'L_surf_reho{pipe_num}') - + + L_reho.inputs.subject = cfg['subject_id'] wf.connect(L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') node, out = strat_pool.get_data('hemi-L_space-fsLR_den-32k_midthickness') wf.connect(node, out, L_reho, 'surface_file') @@ -927,15 +929,16 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, L_reho, 'dtseries') - R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', 'reho_filename', 'structure_name'], + R_reho = pe.Node(util.Function(input_names=['subject','dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', 'reho_filename', 'structure_name'], output_names=['R_reho'], function=run_surf_reho), name=f'R_surf_reho{pipe_num}') - + + R_reho.inputs.subject = cfg['subject_id'] wf.connect(R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') node, out = strat_pool.get_data('hemi-R_space-fsLR_den-32k_midthickness') wf.connect(node, out, R_reho, 'surface_file') - L_reho.inputs.structure_name = "CIFTI_STRUCTURE_CORTEX_RIGHT" + R_reho.inputs.structure_name = "CIFTI_STRUCTURE_CORTEX_RIGHT" node, out = strat_pool.get_data('hemi-R_space-fsLR_den-32k_desc-atlasroi_mask') wf.connect(node, out, R_reho, 'mask') wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') @@ -1008,7 +1011,11 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold"], + "inputs": ["space-fsLR_den-32k_bold", + "hemi-L_space-fsLR_den-32k_midthickness", + "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", + "hemi-R_space-fsLR_den-32k_midthickness", + "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask"], "outputs": ["surf-L_reho", "surf-R_reho"]} ''' wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) @@ -1048,28 +1055,30 @@ def run_surf_alff(subject,dtseries): def run_get_cortex(subject, dtseries, structure, cortex_filename): import os import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess cortex_file = os.path.join(os.getcwd(), f'{subject}_{cortex_filename}') - cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_file] - subprocess.check_output(cmd) + cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-metric', structure, cortex_file] + log_subprocess(cmd) return cortex_file def run_mean_timeseries(subject, dtseries): import os import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess mean_timeseries = os.path.join(os.getcwd(), f'{subject}_mean.dscalar.nii') cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', mean_timeseries] - subprocess.check_output(cmd) + log_subprocess(cmd) return mean_timeseries def run_surf_reho(subject, dtseries, mask, cortex_file, surface_file,mean_timeseries,reho_filename,structure_name): import os import subprocess - + from CPAC.utils.monitoring.custom_logging import log_subprocess surf_reho = os.path.join(os.getcwd(), f'{subject}_{reho_filename}') cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, structure_name, surf_reho] - subprocess.check_output(cmd) + log_subprocess(cmd) return surf_reho # def run_ciftiparcellate(dtseries, surf_atlaslabel): From a55d59aab738f52cbbbf9bcb29d6ee1dda22cdf4 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 1 Mar 2023 16:13:11 +0000 Subject: [PATCH 014/213] updated nibabel version --- CPAC/info.py | 2 +- CPAC/pipeline/cpac_pipeline.py | 5 +- CPAC/surface/surf_preproc.py | 95 ++++++++++++++++++---------------- requirements.txt | 2 +- 4 files changed, 55 insertions(+), 49 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 41dcdbe2ca..a256452a0f 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -179,7 +179,7 @@ def get_cpac_gitversion(): "lockfile==0.12.2", "matplotlib==3.1.3", "networkx==2.4", - "nibabel==2.3.3", + "nibabel==3.2.1", "nilearn==0.4.1", "nipype==1.5.1", "nose==1.3.7", diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index 97f752a8e8..b87d73490b 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -173,7 +173,7 @@ from CPAC.surface.surf_preproc import surface_falff from CPAC.surface.surf_preproc import surface_alff from CPAC.surface.surf_preproc import surface_reho -#from CPAC.surface.surf_preproc import cal_connectivity_matrix +from CPAC.surface.surf_preproc import surface_connectivity_matrix from CPAC.timeseries.timeseries_analysis import ( timeseries_extraction_AVG, @@ -1327,6 +1327,9 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if not rpool.check_rpool('surf-L_reho') or not rpool.check_rpool('surf-R_reho') : pipeline_blocks += [surface_reho] + if not rpool.check_rpool('surf-correlation_matrix'): + pipeline_blocks += [surface_connectivity_matrix] + # Extractions and Derivatives tse_atlases, sca_atlases = gather_extraction_maps(cfg) cfg.timeseries_extraction['tse_atlases'] = tse_atlases diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index f7973a4056..f341c51ca2 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -952,28 +952,30 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs -# def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): +def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): -# connectivity_parcellation = pe.Node(util.Function(input_names=['dtseries', 'surf_atlaslabel'], -# output_names=['parcellation_file'], -# function=run_ciftiparcellate), -# name=f'connectivity_parcellation{pipe_num}') + connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], + output_names=['parcellation_file'], + function=run_ciftiparcellate), + name=f'connectivity_parcellation{pipe_num}') + + connectivity_parcellation.inputs.subject = cfg['subject_id'] + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') + wf.connect(node, out, connectivity, 'dtseries') + connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' + + correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], + output_names=['correlation_matrix'], + function=run_cifticorrelation), + name=f'correlation_matrix{pipe_num}') -# wf.connect(node, out, connectivity, 'dtseries') -# connectivity_parcellation.inputs.surf_atlaslabel = ## path to the label file - -# correlation_matrix = pe.Node(util.Function(input_names=['ptseries'], -# output_names=['correlation_matrix'], -# function=run_cifticorrelation), -# name=f'correlation_matrix{pipe_num}') - - -# wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix 'ptseries') + correlation_matrix.inputs.subject = cfg['subject_id'] + wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix, 'ptseries') -# outputs = { -# 'surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} + outputs = { + 'surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} -# return wf, outputs + return wf, outputs def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): @@ -1022,19 +1024,19 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -# def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): -# ''' -# {"name": "surface_connectivity_matrix", -# "config": ["surface_analysis", "post_freesurfer"], -# "switch": ["run"], -# "option_key": "None", -# "option_val": "None", -# "inputs": ["space-fsLR_den-32k_bold"], -# "outputs": ["surf-correlation_matrix"} -# ''' -# wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) +def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "surface_connectivity_matrix", + "config": ["seed_based_correlation_analysis"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["space-fsLR_den-32k_bold"], + "outputs": ["surf-correlation_matrix"]} + ''' + wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) -# return (wf, outputs) + return (wf, outputs) def run_surf_falff(subject,dtseries): import os @@ -1081,19 +1083,20 @@ def run_surf_reho(subject, dtseries, mask, cortex_file, surface_file,mean_timese log_subprocess(cmd) return surf_reho -# def run_ciftiparcellate(dtseries, surf_atlaslabel): -# import os -# import subprocess -# parcellation_file = os.path.join(os.getcwd(), 'parcellation.ptseries.nii') -# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] -# subprocess.check_output(cmd) - -# return parcellation_file - -# def run_cifticorrelation(ptseries): -# import os -# import subprocess -# correlation_matrix = os.path.join(os.getcwd(), 'cifti_corr.pconn.nii') -# cmd = ['wb_command', '-cifti-correlation ', ptseries , correlation_matrix] -# subprocess.check_output(cmd) -# return correlation_matrix \ No newline at end of file +def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): + import os + import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess + parcellation_file = os.path.join(os.getcwd(), f'{subject}_parcellation.ptseries.nii') + cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] + log_subprocess(cmd) + return parcellation_file + +def run_cifticorrelation(subject, ptseries): + import os + import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess + correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') + cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] + log_subprocess(cmd) + return correlation_matrix \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index c37cfe918f..5b7529e41c 100755 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ git+https://git@github.com/FCP-INDI/INDI-Tools.git#egg=INDI-Tools lockfile==0.12.2 matplotlib==3.1.3 networkx==2.4 -nibabel==2.3.3 +nibabel==3.2.1 nilearn==0.4.1 nipype==1.5.1 nose==1.3.7 From 75dfb54eb1cc18db88c03ff2cc0a9baccd3d5143 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 1 Mar 2023 16:14:13 +0000 Subject: [PATCH 015/213] added surface Schaefer2018_200Parcels_17Networks label to templates --- ...2018_200Parcels_17Networks_order.dlabel.nii | Bin 0 -> 656832 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii diff --git a/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii b/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii new file mode 100644 index 0000000000000000000000000000000000000000..152a1223dffb56f299295d5346f246e0bd9f1d0b GIT binary patch literal 656832 zcmd?y%aY^wfoFHwi&@Z@@Y>-8f-6sSs48&>6l!V2lGLrRF0{yQ+pBVsOsdOGR&k0& zwfgD&8h#AFfFpc9zf2@hHvoT4dof{6!$`2W$r@T2~$ z|L1@8qaQta`QpVdZ(n?W``c$<+i$DGC$N%v8uYbJz_~$?S=%-J9^Xt!lGyBKGXW^4o8pz4&VO+vhKCXTSLFyKkO<`RsLnu8;1o_fKZ?NBzH#{^!>&`rY$yZofMG zk$y5;J=#55`Jevy!;9C?`?o(xcmIoj`SaI5nJwnK{mp8=d$zd!;>-P)^Tk(RZ*IQY z-Y&k{&$nOQ?)P8KS6@H7z5VD;m~~@x)fPAN^^b41KVIC-ZgxLeZho@7nf>@?eRJbt zuF0#P%>MK@f3sT6{>R5ZeE;h47tde(`-lJO^s1~LZ4dwatJyDazxd%#Kbigh4eSCMTy>V;)^zrZB%JI{;|A8C*r-we*g?ao{ z*&jdq?z`_FKYR7%KRq5-;OSp>o2Q%AEnMn{p07~e)sa#>)G8m{NelVl#gHi^UD{1di?$C zm#?1v>GtuHPk!@vPrrNh{LkI?{ljNpd~@4>effWMzxn?07q6c6jlb(U-hT7VxPLtU z?8|?8cKh}1t19iD{`TdU&%XJ)Z(e@!?3>4*o?Pnt$1iUGW&Amycfm}J^uE^>&LhM@teort$Iwmm)`#6_3f({-LLNM zuKyq1O`p8{s)Ojo$9+eEcaGKf$MfI3`0DwWx8MKn*>`t`(cAAoe|dML|7AzU7kAGU zJyRSn_xVc)eTU({{dhcAJpIk@fBCEb_37vT+o!*J`rBW8@~hu|cK?*|a5#5#`KoX6 zo+pO>={WY>JxIUrn%@6|Hx6Ut7&V^bKKBTJ_uq58!0dmz{nx+!xNH2!+pl_-`*`+u zuWoNW-+es$q$ic}|M|r?-~H1w7y8-HfBy5IJ|6$#%m2>)4ddT=^JulbS?_ia|LU7Z zH{%~H4&UPD(R#67?LVH~f1~-wKRY=@{Pypk{^RrSpWME9{q$FV`Rw(pr}L|?Lf_%~ ztFZK+Yp=uN>g&+Ia>8}kF4pVI*P&bCc?a+bx5R47wOGyP+s)-`aaUt`^)1mK?D|_` zwZ7SRm$~j9vAX&?^v9ZT9ricfgRZ*@>#MKA_WmjyA8S1zZkGGSeBJ+a_n^;Nk3VbP=gnycWRxawxP`Wjq+cbva_ z&^x`^A41I6o89L8fnjv;pnUS|n+X}_hePCr4)guyW_$j@aJ(mc_QQ8muEOCEdEqK7 zmg~j-+IxblaQ!`Demp`hwyX8&6>$u>>AN0UZ2GUuGtU#Bz5MofFJJ#+%AfyuV7&Cr zw>Nd@+I{G*c=+ZM{^Z9a;^l9CcS~IQ<`eGz$3x-8Z$4jc7iXRj4uA6N55x1rLGb3$ zr|&G+7~ z=4YP#4&Qut{WtHSbN|#k?|{1K9&mrEdGn|s4-fGR2b#NY{K?Z_{P5L;hxy`gn7es& z{+stKeDRKc_sy?=m@ke8xU=8fY4XMU+9yvxTTJI>(*XC7_8eEI78U%Y<(;ulXp zzy0>RKYaP+g!}#SKB*(+xD64zluj^p9*itBJ~4%gxO!^867xOno|Slu5C4iRp~ ze?N1!dAKut^7PY}-@kq`rNhIa@$C2S@Nn+<@b>qg(BR?lc<%cj7NQTG@V@>1C*1xI z2gtME|H1(A_V>U3+}8`3yQii%zW?3L{m|bNlY7eLKmV_P_3H`sSH}b6_U+TK#r?VX z;Y#c;y!`*{**E{#EO&Q|c1-F=EmN+_@!0t8RdGl@d9IjrRetlLpD|p0V!ApW8?U$; z=c~MNi~M@>4RSm}UcM&xd(nsPAMd*+*FQ#A$K&J`*W~;<@y0djUh=!!DQE7^knT_9 zwvD4!;)j{Py{`Up)Wvlc#_9^^~)Q_3_v#`%}k z?_7%sH^%X>c*V6i{|ft^t8x9g)cSZ(yy9w{f35w_)wuqY$`4NN9~t9C)*BB|lkv$T z!};m2!tSKv3Fem3R%AC8MxegE_K%H#LH{_eOr z92~Fu{%7}|!s9^fZb zSKkB|UfbLynE2GZIUX0UxCySf3ykkS;VyVQB3}OfewfvL=0i`BCpW-^JK^zIxc7dC z?h+5rPwTf2LRZ}fp7fTQZ>QV`j)%eV2Ryw7ho2!H9tLgzKL|N@6MQoDFt|A$2CujR z=YN)`!PHYzKdQNZ5WMsKPo4r67k-R*_pK-1|F_3O;QIcpBoF!jx*LD$Az*tv3SMyy zuDSK^uEF(>!R_%dxVqnu9&UqPx_LLn;r_R|;{NyK>32_lcroDtU@^GwfBE}gz5(vP z|AasP@fdjN`(OHLvisnZr;Y$q&O^3`gW&NDsQ=&LHb1`0U&))-;rbWCyTbwT zs_Ss}?IjOaVcJuH_xavG9^O;pZk3sQkDU0lusa+Q-+L>(bses~M~>@o{XKGjJStwk z9j?7cj_Yv!J#v3MG+w?A*WM$?b-4Z>X?l6MKR5{gTO6Uf4pUwm?@y1Cm#)Kv`@^3n ztoGhKdG+lu;r{UF2|sz>pB^PI-3}A(4}X3-;r{S&lsw)Mj%TRr>u&ug6VFfg4~NC~ zf7A2tFuXq!K6(1b@28xLd;9ub@#8mr&l|n3{v&_-_ft+x_s3)4&3H@Q>FMEoycOqo zvya!qJy1XNv}_ISCwCKGiOp}0$G>a7|J_7(>HA-Q_?_Pzk9{lCba(xSGlH9bcrZR) zaCjm*_wkcI{`DU}nR~%||DeC(N}T%u$~)I$%1v=R{9SV`&dlQ{*JAodQ0Csref_O* zZXr9l9#cPrGQT+<1h2R?&Ml?yT#M_Eg7ce)!{DQ9uEmGv(s!=Jg!e(;JRBAu9gYBp z$H>F6;R6SSyKj5^)WNjRpUiI_j*TDw&K)byzG!>jRhaUqI36HB_=kUVbM}SX$u;67tugX3-R=8DUGwcnmQGd=nC z6Ar(ppF_F)?a!Q}o_zZWA4EC*B+A8af9}=5$+y4$vncb^52IZE_8*=qPQLr~A4Zuk zj;Dv0?|Jv{t+{m1+h6^b!}-bQQ7(V`3+IK0hyDC!!uLO(5?=BB&z})KeE;j;Lo@f8 zi~Gag{Qga*hcl0d0q^0cd+rlK5A~;hB51xi9{R4h3THm4@YYqBaP&R>kjlkd;oLi# zPOieFPY2C?3hU|)XWlmQ<`tN76C6(jFITw#5#ssB;rM{mgy*2e@jUQ~YjEZ*OmE%> z6P|`nKC5#18r;A0?b2;9@k2xNlh3Iv-+uGL=IsxN-2Y(VL)YQ(*7(2Xb360p@r>|_ zD{|&te&sk`k;xyJnfp}`_m7Oj4^AGAQ15(@>FOI~+9zh_%j044iYsyLjWO*bGxOu; zRUTcw66cQ*#~{-_GBaNuPZY1X4rku(_{P1$m6-B4JsvC{UKBmtC#HRX=j3Wk{{YW? zc|2%db4AX5lIJ~FWWv$=_)(VQ%ft`gBHcg7yP_@~Hx9SRgoF6Wr&_MKMGo`dwO3@q zeZ;%U?hhO9yCPFQ^LpMIw0?K6vaKQ(dp2H6kY8Yl0W|HaekpYoaekw}?2k+{5Ox<3*9_K!7^!D|b{JE#O-|+Hq7rDDP{@dI|rhdq0{_x?Jn@8`t zQM?j4y|Ye;Gx>v0^M}v6Tys^X^trz(6YeSxpMAONs+{>a*t>U?X`g+XpL_=9?ZNQT zq|ZRTc}=Fi(R6EWh0 z_es6?+&d1{ih)&oSU9}N@h3C#7=(H@y-Y6 z&cBd*=d)T9w!f3l%3N_Z&cBv>=Xy-IQ=EKa=8Efae)xIkdQ7=z9AD&Lz8)9mpLedu zl)J~tar6ESNXJ8kpFZ@`=5VO+!;lYth^~Xy-3Mr<9MvxkK6d0O0O*I?S4hv(blvG9s3aOM+i z4>!LnFy$6F9t7WW1>QWbKl>57hb!RjKjkwm9e5tjU$3|d=id@=cQ?4Z3R7-{KfOt}?~XN~LoBi)%t!!>utuEMm__mj`o zTyYhyzb{NUJvsS&&C1@!dySdW(w$0OpUH^{g+ckl5q>Cos!(ZfsoyM^}TMtJj}aN%Qr9iJbr#^Ez>6He4lK4`PQKR3R=CZ{)q z7u4e=_=ldRAFhHU!<4sIpM1>b-1k2W?$>?)3CG5hkJy~~{+Hf8`Q{&g!a?cu(>3=$ zLU_0%yz{xY3-8>zzY^2W)J{KM^X`?n8i@J^6>V~i{E|P$4~}x^hQj+t#gnJgK6Wxce$?jC!|$+s zNHA|j@pgi{0B2sl{1qQKIey&cQGa_>i)&Aq$8S9411~)_9KQdABjV`?Zm#(L=YPI< z`2N=)68r0w9-bSo`SYLu(beJme|SE+f3M+t{(hOezx(ISzrV)cQ{%5gJN~se$G<;j z%HOQhUFP_&IQuv2eDcR%{O0#hfA@!9zUS}P`NZFI^}GHqpl|%!ZvXO!ufP8O_VxH% zaK?Xs^0L3^>~B9_E>`0gN4a$G@BiV;*FU^^_)B~~`}~jp@Z|G<_~WmhKKa8RKkx7J z`R%WM{rShU@ozo-%YMc+xckd~KKqA1{`wbBe)aL}vmai4{p`!z-~aIK7q_qe@O6Kk z+G~HQ(BV5CZ<>d{5y(Yu54YaWZf5h@Vz!*EX6xBzww>)}``NsIIG@cIv-xs1U(M$0 z*?cpbZ)fw}Y`*U=S?h0Sn=KZz#d5Y-%@*s~Vl!K8XN%ozv7hxft}W-YW&g_MY`K~( z*R$njw%pE^yV-I-Tiwi7^Vw=KTlF1Rv(KvrX4`Guv!uo84@)pKWhu+xcv}m~EG{?P|7N z&$j(>wzKVSw%yNmH?!S*wp+}0%h_%<+pTB2&1~17b~oGYXZxGkem>hTX8YxAznbmW zv;Aha-_G{k7;cSjj+<_en{JSsZjqaAlACUmn{JewZk3yEmYXg&ZniGxhI7lg>D+d1 zJhz^kuiLM8EBEF0?Q-3Qy@9o_F4xW2n<)G0a@~^iZpz+E*Ow4ouA8$rQ1#X2xT=z%y)mG#F4t|_&!PM3a^1ZB%(Jg9*Dc%++4|~o-N>C-_SNOO zo%=vvUtO-7dfsh4@5Y{YYqzQP)#bXu=iTD-Zt~WxzPenudV@<}U9KB`-YwtD?!LNQ zH~zd^zt>)Ub-4m`^50jNt3e0yzPel)=5^>Cq^~Ylik|-Z>T=bXmt$U!j!yofzrMN) z)?-nRMLibvSkz-tk3~He^;mR2Uesezk3~H?gYK)#)uX>+u&*xX4n6MCUCw>lo!Y(H z-P--y9lIWjdMxU(sK=rni+c17)K{0Q$D$tn8uA_!U9KLBdUXESSC^~Dq8^KSEb7tG zpa)KutH+`qi+c16N&D(@^;pznQIADE7WG)vV^NPqJr?y?)MHVPMLibvSkz-tk3~He z^;p!SUu)P`m#fF39*cS`>anQDq8^KSEb6hS$D$sKdMxU(sK=rny_vhOE?195J({Tc z>T>m1)T7C=FOT>h^7UBOV_A=7J$k!kUp?^av8+d@tQ{5{8oFFP`i;DOb-8*h>#?lI zvL4HNEbFnX$Fj%AvK}2e`|5J_Sk_}%kEJ7xLycq2IM{SKha1Nm2OLKnhn#vW>#?lI zvL4HNEbFnX$Fd&FdMxX)tjDq*%X;+2jJ~>DJ(l%Y)?-Jv8uanWFsvfI)tm@Iw z)K{0Q$EqHydaUZPsz-nOW?x;d9;anWFsvfI)tm?6<$EqHydaUZvnMhv_?_I7Q zt9q>Jv8uanWFsvfI) ztm?6<$EqH^YqGB{SC3Ua`mITQb-8-1>d~9t`|5J_Sk+@yk5xTZ^;p%TUq#wim#fFB z9<4Kdb-8-1>d|K_`|5J_Sk#5JvUze*#=ktAaxq7VY(W{HTx?DZh^;p+qU5|A=*7fK^$9;9V zdaUcwme!MKm#fFR9{molzPemJ*7aD|V_lDRJ=XPT5bUeV)nnb`qnWg?E?19rJ^JZE zPsd%Z9u0MUb-8-1>#?rKx*qF#tn0C^$GRTtdaUcQuE)9_>w2u~(QB!`x?DZh^;p+q zU5|A=*7aD|V_lDRJ=XQ;XH|W5xq7VYv98Cu9_xCn>(LuQ`|5J_Sl6T9quW=PtH-(? zy_Ki0E?19rJvQ~&)MHbRO+7aC*wkZFk529T>V%>mn|kzi^}f1XJvQ~&)MHbRO+7aC z*wkZFk4-%`_1M&7Q;$tOHudO7tbKL4dTi>ksmG=sn|f^Ov8l(V9-De>>anTErXHJm zZ0fP8$EF^edTi>^&k_6Ta`o8MV^fb!JvQ~&)MHbRO+7aC*wkZFk4-%`_1M&7Q;$tO zHudQJqkVO`dTi>ksmG=sn|f^Ov8l(V9-De>>anTErXHJmZ0fP8$EF^edTi>^OXR+~ zTs=1R*wkZFk4-%`^=Q!TtIO46Q;+@vuD+bPb?R1+Z9TU2*w&-Lqpwcj>anfIwjSGh zZ0oVDN1veUtIO46TaRr$w)NQ7V_T1HJ+}4O)?-_be!|>Wm#fFN9@~0s>#?oJwjSGh zZ0oVD$F?5ZdTi^lt;e<=+j?y4v8~6p9=+?guP#@QZ9TU2*w$lPk8M4+_1M;9TaRr$ zw)NQ7V_T1HJ+}4O)?-_bUOV^IT>ni)}x)SuP#@QZ9TU2*w$lPk8M4+_1M;9TaRr$w)NQ7V_T1HJ$Cij)niwW z2JpT*VXnun9=m$%>anZGt{%I3?CP)`FoeE$F3f|AGxnCSC3sicJ_1M*8SC4+PLtkC49=m$%>anZGt{%I3?CP(P|lSC^~Dz8?E}?CY_w$G#r>dhF}5ugAU~`+Dr_v9HIz9{YOi>#?uL zz8<|DtgkLtk9|G%_1M>AUypq~_Vw7;V_%PbJ@)n3*JEFgeLeQ|*w z_1M>AUypq~_Vw7;V_%PbJ@)nJ?M8idxq9sD(T3btm#fFV9?ds>b-8-%>(LJz`s#A^ z*wAUypq~_Vw7;qo0WM)#d83uSc&3d!ceuk5FIW1h z3G{;HrZT;HWYi`wsuLLX35*H_MvZ!{$*59b)G0736&SS&jB54Dlu@t1s90dsEHJ7T z7%ECXX27~8-Y2gW)u=7F&fjDcV* z1Y;r?8^IU}#!4_|g0T~fpG8mh|7!Ag1FlK|X z8;s##EC*vc7~8=Z55{^h=7X^xi~(UR2xCGR8^Rb7#)>dzgs~%xAz>^DV@eoX!Wa|A znlR>su_uf{VJr$`QW%@U7!}5y~e20KGJDrjj46|^;knp+z}&Fu}L<`#$AF*G+i1ct}C-61eEH$4P~$GP<( zFg(r;5P{)wZi5I6k8?9bV0fHcA_BwX+!zrU9_RLm?m`TYbCX11c$`}$0>k6nFcBCY z=eCK!@HjV51ct}Cg(5IK&W#j-;c;%K2n>&NQ$=8SoLeipCo??G4Hkjnac;8+43BfO zMPPWGTP^~_Li@@+WH(>;Z$GH_FFg(r;8G+$(Zp-Kam0`^Y8TO2jVbKT~ zHjR*B)#%a3(A=;Q7@FHQ0z-52Mqp@e;Rp=PjU0iYxt$|0G&gkwhUUFd4H%jmJOV>= zn@0x$hUR9Ez|h?C5g3{qKLSH@`$u4CZUPAm&8;ATp}8R>Ff_M?1cv73kigK~BGR#l zp}A2cFf_M|1cv6Ok-*U0IuaO~8%P2}a~nxuXl^D649zVifuXsvBrr6$mvl(Xu$Y7l zn@Py9nuH9yNyxCAbo^v!ZafJL&Fv?Fp}7eqFf_NK1cv5@l)%v3mJ%46n^OWqbBjt~ zXl_&q49)E-9mW}&n^potbL&cAXl`H$49#sUfuXsXB``F%v;>Cc#+Ja)+};uxnwwk# zLvyQ3&n67b4KIPAx$Pw|G&jElhUONSz|h&%6W}U#$+_Ka807G-*PGD$m-w6!OO+102xs@j{G&l4FhUT`Oz|h>>6BwFXd;&vr zqfcOHZujZ5B*XF(GHgE~!}=34>^~vH0@OJSLvtfgU}$a!3JlFnL4l#UH7GDNHwXoW z<~E_g(A+E(7@Av#0z-4-P+(|oAL>+!p}C1DFf_Lk1%~E^qQKDHRumYTn~MTNbBj@6 zXl^tL49)FEfuXtSC@?g)9(6{?(AV6d0P@mO8P_ur7rR`%=iTFog^oQ^>F~br#Cd+|U#ln%kNJLvwReU}$b} z3JlGSPJyAh-6=3MH$4T0=GLdc(A)qO7@FIlIvHkYZiWgB%`H)Zp}8?CFf_ME1%~D( zsld?ODis)-8>Rw7bK6v4Xl|Yg49zW6os%;(H&O+L=60&U(A-oN7@AwF0z-3yRbXgt zvkDB&%~pY-x#cP_G&f!ahUWIGUK(UrutJ6nD`Z%)LWUhHWLUC#9l_Atm=zeB+p_{g zbCXtJXl~UC49yK&fuXr=D=;)SZv}?t7Oue1+{hIen%lX0Im6K0)D;+-Te|{7bAwl4 zXm0Zg49(46fuXtOD=;)Seg%f+_OHOu+yoXFnp?qoRmITU5EdAk+rk1vb8}c=Xl@Y; z49$&VfuXrwEHE@TjRl70*0I3Q+&~r>n%l^FahG8w3mJB@kYOnc8Md;JVJ+*GAVYJ5 zSzu^xGYbsO&1Qk2x#cV{G&i0FhUWIOz|h=;78sga(E>wrLt0>HZcFP0DMNE}T3~2y zQ40*sjcS3Rxm_(VG&ijUhUV6_z|h>l78sh_*aAayGh1M2ZfWavF++1>TVQBzZwm~~ zO>Tjqxz#N&G&j5jhUT`nz|h?M78sga-~vN)BV1r;ZinmTc|V}G!-alCZHEi}klGFx z`Z2W~F7$(HJ6x~j88r`#ng>SB1Ec1FQS)B-Gin|fH4luM2S&{UqvovyjG6~V%>$$6 zfl>3osCknDqvnB8^T4QiVAMP?YTo|9sCi)2JTPh=7&Q-!nm1N3Y91Ih4~&`zM$H4G z<}DkHng>SB1Ec1FQS-p4c{2#3=7CZ3z^Hj()I2b1-e$t6d0^B$FlrtcH4hBU?QkK( z4i_@)a3RAE7c%T{fuVUT8!$At!v%)s-klQ|nz!WuL-R%yU})ZY0SwKX4T9#qxCe&j zy{ZO==DnN+hUUGF1cv6lfCGl+y>bGE=DlPIn)kv27@BuR4-Cyal?I09ox=h{^G+Ut zp?PO*z|g$YrJ#8yHNeokvk72m-qScRH1GKn7@GIQ1q{u5#sG%q9jb%o9Z-Rxc}Fr} zXxTY|=Wg2tPI#=C;X+k(dXg2o$z#yf+?TZ6`XgT|YK z#=C>Y+k?jYgT@<##yf<@TZG1YgvOhM#=C^Z+l0pZgvJ|%#yf?^TZP7Zg~pqO#=C{a z+l9vag~l6(#yf__TZYDahQ^zQ#=C~b+lI#bhQ=F*#yf|`TZhJbhsK+S#=D2c+lR*c zhsGO-#yg0{TZqPch{l_U#=D5d+la>dh{hX<#yg3|TZzVdiN>3W#=D8e+lj{eiN+g> z#yg6}TZ-&(-MICz!-aa-;X*y^aG@S{xKIx}TqPKq+u;I3b30sMXl{oK49)Fuf#Gp( zhYJkN?QntNac+kT43Bd=Twr*d+u;Jk~JB&4i_@) za6Oh7n%m(5LvuS^U}$cK3k=QeaDkz@9WF35x5EX7=61Ni(A*9e7@FJR0z-2QUhURv-z|h~JB&4i_@)a3RAE*BJ>zb30sMXl{oK49)FufuXq_E-*B=!v%)scDTUM z+zuBQn%m(5LvuS^U}$cK>%@qmxg9PrG`GVAhURv-z|hR4i^}j+u;I3b30sMXl{oK49)Fu zfuXq_E-*B=!v%)scDTUM+zuBQn%m(zwPk2-hYJkN?Qnsixg9PrG`GVAhURv-z|h~Os*U}$cK3k=QeaDkz@9WF35 zx5EX7=61Ni(A*9e7@FJR0z-2w^h)xX?!v>~NtEC)nXaA5XBug+8EQhwF76 zqvnB8^T4QiVAMP?YTk=LM$H4G=7CZ3z^Hj()Vx=WjG6~V%>$$6fl>3osCh3h88r`# zng>SB1Ec1FQS)AlGHM49)Futu_qJ+h~BHdE*E$ zG;fsvhUU!yz|g$c;lR+m7r?;KyjPyU(7cy?z|g$cTENh}7db)mUWx!i^Iii0L-S6) zfuVV4y};1C(@kJ#-gzD{H17l}Xx?cMFf{M{0~nh3#19P3d&UKZ<~`K`L-U?vfT4K@ z_dY+Td52)g=s*b>9nK)5gAQbLXb77300xHUJ#v7dd3RZ0Xx@DV7@8Le7@BwM07LVx zR?s{d7@FUG{7>_{4*+U@_YpwN$A@_p$A<#Prvk^v0>|e9#|Hz)Cj-Yv1IK3r$A<&Qrvt~w1IOnB z#|H$*Cj`ew1jlCt$A<*Rrv%5x1jpwD#|H(+Ck4kx1;=Lv$A<;Srv=By1;^(F#|H+- zCkDqy2FGUx$A<>Trv}Hz2FK?H#|H<;CkMwz2ghdz$A<^Urw7N!2kmg(RNcCExX`U@ zhYR(v!-aa-;X*y^aNVv9&Fyf3p}8F{Ff_Nr1%~E!xWLfd4i^}j+u;I3b30sMXl{oK z49)Fuf#Gp(hbu3`k6n4i^|6=XSWj@Hn@_1%}7D9WF3D&h2o4 z;c;$<3k;8QJ6vFRoZI2LvuD`hLWUhKWZ2)6K7+zuBQn%m(5 zLvuS^U}$cK3k=QeaDkz@9WF35x5EX7=61Ni(A*9e7@FJRI>a(Gx5EX7=61Ni(A*9e z7@FJR0z-2~JB& z4%hhwLvuS^U}$cK3k=QeaDkz@9WF35x5EX7=61Ni(A*9e7@FJR0z-2l~j^^T4QiVAMP?Y91Ih?*##)=7CZ3z^Hj( z)I2b1-m3>j%>$$6fl>3osCi)2yq6k`ng>SB1Ec1FQS-p4d9OAJn^IqlyL-Sr=14Hv(*appe`3Vfod))^N&3nNG49$C`0}Rc3i2)4FJGTdh=ABdr z%{%o4hUT4f0z>mo_JE;zXIa3|ywe+CXx@1RFf{K8z2AYQc~85L(UT)&^b`geJ<&i$ zPX|Hs4%)!byrU&BH19A449z<}07LU0n847yM+7i5@2(g$?+ybD%_{{A&AW+!p?TL0 z7@GGFfuZ@`ul>^e?iYV)K7RGr_}yRQmw%1l{xyF6*ZBQk;}?L9-vBm#1=#o5;}?RB-v~B-CD{0#VB?p9 zjo%73el6Jeyk6n4%dB#;c;$<3k;8Q zJ6vFRoZI07!{giz7Z@JrcDTUsIJd(EhR3-bE-*aK?QntNac+kT43Bd=TzB0JJ6y=H z!-WhxT*$D)g$z4f_j88kcDTUM+zuBQn%m(5LvuS^U}$cK3k=QeaDkz@9WF35x5EX7 z=61Ni(A*B!!;PW29WF35x5EX7=61Ni(A*9e7@FJR0z-2~I~a7@FJR0z-2$!%Zxg9PrG`GVAhURv-z|h%H8VAMP?Y91Ih4~&|3CdsIIVAMP?Y91Ih4~&|3+R3PSVAMP? zY91Ih4~&|3j>@QcVAMP?Y91Ih4~&|3Ld&RmVAMP?Y91Ih4~&|3_RFYwVAMP?Y91Ih z4~&|3s?4Z)VAMP?Y91Ih4~&|3Ud^a^VAMP?Y91Ih4-C!ia3RAE7c%T{A;S(AGVE}H zp}8F{Ff_Nr1%~E!xWLfd4i^}j+u;I3b30sMXl{q=wE#nNJ6vFBZifpD&Fyf3p}8F{ zFf_Nr1%~E!xWLfd4i^}j+u;I3b30sMXl{q=B?&`wJ6vFBZifpD&Fyf3p}8F{Ff_Nr z1%~E!xWLfd4i^}j+u;I3b30sMXl{q=l@UX8J6vFBZifpD&Fyd@!wwfR>~JB&4i_@) za3RAE7Z{q`;Q~W*J6vFBZifpD&Fyf3p}8F{Ff_Nr1%~E!xL(aMG`GVAhURv-z|h~Mjhxg9PrG`GVAhURv-z|hU28QOH(gH*C z&Lx4Nc_(rG9(&C@)q;#ph#;fW7Rc!20x~)U2%7gq4GhhDh6IM@Jv9MC^PUrcp?L>m zU})Y^5Ezou1%~E!xWLfd4i^}j z+u;I3b30sMXl{oK49)FufuXq_E-*B=!v%)scDQbOhURv-z|h z;X;22jU6uZ*U;GELVppB9j@noM$H4G=7CZ3z^Hj()Vvb~M$H4G=7CZ3z^Hj()V#9_ zM$H4G=7CZ3z^Hj()Vxy=M$H4G=7CZ3z^Hj()V%W*M$H4G=7CZ3z^Hj()Vz}$M$H4G z=7CZ3z^Hj()VwnxM$H4G=7CZ3z^Hj()V$LsM$H4G=7CZ3z^Hj()Vy;nM$H4G=7CZ3 zz^Hj(Xl{oK8FsjkVTTJDcDRsXhYJkN?Qnsixg9PrG`GVAhURv-z|h=~Nd;Q~W*J6vFBZifpD&Fyf3p}8F{Ff_Nr1%~E!xWLfd4i^}j+u;I3 zb30rwFc_NK;Q~W*J6vFBZifpD&Fyf3p}8F{Ff_Nr1%~E!xWLfd4i^}j+u;I3b30tG za~PW2;Q~W*J6vFBZifpQcDRsXhYJ~YxR7Co3mJB}z|h8JgSS0z-2LvuS^U}$cK3k=Qea3RAE7c%T{A;S(AGVE|6!wwf1n%m(5LvuS^ zU}$cK3k=QeaDkz@9WF35x5EX7=61OD5r*b=xWLfd4i^}j+u;I3b30sMXl{oK49)Fu zfuXq_E-*B=!v%)s?P$Qzya6j{-pm9H&D(c?p?Sj!Ff?z`0EXsG3Bb_2*YLp5ycf?w z^IqZtL-Sr+0z>m&)B!{DUQGc*^IpaPL-Srg07LUm-21yIHShEqGCB!{j80V{qZ3NV z=(I0r-pLs-H1Dhk7@BuF0u0SN4*-VdJpltl^Pc&Dp?Oa^LGzv%fT4LuWMF9Cp%56F zcMJlC<~{gxb=dp}&CG4%hPlqvnB8^T4QiVAMP? zYTlCuqvnB8^T4QiVAMP?YTh#pqvnB8^T4QiVAMP?YTnZkqvnB8^T4QiVAMP?YTk1f zqvnB8^T4QiVAMP?YTgqaqvnB8^T4QiVAMP?YTmOVqvnB8^T4QiVAMP?YTi>QqvnB8 z^T4QiVAMP?YTolLqvnB8^T4QiVAMP?G`GWr3_D!Nu)~E6J6y=H!v%)scDTUM+zuBQ zn%m(5LvuS^U}$cK3k=QeaDkz@9j>ep?POJ zz|g$YjG%cZ1HjO{XJKGy-qRm2H1Bx_7@Bv$2ZrVyX@Q}6hq$152O?l--Vp#8n)lEH zhUVSpfuVVKHehI8WngID%^NiDMgWH9eRp7J-hY6hxg9PrG`GVAhURv-z|hjr0NZifpD&Fyf3p}8F{Ff_Nr1%~E!xWLfd4i^}j+u;I3b30sMXl{oK49)Fu zb!TX9hYJkN?Qnsixg9QK*x^Ek9WG?p;X;NTE@ar@0z-2$$6fl>3osCi)2JTPh=7&Q-!ng>SB1Ec1FQS-p4 zd0^B$FlrtcH4luM2S&{UqvnB8^T4QiVAMP?Y91Ih4~&`zM$H4G=7CZ3z^Hj()I2b1 z9vC$bjG6~V%|nJAE@ar@LWUhKWZ2-bx5EX7=61Ni(A*9e7@FJR0z-2Xl{oK49)FufuXq_E-*B=!v%)scDTUM+zuBQn%m(5LvuS^ zU}$cK3k=QeaGk+2G`GVAhURv-z|h~Mjhxg9PrG`GVA zhURv-z|h5CRO%TOfd;c`yBep?R;lA){Bu zkkRW`$mmrjWb|4P7@GGY3>cdC>IWE__p$>Rns>er49z>y28QOH;Q~YRPA!Axod5zu z^Ul10p?Rk~z|g#N4Pa>AlRPjq@7Wa?n)kF8H1Ej=7@Bv~2ZrVyZh@hB$2nkV-T?*} zn)k>ChUPt_g67@vfuVW#IACaAYG7#IZ43;}`@;c4^Zu>C(A*B!7ejM9TwrK!hYJkN z?QkK(4i_@)a3RAE7c%T{A;S(A7@FJR0z-2$$6fl>3osCi)2 zJTPh=7&Q-!ng>SB1Ec1FQS-p4d0^B$FlrtcH4luM2S&{UqvnB8^T4QiVAMQh*x^Ek z9WG?p;X;NTE@ar@0z-2r|ehxg9PrG`GVAhURv-z|h}MYQT3E$?=254GRqSUT?pavHe&%tOg({*U3suA{7OIFWEL73w z|AkfTXWj?zg;nfl-Y4FLRqSWpN6m#*>}TF*yoFWlXWoaag;nfl-lv*{RqSWp$BDvz z=H2u!tYSa&?zR_Jv7dRjxeKe<&%FD~g;nfl-i_VDD)uw)j%r~Q`}TFP{lY5tGw&^SVHNwC_ujU!iv7%cQ(0KWe&%iSg;nfl-Wo0JXWp_~SjB$kZJC8t z>}TFz?}b(DXWrkdg;nflo}m|3v7dQPT3E$?=KTl@`KtIbHu)n=vTYBSSvwb`jWKP{@wQOnilspV>O)pE6b)&ENw?OR;! zc;Dh`NBkC7JLb2z+EKqEUyb`MSIbvJe^b=*)#%?8wR|-In8H^>fXnset5Luy`tsF4 z;1qrNYAi5?uSNrx>&sUIf>ZS6t1-b8z8V!=t}kB=3{KIPuf_(a=*w5bgDHG9K)76A zz8WK(qAy4UyUs;SIbw!i&NC{)d=GhwR|OpuSOh~>&sVzj#KpIt8vE^z8ZO4t}kB=K2Fh>uf`vz=*w3_kSTmM2)SHez8Z&| zqAyioSd`K$*f< zLzK()<*QN3Df;r&K;;yD`D&~(g|9{{m+Q+{1C~?t<*PBvb`xKXS}tGTam&Tkj$AIT zcIVNOxYSEHCy)biCpW(r>oWiHp3uSPSc=*w3Fnp5=Ut1-xxRcgz&S-&~%Evd^K*G!dD}w z%k|}}!P6=F^40ih3SW(&F4vc@22rQz%U9#5Q}pGlq0|(<8cbcTFJFzPPSKaIhE%8M z%U7eSDSS1qx?Eqr8d{yAFJFzWrtsDH>T-SgYKV1;zI-*xIz?Z;8fZ=7tD)BA`tsFi z>lA(YYQS}hzI-+2n!;D3uFLi1tAW=k`tsG-YxhrlHTt@IeaBxHS33f`xY{w;#q}M9 zE%Mbk>~ghyH55BVEnkhsPEpHO1F|W6H6*)SU%ncZouV&a4a`o_m#@ZVQ}}9hcDcTM zH9$K>U%ncnP2sCi+U5H4)j;hOefesvc8b1yHC&s*R|B@o_2sKE+bR0;)v)apefetS zHifUoZkOxJSHrhc^yRA&+!VeV!(FZ~Uk&3<(U-4Aa;NCaSA)4Jd^McATwlH#(Ve0% zUk&O`(U-5rbyN6iWOuo~d^NZ`MPI%e-|dc^uSR&6ukRS|;%Y~E7gsyZySTn1y+ytn z>s_vvuZDZ4sO75>-zjSOYS1@@uZDe>>&sUozf<((tHIwX`tsHIZwgK2T#$LuZDzE_-asixxRcgE<8nFz8V^yqAy>K4yW+d z`0#Rl`D%!GioSd`N}R%1(%`D(y8g|CK;m+Q+{qsCM8<*R|? zDf;r&*l`M9jUF%8m#+qpr|8R9W5|8Rb;XmXLS#*>$; z<*Om(DQfv@RC$V8z8Y9g;j5wL<@)l~=<*bO`D%c9ioSd`#+<@eqs+_o<*R|_Df;r& zSaS+rjW#dWm#+q#r|8R9W6o3b<*Q-m6uugGUal`+jXh7%m#>DOr|8R9BhV>)H3q$0 zU%ncKo}w>bjYOyL)mZd$eferQdWyb$H6lGlU%ncYPT{Lz>E-(J)yVV|efer|dWyb$ zH9nofS0mKR_2sKU>M8p2)i`z3fUicXm#^Nztk?SdH`D*Ywg|CLMm+Q+{BiK{)<*PyLDf;r&ICctOjbty^m#+r1r|8R9E zHKM&-U%ndDo}w>bjcZTQm#>DlQ}}9dd%3=RHNHJXU%ndRo}w>bjdG{()j0QZefesr zdy2k%HQJrRSL5Bw_2sJ}?4-jgn8%m#+rOr|8R9W92D)HCn!0U%nbJpQ0~cjhUzL)u{P$ zefetOe2Tt&HFiElU%nbXPvNTp^yT{U)foB|efeq_eTu$(HIkmfS7YhR_2sMK^eOuC z)rfiuUyZ3R*O#w`)u-soS0n3F^yRC;^%TAuUSF;+UyZO&(U-3V*{A5sSL5s{d^OU( zTwlH#Y@ebpU*YXx(fSsvE!MYKZL!*7eT&r=t1Z^ISl@7%+WD$n?R-_PcD^cCJ71Nn zov%V3YUitRwewZE+WD$n?R-_PcE0Lkt=jpjTwNJ71Nnov+H(&R6AX=c{tH^Hr-v?R-_PcD^cCJ71Nnov+H(&R5w*?R-_PcD^cC zJ71Nnov+H(ZeR6(R@;wUTx~xFakYJG#ML&gxY}M~k+1q6xmv!$+mqGu72ckrmap*k zAiY|?!rN2yDPQ_Rd)JAYd%zQWtf_2nzPy#e**tDVE`>-h?A zFL%9sg}0};UcSQHyExa&S38os%hi{!b}Dy@zI?TVxhZ^wx0mb7S38}%Kh>A7c0hNE zzI=tZ_l?w-ukiL1wS0xQr>NyCyuEL{>*XuFJ;ls?g}0}enXmBn4n~`qukiL1GxOEX z?lvJ`;qB%6@)h3R4|#p@_Tp;s_Tp;s_Tu{D?ZsU$-ds^u%ZJw;!>!rL?8t`~1Fs^u%ZJ;ls?g}0~Z%U5`N<~1{4?W}LF z##eZIxtaM2Z%;8ZU*YZjqDf!A+OgkWfv@oPax?Q4-ripkGxHVRo}w>b?F4YIz*l&C zxtaM2Z||>{nfYobf%|&<3U4nrvwelPr&4rPYWWIpPtljJ@b;F|t`~1Fs^u%ZJ;ls?g}0~Z%U5`N zzeqGQU+p|`uf|t+d%2nU3U5y_GhgBDEk%9#YDbHE1-`=D%gxMJczf&9%zTBnr|8R9 zJ7wG}@D<)(Zf3s1+grV6=Bu4H?(6vqZ!b49U*YX3X67rry|ry-zS_a#UV*Rh_Hr}x z72e)2RL#s+czcSze6=&ky#in1?d4|XE4;lohs}()7gvk77gvk77uOeWFK%YMy{MM2 zb}D)LX2#o#yI#D#xV}4^T;wafy?ob;w-?p&72ckrFJIy9y>ab&@%ExxzQWs6%*Rc!rObp)R(Vze7RTPE4;nj%zTBn_tt7= zzQWs6^yRCaWbPIC3U4nrGhgBD{TkfNe6DP zyWKN0U+n;OufSJ$d%2nU3UBWqhMD;aZ%@&euXdKYSKuqWz1+-vg|~N8xta0y;%f2s z;%f2s;`-w4#m$Vj7uE9BPFGLg%y@fo*Ne9o*LP>Ei+qK*m+yM<_M%$8!rN2y%-!rRNu%vX4O$7jsUS38;A*Yg$LUT$W- z!rN2K%vX4O9|g?JS39KLEASQGUT$W-!rS}MU}nC;+f(%AtDV>G75EBoFE=w^;q4vp z+01x*akY4RakY4RaeeXj;%3I%i)#65C%C6?X1u+)>&4rP>$`K@MZUt@%Xhtadr>W4 z;q58<@)h3RKUv)M;_XGXe1*5Cn3=Ee_7r{j3UBX&l$rTz=ev6~zQWtf&CFMLdy1L) z3UBX2n7(|qqu#v&U*YZLX67rry?<9}X1>DPQ}pGlo%-$-_zG_?H#1-1?S0fUGhglW zcVEv}czd~-`3i4OF*9G`?R`u%Ghgi>c(1@$czd~-`3i6EAAg#eukiL1efer6;mEFYbEr_Tu{Ptay>H z@b>auFWz2M%U5`NioSe>xA#GL*Ne9o)$$eIo?>Rc!rN2y%9VB;qB#S<}18C%wuN0!rN2y<*S`u?-lq8 zZ!b49U*YW`A~W;VPOB=u7QAs$A`S6=qXAUzMvJ7cEyiUzMw!ugcYq zw+H9c&R6AX=c{tH^HsUp@%D1H^HoSs?R-_PcD^cCJ1$zTcD^cCJ6{C?)sDB9tDUdP z)y`MtYUitRwd11UL$&i&x!U=vTvP4{MzrYYz+bdua$map>o6u#dRMndy2k%73^3Q zUxgv$`tnsD@+tcARUe_J@KqmZ<@)kf9~UWR=Bqx8QOwL&ebkx4SA7(b>&sVodw;4g zU*YX3`tnsbrmNzsZW-nJ@>Mrv6n*)s+np(V)y;=oU%u+ConmIb>W!0PX1?leX$oKU zwjtM-ukiN%RA0Wr+f&xJ)g!KN>p)y>e?`Uh?XQivzFApR%U5`N;9M^J^z}Z7xA%`E)Y?~gdy1LuE4)2LU;7GgPcgH7g|}xzeeEl} zJ;n9fSI)PmnAyH^zCGKzUhjj>x2Krd`yk$)VrK7yczgeh!_4*--kxG+`wDMQF|&Pz zx2KrdzQWu4i(+Q`3U5y_vwh`!dy1LuE9cw$i)Ci-gU+|7nA!Uv-kxG+?}K=I|IozD z_7&cqVrKgaZ%;9^eTBEDY-YT@xW0IMakY4RaWmuX#r4J8i)!sFyuAgm>&4rPn;CB} zt}otR-1Xw^{Zp9DjJFrn+E;jcioW(0-kze?zQWsEGiJ80oNrIj*S>PTJ;luSmGkYb zC4KEH=i5_UuYHBLre0z$S?JK-J#mx2<-kxG+`wDOGSDj|IukiL1Guu~qdy1Lu zE4;l`ZD#ulZ%;9^eTBEDnAyH^zP;7Hneq1G`r_@y)#B~N&5XAf*B5W^7qDvWE9cu& zcD;CeaWmuX#r4J8i@RRDy||h2_M%$*%K7#beeEmf+f&rqS9p7GL}s?H@b(ma?JK-J z#mx2<-rg^Y^|i0?_7vA^U*YX3X11^J_TK1RuYHBLrSE%K7%* zD$Q(PIp3aQX8Q_nPcgH7g}3*sY%|+eczcSO?JK-J#mx2<-rifWne8jQJ;luS72cj= zX8X$d_7pSQSI)QhW^QKt%K7#bGuu~qdy1LuE4;m5wr^& z@b(ma?JK-J#mx2<-rlW^zV;Q~p5l7#E9cu&%xqsd-`=f|>$R_(Z%;9^eTBEDnAyI< z+dHaYX8Q_nPcgH7g}0}e*}lTtQ_O5%;qBdgnc2R=+f&SJUpe2NVrKiw`Sxzs%xqsd z-=1P-`wDMQF|&PzxA%`1&1_%c?I~uqukiL1Guu~qd&*|U+l%Xqw-;B7w-+}v-d@b+%5&1_%c?I~uqukiL1Guv0rw|6scX8X$d_7pSQS9p7hne8jQJ;luS z72e+Q88h2gczcSO?JK-J#mx2<-rnuMne8jQJ;luS72cj=X8X$d_C79bX1u+)zIc0a zwRn4RGvn>W^~Kve)T7qEa=txf*Ne9oH#6Q|TwlDsxa-B+i<=p5FRHb#oNrIj*S>PT zJw>g3g}3+N#?1B=-kzebeTBEDnAyI<+dF)uuYHBLr?_7G3U5y_vwelP_uoNw>rmznJ==i5`vY+vE+DQ32>@b->Jnc2R=+f&SJU*YX3 zX11^J_CDU3*}lTtQ_O5%;q57Awy&ITPcgH7<$QY|5Y22~Ip3aQX8Q_nPcgH7g|~Nr zYcu2R#r4J8i>t-ki<=p5FRm}%UQ}ye;q58AUc9}yneq1G`r_?SE3U5y_vwelP zr!;ezq1s}7i_KiDwpia{GZ(8Z*0kAqutgRk_;vs$A`SRjzivDpxyS1vb>q zSLJHwt8%s5SLJHwt8%sTRX9ZL_Eovs`Kny)d{wS?`>I^+d=*4dJ71Nn-M%VUJ71Nn zov+H(ZeN97)XrDsYUitRwcA(aYUitRwewZLM(y@hx!U=vTK4kczbcRczbcRczbcRczbcRczaPTU*YXRto6m)i|gCj9C3a7y|=i&czcg?*v!#f zQ7vD^9w=)0s=F|XTE1%bDSU;umz$Zd@b(ma`3i4OF*9G`?O`^3`KqIPdriK=+spOk zE4)1*r!QZ1ENoxTS9p85nfVHDPcbuJ;qAdZ*UMKO-`Okh72aNMX1>DPQ_Rd)czYmF zU%u*?#a@B0@b+>u^A+A6GBh(^^(*{+JzwGNDP`%^RX72cj= zX1?kJ&#L$eZ!b49U*YX3X67rry~m~K%U9i=?iKjT`Sx-%^Of`MDQ4!YZg=+eeAVrU z+{}E1xA&)J<}18CWi$7dCT`~5X2jLD`o;Ba9gCZ}6)CFas}|4{zG^AR)!JA6m7}QT zs|-DbuQHijU%tZI`%``S3U5!*m#-RPReXiFm+Q+{czc4re1*5C=*w4ld&lARwXg8@ z6n(u9;_WH=dLP8wdwDbS72clWdie@(PjS6`g||13nfVHDPcbuJ;q57A<}18C#msz# zw|8LQ%=Q)Do?>S2gLr$2nY|Cb;q57E`3i6EpF5b@zQWs6^mTuQx2Krd{T1Gxee|`j@b(nfYhU5* zDQ32>@b(nfYhU5*8PLr372cj=X8Q_nPcgH7g}3()GR$mW;q57Ac7KJpr-+Zf3l_xW0IMakY4RaWmuX#r4J8`-`jAzQWs6cD;CeaWmuX#r4J8 zi@RRDy||h2_M%$%S9p7hzV5H^_7t`D72e*$FtdGyx2Nc9U*YX3X11^J_7;r3_7&cq z;(F~XygkLt_7&dVKe%zd_7&cqVrKgaZ%;9^eTBEDnAyI<+goX7wy*H^6f@gbczcSO z?JK;!6=-Jr3U5y_vwelPrW^~KwZtHs-kn;CB}t}otRRBK=1?J2unyuG-Y@%G~S z;_bZ^?0WI`;%3I%i)!sFygfx<`wDOG4MeSdg}0}e*}lTtQ}ng3@b(ll+gEsdk2KTQ zzQWs6T(5nFx2KrdzQWsk%W}Q;72cj=X8Q_nPcgH7g}3(>XJ-2fZ%;9^eTBEDnAyI< z+f&SJU*YZjBQP`DS9p7hne8jQJ;luS72e*Ps+sL8ygkLt_7&cqVrKgaZ|_am%=Q)D zo?>SE3U5y_vwelPr)*}ty|})3dvUdRdvP=4?Zx%Q+ly-LE4;lo|6MQMUfj%hdvSg7 z_TsJ=Z|^o?Gvn<=we}U>o}#aPg}0}uwXg8@{t2C#?JK-JMPK_0Z%;9^eTBDoOQNrR zg}0};Ui%7fPcgH7g}0};Ui%7f@21Ag_7&cqVrKgaZ%;9^eTBF8kNnJRU*YX3X11^J z_7pSQS9p6jO=h;Q@b(ll+gEsdika;zygkLt_7&dVZI_wtE4)3$%=Q)Do?>SE3UBY9 zA)48~!rN2KY+vE+DQ32>@b+%&HZ$H{TwlDsxLUluxS8?x;`-w4-3+R=ukiMiT`%5V z+{}1;aeeXj;;t8OFK%YMy{Oi{!rN2ywXg8@6t(sh-rh~9ne8jQJw;#p3U5y_vwelP zchjn`eTBEDxL*4TZ%;9^eTBF8k2qbgeTBEDnAyI<+f&SJU*YX3X11^J_HL8SY+vE+ zDQ32>@b(ll+gEsdx7B90ukiL1Guu~qdy1LuE4;nOI-1$O!rN2KY+vE+DQ32>@b(ll z+gEsdH}Yn-ukiL1Guu~qdy1LuE4;lM|ILiI7uOeWFRm7EFK%YMy|})3dr_@@g}0~d zdhzz+X2#o#>x;Md@nYADw-+}v-dF+E;jcika;zygfx<`wDMQ zF|&PzxA&M#eeEl}J;n9fS9p7hne8jQy^lez*S^BrQ_O5%;q57Awy*H^J~o-zzQWs6 z%xqub?I~uqukiL1Guu~qd;hT5%=Q)Do?>SE3U5y_vwelP_d(6f_7&cqVrKgaZ%;9^ zeTBF8!OqO~72cj=X8Q_nPcgH7g}0|Pa~}t*E!MZ#%*ASp^({7YvD#vNi_KhAyM5J1 zNwxD;x!U=vTI^+eAS0twewZE+U=`ywewZE+WD$n?exu6DjES36(z(O>QMRk_;vs$A`SRjzjXs(iJ0dvUdRdvUdRdvUdRdvUdRdr>W4 z;qAeO^~KwZ>x;J+*B5Uut}osmme|aAdr>W4;q58<@)h2mqL#1l_K=2|`6`;VSL3Tb zU&{66tKMlTX6CEDb_!oP-(GHJzQWs6TrXeY?ST_B^A+BnqAy?J?J4^572ckrFJIy9 zp%>T7S9p7hnfa=JP`cUp3U3e6=*w4ldy2k%g}0~Z%U7N!lcFzQIo}@U(U-6A_7r{j z3U5#Gz2YmpJuKvV#aDQHitiO);q57A<}18CjI^2Y_Tu{D?ZwsN?ZwTEw-?tJZx24H zwXg8@lwB|0Ufj%hdvSg7_TsJ=Z!d0UyuGN_zQWs6^tG?>_7t`D72e)M9n8#E&bO!N zYhO9vo?>SEs-v#!$X9rKxxRemc`_;b@|EYwr0C069ZcLS*jIRax$l*I<$QaJ>$R_( zZ|_kP`r21`dy2mH72ckrFJIy9Df;pi-X6?zy?lkYr?_6e!rN0^FJIy9!9O$e72cj= zX1;R1J;ls?<$QY&!!R>n;q57A<}18C#msz#x2J4oyuG--czbcRczba(3_Tpyl*JI-PI^SO0_2TV4u46Of?M1bGg}0}uCs`vW#72aNMX1)r}?oaJ2&yy)vYhQVuOp5EZuRKqt2a1@PuR>{i1^WtbFE_J& zg}0}e*}e+R?Cbd|bRzeC<}19tKQ%L7;q57A=BqwPuZpicPo~_=eC2sEDQ4y?&y(qq zC;IYLAA9x+_7&bL({SDq)+BV^RtSDq(RP-|a#etU{q`^xj%`x4j7 zSDxRVVrIVbJed^N%U7N!6T&w$UwNKPikbP!^JG%Y%vYW#lVWDR@;sS_GP8ZpLGhcb0Op2NL%JXFUC4-sy%JXDW%*W4d7ez)>|HP3Ufj%hdvSg7_TsJ=Z|~P2n;CB} zs^u%slS$E+uRKpCMJ-=>o=iVdGxL?_x2NdKSDxRVVrIVb{PrxMuYKkD?J2I;zVbYo z6f@gbo+p#ydhILElj)Z>X11?9PbS68_Lb+!q?p;h@;sSLXJ-4#^JG%Y?EcF0WKzuR z{>t;)GpU*FE6;CFF|&Q;c`_+xwy!)-CdJJ5mFLOyYb7(=SDq)6VrKiw^JG%YY+rev zOn)uRY+revOp2M^UwNKPikaPCd479;jW#phUR+6fl*?JLidNinm1<#{qG`r22XCzE1k`^xiVdK=N#zVbYo6xVBCd479} zne8jjZ|`l#_1agS-=1P-`^xiVQp{{$d7eza7B;he<#{qGX11?9PbS68_Lb+!q?p;h z@;sT|=*(y)l~EzViI`6f@gbo+p!HX8X$XWctOmne8jj zlSwhNedT#FDQ32>JWnQNGvn>W^~KwZtHs-kn;CB}t}otRRBK;(o=k7xyI#D#xS8?x z;`-w4#a%Dn-mlg-Gu~cQYhQVuOp3ntmFLN%sI{*=Po~=hGuv05-=3ncedYP>DQ32> zJioo$3VrP>&u>q0z4n#o$)uRszVbYo6xVBCd7exM0nBV)d7ey)ne8jjlSwhNedT#F z-N=~PzVbYo6f@gbo+p!HX8X$X+q>~Gvwh|H?I~uquRKpC#mx4V=gFj)*}n2TnT{%$ z*}n2TnG`eISDq)6VrKiw^JKc!GP8ZpL zvwh`xGAU->zUsEUzQtxPR$HuZv6+k27VBGV=3=!)wewZC{A#za%GGXPm8;#pDp$LG zRjzjXst*ckx39|8&R6AX=c{tH+gIgk=c_(msGYCM)ox#vtDUdP)y`MtYPYZYP@;Ce zDpxySm8;#pDpxySm8+ev`Y5Az`>I^+d{wS?zA9I{eO0b@zUl*z+WD$n?ea<%hSx!Ucka<%hSx!U=v4_j)tugcZVSLJHwt8%s5SLJHwt3INs zov+H(ZeNwFov+H(&R6BD#oLRk#oLRk#oLRk#oLRk#oLQ&`3i6EL*e@3?Zx%Q+l%Xq zw-?tJZ|~#dX2#o#YWWIpPtljJ@b(n7e1*67(bLR)g}0~Z%U7Md+3WKa-d=8IzQWu4 z*s3pI#Vz*reAOojx$EVtcIp(q>VM^G`O5kB{?yET<$QaJnfc23_C6e|>Gvn>W^~KwZtHs-kn;CB}t}osmBv5N#;q58AUc9}y zneq1G`r_@yT`%5V+{}1;QLTN2x2Nc9U*YX3YV9k$y~BWJwy*H^6n*&$Z%;8ZU*YY+ z41M_uZ%=W(e1*5Cn3=Ee_TY!>lWD|jEo+sl2g>?`NnQ(Uio<$QZMO<(&8Z%@(J zzQWs6^tG?>_7r{j3U3d{xn91)+f!UGU*YX3u9vUy_72RNnXmBn6f^Uc^X(~S<}2sh z1Ab=aE4)3$%zTBnrNyCygi($maqCH&0fd*Al_cCulGT` zJ;ls?g|~O~SYN)v+f(%AE4)2LU%m<_-5uSygkMB@)h2mVrIU=+Z(~me1*5Cn3=Ee z_7pSo72cj=X1>DPy9hJeS9p7hne8jQJ;luS72e)288$QCUR+&4rPn;CB}t}ou+w|3Wyw-+}v-d;P?RxR{;%3I%i|dQG7k9mQd%xz|%y@fIt@lB^Jw;#dgLr$2TKfub@2{+x?JK-J zMPK_0Z%;9^eTBF8S6pBF3U5zwz3#8@_7pSQS9p7h>$R`&_I@d6X8Q_nPcgH7g}0}e z*}lTtTPkL@ukiL1Guu~qdy1LuE4;lWWM=ycZ%;9^eTBEDnAyI<+f&SJU*YZj+R)7Q z72cj=X8Q_nPcgH7g}1l%%xqub?I~uqukiL1Guu~qduwttgKv zzQWs6^tG?>_7pSQS9p8Bbk*0s!rN0^uYHBLr+f&SJU*YX3X11^J_I`1_neq1G`r_@y)#B~N z&5XAf*B5Uus`}*ST#r4J8i|dQG7uOeW?^w-d#@mZ(`3i4O(U-6A_7t^z zg}3(+!OVPxx2NdKS9p7hnfVHD?<0l2e1*5CxL&@(+f&TUSN(2$bMh75-p3Jr`6`aJ zKjo`FDazIIRqyZ=-z&cAYp3uP-d=8IzQWs6%*x2NdKS9p7h zzI=tZ_p!x;J+ zSBtk7H#6Q|TwlDs4|8hmE4)2r*Ne9oH#6Q|TwlDsxa-B+i<=p5FRHb#@b(ma?JK-J zMXh~>xA!5^%=Q)Do}#aPg}0}e*}lTt`_QSceTBEDxL*4TZ%;8ZU*YW?3Uj@Dg}0}e znXmBn6f^S`-kxG+zQWu4m}_SH3U5y_vwelPrx;J+)!J8hd&;gCZ!d0UyuG--czbwY*Ne9oH#6Q|RBK=1?J4@& zS9p6+L9Km-x2KrdzQWs6^tG?>_7pSQS9p8J0QI%6oNrHYz4n#!?I~uqubgiWW4K=X z3U5y_vwelPr$Z||6=ne8jQJw;#p3U5y_vwelPhpF_nukiL1*K1$l?I~uqukiL1*K1$l?SU>c z+gBY^-nH-*-d?URU*YW?LDiS9@b(ma`Km*udj-D2+sj=qU*YZHG}p^lczcSzeAN-a zy@Gv(x0jpQzQWr>ab~u!I#RZ;=PSIu+{}E1w|7X^%zTBnrd*jPt@lCa+xr@|eC2$5$9Ok0-d@y~ zubgjB(U-6K1*)&qm#_Nug?cwXU*YZL`tlXto}w>bg$wufd=zP&$ny?o_-dy4DjtKiP6_zG_?H#1-1?I~vFE4)3Rt1n;mv3#$)VGJaWnS;LtJe){fqWhH{x=&eAR6(MXi0+O(aFF`>Srz zrntZAwn?t9_rY#TDEjhMZ}}8``KmY6DfU%wa&mp`tKLE=`r215=qY^F(v<7VSFI$9 zzI@eRc#6J!)nBS9e3kX(`tp_Y?ft2~eC2$5ioSg1e0x}3Enhj`o}w>bIp3b5FJC#| zo@{2ma=tyq%=VS@?I~vVKInXVFJorDa=tyq%zWj1dy1L)%K7#bGxL@6?SX$Y^Of`M zDQ4y?=i5`v%vX4OgKuWMy|})3dvUdRdvP=4?Zx$VzP+f{zQWs6cD;CeaWmuX#r4J8 z`*p;w7jG|aX6M_BYWd3f_7r{j%K7%bscQMk`Suhu+gHxFr|4^6Ip3aQX1;R1y&sFd zeC2$5itFVo=i5`v%va90_iGc^%U8~~rS2gU+|7 znA!c6^X(~Swy&IT&p2jwf8~68ika;z=i5`vY+pIw-Y<5{Y+pIwo?>SE%K7#bGuv0r zw`WW<+gHxFr zdhzz+X2#o#>x;J+cfELfe|0u9-dX11@KZ|~P)`r22{x2L#X`^x$D6f@gb&bOzyUi-@V_Wq)q+5MIC?I~uqubgjB zF|&Q;e0z(*%=VS@?I~uqubgjBF|&Q;e0#sRGqZi=e0z$S?JMWoQ_O5%Ip3aQX8X$d z_EwRZ?JMWoQ_O5%Ip3aQX8X$d_Ewjf?JMWoQ_O5%Ip3aQX8X$d_I|avneq1G`r_@y z)#B~N&5XAf*B5VZL8`T{oNrIr_2TWt&5XAf*B5Uu?t1a|;%3I%i)!sF=i5{CwXd9S zPf=@MIp5wdLd|SnIp3b5uYKiwdy1LuE9cu=xu6FyXTx;J+*B5W^ z_`_z#+ly-X3U5!*m#^^l6t#SXw|6UNX1>DPQ}pF4ygkLte1*4n>!&YY;q57|m#^^l z6f^S`-k#!m`3i6E=F!Z2g}0}enXfvjv8&^&e)GAUukiMAwS3hlb$_asue#HuxL&^M zXElYd@b+>u^A+BnVrIU=+f(%AE4;niTYdQoZ%@&eukiL1efbJ+?{?VtnXmBn6f^S` z-kxG+zQWtPecsG?dvSg7_Tp;s_Tpy7+l%Xqw|CR6*1p2qQ+B<0dvP=4?Zx%Q+l#wi zyuG-Y@%Exx`wDMQ(bvAh+f&rqS9p6j`)0PU@b(ma?JK-J#mx2<-rk1;eeEl}J;n9f zS9p7hne8jQy~8`M*S^BrQ_O5%;q57A<}18C#msz#xA$?x%zTBnrSE3UBWN)@H`ri|dQG7gvk77dJEBUR+W^~Kx! z7`N-i+l!kSZ!fB~ukiL1eeEl}y$^qC?JK-J#mx2<-kzebeTBEDnAyI<+dHnMuYHBL zr?_7G3U5y_vwelP_i@wp+E;jcika;zygkLt_7&dV$5S(VAH>^J%xqub?I~uqukiL1 zGuu~qdk4zQY+vE+DQ32>@b(ll+gEsdABfFtU*YX3X11^J_7pSQS9p6Lpv`Pw;q57A zwy*H^6f@gbczeob#@mbQi?@b(ll+gEsd2L{b-U*YX3X11^J_7pSQ zSI)NwJj`rgIp3aQX8X$d_7pSQS9p7hne8jQJ!E2L`wDMQF|&Pzx2KrdzQWr((r9M; z3U5y_vwelPr+LJNz1;QMS9p6zR$Z@sg}0};Ui+#;hkFIS!rRNu z%vX4O_|43Gg}0~Z%U2x{+bi%D-d?_$@%G|sJKiL&Z%2;A_3aptxS2beBdX;qyuAaq zYWWIpPf=@M;q57E`3i3j5bA4RIp3b5FJC#|o}w>bIo}>o-1iD^FY4=k(DP(c^z}aI zc`_;bdLP8wJN&D!_d(B-NzvE)V85K(>+_ZK?d7hQukiLjroMdTe0z$%eC2$5ioSf+ zuPFAKe1*4{`#$p(-kzc_UxmDVy}o=EP@ck9L0-9;`6`4;@x9`!0Ob_E3L47I%vT{f zikbN;;6>4wufj=F_$tIB*O#vXC=`A9Dm+11-;ja0zI}`rSKCKxakYKi71y_qprTs7 z>I2>szQWtf)$$eIo}!ko@b<8=zI@f~_+G)j!rROBwXg8@6n*WhZtwQ>_EooEax>dk zczb_pX8Q_nPcgH7)tm9E_{#bAax?Rl^X(~Sc7Nr3dth5%_g5{@y#img&g5q1E4;lw zH8WrJ7jj?2S9p85nfVHDPcbuJ;q57A<}18Cpsp`p;q58<@)h1*(3h|9_5|1KeGqR? zF|&Pzx2L#X`wDOGfV`Rc3U5y_GhgBDDQ4y?ygg+zDPQ(P}!;qCo{12gj#-kxG+zQWs6%*dy1LuE4;nGpsv@x!rN2KY+vE+DQ5P0 z5N}U0vwelP_gCD^_7&cqVrKgaZ%;9^eTBF8PhQMyU*YX3X11^J_7pSQS9p6X#LV^; z-kxG+`wDMQF|&Pzx2KrdzQWsELT0wF@b(ll+gEsdikY{sT37WgHgmDsVttFvT&%WO z-(oWtt1YUXuUd6#x39|8ZeNwF-M%VUyM0xzcKfOYsdoFSTxu6Dj^ zt*V``%GGXPm8+ev%GJ(SI^+d{wS? zzA9I{eO0b@zH0HSov+H(ZeNwFov+H(&R6AXx37A;P&;3htDUdP)ox#vtDUdP)y`MF z$*A4FDpxySm8+ev%GGXPm8+evdTUZUUzMxfzA9HcUzMw!ugX`8w-;B7w-;B7w-;B7 zw-;B7w-?p&72e*P;rin3#r4J8i|dQG7uOeW?`?B4DPdyCeWukiL1*UMLUdy1L)3U5zwy?lkY_a<*!$hU*YX3X11^J_7pSQS9p6j!kZayFRm}% zUR*8SUfj%hdvSg7_M%$*3U5!@_2TWt&5XAf*B5W^pOfx-@%G|o#@mZ(?JK-JMPK_0 zZ|^2ut$l^Jr zdy1LuE4)3$%=Q)D-p2?t+gEsdika;zygkLt_7&cqVrKgaZ|{SMne8jQJ;luS72cj= zX8Q_n?;qxx+4~^go?>SE3U5y_vwelP_d&<;q57Awy*H^ z6f@gbczcSO?JK;!kG5vEukiL1Guu~qdy1LuE4;mr!e+Lw@b(ll+gEsdika;zyuE)K zzM1j%;`-w4#ns~N#m$Vj7uOeW?*q45`wDMQ+4bV>#m$Vj7uOeWFYbEr_Tpy7+ly-L zE4)2LU;7GgPf=@M;qCoHb~D>oczcSz_7&cqVrKgaZx0OUYhU5*DX!PP!rN2KY+vE+ zfdtoUU*YX3X11^J_7pSQS9p7hne8jQy?<(NX8Q_nPcgH7g}0}e*}ihVJ#=Aa`^xiV zQp{{$;q57Awy*H^P=}fAE4)3$%=Q)Do?>SE3U5y_vwelP_b>o6+gEsdika;zygkLt z_7&b9T-nTcdvSg7_Tp;s_Tpy7+l%Y#e0x!?edT#FDZ5_0y||h2_Tu__o=lG@*!AM= z#m$Vj7uDKVczcSz_7&b9_)%+L;q57Awy*H^6n*V0ygkLt_7&b9I?~s^!rN0^uYHBL zrg3 zg|`R!^yMqOJw;!>a=tx9U%qm_Jt$~qzQWs6%*nELWnzarY#^A+A+?t1wO zZ|`9qu9vUy_7vC4S9p7hzI=tZr|8R9!RU42E4;m2U%tZIQ}pF4ygjh0FJFZY_X_rv z=gE}&UfEZkCzIlPWnYD&`ud=fxY|IExW2&`aWe-*#MK5V7Wpc0AXm#*eJrP_L&EDEjhM9{{F!AMB=FuCMpOZh0wY_CDARe1*67 zr~2|0-W~|om#^^l6t#SnarZiWm6_!F@>M^oDSU;um#gI~ygkLte1*3c%*&4rP>x;J+SBtk7H#6Q|TwlDssMfy1+f(+v!rP0R8E-GH zFW%mmyI#D#xS8?xqFTPf+f(%AE4;m5CaC2rygkLt_7&cqqOX00x2KqyukiN1J^Jz$ z-k#!m`3i4OF*9G`?R`64FJIy9DQ4y?ygkLte1*67>kc#X72cj=X8Q_nPcbuJ;q57A z<}19tAE24}3U5y_GhgBDDQ4y?yuBZ|ne8jQJ;luS72cj=X8Q_n?-w#=wy*H^6f=7t z#M@KM?0pb#Pif|CRc*1p#bz#6TdZ%fnTypH>sxH*qT21NEU9+BDpxySm8+ev%GJ(S zAs$A`SmHpLjUzMw!ugcZVSLJHAugcZVSN)|?J71Nn z-M%VUJ71Nnov+H(ZeR6RP3?SDu6DjESG)JYa<%hSx!U=vzo2TjugcZVSLJHwt8%s5 zSLJHwtNvQ6ov+H(ZeNwFov+H(&R6AXx35|TYUitRwewZE+U=`ywewZE+WD##qIUbL zTxzFNG!xLUluxLUluxLUluxLUlusFttr_LkQA;_b!t#oLSPi?6U*YX3`tlXto?>Rc!rNP=`tlXtp5l7> z3U5y_GhgBDDXy2V@b;FmnfVHDPcbuJ;q57A<}19t*cEm^!}8uVmxxSeAV3(#msz_N2c)A!&i8F zidw$H+f&r?72e+4(Q5Jb;`-w4#ns~N#a%DnUR+@b(ll+gEsdA3@A)U*YX3X11^J_7pSQS9p6z zgv@MT;q57Awy*H^6f@gbczYjlHZ$H{TwlDsxLUluxS8?x;`-w4eK1mMU*YX3yI#D# zxS8?x;`-w4#a%DnUfj%hdr_@@g}0~ZYhU5*DQfL2yuA-(X11^J_7r{XE4)3$%=Q)D z-Um2+?JK-J#r4`(czcSO?JK;!16HorzQWs6%xqub?I~uqukiL1Guu~qdmkCiY+vE+ zDQ32>@b(ll+gEsdA2H2rU*YX3X11^J_7pSQS9p6zz|3r4;q57Awy*H^6f@gbczcSO z?JK;!54C2tukiL1Guu~qdy1LuE4;lA!J8RxFRm}%UR*8SUfj%hdvSg7_M%$*3U5!@ z_2TWt&5XAf*B5W^qxP;BZ!d0UyuGN_zQWs6^tG?>_CBDiwXg8@6f@gbczcSz_7&cq zVrKgaZ|_K*zV;Q~p5l7#E4)3$%=Q)D9ujc9_7&cqVrKgaZ%;9^eTBD&5X@{};q57A zwy*H^6f@gbczcSO?JK;!Lw{zruRKpC#mx4V=gFj)*}ihVJ!oNO`^xiVQp{{$d7ey) zne8jjlL>N|*}ihVJ;luSmGkW>X11@KZ%^6Gczbbuoo_F$*7^40W_G^4xW3M}7uDKV zczbYV*Xw+HaWmuX#r4J8i@RRu+ru!M8E-GDwXg8@6n*V0ygfy&eTBDoWYWy`72ckr zuYHBLrSE3U5y_vwelPckI;6_7&cqVrKiw`Suhu+gHxFhs`!K-d`tnuBboP~e zg}0Zh%JbVpk7nj8ygkLteAO=zcSZIU-d?V+eTBD&E%mjp@b(ma?JK-JMPK`>U#sjj z`3i3@cfEY&e0z$%eC2$5ioSdm{@yF_Rd`x%X1>DP`%~X%zQWs6);Gi{ZsxF~xY|&l zxW3^zaWjX^M74Yskeb3*czd~8z6!zkQ?>RL-X6Zym#@MH`x?H&+spOkE4)2LU%u+& z=)Rt>`nV`JGhgBD{i(iug}0}enXmfruqwWCzP;SceC2$5ikbP!`St*_zI@fK-d@4J z!rRNuY+vE+DQ32>x^>vs^Hp!{ax?Q4-rk>@*}lTtQ_O5%wdhyHSI)PWo0+eiZ%;8Z zUpe0%0@v63V1GIH3VemPmz$Zd@b(ll^Ho3WeLY|G1CX1Uuev;nnfa<>%HL1)Dqk%= z;t{X-65ryl_z}ON+I&@QzFJhX7S-mfKAUoBUgua>LLSLOL?QEk3j zt~OsSSKGc?t~Otl=c`4v`D(e^e6?I{zFMxfeYIR|zADdGi)woxT&^}>EmxbbmaA=F zmFKHPwfSnf+U~EGtIb!-)#j_^YV%cjzFJh<{nc`{`D(e^e6?I{`zjvFSL5x=S3BOm zxZ3gd#nq0tFRpgHy~tPN?aS5j)p+|9wR|<+K1D5Gjkl-p)p+}Iefesc1aF(U-6GJej_Rug2S#>&sW;?NjvStMT?J`tsGDCzHZg5H6`D*9eQ}}AUeYw7T)fpU$zI@ehYp3wlc>8jF`6@m{(U-5fQ>N(4SGg>uI&rn* z?Tf1&Z(m&B@%F{lj<*;2>hRTg`xLc&HQqi&EnkhdPf^QPSL5wd)biDM`xLc&HQt`WSBJ00+o!1I ztMT?JYVE7>_9<%lYP>y#uMS_0w@*>aSL5wd)biDMdkSCezn8jPU%uLZFLjE(e6{~x z>J)wXYX7~|6uug7U#>4-jkizHm#@a#Q}}AUeYw7THQqi&U%nb|pQ0~cjko6{z8Y^| zzP{t_i>n=PUtH~Y`{MeJw=b^m{(Gs5YWZrseTrJX8gHMXmaoR!Q}}AUeYw7THQqi& zU%nb|PvNWm_fnVZ%UApFrB2b8ulC zygh}l#@mK1D5Gjkixx%U9#=Q`GX+czX(8UA`J`pQ4tp z#@nZ;<*V`b6u!EAHQqi&EnkhdPf^QPu6oeQ`67 zw=b@CynS)C}z8Y^|t}kDWw@=ZRug2S_=*w5*?J0b<=gBPBm#_9bnJN16)t)Dl!dK(%%k|}} z@%AbD^3{0z6n*(>ygh}l#@m0(%hz|jeQ~wp?Tf1&Z(m&B@%AELjkhmX%U9#=Q`GX+c>5H!d^O&l!dK(% z%k|}}J->a5zI?Ukw@=ZRul78d6uug7U#>4-jkizHm#@a#Q}}AUeYw7THQqi&U%nb| zpQ0~cjkl-p)t)D_TwlK0`SvOL^3~3_PtljJcD_A@ug2S#>&sW;?NjvStMT>}z8Y^| zt}kDWw@=ZRug2S_=*w5*?J0b<^X<#^<*S`zynVU8d^O%a zMPI%eZ|`25ug2S#ukU#K;%dj+7gsypzPP^Q?M1#CZ(pvKug2S_sO78i_9<%lYP>y# zug2S#>&sW;?NjvStMT?J`tsFydkSBTw=dV1ug2S_=*w5*?J0b<^X<#^<*S`zynVU8d^O%aMPI%eZ=a$sUyZk?@YQ(xa(($~ynTwkd^O&l!dH8q z%yNDCYR{9IqAy?Vc`{S<<*OdiGKH_k+n4LhSL5wd^yRDZ_9^=E)p&afUyZjf*O#xx z+o$NuSL5w{y5pRFJJ9^`xJfoYUkUh=*w3--=4x(&sW; z?fX-G`D(m9Ucgr!4wkQP2X@8Pc8FG7Z3kP$_3g0fB43TSFIUS~8jF`D(m< zioSd`-abWNz8Y^&;j8iX<@)l~c>5H6`D(m} zz8Y^|t}kDWw@=ZRug2S_=*w5*?J0aU-o9L4z8Y_zqAy>Kw@=ZRug2R`_-g0dm+Q+{ zJKsJDQ`GVm-d>Tue1*5C z=*w4ldy2k%g|~Nz-pqW3x2KqyuO7a_+tbzZ72e)xYWWIpPf^QPczcTLb;q58<@)h3RH&S1|+WGdn z@D<)(t}kEV?S0Gj?^!I#rKM@@b(nnE55?p`|IL*`3i4OF*9G`?I~vFE4;nGUS{Si zygkLte1*5Cn3=Ee_I~|kX1>DPQ_Rd)JKx?WeXsELqFTPf+f#PEczbc*=bdj~TwlDsHM8r* z+l%`?DQ`GVm-rkz`^W`hNJ;nEmukiL1 z*UMLUdv6Q7Uc9}yzIc0awRn4R*Ne9o*B5W^m$z#93U5!@_X=+>Zf3l_xV}5zzPRrd z-d^0yczaPTU*YX3`tlXto}!ko@b=!s%*+WGdr-oC=y%gt&4rPYV9k$Jw;#p3UBWa!LAo?FRJA$ygkLte1*5C=*w4l zdpAU8=Bu4=@74GUZ!b49U*YX3X67rry_+e0`D)K^?-lq8Z!b49U*YW?b1*Ys;q58< z^3~3__X>Q4x0jolukiM6+04vWJKx^d^A+A+Zf3s1+f&TUS9p83duHaV{r6IP1-`=D z%gxMJczZX7X67rrJw;!>+WGcgfv@oPax?Q4-rh~+X2#o#tHs-ktHs-k>x;J+H#6Q| zRLfU8-#&daW!?{JEq`D&lv-k-)-czbI-^A+BnqG!Is+k4Pfm#=od zy+47k@b=bv<}19tM{+&$72ckrE?@0@dw&97;q9&U%vX4O$7l4+SNlAfzMrq~_SSml zE4)2L&wPcq_fkO5e6{oK{Rw=9x3|_aU*YY&XwWlX;q58v^3~3__b2cb-ricze1*4n zz-K++;;t8OFRt#+w-@;eZ*RTp#oLQ= z`3i4OQJ1gq_6{HIdhz!CvpUx5dcNA{$?U7@dcNA{$xKn#^A+B{e@10GU*YYohcxd-b+1o z`D*9e`+mN{+grO{zQWs6TrXeY?fY2sW%1R{w{NYk=c}D>pQ5hktDSF8;VZnowYq$@ z&y(3#)%AR}&y$(5x_EnWJ>%`g<>Kwd<>Kwd)y3P3ay?(+?HwFj&pY3~xSsL$;_Bk< z#ns*U_99>5?XBf{zS{ZreN|o0S3BQ6MXu+ooo`R^+>W=mR+q1KzI|U+m#=odeTuq# zg}3kH0;ls8-ria+U*YX3a`_5x-^ar(i?8tZ)_UeEygfzFe1*67QeMw|g}0~ZnXh)f zy+4z$@b=c~@)h1522hu;cD}vu=PSIuwd>_8ygkMB@)h15LU6r&we#)$34DdOx7IUX z;q4vn(=%V;?J4T=)y}u~C-4>C-dfLmg|`PP*7MG{FD`fI+ZUI+^X-ePyYuaf>ltq^ z%H^w_Z=WvLbNkM>Pm#-4JKvtdS9ts0NKcW=S9p86T)x8FQ{?g$-oCdzS|c_7pwy72du#GVMG0YUkUxmh1K4&bLp|v)6+=-=4x(czbJg z`D*9e_f>VxtDSG3qON(h^X(~og}1j>m#=odeP31AyxRHpDb)>Mm0PUmVs(q<7OPt< zw^(kmy2WyfayPF+UvlTG)^g{o)^g{o)^g{o)^g{ofSKI+sUj^(a za``F{HifT(Q`YM8Rp^JJXTHMQdttnvRj@-;m#;zz6m|Kk7wQys`Kp(}Q~0Wvsn+W9 z72e)g)#WR^eJ`2zoqW}c7HheD)k^}3x_s3GH$`2(>Tz}oU-h_Ytu9~T?R`~UzUm># z_o&NPJ$y{zs~!lf)#a;hx)gQ!s$1F=zUpRUtu9|R$|-v0s|F=SUA}7cq%=gt<@Og_ zTyB5a#MSLDfVkXDxyV-;#ab?3^=qTZ<*P26BA2iFBc_;F{hzhEe1*3stIJn-dy2Yz zg|~MoUM^qZ?J4T=72ckru6c#G2le%AUg7O2dN!}{_7pvvS9p6(>6x$a_7pwy72ckr zXTHMQQ}oPNczc(nXTHMQQ}oPNczcST`3i4u+d-3U5!*vw4NLr|6ll@b-T2dgd#pqCLr|8+d!rQZ`3i4Ok;_+jdx~7X!rS}H;d=QBZ%=W(e1*5CxL&@(+f!UGU*YZj^>V#@ zg}0};UcSQHQ(P}!;q7O3U5zwy?o_-dxO*U@|E-LDXy2V@b(nf%U5`NitFVoy#0)~7v-8) zczcRm^UC@56uIV=^X(06*UMMVx2L#XzQWs6TrXeY?G5-{FWz2UUA(=xT)e%w>&4rP ztBbc6^Jy?J08I2l4i9dV1z7ygkLwim&kY6xYjF zczZWVKP$e%+f!UGU*YX3u9vTzZ$IPhMY-;SczcRm_d&cpMXviG-rlX)&&queZ%=W( ze1*5CxL&?;zCFeD@|E-L-OODtUpe2N;(GZCZ%=W(e1*54@%G|!@%G|+#@mali?>UzF%zP-m8J$t@#zCA@3U5zwy?o_-dy4DjE9cwKczaQ<=XSh3MXu*|ygg;Pczba@Vj`3i4OalL$nx2NctukiL1*UMLUdv6BSGhgBD zDSGBBygfzFe1*67aII&)!rN2y%vX4Oik|t(`Su>h^~_h!x2NctukiL1J@Xabo}y>I z!rObhs-F1@Z%@%PU*YX3dgd#%^~x$c8_dy2a5gLr$2 zT=zk|y%#rnb{}-UJw;vjLFe03^z1(9e0y*9RoC+s-k#!mJzwqLORX!u!rNP`%U5`N zFQnAvE4)2LUB1HGQ`F@vyuBA*>hcxdo}w;a;q57YR($1rdk3TZocYT6_7p!WzQWs6 z^vqXydy1a<3UBYFo}T#%Z%@%PU*YX3dgd#n_LN;O-d*XuFJpkZ(`O5kB6xYjF&bOzyUcPd^{fxI4jN-1(}t-1#aHB6s(})^g{o)^g{o)^c|rY%O=b3ZKZGuUgC9eXzCM`Kqw;Ft>w;F zt>y0dDg?D$yuG+wyuG+wyuG+wyuG+wyghIwm#^^ll-0%Ci>r&b7grZ=FRIH|czYl1 zpe|oI-<~3uubgjBQJ1eeuDU;sukiNP>hhKI?J0WZs}4c>es%c@Zx6Gn%U5`Nin@G- zx2MSEE4)1{x1TfKUR0N_@b(mS`3i4OQJ1gq_K=>se1*5CsLNM)dy2Yzg|~+Q)#a-W zXRHUl!rNP`%U5`Nin@G-w}%ha<*PQ-_b2cb-rm~ph_CSWK%<{CU$r&6@8>JLy|teC z3U5!*GhgBDLCW>q_M5n#+Y%F(+cuTBx@{ea>ltq^$~CXrR-wz~t2Qtwa?Pu@2d3~9 z-ribWzKUb{s=9pD(>+C9zUptr6u#>Jt<~i#yuGig%U5`Nin@FiL|YbL1-7i!85|W#7qH;SX!Me1*67RdxBQm+QVqUB2qY@D#rCc`~il<*Qx<`l`Bo)r+es z=2b6vtkvbKUQST_toW*jb&9%t)uZqf^Qy;FYd!N7-riT$^XbNB9?XBhV72cjAm#?z* zzMrq~_SWk172ckrE??p8DeCf7P3%wLtG-~ZXTHMQ`>LM#3U5zQm#^^lK7K|nU*YX3 z>Y7)0dy2Z|72e(-?|S(PZ%=W(?t^%HitFVoyuEhx%va90r|6lloNrIjv-_a)?J0WZ zE9cw$fE+#ZmGkW>dgd$V+f($+SI)Qh1JE;H`8=5vJ)2iPPbNjr=9SNr=?A7~zQWs6 z^vqXydy1aj2l4il^^CU{R~K(DE*Ebvu4lZxxVm_IQ7&KM?fs&5y?A?ZJ>%`g)y3P3 zyI#D#U+H?r+lzAf3U5zQm#^^l6uEqbxA*Zvdgd#-3U5!*v-=?4-WxLXY+m8*DS9@q@b(lv zn^$;y2G_HBg}0~Z*}THrQ}k?J;q57UHm~sZ{)*_?ebD*#6g`_)&bO!N*}QVTy|;|$ z*}QVTJw?yvmGkW>dN!|oo=krQ*E8N;TwT1qxLmxwxSsL$;_Bk<{l%4QUimzklwB|0 zUR=+3dvSH~_TsJ=Z!fNAyuB#bebDF0q^RpY=<{S!L2K?D@+1_7ru^E9cu& z^lV-^-`;>x*Sx~pQ(Uikg}0~Z*}THrd&7M~AFJIy9DXy2V@b(nf%U5`N%B~l0FRm`$UR*BTUflKK?Zwr_+lzAf3U6;ibw4ZT z+l%WNZ!fMc-d^0#3UBXLu%7YuqFlbh+f&r#E4)2LE??p8-A44xS9p7hx_pJVr|6ll z@b+lHlp>+S3XZBMbCWYe0z$X`O5kB6g`_)&bN1K)w6l!e0z$X%`4~I zQ}k?JIp5x`SkLAa-kzdo^9pZI(X)Alx3^Wkp7HkL>f-Ii<>Kwd^^CU{R~K*ZhA-E= z!rN1Jy?A?ZJ>%`g)y3P3yI#D#xSsL$qFnO|Z%-3U5!* zvw4NLr|8+d!rMC>p=a|7Z%@&)d4;#9=-Ir&+k3cM&v<)rb@BG%a`E=!ddAy}tBbc6 z<(gM`d&;gCZ!fNAyuG-(czZ`ScD;CeaXsVhMY-k`-kzead4;$4;3?OsFV-{OUX*KI?ep8Gt7~5E^V_G$ zHLv#h?J0bPx3|_aU*YX3>hcxdo}y>I!rMDWq%L3K?J4T=72ckrE??p8y$tfR;w!v8 zMbCVNx2NctukiL>HtCtK@b(lv^A+BnqG!Is+f($+S9p5|o%GCCczcST`3i4O(KBD+ z?Y&UbGhgBDDSGBBygfzFe1*67!cNb8<$QaJp83l8_7pwymGkW>_1w$Ba*Ne1)^oAk zVs(r4Tr9U(-C{i#<<3{Vl$1MPwU#?ywU#?ywU#?ywU#?y^#WAxeAQa+eAQa+eAQa+ zeAQa+eAUZVxw{XxmOEdymOEdymb?34Yq|4PFLve5SFPplKG<6BeAQa+eAQa+?t{HV zmOEdymOEdymb?34Yq|4PYq|4PFRbP6KG<6BeAQa+eAQa+?t`u6&R4x0mpfmzmb?34 zYq|4PYq|4PYq`4*_99;HeAQa+eAQa+?t`u6&R4DF&R4zkm%IC5Yq|4PYq|4PYq`4* zwq7pYUR*BTUR*BTUR*BTUR*BTUX;sM&bJ2}Ru^wCt}fnQTwT1qxVm_ISYkcn?M1nK zg}0}u%U5`Nid??J+d~?9<}18CMP0ta+f($+SI)PGK-A?cygkMB@)h2mqG!Is+f!UG zU*YXR6g~4*Z-?Hs@D<+PT3x=v+rusD@)h2mqAp+I?J4T=72ckrE??p80ULGs3U5#G zv*N4XG`LRq3U3eXsLNM)dy2Yzg}0}u%U3>6CPiJoa=tw{q%L3K?J4T=72clWcf?nC zdoXFgBfP!1x_EnWxp;eVJ>%`g)y3P3a`_5xPub78Hw=jD+4=V3>f-Got6eYNUR=+e zL>A@pRj08i>he{4)KknWyuGzt^C}+ZtLmCpy(XZjYhLyDX$oKU|JLgARYyE2>he`b zCn@Uk72Y0Tlgn2f``h>M72e)jUA}U@y`!({@)h2mqAp)K-=3l_Uv&g(ehcxdo}w;a;q57|m#^^l4(hsIzQWs6{H*xO z`Suh&^A+A6Xk5>DdvSH~_TqB!_TqZR+l#B)HlZk&ukiNtU2hv>;(Es0i>r&bcYIi` z`yk$)qOSWO-ku`YeGqR?QJ1gq_JHWF*ZKCMy5?1=nyzQ_DiAz{uY$AIa?PvICq>WZ zRbY{#XY(p-H^qH0lxD4Gz6w-P)a9#?5Jg?S3bIUbAH>^RtLr|9x2LGfS9p7HS6#m9 zCGq|Q^9pZot*&{6x2LGB2gs!_G?;VZnowYq$Tx2LGfSJ`^s?>?B-to6)S&bRkfb^}Pf?ezoNw=2TrXew{Pq;r%U3>6CdKvgmCut2;p>^Ne4b2-p83k>$)xC+ zuY8_Nik|t(=gHKRp83k>$)xC+uY7)cik|t(=eKtedgd$V+f(%H`O5kB6g_*sa=yJy z20inY^X(~m_I%}hdy1YtUpe2NvYzqw;_Bk<#pUAd#r2H07grZ=FUsXB=iB>X?|Sj} z;(Es0i>r&b7k9mQd)pxE8E-Gjou>OZ%@&)dF6b2it9D6oNsT_M$hhp&bO!N*>k(|?J0Wp-0pmP zrqi=|<$QaJp3N)g+f(#xUOC^MN%d@A`TX`2J-ZM3Jed?dyAS$2nG`*nS9p8dN_uu5 z#M@K!Y+m8*DS9@q@b>;%=-Ir&+f(#xUg7O2dN!}{_Wl~JXS}_*x_EnWxp;eVJ>%`g z)y3P}?2>C<;q58AUc9}yp7HkL>f-IiT`%5VT+euWQLg(S-kzea`yk$)BG-3U5!*vw4NLx3RgN@%G~C;_b!d;_b!t zjJFq87jG}hHLvjYlwB|0UR=+3dvSH~_Qv_H7jG}FXS}^A*Sx~pQ`9xD@b)%c<(gM` zdy1aTE4)2LUGoZWPtmh^g|~MbQP;e}+f!Vxd4;#9=-Ir&+q>61h zE4)2L&*l~0o}y>-3U6=YTF>Sc-kzdo^9pZI(X)Alx2LRUyuG-(czbcVczba@+qFnO|Z%$zBNQSN-zBfs3utJZQiuUgC9ylO3X^QyJn&8uE0 z$lbhZEqA_ZEqA_ZEqC*(wcPotmlty9tJZQiuUgBUuUgBUuUgC9yy``X-1(}t-1(}t z+|8@ja_6hoa_6gF%E;ZkYAtuZYAtuZYAtv3s?CP1X@b(lv^A+BnqG!Is+k0`WXTHMQQ}oPNczcST`3i6E z#k8LJ3U5!*GhgBDDSGBBygfzFeC2$5FUR%FSI)Pm=$WsaZ%@%PUpe32%XdBVmGkW> zdgiM>sB6DRzQWsEuP)wRTrS>TT+euWadq+b;;t8OFUsXByggvBp7HkL>f-Ii)y3P3 z>ltqkE$nB7w-@E|mGkW>>hhKI?J08k3UBWipq}}vQ_1_&_^NY)*6Q+AXC)|l<}18C zq@gZf#l!YJ=2fpytzEBq)xCNOU-eV8mdjUodtX(TukiL1b@>W!@1UYwzQWs6)a5I@ zJw;uhcxdo}w;a;q5^hb@>W!Pf?ez@b(mS`3i6E5T&|& zg}0~pIrA0Xp5kZ4S9p8MepYyUadq+b;&So!;(Es0i>r&b7v=Jm^X^}Pf?ezoNrH&%U8~~hphC>S9p7hx_pJVr|6ll@b(aw zy5?1fo7V$h;q9%}pqCL zr>N^bh_|Px>pqCLhvL-bE4)2LUB2>pGAZivmCuvusI2SdE4)3$@0YLe_7uM(zQWs6 z^vqXyd+<-seC6|GQuNGMK2Ih^&wPcq2MgCT-d5N}UW*Srest|DLI?XA`2E4)2LUB1HGL#^tXS7EsQ z34G;zduu;uzH+`j#m|bb!aDnYz6!fo>zS|c_P(lTzQWs6^vqYi2w#?Yg}1lXvw4NL zr|8+d!rOzv>Y7)*WZIv=SI)P$)-zu@-=3mpzUmRY@9$w+Ty77z;_CL$DX!-p1jXg{ zaJI--Juq3z_1xa$2t_Vmb+f0)_1xaAbP8W}le1QrukiN1sxDvQ?J4T=RfBI?e1*5S zR+q2(3-7Dy@)h158dsOEvgy8uudJXQ;q57U<}19tU#Yr$g}0};UcSQHQ}oPNczYIbz2+6(o}y>-3U5!*vw4NLw?(68 z^9pZI(X;0(ygfzFp0Dus6g`_)czdSPv*#%`g)y3P3a?LBe zy}wMmUc9}yp7HkL>f-IiT`%6=HrIN_+lzAD2l4h4bj0g}3)tR?p@Y-kzea zd4;#9=-Ir&+xsi7u6c#Gr?_783U5!*v-=?4p5l7VE4;l;IX#%`g)y3P3%f;J^>ltq^t}fo* zW~N;83U5!@_2TWt^^CU{R~K(D?t1a|;(Es0i*n5?ygfx-^9pZIk!xPz?G1H3n^$;y zin`_%-kzdo^9pZo(^Xyb3U5zwz2+6(o}y>-3UBYG;d;$0ygfzF<`v$aqG$68Z%@&) zd4;!k+tIUmg}0~Z*}THrQ}k?J;q7e;>)E`*+f(#xUg7O2dN!}{_HJu>Hm~sZ6g`_) zczcST%`3b;MbG9H-rkK-&*l~0o}y>-3U5!*vw4NLw{g9m@%G~C;_b!d;_b!tjJFq8 z7jG}hHLvjYlwB|0UR=+3dvSH~_HNg^Uc9}yp7HjgT=NQVPf^#r!rR+amup_(?J0UT zukiL1bou?N_7pvvS9p7hp3N(~ zy={Lzn^$;yik{6YygfzF<`v$aqG$68Z|^}y&*l~0o}y>-3U5!*vw4NL_u!*v^9pZI z(X)Alx2NdYyu#Z%n4o9#3U5!*vw4NLr|8+d!rN2oxyP$=i`6aGbFtiFb&K^}EVo$Q zVm%k-ZeI0hCU?GSEqA_ZEqA_ZEqA_ZEqA`^fllsx)mrX+)mrZ6RcpEPRcpEPRgZyk zH?LaDov&KUov&KU-MnfocfRW3QSN-zTJGjmYq|4PYq|4PYq^_OJ#xyOuUgBUuUgC9 zylO3XzG^LZzUo0$?&ei%x${+Px${+Pxtmw5<<3_<-pZY?TFc$MYAtuZYAtuZYAtv3 zs)u5^^HpoP^HpoPn^&#n&R4DF&R0E3%iX+cEqA_ZEqA_ZEqC*(^>Xp{;&So!;&So! z;&So!;&So!qFlbh+k1FlUA(=xx_EnWb@BG%>f-Gkt69%@dr>Z5;q58v@)h2mBA2i5 z_Ff|BnXmBn6m|IuZ%@%PU*YY&q)?Zy@b(nf%U5`Nik|rjZ%=W(e1*67qD0Spg}0~Z znXmBn6g~45-rkECJ@Xabo}y>I!rN2y%vX4OFM9OMS9p7hp7{!IPth}9;q57U<}19t zmrZ)+E4)2L&wPcqr|6ll@b+G2>6x$a_7pwy72ckrXTHMQds()g@%G~C;_b!d;_b!t zjJFq87jN&yoLut?Z%^6v;_b!tjJFq87jG}_dhzz+ddAy}a?LBeJw;vf3U5!5YhK~) zy@=Gad4;#9sB2z1-=3mp^UC@5UUaH!UUkNHJ@6IY-dbJ0>db|&s>@e+dk4hS<*T^P zzK5@RU2E-n`Kmko6!WUTN!D`BE4;n0>e;-)+f&pvukiL>7RxoS@b(mS%`4~IQ`9xD zoNw>gn%|Lm<$QaJ>ou>OZ%@&)dF6b2ik{6Y=i7TBu4nVg`Suh&n^(@ar|8+d!rOb{ zzMk>+;_Bk<#pUAd#r2H07gyK$_M%+#3U5!@_2TWt^^CU{R~K&&5A1sJ_TqYWzP%{d zymG!hMP2jC`SzfKT=UBL_7pvvS3XZBMP2jC=gFk#*}QVTy<>pt@)h2m;(GZCZ%@&) zd4;!!F za=txXUGvKM_7u71mGkW#^OS2|;q58vnpb#xik{6Yygf{%u6c#Gr?_783U5!*vw4NL zr?_783U3c|>Dj!(+f(#xUg7O2dN!}{_70-z*?kaiPtmh^<$QaJp3N)g+XHEOHm~sZ z6g`_)czcST%`3b;MbG9H-X4n6vw4NLr|8+d!rN2yY+m8*9hKFyd4;#9=-Iq-zCA_H z=9Tm9p}zHuw-;9zZ!azvZ!fNAyuG-(czb|Qu6fmggX!*rczf&h?0kE1b)9c7?t1a| z;(Es0i~CtQ-(Hl+l6g~4*+g-k2UA}5FX^MG;x3_k^ z=2e?0zN)Ty)fUARzQWsEyI#I>zCA_HeC2$5in@FiO5UHqSD{{OJ@Xab-dEM-E4)2L zUA_wZEz7*Z+gt0|yu#a4^lV`&k;=i6KBnXjC0Pth}9^|F88&sV)H zx7IUX;q84@&wPcqr>y5*+KKDAms{d;dkG}2ZZAv3_1sGZQ7&KgAU=h!@b=bn`3i4O zk!xPz?ICA%`KrgJ{Rw=9x3^Z8ukiL1b@{5>@V=j~x=mW^nXmBnzN%-w!rN2y%vTM~ zW$~5s?XC69SI)Pm=$WsaZx4#A>pqzE_b2cb-ricze1*5C=$Wtj!R`C`s*ADKGhg+s z6g~45-ro1?nXmBn4!_GaukiL1x#kt#o}#XKg}3*Ixn91)+f!UGU*YX3u9vUy_KNG7 zukiL1J@Xabo}y>I!rN2UGu~cYUA(=xT)e%wp7HkL>f-H1xqOAUchS3EyuG-d@%G~C z;_byI!rN2y z>^_LMXBIu1S9p7hp3N(~Jw?yv72ckrXY&eg&u)4)ukiL1J)2i}dy1aTE4;n8U+CGq z!rN2y>^_LMr|8*z5O2@U>ltq^t}fnQTrS>TT+euWadq+b{u0PFukiMiT`%5VT+euW zadq+b;;t8OFRo|2y(rgnJKmn6uKOU~o+8)0!rS}Hr)T#;ygfx-^9pZI(X)AlxA&J- zUGoZWPjS8G72ckrXY&eg@69W&*Sx~pQ}pb)9dA$3v*&iaJw?yv72e)>(6i@uygfzF z?t^%Hik{6YyuERvXY&egPtmh^g}0~Z*}THrdwY$Z%`3b;MbG9H-kzdo^9pZI(X)Al zw>QA_Y+m8*DS9@q@b(lvn^$;y18+U!?Zwr_+l$M^+l%WNZ!fMc-d>bzUg7O2yI#D# zxSsL$;_BkZ9I@<2Fop0w^+}`a*Ne1)^oAkVs(r4T$Hw;Ft>w;Ft>tcB zwU#?yb(5DnU$vIIdDU9(eAQa+eAQa+=2edda_6hoa_6hoayPG9%bl-U%bl-!ppd(H z)mrX+)mrX+)mrZ6RcpEPRgWQZ=d0FoH?LaDov&KUov&KU-Ms4IMecmnTJC(+TJGjm zYq|4PYq|4Pk34cWuUgBUuUgBUuUgC9ylTB%yuG+wyuG+wyuG+wyuG+wyuB!wukiLB zvQ`&wFRm`$UR+(gy|}t~dyix58E-Gj*XuFy@y9V^A+BnqG!Is+f($+S9p65n|kIe zygfzFe1*5C=$WtZ_8w04%vX4Oik|rjZ%@%PU*YX3dgd#f-G^bjvlb@b;8l zFWz2U&v<)rb@BG%t`~1Fu4lZxDA&Bg+f&pvukiL1x#kt#-kVwVY+m8*De9V6czcST z%`3dU7YFK^S9p7h>ou?N_7pvvSI)QhV#4*BS9p7hp3N(~Jw?yvRVOueb$o@l_eNWF z`6?2;ukux|=B?%ORZpE1*UMM^Eu3Or;q9&UY+m8*DS9@q@b+Hr=-Ir&+f&pvukiL1 zb72ckrXY&egPtmh^g}3(tYdz!b#nr{zi_68^i|ZM0FRm`$ zUX*KI;q58AUc9}yp7HkL>f-IaO?lUgw-?tl-d>bzUg7O2>Y7)0doTXvnpb#xik{6Y zygfx-^9pZI(X)AlxA*cE4)2L&wPcqr|6ll@b(lv^A+CS3tT;$S9p7hp3N(~Jw?yv72e((zV&Qg;q57U zHm~sZ6g`_)czZ9P^=w|@?J0UTukiL1J)2i}d&+vo+l#AZ%@&)d4;$4c6oKpE4)3$^_o|Bdy1aTE4)3$^_o|Bdq6_Z<`v$aqG$68Z%@&) zd4;zJF!XF*;q57UHm~sZ6g`_)czbW?*Ry$rx2NdYyu#a4^lVJXQIp3Zl*Sx~p`+x*J zn^(@ar>JXQ`8=5vJ)2j~w+EcmHLvjY6xVBB;q57UHm~sZ0F~=CukiL1J)2i}dy1aT zE4)2L&*l~0-bXm-*}QVTJw?yvmGkW>dN!{*p1YqCU*YYo)#WRnCzGNsU->+l6m|Kk z!<73I_zG`t?Rxpj`Sujo%U8~~_rVhC@)h2mqAp+I?J4T=72ck*x_EnWb@BG%a`E=! zt`~1Ft}fnQl*?Cmd%$l$E4;n9o}F(mt}fnQ+|LSc@1rl)bB7y5xqOAUr>o0XczcRm zzQWtXigNj?P38SL<`v%FT3z!BZ%@&)d4;!!B-J&q@b(mS%`3b;MP2g>Z|@^I)HSd0 z_7vA^UOC^M;%8-EIo}@gbiL*k-kzdo^9pZI(X)Alx2NctuL8=uM)yIVC(~M8_d%a0 zlcKKspwE-(<3rTttMK3c1oH}SZ|!=`E4)3$^_o}VqM(UJ>Kp6`Kre+Yd!Oo&y(q^dgd#iCzGOQzUpSYEWX0qTkDyx@b(lv z^A+A6*jAUX8lC$S%qzUTwVutZhJ~-{*}Uqn;uOB>FNw9D`O4?X^i@6cRli{0qi4SI zc`|)qj9l}|=gFj~YhL+0nSxyN%IC=>xL&^Uc`_-km#=)DOp2cQ%IC=h?Dfo7K2Ih^ z&wS+le&KpHuY8_Nik{6YpC^-|XYr&b7nh5-7uPf1 zUR+(gy^SNe=9SNrN!j({?Zx$sw-;9zZ!hk8@%G|+#@mZ>Jzx1enG|(BU->+l6uIV= z&y(pdke=NKeV$B;y5^P7lS$FDdFAtD+Tc>xyz+T6DX!PN@_8~TdN!|oo=ks1U9WlN z^JG%=>^|u8WK#5OUimzk6g`_)K2N5<;(B%;^m#HVdN!|oo=l3K-3NW1Oj~ezHm`i1 zOp2b(E1xHmqG$8U=gBle^lV=FJed?dn^!(hCPmNYmCut&(X)Bw^JE%AdN!|oo=l3K z%`2ZLlcML%tHxDzi}hSAw^-d`Jr~O@R<~Hs#d3>s=c`7Y+|8@jayPG9%iX+cEqC*( zwcO3C2Bh50tJZSotJZSotJZQiuUgBUuNtdz=d0FoH?LaDov&KUov&KU-MnfT%bl-U z%bl-U%iX+cEqA_ZEqA_Zgv;H$YAtuZYAtuZYAtv3siSS9p83Ts`v@-kzc^U*YX3dgd#*XuFy_>wA`3i4O(KBD+?J0WZE4;mj0zLB;-kzdozQWs6^vqXy zdk+zM<}18CMbCVNx2NctukiL1J@Xab-eZWK`3i4O(KBD+?J0WZE4;nO7CrM7-kzdo zzQWs6^vqXydyhHm8E-GHF5X^TF5X^T&v<)rb@BEdj^vtGczepO7jG}FXS}_*x_EnW z*Ne9o*E8N;lxtq$?J4S-S9p7hT=NQV?+}EZ%`3b;MP2g>Z%@&)d4;$45T~wrg}0}; zUh@iXPtmh^g}3+6=X%X6ygfzF<`v$aqG$68Z%@&)d4;!kOheD+72ckrXY;DlL;IQV zRlD(9^A+CSS}tG3|9n+0U-im>;(Gb2`7y=3>i@0vY+m8*eO1rq72ckru6c#GcaTJ` zd4;#9sB2!~?J4S-S9p65!uvVn?Zwr_+l$M^+l%WNZ!fMc-d>bzUg7O2yI#D#xSsL$ z;_Bk<9dFt7;_b!tjJFr%npb#xin`_%-rhsHT=NQVPtmh^g}0}uYhK~)DS9@q@b(__ z)itm1_7vA^Ug7O2dN!}{_KxAWUh@iXPtmh^g}0~Z*}THrdl{i;^9pZI(X)Alx2Nct zukiL1J@Xab-U|^u^A+BnqG!Is+f($+S9p5|h4joZ%@&)d4;!k%t~GJ z3U5zwz2+6(o}y>-3U5zwz2+6(-U~-Pn^$;yik{6YygfzF<`v%F3r#(nS9p7hp3N(~ zJw?yv72e)KFg?2u;_WGVHm~sZ6g`_)czcST%`3dUm$rI#AH>^J^lV z3hUXt!rN2yY+m8*DS9@q@b-?Xt!KQwxVm_Iak+SVaXsVh#nr{zd%-Q&yu#a4cD;Ce zaXsVh#nr{zi@RRDy||w7_M%+#3U5zQ*Sx~pQ{APOMy||w7_TuW|?H!qv%U8~~r>M(UczcRmzQWs6)a5I@JqWbx#oLSO@)h2mqG!Is z+rvfb@)h2mqAp+I?J4T=72ckrE??p89q?3_ukiL1KP$e%+f!UGU*YWmDnBc}!rN2y z%vX4Oik|rjZx3kcnXmBn6g~5m^X(~m<}2shQ}oPN9n#%T$-KhbTdQkcIp3b5u6gBr zd+r&b7v=I5-rgbE{haak z;(B(zy|}t~dvQN!ygj_Po;x%n%H=D(JzZVC!rN2i@)h158kEad9ah+%!&i8FYjybw zZ%@%PU*YW?<5ich@b(mS`3i4OQJ1gq_AsQne1*5CxL&^U`RyrwR(#cl*?Kdt@b=c~ znpe)Zr>JXQIp3b5u6fla$NmJq!rNQBUcSQHQ(P}!;q58v@>MW;e*$0O?XC69S9p7h zp7{!I53H)oSE0lG34G;zduu)OmGkW>dgiN8RNo&|5|*ue#w;)a9#gClq!0 zs$o5auNtP->hcxd-dEM-tN!xud-$rqkk;z*mGkX=Rb9TyOuk25zUo&sg|G1T*6Q*V z-kzdozQWrJ>hcxdo}eyY;q58v@)h2mqAp+I?E(AsjJFq87jG{v7jG}FXS}_*x_En0 zu6c#Gr|f5iw-?tl-d%^~xqOAUr>JXQ;q7fE$mJ`%Jw?yv72ckr zu6c#Gr|6ll@b-Q@>hcxdp5l7>3U5!*GhgBD{Wx7OU*YX3dgd#>LA*Vsp0icC#p)L8xma$oy2W}fmRqcDv7U=^H?Oj! z-1(}t-1(}t-1(}t-1(}t-1#aa%bl-U%bl-U%iVpjwcPotwcPnC`^(+DYAtuZYAtuZ zYAtv3sI!rL3( zdgd#kXeAPJ-in@G-x3_h#E?>nC_dR^o zD@AM9%U3;>Ofj$e+ixw`yu#c2s=DSC-kzead4;$4z_MJty||w7_TqB!_TuW|?Zwr_ z+lz9|E4)2rJ>%`g^^CU{R~K*Zv1q>|yuG-d@%Exz^9pZIQP;e}+k2RjYhK~)DS9@q z@b(mS%`3b;MbG9H-rn&CbJXQ;q57M%`3dU<1KnNukiL1 zb-3UBWvh@Q-%K7$?fa^7{oNrIj zvw7uwdy1aTE9cuo2zoZJoNrIjvw7uwdy1aTE9cu&^lV-^-`=4=J)2j~x2NdYymG!h zMbGAy^X)+kJ)2i}dy1aTE4)2L&*l~09^}xod4;#9=-Ir&+f(#xUg7O2>ltq^t}fnQ zTrS>TT+euWadq+bqFnO|Zx62Qdhzz+ddAy}tBbc6cfELf7-l`=?M1of72ckru6c#G zr^q$0@b->O>e;-)+f&pvukiL1J)2i}d&oy!^9pZIalPgh-kzdo^9pZIalPgh-X1j4 zvw4NLr|8+d!rN2yY+m8*9qQDxdDR;^_7mVMyuG!$e1*5CsLNM)dw@z^zH+`jMP0sf zzCA@hhJ(lSxsRuR7qnKf%1h+gtlNn^(@ar}#OWSI)PG z%~lt0FRo|2y|`Swy|}t~dvQJE?ZGy==2Zvprn?W~?X7pc&bJp=*ZKD1ddAy}>ltq^ z?s}bXFUsXB=i5`%<*SbA>^u1iZ*MJ^uY8_Nik|t(=gFj~%U5`NXi(35g}0}u%U5`N zin@G-w|8_`&wS)E`*+f(#xUg7O2dN!}{_TZ?V`6@iUpSgL3x3^Z; zyu#a4)HSa{oPB?=Qe18TQC!`ip1A7`w28|Nel7ALFl?dDV^CT3ydq-S#NzdcNwW zGKH@i^w#R~Rb!N*E??p8eZRVV)d<-4@Kt{~t<~i#=iB?Lx_sq)dy2Yz<$QY(T`pfa z-=3l_Upe2NqHey5GUThpLp+O@;wR#j_^J4r__-)IUzMA$7Ukxvt>reaww9Z(ww9Z( zTIZ`px%p~qx%p~qxy`Gsxyct>xyct>tzfY@M$b<>srcyC7c>5H&d^O%a zMJ`{Bx2N#cc>C7s^3{0z6m|J(ynTwgd^O&l!dK(%TdT`gfo#K_9=4tYP@}lT)rA_ zPvNVBug2S_$mOf?_9=4tYP@}lT)rA_PvNVBug2S_$mOf?_9=4tYP>y#uMWN%Z=WKU zug2S_$mOf?_DCpSjkj;Tp2yo4mpk6RxZLsf#nl~eFY?v?z0|Gc^3{0z6uEpg-abVx zUyZk?@YQ(x*6Q-rc>5G}`D(mhjfi`xJHgYP@}lx_mX>p2An1__kJ;ug2T=RdxAlygh}l#@n}6 zm#^ZE6m|Kk=X#2|eAVzynSnR`D*`O>J)YPYX4s96m|J(|6XbeUyZkKtu9}Uw@*=*ug2R`_-ed; zYjyc*ynTwgd^O%aMP0rcZ%^T?OTHR!pCXs9#@naJ<*V`b6u#QOm%6pOe6@csb&9%t zwSO;lin@HYe=jwKug2TAR+q2F+o!0@SL5wd)a9%3_7uJvZ{J#7z8Y_zqAp*Jx2N#c z{=L+#)#a=Gd#O{@<*WUBsZ-SDtMT?c#8>0(Td(eT`{HuP+ZUHR-oCiH`}a~8S9iR9 zQ7&JNw@;DFSL5wdCgV$J-ZI zcf5UZb;sKm}zS`%vZ>=t0^$+M$)a9%Fd#U>#b@^(a-=4x(e6`P$nW8RV?ek=&sLNOTJed@} z8gJiPUA`J`pQ0{bjkl-p)p+~X>hjfi`xJHgYP@}lx_mX>-hGa*#@n}E-SPIt<&L*6 zE_b|radpSr7gu+mC$lJ*ug2S_$mOf?_9=4tYP>y#ug2TAR+q2F+o!0@SL5v|e6{oK zTdT`gJKsJ5G}`D(mhjfidkSCe^JKPGm#_LTUy8bX)ko!0)a9%3_MV*hYP@~x)g5nN zT<&=L;&R8^7gx8B85LJ|ynRtFUyZj!@%F9N<*V`bDeCgoc>5G}`D(m9g|Eijw^o<0#@nZ;%U9#=Q`F_F@%9wH+WGda z)#a<5Z=a$rU+sK*3SW)4Z>=t0jkixxm#=odeTuq#we#&Md^O&_wYq#Y-abWLz8Y_z zqAp*Jx2N#cc>C7s^3{0z6m|J(ygh}l#@n}6m#@a#r>M(Uv^jS9iR9adpSr7v=KRc>5H&d^O%aMJ`{Bx2N#cc>C7s^3^`SeTuq# zwe#&Md^O&_wYq$@&y$&=E?@2QWTvRgS3BRH!dK(%TdT`gC7s^3{0z6m|J(ygh}lIyi2vE?zynSnR`D&jhGeup#+ULnkQJ1gA+f(?e!#CFI^3~3_@2l$a)y}t1 zQJ1gA+f(>z=i9edm#=odeTuq#we#&Md^O&_wYq$@&y$&=E?@2QWTvRgSL5v|eAPy& zwYq$@^X>bpx_mX>K1E%=8gEbGt2VT()#a=4_I*`dz8Y^&;j8iXt<~kL@%Aa|^3{0z z6m{pTuxLFO%Pp2$tZuQ~V!6fY7RxP`Ta-Irg;eFvSFPpFSFPpFSFPpFSFPpFSAkf$ z^HpoP^HpoP^HpoP^HpoP^Hum(?tIl+?tIl+?tIl+?tIl+?tB&Wl{;UxmOEdymOEdy zmOEdymOEdCisjB%t>w;Ft>w;Ft>w;Ft>w;F0cN@LRcpEPRcpEPRcpEPRcpEPRajc? zeAQa+eAQa+eAQa+eAQa+d=<==J72YyyLr`G?tIl+?tIl+?tB#jmpfmzmOEdymOEdy zmOEdyUTzi2moBZ?84Ee1*5C$mJ`%J;n9%72clWdie@( z@8Vo9U*YX3u9vUy_7vC4S9p7e{ar6#;q57|m#^^l6g~45-rf&S&wPcqr|6ll@b(lv z^A+BnqG!Is+xzkBnXmBn6g~45-kzdozQWskJA$713U5!*GhgBDDSGBByuDxVddAy} ztBbc6my5R-*E8N;TwT09Q^+;1@b;8lFWz2U&pY3~xVm_Iao3Bt7uPf1UX;sMczcRm zzQWs6-3UAN6>Y7)0dy4BdukiL1J)2i}dz(wH*Sx~p zQ}k?J?R>)8hMnzUn-twVwH^ z^A42tjJFq;8?6_Y8|4z0+pA1*J@<4b%H^wO*c9`s|F@RQS3BRnugW#AcD_BueGqSN ztu9~feEYttE?@0@`xJHgYUkTi%qzUTwYuij&bRNY>Y7(O-#$fM^9pZoJ5gQp3U5!5 zYhK~)DRRv#yuESgdd(}mJw?xag}0~ZnXmBn#;2b73U5!*GhgBDDSGBBygfzFe1*3+ zfc4B*JKx@Q@fF_QT3x=v+mD@Z?|b+PZ*Q$GUtRJQ-kvU(ukiK;yj;G*+f(H772ckr zXTHMQQ`R%yUfj9637v-8) zczcRm^9pZIk!xPz?cFf-Y+m8*DS9@q@b(lvn^$;yH&{KJS3BQc&wPcqw^o<0@b(mS z`3i48@b;oyzQWs6f-Iic>`}R%H=D(y@!tVjJFr(E4;n9x;x*#xSsL$ z9#7^gyuB!wukiL1b@>W!Pm#-4czZ_)^vqZL_fq@Q_zG`ttu9~T?J0WZE4;nOB6ay{ z=iB=e%&VPm-&)V+72e(hl%CBiygfx-^J?eY%i=4%y|teC3U5E~_M*Ccg}0~3dy|}t~dvUpVdvQJE?Zy3$@b;oyzQWs6cD;CealfOT zZ(m$pyuG6$yI#D#xSsL$qFlbh+f(H772e(huUx*u+f($+S9p7hx_pJVr|6ll@b(^= z)#a<5Z?6Zw!rNP`%U5{&vGeVH4`1Q!t<~kLeV)v|s;>LsK2K(fy6%H`dynVp@)h2m zBA2i5_7u5%g}3)O@8`@{czcST`3i4O(KBD+?Z?iy*8^YS?XC69SNr_-eO1rygZupU zDSCDv#M^rTp=Z9r+f(H772cjAm#^^lUT~~uyuG-(czbcVczba@#r3@N?Tf36xA(GU*Ne9o*E8N;l*?Cmdx~7X!rOZ>B$u!7_7pwy72ckrE??p8 zDSGBBy#2u2i*or2Z%>iSS9p7hT)x8Fdl9B*zQWs6{H*v2Z%=W(e1*67qRr2WuXet@ zt9Bp6+gq#aK8UxcsOvt6w;y^J)O8=k+f(Ga58~||Pt&ve;Lf-Ar|}iu z-dbJ0!rN2y%vX4OFSXU>tDSG}PcX0W_SSkfukiL>lnnXmBn*6Q*V-hSZiMLqKs-ku_tukiL1xqOAU2P)Px-dW!Pf?ez@b(lv^A+A6hEbQVcD}tH_zG`ttu9~T?Z?iy_dR@tx3^Z8uXetDUsczA zaOc~nsOvt6w}*Vxc;S3BR{pTk#pduw(13U3cbsmoXUJej`Vyu#aCt7~52?J3m_U-h#pmRsz4i{%#k zITx#2EVtOtxmewz+|8@dm)!ZPwcPotwcPotwcPotwcPnCU?z9IYAtuZYAtv3sy9+-riT$ zk%s)u`ux_s56Geup#>cMmhU-htPt!KXK zQH-KzzUo0|3Saf`VXZD-;q84@UB1HGQ`F_FZcEGJt8N?C>he{Cn4&IUHS8#>+vpKj zw{ajYx4)v|a{Fr|uIH>Q%H^w!GKH`3_SSOEE4)2Lu6c#GhuGESE4;m+u6c#Gr>JXQ z;q58v@)h1*lAg^gygfzFe1*5C=-Ir&+s}A=Q7&KM?J08k3U5!5%U5`Nt+`(F3U5zw zy?lkYr?_6ea=yJwalL%ye0z%PM(UczcSve1*67HV$?93U5#Gv*IhfJ;l$8ukiL1KP$e%+xv^6XTHMQQ}oPNczcST z`3i6EFP5J93U5!*GhgBDDSGBBy#0)~7v-8)czcRm^9pZIk!xPz?fv!L_2TWt^^CU{ zmy5R-cfELfaXsVh{iT;{Ug7O2`&r@b#a%DnUR+(gy||wh-dzBX3`P2Q~ z-~V!R|LXPaSHHc!xj4OgdVKrMn}h$U9v(x9NXQzyx>l>x{y_<7R?{P1WcSFwIjm&)Ai-sJXotu#vITtq?=ih!I z`%Rwa*?xij=KJyYd+Qhe?9|xHn;EldmnHLKLoO#~!)99s%zcfte3$8(WZ5mRHNbLN z7He*0uAJ4l%2OGtDV3G-QNt+*WuInJ#>q8}qWqFsnn2kkk2H94N7iWGWQrWon8^zn zq3P0S>3-EvX`*zSYL+xex;yPzdQZ}Oj^0!Bo}u>yz31mWJ@46hPtF}$>A${jKe+wm z_M_X+Za=*J^!DTH=eK9%Jt21-p#S>5eu#TAZo9ny`o4aUJAtz2;XMuSS-5T5{_Fet zdF~l_CrYjV|)Z6x1|Mh+SXxos(Vrmdi7u5*DqjCs6nCr>-+j81Y5FJ-`DS9&!l09{_FetUF_^fFVp+4 z@9X!mXV6~8_Foq4_pxWsUgq^*HthGYXU<**Wzre7@9X!mC(S))?o@}*EbRBO^Bg{{ zaE9jSzHgqMspsn1dcK~q`+fAd(SQAU{XX^%$!^O1*Z1}N*puU)8@mPdccSm>_t7}- zzrL^EM`N=8`o4Z2ji3JO`}%$C>Ck5l_WRg#p-&m?_pv8JpD)<&W6y#w{^uzN>;-bT%4 zjbYQDw{f$1vw^dTvyrpA;-0m3N8J5zPg%Pc?oPPptK9{658RX0?ti=c?U`zKzTNls zG_`x)?s$8S+TCvVx;;VdKDWEvo}G4w+x=}%O}n@4&bH^J-PLwa+mq7nXS>FhaYPdR(W*%Qv5Z+4ns&o+Cq*>laFYW7UCCz?Ia>}h7tGJBHQ zbIhJ%c4lBtFnfO4X@Nbv?8#;41oqUjXO^81*z?MsR(3XEPbzy(*{Og%qwEP~=K=O~ zvS*W>1lV)Qo=SEGU{54_9@*~yo<;T~vVH$Oh3pw*JN|qA*we@M`uF6q=Z@|2@0nvy z9NXXD)5e}PwzI$Ij6G#+Pk&Dsd%oCi{+=!NWU+nxJyq!VR`R&YaUw*st+mqjp{PyFw8^68y z?ZoeWZ`+069{hITxBtG~_wBuJ=Y9L`+jZZb`*z&7-@bRZZLfVh?R#I_cG+M@_*Lr)_+p*q$^>(YbSG}F;?Ne`;dVAFS7f-f7z1`{kTPNF@-oEtS1-3ou?MUza zU)zn|Ui9AiwSDOALhn6a+kxKx^WN>Xz31&bZ{K;l&U=s7cAU50yxr#QHE*YR@9Www z^Y)ncj;`%5Z+Cg`<=W2j_LcXkY1>oYj`BV)ZM(_aOWr4?Z6A5N$a~M$c96G!ymxDD z?|3`Md!N>JjkjmK9pmj6Z?|~w&Du`!_KEkdtnCqRhj{PD+V1f7hWE*5+ZW!h@ILcw zJHp!!-lv^yFL*n_+Xvn*@b-YW1HAp;?f!1>cRRn^_ua1V-ea{L-|hEqw|9HJ+v(jt z?{;~&$GaWg?eA`PcYC}0|cx?a}TXQQM#0?(E(RwVm1R%kEuJ z+mqdn?B4&h-PrBLZYOs8uzT0j_F%UIyZ1Y7_jP-(+j-sRifz|*d#?LLvF*2Rw{@Q- zww>1Pv+i9@+hg4h>)y|_-PP@_?ww5ASKY4a-ovyV)$ONlH+6fdd*{;jQMZe_J=E=> zZvS+IpnK2Jc0jlPx!uq0eeRt`+xOhA=iXzq9nbA|?%hS( z>)cM~_Bpr9x%U)phjaUzdpFVcHn+36_YrMZb9!D_0&Qn< z`;yz0+@9p#0kr+d?M7}da-X!deaP)X_Rk~qU*Fg7qkndwS0}wZ>G!dH$L%_9&v84B z+i%=%R#qBF@S8;oa+fm$p;&v0am$*;L+CJiT z5%(Ec+dh0f%*pA-z^R}C}y}Z41 zX8U;C#oK#kwu86*yY1d>?{4pu*}mO&?Rq`f3zhBJ6?&<%9lJs=R<>VP=;g|G>k7SK z*IAxr}~Gg=O@6DlDVlRACwYt_sWOx791t zW%T}-N$R~`HeI8vW!srAOK4=slx(Miv^+{3q(y8h`Q`OGNLvM zM12;B8Z8iYS|Dn*chrb_Ef6(ZAnLY2)NX;O-`;;CYPdkuae=7i0#VNeqNaPdj;QMb zQQHNgz6(T+7YLo#qloBlTSWACA|kqS5z(J75IR2}pz|{VIzK0%^RogvpBI=Im>HNF zm>ZZJm>rlNm>-xRm?4-Vm?M}Zm?fAdm?xMhm?@Ylm@Akpm@Swtm@k+xm@$|#m@}9( zm^GL-m^YX>m^qj_m^+v}m_3+2m_L|6m_e9Am_wLEm_?XIm`9jMm`RvQm`j*Um`#{Y zm`|8cm{FKgm{XWkm{piom{*usm|2)wm|K`!m|d7&m|vJ+m|>V=m}8h^m}Qt|;2El; z2APJU2Dyf!2HA$92Kk1f1{sICLwKB%4h2HzyhDNTIHw*8gvUAiP#`?c35WvWan3;$ z2#<3bqCj|@GZ6*CtxRK^PI6j=$z*$5IUzi3WU!6J5zzsIpI+tbk2En6F}&k z_9zfKXFdvq&dHAgp>zJDKx)&jIPKp!= zo%13ELg&;-fzUZSQXq6rkQ4}=b0h^q=QK%y&^c35AaqWa6bPO3CEXGu7?UD`Gbtii zlOlpQDI%DY?w<&qlP3j2=ln^5&^d)tAau^66bPLYDFs63TuOn^Ih|4uYnKrOlKw{bKt-Z*8>QhlRE`M=lo8A&^g6ZAau_16bPLYJq1GNTu*_}Io(qrbk6t` z2%VEY1w!Y%PcKU%n4cno`za#WpCW?)DIyr4Uc(@CP68DOo%28iLg!RafzUY{R3LOt z2o(sOb3z3|=d@6P&^a?yAaqU+6$qX4L%ozj=$s-d5ISdx3WUyyq5`3FuBbrhoGvO5 zI%kXugw9E$0-s6gnPIw}x4XODVChtN5JR3LQDAr%On(?|tE=S)(8&^eh@Aau?r z6$qVEN(DmatWtr{Ik8kAbj~gH!ZLzgDkAu$B7$KmA~>cZf@SJeC_?8%Q-RPq*Hj>M zPB#?@oik1aLg%DYfzUbcR3LOtJrxL@vrh#==LA%N&^ZUyi(!P$X{Z9Bb0(@l=$woy z5IX0h3WUxnsRE&MR;obgoR}&QI_IVegwE-y0-~Sozr0jLg$QFfzUZARv>iFixmi+Q)2}}=j>R4&^bX?Aau@=_2w>uB`YF$vLb>h zDmIcHWNbWWQU2%R%$1w!ZKS%J_we^wxLPN5YDowH~KLgz$U zfzUaZ)*DiU&grxQp>sy9KiFz!eCclW+w>=R90* z&-({z9byYId4Z_&-uNTxyg<}> zfvEEWQRfAs&a(uFIxi4)ULfkcK-77GsPmKpqRtCMofn8YFA#NJAnH8-fT;5VQRfAs z&I?4H7l=AfRv_xUK-77GsPh6*=LMq9GaHCHFA#NJAnLq8)OmrZ^E3#e&I?4H7l=A9 z5OrQ4>O5zHsPh6*=LMq93q+k42%YnAMFbC5MDTD$1P@n4@Nfk}=Lt4}(7BK16bPO3 za0No=xg3Gec@jk+be_Es2%V=53Z3`nULbVdyJ~^Zd2eS0Lg&4Y6bPO722LP!-a99O z(0OlJ3Z3`HLLhYBD|&&@c`u~}Lg&4P6$qX8;!z-U-m5l&(0MPH3Z3_&Mj&+Fs|kV7 zc~9d4q4SHq4PL_(D{81Nay!SAf4Z5fpor41MTBL`#jJ-5VTJO z?IS_^Owc|Qv`+=?V?p~|&^{QnPX_IyLHlgbJ{+`92kqlQ`+U$oAhb^i?IS|_jL<$L z#KUzxu1e=TT;b=?`M!yC9~RoDh4wY1`@GOTFvP>{BjW`^=lj&qzJ7F{8{*;mA)Q0# z`|J=8*AYVJ`~1*8K(y~1-A9P_8KQlNXx}%wj}h^3DNBUTdAP#guFm&qqJ5lbpC{S} ziuQ@3eWZwo>n}Hghbtm@xT34#;fk(`hbuY<4_6Zio%3)7LgzeOfzUY*S0HrG!xadR za~`fh=$wZu5FY0|T!HX7=iv&3$2kvIAUw`_xCR2@an8dP2#<3fu0VL4^Kb>ip z5IX1K3WUyixB}sE&chW5k8>WbKoQEqAI_KdEgwA=m0-rOt+YmzMJY0d$IS*GLbk4&S2%YnA1w!XMT!GN}zMGSW>nMVUDbMSBlLgzeOfzbKBij#-y2%&Qxu0ZIVhbs^|=iv&3&Uv^3p>rOtK`&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1 z=R91`4G5j{a0No=JY0d$IS*GLbk4&S2%YnA1w!XMT!GLz4_6>`&chW5o%3)7LgzeO zPf-y(ToJ*;6%jmK5y8V15j|JX}Wzo%3)7LgzeOfzUY*S0HrG!xadf^Kd-}BXrKg6$qX4a0No=JY0d$ zIS*GLbk4&S2%YnA1w!XMT!GLz4_6>`&chW5o%3+L6hP>lhbs^|=iv&3&Uv^3p>rOt zKoc4Lg<`_>$MI-=R912&^ZrRAau^d6$qX4a0No=JY0d$IS*GLbk4&S z2%YnA1w!XMT!GLz57$dBgwA=m0-eBUL>!*ztvIS*GLbk4&S z2%YnA1w!XMT!GLz57+BpgwA=m0-rOtKe!3WUyixB{Vb9{Jz{#=R912&^Zs+I~jz|dAI_h^ZQ0eo%3)7LgzeOfzbJV zlcUagxB{Vb9oQEqAI=`=P)Hx4VAau^d^@a+ea~`fh=={F3QRh5dfzUY*S0HrG z!xadf^Kb=1=i9|%n^byYId4Z_&0#WA$qRtCMofn8YFA#NJAnLq`;Ngl09oQEqAI_KdEgwA=m zJOx7MJY0d$IS*GLbk4&S2%YnA1w!XMT!GLz4_6>`&chW5o%3)7LgzeOfzUY*moACm z;fe?zu882_iU=OAh~VLJD+rzQa0SBSoQEqA9_KtUPydGEsoLg&2!76_g9&QlcKdG7%PLg&5s76_g9s#hR%-pfsa(0Q-(1VZP%z$$d!%OHW!d9ObNLgzj43xv*l z#uW&i_f#hkI`26~Aavf%z2BeHdADE@(T!3>bUPCf-E>4mw}wLJJ%9y5=RI-+Lg$UF zKw^ZNxro!_qj>U_ThxZeWYuL17&0QZZ4 z`%S?8D&T$>aK8+=-v->T1Mc?$_X~mhjllg%;C?4?zZAIN3f!*+?)L)si-G&i!2N3A zem8Kx9Jt>O+^+}j_XGC}g8L1@{fgjzM{vI+xZe`ouL@9hOoU5w)OCKLfA$K+jn@|AZ!4zLYx=fp@HP$Jp26EPcsmAf!{F@~ zyzPRwTktju-d@4mDtO<_w~d0gPw>8$Z@UCdZ?SZ#D@HPkD zckyj&;Oz{&FXG$2z}psh-@>;|fww2{wglde!21He?FYQ=fcNct+YESn0q?8#wiEC+ z0^UBr+Xi^wy0=Y$w+HaH0OsMk9dy6i{=Yn2N8Nq4`7aOGeWLr-cK+QL?QP%RZTq`# z+1sYS+w*r{v9}$6x8d);UvJy}Znxikx!(5r-B!Qb>319b?tAsN&F^;k-6p?0Tz4f` z<=)Q26|Ty?ormjo)m3e8-)-%?oqe~lFAvxM5V2i-x2f;;^xc-e+tGJlptt>ex1H~H z^WA2?+sk)b`EDoQZRERse7BA7cJbXNzC2vFN#}5H=iv%h<=(z;%iHF?+q-vPmA9RH zw{h>jCvV&KZr9#@N#6GC-Il%khP-XqyZw5%UGH}5-IwESuikCdyPbNsQSbKY-Phu6 zm)>pCyYIx?7QNe{cVCFN{du=NFAvuZy}#Y<&CA1eb7Iws;?zY6;j=0+pcl+UPJKXJtyUlR77w*1#Zad*_Bi!wSyKQi{3+^_- z-5$8x0(U#$ZUfxyf4l8(_ic0A{C0ca?yKgu^X)di-S^CG+uQAWyDypBp10fbc01l~ z!`pqo+_t;jZnyh#x$Skkt#0?ta@**3``m7u+wF3@FO}OKx7*@&-zc{YZnwYfzD{nt z+ir8)?QOfQZTC%b+t_yd+HPB09ha2wk4aJ|~9!R=V*lrWseP`UZu-y)}`@*>GU%TyVw|nh2uibaWZR^_YT)T~HdAMHN zxhjuy9`= z+U-!g4QjVP?Y5`g?zG#Sc6-xqYufEhyNzjixL#~_Roj)8hwI2yd7SSX;I<*{_M_d` zzil_#ZAQEAe%n^G+lh8x{I-2)w+$^1*NfMF^6f#pEoip`?Y{7B`_FFs+3h~N&1bjw z?7r%4JI`+8*?rI3ww>Lsv-^^_?K!(GXL-0@7CVRcYCK%g-|jY><>7k0?B{TA-xs@W zpV@6QyIp3t$t(}o|LQ0AIOpLCgva@Im*wF)at`m+wzKRumfiQbZClyxD!VUn+n%!9 zQg%DaZbR99f7`Z`<>7kS-i8!BT+x;kJY3PH6g*tfwiG;E(Z&=!T(9vFy;my`y;my` z-P;R9@6`%K@6~!kfatwif#|(jfvEEW(Y?Ju)Oqh75WQC`5WQC`5WQC`5WQC`5WQFH ztp=j^=LMq93q<$!0@1y_Ky+{KeF>s_dx7Zvd4cHtd4cHtd4cHtd2eD6y+1DybzUIq zyg<}>fvEG|@gVBFK=gcGAiB2~h&nG2b>7<}M4cCi-k%qUIxi5tKQ9oyKkvO1qSx&O zqQ`lG=y6^kdYl&so%3)-1P@n4@Nh*04_8F+a0No=JY0d$IS*GLbk4&S2%YnA1w!XM zT!GLz4_6>`&cpTo5214&u0ZIVhbs^|=iv&3&Uv^3p>rOtK`&chW5o%3)7LgzeO zfzUY**Slea&Uv^3p>rOtKoQEqAI_Kef2anJ>4_6>`&chW5o%3)7LgzeOfzUY*S0HrG!xadf z^Kb=1=R912&^ZrRAau^dB@z%i=iv&3&Uv^3p>rOtK`&chW5o%3)x7=+GwxB{VbpNA_DI_KdEgwA=m0-oQF#?A#~2e6$qX4a0No=JY0d$IS*GLbk4&S2%Yy*K_GPAbF_%)nN&pdd?zA$ zRuU0CcL;>eyJ-uA&bwO*gwDH7353qOKL~`*dteHL&U-`%gw7kqLgx*PK0Z49=Z z!L~Kn_6FPLVA~yR+k5f4e+f(cdl)*WVIC=R912&^ZrRAau^d6$qX4a0No=JY0d$IS*GL zbk4&S2%YnA1w!XMT!GLz4_8?To%3)7LgzeOfzUY*S0FsjdAI`Man8dP2#<3fu0VL4 z^Kb>ip5FY0|T!HX7=i!ip z5FY0|T!HX7=iv&3$2kvIAUw`_xJEaEhbtm@xFUjwDoQEqAI_KdEgwA=m9&QMo^Kb=1=R912&^ZrR zAau^d6$qX4a0No=JY0d$IS*GLbk4&S2%YnA1w!XMT#tH$&Uv^3p>rOtKoQEqAI_KdEgwA=m0-`&ck)zM(CV}D-b&8 z;R=M#dAI_ha~`fh=$wZu5IX1K3WUyixB{Vb9oQEqAI_Kef`iS7+iU=OAh~VLh z2p+D8;Ng0%LFk-^D-b&8;R=M#dAI_ha~`fh=$wZu5IX1K3WUyixB{Vb9oQEqA zI_Kef%0uX!hbs^|=iv&3&Uv^3p>rOtKrOtKoQEqAI_KdE zgwA=m0-oQEqAI_KdEgwA=m0-rOtmvC)F%EJ|HMash!ZAQw&6>Ue#!xe2v%ER?~4^ig@qRtCMofn8YFA#O! zi$g@67l=A95OrQ4>byYId9Nf9bzUIqyg<}>fvEEWQRltvMAUhKsPh6*=LMq93q+mw z8WmCJ1)|OiM4cCiIxi4)-V0hpofn8YFA#NJAnLq8)OoLd5p`Z5>byYId4Z_&0#WC^ zR7TW!fvEEWQRfAs&I?4H_qrNU=LMq93q+k4h&nG2I_Kev2p+D8;Ngl09oQLbZ07B`&chW5o%3)7 zLgzeOfzUY*S0HrG!xadf^Kb=1=R912&^Zs+TM~rMdAI_ha~`fh=$wZu5IX1K3WUyi zxB{Vb9oQEqAI_KdEgwA=m0-oQEqA zI_KdEgwA=m0-rOtKrEv>=R912&^ZrRAau^d z6$qX4a0No=JY0d$IS*GLbk4&S2%YnA1w!XMT!GLz57&EJgwA=m0-rOtK`&chW5o%3)7LgzeOfzUY*S0HrG!=(ifI_KdE zgwA=m0-rOtKSqp^Ddr2!0I`6flKoQEqAI_Kfy5jyAL3WUyixB{Vb z9oQEqAI_KdEgwA=m0-rOtKoQLbL z9-(s{u0ZIVhbs^|=iv&3&Uv^3p>rOtKoQEqAI_KdEgwA=m1~Gz%DoQEqAI_KdEgwA=m0-`&chW5o%3)7 zLgzeOk70z)dAI_ha~`fh=$wZu5IX1K3WUyixB{Vb9oQEqAI_KdEgwA=m0-oQEqAI_KdEgwA=m0-rOtK-LAxIS*GLbk4&S2%YnA1w!XMT!GLz4_6>`&chW5o%3)7 zLgzeOfzUY*S0HrG!*v%%=$wZu5IX1K3WUyixB{Vb9oQEqAI_KdEgwA=m0- zoQEqAI_KdEgwA=m0-oQEqAI_Kef9!2P!hbs^|=iv&3&Uv^3p>rOtKbyYId9POxbzUIqyg<}>fvEEWQRlt5LDYGHsPh6*=LMq93q+mwN(fQs z1)|OiM4cCiIxi4)-peLLofn8YFA#NJAnLq8)OoM55OrQ4>byYId4Z_&0-oQEqAI_KdEgwA=mUKb*C&chW5 zo%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R912&^ZrRAau^d6$qX4aJ@W5=$wZu5IX1K z3WUyixB{Vb9oQEqAI_KdEgwA=m0-rOtK`&chW5o%3+L&q3&% zhbs^|=iv&3&Uv^Zf`=<2c(@{hhbtm@xFUjwD-b&8;R=M#dAI_ha~`fh=$wZu5IX1K z3WUyixB{Vb9`&chW5o%3)7LgzeOfzUY*S0HrG!xadf z^Kb=1=R90*5fM7);R=M#dAI_ha~`fh=$wZu5IX1K3WUyixB{Vb9oQEqAI_KdE zgwA=m-l-yV&chW5o%3)7LgzeO5y8V15joQEqAI_KdEgwA=m0-rOtH~9#i^Kb=1=R912&^ZrRAau^d6$qX4a0No=JY0d$IS*GL zbk4&S2%YnA1w!XMT&@A3a~`fh=$wZu5IX1KiU=OAh~VLh2p+D8;Ngl09oQEqA zI_KdEgwA=m0-`&chW5o%3)7LgzeO zfzUY*S0HrG!xadf^Kb=1=Xo@N(0Kx@(0Q6kAatJJ5eS_pRs=%l84ZEZc`895bl!V- zfzWwxo(rA#7FQs2-g`@d(0Om_1VZP%n-U0}_clf#bl&?1fzWv`-1{y{o%ixuMD!w9 zMD$WsMD&7EMD((+(0MP;1VZP%DiR2t_i{uabl&R#fzWwRzyhK3p7{hq=RM^VI`4@= zAavdxSs--YtxzCz-aSYlbl!tsAavfNP9SvNxEDHaC`&chW5o%3)7 zLgzeOfzUY*S0HrG!xadf^KkWv&^ZrRAau^d6$qX4a0No=JY0d$IS*GLbk4&S2%YnA z1w!XMT!GLz4_6>`&ciiU5j`&chW5o%3)7LgzeOfzUY*S0HrG!}U-==$wZu5IX1K3WUyixB{Vb9 zoQEqAI_KdEgwA=m0-`&chW5o%3+r7$SJMB7%o2B6zqWf`=<2c)0E&2%YnA1w!XM zT!GLz4_6>`&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R90DGlb50xB{Vb9 zoQEqAI_KdEgwA=m0-rOtdn!WbJY0d$IS*GLbk4&S z2%YnA1w!XMT!GLz4_6>`&chW5o%3)7LgzeOfzUY**R8!T9_HbSzIvF4EBf+b9fvEGI6%ln_AnLq8)OmrZ^8!)lJ%u9byg<}>fvEEWQRfAs&U?N^)OmrZ^8!)l z1)|OigwA=mB7%o2B6zqWf`=<2c(?+ga~`fh=$wZu5IX1K3WUyixB{Vb9oQEqA zI_KefjeyWO4_6>`&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R912&^ZrRAau^d z^-=|)a~`fh=$wZu5IX1K3WUyixB{Vb9oQEqAI_KdEgwA=m0-rOt zK`&cpSZ7ol?=u0ZIVhbs^|=i!P79`&chW5o%3)7 zLgzeOfzUY*S0HrG!xadf^KiXgKoQEqAI_Kef*MiVF4_6>`&chW5o%3)-1P@n4@Nh*04_8F+a76?US0HrG z!xadf^Kb=1=R912&^ZrRAau^d6$qX4a0No=JY4Uz5IX1K3WUyixB{Vb9oQEqA zI_KdEgwA=m0-rOtK`&chW5o%3)7LgzeOZ`lz#=iv&3&Uv^3p>rOt zK`&chW5o%3+n4usBm zxB{Vb9oQEqAI_KdEgwA=m0-rNC>4MNX4_6>` z&chW5o#)2{Lg$GofzWwINFa2ciV+B%=RgEP=g9|w(0T9r1w!Y&-7a+An__{`dGAIA zLg&2=6bPO7{!2vkE=ff6UPeUpjzdKBzCa*!-V1Vp(0Q+f1w!Y&1QiIK_u5Y&bl!_D zfzWxcb_7D_z04?d-irZ&(0R|o0-^Js{scnjJ?{vF&b#3YgwDIu3WUzP#T7d5MkEkA z?+zdkI`5$;5IS$>1w!Wyn?UHimIXrR{q+_)?=L|hbl%woLg)Q|0-rOtKrOtKrOt zKrOtSw-lahbs^|=iv&3&Uv^3p>rOtKbyYId4Z_&0#WA$qRtCMofn8YFA#NJAnLq8)OmrZ z^8!)l1)|OiM4cCiIxi4)ULfkcK-77GsPh6*=LMq93q+k4h&nG2bzUIqyg<}>fvEEW zQRfAs&I?4H7l=A95OrQ4>byYId4Z_&0#WA$qRtCMofn8YFA#NJMDTD$1P@n4@Nh*0 z4_8F+a0No=JY0d$IS*GLbk4&S2%YnA1w!XMT!GLz4_6>`&cpS5fzUY*S0HrG!xadf z^Kb=1=R912&^ZrRAau^d6$qX4a0No=JY0d$IS*GLbk4)|w1v<)4_6>`&chW5o%3)7 zLgzeOfzUY*S0HrG!xadf^Kb=1=R912&^ZrRAau^d_3VkzIS*GLbk4&S2%YnAMFbC5 zMDTD$1P@n4@Nh*04_6>`&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R91`_z0cz za0No=JY0d$IS*GLbk4&S2%YnA1w!XMT!GLz4_6>`&chW5o%3)7LgzeOFFX)B=iv&3 z&Uv^3p>rOtKoQEqAI_KdEgwA=m0-rOtKs2>G=R912&^ZrRAau^d6$qX4a0No=JY0d$IS*GLbk4&S2%YnA z1w!XMT!GLz57&!-gwA=m0-rOtK` z&chW5o%3)7LgzeOfzUY*S0HrG!}Y!ip>rOtKoQLb}8$#ziT!GLz4_6>`&chW5o%3)7LgzeOfzUY*S0HrG z!xadf^Kb=1=R912&^Zs+yGVr2dAI_ha~`fh=$wZuB6zqWf`=<2c(@{hhbtm@xB{Vb z9oQEqAI_KdEgwA=m0-oQEqAI_KdEgwA=m0-rOtKE&chW5o%3)7LgzeO5y8V15joQEqAI_Ke1C=)5N%fzWw(eSy$`&chW5 zo%3)7LgzeOfzUY**L5Rw&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R912&^ZrR zAau^d6$qX4aQ*cmbk4&S2%YnA1w!XMT!GLz4_6>`&chW5o%3)7LgzeOfzUY*S0HrG z!xadf^Ki9@&^ZrRAau^d6$qX4aK+z8m4Awd_!3X?5^wP>e#Eap)OmrZ^8!)l1)|Oi zM4cCiIxi4)ULfkcK-77GsPh6*=LMq93q+k4h&nG2bzUIqyg<}>fvEEWQRfAs&I?4H z7l=A95OrQ4>byYId4Z_&0#WA$qRtCMofn8YFA#NJAnLq8)OmrZ^8!)l1)|OiM4cCi zIxi4)ULfkcK-77GsPh6*=LMq93q+k45j`&chW5 zo%3)7LgzeOfzUY*S0HrG!xadf^Kjie5IX1K3WUyixB{Vb9oQEqAI_KdEgwA=m z0-`&chW5o%3)7LgzeOcT$ATdAI_ha~`fh=$wZuB6zqWf`=<2c(@{hhbtm@xB{Vb z9oQEqAI_KdEgwA=m0-`&chW5o%3)#2_baO!xadf^Kb=1=R912&^ZrRAau^d z6$qX4a0No=JY0d$IS*GLbk4&S2%YnAJr^Q$&chW5o%3)7LgzeO5y8V15j` z&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R912&^Zs+%Ls(ddAI_ha~`fh=$wZu z5IX1K3WUyixB{Vb9oQEqAI_KdEgwA=m0-oQEqAI_KdEgwA=m0-rOtKxCdf=R912 z&^ZrRAau^d6$qX4a0No=JY0d$IS*GLbk4&S2%YnA1w!XMT!GLz57+BagwA=m0-rOtK`&chW5o%3)7LgzeOfzUY*S0HrG z!}U@gp>rOtKoQLZj z1w!XMT!GLz4_6>`&chWEJX{gM!xa%cToJ*;6%jmKfzUY*S0HrG!xadf^Kb=1=R912 z&^ZrRAau^d6$qX4aJ>sc=$wZu5IX1K3WUyixB{Vb9oQEqAI_KdEgwA=m0-oQEqAI_Kev2p+D8;Ngl09rOtK`&chW5o%3+Lokr-Khbs^|=iv&3&Uv^3p>rOtK` z&chW5o%3)7LgzeOfzUY*S0HrG!xadf^Kb=1=R8~{0-rOtK%o@Wse*$@$tvk(!P z1rgEve}T|>Z@dLU=e^?<2%YyAd2g-+Lg&4!5eS|4cB0UEFZu;S=e^n% z2%YybS0HrW>q~*qc`xh)Lg&4r5(u65Ql`*(FE|83=RMO4gwA`46$qX8+$In@?@2`< zbl%-uAavesw9t7sJAu%7cNu}uc@J-a(0Pw5fzWvaEf6|yk_1BMRaoe}zi5Hbc|V~* z=)6B#AnH6NQ|a=t{8~PjujPCBz5H4JF2`1XZ2ilzO@QOE&4A;vO@ZUF%|XWvf*ji@ zI3C+DI3C+LI3C+TI3C+bblgnHu}y{JvCW0!u}y~KvCT%u4Tl`tcsL&0fH)r8h&UeG zkT@ROm~`Bn$gxd|R@gp?<@+R-@sn82PhwfWa&yJ|IUc*YqW-Lm-CVJMR>p3w2*6f0R}`S*op*D^ z0$SO5H&;ZUm7RBU#Rayqxncty@4TBULeR?2ySd^7TiIN(f{u6I%@r|dW#`>oaf4QN z-pv&~*vjULAauO*Zmu{&D?9JziYBzO^KPz~!d5m{T%qHgcXLG-TG@FwSBzmRn=8)H z@y@%sq7AL=yqhcL(8|ucxgrl+*<8_wj(6V86@zGH=iOY9h*oyq%@vQ>%I1nmbiDI! zuE<0yJMZR-Pi&GlSB#=#=j9Y7mQ|EkUQs$PvsiAfxJAcfH&^tcm9d*EhSAE{%@xVm z%I1n@biDI!u9!wEJMZR-Y_ziTZm#&oRyJ3RqvM@-b45B@*?BitykjeyE9TMh&bzrH zAFb@Xn=Ag&%FesFq99w@T#=BDciznv4{2rR-CR+TR(9Ua6&u;g=8BJWyz_3ZC`l_j z@8*h?Y-MxBOFG_pH&@i8m7RBU#ZFq;c{f)CWhJUhrDNyiEhUz@lvwUkIxl-!Zm#%C$745F6sDE2 zn=2O6%Gk{nk=e@Tipq4n^KP!#Oe;I@=8Dj?vh!}PIL%fzSFEPvop*CZY+BiQH&@(d zE1N5J)A7!`xgt2N?7W*Rj?>D{ySbt{TiIL@osM_j%@x;aW#`>o(VbRy-pv)`*~;dM z^K`uPZmwugD?9Jziur71bH#l+-g!4y^rw}bcXP#nTG@FwS0rdFn=2aB@y@%sVnVI# zyqhaB)XL7gx#B}x*<3NAj(6V86)9?E=iOZKqCMMfu9#8B&dZHTEITT({HSzZhP2#V zaiosNZmwujD`PiTOsSQzn=7)kmCY4h>UihfTrs9rcHYeuX=-KX-CXget!%ECQ^z~+ z=88PEvh!}P_|sN4R}8A-op*CZqFUK`H&;BWm7RBUMWwc~xgt{?@4TBUKGn+3ySbuN zt?ay;D^|6Y%@wcec<0?*QL9#V-pv)e+REmNUv<3mZmuX+D?9JziebxG zRIB5icXP$ITG@FwSA?sTop*D^xwf*oVqG2YyqhcH)ymGhx#C`X{j|AaUmZIy|0=Nz zti*D#(s^0fa&yJQIv%^ZqGGL#-CVJ;R>p3w2-#LPSCp*dop*D^%39fZH&?{0m7RBU z#m%;|xngG>@4TBUg4W8;ySd_MTiIN(w2pV)%@t8=W#`>oakW-<-pv(V+sfvOuywri zZmu|6D?9Jzing_~^KPz~+g3JL+^yrCcXLJGTG@FwR}5||n=202@y@%sqH(S4yqhZ~ z*UHYjxgv90*<8`Nj(6V86{Blq=iOY9x>k1H%@wcP%I1pMb-eR#uEok-t`U-pv*N+sfvO0d~CeZmvjRD?9JziU)3GbHxNZ-g!4yWU!T;cXP!DTiJOx zSCnuon=4Y-@y@%s;)Sj3yqha(*vihkxnhS~*7b446m*?Bit+;Jzn=1~v_jsEt7TK}$^2id)BugxpES;B4E;m~ZB&bzr{q^<0{n=4YfmCY3`?Re+iTrtyDcHYeuIc;U<-CXh0 zt!%CsYR5b8=8B}Yvh!}Pcok=Ryt-pv({-OA>Q$#%T+Zm!5|D?9JziqCFk zbH!*o-g!4yq_&lvcXP#STiJOxSJZYZn=5kL@y@%s;A1<+sxWsbe(s^0&a&yIt zJ082aqQp3w2=Z1oR}{J9op*D^l3Uq%H&;Ztm7RBU#g(_Rxnj#5@4TBU z!raQvySd`bTiIN(=8kvX%@uKOW#`>oapzWc-pv(#-pb~RKzF?JZmu|VD?9Jzibl7x z^KPz~^j0=kT)N|(cXLIjTiJOxSB!cqn=4M;@y@%sqSdYJyqha#-OA3pxgytF*<8`< zj(6V86~k_2=iOY9>{fQ(%@xny%I1n`cf9j%uE=&PJMZRdzCA74dCSp3w=G&9>V>egx?XB#*o2&WuR(9Ua)qHy& z=iN1LuIAfY*)?yjeEzmmZLa3qJKlLWSM%*%;Lf|b@;Ti8`_0vSd&m2EH&^rRt?cLB zT+O%l!|mtYT=__@A9v^7T=`V4m7RBU<%7AcY_8_pJKlLWS3aHVf8BXES3aO?W#`>o z&A0a#x$|zW=G$8tySbWgZ)NP}YQDX{`2D<_tNHd;cFmis`SwByj)z?pO2e9q*cV zznX7vW!Jp>)qH#Z6t-*L{mO@e`x7=-^X(n)nm1ST?LCNh&6}(F_EvV@&6Upw_a|(w z=G!~oHE*uw+q(g{=K1y#JKtVn=i5u?oo_E)^L%?bc5~$u!`5B%e0%BVoo_Fl*XM@I z&DDH+$9~@V_HyjzYQDXdop*CJ-`>s1&pY2#CB_R=-ax0ho#S3Z?&-8Ij*mww*)_R@KMHo4qf&9`^#=bdja$8N6X z+gsUrH&^rRJ#qPY=iAG%o2&WuR(8#stNHd;cHYg^e0xuNyXMW6&n)++ZLa3qJKi;K zuIAfY*)?yj=G%M1+<7-wKEB+au(_IV?|9d|xtee9sdd-9xtecpW#`>o`6P3H!scqe zz2jZ;=4!sZe+J(*Z?1fzx&MB1HQ(Oxu6c7c-`>iud2==2-c$Ond2{8%&HV|RtNHeh zcg>rt`Szatcg>rt`SwAdsp zrE8vVFUM}KeDc}4Yo2c}{k-$-rStmybGf;iZ|~U8JKtW8-CWJLx3cqYuIAhO5P_d} zzP%i~xtecpW!Jp9ns0Aq=iOY*xA%f**Sxv%x#<41&DDH+$Ghgu)qHy^yXMW+e0wjZ zcHYgEk4X0?Y_8_pJKi;KuIAhOn8U7lb2Z=I%FesF@@eV*gw54_d&j%x&DDH+FWGj@ zn=7B1?!Vt$&9`^FYu;SVx3{uu-dxSM_i}I7yt(oL>i&ey)qH!$yXMW+e0v|n*fnpi z=G$A@c{f)+OWmKaxtee9c-OqSns4t#rE8vVFR}COC3e2Obl&;)(lyVwmt!|qK3#3y zHP5$~e%|@^(s_Nxy4+mNw|DI4oo_G4Zm#CrTiJOxSM%+?;Pvy)x0ho#SM%+y?3y=M z^X;wdyql}}_CB1lYu;S>>~(+I=4!sZ<6ZOSYQDXdUGwH@zP%UPJMZSo$FTboHdpiQ z9q*bqSM%+?B;Pe}uIAfY*?BitK9Sv@u(_IV?|9d|xtee9<1@SF&6Q7P_up@>=G!~o zHE*uw+gsT+Z?5Lsdn>SO-dy>Rc7MX=YQDYWUGwH@zP&dMyXMW+e0wW9@8-(qwfhq` zSM%*1@0vGP^X+}W$2HHlm)QCC56+);%dwj)pWwFcn&;a~Kks~d>AXJ2 zU2d-C+dKC2&bOCiH&^rRt?ay;tNHeRWzo+&-(HU0T+O$)vTNR4&9}F*^KP!@+j}Fm zYu;S>e0P7^=4!sZ<6ZOSYQDXdUGwH@zP&eLJMZSoN4@(KHdpiQ9q*bqSM%-tUgfTN zb2Z=I%FesF@~Q9sgw54_d&j%x&DDH+Z}oP~n=7CG?!Vt$&9`^FYu;SVx3{uu-dxSM z_cn3Yyt(p0@cx9&)qH!$yXMW+e0#tAxoh5B&9}F*^KPzuCcHmkb2Z=I@veDuHQ(Nw zQP(`*USj9lOYD4m>AdsprE8vVFUM}Kd`jH9Yo2c}{k-$-rStl%c)7WnZ|~U8JKtW8 z-CWJLx3cqYuIAf&qwMFMZ!gDguIAfY*)?yj=G$A@c{f+{?Y+s~HE*tbhP*#*b2Z=I z@veDuHQ(OKu6c7c-`)q}cHYgEkCXQ&Y_8_pJKi;KuIAf&E5B>rT+O$)vh!}Pe6qYh zVRJR#-tn$^b2Zq)-(LE8=i5u?^?CGib2Z=Iv7dLoy&Su_ns0Aq=iOY*w!<&DDH+D?9JzYQDV>Jnot|S3alSpSHQ0Z|`{5yt$fhZ)MlKxtecJ z-t4@aD<4_!PuN_|w|Bg2-dxSMr+IeGo2&WuR(9Ual~1qtCv2|f+dJMhZ?5LsQ$)Mw z&6Q8F_up@>=G!~oHE*uw+gsT+Z?5Ls(@VSN&6N+d_a|(w=G!~oHE*uw+xy_>u6c7c z-`>j3ySeh&_Wp#;)qH!$yJmBhzKSio=Cbpav1R8iW6Q3&?7U@cIhGeqeT_9&9gj6v z9gj6v9gj6v9gj6v3A3^0s^hWds^hVId>VRmWq^Rhn(Ax$1Z9&4^T9&4@=fn)jhj>np- zj>np-j>np-j>qz%>BF(+s^hWds^hWds^hV|XvbsCRnl>+x$1bVx$1Z<-`??9bJg)! zbCs$b%eQwt)?9Tw)?9Tw)?9Uroo_F({bR`z+dp6|vHhdM5}W8>j@?}4T&--b@)-B!kKu9|Txo2&lc9q+uGs}$r`cHYfZf^RE3@8&9fW@U4g-rDibySbWg?|P`MucHYfZZ=tPhu6jeeluJ-x%eym;d?pOPKdn>!< z&DDH+E4${+)qH#Z?67OzT+O$)vTNR4&9}F*Yu;SVxA)h!Yu;SVx3{uu-dxSMx3X*A zTfAPEK-LLlf_EvVyo2&WuR(8#stNHf+VZ=4hx0lX4-(F(p+e_Cx z-(EWJe0w=|b2Z=Iil2ABy>!jJ)c-ud>@HP5$~WA{8b-`>j3yXV3A_I^oX z?Cw|d?XB#ZcfXo%Z)NA*{c66wm0k1hSM%+S;m*7J)qHy^`+0Z2+UMI_*){Kewa>RV zw)=VaJh;!dx3X*A^Wc1YE4$`B56-vuYaF}g-LK}`TiG@5el_3T%C33$tNHd;cFntA z&A0bJ*){KeHQ(OKu6g&XeZIYwUGwf&`+R#3tX=b-2lx5*R(8#M9-MD)W!Jpt!TI)n z(PY=W`_+7VE4$|1ujboZ*){KeHQ(NfYo2c}op-*y#Ll;uu6e$_bl&;)a_sI`^X=UL z{Jit+rE8vVFP(S3z4Y_WxA&_su6e$_9J~9~e0wW9@9tOg?X8U6{c66w+sv+c_p5!r zy_KDJ_p5!ry_H?_?pOPKd$*;XclWD(zP*+Gyt`k`x3{uu-u-I6y_NmEyI;+>_YaA? z=H0L6+gsT+?|wDk-pa0d_pAB#ZiKt$-LK}`TiG@5el_3T%C33$t9`z`8|SWh_p5!r zy_H?_?pO2et?Zh2znX7vW!Jp>)qH#Z)VXWk{c66wm0k1hSM%+y?3#DKns4t`y=&h6 zYQDXdUGwf&^X;wdns>k2=i9rryXN`!(s}3GOYD4m>6+);OXr<$?;l{t?tZn;x3}Ww zoo_E)^L%^hyz}j)pLf2!bj|ba<=EY?_WAZ!cHZ5u_WAZ!#_oPK-`*3^u6g&X`Sw_e8g!clWFL_EvVyyI;+> zx3X*A{c4|YZ)MlK`_(?*-c#kSdH1V*zP*)Q^X^yk?XB#ZcfXo%@1L@F&AVUCx3{uu z-u-I6y_H?_?pO2eJr(bocfXo%Z)MlK`_+7VE4$|1ulD)&R(8$1U+welJ(=&CcfZ=_ z+gsT+?|wDk-pa0d_pAB#{;}OP&$pM(JKtVn=i5uyJl|eA?|geXcK56K_E!A7^X;W; zo^LOmcfP%s7=GUQ_R=-ax0hpgznX7vW#`@fYQDV>0*u}LYQDXdUGwf&^X;wdyt`k` zx3{uu-u-I6y_YsS@9tOg?XB$R-Ti8xZ*OJSy!+KY-`-21{k*$h?ep!e?3#DKns0Aq z*S!1He0v{N*fsBdHQ(OKu6g&X`SwjNZ||2Ecg?$B&9}F*Yu^28zP*)Q z^X^yk?X9@x`S#Lz=i5u{e0%Ad=i5u?oo_G4?tV4j-it~#lkCt9`z`m7RC@t9`z`m0k1hSNnW> zFLig`-LLlf_Ez@u?tV4j-pa0d_pAB#R`&Dmel_3Thf{XVyI;+>x3X*A{c66wm0k1h zSM%+?xZXAIel_3T%C33$tNHd;cFntA?ep!u7~eJTezniHx3X*A{c66wm0k1hSM%+y z?3#DKns4vpGrQ*9ujboZ*){KeHQ(OKu6g&X`SxD^@0xeNns0Aq*S!1He0wXq=H0LM z`S#u}xaRrx(s}3GOYD4m>6+);OXr<$??XLfcfZ=_+gtJT&bODYdA_}L-ud>@&pY2< zy5{-za_sI``+R#VJMZpS`+R#VV|TxrZ|}{`u6g&X`Sw!<-LK}`d-JrPclWFL_EvVyyI;+>x3X*A{c4|YZ)MlK`_(?* z-rKKT^X^yse0wXq=H0L6+gsT+?|wDk-p8YM&AVUCx3{uu-u-I6y_H?_?pO2ey}jEt z?|wDk-pa0d_pAB#R(8$1U+welt?Zh2zuM>9dxN-Z-u-HyZ*OJSy!+LBdn>!<-LK}` z`v8|~o^LOmcfP&E&bODYdA_}L-ud=&?Cw|d?XCEE=i5uyJl|eA?|gf2Tm8KA?WJp; zZ!gF0el_3T%Fes{)qHy&E*rc1)qHy^yXM`m=G$A@d3V2>Z*OJSy!+LBdvBL_-rcX} z+gsVsyZhBX-`>iudH1V*zP-2C`+0Z2+UMI_*){KeHQ(OKu6g&X`Sw2kwrk$~YQDXd zUGwf&^X;wdns>jNZ*OJSy!+LBdvEA>&AVUCx3{uu-u-HyZ*OJSy!+KY-<|;2HSd14 z&$qX-Yu^28zP*)Q^X^yk?fpXhu6g&X`SwX(YIv(qO)$v$!)$v$!)$v&OtJKR_ zbJg)!bJg)!_p6S_nyZe-nyZA(Sof=r$C|5-$C|5-$GTs2Jl0&LdB&Qnj>o!Rbv)Kw zbv)Kwbv)MnDmgUPTy;FwTy;Fw{i@@!=Bned<|?H$*8QsEvF57dvF57dvF=wLW9QpT z?0kEPoo_F(^X(;ezP%i~xtecJVma@8d+EG=HfQO){k!+ldFR{P&cQWjbC+W`SGk9+ zjNM%IDr_rbH&x&$S@9Zb=72e)j&wPcqr|6ll@b*BUx_s3!i~R(?!rNQx znXmBnkfEOWs*mvZ{d|SDx7IUX;q57U<}18C+^A>1>Z8{E1ir%CTkDyx@b;ATjJFq; zi? z@|E-LDRTKLEW2F33Y%K%nXmBnzN#)?;q57U=BpsuviJ&bZ>?v(!rN2qm#^^l9!8=r zUxhsO6Zp#c_SSmlE9cu&^vqYih2Hn`Rc~>v^~_gzdtcQvU*YX3dgiO%@GOh3@b=bv z<}18CMbCVNxA(Xdb@{5>)BOa#a=yK_p83l8_7pwyRku6)e!l8<#9GgMg}3)rJ@Xab zp0b|1q>1af%Z#|(M!&eajbm{=HzGy3eANJ&!dDFiYq{oCzj740e3hZ6@Kq+WR+q2v z_P(kvU*YX3>he`hEQ_!3_SWk172ckpE??p8DeCeS-rjL|b>S9p7hp50&J?fnX_ zXS}_*x_EnWxp;eVJ>%`g)y3QU#g%Jb;q58gFWz2U&v<)rb@BG%_KUX{*E8N;l-3U5!*vw4NL_eWrQHm~sZ z6g`_)czcST%`3dUi>jW@E4)2L&*l~0o}y>-3UBWstY`BIZ%@&)d4;#9=-Ir&+f&vv z-d-3UBYv5cOltq^t}fnQTrS>TT+euWadq+bZU*I=S9p8M_KUX{*E8N;TwT1qxc%bo#r2H0 z7v-8)czcSv<`v$aBGJXQ;q57UHm~sZZd%nfukiL1`!%od_7pvv zS9p7W#A(0g72ckrXY&egPtmh^g}0~Z*}THryG_=!d4;#9=-Ir&+f(#xUg7QCR_ock z!rN2yY+m8*DS9@q@b(_-sAuyEZ%@&)d4;#9=-Ir&+f(#xUg7QC$m`j>!rN2yY+m8* zDS9@q@b+%}*E8N;TwT1qxLmxwxSsL$;_BkDj!(+f(#xUg7O2 zdN!}{_LO?=?O?gZ>K5y{SZ=Yp#dP@`d`KqXp{;&So!;&So!;&So!;&So!qFlbh+k*|Oi?M(UczcSve1*4%UhJ2z@b(lv^HqOP zy59H-Zx7O_%U5`Nin@G-x2LGfSDq)6qAp)K-yY^sm#^^l6m|IuZ%^@B@fF@47V=v0 z72clWwc;zhJw?xag|~;1)-&E-TwT1qxLmxwxSsL$;_BkXTEa2Jw;vf%K7#bJ)2h@bzMci z!rNP`%U7N!lcFwPd7ey)x_s5a#Qg;G3U6=iwKA`qZ%?sb^UC@59yOt^d4;#9sB2!~ z?J4T=72ckrE??p8!94rrE4)3$e)$S-PqAOV!rOy?dgd#r&b7v=I5-X5gfe)0C=dhX*f zadn+iSS9p6URL^{cx2LGfSE1_teDex#Z>?v( z3eN7U=9TBkw3cgLd7ey){hC*vC({E(^vqYGwEYD03U6<%XY&egPtmh^6`I-i^Hu1? z+Uv|$cza*fGhgBDDSGCs-bgQtuRKqtwVwIP^JG%=%vYW#(<4vR<*VNI>?fF4czbI- zn^$;yik{7@Zlm}8eAR8PwVwG3Z||#m<}18CWj%MRB(CRfU&Q5hOChdqmw9nLcj*=7 z@>LhMDSU;ux0cISczcRmzQWr>-RhcGjiLPnzG^gBtIJn-dtX(Tud?;Nhp#f6wVwH^ ze@=>?`KlL-qG!JHJeeLLBiFq0Jeh)A^UCwvQ{Z5d7ey)x_sq%GAVNT z%JXFUC)G1wd479}x_ssN?J0WZE6;Dw0_vJqp5LBgzvh+a$)xDnyz)Gm6#F%=JWr+% zZS-tjd7ey)p3N)IlS$FDdF6RBnNH8- z%JXDW^lV;vo=l3K%`4B7>0>25n^&GElcHzy%JXDW^lV;vo=m?MdN!{-PbNjr?yo#g zCPmNguROoKU!(Pmw-;9zZ!azvZ!fNAyuG-(czYjq$u+M$zddF9#oLSP8E-GHF5X_; ze)0C=ddAy}a?LBxZ%RnG`*nSDq)+*weFl<#{qGdN!{-PbNjr z=9TBSr|8+d^8EG&r=HC#&u>rBvw7utGAVjCukiLh*j&$edvSH~_TqB!_TqZR+l#B~ zc``-0<`v$avi;)i#r2H07grZ=Z=7$xczba@d!9^Du6gBoGAZhsSDq)+hpuwXE6vE6bzUU{BO7x3*DZ!fNAyuG-(czbdC#oPO6eLdstMY-mc z=gFj~YhHPtOp09d%JXEpP0+J><@xO?>Y7)c-=3mp^UCwvyRA^yyz>0^6#F%=JWnP? z&*qiq$)wn?dF6RB9R$#`dF6RBDS9@qJWnP?&*qiq$#f&5XYN6+S!=eMWm*}U>RnG`*nSDq)6qG$8U^JF@zpl9>S^JG%=Y+iYuOp2b(E6rJ ze)0C=ddAy}tBbc6w_m)yxSsL$qFnRJ^V?I@HLpCsJw>j0<#{sQNb1?V@;sRob1(vw7wD?J0UTuRKpCMbGAy=gD*wMbGAy=gFk#*}U>RnG`*nSDq)+t+bxa zE6$zBNQSN-zEx+8&tJZQiuUgC9ylO3X^QyJn&8yxh$lbhZEqA_ZEqA_Z zEqC*(wcPotw-<8ftJZQiuUgBUuUgBUuUgC9yy{Jf-1(}t-1(}t+|8@ja_6hoa_6hw z%E;ZkYAtuZYAtuZYAtv3sSeo-_KXQld!g5 zzG|jU;j8{@EtjvHZ||#m<}2shQ}oPN&bRmGST0{V-=3l_Upe2NqAp+I?Y)`yTJaU$ zp5ot#ukiL1J@Xabo}y>I!rOa0u4lf&+f($+S9p7hp7{!I@9n#u`3i4O(KBD+?J0WZ zE4;n8`|BBRFRm`$UR*BTUR=+3dvSH~_8@^=^9pZI*?#f%;(Es0i>r&b7q?%$y||w7 z_M%+#3U5zQ*Sx~pQ{-%K7#bJ)2j~x2NdYymG$1HR|#e-kzc^U*YX3>hcxd-cd@g6<^`)DPAkS!rN24 zR(yrGhl18K-dxqOAUr)6x$a_7rvb3U5!*GhcOtdKLK!Z*Q$GUpe2NqAp)K z-=3l_Uv=PhKf!enZ*T3jGOwI(PqAO~%K7$in!4r{-kzead4;#9sB2!~?J4T=72Y0@ zvtPc#+f(e9ukiL1`{gUVy#up)<}18CMbCWYe0z$X`O5kBfS;cE3U5!*GhgBDDSGBB zygg+-M(U zczcSvd=(B}6}}48TC2-f&bRkfb@|Hq_7rvbDtNan^9pZo?X@zm@b(n1vw4NLcOY6_ z^D6AJpTJjmduu)O72ckrXTIvK`@WyAdQ)w!XTEa2y|3z-ubgjB(KBE5Mr&E-72e)j z&*l~0o}y>-3UBYo_Ud*sEv{}ixZ-lV=@eJD8$oeBcXPJLSKTmK%Qdg?_P#3D{Z$ux z-y_$&>QXv|ue!Wht7~3$@t~+{Ug7P1zq;mCgKyu%S9p7CJ)2kks{5+C=2gE)Q}`-# zTdT`g&bRkfb@{4)9^a#9zG~Z3_zG`tt!KW%+Y9RQ72ckrE??p8eT%y072ckru6c#G zr>JXQ;q4)OJ@Xabo?^dzg}0~ZnXmBnTF^6J;q57U<}18CMbCVNx2NctukiLZp=a|7 zZ%@&)d4;#9=-Ir&+xw7VJ>%`g)y3P3%f;J^>ltq^t}fnQlxtq$?J3(Y-dmc6VM>KjiukiL1J)2i}dy1aTE4)2L z&*l~0p6T>#Ug7O2dN!}{_7pvvS9p6S)w6kpx2NdYbr5e)(X;Cy-rk2udN!}{_7pvv zS9p7hp3N(~J!L)P?Zwr_+l$M^+l%WNZ!fMc-d>bzUg7QiGHt(jdvQJE?Zwr_+l$*T z-rmPt>ltq^%5@#Y+f&qa9mLyH- z3U6-+>Dj!(+f(#xUg7O2dN!}{_7pvvS9p6L8|vA-!rN2yY+m8*DS9@q@b<=@p3N(~ zJw?yv72ckrXY&egZ%nRdyuG-(czbcVczba@JXQ;q57M%`3dUp{{513U5zQ*Sx~pQ}k?J;q86ss;+s3 zx2M>zd4;#9=-Ir&+q-DkuX%;Hr|8+d!rN2yY+m8*DS9@q@b)e{dN!}{_7pvvS9p7h zp3N(~y^n?UY+m8*DS9@q@b(lvn^$;ymo+_`S9p7hp3N(~Jw?yv72ckrXY&eg@4~2O z^9pZI(X)Alx2NdYyu#c2;Cemd?Zwr_+l$M^+l%WNZ!fMc-d>bzUg7O2+b`Z;T+euW zadq+bF4x;H-d_E4)2L&*l~0-fe~bnpb#xik{6YygfzF<`v%F$NqXYukiL1J)2i}dy1aT zE4)2L&*l~0-i?f&%`3b;MbG9H-kzdo^9pb8#z)WQ72ckrXY&egPtmh^g|~MwLC@wD z-kzdo^9pZI(X)Alx2M!|w^!vBt6Qw+V!6fY7VEiKZn3(>dM?V{yz16W?tIl+?tIl+ z?tIl+?tIl+?tIk^o!t4VwcPotwcO3C)^g{o)^g{oZUg0RUbU7xU$vGyU$vIIdDU9( zeAUgP-1(}t+|8@ja_6hoa_6hoayPHK<&-;LwU#?ywU)bi)mrX+)mrX+)s3p$&8yaO z=d0Fo=d0FoH?LaDov*sRl{;Uxmb-b?TJC(+TJC(+TJGjmH^p-2tJZSotJZQiuUgBU zuUgBUuez0%yLr`G?tIl+?tIl+?&ekN<>Kwd<>Kwd<>Kwd<>Kwd<>Ku{xqOAUck{lw zczbbm@%G~C;_b!N#oIepv!3zxqFlbh+f&r#E4)2LE??p8y+zP7U*YX3>hcxdo}y>I z!rOaGp)OzH?J4%lS9p7hp82ZJ#@8ob;qAR0QJ1gcSoI!rOb(qi4Rt+f&r#E4)2LUB1HGQ`F@vyuG(gUT40-+f($+S9p7h zp7{!I?`@Wz`3i4O(KBD+?J0WZE4;n8W$PJlFRm`$UR*BTUR=+3dvSH~_TJ3NHLvjY zlj0g}3)6QqSfU-kzead4;#9 z=-Ir&+k4Zgu6c#Gr`WG~g}0~ZnXmBn4u#n-U*YX3dgd#Dj!(+f(#xUg7O2dN!}{ z_7pvvS9p7G#Pw`m;q57UHm~sZ6g`_)czbW$*E8N;TwT1qxLmxwxSsL$;_Bk zZ%@&)d4;!k3{YM3%K7#b`!%neZ%@&)dF6b27{h+eE4)2L&*l~0o}y>-3U3d4=-Ir& z+f(#xUg7O2dN!}{_7pvvS9p5|74>Xh;q57UHm~sZ6g`_)czd8l&*l~0o}y>-3U5!* zvw4NL2WIqaUg7O2dN!}{_7pvvS9p8MddAy}tBbc6my5R-*E8N;TwT1qDA&Bg+XF(| zFWz2U&v<)rb@BG%_KUZNj@C2YUX*KI;q58vnpb#xid^#wZ||6=p3N(~Jw;vf3U5!* zvw4NLhpE&xukiL1`!%od_7pvvS9p7h{hC*Jd!S3t=2gd(w->&`+gq#4S9p6zP}Sut zygfx-zUolvega?N?XB&XukiM8n*H(>-kzc^Uv&ghcxdo}w;ag$wund=<#EwqL$-zP+#7FJC#|o?^dz72H`C zU*YYo^~_gzdy1a<3U3eSs>@fsE#FVzE4;n6p7{!IPth}9_13QM?@gMx+}=2etJ|9y zaXt42LtJh*{fp*RH{#ZE`KsGoid^%mn@EaW_gCGbO>uwKZIiXSu7ll_P}JqCF8LI7 z`Kk-*6!WT!oVB{~_dJ11PG_BR;t40z_RCk!x2Nctubgl1V-x%3 zE9cu&^lV-^-=3mp^UC@5{@L|xUOC^MqG#7Z=i5{C?EcF6_7pvvSI)O*96h_ga=tx9 z&*qi$?J0UTubgl1gB?AaSI)Pm=-Iq-zCA_H=9Tm98B@>ZmGkW>dUhRjzCA_H?ysD0 zPg&1+dvSH~_TqB!_TqZR+l#Ac6v6ioNrH2*SvDRJw?yvmGkX=ET*n`<$QaJ{hC+K zx2NdYymG!h#eU5z=iB>5*R%U8=i5{CY+gCvo}y>-%K7#NgPzSR=i5{CY+gCvo}y>- z%K7#_xYM(F<$QaJp3N)g+f(#xUOC^MqG$8U`SwPUp3N)g+f(#xUOC^MqG$8U`SwPa zp3N)g+f(#xUOC^MqG$8U`Sw0qT+euWadq+b;&So!;(Es0i>r&bHz4JjSI)PmY`=JW zaXsVh#nr{zi`y^WUR=+3dr_`=<$QaJy5^Ph?J082E9cw$AXLxhmGkW>>Y7*1x2NdY zymG$1L9VWO<$QaJ{hC+Kx2NdYymG$1!Ee9jmGkW>dN!||Z%@&)dF6b2ik{6Y=iB?J zR?p^@^X(~mHm{s-Ptmh^<$QaW8aK5y{ zSZ-17eAOjX?&ei%xtmw5w;Ft>w;F-5SWXp{;&So!;&So! z;&So!;&So!qFlbh+q=nHUA(=xx_EnWb@BG%>f-Gke^}3Wdr>Z5;q58v@)h2mBA2i5 z_HO0$%vX4Oin@G-x2NctukiM6{nX_vygkK!`3i4O(KBD+?J4%lS9p6jk9y`SygfzF zeAP*f?T)YdI^N>Q0klzkJod)fB$M+gt0IukiL1J@Xabo}w;a z;qBets>@e+dy2Yzg}0}u%U5`Nx5Hj%zQWs6^vqXydy1a<3UBZBc|GIp#nr{zi_68^ zi|ZM0FRm`$-c7e$^9pZI*?#f%;(Es0i>r&b7q?%$y||w7_M%+#3U5zQ*Sx~pQ{-3U5!*vw4NLr|8+d!rObpq-XOAZ%@&)d4;#9=-Ir&+k1nxp7HkL>f-Ii z<>Kwd^^CU{R~K(D$~CX>_LS`xZ!fNAyuG-(czbW-wqLxxxSsL$qFnO|Z%L!rN2yY+m8*DS9@q z@b=yi>)E`*+f(#xUg7O2dN!}{_TE72*}THrQ}k?J;q57UHm~sZl=Y0a7grZ=FD@5v zFRo|2y|}t~dr_`=g}3*{ef!1Ri|ZM0FRm`$Ufh21_TJ*JXS}^A*Sx~pQ`9xD@b(nB z<`v%FaXdYnS9p7hy5<$$o}y>-3U3c5sB2!~?J4$aUg7O2dN!}{_7wXyukiMOgr3bS zygfzF<`v$aqG$68Z|}gMp3N(~Jw?yv72ckrXY-dl4&Jw?xag}0}u%U5`Ns7cR!g}0}u%U5`Niv98x-kzdozQWr( z9BRLOg}0~ZnXmBn6g~45-X7f2GhgBDDSGCsjven6;48enwYq$Tw+F`5<*Sad?)%Lv zyuG#knpb#xM^^3Eyu#a4?AN^N(BXapU*YYo^~_gzd-zSye1*5CsLNL!5!+ATE4;n+ zddAy}%k6lRxVjxV5?8llK;nAtXpShCukiK`*vjQAygfy(d4;#9$mJ`%JwT|gdF6b2 zin@H|e0z$zeC2$5Kyj}X-dpJLpGAZi14))>P zem-A0-`?7O`3i3jWU9+o&bOzi%U8~~r>M(UeMGUJ$ya!LYp*k3;q58v@>R&&_p8fS z0p%%t738(nGhc;JDPAkS3Q$hrtDvE^p7|;yN6|B11-vNg@>Mu#3SWhItkvbK018E2 zz6wuJRySlIu5NGR#pU+aT3l{#cg5B1EvP7$uX=+wg|G1T)^hm@Z%>iSS9p8aSY5vA zc6>jf-Ii<>Kwd^^CU{R~K(D%H=D(y~ej+yuG-d@%G~C;_b!l7jN$f z|9ZyTi*or2Z%mc5qqG$68Z|_ec^lVz zd4;#9=-Ir&+xrEzU-JrYPtmh^g}0~Z+517fJw?yv72e*jxSq``ygfzF<`v$aqG$68 zZ|_fD^lVLMd|^QyJn`Kqhcxd zo?^dzg}0~ZnXmBn6#L~XyuFLOp7{!IPth}9;q57U<}19tn*u%aRVQTk3h-4Yo2=F4 zt3H#bsLNM)dp8v7@>QH>-@{kkUt8NRUv(Xr!dLy*S}tGV?R`~UzQWs6)a5I@z1tSK ze1*5CsLNM)dy2Yzg|~N`v)37KFRm`$UR*BTUR=+3dvSH~_HK^knpb#x%3dqHy||w7 z_TuW|?ZxdEZ!fNAyuB#byu#a4)HSd0_7u7172e(-9qQSY7)0dy4&Y1%`g)y3QUbJFb>Z!fNAyuB#byu#a4)HSd0_HNSUnpb#xik{6Yygfx-^9pZI(X)Al zw|ASbu6c#Gr`WG~g}0~Z*}THr`?FX3HLvjY6g`_)czcST%`3dUw-I_aukiL1J)2i} zdy1aTE4)2L&*l~0-Ww4;n^$;yik{6YygfzF<`v%FALi=Wbr5e)(X)Alx2NdYyu#ai zqoZf@3U5!*vw4NLr|8+d!rN2UGu~cYUA(=xT)e%wp7HkL>f-H1x#kt#-X9Qezj%9b zJ>%`g)y3P3+b`bUTe0r_Y+m8*DS9@q@b(lvn^$;yik{6YyuG)!dN!}{_7pvvS9p7h zp3N(~y|==8Hm~sZ6g`_)czcST%`3dUKMh~cczbbm@%G|!@%G|+#@mali?{cNTdsM9 zx2J5sczba@JXQ;q57M%`3dUKV;Xld4;#9sB2!~ z?J0UTukiN3fV$=t-kxH=<`v$aqG$68Zx1BcuX%;Hr|8+d!rN2yY+m8*DS9@q@b>=H zUeD$g-kzdo^9pZI(X)Bwe0%6Z&*qiq$)xDnyu#a4^lVzuFf_SWk172ckr zE??p8VJda`%K7#bb@|Hq_7rvbs$<`)!dG~EYjyd`^JG%gm#^^l5T?3()kj48e!jxnTiY*R;q5)l!+!Y+Z%?sbzQWs6)a5I@Jw;u<3P!IA zU*YYo)#WR^Jw;uhe|Sa6iGk@;sT=UMus;^JG%IR_0YGs_zdfiOUW2h^rfX z5!Z7-L|kr=Vv(-`2i9`=s<-77xqOAU_x*DDs<)K;9=_^rp0&Ds)te}ax_s4J6pFfh z)f<2*u7ll_TdV6j*ex$b&#r^rP)^~iZt|?v<*RO?DC+W6Hz*W!`KrtR6u#<`Y^^R| zb-|;k%U4}aDC+W6!+Hu|H9)P^-kxB;e1*5CsLNM)dy2Yzg|`Rnw_m)yxVm_Iak+SV zaXsVh#nr{zi*n5?ygg;F72aN4&v<)rb@BGv+Z%@%PU*YY&JnHfl-kxH=e1*5C=$WtZ_Fhi=!rN2SL`F?J0WZtN!M7uL)n_?XA`2E4;nIuP$HV?J4T=RVOC)6Zi^m?-F6Z zd=-J-SNST&V=b4jx_hGNnXmH56ux@+3U5!5%U5`Nid??J+q)bs7jG}FF5X^TF5X_; ze)0C=>f-HP#N?V+czeqJjqvv3ddAy}tBbc6_gdlY#l6mWdr_`=g}0}uYhK~)DRRv# zyuFL3p3N(~Jw;vf3U5!*vw4NLcd=F1yu#a4?AN@)+f(#xUg7P17;eAj72ckrXY&eg zPtmh^g}0~Z*}THryS(e!yu#a4^vqXydy1a<3UBXrK+k-Ix2NctukiL1J@Xab-pBQN z<}18CMbCVNx2NctukiL1J@Xab-VKPJ%`3b;MbG9H-kzdo^9pb8hGjkD?Zwr_+l$M^ z+l%WNZ!fMc-d>bzUg7O2+b`Z;T+euWadq+bZi}{GyuG-d@%Exz^9pZIQP;e}+q;>P zYhK~)DS9@q@b(mS%`3b;MbG9H-rn&Cb_E4)2L&*l~0-tC+Hnpb#xik{6Y zygfzF<`v%F?Vg^^E4)2L&*l~0o}y>-3U5!*vw4NLcR)kW<`v$aqG$68Z%@&)>mc6V z4W^#WE4)2L&#r@bdy1Z22l4i9NcC)9;q57UHm~sZ6g`_)czeov#@mali?ltq^t}fnQ zTrS>TT+euWadq+b-WbU>ukiMi?H6w^u4lZxxVm_Iar?#Fi|ZM0FUmEq@b(mS%`3b; zMXq^;xA%rj&*l~0o}#XKg}0~Z*}THrdjqGgd4;#9*spnox2NdYyu#Z%U}eAN72ckr zXY&egPtmh^g}0~Z*}THrd&{V2^9pZI(X)Alx2NdYyu#aii>YVx3U5!*vw4NLr|8+d z!rMCnrf2gCZ%@&)d4;#9=-Ir&+f(#xUg7P%snxT2g}0~Z*}THrQ}k?J;qAQ%Ue9=Y zadq+b;&So!;(Es0i>r&b7v-8)czeqBi?tkZ zy|}v0w-=Y|e0y;{JKtVhUFX}2a?LBeJ-D*{I^SMg&v<)rb@BG%_Un9m7-l`=?M1of z72ckru6c#Gr^q$0@b->O>e;-)+f&pvukiL1J)2i}d&oy!^9pZIv0w8FZ%@&)d4;#9 z*spnow+D^%Y+m8*DS9@q@b(lvn^(@acc@d(=9Tm9DS9@q@b(lvn^$;yP)g6{72ckr zXY&egPtmh^g}0~Z*}THr!&-VaukiL1J)2i}dy1aTE4;m9r+PN8@b(lvn^(@ar|8+d za=txmwx03!;_Bk<#pUAd#r2H07grZ=54OoQuR3@)-E|OeZ@r$KZ!fMc-d@~(@%G|+ z#@mZ~t(S=3;e&k-U*YYo)#WR^Jw;u<>h0*hpRanmXsu_y!rS|*x_pJVr|6lldh@U>zH+|3 zwVwIP`Suh&^Of`M0cLgis$0GN1oH}SZ>?wZ3U5!*vw796!@i%dy0lyCnXmBnzN%;Q z3U5!*vw78^Ulw0E-`-l!eC2$5ik|t(`SuXFx~_x$a_%Sa72e)j&wPcqr|6ll`p4e) z^Hu)<)_Ufvwnx!3UzJSx`-ooUtHnn=@fAPCFY#Oa5r0Lw`KsJ}wJ5iFwYA)QwYA*l z)z)&GSFQ8aqTGD7wcPHnww9Z(ww9Z(ww9Z(TIZ`pxy`Gs<#rw1T5i7DT5i5-ov#+< z=Busc=BuscHm|mpo3FN(o3C2ut3|o_YHPXqYHPX8tF7hctJe8yQEtB4T5i7DT5i7D zT5j`dYq|NVb-r4Z+jVejx%p~qx%p~qxy`HA`D#&azS>%D_g7oX%~xB?%~xB?%~!4S z)uP<)ueO$(ueO$(ueO%kyo!hN)p+~X%N=iDT<&=L;&R8^7neKUUgWFs_O0de)p+|9 zxqLO=K1D8Hjkl-p)p+~X>hjfi`xJHgYP@}lx_mX>p2An-?OUtMSL5wd)a9%3_7uL_ z|1WiGb@^)lztkz}^3}svPl<*QtlQl7Zn@%F{#j<+wa?s)s+a>v_?e06*^-abVx zUyZj5H&d^O%aMJ`{Bx2N#cc>C7s^3{0z6m|J(ygh}l_Ww)WT3x={|1Wilx_q_& zU+NTf`D*{a)D*rNZ{J#7z8Y_zqAp*Jw@*=*ug2R`_-ed;Yjyc*ynTwgd^O&l!dEX} zjkiyc%U9#=Q{?j1c>5H&d^O&l!dEX}jkiyc%U9#=Q{?j1czX(8y?iy^K1D8Hjkiyc z%U9#=DSY+v)p+|9xqLO=K1D8Hjkix(?s)s+dLD0IT<&=L;&R8^7gu+@eNir7jkl-p z)p+~Xa`|e!eTrPZ8gEbGtMT@&)#a=4_9^P})p+|9b@^(%J%z76`D(mM(U`~Rg*QJ1gw|4U8btMT@&)#a=4_9^P})p+|9b@^(% zJ%z8v+qYJiug2S_sLNO5?J0b<=eKXIE?@2W?Nij{t3AJcin@HY|6ghfUyZkKtu9}U zw@*=*ug2S_sLNO5?J0aU-oCZEd^O%aMP0rcZ|^$CSL5wlukLvJ;&R8^7neKUzPP&M z?M1%Y^V_$U%U9#=Q{?j1c>5H&d^O&l!dK(%TdT`ghjfi`xJHgYP>y#ug2TAR+q2F+o!0@SL5wd z)a9%3_7uL_^JKPGm#_9bnJMb>)t)Dl!dK(%TdT`gm#@a#Q}}AUeQS03YR_+we#&$ z)a9$4Z=a$rU+sK*3SW)4Z>=t0jkixxm#@a#Q}}AUeQS03YP@}lx_mX>K1E%=8gEbG ztDSG(T3x={`SvO5^3~3_Pf?ezcD_A@ug2TAR+q2F+o!0@SL5y7i}TfZ`_`*F-oCip z@%F{#j<+wa?s$8Vug2TAmdjV;?Nj9P)p+|9xqLO=p2An-?OUtMSL5wd)a9%3_9^P} z)p&afUyZkKtu9}Uw@*=*ug2R`_-g0dw^o<0cD{Xzx_q_s?Nij{tDSF8;j8iXt<~kL z@%Aa|^3{0z6m|J(ygh}l#@n}6m#@a#r>M(U5G}`D(mhjfi`xJHgYP>y#ug2TAR+q2F+o!0@SL5wd)a9%3_7uL_`Sz{V z<*S`zynSnR`D(mK1E%=8gHMX zE?hjfi`xJHg zYP@}lx_mX>p2AlhuCi8_ug2T=RdxAlygh}l#@n}6m#@a#r>M(U}g)#a=4_I*`dz8Y^&;j8iXt<~kL@%Aa|^3{0z z6m|J(ygh}l#@n}6m#@a#r>M(Uw;Ft>w;F zt>w;Ft>w;F;aj=$RcpDMSFPpFSFPpFSFPpFS3zI7^HpoP^HpoP^HpoP^HpoP^Hr!= z?tIl+?tIl+?tIl+?tIl+?tB$smOEdymb-b?TJC(+TJC(+TJC%mmXiSS9p6#>hcxdo}w;a;q58v@)h3R zA$mRY72ckrXTEy)3U5!B%U5`Nt;yvpygfxOU*YX3_RCjzdy4(?72e+F?3b_b_7wZ& ztDSG}wc;zhy<`6B@)h2mqAp+I?J4T=72ckrE??p8y^!ki)y}t9g|G1T*6Q*V-rh^D zE??p8DeCf7e`~&vl=Y0a7nd6` z6_*>65SQEizPP$wOGUYSRh=n(g}1ks%U5`Nid??J+xzHd`^DRf>Y7)0dy2Z|72ckr zu6c#GXG3+(tK%!YJzcJOg}0~3HLvjY%q!Qt!rN2yY+m8*DS9@q@b*4j(zAJmx2Jfm z%qzS-#cRb^czcT1im&kYeqHRBukiL1J@Xabo}y>I!rS}x(lcM-?J0WZE4)2L&wPcq z_wkpW`3i4O(KBD|e0%>2e1*5SR+q2v_I{Ps<*VZ>yggm6d4;#9$ThF<_6ERm@%G~C z;_b!d;_b!tjJFr}TH)Nltq^%H=D(Jw;u< z!rN2i@)h3RMNH3pg}0}u%U5`Nin@G-xA!5lx_q_s?e)M{czbJg`3i4OQJ1gq_AZ#} z^3~3__Y?REZ*OhCe1*4nY4uw172ckrE?@2cm)cL@E4;n6p7{!I?_+R1^VQC`_xXTI9`_I?6i;q9&U%vX4O7k@qT72ckrE?@2cm)cJ-ukiNP zdN!}{_Wnof>ltq^E*EbvE*Ebvt}fnQT+euWQLcHl^X=2uGu~d@e)0C=>h64d(Y(Uj zTW`O3dr_`=g}0}uYhK~)9U|C%@%ExzzQWs6^vqXydy2Yzg|~M@q-Va``SyMqU*YYo z^~_gzdy1a<3UBXbN?pF%^V|Cge1*5S)-zw>?HzN_GhgBDDeCgo&bRjy_zG`tt!KW% z+q-4cGhgj|d*9DjczbI-^A+BnqG!Is+q>PO_SSmlE4)2L&wPcqccZN?U+sK*KY_3C_SSmlE4;m1ay|1E-kzc^U+sK* zKY_3C_SSmlE4;nqGkWH$Jx`|Z=PSIuwVwG3Z%@%PU*YY&70@$Z?RTTrS>TTwT1qxSsL$qFlb( z`S$7S8E-Fczj%9bb$7nK$X9rK>+KhBFUsXBygfx-zQWr(e6;=I?fc*ASgY&)YR{9| zSJicYwdcu9QP=$y-oF2h%5=WM+gr=!E4)2LE??p8z5TLZzQWs6^vqXydy1a<3UBZ2 znx6RzZ%@%PU+sA^b;4J8duw(13UBYNp1ORs^X+{bk$$`SvO5y1&}__7uLt+gq#4S9_k!zN)VKt36L<%If0n#r2H07nh5-7nh5- z7grZ=FUoa)g|~NbY(4LM`{H`W+l#A;7uz+xJy<-Cyl|`xLqE zuXesY#eF;8-dbJ0+WGcW!4+E&nS3BR{_wyCr-r9co z3U5!bU%tZILkRZES3BR{Pv9%Oy|teC3UBXlpPu;&Z%+g^m6%X&u`ya&wPcqr|6ll@b>+2?7ow)cD{XUxqP+r?Njv3 zS3BRH;yQ@8?~fiSa`_5xPnXMAczcRmzQWu0CvD5+t3AJcYd!N7-kzdozQWu0hfMoU zzS{Zrt>t<@xby8(^z8lM&bO!V72e)jUB24+_I*`d^J?eYr>JXQ?RYM&@>S@EqG!Is+k0cY*DBZ{ zs>@fQ1d6(R)f;t+x_s5!;3<67+f-|H`3i6EtLpL<-oCd?`%b>g|E8Zv{sj|@bOa=%@)h2mtS(>S?J4T=72e*Vc)5Iqx2LGfS9p7hy5<$$9@N*fd4;#9 z=-Ir&+f(#xUg7OErDwjv+f($+S9p7hp7{!IPth}9;q7fp&wPcqr|6ll@b(lv^A+CS z#}0btE4)2L&*l~0o}y>I!rOb<^vqXydy1aTE4)2L&*l~0o}y>I!rOb{^~_gzdy1a< z3U5!*GhgBDeK4|~@%G~C;_b!d;_b!tjJFq87jG}hHLvjYl%`3b;MP2g>Z|_4Jx#kt#o}y>hLA*UhUDrXpJw?yv72ci=)itm1_7wXy zukiL1J)2i}d$zS-^9pZI(X;Cy-kzdo*Fn7f@b;oyzQWs6c;S9p8MUMsx4xc%bo#nr{z`%{>`R(N}H zJ>%^~xqOAUr>M(UczXjzE??p8DSGBBygfx-zQWs6^vqXydm~C+zQWs6?3b^cZ%@%P zUpe1?czaQ-`?P~U%qm_J;i?c z3U5!bU%tZIQ|yI!rN2S%`gy;gX8ar?#F zi*nsx;q58vy1&BP`|~@w?ysD0PtmjcE9cu&)OCO5e0#SudUk*1e0z$ze1*5C*e_q< z?J0WZE4;lMBKzelygfzFe1*5C=$WtZ_H(|yDA)a!^X(~e-CyDDDRSLk;qBda*)Lz= z?J4%lS9p7h{qhyw-ff!w@)h2mV!wQax2M=IUpe2NV!wRleEZ?;MY-#r2H07nh5-7q?%$y||w7_M%+A!rQy4+-rrm7q?%$y|}t~dvUK7-rk>AZohbY zQ7&KM?J4T=72cjAm#^^lZe8`vSI)PmsLNM)dy1a<3UBXLS6#ls+f(e9ukiL1J@Xab zo?^dzg}3*|pnB#jygfzFe1*5C=$WtZ_HM5A%vX4Oik|rjZ%@%PUpe32&A6WV%K7#b zJ@Xabo}y>I!rN2y%vX4Of3B)$zQWs6^vqXydy1a<3UBZBU(e%`g)y3P3%f;J^>ltq^t}fo*AJNKn9mLyHwqLxxxSsL$;_Bk<#qAewFRo|2 zy(rgp5N}UW*L4tYPm$|7h`0CVM$fK;&bOzi>pJLsdy1Z22c2*4kA2m3e}%WF*suGm z{r^(yim&kY*6Q*V-rgH2b@>W!Pf?ez@b(mS`3i6EjhDK7g}0}u%U5`Nir0#-oNw=7 zl-HTBoNrI@TJaU$o}y>I!rN2y%vX4OZ}s%dS9p7hp7{!IPth}9;qARO)H7ef-Ia0hP;F&bOy*zj%9bJ>%`g)pfqT zxc%bo#r2H07v=I5-kzc^U*YX3a`_5x@1U8U`3i4OQJ1gq_7pwy72e((Wp()qZ%?sb zzQWs6^z6PJZ|{w@{dzx$x2NdY`$4=tMbF+3;_WGV#u@PT!`q8;`3i4Ok;_+jdx~7X z!rOa8Z@+wnx2M=IU*YX3_RCjzdjP^}KfJvtm#^^l6uEqb zx2MSEE4)3-&}&sJw^+}`_FF8sSkJ}wTP(L&&&Bo|oRB+TwU#?ywU#?ywU#?ywU#?y zg*4>OSFPpFSFPplI@nt7eAQa+d=&_hyX#x}I z*jny<)mrX+)mrZ6RnSH5eAQa+eAQa+=2dIC^HpoP^Hr!u?&ei%x${+Pxtmw5<<3{F z<<3_D9=V%Wt>w;Ft>w;Ft>tcBwU#?yg@xqKSFPo4UbU7xU$vGyU$vIIc@<2OJ72Yy zyZfuwa_6hoa_6hoa(90ff?6)#UR*BTUR*BTUR*BTUR*BT9=MXrS9p8M>f-Ii)y3P3 ztBbc6)#WR^y+=E!%U8~~r^w|i=i5`%<*SaX?x*n;-ribWzH+`jMbCWIAxPh^E??p8 zVK#O73U5zQm#^^l6uEqbw}<8SI^*p{b@>W!Pf?ez@b(mS`3i3j>8ZI3!t1ir%CTl+WSE4)3>=ym3+ zKAPS4^A+CSTF-oix2NctukiLD<$CVpH*r1pk(jvLKBf{^w~vm*^^CU{<(gN0tU{N| zSABp%k!xP{@xTS%UAtoOyR5kYppI{;q84@UB1HGQ`F_F zAlkC{DzIg(E??p8eN|n)!rR~Q%D$7Y!XMUh`3i6EtLpMqZ`XZ~x_s4};VFFOc`~il z<*VKV`l`Bo)tjp+=2dTatkvbK-cC@wR(#dXIz?T+>Q;D)dDZQywVwG3Z||$>@)h2m zqAp)`-(t1gNuUDCwmcCisxw+n!{o*T;IavPMQT=S{{G=;D5 z_SSOw3U5!5%U9WY-_KWgduw(13U5zQm#^^l6m|KkCiWBfsxMgUnXmBnzN%-w!rN2S z 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 GrYnAX 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 z700VG�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 literal 0 HcmV?d00001 From f3df844a153c077f75766968f170a9a28974b28f Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 2 Mar 2023 16:02:03 +0000 Subject: [PATCH 016/213] added ciftify package --- CPAC/info.py | 1 + requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CPAC/info.py b/CPAC/info.py index a256452a0f..649e67cba6 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -172,6 +172,7 @@ def get_cpac_gitversion(): REQUIREMENTS = [ "boto3==1.7.37", "click==6.7", + "ciftify", "configparser==3.7.4", "cython", "future", diff --git a/requirements.txt b/requirements.txt index 5b7529e41c..1a18ebf62c 100755 --- a/requirements.txt +++ b/requirements.txt @@ -27,3 +27,4 @@ scikit-learn==0.22.1 traits==4.6.0 PyBASC==0.4.5 voluptuous>=0.12.0 +ciftify From 012edf415f962d7afe15ce63b06069eba561e513 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Thu, 2 Mar 2023 15:30:19 -0500 Subject: [PATCH 017/213] :package: Fix path to tissuepriors in ABCD-HCP variant --- .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index aceb619b16..6d1b031824 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -44,4 +44,6 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ COPY --from=FSL /usr/lib/ /usr/lib/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/*mm /usr/share/fsl/5.0/data/standard/tissuepriors/ +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/2mm /usr/share/fsl/5.0/data/standard/tissuepriors +COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/3mm /usr/share/fsl/5.0/data/standard/tissuepriors From a7fc647bbfb85b70d4a56e13cdc9e16a71624190 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Thu, 2 Mar 2023 16:33:28 -0500 Subject: [PATCH 018/213] :package: Fix C-PAC resource import --- .../Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index 6d1b031824..eb326d86c6 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -1,4 +1,16 @@ -FROM ghcr.io/shnizzedy/c-pac/fsl:neurodebian-bionic as FSL-Neurodebian +FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as FSL-Neurodebian + +# install CPAC resources into FSL +ENV FSLDIR=/usr/share/fsl/5.0 +RUN curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz && \ + tar xfz /tmp/cpac_resources.tar.gz -C /tmp && \ + cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard && \ + cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard && \ + cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard && \ + cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford && \ + cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors && \ + cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors + FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free AS FSL USER root @@ -44,6 +56,5 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ COPY --from=FSL /usr/lib/ /usr/lib/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/2mm /usr/share/fsl/5.0/data/standard/tissuepriors +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/* /usr/share/fsl/5.0/data/standard/tissuepriors COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/3mm /usr/share/fsl/5.0/data/standard/tissuepriors From 19f8c795a4d5b70df4b5d655f72b7516bb0d652c Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Thu, 2 Mar 2023 16:52:45 -0500 Subject: [PATCH 019/213] :package: Create target dir in stage 0 --- .../Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index eb326d86c6..20640a4aea 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -2,14 +2,15 @@ FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as FSL-Neurodebian # install CPAC resources into FSL ENV FSLDIR=/usr/share/fsl/5.0 -RUN curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz && \ - tar xfz /tmp/cpac_resources.tar.gz -C /tmp && \ - cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard && \ - cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard && \ - cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard && \ - cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford && \ - cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors && \ - cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors +RUN mkdir -p /usr/share/fsl/5.0/data/standard \ + && curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz \ + && tar xfz /tmp/cpac_resources.tar.gz -C /tmp \ + && cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard \ + && cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard \ + && cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard \ + && cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford \ + && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors \ + && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free AS FSL @@ -28,11 +29,11 @@ ENV FSLDIR=/usr/share/fsl/5.0 \ # Installing and setting up FSL -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ - echo $TZ > /etc/timezone && \ - apt-get update && \ - apt-get install -y tclsh wish && \ - echo "Downloading FSL ..." \ +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ + && echo $TZ > /etc/timezone \ + && apt-get update \ + && apt-get install -y tclsh wish \ + && echo "Downloading FSL ..." \ && mkdir -p /usr/share/fsl/5.0 \ && curl -sSL --retry 5 https://fsl.fmrib.ox.ac.uk/fsldownloads/fsl-5.0.10-centos6_64.tar.gz \ | tar zx -C /usr/share/fsl/5.0 --strip-components=1 \ @@ -56,5 +57,5 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ COPY --from=FSL /usr/lib/ /usr/lib/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/* /usr/share/fsl/5.0/data/standard/tissuepriors +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/* /usr/share/fsl/5.0/data/standard/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ From 1c07c2698e9852031c5cd05f6b97d5ec21b48764 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Thu, 2 Mar 2023 17:12:47 -0500 Subject: [PATCH 020/213] :package: Set appropriate permissions in build stage --- .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index 20640a4aea..88b730dea5 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -1,8 +1,9 @@ FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as FSL-Neurodebian # install CPAC resources into FSL +USER root ENV FSLDIR=/usr/share/fsl/5.0 -RUN mkdir -p /usr/share/fsl/5.0/data/standard \ +RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard \ && curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz \ && tar xfz /tmp/cpac_resources.tar.gz -C /tmp \ && cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard \ From 780a8e324d16ecce949607cc95befd91e6d24bf6 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 3 Mar 2023 11:41:01 -0500 Subject: [PATCH 021/213] :package: Get more specific in resource copying --- .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index 88b730dea5..a73146451d 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -3,15 +3,15 @@ FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as FSL-Neurodebian # install CPAC resources into FSL USER root ENV FSLDIR=/usr/share/fsl/5.0 -RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard \ +RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard/tissuepriors/2mm /usr/share/fsl/5.0/data/standard/tissuepriors/3mm \ && curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz \ && tar xfz /tmp/cpac_resources.tar.gz -C /tmp \ && cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard \ && cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard \ && cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard \ && cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors + && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm/* $FSLDIR/data/standard/tissuepriors/2mm/ \ + && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm/* $FSLDIR/data/standard/tissuepriors/3mm FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free AS FSL From 6e75a8f0b518a52a839fc445606aa1248d435317 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 3 Mar 2023 14:49:38 -0500 Subject: [PATCH 022/213] fixup! :package: Get more specific in resource copying --- .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 2 +- .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index a73146451d..475bb805e2 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -11,7 +11,7 @@ RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard/ti && cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard \ && cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford \ && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm/* $FSLDIR/data/standard/tissuepriors/2mm/ \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm/* $FSLDIR/data/standard/tissuepriors/3mm + && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm/* $FSLDIR/data/standard/tissuepriors/3mm/ FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free AS FSL diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile index 8c681582c1..24e4dfa586 100755 --- a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile +++ b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile @@ -41,7 +41,7 @@ COPY --from=ANTs /ants_template /ants_template # install FSL COPY --from=FSL /usr/bin/tclsh /usr/bin/tclsh COPY --from=FSL /usr/bin/wish /usr/bin/wish -COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ +COPY --from=FSL /usr/share/fsl /usr/share/fsl COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ COPY --from=FSL /usr/lib/lib*so* /usr/lib/ # set up FSL environment From 2283078322226e5521a034ead6c2f7ee1fc58c33 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 3 Mar 2023 15:51:09 -0500 Subject: [PATCH 023/213] :package: Remove problematic `*` --- .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index 475bb805e2..98e24d20d1 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -10,8 +10,8 @@ RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard/ti && cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard \ && cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard \ && cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm/* $FSLDIR/data/standard/tissuepriors/2mm/ \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm/* $FSLDIR/data/standard/tissuepriors/3mm/ + && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors \ + && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free AS FSL @@ -28,8 +28,7 @@ ENV FSLDIR=/usr/share/fsl/5.0 \ PATH=/usr/lib/fsl/5.0:$PATH \ TZ=America/New_York - -# Installing and setting up FSL +# # Installing and setting up FSL RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && echo $TZ > /etc/timezone \ && apt-get update \ @@ -58,5 +57,5 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ COPY --from=FSL /usr/lib/ /usr/lib/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/* /usr/share/fsl/5.0/data/standard/ +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/ /usr/share/fsl/5.0/data/standard/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ From 4f8f1384d3280a1b36699cb1dd02f5d3d5f26de1 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 6 Mar 2023 17:16:45 +0000 Subject: [PATCH 024/213] changed joblib version to 1.1.0 --- CPAC/info.py | 1 + CPAC/pipeline/cpac_pipeline.py | 6 +-- CPAC/surface/surf_preproc.py | 98 +++++++++++++++++----------------- requirements.txt | 1 + 4 files changed, 54 insertions(+), 52 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 649e67cba6..bf68131ac9 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -200,4 +200,5 @@ def get_cpac_gitversion(): "traits==4.6.0", "PyBASC==0.4.5", "voluptuous>=0.12.0", + "joblib==1.1.0", ] diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index b87d73490b..0f4dbda7d2 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -173,7 +173,7 @@ from CPAC.surface.surf_preproc import surface_falff from CPAC.surface.surf_preproc import surface_alff from CPAC.surface.surf_preproc import surface_reho -from CPAC.surface.surf_preproc import surface_connectivity_matrix +# from CPAC.surface.surf_preproc import surface_connectivity_matrix from CPAC.timeseries.timeseries_analysis import ( timeseries_extraction_AVG, @@ -1327,8 +1327,8 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if not rpool.check_rpool('surf-L_reho') or not rpool.check_rpool('surf-R_reho') : pipeline_blocks += [surface_reho] - if not rpool.check_rpool('surf-correlation_matrix'): - pipeline_blocks += [surface_connectivity_matrix] + # if not rpool.check_rpool('surf-correlation_matrix'): + # pipeline_blocks += [surface_connectivity_matrix] # Extractions and Derivatives tse_atlases, sca_atlases = gather_extraction_maps(cfg) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index f341c51ca2..c16ea9389f 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -952,30 +952,30 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs -def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): +# def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): - connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], - output_names=['parcellation_file'], - function=run_ciftiparcellate), - name=f'connectivity_parcellation{pipe_num}') - - connectivity_parcellation.inputs.subject = cfg['subject_id'] - node, out = strat_pool.get_data('space-fsLR_den-32k_bold') - wf.connect(node, out, connectivity, 'dtseries') - connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' - - correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], - output_names=['correlation_matrix'], - function=run_cifticorrelation), - name=f'correlation_matrix{pipe_num}') +# connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], +# output_names=['parcellation_file'], +# function=run_ciftiparcellate), +# name=f'connectivity_parcellation{pipe_num}') + +# connectivity_parcellation.inputs.subject = cfg['subject_id'] +# node, out = strat_pool.get_data('space-fsLR_den-32k_bold') +# wf.connect(node, out, connectivity, 'dtseries') +# connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' + +# correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], +# output_names=['correlation_matrix'], +# function=run_cifticorrelation), +# name=f'correlation_matrix{pipe_num}') - correlation_matrix.inputs.subject = cfg['subject_id'] - wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix, 'ptseries') +# correlation_matrix.inputs.subject = cfg['subject_id'] +# wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix, 'ptseries') - outputs = { - 'surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} +# outputs = { +# 'surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} - return wf, outputs +# return wf, outputs def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): @@ -1024,19 +1024,19 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_connectivity_matrix", - "config": ["seed_based_correlation_analysis"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold"], - "outputs": ["surf-correlation_matrix"]} - ''' - wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) +# def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): +# ''' +# {"name": "surface_connectivity_matrix", +# "config": ["timeseries_extraction","connectivity_matrix"], +# "switch": ["run"], +# "option_key": "using", +# "option_val": "AFNI", +# "inputs": ["space-fsLR_den-32k_bold"], +# "outputs": ["surf-correlation_matrix"]} +# ''' +# wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) - return (wf, outputs) +# return (wf, outputs) def run_surf_falff(subject,dtseries): import os @@ -1083,20 +1083,20 @@ def run_surf_reho(subject, dtseries, mask, cortex_file, surface_file,mean_timese log_subprocess(cmd) return surf_reho -def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): - import os - import subprocess - from CPAC.utils.monitoring.custom_logging import log_subprocess - parcellation_file = os.path.join(os.getcwd(), f'{subject}_parcellation.ptseries.nii') - cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] - log_subprocess(cmd) - return parcellation_file - -def run_cifticorrelation(subject, ptseries): - import os - import subprocess - from CPAC.utils.monitoring.custom_logging import log_subprocess - correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') - cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] - log_subprocess(cmd) - return correlation_matrix \ No newline at end of file +# def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): +# import os +# import subprocess +# from CPAC.utils.monitoring.custom_logging import log_subprocess +# parcellation_file = os.path.join(os.getcwd(), f'{subject}_parcellation.ptseries.nii') +# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] +# log_subprocess(cmd) +# return parcellation_file + +# def run_cifticorrelation(subject, ptseries): +# import os +# import subprocess +# from CPAC.utils.monitoring.custom_logging import log_subprocess +# correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') +# cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] +# log_subprocess(cmd) +# return correlation_matrix \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 1a18ebf62c..4c77c6bb26 100755 --- a/requirements.txt +++ b/requirements.txt @@ -28,3 +28,4 @@ traits==4.6.0 PyBASC==0.4.5 voluptuous>=0.12.0 ciftify +joblib==1.1.0 From fc3e4f324d62b5a527b312a0be1ce5eb5801437a Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 6 Mar 2023 17:54:53 -0500 Subject: [PATCH 025/213] :package: Rebuild wb_command in ABCD base image --- .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile index 24e4dfa586..7bc7b22fd9 100755 --- a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile +++ b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile @@ -2,7 +2,6 @@ FROM ghcr.io/fcp-indi/c-pac/afni:update.afni.binaries-bionic as AFNI FROM ghcr.io/fcp-indi/c-pac/ants:2.2.0.neurodocker-bionic as ANTs FROM ghcr.io/fcp-indi/c-pac/c3d:1.0.0-bionic as c3d -FROM ghcr.io/fcp-indi/c-pac/connectome-workbench:1.3.2-1.neurodebian-bionic as connectome-workbench FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-bionic as FreeSurfer FROM ghcr.io/fcp-indi/c-pac/fsl:5.0.10-bionic as FSL FROM ghcr.io/fcp-indi/c-pac/ica-aroma:0.4.3-beta-bionic as ICA-AROMA @@ -74,9 +73,14 @@ ENV MSMBINDIR=/opt/msm/Ubuntu \ PATH=$PATH:/opt/msm/Ubuntu # install Connectome Workbench -COPY --from=connectome-workbench /lib64/* /lib64. -COPY --from=connectome-workbench /lib/x86_64-linux-gnu/* /lib/x86_64-linux-gnu/ -COPY --from=connectome-workbench /usr/* /usr/ +RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC && \ + APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 648ACFD622F3D138 && \ + APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DCC9EFBF77E11517 && \ + printf '\ndeb http://httpredir.debian.org/debian/ buster main non-free' >> /etc/apt/sources.list && \ + apt-get update && \ + apt-get install connectome-workbench=1.3.2-1 -y && \ + strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 +ENV PATH=/usr:$PATH # install ICA-AROMA COPY --from=ICA-AROMA /opt/ICA-AROMA /opt/ICA-AROMA From 687bb989513cde276c85103bd4f113a1d3c3e109 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 14 Mar 2023 15:00:54 +0000 Subject: [PATCH 026/213] added node block for calculating surface based connectivity matrix --- CPAC/pipeline/cpac_pipeline.py | 6 +- CPAC/pipeline/schema.py | 2 +- CPAC/surface/surf_preproc.py | 104 ++++++++++++++++----------------- 3 files changed, 56 insertions(+), 56 deletions(-) diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index 0f4dbda7d2..cc7a8e58a9 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -173,7 +173,7 @@ from CPAC.surface.surf_preproc import surface_falff from CPAC.surface.surf_preproc import surface_alff from CPAC.surface.surf_preproc import surface_reho -# from CPAC.surface.surf_preproc import surface_connectivity_matrix +from CPAC.surface.surf_preproc import surface_connectivity_matrix from CPAC.timeseries.timeseries_analysis import ( timeseries_extraction_AVG, @@ -1327,8 +1327,8 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if not rpool.check_rpool('surf-L_reho') or not rpool.check_rpool('surf-R_reho') : pipeline_blocks += [surface_reho] - # if not rpool.check_rpool('surf-correlation_matrix'): - # pipeline_blocks += [surface_connectivity_matrix] + if not rpool.check_rpool('space-fsLR_den-32k_bold_surf-correlation_matrix'): + pipeline_blocks += [surface_connectivity_matrix] # Extractions and Derivatives tse_atlases, sca_atlases = gather_extraction_maps(cfg) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index c7f26fa5a6..1c513bd065 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -67,7 +67,7 @@ 'roi_paths': {'Avg', 'Voxel', 'SpatialReg'}, }, 'connectivity_matrix': { - 'using': {'AFNI', 'Nilearn', 'ndmg'}, + 'using': {'AFNI', 'Nilearn', 'ndmg','Surface'}, 'measure': {'Pearson', 'Partial', 'Spearman', 'MGC', # 'TangentEmbed' # "Skip tangent embedding for now" }, diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index c16ea9389f..85e8971726 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -914,7 +914,7 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): L_reho = pe.Node(util.Function(input_names=['subject', 'dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries','reho_filename', 'structure_name'], output_names=['L_reho'], function=run_surf_reho), - name=f'L_surf_reho{pipe_num}') + name=f'L_surf_reho_{pipe_num}') L_reho.inputs.subject = cfg['subject_id'] wf.connect(L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') @@ -932,7 +932,7 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): R_reho = pe.Node(util.Function(input_names=['subject','dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', 'reho_filename', 'structure_name'], output_names=['R_reho'], function=run_surf_reho), - name=f'R_surf_reho{pipe_num}') + name=f'R_surf_reho_{pipe_num}') R_reho.inputs.subject = cfg['subject_id'] wf.connect(R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') @@ -952,30 +952,30 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs -# def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): +def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): -# connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], -# output_names=['parcellation_file'], -# function=run_ciftiparcellate), -# name=f'connectivity_parcellation{pipe_num}') - -# connectivity_parcellation.inputs.subject = cfg['subject_id'] -# node, out = strat_pool.get_data('space-fsLR_den-32k_bold') -# wf.connect(node, out, connectivity, 'dtseries') -# connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' - -# correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], -# output_names=['correlation_matrix'], -# function=run_cifticorrelation), -# name=f'correlation_matrix{pipe_num}') + connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], + output_names=['parcellation_file'], + function=run_ciftiparcellate), + name=f'connectivity_parcellation{pipe_num}') + + connectivity_parcellation.inputs.subject = cfg['subject_id'] + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') + wf.connect(node, out, connectivity, 'dtseries') + connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' + + correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], + output_names=['correlation_matrix'], + function=run_cifticorrelation), + name=f'correlation_matrix{pipe_num}') -# correlation_matrix.inputs.subject = cfg['subject_id'] -# wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix, 'ptseries') + correlation_matrix.inputs.subject = cfg['subject_id'] + wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix, 'ptseries') -# outputs = { -# 'surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} + outputs = { + 'space-fsLR_den-32k_bold_surf-correlation_matrix': (correlation_matrix,'correlation_matrix')} -# return wf, outputs + return wf, outputs def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): @@ -1008,7 +1008,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): ''' - {"name": "ReHo", + {"name": "surface_reho", "config": ["regional_homogeneity"], "switch": ["run"], "option_key": "None", @@ -1024,19 +1024,19 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -# def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): -# ''' -# {"name": "surface_connectivity_matrix", -# "config": ["timeseries_extraction","connectivity_matrix"], -# "switch": ["run"], -# "option_key": "using", -# "option_val": "AFNI", -# "inputs": ["space-fsLR_den-32k_bold"], -# "outputs": ["surf-correlation_matrix"]} -# ''' -# wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) +def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "surface_connectivity_matrix", + "config": ["timeseries_extraction","connectivity_matrix"], + "switch": ["run"], + "option_key": "using", + "option_val": "Surface", + "inputs": ["space-fsLR_den-32k_bold"], + "outputs": ["space-fsLR_den-32k_bold_surf-correlation_matrix"]} + ''' + wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) -# return (wf, outputs) + return (wf, outputs) def run_surf_falff(subject,dtseries): import os @@ -1083,20 +1083,20 @@ def run_surf_reho(subject, dtseries, mask, cortex_file, surface_file,mean_timese log_subprocess(cmd) return surf_reho -# def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): -# import os -# import subprocess -# from CPAC.utils.monitoring.custom_logging import log_subprocess -# parcellation_file = os.path.join(os.getcwd(), f'{subject}_parcellation.ptseries.nii') -# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] -# log_subprocess(cmd) -# return parcellation_file - -# def run_cifticorrelation(subject, ptseries): -# import os -# import subprocess -# from CPAC.utils.monitoring.custom_logging import log_subprocess -# correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') -# cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] -# log_subprocess(cmd) -# return correlation_matrix \ No newline at end of file +def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): + import os + import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess + parcellation_file = os.path.join(os.getcwd(), f'{subject}_parcellation.ptseries.nii') + cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] + log_subprocess(cmd) + return parcellation_file + +def run_cifticorrelation(subject, ptseries): + import os + import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess + correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') + cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] + log_subprocess(cmd) + return correlation_matrix \ No newline at end of file From b70bf3495ff41fe0e2df4397a50267a2df1efea3 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 14 Mar 2023 18:52:34 +0000 Subject: [PATCH 027/213] Testing for error --- CPAC/pipeline/cpac_pipeline.py | 1 + CPAC/pipeline/engine.py | 4 ++++ CPAC/surface/surf_preproc.py | 11 ++++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index cc7a8e58a9..9e48d2a729 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -1390,6 +1390,7 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, # Connect the entire pipeline! try: wf = connect_pipeline(wf, cfg, rpool, pipeline_blocks) + print(rpool) except LookupError as lookup_error: errorstrings = lookup_error.args[0].split('\n') missing_key = errorstrings[ diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index ccf157fde0..bccef3014c 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -575,6 +575,7 @@ def get_strats(self, resources, debug=False): # strat_list is actually the merged CpacProvenance lists pipe_idx = str(strat_list) new_strats[pipe_idx] = ResourcePool() # <----- new_strats is A DICTIONARY OF RESOURCEPOOL OBJECTS! + # placing JSON info at one level higher only for copy convenience new_strats[pipe_idx].rpool['json'] = {} new_strats[pipe_idx].rpool['json']['subjson'] = {} @@ -1140,6 +1141,7 @@ def grab_tiered_dct(self, cfg, key_list): cfg_dct = cfg for key in key_list: cfg_dct = cfg_dct.__getitem__(key) + #print(key) return cfg_dct def connect_block(self, wf, cfg, rpool): @@ -1240,7 +1242,9 @@ def connect_block(self, wf, cfg, rpool): raise Exception("\n\n[!] Developer info: Docstring error " f"for {name}, make sure the 'config' or " "'switch' fields are lists.\n\n") + print(key_list) switch = self.grab_tiered_dct(cfg, key_list) + else: if isinstance(switch[0], list): # we have multiple switches, which is designed to only work if diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 85e8971726..e4344e6ccd 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -953,14 +953,15 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): - + + connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], output_names=['parcellation_file'], function=run_ciftiparcellate), name=f'connectivity_parcellation{pipe_num}') connectivity_parcellation.inputs.subject = cfg['subject_id'] - node, out = strat_pool.get_data('space-fsLR_den-32k_bold') + node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, connectivity, 'dtseries') connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' @@ -1021,21 +1022,21 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): "outputs": ["surf-L_reho", "surf-R_reho"]} ''' wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) - + return (wf, outputs) def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "surface_connectivity_matrix", "config": ["timeseries_extraction","connectivity_matrix"], - "switch": ["run"], + "switch": ["None"], "option_key": "using", "option_val": "Surface", "inputs": ["space-fsLR_den-32k_bold"], "outputs": ["space-fsLR_den-32k_bold_surf-correlation_matrix"]} ''' + raise Exception("Hello") wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) - return (wf, outputs) def run_surf_falff(subject,dtseries): From 02a52d1ae9ca33840e9370e1fec72f5e6c099aa1 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 20 Mar 2023 18:02:02 +0000 Subject: [PATCH 028/213] modifications made to schema and surface_preproc to test for surface_connectivity --- CPAC/pipeline/cpac_pipeline.py | 3 ++- CPAC/pipeline/engine.py | 9 ++++++--- CPAC/pipeline/schema.py | 5 ++++- CPAC/surface/surf_preproc.py | 17 +++++++++-------- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index 9e48d2a729..8ecf5e4bbc 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -1389,8 +1389,9 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, # Connect the entire pipeline! try: + wf = connect_pipeline(wf, cfg, rpool, pipeline_blocks) - print(rpool) + except LookupError as lookup_error: errorstrings = lookup_error.args[0].split('\n') missing_key = errorstrings[ diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index bccef3014c..998b7eb688 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -21,6 +21,7 @@ import copy import yaml + from CPAC.pipeline import \ nipype_pipeline_engine as pe # pylint: disable=ungrouped-imports from nipype.interfaces.utility import \ @@ -1140,8 +1141,11 @@ def check_output(self, outputs, label, name): def grab_tiered_dct(self, cfg, key_list): cfg_dct = cfg for key in key_list: - cfg_dct = cfg_dct.__getitem__(key) - #print(key) + try: + cfg_dct = cfg_dct.__getitem__(key) + #print(cfg_dct) + except KeyError: + raise Exception(f"[!] The config provided to the node block is not valid") return cfg_dct def connect_block(self, wf, cfg, rpool): @@ -1242,7 +1246,6 @@ def connect_block(self, wf, cfg, rpool): raise Exception("\n\n[!] Developer info: Docstring error " f"for {name}, make sure the 'config' or " "'switch' fields are lists.\n\n") - print(key_list) switch = self.grab_tiered_dct(cfg, key_list) else: diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 1c513bd065..a4bc3c3d0f 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -68,10 +68,11 @@ }, 'connectivity_matrix': { 'using': {'AFNI', 'Nilearn', 'ndmg','Surface'}, - 'measure': {'Pearson', 'Partial', 'Spearman', 'MGC', + 'measure': {'Pearson', 'Partial', 'Spearman', 'MGC' # 'TangentEmbed' # "Skip tangent embedding for now" }, }, + 'surface_connectivity': Any, 'Regressors': { 'CompCor': { 'degree': int, @@ -1024,6 +1025,8 @@ def _changes_1_8_0_to_1_8_1(config_dict): option: Maybe([In(valid_options['connectivity_matrix'][option])]) for option in ['using', 'measure'] }, + 'surface_connectivity': { + option: Maybe([In(valid_options['surface_connectivity'])]), }, 'seed_based_correlation_analysis': { 'run': bool, diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index e4344e6ccd..e5025bde47 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -958,17 +958,17 @@ def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], output_names=['parcellation_file'], function=run_ciftiparcellate), - name=f'connectivity_parcellation{pipe_num}') + name=f'connectivity_parcellation_{pipe_num}') connectivity_parcellation.inputs.subject = cfg['subject_id'] node, out = strat_pool.get_data('space-fsLR_den-32k_bold') - wf.connect(node, out, connectivity, 'dtseries') + wf.connect(node, out, connectivity_parcellation, 'dtseries') connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], output_names=['correlation_matrix'], function=run_cifticorrelation), - name=f'correlation_matrix{pipe_num}') + name=f'correlation_matrix_{pipe_num}') correlation_matrix.inputs.subject = cfg['subject_id'] wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix, 'ptseries') @@ -1028,17 +1028,18 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "surface_connectivity_matrix", - "config": ["timeseries_extraction","connectivity_matrix"], - "switch": ["None"], - "option_key": "using", - "option_val": "Surface", + "config": ["timeseries_extraction", "surface_connectivity"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", "inputs": ["space-fsLR_den-32k_bold"], "outputs": ["space-fsLR_den-32k_bold_surf-correlation_matrix"]} ''' - raise Exception("Hello") + wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) return (wf, outputs) + def run_surf_falff(subject,dtseries): import os import subprocess From acbb2aa7dd0ec38d4add8955195f78e18519aed4 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 20 Mar 2023 19:06:42 +0000 Subject: [PATCH 029/213] modified schema.py --- CPAC/pipeline/schema.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index a4bc3c3d0f..3ae7283541 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -72,7 +72,6 @@ # 'TangentEmbed' # "Skip tangent embedding for now" }, }, - 'surface_connectivity': Any, 'Regressors': { 'CompCor': { 'degree': int, @@ -1025,9 +1024,8 @@ def _changes_1_8_0_to_1_8_1(config_dict): option: Maybe([In(valid_options['connectivity_matrix'][option])]) for option in ['using', 'measure'] }, - 'surface_connectivity': { - option: Maybe([In(valid_options['surface_connectivity'])]), }, + 'surface_connectivity': {'run': bool}, 'seed_based_correlation_analysis': { 'run': bool, Optional('roi_paths_fully_specified'): bool, From b6228534dac645f6b2602fcc1ac2f54b25291db3 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 20 Mar 2023 19:27:03 +0000 Subject: [PATCH 030/213] modified surf_preproc.py --- CPAC/surface/surf_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index e5025bde47..bc3ff4a214 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -1028,7 +1028,7 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "surface_connectivity_matrix", - "config": ["timeseries_extraction", "surface_connectivity"], + "config": ["surface_connectivity"], "switch": ["run"], "option_key": "None", "option_val": "None", From f7cc028634272c60f8bd9bf9b7dbf40b75d60b8f Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 21 Mar 2023 12:53:02 -0400 Subject: [PATCH 031/213] :package: Fix bionic build --- .github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile | 9 ++++----- requirements.txt | 10 +--------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile index df8017c5d0..51db3dedcd 100755 --- a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile +++ b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile @@ -123,9 +123,10 @@ ENV PATH=/usr/bin/nvm/versions/node/v12.12.0/bin:/usr/local/miniconda/bin:$PATH # Installing conda dependencies, torch & Python dependencies COPY requirements.txt /opt/requirements.txt -RUN conda update conda -y && \ - conda install nomkl && \ - conda install -y \ +RUN conda install -n base conda-forge::mamba conda-forge::libarchive==3.5.2 -y && \ + mamba update conda -y && \ + mamba install nomkl -y && \ + mamba install -y \ blas \ cython \ matplotlib==3.1.3 \ @@ -133,9 +134,7 @@ RUN conda update conda -y && \ nose==1.3.7 \ numpy==1.16.4 \ pandas==1.0.5 \ - scipy==1.6.3 \ traits==4.6.0 \ - wxpython \ pip && \ pip install \ torch==1.2.0 torchvision==0.4.0 -f https://download.pytorch.org/whl/torch_stable.html && \ diff --git a/requirements.txt b/requirements.txt index c723e84c5e..aa7dbf8b2b 100755 --- a/requirements.txt +++ b/requirements.txt @@ -3,15 +3,11 @@ click==6.7 configparser==3.7.4 future==0.16.0 git+https://git@github.com/FCP-INDI/INDI-Tools.git#egg=INDI-Tools -joblib==1.0.1 +joblib==1.1.0 lockfile==0.12.2 matplotlib==3.1.3 networkx==2.4 -<<<<<<< HEAD nibabel==3.2.1 -======= -nibabel==3.0.1 ->>>>>>> 7f94c3a42f0c3eb7c76b15ac5591545d20e8a52f nilearn==0.4.1 nipype==1.5.1 nose==1.3.7 @@ -35,7 +31,3 @@ traits==4.6.0 PyBASC==0.4.5 voluptuous>=0.12.0 ciftify -<<<<<<< HEAD -joblib==1.1.0 -======= ->>>>>>> 7f94c3a42f0c3eb7c76b15ac5591545d20e8a52f From aa83f86d6d330573d7b62bea7e10aaa119fdfbbe Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 22 Mar 2023 16:01:58 +0000 Subject: [PATCH 032/213] removed two versions of joblib from info.py --- CPAC/info.py | 1 - CPAC/resources/configs/pipeline_config_default.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 4dface457e..39fc084388 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -178,7 +178,6 @@ def get_cpac_gitversion(): "future", "INDI-Tools", "lockfile==0.12.2", - "joblib==1.0.1", "matplotlib==3.1.3", "networkx==2.4", "nibabel==3.2.1", diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index a2b015bf17..f5c071624d 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1605,7 +1605,6 @@ timeseries_extraction: - Pearson - Partial - seed_based_correlation_analysis: # SCA - Seed-Based Correlation Analysis From 6cc108547a071fd90e11c391b0d45408fc7d697e Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 21 Mar 2023 12:53:02 -0400 Subject: [PATCH 033/213] :package: Fix bionic build --- .github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile | 11 +++++------ requirements.txt | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile index 49904badc6..87be21fe98 100755 --- a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile +++ b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile @@ -120,19 +120,18 @@ ENV PATH=/usr/bin/nvm/versions/node/v12.12.0/bin:/usr/local/miniconda/bin:$PATH # Installing conda dependencies, torch & Python dependencies COPY requirements.txt /opt/requirements.txt -RUN conda update conda -y && \ - conda install nomkl && \ - conda install -y \ +RUN conda install -n base conda-forge::mamba conda-forge::libarchive==3.5.2 -y && \ + mamba update conda -y && \ + mamba install nomkl -y && \ + mamba install -y \ blas \ cython \ matplotlib==3.1.3 \ networkx==2.4 \ nose==1.3.7 \ numpy==1.16.4 \ - pandas==0.23.4 \ - scipy==1.4.1 \ + pandas==1.0.5 \ traits==4.6.0 \ - wxpython \ pip && \ pip install \ torch==1.2.0 torchvision==0.4.0 -f https://download.pytorch.org/whl/torch_stable.html && \ diff --git a/requirements.txt b/requirements.txt index 4c77c6bb26..429bd30465 100755 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,7 @@ click==6.7 configparser==3.7.4 future==0.16.0 git+https://git@github.com/FCP-INDI/INDI-Tools.git#egg=INDI-Tools +joblib==1.1.0 lockfile==0.12.2 matplotlib==3.1.3 networkx==2.4 @@ -28,4 +29,3 @@ traits==4.6.0 PyBASC==0.4.5 voluptuous>=0.12.0 ciftify -joblib==1.1.0 From e8c9a206112be8a6622d84d853f5d246df8ea693 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 22 Mar 2023 16:01:58 +0000 Subject: [PATCH 034/213] removed two versions of joblib from info.py --- .../configs/pipeline_config_default.yml | 1808 +++++++++++++++++ 1 file changed, 1808 insertions(+) create mode 100644 CPAC/resources/configs/pipeline_config_default.yml diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml new file mode 100644 index 0000000000..f5c071624d --- /dev/null +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -0,0 +1,1808 @@ +%YAML 1.1 +--- +# CPAC Pipeline Configuration YAML file +# Version 1.8.5 +# +# http://fcp-indi.github.io for more info. +# +# Tip: This file can be edited manually with a text editor for quick modifications. + +pipeline_setup: + + # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths + pipeline_name: cpac-default-pipeline + + output_directory: + + # Directory where C-PAC should write out processed data, logs, and crash reports. + # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary + # name like '/outputs', and then map (-B/-v) your desired output directory to that label. + # - If running outside a container, this should be a full path to a directory. + path: /outputs/output + + # (Optional) Path to a BIDS-Derivatives directory that already has outputs. + # - This option is intended to ingress already-existing resources from an output + # directory without writing new outputs back into the same directory. + # - If provided, C-PAC will ingress the already-computed outputs from this directory and + # continue the pipeline from where they leave off. + # - If left as 'None', C-PAC will ingress any already-computed outputs from the + # output directory you provide above in 'path' instead, the default behavior. + source_outputs_dir: None + + # Set to True to make C-PAC ingress the outputs from the primary output directory if they + # exist, even if a source_outputs_dir is provided + # - Setting to False will pull from source_outputs_dir every time, over-writing any + # calculated outputs in the main output directory + # - C-PAC will still pull from source_outputs_dir if the main output directory is + # empty, however + pull_source_once: True + + # Include extra versions and intermediate steps of functional preprocessing in the output directory. + write_func_outputs: False + + # Include extra outputs in the output directory that may be of interest when more information is needed. + write_debugging_outputs: False + + # Output directory format and structure. + # Options: default, ndmg + output_tree: "default" + + # Quality control outputs + quality_control: + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: True + + # Generate eXtensible Connectivity Pipeline-style quality control files + generate_xcpqc_files: False + + working_directory: + + # Directory where C-PAC should store temporary and intermediate files. + # - This directory must be saved if you wish to re-run your pipeline from where you left off (if not completed). + # - NOTE: As it stores all intermediate files, this directory can grow to become very + # large, especially for data with a large amount of TRs. + # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary + # name like '/work', and then map (-B/-v) your desired output directory to that label. + # - If running outside a container, this should be a full path to a directory. + # - This can be written to '/tmp' if you do not intend to save your working directory. + path: /outputs/working + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: True + + log_directory: + + # Whether to write log details of the pipeline run to the logging files. + run_logging: True + + path: /outputs/logs + + # Configuration options for logging visualizations of the workflow graph + graphviz: + # Configuration for a graphviz visualization of the entire workflow. See https://fcp-indi.github.io/docs/developer/nodes#CPAC.pipeline.nipype_pipeline_engine.Workflow.write_graph for details about the various options + entire_workflow: + # Whether to generate the graph visualization + generate: Off + # Options: [orig, hierarchical, flat, exec, colored] + graph2use: [] + # Options: [svg, png] + format: [] + # The node name will be displayed in the form `nodename (package)` when On or `nodename.Class.package` when Off + simple_form: On + + crash_log_directory: + + # Directory where CPAC should write crash logs. + path: /outputs/crash + + system_config: + # Stop worklow execution on first crash? + fail_fast: Off + # Random seed used to fix the state of execution. + # If unset, each process uses its own default. + # If set, a `random.log` file will be generated logging the random seed and each node to which that seed was applied. + # If set to a positive integer (up to 2147483647), that integer will be used to seed each process that accepts a random seed. + # If set to 'random', a random positive integer (up to 2147483647) will be generated and that seed will be used to seed each process that accepts a random seed. + random_seed: + + # Select Off if you intend to run CPAC on a single machine. + # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. + on_grid: + + run: Off + + # Sun Grid Engine (SGE), Portable Batch System (PBS), or Simple Linux Utility for Resource Management (SLURM). + # Only applies if you are running on a grid or compute cluster. + resource_manager: SGE + + SGE: + # SGE Parallel Environment to use when running CPAC. + # Only applies when you are running on a grid or compute cluster using SGE. + parallel_environment: mpi_smp + + # SGE Queue to use when running CPAC. + # Only applies when you are running on a grid or compute cluster using SGE. + queue: all.q + + # The maximum amount of memory each participant's workflow can allocate. + # Use this to place an upper bound of memory usage. + # - Warning: 'Memory Per Participant' multiplied by 'Number of Participants to Run Simultaneously' + # must not be more than the total amount of RAM. + # - Conversely, using too little RAM can impede the speed of a pipeline run. + # - It is recommended that you set this to a value that when multiplied by + # 'Number of Participants to Run Simultaneously' is as much RAM you can safely allocate. + maximum_memory_per_participant: 1 + + # Prior to running a pipeline C-PAC makes a rough estimate of a worst-case-scenario maximum concurrent memory usage with high-resoltion data, raising an exception describing the recommended minimum memory allocation for the given configuration. + # Turning this option off will allow pipelines to run without allocating the recommended minimum, allowing for more efficient runs at the risk of out-of-memory crashes (use at your own risk) + raise_insufficient: On + + # A callback.log file from a previous run can be provided to estimate memory usage based on that run. + observed_usage: + # Path to callback log file with previously observed usage. + # Can be overridden with the commandline flag `--runtime_usage`. + callback_log: + # Percent. E.g., `buffer: 10` would estimate 1.1 * the observed memory usage from the callback log provided in "usage". + # Can be overridden with the commandline flag `--runtime_buffer`. + buffer: 10 + + # The maximum amount of cores (on a single machine) or slots on a node (on a cluster/grid) + # to allocate per participant. + # - Setting this above 1 will parallelize each participant's workflow where possible. + # If you wish to dedicate multiple cores to ANTS-based anatomical registration (below), + # this value must be equal or higher than the amount of cores provided to ANTS. + # - The maximum number of cores your run can possibly employ will be this setting multiplied + # by the number of participants set to run in parallel (the 'Number of Participants to Run + # Simultaneously' setting). + max_cores_per_participant: 1 + + # The number of cores to allocate to ANTS-based anatomical registration per participant. + # - Multiple cores can greatly speed up this preprocessing step. + # - This number cannot be greater than the number of cores per participant. + num_ants_threads: 1 + + # The number of cores to allocate to processes that use OpenMP. + num_OMP_threads: 1 + + # The number of participant workflows to run at the same time. + # - The maximum number of cores your run can possibly employ will be this setting + # multiplied by the number of cores dedicated to each participant (the 'Maximum Number of Cores Per Participant' setting). + num_participants_at_once: 1 + + # Full path to the FSL version to be used by CPAC. + # If you have specified an FSL path in your .bashrc file, this path will be set automatically. + FSLDIR: /usr/share/fsl/5.0 + + Amazon-AWS: + + # If setting the 'Output Directory' to an S3 bucket, insert the path to your AWS credentials file here. + aws_output_bucket_credentials: + + # Enable server-side 256-AES encryption on data to the S3 bucket + s3_encryption: False + + Debugging: + + # Verbose developer messages. + verbose: Off + + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + run_reconall: Off + + # Ingress freesurfer recon-all folder + ingress_reconall: Off + + # Add extra arguments to recon-all command + reconall_args: + + + # Run ABCD-HCP post FreeSurfer and fMRISurface pipeline + post_freesurfer: + + run: Off + + subcortical_gray_labels: /opt/dcan-tools/pipeline/global/config/FreeSurferSubcorticalLabelTableLut.txt + + freesurfer_labels: /opt/dcan-tools/pipeline/global/config/FreeSurferAllLut.txt + + surf_atlas_dir: /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases + + gray_ordinates_dir: /opt/dcan-tools/pipeline/global/templates/Greyordinates + + gray_ordinates_res: 2 + + high_res_mesh: 164 + + low_res_mesh: 32 + + fmri_res: 2 + + smooth_fwhm: 2 + + +longitudinal_template_generation: + + # If you have multiple T1w's, you can generate your own run-specific custom + # T1w template to serve as an intermediate to the standard template for + # anatomical registration. + + # This runs before the main pipeline as it requires multiple T1w sessions + # at once. + run: Off + + # Freesurfer longitudinal template algorithm using FSL FLIRT + # Method to average the dataset at each iteration of the template creation + # Options: median, mean or std + average_method: median + + # Degree of freedom for FLIRT in the template creation + # Options: 12 (affine), 9 (traditional), 7 (global rescale) or 6 (rigid body) + dof: 12 + + # Interpolation parameter for FLIRT in the template creation + # Options: trilinear, nearestneighbour, sinc or spline + interp: trilinear + + # Cost function for FLIRT in the template creation + # Options: corratio, mutualinfo, normmi, normcorr, leastsq, labeldiff or bbr + cost: corratio + + # Number of threads used for one run of the template generation algorithm + thread_pool: 2 + + # Threshold of transformation distance to consider that the loop converged + # (-1 means numpy.finfo(np.float64).eps and is the default) + convergence_threshold: -1 + + +anatomical_preproc: + + run: On + + run_t2: Off + + # Non-local means filtering via ANTs DenoiseImage + non_local_means_filtering: + + # this is a fork option + run: [Off] + + # options: 'Gaussian' or 'Rician' + noise_model: 'Gaussian' + + # N4 bias field correction via ANTs + n4_bias_field_correction: + + # this is a fork option + run: [Off] + + # An integer to resample the input image to save computation time. Shrink factors <= 4 are commonly used. + shrink_factor: 2 + + # Bias field correction based on square root of T1w * T2w + t1t2_bias_field_correction: + + run: Off + + BiasFieldSmoothingSigma: 5 + + acpc_alignment: + + run: Off + + # Run ACPC alignment before non-local means filtering or N4 bias + # correction + run_before_preproc: True + + # ACPC size of brain in z-dimension in mm. + # Default: 150mm for human data. + brain_size: 150 + + # Choose a tool to crop the FOV in ACPC alignment. + # Using FSL's robustfov or flirt command. + # Default: robustfov for human data, flirt for monkey data. + FOV_crop: robustfov + + # ACPC Target + # options: 'brain' or 'whole-head' + # note: 'brain' requires T1w_brain_ACPC_template below to be populated + acpc_target: 'whole-head' + + # Run ACPC alignment on brain mask + # If the brain mask is in native space, turn it on + # If the brain mask is ACPC aligned, turn it off + align_brain_mask: Off + + # ACPC aligned template + T1w_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm.nii.gz + T1w_brain_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm_brain.nii.gz + T2w_ACPC_template: None + T2w_brain_ACPC_template: None + + brain_extraction: + + run: On + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] + # this is a fork option + using: ['BET'] + + # option parameters + AFNI-3dSkullStrip: + + # Output a mask volume instead of a skull-stripped volume. The mask volume containes 0 to 6, which represents voxel's postion. If set to True, C-PAC will use this output to generate anatomical brain mask for further analysis. + mask_vol: False + + # Set the threshold value controlling the brain vs non-brain voxels. Default is 0.6. + shrink_factor: 0.6 + + # Vary the shrink factor at every iteration of the algorithm. This prevents the likelihood of surface getting stuck in large pools of CSF before reaching the outer surface of the brain. Default is On. + var_shrink_fac: True + + # The shrink factor bottom limit sets the lower threshold when varying the shrink factor. Default is 0.4, for when edge detection is used (which is On by default), otherwise the default value is 0.65. + shrink_factor_bot_lim: 0.4 + + # Avoids ventricles while skullstripping. + avoid_vent: True + + # Set the number of iterations. Default is 250.The number of iterations should depend upon the density of your mesh. + n_iterations: 250 + + # While expanding, consider the voxels above and not only the voxels below + pushout: True + + # Perform touchup operations at the end to include areas not covered by surface expansion. + touchup: True + + # Give the maximum number of pixels on either side of the hole that can be filled. The default is 10 only if 'Touchup' is On - otherwise, the default is 0. + fill_hole: 10 + + # Perform nearest neighbor coordinate interpolation every few iterations. Default is 72. + NN_smooth: 72 + + # Perform final surface smoothing after all iterations. Default is 20. + smooth_final: 20 + + # Avoid eyes while skull stripping. Default is On. + avoid_eyes: True + + # Use edge detection to reduce leakage into meninges and eyes. Default is On. + use_edge: True + + # Speed of expansion. + exp_frac: 0.1 + + # Perform aggressive push to edge. This might cause leakage. Default is Off. + push_to_edge: False + + # Use outer skull to limit expansion of surface into the skull in case of very strong shading artifacts. Use this only if you have leakage into the skull. + use_skull: Off + + # Percentage of segments allowed to intersect surface. It is typically a number between 0 and 0.1, but can include negative values (which implies no testing for intersection). + perc_int: 0 + + # Number of iterations to remove intersection problems. With each iteration, the program automatically increases the amount of smoothing to get rid of intersections. Default is 4. + max_inter_iter: 4 + + # Multiply input dataset by FAC if range of values is too small. + fac: 1 + + # Blur dataset after spatial normalization. Recommended when you have lots of CSF in brain and when you have protruding gyri (finger like). If so, recommended value range is 2-4. Otherwise, leave at 0. + blur_fwhm: 0 + + # Set it as True if processing monkey data with AFNI + monkey: False + + FSL-BET: + + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 + frac: 0.5 + + # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. + mask_boolean: On + + # Mesh created along with skull stripping + mesh_boolean: Off + + # Create a surface outline image + outline: Off + + # Add padding to the end of the image, improving BET.Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + padding: Off + + # Integer value of head radius + radius: 0 + + # Reduce bias and cleanup neck. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + reduce_bias: Off + + # Eyes and optic nerve cleanup. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + remove_eyes: Off + + # Robust brain center estimation. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + robust: On + + # Create a skull image + skull: Off + + # Gets additional skull and scalp surfaces by running bet2 and betsurf. This is mutually exclusive with reduce_bias, robust, padding, remove_eyes + surfaces: Off + + # Apply thresholding to segmented brain image and mask + threshold: Off + + # Vertical gradient in fractional intensity threshold (-1,1) + vertical_gradient : 0.0 + + UNet: + + # UNet model + unet_model : s3://fcp-indi/resources/cpac/resources/Site-All-T-epoch_36.model + + niworkflows-ants: + + # Template to be used during niworkflows-ants. + # It is not necessary to change this path unless you intend to use a non-standard template. + + # niworkflows-ants Brain extraction template + template_path : /ants_template/oasis/T_template0.nii.gz + + # niworkflows-ants probability mask + mask_path : /ants_template/oasis/T_template0_BrainCerebellumProbabilityMask.nii.gz + + # niworkflows-ants registration mask (can be optional) + regmask_path : /ants_template/oasis/T_template0_BrainCerebellumRegistrationMask.nii.gz + + FreeSurfer-BET: + + # Template to be used for FreeSurfer-BET brain extraction in CCS-options pipeline + T1w_brain_template_mask_ccs: /ccs_template/MNI152_T1_1mm_first_brain_mask.nii.gz + + +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + + tissue_segmentation: + + # using: ['FSL-FAST', 'Template_Based', 'ANTs_Prior_Based', 'FreeSurfer'] + # this is a fork point + using: ['FSL-FAST'] + + # option parameters + FSL-FAST: + + thresholding: + + # thresholding of the tissue segmentation probability maps + # options: 'Auto', 'Custom' + use: 'Auto' + + Custom: + # Set the threshold value for the segmentation probability masks (CSF, White Matter, and Gray Matter) + # The values remaining will become the binary tissue masks. + # A good starting point is 0.95. + + # CSF (cerebrospinal fluid) threshold. + CSF_threshold_value : 0.95 + + # White matter threshold. + WM_threshold_value : 0.95 + + # Gray matter threshold. + GM_threshold_value : 0.95 + + use_priors: + + # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. + run: On + + # Full path to a directory containing binarized prior probability maps. + # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use non-standard priors. + priors_path: $FSLDIR/data/standard/tissuepriors/2mm + + # Full path to a binarized White Matter prior probability map. + # It is not necessary to change this path unless you intend to use non-standard priors. + WM_path: $priors_path/avg152T1_white_bin.nii.gz + + # Full path to a binarized Gray Matter prior probability map. + # It is not necessary to change this path unless you intend to use non-standard priors. + GM_path: $priors_path/avg152T1_gray_bin.nii.gz + + # Full path to a binarized CSF prior probability map. + # It is not necessary to change this path unless you intend to use non-standard priors. + CSF_path: $priors_path/avg152T1_csf_bin.nii.gz + + Template_Based: + + # These masks should be in the same space of your registration template, e.g. if + # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. + # + # Options: ['T1_Template', 'EPI_Template'] + template_for_segmentation: ['T1_Template'] + + # These masks are included as part of the 'Image Resource Files' package available + # on the Install page of the User Guide. + + # Full path to a binarized White Matter mask. + WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz + + # Full path to a binarized Gray Matter mask. + GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz + + # Full path to a binarized CSF mask. + CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz + + ANTs_Prior_Based: + + # Generate white matter, gray matter, CSF masks based on antsJointLabelFusion + # ANTs Prior-based Segmentation workflow that has shown optimal results for non-human primate data. + + # The atlas image assumed to be used in ANTs Prior-based Segmentation. + template_brain_list : + - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_T1w_brain.nii.gz + - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_T1w_brain.nii.gz + + # The atlas segmentation images. + # For performing ANTs Prior-based segmentation method + # the number of specified segmentations should be identical to the number of atlas brain image sets. + # eg. + # ANTs_prior_seg_template_brain_list : + # - atlas1.nii.gz + # - atlas2.nii.gz + # ANTs_prior_seg_template_segmentation_list: + # - segmentation1.nii.gz + # - segmentation1.nii.gz + template_segmentation_list: + - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_Segmentation.nii.gz + - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_Segmentation.nii.gz + + # Label values corresponding to CSF/GM/WM in atlas file + # It is not necessary to change this values unless your CSF/GM/WM label values are different from Freesurfer Color Lookup Table. + # https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/AnatomicalROI/FreeSurferColorLUT + + # Label values corresponding to CSF in multiatlas file + CSF_label : [24] + + # Label values corresponding to Gray Matter in multiatlas file + GM_label : [3, 42] + + # Label values corresponding to White Matter in multiatlas file + WM_label : [2, 41] + + FreeSurfer: + + # Use mri_binarize --erode option to erode segmentation masks + erode: 0 + + # Label values corresponding to CSF in FreeSurfer aseg segmentation file + CSF_label : [24] + + # Label values corresponding to Gray Matter in FreeSurfer aseg segmentation file + GM_label : [3, 42] + + # Label values corresponding to White Matter in FreeSurfer aseg segmentation file + WM_label : [2, 41] + + +registration_workflows: + + anatomical_registration: + + run: On + + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + resolution_for_anat: 2mm + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + # Register skull-on anatomical image to a template. + reg_with_skull: True + + registration: + + # using: ['ANTS', 'FSL', 'FSL-linear'] + # this is a fork point + # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline + using: ['ANTS'] + + # option parameters + ANTs: + + # If a lesion mask is available for a T1w image, use it to improve the ANTs' registration + # ANTS registration only. + use_lesion_mask: False + + # ANTs parameters for T1-template-based registration + T1_registration: + + - collapse-output-transforms: 0 + - dimensionality: 3 + - initial-moving-transform : + initializationFeature: 0 + + - transforms: + - Rigid: + gradientStep : 0.1 + metric : + type : MI + metricWeight: 1 + numberOfBins : 32 + samplingStrategy : Regular + samplingPercentage : 0.25 + convergence: + iteration : 1000x500x250x100 + convergenceThreshold : 1e-08 + convergenceWindowSize : 10 + smoothing-sigmas : 3.0x2.0x1.0x0.0 + shrink-factors : 8x4x2x1 + use-histogram-matching : True + + - Affine: + gradientStep : 0.1 + metric : + type : MI + metricWeight: 1 + numberOfBins : 32 + samplingStrategy : Regular + samplingPercentage : 0.25 + convergence: + iteration : 1000x500x250x100 + convergenceThreshold : 1e-08 + convergenceWindowSize : 10 + smoothing-sigmas : 3.0x2.0x1.0x0.0 + shrink-factors : 8x4x2x1 + use-histogram-matching : True + + - SyN: + gradientStep : 0.1 + updateFieldVarianceInVoxelSpace : 3.0 + totalFieldVarianceInVoxelSpace : 0.0 + metric: + type : CC + metricWeight: 1 + radius : 4 + convergence: + iteration : 100x100x70x20 + convergenceThreshold : 1e-09 + convergenceWindowSize : 15 + smoothing-sigmas : 3.0x2.0x1.0x0.0 + shrink-factors : 6x4x2x1 + use-histogram-matching : True + winsorize-image-intensities : + lowerQuantile : 0.01 + upperQuantile : 0.99 + + # Interpolation method for writing out transformed anatomical images. + # Possible values: Linear, BSpline, LanczosWindowedSinc + interpolation: LanczosWindowedSinc + + FSL-FNIRT: + + # Configuration file to be used by FSL to set FNIRT parameters. + # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. + fnirt_config: T1_2_MNI152_2mm + + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + # specifically for monkey pipeline + ref_resolution: 2mm + + # Reference mask for FSL registration. + ref_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz + + # Template to be used during registration. + # It is for monkey pipeline specifically. + FNIRT_T1w_brain_template: None + + # Template to be used during registration. + # It is for monkey pipeline specifically. + FNIRT_T1w_template: None + + # Interpolation method for writing out transformed anatomical images. + # Possible values: trilinear, sinc, spline + interpolation: sinc + + # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask_dil.nii.gz + + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz + + overwrite_transform: + + run: Off + + # Choose the tool to overwrite transform, currently only support 'FSL' to overwrite 'ANTs' transforms in ABCD-options pipeline. + # using: 'FSL' + using: FSL + + functional_registration: + + coregistration: + # functional (BOLD/EPI) registration to anatomical (structural/T1) + + run: On + + # reference: 'brain' or 'restore-brain' + # In ABCD-options pipeline, 'restore-brain' is used as coregistration reference + reference: brain + + # Choose FSL or ABCD as coregistration method + using: FSL + + # Choose brain or whole-head as coregistration input + input: brain + + # Choose coregistration interpolation + interpolation: trilinear + + # Choose coregistration cost function + cost: corratio + + # Choose coregistration degree of freedom + dof: 6 + + # Extra arguments for FSL flirt + arguments: None + + func_input_prep: + + # Choose whether to use functional brain or skull as the input to functional-to-anatomical registration + reg_with_skull: Off + + # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. + # input: ['Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference'] + input: ['Mean_Functional'] + + Mean Functional: + + # Run ANTs’ N4 Bias Field Correction on the input BOLD (EPI) + # this can increase tissue contrast which may improve registration quality in some data + n4_correct_func: False + + Selected Functional Volume: + + # Only for when 'Use as Functional-to-Anatomical Registration Input' is set to 'Selected Functional Volume'. + #Input the index of which volume from the functional 4D timeseries input file you wish to use as the input for functional-to-anatomical registration. + func_reg_input_volume: 0 + + boundary_based_registration: + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # Standard FSL 5.0 Scheduler used for Boundary Based Registration. + # It is not necessary to change this path unless you intend to use non-standard MNI registration. + bbr_schedule: /usr/share/fsl/5.0/etc/flirtsch/bbr.sch + + # reference for boundary based registration + # options: 'whole-head' or 'brain' + reference: whole-head + + # choose which FAST map to generate BBR WM mask + # options: 'probability_map', 'partial_volume_map' + bbr_wm_map: 'probability_map' + + # optional FAST arguments to generate BBR WM mask + bbr_wm_mask_args: '-thr 0.5 -bin' + + EPI_registration: + + # directly register the mean functional to an EPI template + # instead of applying the anatomical T1-to-template transform to the functional data that has been + # coregistered to anatomical/T1 space + run: Off + + # using: ['ANTS', 'FSL', 'FSL-linear'] + # this is a fork point + # ex. selecting both ['ANTS', 'FSL'] will run both and fork the pipeline + using: ['ANTS'] + + # EPI template for direct functional-to-template registration + # (bypassing coregistration and the anatomical-to-template transforms) + EPI_template: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz + + # EPI template mask. + EPI_template_mask: None + + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + + - collapse-output-transforms: 0 + - dimensionality: 3 + - initial-moving-transform : + initializationFeature: 0 + + - transforms: + - Rigid: + gradientStep : 0.1 + metric : + type : MI + metricWeight: 1 + numberOfBins : 32 + samplingStrategy : Regular + samplingPercentage : 0.25 + convergence: + iteration : 1000x500x250x100 + convergenceThreshold : 1e-08 + convergenceWindowSize : 10 + smoothing-sigmas : 3.0x2.0x1.0x0.0 + shrink-factors : 8x4x2x1 + use-histogram-matching : True + + - Affine: + gradientStep : 0.1 + metric : + type : MI + metricWeight: 1 + numberOfBins : 32 + samplingStrategy : Regular + samplingPercentage : 0.25 + convergence: + iteration : 1000x500x250x100 + convergenceThreshold : 1e-08 + convergenceWindowSize : 10 + smoothing-sigmas : 3.0x2.0x1.0x0.0 + shrink-factors : 8x4x2x1 + use-histogram-matching : True + + - SyN: + gradientStep : 0.1 + updateFieldVarianceInVoxelSpace : 3.0 + totalFieldVarianceInVoxelSpace : 0.0 + metric: + type : CC + metricWeight: 1 + radius : 4 + convergence: + iteration : 100x100x70x20 + convergenceThreshold : 1e-09 + convergenceWindowSize : 15 + smoothing-sigmas : 3.0x2.0x1.0x0.0 + shrink-factors : 6x4x2x1 + use-histogram-matching : True + winsorize-image-intensities : + lowerQuantile : 0.01 + upperQuantile : 0.99 + + # Interpolation method for writing out transformed EPI images. + # Possible values: Linear, BSpline, LanczosWindowedSinc + interpolation: LanczosWindowedSinc + + FSL-FNIRT: + + # Configuration file to be used by FSL to set FNIRT parameters. + # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. + fnirt_config: T1_2_MNI152_2mm + + # Interpolation method for writing out transformed EPI images. + # Possible values: trilinear, sinc, spline + interpolation: sinc + + # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + + # apply the functional-to-template (EPI template) registration transform to the functional data + run_EPI: Off + + output_resolution: + + # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. + # NOTE: + # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. + # for most cases, 3 mm or 4 mm resolutions are suggested. + # NOTE: + # this also includes the single-volume 3D preprocessed functional data, + # such as the mean functional (mean EPI) in template space + func_preproc_outputs: 3mm + + # The resolution (in mm) to which the registered derivative outputs are written into. + # NOTE: + # this is for the single-volume functional-space outputs (i.e. derivatives) + # thus, a higher resolution may not result in a large increase in RAM needs as above + func_derivative_outputs: 3mm + + target_template: + # choose which template space to transform derivatives towards + # using: ['T1_template', 'EPI_template'] + # this is a fork point + # NOTE: + # this will determine which registration transform to use to warp the functional + # outputs and derivatives to template space + using: ['T1_template'] + + T1_template: + + # Standard Skull Stripped Template. Used as a reference image for functional registration. + # This can be different than the template used as the reference/fixed for T1-to-template registration. + T1w_brain_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz + + # Standard Anatomical Brain Image with Skull. + # This can be different than the template used as the reference/fixed for T1-to-template registration. + T1w_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}.nii.gz + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz + + # a standard template for resampling if using float resolution + T1w_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + EPI_template: + + # EPI template for direct functional-to-template registration + # (bypassing coregistration and the anatomical-to-template transforms) + EPI_template_funcreg: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz + + # EPI template mask. + EPI_template_mask_funcreg: None + + # a standard template for resampling if using float resolution + EPI_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + ANTs_pipelines: + + # Interpolation method for writing out transformed functional images. + # Possible values: Linear, BSpline, LanczosWindowedSinc + interpolation: LanczosWindowedSinc + + FNIRT_pipelines: + + # Interpolation method for writing out transformed functional images. + # Possible values: trilinear, sinc, spline + interpolation: sinc + + # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + apply_transform: + + # options: 'default', 'abcd', 'single_step_resampling_from_stc', 'dcan_nhp' + # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. + # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. + # 'single_step_resampling_from_stc': apply motion correction, func-to-anat and anat-to-template transforms on each of slice-time-corrected functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. + # - if 'single_step_resampling_from_stc', 'template' is the only valid option for ``nuisance_corrections: 2-nuisance_regression: space`` + using: 'default' + + +functional_preproc: + + run: On + + truncation: + + # First timepoint to include in analysis. + # Default is 0 (beginning of timeseries). + # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. + # Note: the selection here applies to all scans of all participants. + start_tr: 0 + + # Last timepoint to include in analysis. + # Default is None or End (end of timeseries). + # Last timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. + # Note: the selection here applies to all scans of all participants. + stop_tr: None + + scaling: + + # Scale functional raw data, usually used in rodent pipeline + run: Off + + # Scale the size of the dataset voxels by the factor. + scaling_factor: 10 + + despiking: + + # Run AFNI 3dDespike + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [Off] + + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # use specified slice time pattern rather than one in header + tpattern: None + + # align each slice to given time offset + # The default alignment time is the average of the 'tpattern' values (either from the dataset header or from the tpattern option). + tzero: None + + motion_estimates_and_correction: + + run: On + + motion_estimates: + + # calculate motion statistics BEFORE slice-timing correction + calculate_motion_first: Off + + # calculate motion statistics AFTER motion correction + calculate_motion_after: On + + motion_correction: + + # using: ['3dvolreg', 'mcflirt'] + # this is a fork point + using: ['3dvolreg'] + + # option parameters + AFNI-3dvolreg: + + # This option is useful when aligning high-resolution datasets that may need more alignment than a few voxels. + functional_volreg_twopass: On + + # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference + motion_correction_reference: ['mean'] + + # Choose motion correction reference volume + motion_correction_reference_volume: 0 + + motion_estimate_filter: + + # Filter physiological (respiration) artifacts from the head motion estimates. + # Adapted from DCAN Labs filter. + # https://www.ohsu.edu/school-of-medicine/developmental-cognition-and-neuroimaging-lab + # https://www.biorxiv.org/content/10.1101/337360v1.full.pdf + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [Off] + + filters: + - # options: "notch", "lowpass" + filter_type: "notch" + + # Number of filter coefficients. + filter_order: 4 + + # Dataset-wide respiratory rate data from breathing belt. + # Notch filter requires either: + # "breathing_rate_min" and "breathing_rate_max" + # or + # "center_frequency" and "filter_bandwitdh". + # Lowpass filter requires either: + # "breathing_rate_min" + # or + # "lowpass_cutoff". + # If "breathing_rate_min" (for lowpass and notch filter) + # and "breathing_rate_max" (for notch filter) are set, + # the values set in "lowpass_cutoff" (for lowpass filter), + # "center_frequency" and "filter_bandwidth" (for notch filter) + # options are ignored. + + # Lowest Breaths-Per-Minute in dataset. + # For both notch and lowpass filters. + breathing_rate_min: + + # Highest Breaths-Per-Minute in dataset. + # For notch filter. + breathing_rate_max: + + # notch filter direct customization parameters + + # mutually exclusive with breathing_rate options above. + # If breathing_rate_min and breathing_rate_max are provided, + # the following parameters will be ignored. + + # the center frequency of the notch filter + center_frequency: + + # the width of the notch filter + filter_bandwidth: + + - # options: "notch", "lowpass" + filter_type: "lowpass" + + # Number of filter coefficients. + filter_order: 4 + + # Dataset-wide respiratory rate data from breathing belt. + # Notch filter requires either: + # "breathing_rate_min" and "breathing_rate_max" + # or + # "center_frequency" and "filter_bandwitdh". + # Lowpass filter requires either: + # "breathing_rate_min" + # or + # "lowpass_cutoff". + # If "breathing_rate_min" (for lowpass and notch filter) + # and "breathing_rate_max" (for notch filter) are set, + # the values set in "lowpass_cutoff" (for lowpass filter), + # "center_frequency" and "filter_bandwidth" (for notch filter) + # options are ignored. + + # Lowest Breaths-Per-Minute in dataset. + # For both notch and lowpass filters. + breathing_rate_min: + + # lowpass filter direct customization parameter + + # mutually exclusive with breathing_rate options above. + # If breathing_rate_min is provided, the following + # parameter will be ignored. + + # the frequency cutoff of the filter + lowpass_cutoff: + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] + # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. + # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. + using: ['PhaseDiff', 'Blip'] + + # option parameters + PhaseDiff: + + # Since the quality of the distortion heavily relies on the skull-stripping step, we provide a choice of method ('AFNI' for AFNI 3dSkullStrip or 'BET' for FSL BET). + # Options: 'BET' or 'AFNI' + fmap_skullstrip_option: 'BET' + + # Set the fraction value for the skull-stripping of the magnitude file. Depending on the data, a tighter extraction may be necessary in order to prevent noisy voxels from interfering with preparing the field map. + # The default value is 0.5. + fmap_skullstrip_BET_frac: 0.5 + + # Set the threshold value for the skull-stripping of the magnitude file. Depending on the data, a tighter extraction may be necessary in order to prevent noisy voxels from interfering with preparing the field map. + # The default value is 0.6. + fmap_skullstrip_AFNI_threshold: 0.6 + + Blip-FSL-TOPUP: + + # (approximate) resolution (in mm) of warp basis for the different sub-sampling levels, default 10 + warpres: 10 + + # sub-sampling scheme, default 1 + subsamp: 1 + + # FWHM (in mm) of gaussian smoothing kernel, default 8 + fwhm: 8 + + # Max # of non-linear iterations, default 5 + miter: 5 + + # Weight of regularisation, default depending on --ssqlambda and --regmod switches. See user documentation. + lambda: 1 + + # If set (=1), lambda is weighted by current ssq, default 1 + ssqlambda: 1 + + # Model for regularisation of warp-field [membrane_energy bending_energy], default bending_energy + regmod: bending_energy + + # Estimate movements if set, default 1 (true) + estmov: 1 + + # Minimisation method 0=Levenberg-Marquardt, 1=Scaled Conjugate Gradient, default 0 (LM) + minmet: 0 + + # Order of spline, 2->Qadratic spline, 3->Cubic spline. Default=3 + splineorder: 3 + + # Precision for representing Hessian, double or float. Default double + numprec: double + + # Image interpolation model, linear or spline. Default spline + interp: spline + + # If set (=1), the images are individually scaled to a common mean, default 0 (false) + scale: 0 + + # If set (=1), the calculations are done in a different grid, default 1 (true) + regrid: 1 + + func_masking: + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. + + # this is a fork point + using: ['AFNI'] + + FSL-BET: + + # Apply to 4D FMRI data, if bold_bet_functional_mean_boolean : Off. + # Mutually exclusive with functional, reduce_bias, robust, padding, remove_eyes, surfaces + # It must be 'on' if select 'reduce_bias', 'robust', 'padding', 'remove_eyes', or 'bet_surfaces' on + functional_mean_boolean: Off + + # Set an intensity threshold to improve skull stripping performances of FSL BET on rodent scans. + functional_mean_thr: + run: Off + threshold_value: 98 + + # Bias correct the functional mean image to improve skull stripping performances of FSL BET on rodent scans + functional_mean_bias_correction: Off + + # Set the threshold value controling the brain vs non-brain voxels. + frac: 0.3 + + # Mesh created along with skull stripping + mesh_boolean: Off + + # Create a surface outline image + outline: Off + + # Add padding to the end of the image, improving BET.Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + padding: Off + + # Integer value of head radius + radius: 0 + + # Reduce bias and cleanup neck. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + reduce_bias: Off + + # Eyes and optic nerve cleanup. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + remove_eyes: Off + + # Robust brain center estimation. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces + robust: Off + + # Create a skull image + skull: Off + + # Gets additional skull and scalp surfaces by running bet2 and betsurf. This is mutually exclusive with reduce_bias, robust, padding, remove_eyes + surfaces: Off + + # Apply thresholding to segmented brain image and mask + threshold: Off + + # Vertical gradient in fractional intensity threshold (-1,1) + vertical_gradient: 0.0 + + FSL_AFNI: + + bold_ref: + + brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + Anatomical_Refined: + + # Choose whether or not to dilate the anatomical mask if you choose 'Anatomical_Refined' as the functional masking option. It will dilate one voxel if enabled. + anatomical_mask_dilation: False + + # Apply functional mask in native space + apply_func_mask_in_native_space: On + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + + +nuisance_corrections: + + 1-ICA-AROMA: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [Off] + + # Types of denoising strategy: + # nonaggr: nonaggressive-partial component regression + # aggr: aggressive denoising + denoising_type: nonaggr + + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # this is a fork point + # Run nuisance regression in native or template space + # - If set to [native, template], the number of outputs will be double what it would be if only one space were chosen. Nuisance regression will only be run once per fork. + # - If set to template, will use the brain mask configured in + # ``functional_preproc: func_masking: FSL_AFNI: brain_mask`` + # - If ``registration_workflows: functional_registration: func_registration_to_template: apply_trasnform: using: single_step_resampling_from_stc``, this must only be set to template + space: [native] + + # switch to Off if nuisance regression is off and you don't want to write out the regressors + create_regressors: On + + # Select which nuisance signal corrections to apply + Regressors: + + - Name: 'default' + + Motion: + include_delayed: true + include_squared: true + include_delayed_squared: true + + aCompCor: + summary: + method: DetrendPC + components: 5 + tissues: + - WhiteMatter + - CerebrospinalFluid + extraction_resolution: 2 + + CerebrospinalFluid: + summary: Mean + extraction_resolution: 2 + erode_mask: true + + GlobalSignal: + summary: Mean + + PolyOrt: + degree: 2 + + Bandpass: + bottom_frequency: 0.01 + top_frequency: 0.1 + method: default + + - Name: 'defaultNoGSR' + + Motion: + include_delayed: true + include_squared: true + include_delayed_squared: true + + aCompCor: + summary: + method: DetrendPC + components: 5 + tissues: + - WhiteMatter + - CerebrospinalFluid + extraction_resolution: 2 + + CerebrospinalFluid: + summary: Mean + extraction_resolution: 2 + erode_mask: true + + PolyOrt: + degree: 2 + + Bandpass: + bottom_frequency: 0.01 + top_frequency: 0.1 + method: default + + # Standard Lateral Ventricles Binary Mask + # used in CSF mask refinement for CSF signal-related regressions + lateral_ventricles_mask: $FSLDIR/data/atlases/HarvardOxford/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz + + # Whether to run frequency filtering before or after nuisance regression. + # Options: 'After' or 'Before' + bandpass_filtering_order: 'After' + + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + + erode_anatomical_brain_mask: + + # Erode binarized anatomical brain mask. If choosing True, please also set regressor_masks['erode_csf']['run']: True; anatomical_preproc['brain_extraction']['using']: niworkflows-ants. + run: Off + + # Target volume ratio, if using erosion. + # Default proportion is None for anatomical brain mask. + # If using erosion, using both proportion and millimeters is not recommended. + brain_mask_erosion_prop: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + # Erode binarized brain mask in millimeter + brain_erosion_mm: + + erode_csf: + + # Erode binarized csf tissue mask. + run: Off + + # Target volume ratio, if using erosion. + # Default proportion is None for cerebrospinal fluid mask. + # If using erosion, using both proportion and millimeters is not recommended. + csf_erosion_prop: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + # Erode binarized cerebrospinal fluid mask in millimeter + csf_erosion_mm: + + erode_wm: + + # Erode WM binarized tissue mask. + run: Off + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + # Erode white matter mask in millimeters, default for white matter is None + wm_mask_erosion_mm: + + # Erode binarized white matter mask in millimeters + wm_erosion_mm: + + erode_gm: + + # Erode gray matter binarized tissue mask. + run: Off + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + # Erode gray matter mask in millimeters + gm_mask_erosion_mm: + + # Erode binarized gray matter mask in millimeters + gm_erosion_mm: + + +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + + spatial_smoothing: + + run: On + + # Smooth the derivative outputs. + # Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both. + # + # Options: + # ['smoothed', 'nonsmoothed'] + output: ['smoothed'] + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided + smoothing_method: ['FSL'] + + # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. + # this is a fork point + # i.e. multiple kernels - fwhm: [4,6,8] + fwhm: [4] + + z-scoring: + + run: On + + # z-score standardize the derivatives. This may be needed for group-level analysis. + # Set as ['raw'] to disable z-scoring. Set as ['z-scored', 'raw'] to get both. + # + # Options: + # ['z-scored', 'raw'] + output: ['z-scored'] + + +timeseries_extraction: + + run: On + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg + tse_roi_paths: + /cpac_templates/CC400.nii.gz: Avg + /cpac_templates/aal_mask_pad.nii.gz: Avg + /cpac_templates/CC200.nii.gz: Avg + /cpac_templates/tt_mask_pad.nii.gz: Avg + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: SpatialReg + /cpac_templates/ho_mask_pad.nii.gz: Avg + /cpac_templates/rois_3mm.nii.gz: Avg + /ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/CAPRSC_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/DKT_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/DesikanKlein_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/MICCAI_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-1000Parcels17NetworksOrder.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-200Parcels17NetworksOrder.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-300Parcels17NetworksOrder.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-400Parcels17NetworksOrder.nii.gz: Avg + /ndmg_atlases/label/Human/Talairach_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Desikan_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + + # Functional time-series and ROI realignment method: ['ROI_to_func'] or ['func_to_ROI'] + # 'ROI_to_func' will realign the atlas/ROI to functional space (fast) + # 'func_to_ROI' will realign the functional time series to the atlas/ROI space + # + # NOTE: in rare cases, realigning the ROI to the functional space may + # result in small misalignments for very small ROIs - please double + # check your data if you see issues + realignment: 'ROI_to_func' + + connectivity_matrix: + # Create a connectivity matrix from timeseries data + + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: + - Nilearn + - ndmg + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: + - Pearson + - Partial + +seed_based_correlation_analysis: + + # SCA - Seed-Based Correlation Analysis + # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. + # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. + run: Off + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + /cpac_templates/CC400.nii.gz: Avg, MultReg + /cpac_templates/ez_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/aal_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/CC200.nii.gz: Avg, MultReg + /cpac_templates/tt_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/ho_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/rois_3mm.nii.gz: Avg, MultReg + + # Normalize each time series before running Dual Regression SCA. + norm_timeseries_for_DR: True + + +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: ['Native'] + + # Frequency cutoff (in Hz) for the high-pass filter used when calculating f/ALFF. + highpass_cutoff: [0.01] + + # Frequency cutoff (in Hz) for the low-pass filter used when calculating f/ALFF + lowpass_cutoff: [0.1] + + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On + + # space: Template or Native + target_space: ['Native'] + + # Number of neighboring voxels used when calculating ReHo + # 7 (Faces) + # 19 (Faces + Edges) + # 27 (Faces + Edges + Corners) + cluster_size: 27 + + +voxel_mirrored_homotopic_connectivity: + + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + + symmetric_registration: + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_brain_template_symmetric_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain_symmetric.nii.gz + + # A reference symmetric brain template for resampling + T1w_brain_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_symmetric.nii.gz + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_template_symmetric_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_symmetric.nii.gz + + # A reference symmetric skull template for resampling + T1w_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_symmetric.nii.gz + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz + + # A reference symmetric brain mask template for resampling + dilated_symmetric_brain_mask_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_mask_symmetric_dil.nii.gz + + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On + + # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. + # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. + memory_allocation: 1.0 + + # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. + template_specification_file: /cpac_templates/Mask_ABIDE_85Percent_GM.nii.gz + + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: ['Binarized', 'Weighted'] + + # Select the type of threshold used when creating the degree centrality adjacency matrix. + # options: + # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' + correlation_threshold_option: 'Sparsity threshold' + + # Based on the Threshold Type selected above, enter a Threshold Value. + # P-value for Significance Threshold + # Sparsity value for Sparsity Threshold + # Pearson's r value for Correlation Threshold + correlation_threshold: 0.001 + + eigenvector_centrality: + + # Enable/Disable eigenvector centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: ['Weighted'] + + # Select the type of threshold used when creating the eigenvector centrality adjacency matrix. + # options: + # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' + correlation_threshold_option: 'Sparsity threshold' + + # Based on the Threshold Type selected above, enter a Threshold Value. + # P-value for Significance Threshold + # Sparsity value for Sparsity Threshold + # Pearson's r value for Correlation Threshold + correlation_threshold: 0.001 + + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: ['Binarized', 'Weighted'] + + # Select the type of threshold used when creating the lFCD adjacency matrix. + # options: + # 'Significance threshold', 'Correlation threshold' + correlation_threshold_option: 'Correlation threshold' + + # Based on the Threshold Type selected above, enter a Threshold Value. + # P-value for Significance Threshold + # Sparsity value for Sparsity Threshold + # Pearson's r value for Correlation Threshold + correlation_threshold: 0.6 + + +# PACKAGE INTEGRATIONS +# -------------------- +PyPEER: + + # Training of eye-estimation models. Commonly used for movies data/naturalistic viewing. + run: Off + + # PEER scan names to use for training + # Example: ['peer_run-1', 'peer_run-2'] + eye_scan_names: [] + + # Naturalistic viewing data scan names to use for eye estimation + # Example: ['movieDM'] + data_scan_names: [] + + # Template-space eye mask + eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz + + # PyPEER Stimulus File Path + # This is a file describing the stimulus locations from the calibration sequence. + stimulus_path: None + + minimal_nuisance_correction: + + # PyPEER Minimal nuisance regression + # Note: PyPEER employs minimal preprocessing - these choices do not reflect what runs in the main pipeline. + # PyPEER uses non-nuisance-regressed data from the main pipeline. + + # Global signal regression (PyPEER only) + peer_gsr: True + + # Motion scrubbing (PyPEER only) + peer_scrub: False + + # Motion scrubbing threshold (PyPEER only) + scrub_thresh: 0.2 From 0bf991ebc047902e8b075f9fc2e46aa4c8a57861 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 20 Mar 2023 20:26:50 +0000 Subject: [PATCH 035/213] updated branch --- .circleci/main.yml | 2 +- ...AFNI.16.2.07.neurodocker-xenial.Dockerfile | 1 + .../AFNI.20.0.04-bionic.Dockerfile | 40 - ...kerfile => AFNI.21.1.00-bionic.Dockerfile} | 17 +- .../ANTs.2.2.0.neurodocker-bionic.Dockerfile | 12 +- .../ANTs.2.3.4.neurodocker-xenial.Dockerfile | 4 +- .../Dockerfiles/ANTs.2.3.5-bionic.Dockerfile | 63 - .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 4 +- .../C-PAC.develop-bionic.Dockerfile | 4 +- ...PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 4 +- .../C-PAC.develop-lite-bionic.Dockerfile | 1 + .../Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 1 + .../FSL.5.0.9-5.neurodebian-xenial.Dockerfile | 25 +- .../FSL.neurodebian-bionic.Dockerfile | 45 - ...er.6.0.0-min.neurodocker-bionic.Dockerfile | 11 +- .../FreeSurfer.6.0.1-min-xenial.Dockerfile | 1 + .../FreeSurfer.6.0.1-xenial.Dockerfile | 1 + .../ICA-AROMA.0.4.5-xenial.Dockerfile | 1 + .../Ubuntu.bionic-non-free.Dockerfile | 16 +- .../Ubuntu.xenial-20200114.Dockerfile | 18 +- .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 6 +- .../Dockerfiles/base-fMRIPrep-LTS.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 28 +- .../Dockerfiles/c3d.1.0.0-bionic.Dockerfile | 11 +- .../Dockerfiles/c3d.1.0.0-xenial.Dockerfile | 21 +- ...ench.1.3.2-1.neurodebian-bionic.Dockerfile | 1 + ...ench.1.3.2-2.neurodebian-xenial.Dockerfile | 1 + ...kbench.1.5.0.neurodebian-bionic.Dockerfile | 1 + .github/Dockerfiles/msm.2.0-bionic.Dockerfile | 13 +- .github/scripts/get_package_id.py | 30 +- .github/stage_requirements/ABCD-HCP.txt | 3 +- .github/stage_requirements/fMRIPrep-LTS.txt | 1 - .github/stage_requirements/standard.txt | 2 +- .github/workflows/build_C-PAC.yml | 7 +- .github/workflows/build_and_test.yml | 5 + .github/workflows/build_stages.yml | 73 +- ...rsion.yml => check_updated_preconfigs.yml} | 72 +- .github/workflows/delete_images.yml | 8 + .github/workflows/deploy_to_Docker_Hub.yml | 17 +- .github/workflows/smoke_test_participant.yml | 57 +- .gitignore | 3 - .pylintrc | 11 +- CHANGELOG.md | 57 + CONTRIBUTING.md | 11 + CPAC/alff/alff.py | 47 +- CPAC/anat_preproc/anat_preproc.py | 882 ++++--- CPAC/anat_preproc/utils.py | 32 +- CPAC/connectome/connectivity_matrix.py | 36 +- CPAC/cwas/cwas.py | 48 +- CPAC/cwas/mdmr.py | 10 +- CPAC/cwas/pipeline.py | 31 +- .../distortion_correction.py | 257 ++- CPAC/distortion_correction/utils.py | 57 +- CPAC/easy_thresh/easy_thresh.py | 14 +- CPAC/func_preproc/func_ingress.py | 194 +- CPAC/func_preproc/func_preproc.py | 309 +-- CPAC/func_preproc/utils.py | 2 +- CPAC/image_utils/__init__.py | 24 +- CPAC/image_utils/spatial_smoothing.py | 28 +- CPAC/image_utils/statistical_transforms.py | 21 +- CPAC/info.py | 18 +- .../longitudinal_workflow.py | 28 +- CPAC/network_centrality/network_centrality.py | 6 +- CPAC/network_centrality/pipeline.py | 67 +- CPAC/network_centrality/utils.py | 61 +- CPAC/nuisance/nuisance.py | 672 +++--- CPAC/pipeline/__init__.py | 1 + CPAC/pipeline/check_outputs.py | 104 +- CPAC/pipeline/cpac_group_runner.py | 310 ++- CPAC/pipeline/cpac_pipeline.py | 316 ++- CPAC/pipeline/cpac_runner.py | 174 +- CPAC/pipeline/engine.py | 399 +++- .../nipype_pipeline_engine/__init__.py | 43 +- .../pipeline/nipype_pipeline_engine/engine.py | 415 +++- CPAC/pipeline/random_state/seed.py | 44 +- CPAC/pipeline/schema.py | 715 +++--- CPAC/pipeline/test/test_cpac_runner.py | 5 +- CPAC/pipeline/test/test_engine.py | 12 +- CPAC/pipeline/test/test_schema_validation.py | 64 +- CPAC/pipeline/utils.py | 90 + CPAC/qc/pipeline.py | 164 +- CPAC/qc/tests/test_qc.py | 11 +- CPAC/qc/xcp.py | 62 +- CPAC/randomise/randomise.py | 2 +- CPAC/registration/registration.py | 2056 ++++++++++------- CPAC/registration/tests/mocks.py | 7 +- CPAC/reho/reho.py | 45 +- .../configs/data_config_S3-BIDS-ABIDE.yml | 2 +- .../configs/data_config_S3-BIDS-ADHD200.yml | 2 +- .../data_config_S3-BIDS-ADHD200_only2.yml | 2 +- ...data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- .../configs/data_config_cpac_benchmark.yml | 2 +- .../configs/data_settings_template.yml | 2 +- .../configs/group_config_template.yml | 450 ++-- .../configs/pipeline_config_abcd-options.yml | 338 +-- .../configs/pipeline_config_anat-only.yml | 190 +- .../pipeline_config_benchmark-ANTS.yml | 303 ++- .../pipeline_config_benchmark-FNIRT.yml | 327 ++- .../configs/pipeline_config_blank.yml | 1279 +++++----- .../configs/pipeline_config_ccs-options.yml | 261 ++- .../pipeline_config_default-deprecated.yml | 222 ++ .../pipeline_config_fmriprep-options.yml | 434 ++-- .../configs/pipeline_config_fx-options.yml | 70 +- .../configs/pipeline_config_monkey-ABCD.yml | 522 +++-- .../configs/pipeline_config_monkey.yml | 438 ++-- .../configs/pipeline_config_ndmg.yml | 291 ++- .../configs/pipeline_config_nhp-macaque.yml | 19 +- .../configs/pipeline_config_preproc.yml | 148 +- .../configs/pipeline_config_rbc-options.yml | 346 +-- .../configs/pipeline_config_regtest-1.yml | 305 ++- .../configs/pipeline_config_regtest-2.yml | 335 ++- .../configs/pipeline_config_regtest-3.yml | 389 +++- .../configs/pipeline_config_regtest-4.yml | 376 ++- .../configs/pipeline_config_rodent.yml | 391 ++-- CPAC/resources/configs/system_config.yml | 2 +- .../test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../data-test_S3-ADHD200_no-params.yml | 2 +- .../test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../data_config_S3_CoRR_5only_mult-sess.yml | 2 +- .../configs/test_configs/pipe-test_ABCD.yml | 2 +- .../pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_all.yml | 2 +- CPAC/resources/cpac_outputs.tsv | 130 +- CPAC/resources/cpac_templates.csv | 6 +- CPAC/resources/templates/BIDS_identifiers.tsv | 31 + CPAC/resources/templates/__init__.py | 4 + CPAC/resources/templates/lookup_table.py | 87 + CPAC/resources/tests/test_permissions.py | 29 + CPAC/sca/sca.py | 87 +- CPAC/seg_preproc/seg_preproc.py | 194 +- CPAC/surface/__init__.py | 0 .../fMRISurface/SubcorticalProcessing.sh | 2 +- CPAC/surface/globals.py | 5 + CPAC/surface/surf_preproc.py | 64 +- CPAC/surface/tests/test_config.py | 2 +- CPAC/timeseries/timeseries_analysis.py | 142 +- CPAC/utils/__init__.py | 17 +- CPAC/utils/bids_utils.py | 287 ++- CPAC/utils/build_data_config.py | 53 +- CPAC/utils/configuration/__init__.py | 24 + .../{ => configuration}/configuration.py | 310 ++- CPAC/utils/configuration/diff.py | 224 ++ CPAC/utils/configuration/yaml_template.py | 513 ++++ CPAC/utils/datasource.py | 324 ++- CPAC/utils/datatypes.py | 35 + CPAC/utils/docs.py | 11 +- CPAC/utils/monitoring/__init__.py | 10 +- CPAC/utils/monitoring/config.py | 7 +- CPAC/utils/monitoring/custom_logging.py | 27 +- CPAC/utils/monitoring/draw_gantt_chart.py | 49 +- CPAC/utils/outputs.py | 26 +- CPAC/utils/serialization/__init__.py | 3 + CPAC/utils/serialization/core.py | 39 + CPAC/utils/serialization/workflow_json.py | 128 + CPAC/utils/serialization/workflow_pickle.py | 19 + CPAC/utils/strategy.py | 36 +- CPAC/utils/test_mocks.py | 7 +- CPAC/utils/tests/configs/__init__.py | 14 + CPAC/utils/tests/configs/neurostars_23786.yml | 4 + CPAC/utils/tests/configs/neurostars_24035.yml | 293 +++ CPAC/utils/tests/test_bids_utils.py | 2 +- CPAC/utils/tests/test_yaml.py | 88 +- CPAC/utils/utils.py | 401 +++- CPAC/utils/yaml_template.py | 407 ---- Dockerfile | 3 +- dev/circleci_data/override_version_tag_list | 1 - dev/docker_data/default_pipeline.yml | 1741 +------------- dev/docker_data/required_afni_pkgs.txt | 8 + dev/docker_data/run.py | 193 +- requirements.txt | 8 +- setup.py | 4 - variant-ABCD-HCP.Dockerfile | 3 +- variant-fMRIPrep-LTS.Dockerfile | 3 +- version | 2 +- 184 files changed, 12713 insertions(+), 9471 deletions(-) delete mode 100755 .github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile rename .github/Dockerfiles/{AFNI.update.afni.binaries-bionic.Dockerfile => AFNI.21.1.00-bionic.Dockerfile} (80%) delete mode 100755 .github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile delete mode 100755 .github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile rename .github/workflows/{check_updated_version.yml => check_updated_preconfigs.yml} (68%) create mode 100644 CPAC/pipeline/utils.py create mode 100644 CPAC/resources/configs/pipeline_config_default-deprecated.yml create mode 100644 CPAC/resources/templates/BIDS_identifiers.tsv create mode 100644 CPAC/resources/templates/__init__.py create mode 100644 CPAC/resources/templates/lookup_table.py create mode 100644 CPAC/resources/tests/test_permissions.py create mode 100644 CPAC/surface/__init__.py create mode 100644 CPAC/surface/globals.py create mode 100644 CPAC/utils/configuration/__init__.py rename CPAC/utils/{ => configuration}/configuration.py (59%) create mode 100644 CPAC/utils/configuration/diff.py create mode 100644 CPAC/utils/configuration/yaml_template.py create mode 100644 CPAC/utils/datatypes.py create mode 100644 CPAC/utils/serialization/__init__.py create mode 100644 CPAC/utils/serialization/core.py create mode 100644 CPAC/utils/serialization/workflow_json.py create mode 100644 CPAC/utils/serialization/workflow_pickle.py create mode 100644 CPAC/utils/tests/configs/__init__.py create mode 100644 CPAC/utils/tests/configs/neurostars_23786.yml create mode 100644 CPAC/utils/tests/configs/neurostars_24035.yml delete mode 100755 CPAC/utils/yaml_template.py diff --git a/.circleci/main.yml b/.circleci/main.yml index a0f8ef551d..44660127ab 100755 --- a/.circleci/main.yml +++ b/.circleci/main.yml @@ -157,7 +157,7 @@ commands: name: Testing Singularity installation command: | pip install -r dev/circleci_data/requirements.txt - coverage run -m pytest --junitxml=test-results/junit.xml --continue-on-collection-errors dev/circleci_data/test_install.py + coverage run -m pytest --junitxml=test-results/junit.xml --continue-on-collection-errors dev/circleci_data/test_install.py jobs: combine-coverage: diff --git a/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile b/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile index 467b4211d6..c98f0af760 100755 --- a/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile +++ b/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile @@ -24,6 +24,7 @@ RUN apt-get update && \ FROM ghcr.io/fcp-indi/c-pac/ubuntu:xenial-20200114 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ AFNI 16.2.07 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root COPY --from=AFNI /opt/afni-latest/ /usr/lib/afni/bin/ diff --git a/.github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile b/.github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile deleted file mode 100755 index 61139347dd..0000000000 --- a/.github/Dockerfiles/AFNI.20.0.04-bionic.Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -AFNI 20.0.04 stage" -USER root - -# install AFNI -COPY dev/docker_data/required_afni_pkgs.txt /opt/required_afni_pkgs.txt -RUN if [ -f /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0]; then \ - ln -svf /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0 /usr/lib/x86_64-linux-gnu/libGL.so.1; \ - fi && \ - libs_path=/usr/lib/x86_64-linux-gnu && \ - if [ -f $libs_path/libgsl.so.23 ]; then \ - ln -svf $libs_path/libgsl.so.23 $libs_path/libgsl.so.19 && \ - ln -svf $libs_path/libgsl.so.23 $libs_path/libgsl.so.0; \ - elif [ -f $libs_path/libgsl.so.23.0.0 ]; then \ - ln -svf $libs_path/libgsl.so.23.0.0 $libs_path/libgsl.so.19 && \ - ln -svf $libs_path/libgsl.so.23.0.0 $libs_path/libgsl.so.0; \ - elif [ -f $libs_path/libgsl.so ]; then \ - ln -svf $libs_path/libgsl.so $libs_path/libgsl.so.0; \ - fi && \ - LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH && \ - export LD_LIBRARY_PATH && \ - curl -O https://afni.nimh.nih.gov/pub/dist/bin/linux_openmp_64/@update.afni.binaries && \ - tcsh @update.afni.binaries -package linux_openmp_64 -bindir /opt/afni -prog_list $(cat /opt/required_afni_pkgs.txt) && \ - ldconfig - -# set up AFNI -ENV PATH=/opt/afni:$PATH - -ENTRYPOINT ["/bin/bash"] - -# Link libraries for Singularity images -RUN ldconfig - -RUN apt-get clean && \ - apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# set user -# USER c-pac_user diff --git a/.github/Dockerfiles/AFNI.update.afni.binaries-bionic.Dockerfile b/.github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile similarity index 80% rename from .github/Dockerfiles/AFNI.update.afni.binaries-bionic.Dockerfile rename to .github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile index c4aabb1467..7d841a5dfd 100755 --- a/.github/Dockerfiles/AFNI.update.afni.binaries-bionic.Dockerfile +++ b/.github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile @@ -1,6 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -AFNI @update.afni.binaries stage" +FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as AFNI USER root # install AFNI @@ -21,7 +19,7 @@ RUN if [ -f /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0]; then \ LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH && \ export LD_LIBRARY_PATH && \ apt-get update && apt-get install -y libglw1-mesa-dev && \ - AFNI_VERSION="20.0.04" && \ + AFNI_VERSION="21.1.00" && \ curl -LOJ https://github.com/afni/afni/archive/AFNI_${AFNI_VERSION}.tar.gz && \ mkdir /opt/afni && \ tar -xvf afni-AFNI_${AFNI_VERSION}.tar.gz -C /opt/afni --strip-components 1 && \ @@ -49,5 +47,12 @@ RUN apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# set user -USER c-pac_user \ No newline at end of file +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +AFNI 21.1.00 (Domitian) stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=AFNI /lib/x86_64-linux-gnu/ld* /lib/x86_64-linux-gnu/ +COPY --from=AFNI /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ +COPY --from=AFNI /lib64/ld* /lib64/ +COPY --from=AFNI /opt/afni/ /opt/afni/ +COPY --from=AFNI /usr/lib/x86_64-linux-gnu/lib*so* /usr/lib/x86_64-linux-gnu/ diff --git a/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile b/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile index c242528f25..9efc14316e 100755 --- a/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile +++ b/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile @@ -1,6 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -ANTs 2.2.0 stage" +FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as ANTs USER root # install ANTs from Neurodocker @@ -42,5 +40,9 @@ RUN apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# set user -USER c-pac_user +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +ANTs 2.2.0 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=ANTs /usr/lib/ants/ /usr/lib/ants/ +COPY --from=ANTs /ants_template /ants_template diff --git a/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile b/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile index 37cc2c1633..a9915f0d28 100755 --- a/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile +++ b/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile @@ -37,9 +37,7 @@ RUN apt-get clean && \ FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ ANTs 2.3.4 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=ANTs /usr/lib/ants/ /usr/lib/ants/ COPY --from=ANTs /ants_template /ants_template COPY --from=ANTS /etc/locale.gen /etc/locale.gen - -# set user -USER c-pac_user \ No newline at end of file diff --git a/.github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile b/.github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile deleted file mode 100755 index c232413210..0000000000 --- a/.github/Dockerfiles/ANTs.2.3.5-bionic.Dockerfile +++ /dev/null @@ -1,63 +0,0 @@ -FROM ubuntu:bionic-20200112 as builder - -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - build-essential \ - apt-transport-https \ - ca-certificates \ - curl \ - gnupg \ - software-properties-common \ - wget \ - ninja-build \ - git \ - unzip \ - zlib1g-dev - -RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \ - | apt-key add - \ - && apt-add-repository -y 'deb https://apt.kitware.com/ubuntu/ bionic main' \ - && apt-get update \ - && apt-get -y install cmake=3.18.3-0kitware1 cmake-data=3.18.3-0kitware1 - -RUN mkdir -p /tmp/ants/build \ - && cd /tmp/ants/build \ - && mkdir -p /opt/ants \ - && git config --global url."https://".insteadOf git:// \ - && git clone -b v2.3.5 --depth 1 https://github.com/ANTsX/ANTs.git /tmp/ants/ANTs \ - && cmake \ - -DCMAKE_INSTALL_PREFIX=/opt/ants \ - -DBUILD_SHARED_LIBS=OFF \ - -DUSE_VTK=OFF \ - -DSuperBuild_ANTS_USE_GIT_PROTOCOL=OFF \ - -DBUILD_TESTING=OFF \ - -DRUN_LONG_TESTS=OFF \ - -DRUN_SHORT_TESTS=OFF \ - ../ANTs 2>&1 | tee cmake.log \ - && make -j 4 2>&1 | tee build.log \ - && cd ANTS-build \ - && make install 2>&1 | tee install.log - -# download OASIS templates for niworkflows-ants skullstripping -RUN mkdir /ants_template && \ - curl -sL https://s3-eu-west-1.amazonaws.com/pfigshare-u-files/3133832/Oasis.zip -o /tmp/Oasis.zip && \ - unzip /tmp/Oasis.zip -d /tmp &&\ - mv /tmp/MICCAI2012-Multi-Atlas-Challenge-Data /ants_template/oasis && \ - rm -rf /tmp/Oasis.zip /tmp/MICCAI2012-Multi-Atlas-Challenge-Data - -FROM ubuntu:bionic-20200112 -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -ANTs 2.3.5 stage" -COPY --from=builder /opt/ants /opt/ants -COPY --from=builder /ants_template /ants_template - -ENV ANTSPATH="/opt/ants/bin/" \ - PATH="/opt/ants/bin:$PATH" \ - LD_LIBRARY_PATH="/opt/ants/lib:$LD_LIBRARY_PATH" -RUN apt-get update \ - && apt install -y --no-install-recommends zlib1g-dev \ - && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -WORKDIR /data - -CMD ["/bin/bash"] diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 84c623e680..49a5f18eba 100755 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,9 +1,9 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.4 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.5 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # install C-PAC -COPY dev/docker_data/default_pipeline.yml /cpac_resources/default_pipeline.yml COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code RUN pip install -e /code diff --git a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile index 57c0ffccb0..66410b0af6 100755 --- a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile @@ -1,9 +1,9 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.4 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.5 LABEL org.opencontainers.image.description "Full C-PAC image" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # install C-PAC -COPY dev/docker_data/default_pipeline.yml /cpac_resources/default_pipeline.yml COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code RUN pip install -e /code diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 1533bcd5e5..4d20a4cd9f 100755 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,9 +1,9 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.4 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.5 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # install C-PAC & set up runscript -COPY dev/docker_data/default_pipeline.yml /cpac_resources/default_pipeline.yml COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code RUN pip install -e /code diff --git a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile index 3d1cfaa15a..c40bc784e5 100755 --- a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile @@ -1,5 +1,6 @@ FROM ghcr.io/fcp-indi/c-pac:latest-bionic LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root ENTRYPOINT ["/code/run.py"] diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index 98e24d20d1..6bd6e6182e 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -52,6 +52,7 @@ USER c-pac_user FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ FSL 5.0.10 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=FSL /usr/bin/tclsh /usr/bin/tclsh COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ diff --git a/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile b/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile index 4cf75ec4ab..4a5e0bcc71 100755 --- a/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile @@ -1,6 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:xenial-20200114 -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -FSL 5.0.9-5 stage" +FROM ghcr.io/fcp-indi/c-pac/ubuntu:xenial-20200114 as FSL USER root ARG DEBIAN_FRONTEND=noninteractive @@ -34,7 +32,8 @@ RUN curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o / cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard && \ cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford && \ cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors && \ - cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors + cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors && \ + chmod -R ugo+r $FSLDIR/data/standard ENTRYPOINT ["/bin/bash"] @@ -44,5 +43,19 @@ RUN ldconfig && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# set user -USER c-pac_user \ No newline at end of file +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +FSL 5.0.9-5 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=FSL /etc/fsl /etc/fsl +COPY --from=FSL /usr/lib/fsl /usr/lib/fsl +COPY --from=FSL /usr/lib/libnewmat.so.10 /usr/lib/libnewmat.so.10 +COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ +COPY --from=FSL /usr/lib/libniftiio.so.2 /usr/lib/libniftiio.so.2 +COPY --from=FSL /usr/lib/libznz.so.2 /usr/lib/libznz.so.2 +COPY --from=FSL /usr/share/doc/fsl-core /usr/share/doc/fsl-core +COPY --from=FSL /usr/share/man/man1/fsl-5.0-core.1.gz /usr/share/man/man1/ +COPY --from=FSL /usr/share/man/man1/fsl.1.gz /usr/share/man/man1/ +COPY --from=FSL /usr/share/data/fsl-mni152-templates /usr/share/data/fsl-mni152-templates +COPY --from=FSL /usr/share/doc/fsl-mni152-templates /usr/share/doc/fsl-mni152-templates +COPY --from=FSL /usr/share/fsl /usr/share/fsl diff --git a/.github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile deleted file mode 100755 index 5946f114b8..0000000000 --- a/.github/Dockerfiles/FSL.neurodebian-bionic.Dockerfile +++ /dev/null @@ -1,45 +0,0 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -FSL Neurodebian stage" -USER root - -ARG DEBIAN_FRONTEND=noninteractive - -# install FSL -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - fsl-core \ - fsl-atlases \ - fsl-mni152-templates - -# setup FSL environment -ENV FSLDIR=/usr/share/fsl/5.0 \ - FSLOUTPUTTYPE=NIFTI_GZ \ - FSLMULTIFILEQUIT=TRUE \ - POSSUMDIR=/usr/share/fsl/5.0 \ - LD_LIBRARY_PATH=/usr/lib/fsl/5.0:$LD_LIBRARY_PATH \ - FSLTCLSH=/usr/bin/tclsh \ - FSLWISH=/usr/bin/wish \ - PATH=/usr/lib/fsl/5.0:$PATH - -# install CPAC resources into FSL -RUN curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz && \ - tar xfz /tmp/cpac_resources.tar.gz -C /tmp && \ - cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard && \ - cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard && \ - cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard && \ - cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford && \ - cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors && \ - cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors - -ENTRYPOINT ["/bin/bash"] - -# Link libraries for Singularity images -RUN ldconfig - -RUN apt-get clean && \ - apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# set user -USER c-pac_user \ No newline at end of file diff --git a/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile index ec9d08d613..787356d021 100755 --- a/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile +++ b/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile @@ -1,9 +1,7 @@ # we need mri_vol2vol which is not included in neurodocker freesurfer 6.0.0-min FROM freesurfer/freesurfer:6.0 as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -FreeSurfer 6.0.0-min stage" +FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as FreeSurfer6 USER root # install FreeSurfer @@ -33,5 +31,8 @@ RUN apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# set user -USER c-pac_user \ No newline at end of file +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +FreeSurfer 6.0.0-min stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=FreeSurfer6 /usr/lib/freesurfer/ /usr/lib/freesurfer/ diff --git a/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile index 0cfd26105f..8e1ca0c1a8 100755 --- a/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile +++ b/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile @@ -7,5 +7,6 @@ RUN /freesurfer-prune FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ FreeSurfer 6.0.1-min stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=FreeSurfer /opt/freesurfer /opt/freesurfer COPY dev/docker_data/license.txt /opt/freesurfer/license.txt \ No newline at end of file diff --git a/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile index 60adad0dce..b76c758340 100755 --- a/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile +++ b/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile @@ -50,6 +50,7 @@ RUN apt-get clean && \ FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ FreeSurfer 6.0.1 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=FreeSurfer /opt/freesurfer /opt/freesurfer # set user diff --git a/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile b/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile index eb3b223685..d775562bb3 100755 --- a/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile +++ b/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile @@ -25,4 +25,5 @@ USER c-pac_user FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ ICA-AROMA 0.4.5 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=ICA-AROMA /opt/ICA-AROMA/ /opt/ICA-AROMA/ \ No newline at end of file diff --git a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile index 87be21fe98..51db3dedcd 100755 --- a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile +++ b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile @@ -1,5 +1,7 @@ +FROM ghcr.io/fcp-indi/c-pac_templates:latest as c-pac_templates FROM neurodebian:bionic-non-free AS dcan-hcp + ARG DEBIAN_FRONTEND=noninteractive # Adding DCAN dependencies & HCP code @@ -12,6 +14,7 @@ RUN apt-get update && \ FROM neurodebian:bionic-non-free LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Ubuntu Bionic base image" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC ARG DEBIAN_FRONTEND=noninteractive ENV TZ=America/New_York @@ -105,9 +108,9 @@ RUN groupadd -r c-pac && \ libxp-dev && \ add-apt-repository --remove --yes ppa:zeehio/libxp && \ apt-get update && \ - curl -sO https://repo.anaconda.com/miniconda/Miniconda3-py37_4.8.2-Linux-x86_64.sh && \ - bash Miniconda3-py37_4.8.2-Linux-x86_64.sh -b -p /usr/local/miniconda && \ - rm Miniconda3-py37_4.8.2-Linux-x86_64.sh && chmod -R 777 /usr/local/miniconda && \ + curl -sO https://repo.anaconda.com/miniconda/Miniconda3-py37_4.12.0-Linux-x86_64.sh && \ + bash Miniconda3-py37_4.12.0-Linux-x86_64.sh -b -p /usr/local/miniconda && \ + rm Miniconda3-py37_4.12.0-Linux-x86_64.sh && chmod -R 777 /usr/local/miniconda && \ ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ echo $TZ > /etc/timezone && \ sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ @@ -144,10 +147,15 @@ RUN conda install -n base conda-forge::mamba conda-forge::libarchive==3.5.2 -y & git lfs install # Installing C-PAC templates and atlases -COPY --from=ghcr.io/fcp-indi/c-pac_templates:latest /cpac_templates /cpac_templates +COPY --from=c-pac_templates /cpac_templates /cpac_templates COPY --from=dcan-hcp /opt/dcan-tools/pipeline/global /opt/dcan-tools/pipeline/global COPY --from=ghcr.io/fcp-indi/c-pac/neuroparc:v1.0-human /ndmg_atlases /ndmg_atlases +# Installing surface files for downsampling +COPY --from=c-pac_templates /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases/ /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases/ +COPY --from=c-pac_templates /opt/dcan-tools/pipeline/global/templates/Greyordinates/ /opt/dcan-tools/pipeline/global/templates/Greyordinates/ + + ENTRYPOINT ["/bin/bash"] # Link libraries for Singularity images diff --git a/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile b/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile index ea87c36c95..e2ad01a017 100755 --- a/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile +++ b/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile @@ -1,3 +1,4 @@ +FROM ghcr.io/fcp-indi/c-pac_templates:latest as c-pac_templates FROM nipreps/fmriprep:20.2.1 as fmriprep FROM ubuntu:xenial-20200114 AS dcan-hcp @@ -14,6 +15,7 @@ RUN git clone -b 'v2.0.0' --single-branch --depth 1 https://github.com/DCAN-Labs FROM ubuntu:xenial-20200114 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Ubuntu Xenial base image" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC ARG DEBIAN_FRONTEND=noninteractive # create usergroup and user, set permissions, install curl @@ -119,9 +121,9 @@ RUN apt-get update && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Installing and setting up miniconda -RUN curl -sSLO https://repo.continuum.io/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh && \ - bash Miniconda3-4.5.11-Linux-x86_64.sh -b -p /usr/local/miniconda && \ - rm Miniconda3-4.5.11-Linux-x86_64.sh && chmod -R 777 /usr/local/miniconda +RUN curl -sSLO https://repo.continuum.io/miniconda/Miniconda3-py37_4.12.0-Linux-x86_64.sh && \ + bash Miniconda3-py37_4.12.0-Linux-x86_64.sh -b -p /usr/local/miniconda && \ + rm Miniconda3-py37_4.12.0-Linux-x86_64.sh && chmod -R 777 /usr/local/miniconda # Set CPATH for packages relying on compiled libs (e.g. indexed_gzip) ENV PATH="/usr/local/miniconda/bin:$PATH" \ @@ -140,8 +142,8 @@ RUN conda update conda -y && \ networkx==2.4 \ nose==1.3.7 \ numpy==1.15.4 \ - pandas==0.23.4 \ - scipy==1.1.0 \ + pandas==1.0.5 \ + scipy==1.6.3 \ traits==4.6.0 \ pip @@ -156,9 +158,13 @@ RUN pip install -r /opt/requirements.txt RUN pip install xvfbwrapper # install cpac templates -COPY --from=ghcr.io/fcp-indi/c-pac_templates:latest /cpac_templates /cpac_templates +COPY --from=c-pac_templates /cpac_templates /cpac_templates COPY --from=dcan-hcp /opt/dcan-tools/pipeline/global /opt/dcan-tools/pipeline/global +# Installing surface files for downsampling +COPY --from=c-pac_templates /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases/ /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases/ +COPY --from=c-pac_templates /opt/dcan-tools/pipeline/global/templates/Greyordinates/ /opt/dcan-tools/pipeline/global/templates/Greyordinates/ + RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash RUN apt-get install git-lfs RUN git lfs install diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile index 7bc7b22fd9..b70be7e0c0 100755 --- a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile +++ b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile @@ -1,5 +1,5 @@ # Choose versions -FROM ghcr.io/fcp-indi/c-pac/afni:update.afni.binaries-bionic as AFNI +FROM ghcr.io/fcp-indi/c-pac/afni:21.1.00-bionic as AFNI FROM ghcr.io/fcp-indi/c-pac/ants:2.2.0.neurodocker-bionic as ANTs FROM ghcr.io/fcp-indi/c-pac/c3d:1.0.0-bionic as c3d FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-bionic as FreeSurfer @@ -10,6 +10,7 @@ FROM ghcr.io/fcp-indi/c-pac/msm:2.0-bionic as MSM FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Software dependencies version-matched to `ABCD-HCP BIDS fMRI Pipeline `_" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # allow users to update / create themselves @@ -21,8 +22,9 @@ ENV C3DPATH=/opt/c3d/ ENV PATH=$C3DPATH/bin:$PATH # install AFNI +# AFNI isn't used in used in ABCD-HCP, so we're just matching the version in the standard C-PAC image COPY --from=AFNI /lib/x86_64-linux-gnu/ld* /lib/x86_64-linux-gnu/ -COPY --from=AFNI /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ +COPY --from=AFNI /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ COPY --from=AFNI /lib64/ld* /lib64/ COPY --from=AFNI /opt/afni/ /opt/afni/ COPY --from=AFNI /usr/lib/x86_64-linux-gnu/lib*so* /usr/lib/x86_64-linux-gnu/ diff --git a/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile b/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile index a12d2ee836..75ff624a60 100755 --- a/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile +++ b/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile @@ -12,6 +12,7 @@ FROM ghcr.io/fcp-indi/c-pac/msm:2.0-bionic as MSM FROM ghcr.io/fcp-indi/c-pac/ubuntu:xenial-20200114 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Software dependencies version-matched to `fMRIPrep LTS `_" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # allow users to update / create themselves @@ -101,7 +102,6 @@ COPY --from=FSL /usr/lib/libznz.so.2 /usr/lib/libznz.so.2 COPY --from=FSL /usr/share/doc/fsl-core /usr/share/doc/fsl-core COPY --from=FSL /usr/share/man/man1/fsl-5.0-core.1.gz /usr/share/man/man1/ COPY --from=FSL /usr/share/man/man1/fsl.1.gz /usr/share/man/man1/ -# COPY --from=FSL /usr/share/man/man1/fsl5.0-* /usr/share/man/man1/ # These are all broken symlinks to `fsl-5.0.1.gz` COPY --from=FSL /usr/share/data/fsl-mni152-templates /usr/share/data/fsl-mni152-templates COPY --from=FSL /usr/share/doc/fsl-mni152-templates /usr/share/doc/fsl-mni152-templates COPY --from=FSL /usr/share/fsl /usr/share/fsl diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index 6bbef3e445..b239ed3a02 100755 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -1,3 +1,4 @@ +FROM ghcr.io/fcp-indi/c-pac/afni:21.1.00-bionic as AFNI FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-bionic as FreeSurfer FROM ghcr.io/fcp-indi/c-pac/ica-aroma:0.4.3-beta-bionic as ICA-AROMA FROM ghcr.io/fcp-indi/c-pac/msm:2.0-bionic as MSM @@ -5,6 +6,7 @@ FROM ghcr.io/fcp-indi/c-pac/msm:2.0-bionic as MSM FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard and lite images" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # Installing connectome-workbench & FSL @@ -27,9 +29,14 @@ ENV C3DPATH /opt/c3d ENV PATH $C3DPATH/bin:$PATH # Installing AFNI -# Installing C-PAC resources into FSL -# Installing ANTs -COPY dev/docker_data/required_afni_pkgs.txt /opt/required_afni_pkgs.txt +COPY --from=AFNI /lib/x86_64-linux-gnu/ld* /lib/x86_64-linux-gnu/ +COPY --from=AFNI /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ +COPY --from=AFNI /lib64/ld* /lib64/ +COPY --from=AFNI /opt/afni/ /opt/afni/ +COPY --from=AFNI /usr/lib/x86_64-linux-gnu/lib*so* /usr/lib/x86_64-linux-gnu/ +# set up AFNI +ENV PATH=/opt/afni:$PATH +# Installing C-PAC resources into FSL and installing ANTs ENV LANG="en_US.UTF-8" \ LC_ALL="en_US.UTF-8" \ ANTSPATH=/usr/lib/ants \ @@ -44,20 +51,6 @@ ENV LANG="en_US.UTF-8" \ RUN if [ -f /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0]; then \ ln -svf /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0 /usr/lib/x86_64-linux-gnu/libGL.so.1; \ fi && \ - libs_path=/usr/lib/x86_64-linux-gnu && \ - if [ -f $libs_path/libgsl.so.23 ]; then \ - ln -svf $libs_path/libgsl.so.23 $libs_path/libgsl.so.19 && \ - ln -svf $libs_path/libgsl.so.23 $libs_path/libgsl.so.0; \ - elif [ -f $libs_path/libgsl.so.23.0.0 ]; then \ - ln -svf $libs_path/libgsl.so.23.0.0 $libs_path/libgsl.so.19 && \ - ln -svf $libs_path/libgsl.so.23.0.0 $libs_path/libgsl.so.0; \ - elif [ -f $libs_path/libgsl.so ]; then \ - ln -svf $libs_path/libgsl.so $libs_path/libgsl.so.0; \ - fi && \ - LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH && \ - export LD_LIBRARY_PATH && \ - curl -O https://afni.nimh.nih.gov/pub/dist/bin/linux_openmp_64/@update.afni.binaries && \ - tcsh @update.afni.binaries -package linux_openmp_64 -bindir /opt/afni -prog_list $(cat /opt/required_afni_pkgs.txt) && \ ldconfig && \ curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz && \ tar xfz /tmp/cpac_resources.tar.gz -C /tmp && \ @@ -67,6 +60,7 @@ RUN if [ -f /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1.2.0]; then \ cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford && \ cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors && \ cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors && \ + chmod -R ugo+r $FSLDIR/data/standard && \ echo "Downloading ANTs ..." \ && mkdir -p /usr/lib/ants \ && curl -fsSL --retry 5 https://dl.dropbox.com/s/gwf51ykkk5bifyj/ants-Linux-centos6_x86_64-v2.3.4.tar.gz \ diff --git a/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile b/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile index 09c95f7914..a626610476 100755 --- a/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile +++ b/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile @@ -1,6 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -c3d 1.0.0 (Bionic) stage" +FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as c3d USER root # Installing and setting up c3d @@ -19,5 +17,8 @@ RUN apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# set user -USER c-pac_user \ No newline at end of file +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +c3d 1.0.0 (Bionic) stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=c3d /opt/c3d/ /opt/c3d/ diff --git a/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile b/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile index 00bb6a4f19..1eef0c48d2 100755 --- a/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile +++ b/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile @@ -1,6 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/ubuntu:xenial-20200114 -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -c3d 1.0.0 (Xenial) stage" +FROM ghcr.io/fcp-indi/c-pac/ubuntu:xenial-20200114 as c3d USER root # Installing and setting up c3d @@ -19,5 +17,18 @@ RUN apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -# set user -USER c-pac_user +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +c3d 1.0.0 (Xenial) stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=c3d /usr/lib/libITK* /usr/lib/ +COPY --from=c3d /usr/lib/libitk* /usr/lib/ +COPY --from=c3d /usr/lib/x86_64-linux-gnu/libgdcm* /usr/lib/x86_64-linux-gnu/ +COPY --from=c3d /usr/lib/x86_64-linux-gnu/libfftw3* /usr/lib/x86_64-linux-gnu/ +COPY --from=c3d /lib/x86_64-linux-gnu/lib*.so* /lib/x86_64-linux-gnu/ +COPY --from=c3d /usr/lib/x86_64-linux-gnu/lib*.so* /usr/lib/x86_64-linux-gnu/ +COPY --from=c3d /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 +COPY --from=c3d /usr/bin/c*d /usr/bin/ +COPY --from=c3d /usr/bin/c3d_* /usr/bin/ +COPY --from=c3d /usr/share/doc/convert3d /usr/share/doc/convert3d +COPY --from=c3d /usr/lib/c3d_gui-1.1.0/Convert3DGUI /usr/lib/c3d_gui-1.1.0/Convert3DGUI diff --git a/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile index d5d3ade9a6..3c33cd789d 100755 --- a/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile +++ b/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile @@ -17,6 +17,7 @@ USER c-pac_user FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ connectome-workbench 1.3.2-1 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=base /lib64/ld-linux-x86-64.so.2 /lib64/ COPY --from=base /usr/bin/wb_* /usr/bin/ COPY --from=base /lib/x86_64-linux-gnu/ld-* /lib/x86_64-linux-gnu/ diff --git a/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile index 93aeda1243..30838e14b7 100755 --- a/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile +++ b/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile @@ -15,6 +15,7 @@ USER c-pac_user FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ connectome-workbench 1.3.2-2 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=base /lib64/ld-linux-x86-64.so.2 /lib64/ COPY --from=base /usr/bin/wb_* /usr/bin/ COPY --from=base /lib/x86_64-linux-gnu/ld-* /lib/x86_64-linux-gnu/ diff --git a/.github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile index 80aa82bdb2..406323b857 100755 --- a/.github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile +++ b/.github/Dockerfiles/connectome-workbench.1.5.0.neurodebian-bionic.Dockerfile @@ -14,6 +14,7 @@ USER c-pac_user FROM scratch LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ connectome-workbench 1.5.0 stage" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC COPY --from=base /lib64/ld-linux-x86-64.so.2 /lib64/ COPY --from=base /usr/bin/wb_* /usr/bin/ COPY --from=base /lib/x86_64-linux-gnu/ld-* /lib/x86_64-linux-gnu/ diff --git a/.github/Dockerfiles/msm.2.0-bionic.Dockerfile b/.github/Dockerfiles/msm.2.0-bionic.Dockerfile index 3e8f82779f..0519f9e0da 100755 --- a/.github/Dockerfiles/msm.2.0-bionic.Dockerfile +++ b/.github/Dockerfiles/msm.2.0-bionic.Dockerfile @@ -1,9 +1,5 @@ # using neurodebian runtime as parent image -FROM neurodebian:bionic-non-free -LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ -msm v2.0 stage \ - Multimodal Surface Matching with Higher order Clique Reduction Version 2.00 (Feb 2017)" -LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +FROM neurodebian:bionic-non-free as MSM ARG DEBIAN_FRONTEND=noninteractive @@ -33,3 +29,10 @@ RUN ldconfig RUN apt-get clean && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +FROM scratch +LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ +msm v2.0 stage \ + Multimodal Surface Matching with Higher order Clique Reduction Version 2.00 (Feb 2017)" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC +COPY --from=MSM /opt/msm/Ubuntu/msm /opt/msm/Ubuntu/msm \ No newline at end of file diff --git a/.github/scripts/get_package_id.py b/.github/scripts/get_package_id.py index 01cf05c449..d5e54cc704 100755 --- a/.github/scripts/get_package_id.py +++ b/.github/scripts/get_package_id.py @@ -11,18 +11,18 @@ def get_packages(owner, tag, api_token=None): """Function to collect GHCR packages for a given owner & tag - + Parameters ---------- owner : str username or org name - + tag : str image tag (part left of the colon) api_token : str or None GitHub API personal access token with read.packages permission - + Returns ------- list @@ -32,11 +32,11 @@ def get_packages(owner, tag, api_token=None): def fetch(url): """Method to make API call and return response, given a URL - + Parameters ---------- url : str - + Returns ------- dict or list @@ -59,34 +59,36 @@ def fetch(url): '$VERSION_TAG $GITHUB_TOKEN`' ])) return response - packages = fetch( + _packages = fetch( f'https://api.github.com/orgs/{owner}/packages/container/' f'{tag}/versions') - if packages.get('message', 'Not Found') == 'Not Found': - packages = fetch( - f'https://api.github.com/users/{owner}/packages/container/' - f'{tag}/versions') + packages = [] + for _package in _packages: + if _package.get('message', 'Not Found') == 'Not Found': + packages += fetch( + f'https://api.github.com/users/{owner}/packages/container/' + f'{tag}/versions') return packages def id_from_tag(owner, image, tag, api_token=None): """Function to return a package ID given an image version tag - + Parameters ---------- owner : str GitHub username or org name - + image : str Image tag (the part to the left of the colon) - + tag : str Image version tag (the part to the right of the colon) api_token: str or None GitHub API personal access token with read.packages permission """ - packages = get_packages(owner, image) + packages = get_packages(owner, image, api_token) versions = [image['id'] for image in packages if tag in image.get( 'metadata', {} ).get('container', {}).get('tags', [])] diff --git a/.github/stage_requirements/ABCD-HCP.txt b/.github/stage_requirements/ABCD-HCP.txt index 6b6d1d1151..f7e4721907 100755 --- a/.github/stage_requirements/ABCD-HCP.txt +++ b/.github/stage_requirements/ABCD-HCP.txt @@ -1,9 +1,8 @@ base-ABCD-HCP.Dockerfile -AFNI.update.afni.binaries-bionic.Dockerfile +AFNI.21.1.00-bionic.Dockerfile ANTs.2.2.0.neurodocker-bionic.Dockerfile c3d.1.0.0-bionic.Dockerfile connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile -FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile FSL.5.0.10-bionic.Dockerfile ICA-AROMA.0.4.3-beta-bionic.Dockerfile msm.2.0-bionic.Dockerfile diff --git a/.github/stage_requirements/fMRIPrep-LTS.txt b/.github/stage_requirements/fMRIPrep-LTS.txt index f7a7fdbb1e..28992397a1 100755 --- a/.github/stage_requirements/fMRIPrep-LTS.txt +++ b/.github/stage_requirements/fMRIPrep-LTS.txt @@ -3,7 +3,6 @@ AFNI.16.2.07.neurodocker-xenial.Dockerfile ANTs.2.3.4.neurodocker-xenial.Dockerfile c3d.1.0.0-xenial.Dockerfile connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile -FreeSurfer.6.0.1-min-xenial.Dockerfile FSL.5.0.9-5.neurodebian-xenial.Dockerfile ICA-AROMA.0.4.5-xenial.Dockerfile msm.2.0-bionic.Dockerfile diff --git a/.github/stage_requirements/standard.txt b/.github/stage_requirements/standard.txt index 7438df0843..fea755a727 100755 --- a/.github/stage_requirements/standard.txt +++ b/.github/stage_requirements/standard.txt @@ -1,5 +1,5 @@ base-standard.Dockerfile -FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile +AFNI.21.1.00-bionic.Dockerfile ica-aroma.0.4.3-beta-bionic msm.2.0-bionic.Dockerfile Ubuntu.bionic-non-free.Dockerfile \ No newline at end of file diff --git a/.github/workflows/build_C-PAC.yml b/.github/workflows/build_C-PAC.yml index ed2d1039bb..b5654a0dbf 100755 --- a/.github/workflows/build_C-PAC.yml +++ b/.github/workflows/build_C-PAC.yml @@ -24,7 +24,7 @@ jobs: with: fetch-depth: 2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1.6.0 + uses: docker/setup-buildx-action@v2.2.1 - name: Log in to GitHub Container Registry uses: docker/login-action@v2 with: @@ -74,14 +74,13 @@ jobs: then VARIANT=-${{ inputs.variant }} fi - TAG=latest if [[ $VARIANT == "" ]] then DOCKERFILE=Dockerfile else DOCKERFILE=variant$VARIANT.Dockerfile fi - TAG=$TAG$VARIANT + TAG=release-${{ github.ref_name }}$VARIANT echo DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}" | tr '[:upper:]' '[:lower:]'):$TAG >> $GITHUB_ENV echo DOCKERFILE="${DOCKERFILE}" >> $GITHUB_ENV cat $GITHUB_ENV @@ -93,7 +92,7 @@ jobs: echo $DOCKERFILE cat $DOCKERFILE - name: Build and push Docker image - uses: docker/build-push-action@v2.9.0 + uses: docker/build-push-action@v3.2.0 with: context: . file: ${{ env.DOCKERFILE }} diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index f86aa48d23..46a5a5a249 100755 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -115,6 +115,11 @@ jobs: --header 'content-type: application/json' \ --data "${DATA}" | jq '.number') + if [[ $PIPELINE_NUMBER == 'null' ]] + then + echo "Failed to trigger CircleCI tests" + exit 126 + fi PIPELINE_ID=$(curl \ --request GET \ --url "https://circleci.com/api/v2/project/gh/${GITHUB_REPOSITORY}/pipeline/${PIPELINE_NUMBER}" \ diff --git a/.github/workflows/build_stages.yml b/.github/workflows/build_stages.yml index d5f01fb9a0..68e8249f7c 100755 --- a/.github/workflows/build_stages.yml +++ b/.github/workflows/build_stages.yml @@ -46,14 +46,14 @@ jobs: with: fetch-depth: 2 - name: Get changed files since fork point - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v34.0.0 if: github.event.inputs.base_ref != '' id: changed-files-base with: use_fork_point: "true" files: .github/Dockerfiles/* - name: Get changed files since last commit - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v34.0.0 if: github.event.inputs.base_ref == '' id: changed-files with: @@ -65,10 +65,9 @@ jobs: TAG=$(sed 's/\./:/' <(echo ${{ matrix.Dockerfile }})) DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV - docker manifest inspect $DOCKER_TAG >/dev/null - echo "::set-output name=not_yet_exists::$?" + docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1.6.0 + uses: docker/setup-buildx-action@v2.2.1 if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) - name: Log in to GitHub Container Registry uses: docker/login-action@v2 @@ -78,14 +77,14 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) - name: Build and push Docker image - uses: docker/build-push-action@v2.9.0 + uses: docker/build-push-action@v3.2.0 with: file: .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile push: true tags: | ${{ env.DOCKER_TAG }} cache-from: type=gha - cache-to: type=gha,mode=max + cache-to: type=gha,mode=min if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) stages: @@ -95,13 +94,11 @@ jobs: matrix: Dockerfile: - AFNI.16.2.07.neurodocker-xenial - - AFNI.20.0.04-bionic + - AFNI.21.1.00-bionic - ANTs.2.2.0.neurodocker-bionic - c3d.1.0.0-xenial - connectome-workbench.1.3.2-1.neurodebian-bionic - connectome-workbench.1.3.2-2.neurodebian-xenial - - FreeSurfer.6.0.0-min.neurodocker-bionic - - FreeSurfer.6.0.1-min-xenial - FSL.5.0.9-5.neurodebian-xenial - FSL.5.0.10-bionic - ICA-AROMA.0.4.5-xenial @@ -119,55 +116,58 @@ jobs: with: fetch-depth: 2 - name: Get changed files since fork point - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v34.0.0 if: github.event.inputs.base_ref != '' id: changed-files-base with: use_fork_point: "true" - files: .github/Dockerfiles/* + files: | + dev/docker_data/required_afni_pkgs.txt + .github/Dockerfiles/* - name: Get changed files since last commit - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v34.0.0 if: github.event.inputs.base_ref == '' id: changed-files with: since_last_remote_commit: "true" - files: .github/Dockerfiles/* + files: | + dev/docker_data/required_afni_pkgs.txt + .github/Dockerfiles/* - name: Clear up some space on runner - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) run: | sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc sudo rm -rf "/usr/local/share/boost" sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1.6.0 - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + uses: docker/setup-buildx-action@v2.2.1 + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - name: Log in to GitHub Container Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - name: Set tag & see if it exists continue-on-error: true run: | TAG=$(sed 's/\./:/' <(echo ${{ matrix.Dockerfile }})) DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV - docker manifest inspect $DOCKER_TAG >/dev/null - echo "::set-output name=not_yet_exists::$?" - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - name: Prep Dockerfiles for forked repository - if: github.repository_owner != 'FCP-INDI' && contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + if: github.repository_owner != 'FCP-INDI' && contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) run: | .github/scripts/local_ghcr .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile ${{ github.repository_owner }} $DOCKER_TAG cat .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile - name: See Dockerfile run: cat .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - name: Build and push Docker image - uses: docker/build-push-action@v2.9.0 + uses: docker/build-push-action@v3.2.0 with: context: . file: .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile @@ -175,12 +175,14 @@ jobs: tags: | ${{ env.DOCKER_TAG }} cache-from: type=gha - cache-to: type=gha,mode=max - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + cache-to: type=gha,mode=min + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) build-base: needs: stages runs-on: ubuntu-latest + env: + BUILD_CACHE: /home/runner/.docker/buildkit strategy: matrix: variant: @@ -206,9 +208,13 @@ jobs: with: fetch-depth: 2 - name: Prep source files - run: sed -i -e 's/^/\.github\/Dockerfiles\//' .github/stage_requirements/${{ matrix.variant }}.txt + run: | + sed -i -e 's/^/\.github\/Dockerfiles\//' .github/stage_requirements/${{ matrix.variant }}.txt + echo 'dev/docker_data/required_afni_pkgs.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt + echo '.github/workflows/build_stages.yml' >> .github/stage_requirements/${{ matrix.variant }}.txt + echo '.github/stage_requirements/${{ matrix.variant }}.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt - name: Get changed files since fork point - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v34.0.0 if: github.event.inputs.base_ref != '' id: changed-files-base with: @@ -216,7 +222,7 @@ jobs: files_from_source_file: | .github/stage_requirements/${{ matrix.variant }}.txt - name: Get changed files since last commit - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v34.0.0 if: github.event.inputs.base_ref == '' id: changed-files with: @@ -229,8 +235,7 @@ jobs: TAG="stage-base:${{ matrix.variant }}-$(cat version)" DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV - docker manifest inspect $DOCKER_TAG >/dev/null - echo "::set-output name=not_yet_exists::$?" + docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT id: docker_tag - name: Clear up some space on runner if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 @@ -240,7 +245,7 @@ jobs: sudo rm -rf "/usr/local/share/boost" sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1.6.0 + uses: docker/setup-buildx-action@v2.2.1 if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - name: Log in to GitHub Container Registry uses: docker/login-action@v2 @@ -258,7 +263,7 @@ jobs: run: cat .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - name: Build and push base image - uses: docker/build-push-action@v2.9.0 + uses: docker/build-push-action@v3.2.0 with: context: . file: .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile @@ -266,7 +271,7 @@ jobs: tags: | ${{ env.DOCKER_TAG }} cache-from: type=gha - cache-to: type=gha,mode=max + cache-to: type=gha,mode=min if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 trigger-next-workflow: diff --git a/.github/workflows/check_updated_version.yml b/.github/workflows/check_updated_preconfigs.yml similarity index 68% rename from .github/workflows/check_updated_version.yml rename to .github/workflows/check_updated_preconfigs.yml index 21db9eba82..eb0d4a190f 100755 --- a/.github/workflows/check_updated_version.yml +++ b/.github/workflows/check_updated_preconfigs.yml @@ -1,24 +1,67 @@ -name: Check updated version +name: Check updated preconfigs on: - pull_request_target: - types: [edited, opened, reopened, ready_for_review, synchronize] push: jobs: - check-updated-version: - name: Check if version updated + check-updated-preconfigs: + name: Check if preconfigs need updated runs-on: ubuntu-latest steps: - name: Check out C-PAC uses: actions/checkout@v2 with: fetch-depth: 2 + - uses: actions/setup-python@v4 + with: + python-version: '3.9' + cache: 'pip' - name: Check if version updated run: | git config --global user.email "CMI_CPAC_Support@childmind.org" git config --global user.name "Theodore (Machine User)" GITHUB_BRANCH=$(echo ${GITHUB_REF} | cut -d '/' -f 3-) + export PYTHONPATH=$PWD + pip install -q wheel + pip install -q nipype numpy matplotlib pandas pathvalidate pytz pyyaml voluptuous yamlordereddictloader + python ./CPAC/utils/configuration/yaml_template.py + if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] + then + git add CPAC/resources/configs + git commit -m ":bulb: Update comments based on default preconfig" + fi + COMMIT_MESSAGE=$(git log -1 --pretty=%B) + if [[ ! "$COMMIT_MESSAGE" == *"Update version to"* ]] + then + cd CPAC + VERSION=$(python -c "from info import __version__; print('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__)") + cd .. + echo "v${VERSION}" > version + find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; + git add version + VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) + export PATTERN="(declare|typeset) -a" + if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] + then + for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") + do + export IFS="" + for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) + do + echo "Updating stage tags in ${DOCKERFILE}" + sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} + done + done + unset IFS + fi + if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] + then + git add CPAC/resources/configs .github/Dockerfiles + git commit -m ":bookmark: Update version to ${VERSION} ($COMMIT_MESSAGE)" || true + git push origin HEAD:${GITHUB_BRANCH} || true + fi + cd .. + fi if [[ "${GITHUB_REF_TYPE}" == "tag" ]] then cd $HOME/work/C-PAC/C-PAC @@ -37,26 +80,9 @@ jobs: [skip ci]" git push origin HEAD:${GITHUB_BRANCH} || true fi - COMMIT_MESSAGE=$(git log -1 --pretty=%B) - if [[ ! "$COMMIT_MESSAGE" == *"Update version to"* ]] - then - cd CPAC - VERSION=$(python -c "from info import __version__; print('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__)") - cd .. - echo "v${VERSION}" > version - sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" dev/docker_data/default_pipeline.yml - find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; - git add version CPAC/resources/configs dev/docker_data/default_pipeline.yml - if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] - then - git commit -m ":bookmark: Update version to ${VERSION} ($COMMIT_MESSAGE)" - git push origin HEAD:${GITHUB_BRANCH} || true - fi - cd .. - fi trigger-next-workflow: - needs: check-updated-version + needs: check-updated-preconfigs runs-on: ubuntu-latest steps: - name: Set up check diff --git a/.github/workflows/delete_images.yml b/.github/workflows/delete_images.yml index 36db669a8b..98ab8e75c9 100755 --- a/.github/workflows/delete_images.yml +++ b/.github/workflows/delete_images.yml @@ -42,3 +42,11 @@ jobs: -u ${GITHUB_TOKEN}: \ -X DELETE \ https://api.github.com/${OWNER_TYPE}/${OWNER}/packages/container/c-pac/versions/${VERSION_ID} + - name: Delete all containers from repository without tags + uses: Chizkiyahu/delete-untagged-ghcr-action@v2 + with: + token: ${GITHUB_TOKEN} + repository_owner: ${{ github.repository_owner }} + repository: ${{ github.repository }} + untagged_only: true + owner_type: org diff --git a/.github/workflows/deploy_to_Docker_Hub.yml b/.github/workflows/deploy_to_Docker_Hub.yml index 3dbcfa693d..f9d41f9b48 100755 --- a/.github/workflows/deploy_to_Docker_Hub.yml +++ b/.github/workflows/deploy_to_Docker_Hub.yml @@ -28,13 +28,18 @@ jobs: then VARIANT=-${{ inputs.variant }} fi - TAG1=latest$VARIANT - TAG2=release-${{ github.ref_name }}$VARIANT + TAG_PATTERN='^v[0-9]+\.[0-9]+\.[0-9]+$' + TAG1=release-${{ github.ref_name }}$VARIANT DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}" | tr '[:upper:]' '[:lower:]') echo "original tag: ${DOCKER_TAG}:${TAG1}" - echo "new tags: fcpindi/c-pac:${TAG1} fcpindi/c-pac:${TAG2}" - docker pull ${DOCKER_TAG}:${TAG1} docker tag ${DOCKER_TAG}:${TAG1} fcpindi/c-pac:${TAG1} - docker tag ${DOCKER_TAG}:${TAG1} fcpindi/c-pac:${TAG2} docker push fcpindi/c-pac:${TAG1} - docker push fcpindi/c-pac:${TAG2} + if [[ ${{ github.ref_name }} =~ ${TAG_PATTERN} ]] + then + TAG2=latest$VARIANT + docker tag ${DOCKER_TAG}:${TAG1} fcpindi/c-pac:${TAG2} + docker push fcpindi/c-pac:${TAG2} + echo "new tags: fcpindi/c-pac:${TAG1} fcpindi/c-pac:${TAG2}" + else + echo "new tags: fcpindi/c-pac:${TAG1}" + fi diff --git a/.github/workflows/smoke_test_participant.yml b/.github/workflows/smoke_test_participant.yml index 65e924bbcd..b09441a3dd 100755 --- a/.github/workflows/smoke_test_participant.yml +++ b/.github/workflows/smoke_test_participant.yml @@ -36,21 +36,25 @@ jobs: - fx-options - ndmg - preproc - # - rbc-options - # - regtest-1 - # - regtest-2 - # - regtest-3 - # - regtest-4 + - rbc-options + - regtest-1 + - regtest-2 + - regtest-3 + - regtest-4 variant: - '' - - lite - - ABCD-HCP - - fMRIPrep-LTS participant: - - 1019436 2014113 3154996 3699991 3884955 # ADHD200 - - NDARAA504CRN NDARAA947ZG5 NDARAB348EWR NDARAB458VK9 # HBN with EPI field maps - - NDARAD481FXF NDARAV894XWD NDARCA186WGH # HBN with gradient echo field maps - - 0025428 0025429 0025448 0025452 0025453 # CoRR HNU + - 1019436 2014113 3154996 3699991 3884955 NDARAA504CRN NDARAA947ZG5 NDARAB348EWR NDARAB458VK9 NDARAD481FXF NDARAV894XWD NDARCA186WGH 0025428 0025429 0025448 0025452 0025453 + include: + - preconfig: default + variant: lite + participant: 1019436 2014113 3154996 3699991 3884955 NDARAA504CRN NDARAA947ZG5 NDARAB348EWR NDARAB458VK9 NDARAD481FXF NDARAV894XWD NDARCA186WGH 0025428 0025429 0025448 0025452 0025453 + - preconfig: abcd-options + variant: ABCD-HCP + participant: 1019436 2014113 3154996 3699991 3884955 NDARAA504CRN NDARAA947ZG5 NDARAB348EWR NDARAB458VK9 NDARAD481FXF NDARAV894XWD NDARCA186WGH 0025428 0025429 0025448 0025452 0025453 + - preconfig: fmriprep-options + variant: fMRIPrep-LTS + participant: 1019436 2014113 3154996 3699991 3884955 NDARAA504CRN NDARAA947ZG5 NDARAB348EWR NDARAB458VK9 NDARAD481FXF NDARAV894XWD NDARCA186WGH 0025428 0025429 0025448 0025452 0025453 steps: - name: Get C-PAC run: | @@ -101,7 +105,7 @@ jobs: if: ${{ always() }} with: name: expectedOutputs human ${{ matrix.preconfig }} ${{ matrix.variant }} ${{ matrix.participant }} - path: outputs/log/pipeline_*/sub-*/*_expectedOutputs.yml + path: outputs/log/pipeline_*/*/*_expectedOutputs.yml if-no-files-found: ignore smoke_test_nhp: name: Non-human primate ${{ matrix.preconfig }} participant smoke tests @@ -113,25 +117,19 @@ jobs: matrix: preconfig: - monkey - # - monkey-ABCD - nhp-macaque variant: - '' - - lite - - ABCD-HCP - - fMRIPrep-LTS participant: - - 032102 032106 # Newcastle - - 032164 032167 # Oxford - - 032130 032128 # UC Davis - - 2215 2312 # UW Madison - - 032191 032195 # UWO - exclude: - # No T2w + - 032102 032106 032164 032167 032130 032128 2215 2312 032191 032195 + include: + # requires T2w - preconfig: monkey-ABCD - participant: 2215 2312 + variant: '' + participant: 032102 032106 032130 032128 032191 032195 - preconfig: monkey-ABCD - participant: 032164 032167 + variant: ABCD-HCP + participant: 032102 032106 032130 032128 032191 032195 steps: - name: Get C-PAC run: | @@ -181,7 +179,7 @@ jobs: if: ${{ always() }} with: name: expectedOutputs nhp ${{ matrix.preconfig }} ${{ matrix.variant }} ${{ matrix.participant }} - path: outputs/log/pipeline_*/sub-*/*_expectedOutputs.yml + path: outputs/log/pipeline_*/*/*_expectedOutputs.yml if-no-files-found: ignore smoke_test_rodent: name: Rodent participant smoke tests @@ -193,9 +191,6 @@ jobs: matrix: variant: - '' - - lite - - ABCD-HCP - - fMRIPrep-LTS steps: - name: Get C-PAC run: | @@ -244,7 +239,7 @@ jobs: if: ${{ always() }} with: name: expectedOutputs rodent ${{ matrix.variant }} - path: outputs/log/pipeline_*/sub-*/*_expectedOutputs.yml + path: outputs/log/pipeline_*/*/*_expectedOutputs.yml if-no-files-found: ignore finish-check: name: Finish GitHub check diff --git a/.gitignore b/.gitignore index e652d89bf7..61dad5a2d7 100755 --- a/.gitignore +++ b/.gitignore @@ -17,9 +17,6 @@ develop-eggs .installed.cfg .env* -# Copy from packaging -CPAC/resources/configs/default_pipeline.yml - # Installer logs pip-log.txt diff --git a/.pylintrc b/.pylintrc index 97a947e3c6..41277323fd 100755 --- a/.pylintrc +++ b/.pylintrc @@ -291,7 +291,7 @@ contextmanager-decorators=contextlib.contextmanager # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. -generated-members= +generated-members=CPAC.utils.configuration.configuration.Configuration.* # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). @@ -428,18 +428,25 @@ function-naming-style=snake_case # Good variable names which should always be accepted, separated by a comma. good-names=c, e, + f, i, j, k, ex, nb, Run, + TR, + v, wf, _, # Good variable names regexes, separated by a comma. If names match any regex, # they will always be accepted -good-names-rgxs=^_version_(extra|m[a-n]{2}[or]{2})$ # version parts in info.py +good-names-rgxs=^_version_(extra|m[a-n]{2}[or]{2})$, # version parts in info.py + .*EPI.*, + .*TE.*, + .*T1.*, + .*T2.* # Include a hint for the correct naming format with invalid-name. include-naming-hint=yes diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c33144bd..4c513cdfe5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,63 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [unreleased] + +### Added +- Added the ability to downsample to 10K or 2K resolution for freesurfer runs +- Added the ability to run AFNI 3dDespike on template-space BOLD data. +- Added the ability to ingress TotalReadoutTime from epi field map meta-data from the JSON sidecars. +- Added the ability to use TotalReadoutTime of epi field maps in the calculation of FSL topup distortion correction. +- Difference method (`-`) for `CPAC.utils.configuration.Configuration` instances +- Calculate reho and alff when timeseries in template space +- Added new default pipeline that uses FSL-BET for brain extraction. Previous default pipleine is now called default-deprecated. +- Added `fail_fast` configuration setting and CLI flag +- Added abililty to fork on motion filter +- Added [`sdcflows`](https://www.nipreps.org/sdcflows/2.0/) to CPAC requirements +- Added NodeBlock information to `pypeline.log` when verbose debugging is on +- Added the ability to ingress FreeSurfer data into CPAC +- Added the ability to toggle FreeSurfer derived masks for brain extraction + +### Changed +- Freesurfer output directory ingress moved to the data configuration YAML +- Space labels in output filenames now contain specific template labels for MNI templates +- Added a level of depth to `working` directories to match `log` and `output` directory structure +- Renamed participant-pipeline-level `output` directory prefix to `pipeline_` to match `log` and `working` paths +- Changed the 1mm atlases chosen in the rbc-options preconfig to the 2mm versions +- For Nilearn-generated correlation matrices, diagonals are now set to all `1`s (were all `0`s) +- Added ability to apply nusiance correction to template-space BOLD images +- Removed ability to run single-step-resampling on motion-corrected BOLD data +- Moved default pipeline config into directory with other preconfigs +- Added crash messages from during and before graph building to logs +- Added data-config-specific hash string to C-PAC-generated config files +- Updated `rbc-options` preconfig to use `fmriprep-options` preprocessing +- Changed minimized pipeline base from `default` to `blank` +- Removed deprecated `--disable_file_logging` CLI flag +- Improved flexibility of some pipeline options regarding the application of distortion correction transforms +- Pinned AFNI to AFNI_21.1.00 +- Updated some output filenaming conventions for human-readability and to move closer to BIDS-derivatives compliance +- Changed motion filter from single dictionary to list of dictionaries +- Changed CI logic to allow non-release tags + +### Upgraded dependencies +- `nibabel` 2.3.3 → 3.0.1 +- `numpy` 1.16.4 → 1.21.0 +- `pandas` 0.23.4 → 1.0.5 +- `pybids` 0.13.2 → 0.15.1 +- `scipy` 1.4.1 → 1.6.0 + +### Fixed +- Fixed an issue where the distortion correction un-warps were not being applied to the final template-space BOLD time series data depending on pipeline configuration decisions. +- Fixed [a bug](https://github.com/FCP-INDI/C-PAC/issues/1779) in which generated pipeline configs were not 100% accurate. The only affected configurable option discovered in testing was seed-based correlation analysis always reverting to the default configuration. +- Fixed [bug](https://github.com/FCP-INDI/C-PAC/issues/1795) that was causing `cpac run` to fail when passing a manual random seed via `--random_seed`. +- Replaces `DwellTime` with `EffectiveEchoSpacing` for FSL usage of the term +- Fixed an issue that was causing some epi field maps to not be ingressed if the BIDS tags were not in the correct order. +- Fixed an issue where some phase-difference GRE field map files were not properly being ingressed if the filenames were not expected. +- Fixed a bug where ALFF & f/ALFF would not run if frequency filtering was disabled earlier in the pipeline. +- Fixed a bug where `surface_analysis.freesurfer.freesurfer_dir` in the pipeline config was not ingressed at runtime. +- Added public read access to some overly restricted packaged templates +- Fixed a bug where notch filter was always assuming the sampling frequency was `2.0`. + ## [v1.8.4] - 2022-06-27 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19d9e55a15..d3f3069719 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,17 @@ C-PAC is free software: you can redistribute it and/or modify it under the terms C-PAC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with C-PAC. If not, see . --> +## Git branches, tags and continuous integration +GitHub Actions builds C-PAC images for each branch and tag pushed to GitHub; these images are pushed to [GHCR](https://github.com/FCP-INDI/C-PAC/pkgs/container/c-pac/versions) and deleted upon branch deletion on GitHub. + +If a commit is pushed or merged into [`develop` on GitHub](https://github.com/FCP-INDI/C-PAC/tree/develop), GitHub Actions will push [`nightly` and its variants to Docker Hub](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=nightly). + +If a tag is pushed to GitHub that matches the regular expression +```Regular Expression +^v[0-9]+\.[0-9]+\.[0-9]+$ +``` +GitHub Actions will push [`release-${TAG}` and its variants](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=release-) and [`latest` and its variants to Docker Hub](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=latest). + ## Software dependencies and variant images We currently have one main and 3 variant images: * `ABCD-HCP`: dependency versions matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/releases/tag/v0.1.1) versions diff --git a/CPAC/alff/alff.py b/CPAC/alff/alff.py index 15a09c90f2..dd04dc7bdc 100755 --- a/CPAC/alff/alff.py +++ b/CPAC/alff/alff.py @@ -246,9 +246,9 @@ def alff_falff(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["desc-cleaned_bold", "desc-brain_bold", "desc-preproc_bold", - "bold"], - "space-bold_desc-brain_mask"], + "inputs": [(["desc-denoisedNofilt_bold", + "desc-preproc_bold"], + "space-bold_desc-brain_mask")], "outputs": ["alff", "falff"]} ''' @@ -262,8 +262,8 @@ def alff_falff(wf, cfg, strat_pool, pipe_num, opt=None): alff.get_node('hp_input').iterables = ('hp', alff.inputs.hp_input.hp) alff.get_node('lp_input').iterables = ('lp', alff.inputs.lp_input.lp) - node, out = strat_pool.get_data(["desc-cleaned_bold", "desc-brain_bold", - "desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data(["desc-denoisedNofilt_bold", + "desc-preproc_bold"]) wf.connect(node, out, alff, 'inputspec.rest_res') node, out = strat_pool.get_data('space-bold_desc-brain_mask') @@ -275,3 +275,40 @@ def alff_falff(wf, cfg, strat_pool, pipe_num, opt=None): } return (wf, outputs) + + +def alff_falff_space_template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "alff_falff_space_template", + "config": ["amplitude_low_frequency_fluctuation"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": [(["space-template_res-derivative_desc-denoisedNofilt_bold", + "space-template_res-derivative_desc-preproc_bold"], + "space-template_res-derivative_desc-bold_mask")], + "outputs": ["space-template_alff", + "space-template_falff"]} + ''' + alff = create_alff(f'alff_falff_{pipe_num}') + + alff.inputs.hp_input.hp = \ + cfg.amplitude_low_frequency_fluctuation['highpass_cutoff'] + alff.inputs.lp_input.lp = \ + cfg.amplitude_low_frequency_fluctuation['lowpass_cutoff'] + alff.get_node('hp_input').iterables = ('hp', alff.inputs.hp_input.hp) + alff.get_node('lp_input').iterables = ('lp', alff.inputs.lp_input.lp) + + node, out = strat_pool.get_data(["space-template_res-derivative_desc-denoisedNofilt_bold", + "space-template_res-derivative_desc-preproc_bold"]) + wf.connect(node, out, alff, 'inputspec.rest_res') + + node, out = strat_pool.get_data("space-template_res-derivative_desc-bold_mask") + wf.connect(node, out, alff, 'inputspec.rest_mask') + + outputs = { + 'space-template_alff': (alff, 'outputspec.alff_img'), + 'space-template_falff': (alff, 'outputspec.falff_img') + } + + return (wf, outputs) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index eac127c152..fad2199e0a 100755 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +from copy import deepcopy import os +from nipype import logging from nipype.interfaces import afni from nipype.interfaces import ants from nipype.interfaces import fsl @@ -15,9 +17,12 @@ wb_command, \ fslmaths_command, \ VolumeRemoveIslands +from CPAC.pipeline.engine import flatten_list +from CPAC.utils.docs import docstring_parameter from CPAC.utils.interfaces.fsl import Merge as fslMerge from CPAC.utils.interfaces.function.seg_preproc import \ pick_tissue_from_labels_file_interface +from CPAC.utils.monitoring import WARNING_FREESURFER_OFF_WITH_DATA from CPAC.unet.function import predict_volumes @@ -542,16 +547,12 @@ def afni_brain_connector(wf, cfg, strat_pool, pipe_num, opt): name=f'anat_skullstrip_{pipe_num}') anat_skullstrip.inputs.outputtype = 'NIFTI_GZ' - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w','T1w']) + if strat_pool.check_rpool('desc-preproc_T1w'): + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_skullstrip, 'in_file') - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w','T2w']) + elif strat_pool.check_rpool('desc-preproc_T2w'): + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_skullstrip, 'in_file') wf.connect(skullstrip_args, 'expr', anat_skullstrip, 'args') @@ -566,16 +567,12 @@ def afni_brain_connector(wf, cfg, strat_pool, pipe_num, opt): wf.connect(anat_skullstrip, 'out_file', anat_brain_mask, 'in_file_a') - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): outputs = { 'space-T1w_desc-brain_mask': (anat_brain_mask, 'out_file') } - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): + elif strat_pool.check_rpool('desc-preproc_T2w'): outputs = { 'space-T2w_desc-brain_mask': (anat_brain_mask, 'out_file') } @@ -638,16 +635,12 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w','T1w']) + if strat_pool.check_rpool('desc-preproc_T1w'): + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_skullstrip, 'in_file') - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w','T2w']) + elif strat_pool.check_rpool('desc-preproc_T2w'): + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_skullstrip, 'in_file') wf.connect([ @@ -668,16 +661,12 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): ]) ]) - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): outputs = { 'space-T1w_desc-brain_mask': (anat_skullstrip, 'mask_file') } - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): + elif strat_pool.check_rpool('desc-preproc_T2w'): outputs = { 'space-T2w_desc-brain_mask': (anat_skullstrip, 'mask_file') } @@ -701,29 +690,21 @@ def niworkflows_ants_brain_connector(wf, cfg, strat_pool, pipe_num, opt): atropos_use_random_seed=cfg.pipeline_setup['system_config'][ 'random_seed'] is None) - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w','T1w']) + if strat_pool.check_rpool('desc-preproc_T1w'): + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_skullstrip_ants, 'inputnode.in_files') - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w','T2w']) + elif strat_pool.check_rpool('desc-preproc_T2w'): + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_skullstrip_ants, 'inputnode.in_files') - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): outputs = { 'space-T1w_desc-brain_mask': (anat_skullstrip_ants, 'atropos_wf.copy_xform.out_mask'), 'desc-preproc_T1w': (anat_skullstrip_ants, 'copy_xform.out_file') } - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): + elif strat_pool.check_rpool('desc-preproc_T2w'): outputs = { 'space-T2w_desc-brain_mask': (anat_skullstrip_ants, 'atropos_wf.copy_xform.out_mask'), 'desc-preproc_T2w': (anat_skullstrip_ants, 'copy_xform.out_file') @@ -750,16 +731,12 @@ def unet_brain_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('unet-model') wf.connect(node, out, unet_mask, 'model_path') - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w','T1w']) + if strat_pool.check_rpool('desc-preproc_T1w'): + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, unet_mask, 'cimg_in') - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w','T2w']) + elif strat_pool.check_rpool('desc-preproc_T2w'): + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, unet_mask, 'cimg_in') """ @@ -770,16 +747,12 @@ def unet_brain_connector(wf, cfg, strat_pool, pipe_num, opt): name=f'unet_masked_brain_{pipe_num}') unet_masked_brain.inputs.op_string = "-mul %s" - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w','T1w']) + if strat_pool.check_rpool('desc-preproc_T1w'): + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, unet_masked_brain, 'in_file') - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w','T2w']) + elif strat_pool.check_rpool('desc-preproc_T2w'): + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, unet_masked_brain, 'in_file') wf.connect(unet_mask, 'out_path', unet_masked_brain, 'operand_files') @@ -802,16 +775,12 @@ def unet_brain_connector(wf, cfg, strat_pool, pipe_num, opt): f'head_{pipe_num}') native_head_to_template_head.inputs.apply_xfm = True - if strat_pool.check_rpool('desc-preproc_T1w') or \ - strat_pool.check_rpool('desc-reorient_T1w') or \ - strat_pool.check_rpool('T1w'): - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w','T1w']) + if strat_pool.check_rpool('desc-preproc_T1w'): + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, native_head_to_template_head, 'in_file') - elif strat_pool.check_rpool('desc-preproc_T2w') or \ - strat_pool.check_rpool('desc-reorient_T2w') or \ - strat_pool.check_rpool('T2w'): - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w','T2w']) + elif strat_pool.check_rpool('desc-preproc_T2w'): + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, native_head_to_template_head, 'in_file') wf.connect(native_brain_to_template_brain, 'out_matrix_file', @@ -901,10 +870,10 @@ def freesurfer_brain_connector(wf, cfg, strat_pool, pipe_num, opt): name='fs_brain_mask_to_native') fs_brain_mask_to_native.inputs.reg_header = True - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + node, out = strat_pool.get_data('pipeline-fs_brainmask') wf.connect(node, out, fs_brain_mask_to_native, 'source_file') - node, out = strat_pool.get_data('raw-average') + node, out = strat_pool.get_data('pipeline-fs_raw-average') wf.connect(node, out, fs_brain_mask_to_native, 'target_file') node, out = strat_pool.get_data('freesurfer-subject-dir') @@ -953,7 +922,7 @@ def freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt): name=f'wmparc_to_nifti_{pipe_num}') wmparc_to_nifti.inputs.args = '-rt nearest' - node, out = strat_pool.get_data('wmparc') + node, out = strat_pool.get_data('pipeline-fs_wmparc') wf.connect(node, out, wmparc_to_nifti, 'in_file') node, out = strat_pool.get_data('desc-preproc_T1w') @@ -1007,7 +976,7 @@ def freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): function=mri_convert), name=f'convert_fs_brainmask_to_nifti_{node_id}') - node, out = strat_pool.get_data('brainmask') + node, out = strat_pool.get_data('pipeline-fs_brainmask') wf.connect(node, out, convert_fs_brainmask_to_nifti, 'in_file') # mri_convert -it mgz ${SUBJECTS_DIR}/${subject}/mri/T1.mgz -ot nii T1.nii.gz @@ -1016,7 +985,7 @@ def freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): function=mri_convert), name=f'convert_fs_T1_to_nifti_{node_id}') - node, out = strat_pool.get_data('T1') + node, out = strat_pool.get_data('pipeline-fs_T1') wf.connect(node, out, convert_fs_T1_to_nifti, 'in_file') # 3dresample -orient RPI -inset brainmask.nii.gz -prefix brain_fs.nii.gz @@ -1149,7 +1118,7 @@ def freesurfer_fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): wf.connect(binarize_combined_mask, 'out_file', fs_fsl_brain_mask_to_native, 'source_file') - node, out = strat_pool.get_data('raw-average') + node, out = strat_pool.get_data('pipeline-fs_raw-average') wf.connect(node, out, fs_fsl_brain_mask_to_native, 'target_file') node, out = strat_pool.get_data('freesurfer-subject-dir') @@ -1240,7 +1209,8 @@ def anatomical_init(wf, cfg, strat_pool, pipe_num, opt=None): "option_val": "None", "inputs": ["T1w"], "outputs": ["desc-preproc_T1w", - "desc-reorient_T1w"]} + "desc-reorient_T1w", + "desc-head_T1w"]} ''' anat_deoblique = pe.Node(interface=afni.Refit(), @@ -1260,7 +1230,8 @@ def anatomical_init(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(anat_deoblique, 'out_file', anat_reorient, 'in_file') outputs = {'desc-preproc_T1w': (anat_reorient, 'out_file'), - 'desc-reorient_T1w': (anat_reorient, 'out_file')} + 'desc-reorient_T1w': (anat_reorient, 'out_file'), + 'desc-head_T1w': (anat_reorient, 'out_file')} return (wf, outputs) @@ -1273,9 +1244,11 @@ def acpc_align_head(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], + "inputs": ["desc-head_T1w", + "desc-preproc_T1w", "T1w-ACPC-template"], - "outputs": ["desc-preproc_T1w", + "outputs": ["desc-head_T1w", + "desc-preproc_T1w", "from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm"]} ''' @@ -1285,17 +1258,18 @@ def acpc_align_head(wf, cfg, strat_pool, pipe_num, opt=None): mask=False, wf_name=f'acpc_align_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data(['desc-head_T1w', 'desc-preproc_T1w']) wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('T1w-ACPC-template') wf.connect(node, out, acpc_align, 'inputspec.template_head_for_acpc') outputs = { + 'desc-head_T1w': (acpc_align, 'outputspec.acpc_aligned_head'), 'desc-preproc_T1w': (acpc_align, 'outputspec.acpc_aligned_head'), 'from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm': ( - acpc_align, 'outputspec.from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm') + acpc_align, + 'outputspec.from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm') } return (wf, outputs) @@ -1309,11 +1283,12 @@ def acpc_align_head_with_mask(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - "space-T1w_desc-brain_mask"), + "inputs": [("desc-head_T1w", "desc-preproc_T1w", + "space-T1w_desc-brain_mask"), "T1w-ACPC-template", "T1w-brain-ACPC-template"], - "outputs": ["desc-preproc_T1w", + "outputs": ["desc-head_T1w", + "desc-preproc_T1w", "space-T1w_desc-brain_mask", "from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm"]} ''' @@ -1324,21 +1299,21 @@ def acpc_align_head_with_mask(wf, cfg, strat_pool, pipe_num, opt=None): mask=True, wf_name=f'acpc_align_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data(['desc-head_T1w', 'desc-preproc_T1w']) wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('T1w-ACPC-template') wf.connect(node, out, acpc_align, 'inputspec.template_head_for_acpc') - if strat_pool.check_rpool('space-T1w_desc-brain_mask'): - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + if strat_pool.check_rpool("space-T1w_desc-brain_mask"): + node, out = strat_pool.get_data("space-T1w_desc-brain_mask") wf.connect(node, out, acpc_align, 'inputspec.brain_mask') node, out = strat_pool.get_data('T1w-brain-ACPC-template') wf.connect(node, out, acpc_align, 'inputspec.template_brain_for_acpc') outputs = { + 'desc-head_T1w': (acpc_align, 'outputspec.acpc_aligned_head'), 'desc-preproc_T1w': (acpc_align, 'outputspec.acpc_aligned_head'), 'space-T1w_desc-brain_mask': ( acpc_align, 'outputspec.acpc_brain_mask'), @@ -1357,7 +1332,7 @@ def acpc_align_brain(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], + "inputs": [("desc-preproc_T1w", "desc-tempbrain_T1w", "T1w-ACPC-template", "T1w-brain-ACPC-template")], @@ -1372,8 +1347,7 @@ def acpc_align_brain(wf, cfg, strat_pool, pipe_num, opt=None): mask=False, wf_name=f'acpc_align_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('desc-tempbrain_T1w') @@ -1403,8 +1377,9 @@ def acpc_align_brain_with_mask(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - "desc-tempbrain_T1w", "space-T1w_desc-brain_mask"), + "inputs": [("desc-preproc_T1w", + "desc-tempbrain_T1w", + "space-T1w_desc-brain_mask"), "T1w-ACPC-template", "T1w-brain-ACPC-template"], "outputs": ["desc-preproc_T1w", @@ -1419,14 +1394,13 @@ def acpc_align_brain_with_mask(wf, cfg, strat_pool, pipe_num, opt=None): mask=True, wf_name=f'acpc_align_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('desc-tempbrain_T1w') wf.connect(node, out, acpc_align, 'inputspec.anat_brain') - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + node, out = strat_pool.get_data("space-T1w_desc-brain_mask") wf.connect(node, out, acpc_align, 'inputspec.brain_mask') node, out = strat_pool.get_data('T1w-ACPC-template') @@ -1439,7 +1413,7 @@ def acpc_align_brain_with_mask(wf, cfg, strat_pool, pipe_num, opt=None): 'desc-preproc_T1w': (acpc_align, 'outputspec.acpc_aligned_head'), 'desc-acpcbrain_T1w': (acpc_align, 'outputspec.acpc_aligned_brain'), 'space-T1w_desc-brain_mask': (acpc_align, 'outputspec.acpc_brain_mask'), - 'space-T1w_desc-prebrain_mask': (strat_pool.get_data('space-T1w_desc-brain_mask')) + 'space-T1w_desc-prebrain_mask': (strat_pool.get_data(desc_brain_mask)) } return (wf, outputs) @@ -1452,8 +1426,8 @@ def registration_T2w_to_T1w(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run_t2"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - ["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": [("desc-preproc_T1w", + "desc-preproc_T2w", 'desc-acpcbrain_T1w', 'desc-acpcbrain_T2w')], "outputs": ["desc-preproc_T2w"]} @@ -1461,12 +1435,10 @@ def registration_T2w_to_T1w(wf, cfg, strat_pool, pipe_num, opt=None): T2_to_T1_reg = T2wToT1wReg(wf_name=f'T2w_to_T1w_Reg_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, T2_to_T1_reg, 'inputspec.T1w') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, T2_to_T1_reg, 'inputspec.T2w') node, out = strat_pool.get_data(['desc-acpcbrain_T1w']) @@ -1490,7 +1462,7 @@ def non_local_means(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": ["T1w"], + "inputs": ["desc-preproc_T1w"], "outputs": ["desc-preproc_T1w"]} ''' @@ -1499,7 +1471,7 @@ def non_local_means(wf, cfg, strat_pool, pipe_num, opt=None): denoise.inputs.noise_model = cfg.anatomical_preproc['non_local_means_filtering']['noise_model'] - node, out = strat_pool.get_data('T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, denoise, 'input_image') outputs = { @@ -1517,7 +1489,7 @@ def n4_bias_correction(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": { "desc-preproc_T1w": { "Description": "T1w image that has been N4-bias-field corrected @@ -1533,8 +1505,7 @@ def n4_bias_correction(wf, cfg, strat_pool, pipe_num, opt=None): name=f'anat_n4_{pipe_num}') n4.inputs.shrink_factor = cfg.anatomical_preproc['n4_bias_field_correction']['shrink_factor'] - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, n4, 'input_image') outputs = { @@ -1552,8 +1523,8 @@ def t1t2_bias_correction(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - ["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": [("desc-preproc_T1w", + "desc-preproc_T2w", "desc-acpcbrain_T1w")], "outputs": ["desc-preproc_T1w", "desc-brain_T1w", @@ -1564,14 +1535,10 @@ def t1t2_bias_correction(wf, cfg, strat_pool, pipe_num, opt=None): t1t2_bias_correction = BiasFieldCorrection_sqrtT1wXT1w(config=cfg, wf_name=f't1t2_bias_correction_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T1w', - 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, t1t2_bias_correction, 'inputspec.T1w') - node, out = strat_pool.get_data(['desc-preproc_T2w', - 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, t1t2_bias_correction, 'inputspec.T2w') node, out = strat_pool.get_data("desc-acpcbrain_T1w") @@ -1587,7 +1554,6 @@ def t1t2_bias_correction(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) - def brain_mask_afni(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "brain_mask_afni", @@ -1596,7 +1562,7 @@ def brain_mask_afni(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "3dSkullStrip", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": ["space-T1w_desc-brain_mask"]} ''' @@ -1604,7 +1570,6 @@ def brain_mask_afni(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) - def brain_mask_acpc_afni(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "brain_mask_acpc_afni", @@ -1613,7 +1578,7 @@ def brain_mask_acpc_afni(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "3dSkullStrip", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": ["space-T1w_desc-acpcbrain_mask"]} ''' @@ -1626,7 +1591,6 @@ def brain_mask_acpc_afni(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) - def brain_mask_fsl(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "brain_mask_fsl", @@ -1635,7 +1599,7 @@ def brain_mask_fsl(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "BET", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": ["space-T1w_desc-brain_mask"]} ''' @@ -1652,7 +1616,7 @@ def brain_mask_acpc_fsl(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "BET", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": ["space-T1w_desc-acpcbrain_mask"]} ''' @@ -1665,7 +1629,6 @@ def brain_mask_acpc_fsl(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) - def brain_mask_niworkflows_ants(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "brain_mask_niworkflows_ants", @@ -1674,7 +1637,7 @@ def brain_mask_niworkflows_ants(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "niworkflows-ants", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": ["space-T1w_desc-brain_mask", "desc-preproc_T1w"]} ''' @@ -1693,7 +1656,7 @@ def brain_mask_acpc_niworkflows_ants(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "niworkflows-ants", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_T1w"], "outputs": ["space-T1w_desc-acpcbrain_mask", "desc-preproc_T1w"]} ''' @@ -1719,7 +1682,7 @@ def brain_mask_unet(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "UNet", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], + "inputs": ["desc-preproc_T1w", "T1w-brain-template", "T1w-template", "unet-model"], @@ -1739,7 +1702,7 @@ def brain_mask_acpc_unet(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "UNet", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], + "inputs": ["desc-preproc_T1w", "T1w-brain-template", "T1w-template", "unet-model"], @@ -1763,9 +1726,9 @@ def brain_mask_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): "switch": [["anatomical_preproc", "brain_extraction", "run"], ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], - "option_val": "Freesurfer", - "inputs": ["space-T1w_desc-brain_mask", - "raw-average", + "option_val": "FreeSurfer-Brainmask", + "inputs": ["pipeline-fs_raw-average", + "pipeline-fs_brainmask", "freesurfer-subject-dir"], "outputs": ["space-T1w_desc-brain_mask"]} ''' @@ -1783,9 +1746,9 @@ def brain_mask_acpc_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): "switch": [["anatomical_preproc", "brain_extraction", "run"], ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], - "option_val": "Freesurfer", + "option_val": "FreeSurfer-Brainmask", "inputs": ["space-T1w_desc-brain_mask", - "raw-average", + "pipeline-fs_raw-average", "freesurfer-subject-dir"], "outputs": ["space-T1w_desc-acpcbrain_mask"]} ''' @@ -1807,8 +1770,8 @@ def brain_mask_freesurfer_abcd(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "FreeSurfer-ABCD", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - "wmparc", + "inputs": ["desc-preproc_T1w", + "pipeline-fs_wmparc", "freesurfer-subject-dir"], "outputs": ["space-T1w_desc-brain_mask"]} ''' @@ -1826,9 +1789,9 @@ def brain_mask_freesurfer_fsl_tight(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "FreeSurfer-BET-Tight", - "inputs": ["brainmask", - "T1", - "raw-average", + "inputs": ["pipeline-fs_brainmask", + "pipeline-fs_T1", + "pipeline-fs_raw-average", "freesurfer-subject-dir", "T1w-brain-template-mask-ccs", "T1w-ACPC-template"], @@ -1848,8 +1811,8 @@ def brain_mask_acpc_freesurfer_abcd(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "FreeSurfer-ABCD", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - "wmparc", + "inputs": ["desc-preproc_T1w", + "pipeline-fs_wmparc", "freesurfer-subject-dir"], "outputs": ["space-T1w_desc-acpcbrain_mask"]} ''' @@ -1870,9 +1833,9 @@ def brain_mask_freesurfer_fsl_loose(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "FreeSurfer-BET-Loose", - "inputs": ["brainmask", - "T1", - "raw-average", + "inputs": ["pipeline-fs_brainmask", + "pipeline-fs_T1", + "pipeline-fs_raw-average", "freesurfer-subject-dir", "T1w-brain-template-mask-ccs", "T1w-ACPC-template"], @@ -1892,8 +1855,8 @@ def brain_mask_acpc_freesurfer_fsl_tight(wf, cfg, strat_pool, pipe_num, opt=None ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "FreeSurfer-BET-Tight", - "inputs": ["brainmask", - "T1", + "inputs": ["pipeline-fs_brainmask", + "pipeline-fs_T1", "T1w-brain-template-mask-ccs", "T1w-ACPC-template"], "outputs": ["space-T1w_desc-tight_acpcbrain_mask"]} @@ -1915,8 +1878,8 @@ def brain_mask_acpc_freesurfer_fsl_loose(wf, cfg, strat_pool, pipe_num, opt=None ["anatomical_preproc", "run"]], "option_key": ["anatomical_preproc", "brain_extraction", "using"], "option_val": "FreeSurfer-BET-Loose", - "inputs": ["brainmask", - "T1", + "inputs": ["pipeline-fs_brainmask", + "pipeline-fs_T1", "T1w-brain-template-mask-ccs", "T1w-ACPC-template"], "outputs": ["space-T1w_desc-loose_acpcbrain_mask"]} @@ -1938,9 +1901,16 @@ def brain_extraction(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - ["space-T1w_desc-brain_mask", "space-T1w_desc-acpcbrain_mask"])], - "outputs": ["desc-brain_T1w"]} + "inputs": [("desc-head_T1w", "desc-preproc_T1w", + ["space-T1w_desc-brain_mask", "space-T1w_desc-acpcbrain_mask"] + )], + "outputs": { + "desc-preproc_T1w": { + "SkullStripped": "True"}, + "desc-brain_T1w": { + "SkullStripped": "True"}, + "desc-head_T1w": { + "SkullStripped": "False"}}} ''' ''' @@ -1966,16 +1936,17 @@ def brain_extraction(wf, cfg, strat_pool, pipe_num, opt=None): anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) - wf.connect(node, out, anat_skullstrip_orig_vol, 'in_file_a') + node_T1w, out_T1w = strat_pool.get_data('desc-head_T1w') + wf.connect(node_T1w, out_T1w, anat_skullstrip_orig_vol, 'in_file_a') node, out = strat_pool.get_data(['space-T1w_desc-brain_mask', 'space-T1w_desc-acpcbrain_mask']) wf.connect(node, out, anat_skullstrip_orig_vol, 'in_file_b') outputs = { - 'desc-brain_T1w': (anat_skullstrip_orig_vol, 'out_file') + 'desc-preproc_T1w': (anat_skullstrip_orig_vol, 'out_file'), + 'desc-brain_T1w': (anat_skullstrip_orig_vol, 'out_file'), + 'desc-head_T1w': (node_T1w, out_T1w) } return (wf, outputs) @@ -1988,9 +1959,13 @@ def brain_extraction_temp(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], + "inputs": [("desc-preproc_T1w", ["space-T1w_desc-brain_mask", "space-T1w_desc-acpcbrain_mask"])], - "outputs": ["desc-tempbrain_T1w"]} + "outputs": { + "desc-preproc_T1w": { + "SkullStripped": "True"}, + "desc-tempbrain_T1w": { + "SkullStripped": "True"}}} ''' anat_skullstrip_orig_vol = pe.Node(interface=afni.Calc(), @@ -1999,8 +1974,7 @@ def brain_extraction_temp(wf, cfg, strat_pool, pipe_num, opt=None): anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', - 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_skullstrip_orig_vol, 'in_file_a') node, out = strat_pool.get_data(['space-T1w_desc-brain_mask', @@ -2008,6 +1982,7 @@ def brain_extraction_temp(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, anat_skullstrip_orig_vol, 'in_file_b') outputs = { + 'desc-preproc_T1w': (anat_skullstrip_orig_vol, 'out_file'), 'desc-tempbrain_T1w': (anat_skullstrip_orig_vol, 'out_file') } @@ -2023,7 +1998,8 @@ def anatomical_init_T2(wf, cfg, strat_pool, pipe_num, opt=None): "option_val": "None", "inputs": ["T2w"], "outputs": ["desc-preproc_T2w", - "desc-reorient_T2w"]} + "desc-reorient_T2w", + "desc-head_T2w"]} ''' T2_deoblique = pe.Node(interface=afni.Refit(), @@ -2043,7 +2019,8 @@ def anatomical_init_T2(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(T2_deoblique, 'out_file', T2_reorient, 'in_file') outputs = {'desc-preproc_T2w': (T2_reorient, 'out_file'), - 'desc-reorient_T2w': (T2_reorient, 'out_file')} + 'desc-reorient_T2w': (T2_reorient, 'out_file'), + 'desc-head_T2w': (T2_reorient, 'out_file')} return (wf, outputs) @@ -2056,7 +2033,7 @@ def acpc_align_head_T2(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run_t2"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": ["desc-preproc_T2w", "T2w-ACPC-template"], "outputs": ["desc-preproc_T2w"]} ''' @@ -2067,8 +2044,7 @@ def acpc_align_head_T2(wf, cfg, strat_pool, pipe_num, opt=None): mask=False, wf_name=f'acpc_align_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('T2w-ACPC-template') @@ -2089,7 +2065,7 @@ def acpc_align_head_with_mask_T2(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run_t2"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": [("desc-preproc_T2w", "space-T2w_desc-brain_mask"), "T2w-ACPC-template"], "outputs": ["desc-preproc_T2w", @@ -2102,8 +2078,7 @@ def acpc_align_head_with_mask_T2(wf, cfg, strat_pool, pipe_num, opt=None): mask=True, wf_name=f'acpc_align_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('T2w-ACPC-template') @@ -2126,7 +2101,7 @@ def acpc_align_brain_T2(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run_t2"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": [("desc-preproc_T2w", "desc-tempbrain_T2w", "T2w-ACPC-template", "T2w-brain-ACPC-template")], @@ -2140,8 +2115,7 @@ def acpc_align_brain_T2(wf, cfg, strat_pool, pipe_num, opt=None): mask=False, wf_name=f'acpc_align_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('desc-tempbrain_T2w') @@ -2169,7 +2143,7 @@ def acpc_align_brain_with_mask_T2(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run_t2"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": [("desc-preproc_T2w", "desc-tempbrain_T2w", "space-T2w_desc-brain_mask"), "T2w-ACPC-template", "T2w-brain-ACPC-template"], @@ -2183,8 +2157,7 @@ def acpc_align_brain_with_mask_T2(wf, cfg, strat_pool, pipe_num, opt=None): mask=True, wf_name=f'acpc_align_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, acpc_align, 'inputspec.anat_leaf') node, out = strat_pool.get_data('desc-tempbrain_T2w') @@ -2217,15 +2190,14 @@ def non_local_means_T2(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run_t2"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["desc-preproc_T2w"]} ''' denoise = pe.Node(interface=ants.DenoiseImage(), name=f'anat_denoise_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, denoise, 'input_image') outputs = { @@ -2243,7 +2215,7 @@ def n4_bias_correction_T2(wf, cfg, strat_pool, pipe_num, opt=None): ["anatomical_preproc", "run_t2"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["desc-preproc_T2w"]} ''' @@ -2252,8 +2224,7 @@ def n4_bias_correction_T2(wf, cfg, strat_pool, pipe_num, opt=None): copy_header=True), name=f'anat_n4_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, n4, 'input_image') outputs = { @@ -2270,7 +2241,7 @@ def brain_mask_afni_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "3dSkullStrip", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["space-T2w_desc-brain_mask"]} ''' @@ -2286,7 +2257,7 @@ def brain_mask_acpc_afni_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "3dSkullStrip", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["space-T2w_desc-acpcbrain_mask"]} ''' @@ -2307,7 +2278,7 @@ def brain_mask_fsl_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "BET", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["space-T2w_desc-brain_mask"]} ''' @@ -2323,7 +2294,7 @@ def brain_mask_acpc_fsl_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "BET", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["space-T2w_desc-acpcbrain_mask"]} ''' @@ -2344,7 +2315,7 @@ def brain_mask_niworkflows_ants_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "niworkflows-ants", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["space-T2w_desc-brain_mask"]} ''' @@ -2361,7 +2332,7 @@ def brain_mask_acpc_niworkflows_ants_T2(wf, cfg, strat_pool, pipe_num, opt=None) "switch": "None", "option_key": "using", "option_val": "niworkflows-ants", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"]], + "inputs": ["desc-preproc_T2w"], "outputs": ["space-T2w_desc-acpcbrain_mask"]} ''' @@ -2384,7 +2355,7 @@ def brain_mask_unet_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "UNet", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": ["desc-preproc_T2w", "T1w-brain-template", "T1w-template", "unet_model"], @@ -2403,7 +2374,7 @@ def brain_mask_acpc_unet_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "using", "option_val": "UNet", - "inputs": [["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": ["desc-preproc_T2w", "T1w-brain-template", "T1w-template", "unet_model"], @@ -2468,19 +2439,18 @@ def brain_mask_acpc_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run_t2"], "option_key": "None", "option_val": "None", - "inputs": [["desc-reorient_T1w", "T1w"], - ["desc-reorient_T2w", "T2w"], + "inputs": ["desc-reorient_T1w", + "desc-reorient_T2w", ["space-T1w_desc-acpcbrain_mask", "space-T1w_desc-prebrain_mask"]], "outputs": ["space-T2w_desc-acpcbrain_mask"]} ''' brain_mask_T2 = mask_T2(wf_name=f'brain_mask_acpc_T2_{pipe_num}') - node, out = strat_pool.get_data(['desc-reorient_T1w','T1w']) + node, out = strat_pool.get_data('desc-reorient_T1w') wf.connect(node, out, brain_mask_T2, 'inputspec.T1w') - node, out = strat_pool.get_data(['desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-reorient_T2w') wf.connect(node, out, brain_mask_T2, 'inputspec.T2w') node, out = strat_pool.get_data(["space-T1w_desc-acpcbrain_mask", "space-T1w_desc-prebrain_mask"]) @@ -2501,8 +2471,8 @@ def brain_extraction_T2(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": [("desc-acpcbrain_T2w", - ["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], - ["space-T2w_desc-brain_mask", "space-T2w_desc-acpcbrain_mask"])], + "desc-preproc_T2w", + ["space-T2w_desc-brain_mask", "space-T2w_desc-acpcbrain_mask"])], "outputs": ["desc-brain_T2w"]} ''' if cfg.anatomical_preproc['acpc_alignment']['run'] and cfg.anatomical_preproc['acpc_alignment']['acpc_target'] == 'brain': @@ -2516,8 +2486,7 @@ def brain_extraction_T2(wf, cfg, strat_pool, pipe_num, opt=None): anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_skullstrip_orig_vol, 'in_file_a') node, out = strat_pool.get_data(['space-T2w_desc-brain_mask']) @@ -2537,7 +2506,7 @@ def brain_extraction_temp_T2(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run_t2"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_T2w", "desc-reorient_T2w", "T2w"], + "inputs": [("desc-preproc_T2w", ["space-T2w_desc-brain_mask", "space-T2w_desc-acpcbrain_mask"])], "outputs": ["desc-tempbrain_T2w"]} ''' @@ -2548,8 +2517,7 @@ def brain_extraction_temp_T2(wf, cfg, strat_pool, pipe_num, opt=None): anat_skullstrip_orig_vol.inputs.expr = 'a*step(b)' anat_skullstrip_orig_vol.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(['desc-preproc_T2w', 'desc-reorient_T2w', - 'T2w']) + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_skullstrip_orig_vol, 'in_file_a') node, out = strat_pool.get_data(['space-T2w_desc-brain_mask', @@ -2562,39 +2530,199 @@ def brain_extraction_temp_T2(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) +def freesurfer_abcd_preproc(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "freesurfer_abcd_preproc", + "config": ["anatomical_preproc", "brain_extraction"], + "switch": "None", + "option_key": "using", + "option_val": "FreeSurfer-ABCD", + "inputs": ["desc-preproc_T1w", + "T1w-template", + "T1w-brain-template-mask", + "template-ref-mask-res-2", + "T1w-template-res-2", + "freesurfer-subject-dir"], + "outputs": ["desc-restore_T1w", + "desc-restore-brain_T1w", + "pipeline-fs_desc-fast_biasfield", + "pipeline-fs_hemi-L_desc-surface_curv", + "pipeline-fs_hemi-R_desc-surface_curv", + "pipeline-fs_hemi-L_desc-surfaceMesh_pial", + "pipeline-fs_hemi-R_desc-surfaceMesh_pial", + "pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm", + "pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm", + "pipeline-fs_hemi-L_desc-surfaceMesh_sphere", + "pipeline-fs_hemi-R_desc-surfaceMesh_sphere", + "pipeline-fs_hemi-L_desc-surfaceMap_sulc", + "pipeline-fs_hemi-R_desc-surfaceMap_sulc", + "pipeline-fs_hemi-L_desc-surfaceMap_thickness", + "pipeline-fs_hemi-R_desc-surfaceMap_thickness", + "pipeline-fs_hemi-L_desc-surfaceMap_volume", + "pipeline-fs_hemi-R_desc-surfaceMap_volume", + "pipeline-fs_hemi-L_desc-surfaceMesh_white", + "pipeline-fs_hemi-R_desc-surfaceMesh_white", + "pipeline-fs_wmparc", + "freesurfer-subject-dir"]} + ''' + + # fnirt-based brain extraction + brain_extraction = fnirt_based_brain_extraction(config=cfg, + wf_name=f'fnirt_based_brain_extraction_{pipe_num}') + + node, out = strat_pool.get_data('desc-preproc_T1w') + wf.connect(node, out, brain_extraction, 'inputspec.anat_data') + + node, out = strat_pool.get_data('template-ref-mask-res-2') + wf.connect(node, out, brain_extraction, 'inputspec.template-ref-mask-res-2') + + node, out = strat_pool.get_data('T1w-template') + wf.connect(node, out, brain_extraction, 'inputspec.template_skull_for_anat') + + node, out = strat_pool.get_data('T1w-template-res-2') + wf.connect(node, out, brain_extraction, 'inputspec.template_skull_for_anat_2mm') + + node, out = strat_pool.get_data('T1w-brain-template-mask') + wf.connect(node, out, brain_extraction, 'inputspec.template_brain_mask_for_anat') + + # fast bias field correction + fast_correction = fast_bias_field_correction(config=cfg, + wf_name=f'fast_bias_field_correction_{pipe_num}') + + node, out = strat_pool.get_data('desc-preproc_T1w') + wf.connect(node, out, fast_correction, 'inputspec.anat_data') + + wf.connect(brain_extraction, 'outputspec.anat_brain', fast_correction, 'inputspec.anat_brain') + + wf.connect(brain_extraction, 'outputspec.anat_brain_mask', fast_correction, 'inputspec.anat_brain_mask') + + ### ABCD Harmonization ### + # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/FreeSurfer/FreeSurferPipeline.sh#L140-L144 + + # flirt -interp spline -in "$T1wImage" -ref "$T1wImage" -applyisoxfm 1 -out "$T1wImageFile"_1mm.nii.gz + resample_head_1mm = pe.Node(interface=fsl.FLIRT(), + name=f'resample_anat_head_1mm_{pipe_num}') + resample_head_1mm.inputs.interp = 'spline' + resample_head_1mm.inputs.apply_isoxfm = 1 -def freesurfer_preproc(wf, cfg, strat_pool, pipe_num, opt=None): + node, out = strat_pool.get_data('desc-preproc_T1w') + wf.connect(node, out, resample_head_1mm, 'in_file') + + wf.connect(node, out, resample_head_1mm, 'reference') + + # applywarp --rel --interp=spline -i "$T1wImage" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageFile"_1mm.nii.gz + applywarp_head_to_head_1mm = pe.Node(interface=fsl.ApplyWarp(), + name=f'applywarp_head_to_head_1mm_{pipe_num}') + applywarp_head_to_head_1mm.inputs.relwarp = True + applywarp_head_to_head_1mm.inputs.interp = 'spline' + applywarp_head_to_head_1mm.inputs.premat = cfg.registration_workflows['anatomical_registration']['registration']['FSL-FNIRT']['identity_matrix'] + + wf.connect(node, out, applywarp_head_to_head_1mm, 'in_file') + + wf.connect(resample_head_1mm, 'out_file', + applywarp_head_to_head_1mm, 'ref_file') + + # applywarp --rel --interp=nn -i "$T1wImageBrain" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageBrainFile"_1mm.nii.gz + applywarp_brain_to_head_1mm = pe.Node(interface=fsl.ApplyWarp(), + name=f'applywarp_brain_to_head_1mm_{pipe_num}') + applywarp_brain_to_head_1mm.inputs.relwarp = True + applywarp_brain_to_head_1mm.inputs.interp = 'nn' + applywarp_brain_to_head_1mm.inputs.premat = cfg.registration_workflows['anatomical_registration']['registration']['FSL-FNIRT']['identity_matrix'] + + wf.connect(fast_correction, 'outputspec.anat_brain_restore', + applywarp_brain_to_head_1mm, 'in_file') + + wf.connect(resample_head_1mm, 'out_file', + applywarp_brain_to_head_1mm, 'ref_file') + + # fslstats $T1wImageBrain -M + average_brain = pe.Node(interface=fsl.ImageStats(), + name=f'average_brain_{pipe_num}') + average_brain.inputs.op_string = '-M' + average_brain.inputs.output_type = 'NIFTI_GZ' + + wf.connect(fast_correction, 'outputspec.anat_brain_restore', + average_brain, 'in_file') + + # fslmaths "$T1wImageFile"_1mm.nii.gz -div $Mean -mul 150 -abs "$T1wImageFile"_1mm.nii.gz + normalize_head = pe.Node(util.Function(input_names=['in_file', 'number', 'out_file_suffix'], + output_names=['out_file'], + function=fslmaths_command), + name=f'normalize_head_{pipe_num}') + normalize_head.inputs.out_file_suffix = '_norm' + + wf.connect(applywarp_head_to_head_1mm, 'out_file', + normalize_head, 'in_file') + + wf.connect(average_brain, 'out_stat', + normalize_head, 'number') + + if strat_pool.check_rpool('freesurfer-subject-dir'): + outputs = { + 'desc-restore_T1w': (fast_correction, 'outputspec.anat_restore'), + 'desc-restore-brain_T1w': (fast_correction, + 'outputspec.anat_brain_restore'), + 'pipeline-fs_desc-fast_biasfield': (fast_correction, 'outputspec.bias_field')} + return (wf, outputs) + + else: + ### recon-all -all step ### + reconall = pe.Node(interface=freesurfer.ReconAll(), + name=f'anat_freesurfer_{pipe_num}', + mem_gb=2.7) + + sub_dir = cfg.pipeline_setup['working_directory']['path'] + freesurfer_subject_dir = os.path.join(sub_dir, + 'cpac_'+cfg['subject_id'], + f'anat_preproc_freesurfer_{pipe_num}', + 'anat_freesurfer') + + # create the directory for FreeSurfer node + if not os.path.exists(freesurfer_subject_dir): + os.makedirs(freesurfer_subject_dir) + + reconall.inputs.directive = 'all' + reconall.inputs.subjects_dir = freesurfer_subject_dir + reconall.inputs.openmp = cfg.pipeline_setup['system_config']['num_OMP_threads'] + + wf.connect(normalize_head, 'out_file', + reconall, 'T1_files') + + wf, hemisphere_outputs = freesurfer_hemispheres(wf, reconall, pipe_num) + + outputs = { + 'desc-restore_T1w': (fast_correction, 'outputspec.anat_restore'), + 'desc-restore-brain_T1w': (fast_correction, + 'outputspec.anat_brain_restore'), + 'pipeline-fs_desc-fast_biasfield': (fast_correction, 'outputspec.bias_field'), + 'pipeline-fs_wmparc': (reconall, 'wmparc'), + 'freesurfer-subject-dir': (reconall, 'subjects_dir'), + **hemisphere_outputs + } + + return (wf, outputs) + + +# we're grabbing the postproc outputs and appending them to +# the reconall outputs +@docstring_parameter(postproc_outputs=str(flatten_list(freesurfer_abcd_preproc, 'outputs') + ).lstrip('[').replace("'", '"')) + +def freesurfer_reconall(wf, cfg, strat_pool, pipe_num, opt=None): ''' - {"name": "freesurfer_preproc", - "config": ["surface_analysis", "freesurfer"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], - "outputs": ["space-T1w_desc-brain_mask", - "freesurfer-subject-dir", - "hemi-L_desc-surface_curv", - "hemi-R_desc-surface_curv", - "hemi-L_desc-surfaceMesh_pial", - "hemi-R_desc-surfaceMesh_pial", - "hemi-L_desc-surfaceMesh_smoothwm", - "hemi-R_desc-surfaceMesh_smoothwm", - "hemi-L_desc-surfaceMesh_sphere", - "hemi-R_desc-surfaceMesh_sphere", - "hemi-L_desc-surfaceMap_sulc", - "hemi-R_desc-surfaceMap_sulc", - "hemi-L_desc-surfaceMap_thickness", - "hemi-R_desc-surfaceMap_thickness", - "hemi-L_desc-surfaceMap_volume", - "hemi-R_desc-surfaceMap_volume", - "hemi-L_desc-surfaceMesh_white", - "hemi-R_desc-surfaceMesh_white", - "label-CSF_mask", - "label-WM_mask", - "label-GM_mask", - "raw-average", - "brainmask", - "T1"]} + {{"name": "freesurfer_reconall", + "config": ["surface_analysis", "freesurfer"], + "switch": ["run_reconall"], + "option_key": "None", + "option_val": "None", + "inputs": ["desc-preproc_T1w"], + "outputs": ["freesurfer-subject-dir", + "pipeline-fs_raw-average", + "pipeline-fs_subcortical-seg", + "pipeline-fs_brainmask", + "pipeline-fs_wmparc", + "pipeline-fs_T1", + {postproc_outputs}}} ''' reconall = pe.Node(interface=freesurfer.ReconAll(), @@ -2617,114 +2745,38 @@ def freesurfer_preproc(wf, cfg, strat_pool, pipe_num, opt=None): 'num_OMP_threads'] if cfg.surface_analysis['freesurfer']['reconall_args'] is not None: - reconall.inputs.args = cfg.surface_analysis['freesurfer']['reconall_args'] + reconall.inputs.args = cfg.surface_analysis['freesurfer'][ + 'reconall_args'] - node, out = strat_pool.get_data(["desc-preproc_T1w", "desc-reorient_T1w", - "T1w"]) + node, out = strat_pool.get_data("desc-preproc_T1w") wf.connect(node, out, reconall, 'T1_files') - # register FS brain mask to native space - fs_brain_mask_to_native = pe.Node( - interface=freesurfer.ApplyVolTransform(), - name=f'fs_brain_mask_to_native_{pipe_num}') - fs_brain_mask_to_native.inputs.reg_header = True - - wf.connect(reconall, 'brainmask', fs_brain_mask_to_native, 'source_file') - wf.connect(reconall, 'rawavg', fs_brain_mask_to_native, 'target_file') - wf.connect(reconall, 'subjects_dir', - fs_brain_mask_to_native, 'subjects_dir') - - # convert brain mask file from .mgz to .nii.gz - fs_brain_mask_to_nifti = pe.Node(util.Function(input_names=['in_file'], - output_names=['out_file'], - function=mri_convert), - name=f'fs_brainmask_to_nifti_{pipe_num}') - wf.connect(fs_brain_mask_to_native, 'transformed_file', - fs_brain_mask_to_nifti, 'in_file') - - # binarize the brain mask - binarize_fs_brain_mask = pe.Node(interface=fsl.maths.MathsCommand(), - name=f'binarize_fs_brainmask_{pipe_num}') - binarize_fs_brain_mask.inputs.args = '-bin' - wf.connect(fs_brain_mask_to_nifti, 'out_file', - binarize_fs_brain_mask, 'in_file') - - # fill holes - fill_fs_brain_mask = pe.Node(interface=afni.MaskTool(), - name=f'fill_fs_brainmask_{pipe_num}') - fill_fs_brain_mask.inputs.fill_holes = True - fill_fs_brain_mask.inputs.outputtype = 'NIFTI_GZ' - wf.connect(binarize_fs_brain_mask, 'out_file', - fill_fs_brain_mask, 'in_file') - - # register FS segmentations (aseg.mgz) to native space - fs_aseg_to_native = pe.Node(interface=freesurfer.ApplyVolTransform(), - name=f'fs_aseg_to_native_{pipe_num}') - fs_aseg_to_native.inputs.reg_header = True - fs_aseg_to_native.inputs.interp = 'nearest' - fs_aseg_to_native.inputs.subjects_dir = freesurfer_subject_dir - - wf.connect(reconall, 'aseg', fs_aseg_to_native, 'source_file') - wf.connect(reconall, 'rawavg', fs_aseg_to_native, 'target_file') - - # convert registered FS segmentations from .mgz to .nii.gz - fs_aseg_to_nifti = pe.Node(util.Function(input_names=['in_file'], - output_names=['out_file'], - function=mri_convert), - name=f'fs_aseg_to_nifti_{pipe_num}') - fs_aseg_to_nifti.inputs.args = '-rt nearest' - - wf.connect(fs_aseg_to_native, 'transformed_file', - fs_aseg_to_nifti, 'in_file') - - pick_tissue = pe.Node(pick_tissue_from_labels_file_interface(), - name=f'select_fs_tissue_{pipe_num}') - - pick_tissue.inputs.csf_label = cfg['segmentation'][ - 'tissue_segmentation']['FreeSurfer']['CSF_label'] - pick_tissue.inputs.gm_label = cfg['segmentation'][ - 'tissue_segmentation']['FreeSurfer']['GM_label'] - pick_tissue.inputs.wm_label = cfg['segmentation'][ - 'tissue_segmentation']['FreeSurfer']['WM_label'] - - wf.connect(fs_aseg_to_nifti, 'out_file', pick_tissue, 'multiatlas_Labels') - - erode_tissues = {} - if cfg['segmentation']['tissue_segmentation']['FreeSurfer']['erode'] > 0: - for tissue in ['csf', 'wm', 'gm']: - erode_tissues[tissue] = pe.Node( - interface=freesurfer.model.Binarize(), - name=f'erode_{tissue}_{pipe_num}') - erode_tissues[tissue].inputs.match = [1] - erode_tissues[tissue].inputs.erode = cfg['segmentation'][ - 'tissue_segmentation']['FreeSurfer']['erode'] - wf.connect(pick_tissue, f'{tissue}_mask', erode_tissues[tissue], - 'in_file') - wf, hemisphere_outputs = freesurfer_hemispheres(wf, reconall, pipe_num) outputs = { - 'space-T1w_desc-brain_mask': (fill_fs_brain_mask, 'out_file'), 'freesurfer-subject-dir': (reconall, 'subjects_dir'), **hemisphere_outputs, - 'raw-average': (reconall, 'rawavg'), - 'brainmask': (reconall, 'brainmask'), - 'T1': (reconall, 'T1') + 'pipeline-fs_raw-average': (reconall, 'rawavg'), + 'pipeline-fs_subcortical-seg': (reconall, 'aseg'), + 'pipeline-fs_brainmask': (reconall, 'brainmask'), + 'pipeline-fs_wmparc': (reconall, 'wmparc'), + 'pipeline-fs_T1': (reconall, 'T1') } - if erode_tissues: - outputs['label-CSF_mask'] = (erode_tissues['csf'], 'binary_file') - outputs['label-WM_mask'] = (erode_tissues['wm'], 'binary_file') - outputs['label-GM_mask'] = (erode_tissues['gm'], 'binary_file') - else: - outputs['label-CSF_mask'] = (pick_tissue, 'csf_mask') - outputs['label-WM_mask'] = (pick_tissue, 'wm_mask') - outputs['label-GM_mask'] = (pick_tissue, 'gm_mask') + # for label, connection in outputs.items(): + # strat_pool.set_data(label, connection[0], connection[1], + # deepcopy(strat_pool.get('json')), + # pipe_num, 'freesurfer_reconall', fork=False) + # Run postproc if we ran reconall + # wf, post_outputs = freesurfer_postproc(wf, cfg, strat_pool, pipe_num, opt) + # Update the outputs to include the postproc outputs + # outputs.update(post_outputs) - return (wf, outputs) + return wf, outputs -def fnirt_based_brain_extraction(config=None, wf_name='fnirt_based_brain_extraction'): +def fnirt_based_brain_extraction(config=None, + wf_name='fnirt_based_brain_extraction'): ### ABCD Harmonization - FNIRT-based brain extraction ### # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PreFreeSurfer/scripts/BrainExtraction_FNIRTbased.sh @@ -2928,169 +2980,6 @@ def fast_bias_field_correction(config=None, wf_name='fast_bias_field_correction' return preproc -def freesurfer_abcd_preproc(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "freesurfer_abcd_preproc", - "config": ["anatomical_preproc", "brain_extraction"], - "switch": "None", - "option_key": "using", - "option_val": "FreeSurfer-ABCD", - "inputs": [["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], - "T1w-template", - "T1w-brain-template-mask", - "template-ref-mask-res-2", - "T1w-template-res-2"], - "outputs": ["desc-restore_T1w", - "desc-restore-brain_T1w", - "desc-fast_biasfield", - "hemi-L_desc-surface_curv", - "hemi-R_desc-surface_curv", - "hemi-L_desc-surfaceMesh_pial", - "hemi-R_desc-surfaceMesh_pial", - "hemi-L_desc-surfaceMesh_smoothwm", - "hemi-R_desc-surfaceMesh_smoothwm", - "hemi-L_desc-surfaceMesh_sphere", - "hemi-R_desc-surfaceMesh_sphere", - "hemi-L_desc-surfaceMap_sulc", - "hemi-R_desc-surfaceMap_sulc", - "hemi-L_desc-surfaceMap_thickness", - "hemi-R_desc-surfaceMap_thickness", - "hemi-L_desc-surfaceMap_volume", - "hemi-R_desc-surfaceMap_volume", - "hemi-L_desc-surfaceMesh_white", - "hemi-R_desc-surfaceMesh_white", - "wmparc", - "freesurfer-subject-dir"]} - ''' - - # fnirt-based brain extraction - brain_extraction = fnirt_based_brain_extraction(config=cfg, - wf_name=f'fnirt_based_brain_extraction_{pipe_num}') - - node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, brain_extraction, 'inputspec.anat_data') - - node, out = strat_pool.get_data('template-ref-mask-res-2') - wf.connect(node, out, brain_extraction, 'inputspec.template-ref-mask-res-2') - - node, out = strat_pool.get_data('T1w-template') - wf.connect(node, out, brain_extraction, 'inputspec.template_skull_for_anat') - - node, out = strat_pool.get_data('T1w-template-res-2') - wf.connect(node, out, brain_extraction, 'inputspec.template_skull_for_anat_2mm') - - node, out = strat_pool.get_data('T1w-brain-template-mask') - wf.connect(node, out, brain_extraction, 'inputspec.template_brain_mask_for_anat') - - # fast bias field correction - fast_correction = fast_bias_field_correction(config=cfg, - wf_name=f'fast_bias_field_correction_{pipe_num}') - - node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, fast_correction, 'inputspec.anat_data') - - wf.connect(brain_extraction, 'outputspec.anat_brain', fast_correction, 'inputspec.anat_brain') - - wf.connect(brain_extraction, 'outputspec.anat_brain_mask', fast_correction, 'inputspec.anat_brain_mask') - - ### ABCD Harmonization ### - # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/FreeSurfer/FreeSurferPipeline.sh#L140-L144 - - # flirt -interp spline -in "$T1wImage" -ref "$T1wImage" -applyisoxfm 1 -out "$T1wImageFile"_1mm.nii.gz - resample_head_1mm = pe.Node(interface=fsl.FLIRT(), - name=f'resample_anat_head_1mm_{pipe_num}') - resample_head_1mm.inputs.interp = 'spline' - resample_head_1mm.inputs.apply_isoxfm = 1 - - node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, resample_head_1mm, 'in_file') - - wf.connect(node, out, resample_head_1mm, 'reference') - - # applywarp --rel --interp=spline -i "$T1wImage" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageFile"_1mm.nii.gz - applywarp_head_to_head_1mm = pe.Node(interface=fsl.ApplyWarp(), - name=f'applywarp_head_to_head_1mm_{pipe_num}') - applywarp_head_to_head_1mm.inputs.relwarp = True - applywarp_head_to_head_1mm.inputs.interp = 'spline' - applywarp_head_to_head_1mm.inputs.premat = cfg.registration_workflows['anatomical_registration']['registration']['FSL-FNIRT']['identity_matrix'] - - wf.connect(node, out, applywarp_head_to_head_1mm, 'in_file') - - wf.connect(resample_head_1mm, 'out_file', - applywarp_head_to_head_1mm, 'ref_file') - - # applywarp --rel --interp=nn -i "$T1wImageBrain" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageBrainFile"_1mm.nii.gz - applywarp_brain_to_head_1mm = pe.Node(interface=fsl.ApplyWarp(), - name=f'applywarp_brain_to_head_1mm_{pipe_num}') - applywarp_brain_to_head_1mm.inputs.relwarp = True - applywarp_brain_to_head_1mm.inputs.interp = 'nn' - applywarp_brain_to_head_1mm.inputs.premat = cfg.registration_workflows['anatomical_registration']['registration']['FSL-FNIRT']['identity_matrix'] - - wf.connect(fast_correction, 'outputspec.anat_brain_restore', - applywarp_brain_to_head_1mm, 'in_file') - - wf.connect(resample_head_1mm, 'out_file', - applywarp_brain_to_head_1mm, 'ref_file') - - # fslstats $T1wImageBrain -M - average_brain = pe.Node(interface=fsl.ImageStats(), - name=f'average_brain_{pipe_num}') - average_brain.inputs.op_string = '-M' - average_brain.inputs.output_type = 'NIFTI_GZ' - - wf.connect(fast_correction, 'outputspec.anat_brain_restore', - average_brain, 'in_file') - - # fslmaths "$T1wImageFile"_1mm.nii.gz -div $Mean -mul 150 -abs "$T1wImageFile"_1mm.nii.gz - normalize_head = pe.Node(util.Function(input_names=['in_file', 'number', 'out_file_suffix'], - output_names=['out_file'], - function=fslmaths_command), - name=f'normalize_head_{pipe_num}') - normalize_head.inputs.out_file_suffix = '_norm' - - wf.connect(applywarp_head_to_head_1mm, 'out_file', - normalize_head, 'in_file') - - wf.connect(average_brain, 'out_stat', - normalize_head, 'number') - - ### recon-all -all step ### - reconall = pe.Node(interface=freesurfer.ReconAll(), - name=f'anat_freesurfer_{pipe_num}', - mem_gb=2.7) - - sub_dir = cfg.pipeline_setup['working_directory']['path'] - freesurfer_subject_dir = os.path.join(sub_dir, - 'cpac_'+cfg['subject_id'], - f'anat_preproc_freesurfer_{pipe_num}', - 'anat_freesurfer') - - # create the directory for FreeSurfer node - if not os.path.exists(freesurfer_subject_dir): - os.makedirs(freesurfer_subject_dir) - - reconall.inputs.directive = 'all' - reconall.inputs.subjects_dir = freesurfer_subject_dir - reconall.inputs.openmp = cfg.pipeline_setup['system_config']['num_OMP_threads'] - - wf.connect(normalize_head, 'out_file', - reconall, 'T1_files') - - wf, hemisphere_outputs = freesurfer_hemispheres(wf, reconall, pipe_num) - - outputs = { - 'desc-restore_T1w': (fast_correction, 'outputspec.anat_restore'), - 'desc-restore-brain_T1w': (fast_correction, - 'outputspec.anat_brain_restore'), - 'desc-fast_biasfield': (fast_correction, 'outputspec.bias_field'), - 'wmparc': (reconall, 'wmparc'), - 'freesurfer-subject-dir': (reconall, 'subjects_dir'), - **hemisphere_outputs - } - - return (wf, outputs) - - def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "correct_restore_brain_intensity_abcd", @@ -3098,13 +2987,13 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None "switch": "None", "option_key": "using", "option_val": "FreeSurfer-ABCD", - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], + "inputs": [("desc-preproc_T1w", "desc-n4_T1w", - "desc-restore-brain_T1w", "space-T1w_desc-brain_mask", - "desc-fast_biasfield", + "pipeline-fs_desc-fast_biasfield", "from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm", - "from-T1w_to-template_mode-image_xfm")], + "from-T1w_to-template_mode-image_xfm", + "desc-restore-brain_T1w")], "outputs": ["desc-restore-brain_T1w"]} ''' @@ -3144,8 +3033,8 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None convertwarp_orig_t1_to_t1.inputs.out_relwarp = True convertwarp_orig_t1_to_t1.inputs.relwarp = True - - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + + node, out = strat_pool.get_data("space-T1w_desc-brain_mask") wf.connect(node, out, convertwarp_orig_t1_to_t1, 'reference') node, out = strat_pool.get_data('from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm') @@ -3161,10 +3050,10 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None applywarp_biasfield.inputs.relwarp = True applywarp_biasfield.inputs.interp = 'spline' - node, out = strat_pool.get_data('desc-fast_biasfield') + node, out = strat_pool.get_data('pipeline-fs_desc-fast_biasfield') wf.connect(node, out, applywarp_biasfield, 'in_file') - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + node, out = strat_pool.get_data("space-T1w_desc-brain_mask") wf.connect(node, out, applywarp_biasfield, 'ref_file') node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') @@ -3189,7 +3078,7 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None node, out = strat_pool.get_data('desc-n4_T1w') wf.connect(node, out, applywarp_t1, 'in_file') - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + node, out = strat_pool.get_data("space-T1w_desc-brain_mask") wf.connect(node, out, applywarp_t1, 'ref_file') wf.connect(convertwarp_orig_t1_to_t1, 'out_file', @@ -3210,7 +3099,7 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None wf.connect(abs_t1, 'out_file', div_t1_by_biasfield, 'in_file') - node, out = strat_pool.get_data('desc-fast_biasfield') + node, out = strat_pool.get_data('pipeline-fs_desc-fast_biasfield') wf.connect(node, out, div_t1_by_biasfield, 'in_file2') # fslmaths "$OutputT1wImageRestore" -mas "$T1wImageBrain" "$OutputT1wImageRestoreBrain" @@ -3220,7 +3109,7 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None wf.connect(div_t1_by_biasfield, 'out_file', apply_mask, 'in_file') - node, out = strat_pool.get_data('space-T1w_desc-brain_mask') + node, out = strat_pool.get_data("space-T1w_desc-brain_mask") wf.connect(node, out, apply_mask, 'mask_file') outputs = { @@ -3228,3 +3117,4 @@ def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None } return (wf, outputs) + diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index f212805077..c0d44be9fb 100755 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -174,22 +174,22 @@ def split_hemi_interface(): for label in splits: wf.connect(reconall, label, splits[label], 'multi_file') outputs = { - 'hemi-L_desc-surface_curv': (splits['curv'], 'lh'), - 'hemi-R_desc-surface_curv': (splits['curv'], 'rh'), - 'hemi-L_desc-surfaceMesh_pial': (splits['pial'], 'lh'), - 'hemi-R_desc-surfaceMesh_pial': (splits['pial'], 'rh'), - 'hemi-L_desc-surfaceMesh_smoothwm': (splits['smoothwm'], 'lh'), - 'hemi-R_desc-surfaceMesh_smoothwm': (splits['smoothwm'], 'rh'), - 'hemi-L_desc-surfaceMesh_sphere': (splits['sphere'], 'lh'), - 'hemi-R_desc-surfaceMesh_sphere': (splits['sphere'], 'rh'), - 'hemi-L_desc-surfaceMap_sulc': (splits['sulc'], 'lh'), - 'hemi-R_desc-surfaceMap_sulc': (splits['sulc'], 'rh'), - 'hemi-L_desc-surfaceMap_thickness': (splits['thickness'], 'lh'), - 'hemi-R_desc-surfaceMap_thickness': (splits['thickness'], 'rh'), - 'hemi-L_desc-surfaceMap_volume': (splits['volume'], 'lh'), - 'hemi-R_desc-surfaceMap_volume': (splits['volume'], 'rh'), - 'hemi-L_desc-surfaceMesh_white': (splits['white'], 'lh'), - 'hemi-R_desc-surfaceMesh_white': (splits['white'], 'rh')} + 'pipeline-fs_hemi-L_desc-surface_curv': (splits['curv'], 'lh'), + 'pipeline-fs_hemi-R_desc-surface_curv': (splits['curv'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMesh_pial': (splits['pial'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMesh_pial': (splits['pial'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm': (splits['smoothwm'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm': (splits['smoothwm'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMesh_sphere': (splits['sphere'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMesh_sphere': (splits['sphere'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMap_sulc': (splits['sulc'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMap_sulc': (splits['sulc'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMap_thickness': (splits['thickness'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMap_thickness': (splits['thickness'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMap_volume': (splits['volume'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMap_volume': (splits['volume'], 'rh'), + 'pipeline-fs_hemi-L_desc-surfaceMesh_white': (splits['white'], 'lh'), + 'pipeline-fs_hemi-R_desc-surfaceMesh_white': (splits['white'], 'rh')} return wf, outputs diff --git a/CPAC/connectome/connectivity_matrix.py b/CPAC/connectome/connectivity_matrix.py index 8dfbb8da1f..8e942b6c4c 100755 --- a/CPAC/connectome/connectivity_matrix.py +++ b/CPAC/connectome/connectivity_matrix.py @@ -1,11 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +# Copyright (C) 2021-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . """Functions for creating connectome connectivity matrices.""" import os from warnings import warn import numpy as np from nilearn.connectome import ConnectivityMeasure -from nilearn.input_data import NiftiLabelsMasker from nipype import logging from nipype.interfaces import utility as util from CPAC.pipeline import nipype_pipeline_engine as pe @@ -99,18 +114,23 @@ def compute_connectome_nilearn(in_rois, in_file, method, atlas_name): ------- numpy.ndarray or NotImplemented """ + from nilearn.input_data import NiftiLabelsMasker + from nipype.utils.tmpdirs import TemporaryDirectory tool = 'Nilearn' output = connectome_name(atlas_name, tool, method) method = get_connectome_method(method, tool) if method is NotImplemented: return NotImplemented - masker = NiftiLabelsMasker(labels_img=in_rois, - standardize=True, - verbose=True) - timeser = masker.fit_transform(in_file) - correlation_measure = ConnectivityMeasure(kind=method) - corr_matrix = correlation_measure.fit_transform([timeser])[0] - np.fill_diagonal(corr_matrix, 0) + with TemporaryDirectory() as cache_dir: + masker = NiftiLabelsMasker(labels_img=in_rois, + standardize=True, + verbose=True, + memory=cache_dir, + memory_level=3) + timeser = masker.fit_transform(in_file) + correlation_measure = ConnectivityMeasure(kind=method) + corr_matrix = correlation_measure.fit_transform([timeser])[0] + np.fill_diagonal(corr_matrix, 1) np.savetxt(output, corr_matrix, delimiter='\t') return output diff --git a/CPAC/cwas/cwas.py b/CPAC/cwas/cwas.py index 5264b07bd0..5513ed8cac 100755 --- a/CPAC/cwas/cwas.py +++ b/CPAC/cwas/cwas.py @@ -3,6 +3,9 @@ import nibabel as nb import numpy as np import pandas as pd +import scipy.stats +from scipy.stats import t +from numpy import inf from CPAC.cwas.mdmr import mdmr from CPAC.utils import correlation @@ -35,7 +38,6 @@ def joint_mask(subjects, mask_file=None): mask_file = os.path.join(os.getcwd(), 'joint_mask.nii.gz') create_merged_copefile(files, cope_file) create_merge_mask(cope_file, mask_file) - return mask_file @@ -48,7 +50,6 @@ def calc_mdmrs(D, regressor, cols, permutations): def calc_subdists(subjects_data, voxel_range): subjects, voxels, _ = subjects_data.shape D = np.zeros((len(voxel_range), subjects, subjects)) - for i, v in enumerate(voxel_range): profiles = np.zeros((subjects, voxels)) for si in range(subjects): @@ -67,6 +68,12 @@ def calc_cwas(subjects_data, regressor, regressor_selected_cols, permutations, v D, regressor, regressor_selected_cols, permutations) return F_set, p_set +def pval_to_zval(p_set, permu): + inv_pval = 1 - p_set + zvals = t.ppf(inv_pval, (len(p_set) - 1)) + zvals[zvals == -inf] = permu / (permu + 1) + zvals[zvals == inf] = permu / (permu + 1) + return zvals def nifti_cwas(subjects, mask_file, regressor_file, participant_column, columns_string, permutations, voxel_range): @@ -130,7 +137,7 @@ def nifti_cwas(subjects, mask_file, regressor_file, participant_column, for sub_id in subject_ids: if str(sub_id).lstrip('0') == str(pheno_sub_id): regressor_data.at[index, participant_column] = str(sub_id) - + regressor_data.index = regressor_data[participant_column] # Keep only data from specific subjects @@ -144,33 +151,27 @@ def nifti_cwas(subjects, mask_file, regressor_file, participant_column, if len(regressor_selected_cols) == 0: regressor_selected_cols = [i for i, c in enumerate(regressor_cols)] regressor_selected_cols = np.array(regressor_selected_cols) - # Remove participant id column from the dataframe and convert it to a numpy matrix regressor = ordered_regressor_data \ .drop(columns=[participant_column]) \ .reset_index(drop=True) \ .values \ .astype(np.float64) - if len(regressor.shape) == 1: regressor = regressor[:, np.newaxis] elif len(regressor.shape) != 2: raise ValueError('Bad regressor shape: %s' % str(regressor.shape)) - if len(subject_files) != regressor.shape[0]: raise ValueError('Number of subjects does not match regressor size') - - mask = nb.load(mask_file).get_data().astype('bool') + mask = nb.load(mask_file).get_fdata().astype('bool') mask_indices = np.where(mask) - subjects_data = np.array([ - nb.load(subject_file).get_data().astype('float64')[mask_indices].T + nb.load(subject_file).get_fdata().astype('float64')[mask_indices] for subject_file in subject_files ]) F_set, p_set = calc_cwas(subjects_data, regressor, regressor_selected_cols, permutations, voxel_range) - cwd = os.getcwd() F_file = os.path.join(cwd, 'pseudo_F.npy') p_file = os.path.join(cwd, 'significance_p.npy') @@ -182,7 +183,7 @@ def nifti_cwas(subjects, mask_file, regressor_file, participant_column, def create_cwas_batches(mask_file, batches): - mask = nb.load(mask_file).get_data().astype('bool') + mask = nb.load(mask_file).get_fdata().astype('bool') voxels = mask.sum(dtype=int) return np.array_split(np.arange(voxels), batches) @@ -198,7 +199,7 @@ def volumize(mask_image, data): ) -def merge_cwas_batches(cwas_batches, mask_file): +def merge_cwas_batches(cwas_batches, mask_file, z_score, permutations): _, _, voxel_range = zip(*cwas_batches) voxels = np.array(np.concatenate(voxel_range)) @@ -211,18 +212,37 @@ def merge_cwas_batches(cwas_batches, mask_file): p_set[voxel_range] = np.load(p_file) log_p_set = -np.log10(p_set) + one_p_set = 1 - p_set F_vol = volumize(mask_image, F_set) p_vol = volumize(mask_image, p_set) log_p_vol = volumize(mask_image, log_p_set) + one_p_vol = volumize(mask_image, one_p_set) cwd = os.getcwd() F_file = os.path.join(cwd, 'pseudo_F_volume.nii.gz') p_file = os.path.join(cwd, 'p_significance_volume.nii.gz') log_p_file = os.path.join(cwd, 'neglog_p_significance_volume.nii.gz') + one_p_file = os.path.join(cwd, 'one_minus_p_values.nii.gz') F_vol.to_filename(F_file) p_vol.to_filename(p_file) log_p_vol.to_filename(log_p_file) + one_p_vol.to_filename(one_p_file) + + if 1 in z_score: + zvals = pval_to_zval(p_set, permutations) + z_file = zstat_image(zvals, mask_file) + + return F_file, p_file, log_p_file, one_p_file, z_file + +def zstat_image(zvals, mask_file): + mask_image = nb.load(mask_file) - return F_file, p_file, log_p_file + z_vol = volumize(mask_image, zvals) + + cwd = os.getcwd() + z_file = os.path.join(cwd, 'zstat.nii.gz') + + z_vol.to_filename(z_file) + return z_file diff --git a/CPAC/cwas/mdmr.py b/CPAC/cwas/mdmr.py index 5aed0505ca..80524ff4d2 100755 --- a/CPAC/cwas/mdmr.py +++ b/CPAC/cwas/mdmr.py @@ -83,15 +83,15 @@ def mdmr(D, X, columns, permutations): Gs[:, di] = gower(D[di]).flatten() X1 = np.hstack((np.ones((subjects, 1)), X)) - columns = columns.copy() + 1 + columns = columns.copy() #removed a +1 regressors = X1.shape[1] - - permutation_indexes = np.zeros((permutations + 1, subjects), dtype=np.int) + + permutation_indexes = np.zeros((permutations, subjects), dtype=np.int) permutation_indexes[0, :] = range(subjects) - for i in range(1, permutations + 1): + for i in range(1, permutations): permutation_indexes[i,:] = np.random.permutation(subjects) - + H2perms = gen_h2_perms(X1, columns, permutation_indexes) IHperms = gen_ih_perms(X1, columns, permutation_indexes) diff --git a/CPAC/cwas/pipeline.py b/CPAC/cwas/pipeline.py index 401c7fa336..5dcab83340 100755 --- a/CPAC/cwas/pipeline.py +++ b/CPAC/cwas/pipeline.py @@ -2,6 +2,7 @@ import os from CPAC.pipeline import nipype_pipeline_engine as pe import nipype.interfaces.utility as util +from nipype import config from CPAC.utils.interfaces.function import Function @@ -11,6 +12,7 @@ create_cwas_batches, merge_cwas_batches, nifti_cwas, + zstat_image, ) @@ -54,6 +56,8 @@ def create_cwas(name='cwas', working_dir=None, crash_dir=None): Pseudo F values of CWAS outputspec.p_map : string (nifti file) Significance p values calculated from permutation tests + outputspec.z_map : string (nifti file) + Significance p values converted to z-scores CWAS Procedure: @@ -83,10 +87,9 @@ def create_cwas(name='cwas', working_dir=None, crash_dir=None): References ---------- - .. [1] Shehzad Z, Kelly C, Reiss PT, Emerson JW, McMahon K, Copland DA, Castellanos FX, Milham MP. An Analytic Framework for Connectome-Wide Association Studies. Under Review. + .. [1] Shehzad Z, Kelly C, Reiss PT, Cameron Craddock R, Emerson JW, McMahon K, Copland DA, Castellanos FX, Milham MP. A multivariate distance-based analytic framework for connectome-wide association studies. Neuroimage. 2014 Jun;93 Pt 1(0 1):74-94. doi: 10.1016/j.neuroimage.2014.02.024. Epub 2014 Feb 28. PMID: 24583255; PMCID: PMC4138049. """ - if not working_dir: working_dir = os.path.join(os.getcwd(), 'MDMR_work_dir') if not crash_dir: @@ -95,7 +98,8 @@ def create_cwas(name='cwas', working_dir=None, crash_dir=None): workflow = pe.Workflow(name=name) workflow.base_dir = working_dir workflow.config['execution'] = {'hash_method': 'timestamp', - 'crashdump_dir': os.path.abspath(crash_dir)} + 'crashdump_dir': os.path.abspath(crash_dir), + 'crashfile_format': 'txt'} inputspec = pe.Node(util.IdentityInterface(fields=['roi', 'subjects', @@ -103,12 +107,15 @@ def create_cwas(name='cwas', working_dir=None, crash_dir=None): 'participant_column', 'columns', 'permutations', - 'parallel_nodes']), + 'parallel_nodes', + 'z_score']), name='inputspec') outputspec = pe.Node(util.IdentityInterface(fields=['F_map', 'p_map', - 'neglog_p_map']), + 'neglog_p_map', + 'one_p_map', + 'z_map']), name='outputspec') ccb = pe.Node(Function(input_names=['mask_file', @@ -139,10 +146,14 @@ def create_cwas(name='cwas', working_dir=None, crash_dir=None): name='joint_mask') mcwasb = pe.Node(Function(input_names=['cwas_batches', - 'mask_file'], + 'mask_file', + 'z_score', + 'permutations'], output_names=['F_file', 'p_file', - 'neglog_p_file'], + 'neglog_p_file', + 'one_p_file', + 'z_file'], function=merge_cwas_batches, as_module=True), name='cwas_volumes') @@ -181,9 +192,15 @@ def create_cwas(name='cwas', working_dir=None, crash_dir=None): mcwasb, 'cwas_batches') workflow.connect(jmask, 'joint_mask', mcwasb, 'mask_file') + workflow.connect(inputspec, 'z_score', + mcwasb, 'z_score') + workflow.connect(inputspec, 'permutations', + mcwasb, 'permutations') workflow.connect(mcwasb, 'F_file', outputspec, 'F_map') workflow.connect(mcwasb, 'p_file', outputspec, 'p_map') workflow.connect(mcwasb, 'neglog_p_file', outputspec, 'neglog_p_map') + workflow.connect(mcwasb, 'one_p_file', outputspec, 'one_p_map') + workflow.connect(mcwasb, 'z_file', outputspec, 'z_map') return workflow diff --git a/CPAC/distortion_correction/distortion_correction.py b/CPAC/distortion_correction/distortion_correction.py index 33ff232b58..bbb8b5377e 100755 --- a/CPAC/distortion_correction/distortion_correction.py +++ b/CPAC/distortion_correction/distortion_correction.py @@ -1,5 +1,21 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright (C) 2017-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import os import subprocess @@ -101,11 +117,15 @@ def distcor_phasediff_fsl_fugue(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "using", "option_val": "PhaseDiff", - "inputs": ["diffphase", - "diffmag", + "inputs": ["phasediff", + "phase1", + "phase2", + "magnitude", + "magnitude1", + "magnitude2", "deltaTE", - "diffphase-dwell", - "dwell-asym-ratio"], + "effectiveEchoSpacing", + "ees-asym-ratio"], "outputs": ["despiked-fieldmap", "fieldmap-mask"]} ''' @@ -128,7 +148,11 @@ def distcor_phasediff_fsl_fugue(wf, cfg, strat_pool, pipe_num, opt=None): afni.inputs.outputtype = 'NIFTI_GZ' wf.connect(skullstrip_args, 'expr', afni, 'args') - node, out = strat_pool.get_data('diffmag') + if strat_pool.check_rpool('magnitude'): + node, out = strat_pool.get_data('magnitude') + elif strat_pool.check_rpool('magnitude1'): + node, out = strat_pool.get_data('magnitude1') + wf.connect(node, out, afni, 'in_file') brain_node, brain_out = (afni, 'out_file') @@ -142,7 +166,10 @@ def distcor_phasediff_fsl_fugue(wf, cfg, strat_pool, pipe_num, opt=None): bet.inputs.frac = cfg.functional_preproc['distortion_correction'][ 'PhaseDiff']['fmap_skullstrip_BET_frac'] - node, out = strat_pool.get_data('diffmag') + if strat_pool.check_rpool('magnitude'): + node, out = strat_pool.get_data('magnitude') + elif strat_pool.check_rpool('magnitude1'): + node, out = strat_pool.get_data('magnitude1') wf.connect(node, out, bet, 'in_file') brain_node, brain_out = (bet, 'out_file') @@ -156,9 +183,23 @@ def distcor_phasediff_fsl_fugue(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data('deltaTE') wf.connect(node, out, prepare, 'delta_TE') - node, out = strat_pool.get_data('diffphase') - wf.connect(node, out, prepare, 'in_phase') + if strat_pool.check_rpool('phase1') and strat_pool.check_rpool('phase2'): + fslmaths_sub = pe.Node(interface=fsl.BinaryMaths(), + name='fugue_phase_subtraction') + fslmaths_sub.inputs.operation = 'sub' + + node, out = strat_pool.get_data('phase1') + wf.connect(node, out, fslmaths_sub, 'in_file') + + node, out = strat_pool.get_data('phase2') + wf.connect(node, out, fslmaths_sub, 'operand_file') + + node, out = (fslmaths_sub, 'out_file') + elif strat_pool.check_rpool('phasediff'): + node, out = strat_pool.get_data('phasediff') + + wf.connect(node, out, prepare, 'in_phase') wf.connect(brain_node, brain_out, prepare, 'in_magnitude') # erode the masked magnitude image @@ -203,16 +244,16 @@ def distcor_phasediff_fsl_fugue(wf, cfg, strat_pool, pipe_num, opt=None): # option in the GUI. # fugue - fugue1 = pe.Node(interface=fsl.FUGUE(), name='fugue1') + fugue1 = pe.Node(interface=fsl.FUGUE(), name='fsl_fugue') fugue1.inputs.save_fmap = True fugue1.outputs.fmap_out_file = 'fmap_rads' wf.connect(fslmath_mask, 'out_file', fugue1, 'mask_file') - node, out = strat_pool.get_data('diffphase-dwell') + # FSL calls EffectiveEchoSpacing "dwell_time" + node, out = strat_pool.get_data('effectiveEchoSpacing') wf.connect(node, out, fugue1, 'dwell_time') - - node, out = strat_pool.get_data('dwell-asym-ratio') + node, out = strat_pool.get_data('ees-asym-ratio') wf.connect(node, out, fugue1, 'dwell_to_asym_ratio') wf.connect(prepare, 'out_fieldmap', fugue1, 'fmap_in_file') @@ -324,16 +365,16 @@ def distcor_blip_afni_qwarp(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "using", "option_val": "Blip", - "inputs": [("desc-mean_bold", + "inputs": [("sbref", "space-bold_desc-brain_mask"), "epi-1", "epi-1-scan-params", "epi-2", "epi-2-scan-params", "pe-direction"], - "outputs": ["blip-warp", - "desc-mean_bold", - "space-bold_desc-brain_mask"]} + "outputs": ["sbref", + "space-bold_desc-brain_mask", + "ants-blip-warp"]} ''' match_epi_imports = ['import json'] @@ -391,7 +432,7 @@ def distcor_blip_afni_qwarp(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(func_edge_detect, 'out_file', opp_pe_to_func, 'in_file') - node, out = strat_pool.get_data('desc-mean_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, opp_pe_to_func, 'reference') prep_qwarp_input_imports = ['import os', 'import subprocess'] @@ -406,7 +447,7 @@ def distcor_blip_afni_qwarp(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(match_epi_fmaps_node, 'same_pe_epi', prep_qwarp_input, 'same_pe_epi') - node, out = strat_pool.get_data('desc-mean_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, prep_qwarp_input, 'func_mean') calculate_blip_warp_imports = ['import os', 'import subprocess'] @@ -443,7 +484,7 @@ def distcor_blip_afni_qwarp(wf, cfg, strat_pool, pipe_num, opt=None): undistort_func_mean.inputs.dimension = 3 undistort_func_mean.inputs.input_image_type = 0 - node, out = strat_pool.get_data('desc-mean_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, undistort_func_mean, 'input_image') wf.connect(node, out, undistort_func_mean, 'reference_image') wf.connect(convert_afni_warp, 'ants_warp', @@ -460,15 +501,15 @@ def distcor_blip_afni_qwarp(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(undistort_func_mean, 'output_image', remask, 'in_file') outputs = { - 'blip-warp': (convert_afni_warp, 'ants_warp'), + 'ants-blip-warp': (convert_afni_warp, 'ants_warp'), #'inv-blip-warp': None, # TODO - 'desc-mean_bold': (undistort_func_mean, 'output_image'), + 'sbref': (undistort_func_mean, 'output_image'), 'space-bold_desc-brain_mask': (remask, 'out_file') } return (wf, outputs) - - + + def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): '''Execute FSL TOPUP to calculate the distortion "unwarp" for phase encoding direction EPI field map distortion correction. @@ -479,20 +520,22 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "using", "option_val": "Blip-FSL-TOPUP", - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("sbref", "space-bold_desc-brain_mask"), "pe-direction", "epi-1", "epi-1-pedir", "epi-1-TE", "epi-1-dwell", + "epi-1-total-readout", "epi-2", "epi-2-pedir", "epi-2-TE", - "epi-2-dwell"], - "outputs": ["desc-reginput_bold", + "epi-2-dwell", + "epi-2-total-readout"], + "outputs": ["sbref", "space-bold_desc-brain_mask", - "blip-warp"]} + "fsl-blip-warp"]} ''' # TODO: re-integrate gradient distortion coefficient usage at a later date @@ -531,12 +574,12 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): else: ''' - + create_list = pe.Node(interface=util.Merge(2), name="create_list") node, out = strat_pool.get_data('epi-1') wf.connect(node, out, create_list, 'in1') - + node, out = strat_pool.get_data('epi-2') wf.connect(node, out, create_list, 'in2') @@ -550,26 +593,28 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): Mask.inputs.operand_value = 0 Mask.inputs.operation = "mul" Mask.inputs.args = "-add 1" - + node, out = strat_pool.get_data('epi-1') wf.connect(node, out, Mask, 'in_file') - #zpad_phases = z_pad("zpad_phases") - #wf.connect(merge_image, "merged_file", zpad_phases, "inputspec.input_image") + # zpad_phases = z_pad("zpad_phases") + # wf.connect(merge_image, "merged_file", zpad_phases, "inputspec.input_image") - #zpad_mask = z_pad("zpad_mask") - #wf.connect(Mask, "out_file", zpad_mask, "inputspec.input_image") + # zpad_mask = z_pad("zpad_mask") + # wf.connect(Mask, "out_file", zpad_mask, "inputspec.input_image") # extrapolate existing values beyond the mask - extrap_vals = pe.Node(interface=fsl.maths.BinaryMaths(), + extrap_vals = pe.Node(interface=fsl.maths.BinaryMaths(), name="extrap_vals") extrap_vals.inputs.operation = "add" extrap_vals.inputs.operand_value = 1 extrap_vals.inputs.args = "-abs -dilM -dilM -dilM -dilM -dilM" - - #wf.connect(zpad_phases, "outputspec.output_image", extrap_vals, "in_file") - #wf.connect(zpad_mask, "outputspec.output_image", extrap_vals, "operand_file") - + + # wf.connect(zpad_phases, "outputspec.output_image", + # extrap_vals, "in_file") + # wf.connect(zpad_mask, "outputspec.output_image", + # extrap_vals, "operand_file") + wf.connect(merge_image, "merged_file", extrap_vals, "in_file") wf.connect(Mask, "out_file", extrap_vals, "operand_file") @@ -588,7 +633,9 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): "phase_one", "phase_two", "dwell_time_one", - "dwell_time_two" + "dwell_time_two", + "ro_time_one", + "ro_time_two" ], output_names=["acq_params"], function=phase_encode, @@ -598,18 +645,30 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): ) node, out = strat_pool.get_data('epi-1') wf.connect(node, out, phase_encoding, 'phase_one') - + node, out = strat_pool.get_data('epi-2') wf.connect(node, out, phase_encoding, 'phase_two') - + node, out = strat_pool.get_data('pe-direction') wf.connect(node, out, phase_encoding, 'unwarp_dir') - - node, out = strat_pool.get_data('epi-1-dwell') - wf.connect(node, out, phase_encoding, 'dwell_time_one') - node, out = strat_pool.get_data('epi-2-dwell') - wf.connect(node, out, phase_encoding, 'dwell_time_two') + if strat_pool.check_rpool('epi-1-dwell') and \ + strat_pool.check_rpool('epi-2-dwell'): + + node, out = strat_pool.get_data('epi-1-dwell') + wf.connect(node, out, phase_encoding, 'dwell_time_one') + + node, out = strat_pool.get_data('epi-2-dwell') + wf.connect(node, out, phase_encoding, 'dwell_time_two') + + if strat_pool.check_rpool('epi-1-total-readout') and \ + strat_pool.check_rpool('epi-2-total-readout'): + + node, out = strat_pool.get_data('epi-1-total-readout') + wf.connect(node, out, phase_encoding, 'ro_time_one') + + node, out = strat_pool.get_data('epi-2-total-readout') + wf.connect(node, out, phase_encoding, 'ro_time_two') topup_imports = ["import os", "import subprocess"] @@ -631,24 +690,23 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(phase_encoding, "acq_params", run_topup, "acqparams") choose_phase = pe.Node( - util.Function( - input_names=["phase_imgs", + util.Function( + input_names=["phase_imgs", "unwarp_dir"], output_names=["out_phase_image", "vnum"], function=choose_phase_image - ), - name="choose_phase", + ), name="choose_phase", ) - + wf.connect(create_list, 'out', choose_phase, 'phase_imgs') node, out = strat_pool.get_data("pe-direction") wf.connect(node, out, choose_phase, "unwarp_dir") vnum_base = pe.Node( - util.Function( - input_names=["vnum", + util.Function( + input_names=["vnum", "motion_mat_list", "jac_matrix_list", "warp_field_list"], @@ -656,72 +714,59 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): "out_jacobian", "out_warp_field"], function=find_vnum_base - ), - name="Motion_Jac_Warp_matrices", - ) + ), name="Motion_Jac_Warp_matrices", + ) wf.connect(choose_phase, 'vnum', vnum_base, 'vnum') wf.connect(run_topup, 'out_xfms', vnum_base, 'motion_mat_list') wf.connect(run_topup, 'out_jacs', vnum_base, 'jac_matrix_list') wf.connect(run_topup, 'out_warps', vnum_base, 'warp_field_list') - create_scout = pe.Node(interface=afni_utils.Calc(), - name="topupwf_create_scout") - create_scout.inputs.set( - expr='a', - single_idx=0, - outputtype='NIFTI_GZ' - ) - - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) - wf.connect(node, out, create_scout, 'in_file_a') + mean_bold = strat_pool.node_data("sbref") flirt = pe.Node(interface=fsl.FLIRT(), name="flirt") flirt.inputs.dof = 6 flirt.inputs.interp = 'spline' flirt.inputs.out_matrix_file = 'SBRef2PhaseTwo_gdc.mat' - wf.connect(create_scout, 'out_file', flirt, 'in_file') + wf.connect(mean_bold.node, mean_bold.out, flirt, 'in_file') wf.connect(choose_phase, 'out_phase_image', flirt, 'reference') - - #fsl_convert_xfm + + # fsl_convert_xfm convert_xfm = pe.Node(interface=fsl.ConvertXFM(), name="convert_xfm") convert_xfm.inputs.concat_xfm = True convert_xfm.inputs.out_file = 'SBRef2WarpField.mat' - wf.connect(flirt, 'out_matrix_file', convert_xfm,'in_file') - wf.connect(vnum_base, 'out_motion_mat', convert_xfm,'in_file2') + wf.connect(flirt, 'out_matrix_file', convert_xfm, 'in_file') + wf.connect(vnum_base, 'out_motion_mat', convert_xfm, 'in_file2') - #fsl_convert_warp + # fsl_convert_warp convert_warp = pe.Node(interface=fsl.ConvertWarp(), - name = "convert_warp") + name="convert_warp") convert_warp.inputs.relwarp = True convert_warp.inputs.out_relwarp = True convert_warp.inputs.out_file = 'WarpField.nii.gz' wf.connect(choose_phase, 'out_phase_image', convert_warp, 'reference') wf.connect(vnum_base, 'out_warp_field', convert_warp, 'warp1') - wf.connect(convert_xfm, 'out_file' ,convert_warp, 'premat') - - out_convert_warp = (convert_warp,'out_file') + wf.connect(convert_xfm, 'out_file', convert_warp, 'premat') - VolumeNumber = 1+1 + VolumeNumber = 1 + 1 vnum = str(VolumeNumber).zfill(2) name = "PhaseTwo_aw" vnum_base_two = pe.Node( - util.Function( + util.Function( input_names=["vnum", "motion_mat_list", "jac_matrix_list", "warp_field_list"], - output_names=["out_motion_mat", - "out_jacobian", + output_names=["out_motion_mat", + "out_jacobian", "out_warp_field"], function=find_vnum_base - ), - name=f"Motion_Jac_Warp_matrices_{name}", - ) + ), name=f"Motion_Jac_Warp_matrices_{name}", + ) vnum_base_two.inputs.vnum = vnum wf.connect(run_topup, 'out_xfms', vnum_base_two, 'motion_mat_list') @@ -732,7 +777,7 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): aw_two = pe.Node(interface=fsl.ApplyWarp(), name="aw_two") aw_two.inputs.relwarp = True aw_two.inputs.interp = 'spline' - + node, out = strat_pool.get_data('epi-2') wf.connect(node, out, aw_two, 'in_file') wf.connect(node, out, aw_two, 'ref_file') @@ -746,14 +791,15 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(aw_two, 'out_file', mul_phase_two, 'in_file') wf.connect(vnum_base_two, 'out_jacobian', mul_phase_two, 'operand_file') - - # PhaseOne (first vol) - warp and Jacobian modulate to get distortion corrected output - VolumeNumber= 0 + 1 + + # PhaseOne (first vol) - warp and Jacobian modulate to get + # distortion corrected output + VolumeNumber = 0 + 1 vnum = str(VolumeNumber).zfill(2) name = "PhaseOne_aw" vnum_base_one = pe.Node( - util.Function( + util.Function( input_names=["vnum", "motion_mat_list", "jac_matrix_list", @@ -762,9 +808,8 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): "out_jacobian", "out_warp_field"], function=find_vnum_base - ), - name=f"Motion_Jac_Warp_matrices_{name}", - ) + ), name=f"Motion_Jac_Warp_matrices_{name}", + ) vnum_base_one.inputs.vnum = vnum wf.connect(run_topup, 'out_xfms', vnum_base_one, 'motion_mat_list') @@ -772,7 +817,7 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(run_topup, 'out_warps', vnum_base_one, 'warp_field_list') # fsl_applywarp to phaseOne - aw_one = pe.Node(interface=fsl.ApplyWarp(),name = "aw_one") + aw_one = pe.Node(interface=fsl.ApplyWarp(), name="aw_one") aw_one.inputs.relwarp = True aw_one.inputs.interp = 'spline' @@ -783,7 +828,7 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(vnum_base_one, 'out_motion_mat', aw_one, 'premat') wf.connect(vnum_base_one, 'out_warp_field', aw_one, 'field_file') - mul_phase_one = pe.Node(interface = fsl.BinaryMaths(), name="mul_phase_one") + mul_phase_one = pe.Node(interface=fsl.BinaryMaths(), name="mul_phase_one") mul_phase_one.inputs.operation = 'mul' wf.connect(aw_one, 'out_file', mul_phase_one, 'in_file') @@ -794,19 +839,20 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): aw_jac.inputs.relwarp = True aw_jac.inputs.interp = 'spline' - wf.connect(create_scout, 'out_file', aw_jac, 'in_file') #SBRef.nii.gz - wf.connect(create_scout, 'out_file', aw_jac, 'ref_file') #SBRef.nii.gz + wf.connect(mean_bold.node, mean_bold.out, aw_jac, 'in_file') # SBRef.nii.gz + wf.connect(mean_bold.node, mean_bold.out, + aw_jac, 'ref_file') # SBRef.nii.gz wf.connect(convert_warp, 'out_file', aw_jac, 'field_file') - mul_jac = pe.Node(interface = fsl.BinaryMaths(),name = "mul_jac") + mul_jac = pe.Node(interface=fsl.BinaryMaths(), name="mul_jac") mul_jac.inputs.operation = 'mul' mul_jac.inputs.out_file = "SBRef_dc_jac.nii.gz" wf.connect(aw_jac, 'out_file', mul_jac, 'in_file') wf.connect(vnum_base, 'out_jacobian', mul_jac, 'operand_file') - #Calculate Equivalent Field Map - tp_field_map = pe.Node(interface = fsl.BinaryMaths(),name = "tp_field_map") + # Calculate Equivalent Field Map + tp_field_map = pe.Node(interface=fsl.BinaryMaths(), name="tp_field_map") tp_field_map.inputs.operation = 'mul' tp_field_map.inputs.operand_value = 6.283 @@ -819,18 +865,17 @@ def distcor_blip_fsl_topup(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(run_topup, 'corrected_outfile', mag_field_map, 'in_file') - #fsl_bet - bet = pe.Node(interface = fsl.BET(), name="bet") + # fsl_bet + bet = pe.Node(interface=fsl.BET(), name="bet") bet.inputs.frac = 0.35 bet.inputs.mask = True wf.connect(mag_field_map, 'out_file', bet, 'in_file') outputs = { - 'desc-reginput_bold': (mul_jac, 'out_file'), - 'space-bold_desc-brain_mask': (bet, 'out_file'), - 'blip-warp': (convert_warp, 'out_file') + 'sbref': (mul_jac, 'out_file'), + 'fsl-blip-warp': (convert_warp, 'out_file') + #'space-bold_desc-brain_mask': (mask_sbref, 'out_file') } return (wf, outputs) - diff --git a/CPAC/distortion_correction/utils.py b/CPAC/distortion_correction/utils.py index e617bd6eb4..8df4ff6f6e 100755 --- a/CPAC/distortion_correction/utils.py +++ b/CPAC/distortion_correction/utils.py @@ -140,11 +140,9 @@ def gradient_distortion_correction(wf, inp_image, name): return (wf, out_warpmask, out_applywarp) -def phase_encode(unwarp_dir, phase_one, phase_two, dwell_time_one, - dwell_time_two): - """ - - Calculate readout time and populate parameter file +def phase_encode(unwarp_dir, phase_one, phase_two, dwell_time_one=None, + dwell_time_two=None, ro_time_one=None, ro_time_two=None): + """Calculate readout time and populate parameter file Parameters __________ @@ -159,8 +157,10 @@ def phase_encode(unwarp_dir, phase_one, phase_two, dwell_time_one, echo spacing of phase one dwell_time_two echo spacing of phase two - fsl_dir - FSL directory + ro_time_one + total readout time of phase one + ro_time_two + total readout time of phase two Returns _______ @@ -170,29 +170,44 @@ def phase_encode(unwarp_dir, phase_one, phase_two, dwell_time_one, """ + meta_data = [dwell_time_one, dwell_time_two, + ro_time_one, ro_time_two] + if not any(meta_data): + raise Exception("\n[!] Blip-FSL-TOPUP workflow: neither " + "TotalReadoutTime nor DwellTime is present in the " + "epi field map meta-data.") + # create text file acq_params = os.path.join(os.getcwd(), "acqparams.txt") if isinstance(unwarp_dir, bytes): unwarp_dir = unwarp_dir.decode() - if unwarp_dir in ["x", "x-", "-x","i","-i","i-"]: - dim = nibabel.load(phase_one).shape[0] - n_PE_steps = dim - 1 - ro_time_one = np.round(dwell_time_one * n_PE_steps, 6) - ro_time_two = np.round(dwell_time_two * n_PE_steps, 6) - ro_times = [f"-1 0 0 {ro_time_one}", f"1 0 0 {ro_time_two}"] - elif unwarp_dir in ["y", "y-", "-y","j","-j","j-"]: - dim = nibabel.load(phase_one).shape[1] - n_PE_steps = dim - 1 - ro_time_one = np.round(dwell_time_one * n_PE_steps, 6) - ro_time_two = np.round(dwell_time_two * n_PE_steps, 6) - ro_times = [f"0 -1 0 {ro_time_one}", f"0 1 0 {ro_time_two}"] + if unwarp_dir in ["x", "x-", "-x", "i", "-i", "i-"]: + if dwell_time_one and dwell_time_two: + dim = nibabel.load(phase_one).shape[0] + n_PE_steps = dim - 1 + ro_time_one = np.round(dwell_time_one * n_PE_steps, 6) + ro_time_two = np.round(dwell_time_two * n_PE_steps, 6) + if ro_time_one and ro_time_two: + ro_times = [f"-1 0 0 {ro_time_one}", f"1 0 0 {ro_time_two}"] + else: + raise Exception("[!] No dwell time or total readout time " + "present for the acq-fMRI EPI field maps.") + elif unwarp_dir in ["y", "y-", "-y", "j", "-j", "j-"]: + if dwell_time_one and dwell_time_two: + dim = nibabel.load(phase_one).shape[1] + n_PE_steps = dim - 1 + ro_time_one = np.round(dwell_time_one * n_PE_steps, 6) + ro_time_two = np.round(dwell_time_two * n_PE_steps, 6) + if ro_time_one and ro_time_two: + ro_times = [f"0 -1 0 {ro_time_one}", f"0 1 0 {ro_time_two}"] + else: + raise Exception("[!] No dwell time or total readout time " + "present for the acq-fMRI EPI field maps.") else: raise Exception(f"unwarp_dir={unwarp_dir} is unsupported.") - - # get number of volumes dims = [ int(subprocess.check_output([f"fslval", phase_one, "dim4"]).decode(sys.stdout.encoding)), diff --git a/CPAC/easy_thresh/easy_thresh.py b/CPAC/easy_thresh/easy_thresh.py index 0b7daa6237..feba789024 100755 --- a/CPAC/easy_thresh/easy_thresh.py +++ b/CPAC/easy_thresh/easy_thresh.py @@ -1,4 +1,8 @@ +import os +import re +import subprocess +import nibabel as nib from CPAC.pipeline import nipype_pipeline_engine as pe import nipype.interfaces.fsl as fsl import nipype.interfaces.utility as util @@ -232,7 +236,7 @@ def easy_thresh(wf_name): # #defines the cluster cordinates # cluster.inputs.out_localmax_txt_file = True - cluster_imports = ['import os', 'import re', 'import subprocess as sb'] + cluster_imports = ['import os', 'import re', 'import subprocess'] cluster = pe.MapNode(util.Function(input_names=['in_file', 'volume', 'dlh', @@ -279,7 +283,7 @@ def easy_thresh(wf_name): # function mapnode to get the standard fsl brain image based on parameters # as FSLDIR,MNI and voxel size - get_bg_imports = ['import os', 'from nibabel import load'] + get_bg_imports = ['import os', 'import nibabel as nib'] get_backgroundimage = pe.MapNode(util.Function(input_names=['in_file', 'file_parameters'], output_names=['out_file'], @@ -351,7 +355,7 @@ def easy_thresh(wf_name): def call_cluster(in_file, volume, dlh, threshold, pthreshold, parameters): - out_name = re.match('z(\w)*stat(\d)+', os.path.basename(in_file)) + out_name = re.match(r'z(\w)*stat(\d)+', os.path.basename(in_file)) filename, ext = os.path.splitext(os.path.basename(in_file)) ext= os.path.splitext(filename)[1] + ext @@ -372,7 +376,7 @@ def call_cluster(in_file, volume, dlh, threshold, pthreshold, parameters): f = open(localmax_txt_file,'wb') - cmd = sb.Popen([ cmd_path, + cmd = subprocess.Popen([ cmd_path, '--dlh=' + str(dlh), '--in=' + in_file, '--oindex=' + index_file, @@ -451,7 +455,7 @@ def get_standard_background_img(in_file, file_parameters): try: - img = load(in_file) + img = nib.load(in_file) hdr = img.get_header() group_mm = int(hdr.get_zooms()[2]) FSLDIR, MNI = file_parameters diff --git a/CPAC/func_preproc/func_ingress.py b/CPAC/func_preproc/func_ingress.py index a7c46824c1..d34758ff58 100755 --- a/CPAC/func_preproc/func_ingress.py +++ b/CPAC/func_preproc/func_ingress.py @@ -1,26 +1,28 @@ -from nipype import logging -logger = logging.getLogger('nipype.workflow') +# Copyright (C) 2020-2022 C-PAC Developers -from CPAC.pipeline import nipype_pipeline_engine as pe +# This file is part of C-PAC. -import nipype.interfaces.afni as afni +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -from CPAC.utils.interfaces.function import Function -from CPAC.utils.utils import ( - get_scan_params -) +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +from nipype import logging from CPAC.utils.datasource import ( create_func_datasource, - create_fmap_datasource, - get_fmap_phasediff_metadata, - calc_deltaTE_and_asym_ratio -) + ingress_func_metadata) +logger = logging.getLogger('nipype.workflow') def connect_func_ingress(workflow, strat_list, c, sub_dict, subject_id, input_creds_path, unique_id=None): - for num_strat, strat in enumerate(strat_list): if 'func' in sub_dict: @@ -49,168 +51,8 @@ def connect_func_ingress(workflow, strat_list, c, sub_dict, subject_id, 'scan': (func_wf, 'outputspec.scan') }) - # Grab field maps - diff = False - blip = False - fmap_rp_list = [] - fmap_TE_list = [] - - if "fmap" in sub_dict: - for key in sub_dict["fmap"]: - - gather_fmap = create_fmap_datasource(sub_dict["fmap"], - "fmap_gather_" - "{0}".format(key)) - gather_fmap.inputs.inputnode.set( - subject=subject_id, - creds_path=input_creds_path, - dl_dir=c.pipeline_setup['working_directory']['path'] - ) - gather_fmap.inputs.inputnode.scan = key - strat.update_resource_pool({ - key: (gather_fmap, 'outputspec.rest'), - "{0}_scan_params".format(key): (gather_fmap, - 'outputspec.scan_params') - }) - - fmap_rp_list.append(key) - - if key == "diff_phase" or key == "diff_mag_one" or \ - key == "diff_mag_two": - diff = True - - get_fmap_metadata_imports = ['import json'] - get_fmap_metadata = pe.Node(Function( - input_names=['data_config_scan_params'], - output_names=['echo_time', - 'dwell_time', - 'pe_direction'], - function=get_fmap_phasediff_metadata, - imports=get_fmap_metadata_imports), - name='{0}_get_metadata_{1}'.format(key, - num_strat)) - - node, out_file = strat["{}_scan_params".format(key)] - workflow.connect(node, out_file, get_fmap_metadata, - 'data_config_scan_params') - - strat.update_resource_pool({ - "{}_TE".format(key): (get_fmap_metadata, - 'echo_time'), - "{}_dwell".format(key): (get_fmap_metadata, - 'dwell_time'), - "{}_pedir".format(key): (get_fmap_metadata, - 'pe_direction') - }) - fmap_TE_list.append("{}_TE".format(key)) - - if "epi_" in key: - blip = True - - if diff: - calc_delta_ratio = pe.Node(Function( - input_names=['dwell_time', - 'echo_time_one', - 'echo_time_two', - 'echo_time_three'], - output_names=['deltaTE', - 'dwell_asym_ratio'], - function=calc_deltaTE_and_asym_ratio), - name='diff_distcor_calc_delta_{}'.format(num_strat)) - - node, out_file = strat['diff_phase_dwell'] - workflow.connect(node, out_file, calc_delta_ratio, - 'dwell_time') - - node, out_file = strat[fmap_TE_list[0]] - workflow.connect(node, out_file, calc_delta_ratio, - 'echo_time_one') - - node, out_file = strat[fmap_TE_list[1]] - workflow.connect(node, out_file, calc_delta_ratio, - 'echo_time_two') - - if len(fmap_TE_list) > 2: - node, out_file = strat[fmap_TE_list[2]] - workflow.connect(node, out_file, calc_delta_ratio, - 'echo_time_three') - - strat.update_resource_pool({ - 'deltaTE': (calc_delta_ratio, 'deltaTE'), - 'dwell_asym_ratio': (calc_delta_ratio, - 'dwell_asym_ratio') - }) - - # Add in nodes to get parameters from configuration file - # a node which checks if scan_parameters are present for each scan - if unique_id is None: - workflow_name=f'scan_params_{num_strat}' - else: - workflow_name=f'scan_params_{unique_id}_{num_strat}' - - scan_params = \ - pe.Node(Function( - input_names=['data_config_scan_params', - 'subject_id', - 'scan', - 'pipeconfig_tr', - 'pipeconfig_tpattern', - 'pipeconfig_start_indx', - 'pipeconfig_stop_indx'], - output_names=['tr', - 'tpattern', - 'ref_slice', - 'start_indx', - 'stop_indx', - 'pe_direction'], - function=get_scan_params, - as_module=True - ), name=workflow_name) - - if "Selected Functional Volume" in c.functional_registration['1-coregistration']['func_input_prep']['input']: - get_func_volume = pe.Node(interface=afni.Calc(), - name='get_func_volume_{0}'.format( - num_strat)) - - get_func_volume.inputs.set( - expr='a', - single_idx=c.functional_registration['1-coregistration']['func_input_prep']['Selected Functional Volume']['func_reg_input_volume'], - outputtype='NIFTI_GZ' - ) - workflow.connect(func_wf, 'outputspec.rest', - get_func_volume, 'in_file_a') - - # wire in the scan parameter workflow - workflow.connect(func_wf, 'outputspec.scan_params', - scan_params, 'data_config_scan_params') - - workflow.connect(func_wf, 'outputspec.subject', - scan_params, 'subject_id') - - workflow.connect(func_wf, 'outputspec.scan', - scan_params, 'scan') - - # connect in constants - scan_params.inputs.set( - pipeconfig_start_indx=c.functional_preproc['truncation']['start_tr'], - pipeconfig_stop_indx=c.functional_preproc['truncation']['stop_tr'] - ) - - strat.update_resource_pool({ - 'raw_functional': (func_wf, 'outputspec.rest'), - 'scan_id': (func_wf, 'outputspec.scan'), - 'tr': (scan_params, 'tr'), - 'tpattern': (scan_params, 'tpattern'), - 'start_idx': (scan_params, 'start_indx'), - 'stop_idx': (scan_params, 'stop_indx'), - 'pe_direction': (scan_params, 'pe_direction'), - }) - - strat.set_leaf_properties(func_wf, 'outputspec.rest') - - if "Selected Functional Volume" in c.functional_registration['1-coregistration']['func_input_prep']['input']: - strat.update_resource_pool({ - 'selected_func_volume': (get_func_volume, 'out_file') - }) + (workflow, strat.rpool, diff, blip, fmap_rp_list + ) = ingress_func_metadata(workflow, c, strat.rpool, sub_dict, + subject_id, input_creds_path, unique_id) return (workflow, diff, blip, fmap_rp_list) diff --git a/CPAC/func_preproc/func_preproc.py b/CPAC/func_preproc/func_preproc.py index 6b5eed6bff..61d14a2574 100755 --- a/CPAC/func_preproc/func_preproc.py +++ b/CPAC/func_preproc/func_preproc.py @@ -156,6 +156,7 @@ def anat_refined_mask(init_bold_mask=True, wf_name='init_bold_mask'): return wf + def anat_based_mask(wf_name='bold_mask'): # reference DCAN lab BOLD mask # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/DistortionCorrectionAndEPIToT1wReg_FLIRTBBRAndFreeSurferBBRbased.sh @@ -574,7 +575,7 @@ def get_idx(in_files, stop_idx=None, start_idx=None): else: startidx = int(start_idx) - if (stop_idx == None) or (int(stop_idx) > (nvols - 1)): + if (stop_idx in [None, "End"]) or (int(stop_idx) > (nvols - 1)): stopidx = nvols - 1 else: stopidx = int(stop_idx) @@ -607,7 +608,7 @@ def motion_correct_connections(wf, cfg, strat_pool, pipe_num, opt): # 10-TR sized chunks chunk.inputs.chunk_size = 10 - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, chunk, 'func_file') split_imports = ['import os', 'import subprocess'] @@ -618,7 +619,7 @@ def motion_correct_connections(wf, cfg, strat_pool, pipe_num, opt): imports=split_imports), name=f'split_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, split, 'func_file') wf.connect(chunk, 'TR_ranges', split, 'tr_ranges') @@ -654,7 +655,7 @@ def motion_correct_connections(wf, cfg, strat_pool, pipe_num, opt): interface=util.IdentityInterface(fields=['out_file']), name=f'out_split_func_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, out_split_func, 'out_file') func_motion_correct = pe.Node(interface=preprocess.Volreg(), @@ -675,7 +676,7 @@ def motion_correct_connections(wf, cfg, strat_pool, pipe_num, opt): interface=util.IdentityInterface(fields=['out_file']), name=f'out_split_func_{pipe_num}') - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, out_split_func, 'out_file') func_motion_correct = pe.Node(interface=preprocess.Volreg(), @@ -855,7 +856,7 @@ def motion_correct_connections(wf, cfg, strat_pool, pipe_num, opt): func_motion_correct_A.inputs.save_plots = True func_motion_correct_A.inputs.save_rms = True - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, func_motion_correct_A, 'in_file') node, out = strat_pool.get_data('motion-basefile') @@ -890,6 +891,47 @@ def motion_correct_connections(wf, cfg, strat_pool, pipe_num, opt): return (wf, outputs) +def func_reorient(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "func_reorient", + "config": ["functional_preproc"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["bold"], + "outputs": ["desc-preproc_bold", + "desc-reorient_bold"]} + ''' + + func_deoblique = pe.Node(interface=afni_utils.Refit(), + name=f'func_deoblique_{pipe_num}', + mem_gb=0.68, + mem_x=(4664065662093477 / + 1208925819614629174706176, + 'in_file')) + func_deoblique.inputs.deoblique = True + + node, out = strat_pool.get_data('bold') + wf.connect(node, out, func_deoblique, 'in_file') + + func_reorient = pe.Node(interface=afni_utils.Resample(), + name=f'func_reorient_{pipe_num}', + mem_gb=0, + mem_x=(0.0115, 'in_file', 't')) + + func_reorient.inputs.orientation = 'RPI' + func_reorient.inputs.outputtype = 'NIFTI_GZ' + + wf.connect(func_deoblique, 'out_file', func_reorient, 'in_file') + + outputs = { + 'desc-preproc_bold': (func_reorient, 'out_file'), + 'desc-reorient_bold': (func_reorient, 'out_file') + } + + return (wf, outputs) + + def func_scaling(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "func_scaling", @@ -897,7 +939,7 @@ def func_scaling(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"]], + "inputs": ["desc-preproc_bold"], "outputs": ["desc-preproc_bold"]} ''' @@ -906,7 +948,7 @@ def func_scaling(wf, cfg, strat_pool, pipe_num, opt=None): wf_name=f"scale_func_{pipe_num}" ) - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, scale_func_wf, 'inputspec.func') outputs = { @@ -923,7 +965,7 @@ def func_truncate(wf, cfg, strat_pool, pipe_num, opt=None): "switch": "None", "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"]], + "inputs": ["desc-preproc_bold"], "outputs": { "desc-preproc_bold": { "Description": "Truncated functional time-series BOLD data." @@ -933,7 +975,7 @@ def func_truncate(wf, cfg, strat_pool, pipe_num, opt=None): # if cfg.functional_preproc['truncation']['start_tr'] == 0 and \ # cfg.functional_preproc['truncation']['stop_tr'] == None: - # data, key = strat_pool.get_data(["desc-preproc_bold", "bold"], + # data, key = strat_pool.get_data("desc-preproc_bold", # True) # outputs = {key: data} # return (wf, outputs) @@ -946,7 +988,7 @@ def func_truncate(wf, cfg, strat_pool, pipe_num, opt=None): trunc_wf.inputs.inputspec.stop_idx = cfg.functional_preproc['truncation'][ 'stop_tr'] - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, trunc_wf, 'inputspec.func') outputs = { @@ -961,9 +1003,9 @@ def func_despike(wf, cfg, strat_pool, pipe_num, opt=None): {"name": "func_despike", "config": ["functional_preproc", "despiking"], "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"]], + "option_key": ["space"], + "option_val": ["native"], + "inputs": ["desc-preproc_bold"], "outputs": { "desc-preproc_bold": { "Description": "De-spiked BOLD time-series via AFNI 3dDespike." @@ -978,7 +1020,7 @@ def func_despike(wf, cfg, strat_pool, pipe_num, opt=None): 'in_file')) despike.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, despike, 'in_file') outputs = { @@ -988,6 +1030,59 @@ def func_despike(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) +def func_despike_template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "func_despike_template", + "config": ["functional_preproc", "despiking"], + "switch": ["run"], + "option_key": ["space"], + "option_val": ["template"], + "inputs": [("space-template_desc-preproc_bold", + "space-template_res-derivative_desc-preproc_bold"), + "T1w-template-funcreg", + "T1w-template-deriv"], + "outputs": { + "space-template_desc-preproc_bold": { + "Description": "De-spiked BOLD time-series via AFNI 3dDespike.", + "Template": "T1w-template-funcreg"}, + "space-template_res-derivative_desc-preproc_bold": { + "Description": "De-spiked BOLD time-series via AFNI 3dDespike.", + "Template": "T1w-template-deriv"} + }} + ''' + + despike = pe.Node(interface=preprocess.Despike(), + name=f'func_despiked_template_{pipe_num}', + mem_gb=0.66, + mem_x=(8251808479088459 / 1208925819614629174706176, + 'in_file')) + despike.inputs.outputtype = 'NIFTI_GZ' + + node, out = strat_pool.get_data("space-template_desc-preproc_bold") + wf.connect(node, out, despike, 'in_file') + + outputs = { + 'space-template_desc-preproc_bold': (despike, 'out_file') + } + + if strat_pool.get_data("space-template_res-derivative_desc-preproc_bold"): + despike_funcderiv = pe.Node(interface=preprocess.Despike(), + name=f'func_deriv_despiked_template_{pipe_num}', + mem_gb=0.66, + mem_x=(8251808479088459 / 1208925819614629174706176, + 'in_file')) + despike_funcderiv.inputs.outputtype = 'NIFTI_GZ' + + node, out = strat_pool.get_data("space-template_res-derivative_desc-preproc_bold") + wf.connect(node, out, despike_funcderiv, 'in_file') + + outputs.update({ + 'space-template_res-derivative_desc-preproc_bold': + (despike_funcderiv, 'out_file')}) + + return (wf, outputs) + + def func_slice_time(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "func_slice_time", @@ -995,26 +1090,28 @@ def func_slice_time(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"], + "inputs": ["desc-preproc_bold", "TR", "tpattern"], "outputs": { "desc-preproc_bold": { - "Description": "Slice-time corrected BOLD time-series via AFNI 3dTShift." + "Description": "Slice-time corrected BOLD time-series via" + " AFNI 3dTShift." }, "desc-stc_bold": { - "Description": "Slice-time corrected BOLD time-series via AFNI 3dTShift."}} + "Description": "Slice-time corrected BOLD time-series via" + " AFNI 3dTShift."}} } ''' slice_time = slice_timing_wf(name='func_slice_timing_correction_' - f'{pipe_num}', + f'{pipe_num}', tpattern=cfg.functional_preproc[ - 'slice_timing_correction']['tpattern'], + 'slice_timing_correction']['tpattern'], tzero=cfg.functional_preproc[ - 'slice_timing_correction']['tzero']) + 'slice_timing_correction']['tzero']) - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, slice_time, 'inputspec.func_ts') node, out = strat_pool.get_data('TR') @@ -1031,46 +1128,6 @@ def func_slice_time(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -def func_reorient(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "func_reorient", - "config": ["functional_preproc"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"]], - "outputs": ["desc-preproc_bold", "desc-reorient_bold"]} - ''' - - func_deoblique = pe.Node(interface=afni_utils.Refit(), - name=f'func_deoblique_{pipe_num}', - mem_gb=0.68, - mem_x=(4664065662093477 / - 1208925819614629174706176, - 'in_file')) - func_deoblique.inputs.deoblique = True - - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) - wf.connect(node, out, func_deoblique, 'in_file') - - func_reorient = pe.Node(interface=afni_utils.Resample(), - name=f'func_reorient_{pipe_num}', - mem_gb=0, - mem_x=(0.0115, 'in_file', 't')) - - func_reorient.inputs.orientation = 'RPI' - func_reorient.inputs.outputtype = 'NIFTI_GZ' - - wf.connect(func_deoblique, 'out_file', func_reorient, 'in_file') - - outputs = { - 'desc-preproc_bold': (func_reorient, 'out_file'), - 'desc-reorient_bold': (func_reorient, 'out_file') - } - - return (wf, outputs) - - def get_motion_ref(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "get_motion_ref", @@ -1080,8 +1137,8 @@ def get_motion_ref(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": ["functional_preproc", "motion_estimates_and_correction", "motion_correction", "motion_correction_reference"], "option_val": ["mean", "median", "selected_volume", "fmriprep_reference"], - "inputs": [["desc-preproc_bold", "bold"], - "bold"], + "inputs": ["desc-preproc_bold", + "desc-reorient_bold"], "outputs": ["motion-basefile"]} ''' option_vals = grab_docstring_dct(get_motion_ref).get('option_val') @@ -1104,7 +1161,7 @@ def get_motion_ref(wf, cfg, strat_pool, pipe_num, opt=None): func_get_RPI.inputs.options = '-mean' func_get_RPI.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, func_get_RPI, 'in_file') elif opt == 'median': @@ -1114,7 +1171,7 @@ def get_motion_ref(wf, cfg, strat_pool, pipe_num, opt=None): func_get_RPI.inputs.options = '-median' func_get_RPI.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, func_get_RPI, 'in_file') elif opt == 'selected_volume': @@ -1128,7 +1185,7 @@ def get_motion_ref(wf, cfg, strat_pool, pipe_num, opt=None): outputtype='NIFTI_GZ' ) - node, out = strat_pool.get_data(['desc-preproc_bold', 'bold']) + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, func_get_RPI, 'in_file_a') elif opt == 'fmriprep_reference': @@ -1137,7 +1194,7 @@ def get_motion_ref(wf, cfg, strat_pool, pipe_num, opt=None): function=estimate_reference_image), name=f'func_get_fmriprep_ref_{pipe_num}') - node, out = strat_pool.get_data('bold') + node, out = strat_pool.get_data('desc-reorient_bold') wf.connect(node, out, func_get_RPI, 'in_file') outputs = { @@ -1151,12 +1208,12 @@ def func_motion_correct(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "motion_correction", "config": "None", - "switch": ["functional_preproc", "motion_estimates_and_correction", + "switch": ["functional_preproc", "motion_estimates_and_correction", "run"], "option_key": ["functional_preproc", "motion_estimates_and_correction", "motion_correction", "using"], "option_val": ["3dvolreg", "mcflirt"], - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("desc-preproc_bold", "motion-basefile")], "outputs": ["desc-preproc_bold", "desc-motion_bold", @@ -1176,12 +1233,12 @@ def func_motion_estimates(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "motion_estimates", "config": "None", - "switch": ["functional_preproc", "motion_estimates_and_correction", + "switch": ["functional_preproc", "motion_estimates_and_correction", "run"], "option_key": ["functional_preproc", "motion_estimates_and_correction", "motion_correction", "using"], "option_val": ["3dvolreg", "mcflirt"], - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("desc-preproc_bold", "motion-basefile")], "outputs": ["max-displacement", "rels-displacement", @@ -1216,7 +1273,7 @@ def func_motion_correct_only(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": ["functional_preproc", "motion_estimates_and_correction", "motion_correction", "using"], "option_val": ["3dvolreg", "mcflirt"], - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("desc-preproc_bold", "motion-basefile")], "outputs": ["desc-preproc_bold", "desc-motion_bold"]} @@ -1226,6 +1283,7 @@ def func_motion_correct_only(wf, cfg, strat_pool, pipe_num, opt=None): opt) outputs = { + 'desc-preproc_bold': wf_outputs['desc-motion_bold'], 'desc-motion_bold': wf_outputs['desc-motion_bold'] } @@ -1238,19 +1296,20 @@ def motion_estimate_filter(wf, cfg, strat_pool, pipe_num, opt=None): "config": ["functional_preproc", "motion_estimates_and_correction", "motion_estimate_filter"], "switch": ["run"], - "option_key": "filter_type", - "option_val": ["notch", "lowpass"], + "option_key": "filters", + "option_val": "USER-DEFINED", "inputs": ["movement-parameters", "TR"], "outputs": ["movement-parameters", "motion-filter-info", "motion-filter-plot"]} ''' - notch_imports = ['import os', 'import numpy as np', - 'from scipy.signal import iirnotch, lfilter, firwin, freqz', + 'from scipy.signal import iirnotch, lfilter, firwin, ' + 'freqz', 'from matplotlib import pyplot as plt', - 'from CPAC.func_preproc.utils import degrees_to_mm, mm_to_degrees'] + 'from CPAC.func_preproc.utils import degrees_to_mm, ' + 'mm_to_degrees'] notch = pe.Node(Function(input_names=['motion_params', 'filter_type', 'TR', @@ -1266,29 +1325,15 @@ def motion_estimate_filter(wf, cfg, strat_pool, pipe_num, opt=None): 'filter_plot'], function=notch_filter_motion, imports=notch_imports), - name=f'filter_motion_params_{pipe_num}') - - notch.inputs.filter_type = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['filter_type'] - notch.inputs.fc_RR_min = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['breathing_rate_min'] - notch.inputs.fc_RR_max = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['breathing_rate_max'] - notch.inputs.center_freq = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['center_frequency'] - notch.inputs.freq_bw = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['filter_bandwidth'] - notch.inputs.lowpass_cutoff = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['lowpass_cutoff'] - notch.inputs.filter_order = cfg.functional_preproc[ - "motion_estimates_and_correction"][ - "motion_estimate_filter"]['filter_order'] + name=f'filter_motion_params_{opt["Name"]}_{pipe_num}') + + notch.inputs.filter_type = opt.get('filter_type') + notch.inputs.fc_RR_min = opt.get('breathing_rate_min') + notch.inputs.fc_RR_max = opt.get('breathing_rate_max') + notch.inputs.center_freq = opt.get('center_frequency') + notch.inputs.freq_bw = opt.get('filter_bandwidth') + notch.inputs.lowpass_cutoff = opt.get('lowpass_cutoff') + notch.inputs.filter_order = opt.get('filter_order') node, out = strat_pool.get_data('movement-parameters') wf.connect(node, out, notch, 'motion_params') @@ -1394,7 +1439,7 @@ def bold_mask_afni(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["func_masking", "using"], "option_val": "AFNI", - "inputs": [["desc-preproc_bold", "bold"]], + "inputs": ["desc-preproc_bold"], "outputs": { "space-bold_desc-brain_mask": { "Description": "Binary brain mask of the BOLD functional " @@ -1405,8 +1450,7 @@ def bold_mask_afni(wf, cfg, strat_pool, pipe_num, opt=None): name=f'func_get_brain_mask_AFNI_{pipe_num}') func_get_brain_mask.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(["desc-preproc_bold", - "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_get_brain_mask, 'in_file') outputs = { @@ -1423,7 +1467,7 @@ def bold_mask_fsl(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["func_masking", "using"], "option_val": "FSL", - "inputs": [["desc-preproc_bold", "bold"]], + "inputs": ["desc-preproc_bold"], "outputs": ["space-bold_desc-brain_mask"]} ''' @@ -1495,7 +1539,7 @@ def bold_mask_fsl(wf, cfg, strat_pool, pipe_num, opt=None): func_skull_mean.inputs.options = '-mean' func_skull_mean.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_skull_mean, 'in_file') out_node, out_file = (func_skull_mean, 'out_file') @@ -1549,7 +1593,7 @@ def form_thr_string(thr): else: func_get_brain_mask.inputs.functional = True - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_get_brain_mask, 'in_file') # erode one voxel of functional brian mask @@ -1576,8 +1620,10 @@ def bold_mask_fsl_afni(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["func_masking", "using"], "option_val": "FSL_AFNI", - "inputs": [["desc-motion_bold", "desc-preproc_bold", "bold"], - "motion-basefile", "FSL-AFNI-bold-ref", "FSL-AFNI-brain-mask", + "inputs": [("motion-basefile", + "desc-preproc_bold"), + "FSL-AFNI-bold-ref", + "FSL-AFNI-brain-mask", "FSL-AFNI-brain-probseg"], "outputs": ["space-bold_desc-brain_mask", "desc-ref_bold"]} @@ -1758,8 +1804,8 @@ def bold_mask_anatomical_refined(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["func_masking", "using"], "option_val": "Anatomical_Refined", - "inputs": ["bold", - ["desc-preproc_bold", "bold"], + "inputs": [("bold", + "desc-preproc_bold"), ("desc-brain_T1w", ["space-T1w_desc-brain_mask", "space-T1w_desc-acpcbrain_mask"])], @@ -1884,9 +1930,9 @@ def bold_mask_anatomical_based(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["func_masking", "using"], "option_val": "Anatomical_Based", - "inputs": [["desc-preproc_bold", "bold"], - "desc-brain_T1w", - ["desc-preproc_T1w", "desc-reorient_T1w", "T1w"]], + "inputs": ["desc-preproc_bold", + ("desc-brain_T1w", + ["desc-preproc_T1w", "desc-reorient_T1w", "T1w"])], "outputs": ["space-bold_desc-brain_mask"]} ''' @@ -1900,8 +1946,7 @@ def bold_mask_anatomical_based(wf, cfg, strat_pool, pipe_num, opt=None): outputtype='NIFTI_GZ' ) - node, out = strat_pool.get_data(["desc-preproc_bold", - "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_single_volume, 'in_file_a') # 1. Register func head to anat head to get func2anat matrix @@ -1938,8 +1983,7 @@ def bold_mask_anatomical_based(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("desc-brain_T1w") wf.connect(node, out, reg_anat_brain_to_func, 'in_file') - node, out = strat_pool.get_data(["desc-preproc_bold", - "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, reg_anat_brain_to_func, 'ref_file') wf.connect(inv_func_to_anat_affine, 'out_file', @@ -1980,9 +2024,9 @@ def bold_mask_anatomical_resampled(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["func_masking", "using"], "option_val": "Anatomical_Resampled", - "inputs": [["desc-preproc_bold", "bold"], + "inputs": ["desc-preproc_bold", "T1w-template-funcreg", - "space-template_desc-brain_T1w", + "space-template_desc-preproc_T1w", "space-template_desc-T1w_mask"], "outputs": ["space-template_res-bold_desc-brain_T1w", "space-template_desc-bold_mask", @@ -1997,7 +2041,7 @@ def bold_mask_anatomical_resampled(wf, cfg, strat_pool, pipe_num, opt=None): anat_brain_to_func_res.inputs.premat = cfg.registration_workflows[ 'anatomical_registration']['registration']['FSL-FNIRT']['identity_matrix'] - node, out = strat_pool.get_data('space-template_desc-brain_T1w') + node, out = strat_pool.get_data('space-template_desc-preproc_T1w') wf.connect(node, out, anat_brain_to_func_res, 'in_file') node, out = strat_pool.get_data('T1w-template-funcreg') @@ -2030,7 +2074,7 @@ def bold_mask_anatomical_resampled(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(anat_brain_mask_to_func_res, 'out_file', func_mask_template_to_native, 'in_file') - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_mask_template_to_native, 'master') outputs = { @@ -2190,10 +2234,11 @@ def bold_masking(wf, cfg, strat_pool, pipe_num, opt=None): {"name": "bold_masking", "config": None, "switch": [["functional_preproc", "run"], - ["functional_preproc", "func_masking", "apply_func_mask_in_native_space"]], + ["functional_preproc", "func_masking", + "apply_func_mask_in_native_space"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("desc-preproc_bold", "space-bold_desc-brain_mask")], "outputs": { "desc-preproc_bold": { @@ -2204,15 +2249,13 @@ def bold_masking(wf, cfg, strat_pool, pipe_num, opt=None): "SkullStripped": True}} } ''' - func_edge_detect = pe.Node(interface=afni_utils.Calc(), name=f'func_extract_brain_{pipe_num}') func_edge_detect.inputs.expr = 'a*b' func_edge_detect.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(["desc-preproc_bold", - "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_edge_detect, 'in_file_a') node, out = strat_pool.get_data("space-bold_desc-brain_mask") @@ -2234,7 +2277,7 @@ def func_mean(wf, cfg, strat_pool, pipe_num, opt=None): ["functional_preproc", "generate_func_mean", "run"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"]], + "inputs": ["desc-preproc_bold"], "outputs": ["desc-mean_bold"] } ''' @@ -2245,7 +2288,7 @@ def func_mean(wf, cfg, strat_pool, pipe_num, opt=None): func_mean.inputs.options = '-mean' func_mean.inputs.outputtype = 'NIFTI_GZ' - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_mean, 'in_file') outputs = { @@ -2263,7 +2306,7 @@ def func_normalize(wf, cfg, strat_pool, pipe_num, opt=None): ["functional_preproc", "normalize_func", "run"]], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"]], + "inputs": ["desc-preproc_bold"], "outputs": ["desc-preproc_bold"]} ''' @@ -2275,7 +2318,7 @@ def func_normalize(wf, cfg, strat_pool, pipe_num, opt=None): func_normalize.inputs.op_string = '-ing 10000' func_normalize.inputs.out_data_type = 'float' - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_normalize, 'in_file') outputs = { @@ -2292,7 +2335,7 @@ def func_mask_normalize(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("desc-preproc_bold", "space-bold_desc-brain_mask")], "outputs": ["space-bold_desc-brain_mask"]} ''' @@ -2305,7 +2348,7 @@ def func_mask_normalize(wf, cfg, strat_pool, pipe_num, opt=None): func_mask_normalize.inputs.op_string = '-Tmin -bin' func_mask_normalize.inputs.out_data_type = 'char' - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, func_mask_normalize, 'in_file') outputs = { diff --git a/CPAC/func_preproc/utils.py b/CPAC/func_preproc/utils.py index ab27caedd2..bd72642ca3 100755 --- a/CPAC/func_preproc/utils.py +++ b/CPAC/func_preproc/utils.py @@ -163,7 +163,7 @@ def notch_filter_motion(motion_params, filter_type, TR, fc_RR_min=None, bandwidth = fa[1] - fa[0] Q = Wn/bw - [b_filt, a_filt] = iirnotch(Wn, Q) + [b_filt, a_filt] = iirnotch(Wn, Q, fs) num_f_apply = np.floor(filter_order / 2) filter_info = f"Motion estimate filter information\n\nType: Notch\n" \ diff --git a/CPAC/image_utils/__init__.py b/CPAC/image_utils/__init__.py index 3bb29507ac..6d79f91bd8 100755 --- a/CPAC/image_utils/__init__.py +++ b/CPAC/image_utils/__init__.py @@ -1,2 +1,22 @@ -from .spatial_smoothing import * -from .statistical_transforms import * +# Copyright (C) 2018-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +from .spatial_smoothing import set_gauss, spatial_smoothing +from .statistical_transforms import calc_avg, fisher_z_score_standardize, \ + z_score_standardize + +__all__ = ['calc_avg', 'fisher_z_score_standardize', 'set_gauss', + 'spatial_smoothing', 'z_score_standardize'] diff --git a/CPAC/image_utils/spatial_smoothing.py b/CPAC/image_utils/spatial_smoothing.py index de5aa81fe3..f14dff8d87 100755 --- a/CPAC/image_utils/spatial_smoothing.py +++ b/CPAC/image_utils/spatial_smoothing.py @@ -1,8 +1,22 @@ -import nipype.interfaces.fsl as fsl +# Copyright (C) 2018-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +from nipype.interfaces import fsl, utility as util from nipype.interfaces.afni import preprocess as afni from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.utility as util -from CPAC.utils import Outputs def set_gauss(fwhm): @@ -64,17 +78,17 @@ def spatial_smoothing(wf_name, fwhm, input_image_type='func_derivative', elif opt == 'AFNI': if input_image_type == 'func_derivative_multi': - output_smooth = pe.MapNode(interface= afni.BlurToFWHM(), + output_smooth = pe.MapNode(interface=afni.BlurToFWHM(), name='smooth_multi', iterfield=['in_file']) else: - output_smooth = pe.Node(interface= afni.BlurToFWHM(), + output_smooth = pe.Node(interface=afni.BlurToFWHM(), name='smooth', iterfield=['in_file']) output_smooth.inputs.outputtype = 'NIFTI_GZ' - if opt =='FSL': - # wire in the resource to be smoothed + if opt == 'FSL': + # wire in the resource to be smoothed wf.connect(inputnode, 'in_file', output_smooth, 'in_file') # get the parameters for fwhm wf.connect(inputnode_fwhm, ('fwhm', set_gauss), diff --git a/CPAC/image_utils/statistical_transforms.py b/CPAC/image_utils/statistical_transforms.py index 490fe593e4..c3b989931c 100755 --- a/CPAC/image_utils/statistical_transforms.py +++ b/CPAC/image_utils/statistical_transforms.py @@ -1,7 +1,22 @@ -from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.utility as util -from nipype.interfaces.afni import preprocess +# Copyright (C) 2018-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +from nipype.interfaces import utility as util +from nipype.interfaces.afni import preprocess +from CPAC.pipeline import nipype_pipeline_engine as pe from CPAC.utils import function from CPAC.utils.utils import ( extract_output_mean, diff --git a/CPAC/info.py b/CPAC/info.py index bf68131ac9..4dface457e 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -43,7 +43,7 @@ # version _version_major = 1 _version_minor = 8 -_version_micro = 4 +_version_micro = 5 _version_extra = '' @@ -178,27 +178,31 @@ def get_cpac_gitversion(): "future", "INDI-Tools", "lockfile==0.12.2", + "joblib==1.0.1", "matplotlib==3.1.3", "networkx==2.4", "nibabel==3.2.1", "nilearn==0.4.1", "nipype==1.5.1", "nose==1.3.7", - "numpy==1.16.4", - "pandas==0.23.4", + "numpy==1.21.0", + "pandas==1.0.5", + "pathvalidate==2.5.2", "patsy==0.5.0", "prov==1.5.2", - "psutil==5.4.6", - "pybids==0.13.2", + "psutil==5.6.6", + "pybids==0.15.1", "pygraphviz==1.3.1", "PyPEER", "python-dateutil==2.7.3", - "pyyaml==5.3", + "pyyaml==5.4", "scikit-learn==0.22.1", - "scipy==1.4.1", + "scipy==1.6.3", + "sdcflows==2.0.5", "simplejson==3.15.0", "traits==4.6.0", "PyBASC==0.4.5", "voluptuous>=0.12.0", "joblib==1.1.0", + "ciftify", ] diff --git a/CPAC/longitudinal_pipeline/longitudinal_workflow.py b/CPAC/longitudinal_pipeline/longitudinal_workflow.py index 08f399c4ef..a7ee45c210 100755 --- a/CPAC/longitudinal_pipeline/longitudinal_workflow.py +++ b/CPAC/longitudinal_pipeline/longitudinal_workflow.py @@ -1,4 +1,20 @@ # -*- coding: utf-8 -*- +# Copyright (C) 2020-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import os import copy import time @@ -44,14 +60,12 @@ subject_specific_template ) -from CPAC.utils import Strategy, find_files, function, Outputs -from CPAC.utils.utils import check_prov_for_regtool - +from CPAC.utils import find_files, function +from CPAC.utils.outputs import Outputs +from CPAC.utils.strategy import Strategy from CPAC.utils.utils import ( check_config_resources, - check_system_deps, - get_scan_params, - get_tr + check_prov_for_regtool ) logger = logging.getLogger('nipype.workflow') @@ -446,7 +460,7 @@ def anat_longitudinal_wf(subject_id, sub_list, config): workflow.run() - cpac_dir = os.path.join(out_dir, f'cpac_{orig_pipe_name}', + cpac_dir = os.path.join(out_dir, f'pipeline_{orig_pipe_name}', f'{subject_id}_{unique_id}') cpac_dirs.append(os.path.join(cpac_dir, 'anat')) diff --git a/CPAC/network_centrality/network_centrality.py b/CPAC/network_centrality/network_centrality.py index 2744aa71ed..2c361d231c 100755 --- a/CPAC/network_centrality/network_centrality.py +++ b/CPAC/network_centrality/network_centrality.py @@ -126,10 +126,14 @@ def create_centrality_wf(wf_name, method_option, weight_options, afni_centrality_node, 'thresh') # Need to separate sub-briks + sep_nifti_imports = ["import os", "import nibabel as nib", + "from CPAC.pipeline.schema import valid_options", + "from CPAC.utils.docs import docstring_parameter"] sep_subbriks_node = \ pe.Node(util.Function(input_names=['nifti_file', 'out_names'], output_names=['output_niftis'], - function=utils.sep_nifti_subbriks), + function=utils.sep_nifti_subbriks, + imports=sep_nifti_imports), name='sep_nifti_subbriks') sep_subbriks_node.inputs.out_names = out_names diff --git a/CPAC/network_centrality/pipeline.py b/CPAC/network_centrality/pipeline.py index 87b456d8ff..4457b0114f 100755 --- a/CPAC/network_centrality/pipeline.py +++ b/CPAC/network_centrality/pipeline.py @@ -79,17 +79,21 @@ def network_centrality(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", - "space-template_bold"], + "inputs": [("space-template_desc-preproc_bold", + "T1w-brain-template-funcreg"), "template-specification-file"], - "outputs": ["space-template_desc-weighted_degree-centrality", - "space-template_desc-binarized_degree-centrality", - "space-template_desc-weighted_eigen-centrality", - "space-template_desc-binarized_eigen-centrality", - "space-template_desc-weighted_lfcd", - "space-template_desc-binarized_lfcd"]} + "outputs": {"space-template_dcw": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_dcb": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_ecw": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_ecb": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_lfcdw": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_lfcdb": { + "Template": "T1w-brain-template-funcreg"}}} ''' # Resample the functional mni to the centrality mask resolution @@ -106,10 +110,7 @@ def network_centrality(wf, cfg, strat_pool, pipe_num, opt=None): apply_xfm=True ) - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") wf.connect(node, out, resample_functional_to_template, 'in_file') node, out = strat_pool.get_data("template-specification-file") @@ -139,20 +140,28 @@ def network_centrality(wf, cfg, strat_pool, pipe_num, opt=None): for option in valid_options['centrality']['method_options']: if cfg.network_centrality[option]['weight_options']: for weight in cfg.network_centrality[option]['weight_options']: - if 'degree' in option.lower(): - if 'weight' in weight.lower(): - outputs['space-template_desc-weighted_degree-centrality'] = (merge_node, 'degree_weighted') - elif 'binarize' in weight.lower(): - outputs['space-template_desc-binarized_degree-centrality'] = (merge_node, 'degree_binarized') - elif 'eigen' in option.lower(): - if 'weight' in weight.lower(): - outputs['space-template_desc-weighted_eigen-centrality'] = (merge_node, 'eigen_weighted') - elif 'binarize' in weight.lower(): - outputs['space-template_desc-binarized_eigen-centrality'] = (merge_node, 'eigen_binarized') - elif 'lfcd' in option.lower() or 'local_functional' in option.lower(): - if 'weight' in weight.lower(): - outputs['space-template_desc-weighted_lfcd'] = (merge_node, 'lfcd_weighted') - elif 'binarize' in weight.lower(): - outputs['space-template_desc-binarized_lfcd'] = (merge_node, 'lfcd_binarized') + _option = option.lower() + _weight = weight.lower() + if 'degree' in _option: + if 'weight' in _weight: + outputs['space-template_dcw'] = (merge_node, + 'degree_weighted') + elif 'binarize' in _weight: + outputs['space-template_dcb'] = (merge_node, + 'degree_binarized') + elif 'eigen' in _option: + if 'weight' in _weight: + outputs['space-template_ecw'] = (merge_node, + 'eigen_weighted') + elif 'binarize' in _weight: + outputs['space-template_ecb'] = (merge_node, + 'eigen_binarized') + elif 'lfcd' in _option or 'local_functional' in _option: + if 'weight' in _weight: + outputs['space-template_lfcdw'] = (merge_node, + 'lfcd_weighted') + elif 'binarize' in _weight: + outputs['space-template_lfcdb'] = (merge_node, + 'lfcd_binarized') return (wf, outputs) diff --git a/CPAC/network_centrality/utils.py b/CPAC/network_centrality/utils.py index 9d61516b43..048f6fc2dc 100755 --- a/CPAC/network_centrality/utils.py +++ b/CPAC/network_centrality/utils.py @@ -1,3 +1,19 @@ +# Copyright (C) 2012-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . from CPAC.pipeline.schema import valid_options from CPAC.utils.docs import docstring_parameter @@ -82,21 +98,40 @@ def merge_lists(deg_list=[], eig_list=[], lfcd_list=[]): eigen_binarized, lfcd_weighted, lfcd_binarized) -# Separate sub-briks of niftis and save +@docstring_parameter( + weight_options=tuple(valid_options['centrality']['weight_options'])) def sep_nifti_subbriks(nifti_file, out_names): + '''Separate sub-briks of niftis and save specified out + + Parameters + ---------- + nifti_file : str + path to NIfTI output of an AFNI centrality tool + + out_names : iterable of str + an iterable of strings, each ending with one of {weight_options} + + Returns + ------- + list + each of the specified outputs as its own file ''' - ''' + # pylint: disable=redefined-outer-name,reimported,unused-import import os import nibabel as nib + from CPAC.pipeline.schema import valid_options + from CPAC.utils.docs import docstring_parameter # noqa: F401 output_niftis = [] + weight_options = valid_options['centrality']['weight_options'] + selected_options = {_[::-1].split('_', 1)[0][::-1]: _ for _ in out_names} nii_img = nib.load(nifti_file) nii_arr = nii_img.get_data() nii_affine = nii_img.get_affine() nii_dims = nii_arr.shape - if nii_dims[-1] != len(out_names): + if nii_dims[-1] != len(weight_options): if len(nii_dims) == 3 and len(out_names) == 1: pass else: @@ -104,15 +139,17 @@ def sep_nifti_subbriks(nifti_file, out_names): 'nifti sub-briks' raise Exception(err_msg) - for brik, out_name in enumerate(out_names): - if len(nii_dims) == 3: - brik_arr = nii_arr - elif len(nii_dims) > 3: - brik_arr = nii_arr[:, :, :, 0, brik] - out_file = os.path.join(os.getcwd(), out_name+'.nii.gz') - out_img = nib.Nifti1Image(brik_arr, nii_affine) - out_img.to_filename(out_file) - output_niftis.append(out_file) + for brik, option in enumerate(weight_options): + if option in selected_options: + if len(nii_dims) == 3: + brik_arr = nii_arr + elif len(nii_dims) > 3: + brik_arr = nii_arr[:, :, :, 0, brik] + out_file = os.path.join(os.getcwd(), + selected_options[option] + '.nii.gz') + out_img = nib.Nifti1Image(brik_arr, nii_affine) + out_img.to_filename(out_file) + output_niftis.append(out_file) return output_niftis diff --git a/CPAC/nuisance/nuisance.py b/CPAC/nuisance/nuisance.py index 72400da07a..b743e33749 100755 --- a/CPAC/nuisance/nuisance.py +++ b/CPAC/nuisance/nuisance.py @@ -1,18 +1,35 @@ +# Copyright (C) 2012-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import re import os import numpy as np import nibabel as nb +# pylint: disable=wrong-import-order from CPAC.pipeline import nipype_pipeline_engine as pe import nipype.interfaces.utility as util import CPAC +from nipype import logging from nipype.interfaces import fsl from nipype.interfaces import ants from nipype.interfaces import c3 from nipype.interfaces import afni from nipype.interfaces.afni import utils as afni_utils from scipy.fftpack import fft, ifft -from CPAC import utils from CPAC.utils.interfaces.function import Function from CPAC.utils.interfaces.masktool import MaskTool from CPAC.utils.interfaces.pc import PC @@ -35,6 +52,7 @@ from CPAC.utils.datasource import check_for_s3 from CPAC.utils.utils import check_prov_for_regtool from .bandpass import (bandpass_voxels, afni_1dBandpass) +logger = logging.getLogger('nipype.workflow') def choose_nuisance_blocks(cfg, generate_only=False): @@ -56,21 +74,25 @@ def choose_nuisance_blocks(cfg, generate_only=False): nuisance = [] to_template_cfg = cfg.registration_workflows['functional_registration'][ 'func_registration_to_template'] - out = {'default': ("desc-preproc_bold", ["desc-preproc_bold", "bold"]), - 'abcd': ("desc-preproc_bold", "bold"), - 'single_step_resampling': ("desc-preproc_bold", - ["desc-preproc_bold", "bold"]), - 'single_step_resampling_from_stc': ("desc-preproc_bold", - "desc-stc_bold") - }.get(to_template_cfg['apply_transform']['using']) - if out is not None: + apply_transform_using = to_template_cfg['apply_transform']['using'] + input_interface = { + 'default': ('desc-preproc_bold', ['desc-preproc_bold', 'bold']), + 'abcd': ('desc-preproc_bold', 'bold'), + 'single_step_resampling_from_stc': ("desc-preproc_bold", + "desc-stc_bold") + }.get(apply_transform_using) + if input_interface is not None: if 'T1_template' in to_template_cfg['target_template']['using']: - nuisance.append((nuisance_regressors_generation, out)) + nuisance.append((nuisance_regressors_generation_T1w, + input_interface)) if 'EPI_template' in to_template_cfg['target_template']['using']: - nuisance.append((nuisance_regressors_generation_EPItemplate, out)) + nuisance.append((nuisance_regressors_generation_EPItemplate, + input_interface)) - if not generate_only: - nuisance.append((nuisance_regression, out)) + if not generate_only and 'native' in cfg['nuisance_corrections', + '2-nuisance_regression', + 'space']: + nuisance.append((nuisance_regression_native, input_interface)) return nuisance @@ -1766,7 +1788,7 @@ def ICA_AROMA_FSLreg(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["desc-preproc_bold", "bold"], + "inputs": ["desc-preproc_bold", "from-bold_to-T1w_mode-image_desc-linear_xfm", "from-T1w_to-template_mode-image_xfm"], "outputs": ["desc-preproc_bold", @@ -1784,7 +1806,7 @@ def ICA_AROMA_FSLreg(wf, cfg, strat_pool, pipe_num, opt=None): aroma_preproc.inputs.params.denoise_type = \ cfg.nuisance_corrections['1-ICA-AROMA']['denoising_type'] - node, out = strat_pool.get_data(["desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, aroma_preproc, 'inputspec.denoise_file') node, out = strat_pool.get_data( @@ -1815,8 +1837,8 @@ def ICA_AROMA_ANTsreg(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_bold", "bold"], - "desc-mean_bold", + "inputs": [("desc-preproc_bold", + "sbref", "from-bold_to-template_mode-image_xfm", "from-template_to-bold_mode-image_xfm"), "T1w-brain-template-funcreg"], @@ -1861,7 +1883,7 @@ def ICA_AROMA_ANTsreg(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, apply_xfm, 'inputspec.input_image') - node, out = strat_pool.get_data("desc-mean_bold") + node, out = strat_pool.get_data("sbref") wf.connect(node, out, apply_xfm, 'inputspec.reference') node, out = strat_pool.get_data('from-template_to-bold_mode-image_xfm') @@ -1888,7 +1910,8 @@ def ICA_AROMA_FSLEPIreg(wf, cfg, strat_pool, pipe_num, opt=None): "inputs": [["desc-brain_bold", "desc-motion_bold", "desc-preproc_bold", "bold"], "from-bold_to-EPItemplate_mode-image_xfm"], - "outputs": ["desc-cleaned_bold"]} + "outputs": ["desc-preproc_bold", + "desc-cleaned_bold"]} ''' xfm_prov = strat_pool.get_cpac_provenance('from-bold_to-EPItemplate_mode-image_xfm') @@ -1915,6 +1938,7 @@ def ICA_AROMA_FSLEPIreg(wf, cfg, strat_pool, pipe_num, opt=None): node, out = (aroma_preproc, 'outputspec.aggr_denoised_file') outputs = { + 'desc-preproc_bold': (node, out), 'desc-cleaned_bold': (node, out) } @@ -1931,8 +1955,8 @@ def ICA_AROMA_ANTsEPIreg(wf, cfg, strat_pool, pipe_num, opt=None): "EPI_registration", "run"]], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_bold", "bold"], - "desc-mean_bold", + "inputs": [("desc-preproc_bold", + "sbref", "from-bold_to-EPItemplate_mode-image_xfm", "from-EPItemplate_to-bold_mode-image_xfm"), "EPI-template"], @@ -1978,7 +2002,7 @@ def ICA_AROMA_ANTsEPIreg(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, apply_xfm, 'inputspec.input_image') - node, out = strat_pool.get_data("desc-mean_bold") + node, out = strat_pool.get_data("sbref") wf.connect(node, out, apply_xfm, 'inputspec.reference') node, out = strat_pool.get_data('from-EPItemplate_to-bold_mode-image_xfm') @@ -2153,7 +2177,45 @@ def erode_mask_WM(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -def nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt=None): + +def nuisance_regressors_generation_EPItemplate(wf, cfg, strat_pool, pipe_num, + opt=None): + ''' + Node Block: + {"name": "nuisance_regressors_generation_EPItemplate", + "config": ["nuisance_corrections", "2-nuisance_regression"], + "switch": ["create_regressors"], + "option_key": "Regressors", + "option_val": "USER-DEFINED", + "inputs": [("desc-preproc_bold", + "desc-brain_bold", + "space-bold_desc-brain_mask", + "movement-parameters", + "framewise-displacement-jenkinson", + "framewise-displacement-power", + "dvars", + ["space-bold_desc-eroded_mask", "space-bold_desc-brain_mask"], + ["space-bold_label-CSF_desc-eroded_mask", + "space-bold_label-CSF_desc-preproc_mask", + "space-bold_label-CSF_mask"], + ["space-bold_label-WM_desc-eroded_mask", + "space-bold_label-WM_desc-preproc_mask", + "space-bold_label-WM_mask"], + ["space-bold_label-GM_desc-eroded_mask", + "space-bold_label-GM_desc-preproc_mask", + "space-bold_label-GM_mask"], + "from-EPItemplate_to-bold_mode-image_desc-linear_xfm", + "from-bold_to-EPItemplate_mode-image_desc-linear_xfm"), + "lateral-ventricles-mask", + "TR"], + "outputs": ["regressors", "censor-indices"]} + ''' + return nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt, + 'bold') + + +def nuisance_regressors_generation_T1w(wf, cfg, strat_pool, pipe_num, opt=None + ): ''' Node Block: {"name": "nuisance_regressors_generation", @@ -2179,22 +2241,53 @@ def nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt=None): "TR"], "outputs": ["regressors", "censor-indices"]} ''' + return nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt, + 'T1w') + + +def nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt, space): + ''' + Parameters + ---------- + wf, cfg, strat_pool, pipe_num, opt + pass through from Node Block + + space : str + T1w or bold + + Returns + ------- + wf : nipype.pipeline.engine.workflows.Workflow - use_ants = None - if strat_pool.check_rpool( - 'from-template_to-T1w_mode-image_desc-linear_xfm'): + outputs : dict + ''' + + prefixes = [f'space-{space}_'] * 2 + reg_tool = None + if space == 'T1w': + prefixes[0] = '' + if strat_pool.check_rpool( + 'from-template_to-T1w_mode-image_desc-linear_xfm'): + xfm_prov = strat_pool.get_cpac_provenance( + 'from-template_to-T1w_mode-image_desc-linear_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) + elif space == 'bold': xfm_prov = strat_pool.get_cpac_provenance( - 'from-template_to-T1w_mode-image_desc-linear_xfm') + 'from-EPItemplate_to-bold_mode-image_desc-linear_xfm') reg_tool = check_prov_for_regtool(xfm_prov) + if reg_tool is not None: use_ants = reg_tool == 'ants' ventricle = strat_pool.check_rpool('lateral-ventricles-mask') - csf_mask = strat_pool.check_rpool(["label-CSF_desc-eroded_mask", - "label-CSF_desc-preproc_mask", - "label-CSF_mask"]) + csf_mask = strat_pool.check_rpool([f'{prefixes[0]}label-CSF_' + 'desc-eroded_mask', + f'{prefixes[0]}label-CSF_' + 'desc-preproc_mask', + f'{prefixes[0]}label-CSF_mask']) regressors = create_regressor_workflow(opt, use_ants, ventricle_mask_exist=ventricle, + all_bold=space=='bold', csf_mask_exist = csf_mask, name='nuisance_regressors_' f'{opt["Name"]}_{pipe_num}') @@ -2203,73 +2296,126 @@ def nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, regressors, 'inputspec.functional_file_path') node, out = strat_pool.get_data('space-bold_desc-brain_mask') - wf.connect(node, out, regressors, 'inputspec.functional_brain_mask_file_path') + wf.connect(node, out, + regressors, 'inputspec.functional_brain_mask_file_path') - if strat_pool.check_rpool('desc-brain_T1w'): - node, out = strat_pool.get_data('desc-brain_T1w') + if strat_pool.check_rpool(f'desc-brain_{space}'): + node, out = strat_pool.get_data(f'desc-brain_{space}') wf.connect(node, out, regressors, 'inputspec.anatomical_file_path') - if strat_pool.check_rpool(["space-T1w_desc-eroded_mask", - "space-T1w_desc-brain_mask"]): - node, out = strat_pool.get_data(["space-T1w_desc-eroded_mask", - "space-T1w_desc-brain_mask"]) + if strat_pool.check_rpool([f'{prefixes[1]}desc-eroded_mask', + f'{prefixes[1]}desc-brain_mask']): + node, out = strat_pool.get_data([f'{prefixes[1]}desc-eroded_mask', + f'{prefixes[1]}desc-brain_mask']) wf.connect(node, out, regressors, 'inputspec.anatomical_eroded_brain_mask_file_path') - - if strat_pool.check_rpool(["label-CSF_desc-eroded_mask", - "label-CSF_desc-preproc_mask", - "label-CSF_mask"]): - node, out = strat_pool.get_data(["label-CSF_desc-eroded_mask", - "label-CSF_desc-preproc_mask", - "label-CSF_mask"]) + else: + logger.warning('No %s-space brain mask found in resource pool.', space) + + if strat_pool.check_rpool([f'{prefixes[0]}label-CSF_desc-eroded_mask', + f'{prefixes[0]}label-CSF_desc-preproc_mask', + f'{prefixes[0]}label-CSF_mask']): + node, out = strat_pool.get_data([f'{prefixes[0]}label-CSF_' + 'desc-eroded_mask', + f'{prefixes[0]}label-CSF_' + 'desc-preproc_mask', + f'{prefixes[0]}label-CSF_mask']) wf.connect(node, out, regressors, 'inputspec.csf_mask_file_path') - - if strat_pool.check_rpool(["label-WM_desc-eroded_mask", - "label-WM_desc-preproc_mask", - "label-WM_mask"]): - node, out = strat_pool.get_data(["label-WM_desc-eroded_mask", - "label-WM_desc-preproc_mask", - "label-WM_mask"]) + else: + logger.warning('No %s-space CSF mask found in resource pool.', space) + + if strat_pool.check_rpool([f'{prefixes[0]}label-WM_desc-eroded_mask', + f'{prefixes[0]}label-WM_desc-preproc_mask', + f'{prefixes[0]}label-WM_mask']): + node, out = strat_pool.get_data([f'{prefixes[0]}label-WM_' + 'desc-eroded_mask', + f'{prefixes[0]}label-WM_' + 'desc-preproc_mask', + f'{prefixes[0]}label-WM_mask']) wf.connect(node, out, regressors, 'inputspec.wm_mask_file_path') - - if strat_pool.check_rpool(["label-GM_desc-eroded_mask", - "label-GM_desc-preproc_mask", - "label-GM_mask"]): - node, out = strat_pool.get_data(["label-GM_desc-eroded_mask", - "label-GM_desc-preproc_mask", - "label-GM_mask"]) + else: + logger.warning('No %s-space WM mask found in resource pool.', space) + + if strat_pool.check_rpool([f'{prefixes[0]}label-GM_desc-eroded_mask', + f'{prefixes[0]}label-GM_desc-preproc_mask', + f'{prefixes[0]}label-GM_mask']): + node, out = strat_pool.get_data([f'{prefixes[0]}label-GM_' + 'desc-eroded_mask', + f'{prefixes[0]}label-GM_' + 'desc-preproc_mask', + f'{prefixes[0]}label-GM_mask']) wf.connect(node, out, regressors, 'inputspec.gm_mask_file_path') + else: + logger.warning('No %s-space GM mask found in resource pool.', space) if ventricle: node, out = strat_pool.get_data('lateral-ventricles-mask') wf.connect(node, out, regressors, 'inputspec.lat_ventricles_mask_file_path') - if strat_pool.check_rpool('from-bold_to-T1w_mode-image_desc-linear_xfm'): - node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') - wf.connect(node, out, regressors, 'inputspec.func_to_anat_linear_xfm_file_path') - - # invert func2anat matrix to get anat2func_linear_xfm - anat2func_linear_xfm = pe.Node(interface=fsl.ConvertXFM(), - name=f'anat_to_func_linear_xfm_' - f'{opt["Name"]}_{pipe_num}') - anat2func_linear_xfm.inputs.invert_xfm = True - wf.connect(node, out, anat2func_linear_xfm, 'in_file') - - wf.connect(anat2func_linear_xfm, 'out_file', - regressors, 'inputspec.anat_to_func_linear_xfm_file_path') - - if strat_pool.check_rpool('from-template_to-T1w_mode-image_desc-linear_xfm'): - node, out = strat_pool.get_data('from-template_to-T1w_mode-image_desc-linear_xfm') - wf.connect(node, out, regressors, 'inputspec.mni_to_anat_linear_xfm_file_path') - - if strat_pool.check_rpool('from-T1w_to-template_mode-image_desc-linear_xfm'): - node, out = strat_pool.get_data('from-T1w_to-template_mode-image_desc-linear_xfm') - wf.connect(node, out, regressors, 'inputspec.anat_to_mni_linear_xfm_file_path') + if space == 'T1w': + if strat_pool.check_rpool( + 'from-bold_to-T1w_mode-image_desc-linear_xfm'): + node, out = strat_pool.get_data( + 'from-bold_to-T1w_mode-image_desc-linear_xfm') + wf.connect(node, out, + regressors, + 'inputspec.func_to_anat_linear_xfm_file_path') + + # invert func2anat matrix to get anat2func_linear_xfm + anat2func_linear_xfm = pe.Node(interface=fsl.ConvertXFM(), + name=f'anat_to_func_linear_xfm_' + f'{opt["Name"]}_{pipe_num}') + anat2func_linear_xfm.inputs.invert_xfm = True + wf.connect(node, out, anat2func_linear_xfm, 'in_file') + + wf.connect(anat2func_linear_xfm, 'out_file', + regressors, + 'inputspec.anat_to_func_linear_xfm_file_path') + + if strat_pool.check_rpool( + 'from-template_to-T1w_mode-image_desc-linear_xfm'): + node, out = strat_pool.get_data( + 'from-template_to-T1w_mode-image_desc-linear_xfm') + wf.connect(node, out, + regressors, + 'inputspec.mni_to_anat_linear_xfm_file_path') + + if strat_pool.check_rpool( + 'from-T1w_to-template_mode-image_desc-linear_xfm'): + node, out = strat_pool.get_data( + 'from-T1w_to-template_mode-image_desc-linear_xfm') + wf.connect(node, out, + regressors, + 'inputspec.anat_to_mni_linear_xfm_file_path') + + elif space == 'bold': + if strat_pool.check_rpool( + 'from-EPItemplate_to-bold_mode-image_desc-linear_xfm'): + node, out = strat_pool.get_data( + 'from-EPItemplate_to-bold_mode-image_desc-linear_xfm') + wf.connect(node, out, + regressors, + 'inputspec.mni_to_anat_linear_xfm_file_path') + wf.connect(node, out, + regressors, + 'inputspec.anat_to_func_linear_xfm_file_path') + + if strat_pool.check_rpool( + 'from-bold_to-EPItemplate_mode-image_desc-linear_xfm'): + node, out = strat_pool.get_data( + 'from-bold_to-EPItemplate_mode-image_desc-linear_xfm') + wf.connect(node, out, + regressors, + 'inputspec.anat_to_mni_linear_xfm_file_path') + wf.connect(node, out, + regressors, + 'inputspec.func_to_anat_linear_xfm_file_path') if strat_pool.check_rpool('movement-parameters'): node, out = strat_pool.get_data('movement-parameters') - wf.connect(node, out, regressors, 'inputspec.motion_parameters_file_path') + wf.connect(node, out, + regressors, 'inputspec.motion_parameters_file_path') if strat_pool.check_rpool('framewise-displacement-jenkinson'): node, out = strat_pool.get_data('framewise-displacement-jenkinson') @@ -2294,26 +2440,23 @@ def nuisance_regressors_generation(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) -def nuisance_regression(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - Node Block: - {"name": "nuisance_regression", - "config": ["nuisance_corrections", "2-nuisance_regression"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": [("desc-preproc_bold", - "regressors", - "space-bold_desc-brain_mask", - "framewise-displacement-jenkinson", - "framewise-displacement-power", - "dvars"), - "TR"], - "outputs": ["desc-preproc_bold", - "desc-cleaned_bold", - "regressors"]} - ''' +def nuisance_regression(wf, cfg, strat_pool, pipe_num, opt, space, res=None): + '''Nuisance regression in native (BOLD) or template space + Parameters + ---------- + wf, cfg, strat_pool, pipe_num, opt + pass through from Node Block + + space : str + native or template + + Returns + ------- + wf : nipype.pipeline.engine.workflows.Workflow + + outputs : dict + ''' regressor_prov = strat_pool.get_cpac_provenance('regressors') regressor_strat_name = regressor_prov[-1].split('_')[-1] @@ -2323,81 +2466,220 @@ def nuisance_regression(wf, cfg, strat_pool, pipe_num, opt=None): opt = regressor_dct break - nuis = create_nuisance_regression_workflow(opt, name='nuisance_regression' - f'_{opt["Name"]}_{pipe_num}') - - node, out = strat_pool.get_data("space-bold_desc-brain_mask") - wf.connect(node, out, nuis, 'inputspec.functional_brain_mask_file_path') + bandpass = 'Bandpass' in opt + bandpass_before = bandpass and cfg['nuisance_corrections', + '2-nuisance_regression', + 'bandpass_filtering_order'] == 'Before' + + name_suff = (f'space-{space}_reg-{opt["Name"]}_{pipe_num}' + if res is None else + f'space-{space}_res-{res}_reg-{opt["Name"]}_{pipe_num}') + nuis_name = f'nuisance_regression_{name_suff}' + + nuis = create_nuisance_regression_workflow(opt, name=nuis_name) + if bandpass_before: + nofilter_nuis = nuis.clone(name=f'{nuis.name}-noFilter') + + desc_keys = ('desc-preproc_bold', 'desc-cleaned_bold', + 'desc-denoisedNofilt_bold') + if space != 'native': + new_label = f'space-{space}' + if res: + new_label = f'{new_label}_res-{res}' + desc_keys = tuple(f'{new_label}_{key}' for key in desc_keys) + + if space == 'template': + # sometimes mm dimensions match but the voxel dimensions don't + # so here we align the mask to the resampled data before applying + match_grid = pe.Node(afni.Resample(), + name='align_template_mask_to_template_data_' + f'{name_suff}') + match_grid.inputs.outputtype = 'NIFTI_GZ' + match_grid.inputs.resample_mode = 'Cu' + node, out = strat_pool.get_data('FSL-AFNI-brain-mask') + wf.connect(node, out, match_grid, 'in_file') + node, out = strat_pool.get_data(desc_keys[0]) + wf.connect(node, out, match_grid, 'master') + wf.connect(match_grid, 'out_file', + nuis, 'inputspec.functional_brain_mask_file_path') + if bandpass_before: + wf.connect(match_grid, 'out_file', + nofilter_nuis, + 'inputspec.functional_brain_mask_file_path') + else: + node, out = strat_pool.get_data('space-bold_desc-brain_mask') + wf.connect(node, out, + nuis, 'inputspec.functional_brain_mask_file_path') + if bandpass_before: + wf.connect(node, out, + nofilter_nuis, + 'inputspec.functional_brain_mask_file_path') - node, out = strat_pool.get_data("regressors") + node, out = strat_pool.get_data('regressors') wf.connect(node, out, nuis, 'inputspec.regressor_file') + if bandpass_before: + wf.connect(node, out, nofilter_nuis, 'inputspec.regressor_file') if strat_pool.check_rpool('framewise-displacement-jenkinson'): - node, out = strat_pool.get_data("framewise-displacement-jenkinson") + node, out = strat_pool.get_data('framewise-displacement-jenkinson') wf.connect(node, out, nuis, 'inputspec.fd_j_file_path') + if bandpass_before: + wf.connect(node, out, nofilter_nuis, 'inputspec.fd_j_file_path') if strat_pool.check_rpool('framewise-displacement-power'): - node, out = strat_pool.get_data("framewise-displacement-power") + node, out = strat_pool.get_data('framewise-displacement-power') wf.connect(node, out, nuis, 'inputspec.fd_p_file_path') + if bandpass_before: + wf.connect(node, out, nofilter_nuis, 'inputspec.fd_p_file_path') if strat_pool.check_rpool('dvars'): - node, out = strat_pool.get_data("dvars") + node, out = strat_pool.get_data('dvars') wf.connect(node, out, nuis, 'inputspec.dvars_file_path') + if bandpass_before: + wf.connect(node, out, nofilter_nuis, 'inputspec.dvars_file_path') - if 'Bandpass' in opt: + if bandpass: filt = filtering_bold_and_regressors(opt, name=f'filtering_bold_and_' - f'regressors_{opt["Name"]}_{pipe_num}') + f'regressors_{name_suff}') filt.inputs.inputspec.nuisance_selectors = opt - node, out = strat_pool.get_data("regressors") + node, out = strat_pool.get_data('regressors') wf.connect(node, out, filt, 'inputspec.regressors_file_path') - node, out = strat_pool.get_data('space-bold_desc-brain_mask') - wf.connect(node, out, - filt, 'inputspec.functional_brain_mask_file_path') + if space == 'template': + wf.connect(match_grid, 'out_file', + filt, 'inputspec.functional_brain_mask_file_path') + else: + node, out = strat_pool.get_data('space-bold_desc-brain_mask') + wf.connect(node, out, + filt, 'inputspec.functional_brain_mask_file_path') node, out = strat_pool.get_data('TR') wf.connect(node, out, filt, 'inputspec.tr') - if cfg.nuisance_corrections['2-nuisance_regression'][ - 'bandpass_filtering_order'] == 'After': + if cfg['nuisance_corrections', '2-nuisance_regression', + 'bandpass_filtering_order'] == 'After': - node, out = strat_pool.get_data("desc-preproc_bold") + node, out = strat_pool.get_data(desc_keys[0]) wf.connect(node, out, nuis, 'inputspec.functional_file_path') wf.connect(nuis, 'outputspec.residual_file_path', filt, 'inputspec.functional_file_path') outputs = { - 'desc-preproc_bold': (filt, 'outputspec.residual_file_path'), - 'desc-cleaned_bold': (filt, 'outputspec.residual_file_path'), + desc_keys[0]: (filt, 'outputspec.residual_file_path'), + desc_keys[1]: (filt, 'outputspec.residual_file_path'), + desc_keys[2]: (nuis, 'outputspec.residual_file_path'), 'regressors': (filt, 'outputspec.residual_regressor') } - elif cfg.nuisance_corrections['2-nuisance_regression'][ - 'bandpass_filtering_order'] == 'Before': + elif bandpass_before: - node, out = strat_pool.get_data("desc-preproc_bold") + node, out = strat_pool.get_data(desc_keys[0]) wf.connect(node, out, filt, 'inputspec.functional_file_path') + wf.connect(node, out, + nofilter_nuis, 'inputspec.functional_file_path') wf.connect(filt, 'outputspec.residual_file_path', nuis, 'inputspec.functional_file_path') + outputs = { - 'desc-preproc_bold': (nuis, 'outputspec.residual_file_path'), - 'desc-cleaned_bold': (nuis, 'outputspec.residual_file_path'), - 'regressors': (filt, 'outputspec.residual_regressor') - } + desc_keys[0]: (nuis, 'outputspec.residual_file_path'), + desc_keys[1]: (nuis, 'outputspec.residual_file_path'), + desc_keys[2]: (nofilter_nuis, 'outputspec.residual_file_path'), + 'regressors': (filt, 'outputspec.residual_regressor')} else: - node, out = strat_pool.get_data("desc-preproc_bold") + node, out = strat_pool.get_data(desc_keys[0]) wf.connect(node, out, nuis, 'inputspec.functional_file_path') - outputs = { - 'desc-preproc_bold': (nuis, 'outputspec.residual_file_path'), - 'desc-cleaned_bold': (nuis, 'outputspec.residual_file_path'), - } + outputs = {desc_key: (nuis, 'outputspec.residual_file_path') for + desc_key in desc_keys} + + return (wf, outputs) + + +def nuisance_regression_native(wf, cfg, strat_pool, pipe_num, opt=None): + '''Apply nuisance regression to native-space image + + Node Block: + {"name": "nuisance_regression_native", + "config": ["nuisance_corrections", "2-nuisance_regression"], + "switch": ["run"], + "option_key": "space", + "option_val": "native", + "inputs": [("desc-preproc_bold", + "regressors", + "space-bold_desc-brain_mask", + "framewise-displacement-jenkinson", + "framewise-displacement-power", + "dvars"), + "TR"], + "outputs": {"desc-preproc_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in native space"}, + "desc-cleaned_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in native space"}, + "desc-denoisedNofilt_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in native space, but without " + "frequency filtering."}, + "regressors": { + "Description": "Regressors that were applied in native space"}}} + ''' + return nuisance_regression(wf, cfg, strat_pool, pipe_num, opt, 'native') + + +def nuisance_regression_template(wf, cfg, strat_pool, pipe_num, opt=None): + '''Apply nuisance regression to template-space image + Node Block: + {"name": "nuisance_regression_template", + "config": ["nuisance_corrections", "2-nuisance_regression"], + "switch": ["run"], + "option_key": "space", + "option_val": "template", + "inputs": [("desc-stc_bold", + "space-template_desc-preproc_bold", + "space-template_res-derivative_desc-preproc_bold", + "movement-parameters", + "regressors", + "FSL-AFNI-brain-mask", + "framewise-displacement-jenkinson", + "framewise-displacement-power", + "dvars"), + "TR"], + "outputs": {"space-template_desc-preproc_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in template space"}, + "space-template_res-derivative_desc-preproc_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in template space"}, + "space-template_desc-cleaned_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in template space"}, + "space-template_res-derivative_desc-cleaned_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in template space"}, + "space-template_desc-denoisedNofilt_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in template space, but without " + "frequency filtering."}, + "space-template_res-derivative_desc-denoisedNofilt_bold": { + "Description": "Preprocessed BOLD image that was nuisance-" + "regressed in template space, but without " + "frequency filtering."}, + "regressors": { + "Description": "Regressors that were applied in template space"}}} + ''' + wf, outputs = nuisance_regression(wf, cfg, strat_pool, pipe_num, opt, + 'template') + if strat_pool.check_rpool('space-template_res-derivative_desc-preproc_bold'): + wf, res_outputs = nuisance_regression(wf, cfg, strat_pool, pipe_num, + opt, 'template', 'derivative') + outputs.update(res_outputs) return (wf, outputs) @@ -2556,132 +2838,8 @@ def erode_mask_boldWM(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, erode, 'inputspec.brain_mask') outputs = { - 'space-bold_label-WM_desc-eroded_mask': (erode, 'outputspec.eroded_mask') - } - - return (wf, outputs) - - -def nuisance_regressors_generation_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - Node Block: - {"name": "nuisance_regressors_generation_EPItemplate", - "config": ["nuisance_corrections", "2-nuisance_regression"], - "switch": ["create_regressors"], - "option_key": "Regressors", - "option_val": "USER-DEFINED", - "inputs": [("desc-preproc_bold", - "desc-brain_bold", - "space-bold_desc-brain_mask", - "movement-parameters", - "framewise-displacement-jenkinson", - "framewise-displacement-power", - "dvars", - ["space-bold_desc-eroded_mask", "space-bold_desc-brain_mask"], - ["space-bold_label-CSF_desc-eroded_mask", "space-bold_label-CSF_desc-preproc_mask", - "space-bold_label-CSF_mask"], - ["space-bold_label-WM_desc-eroded_mask", "space-bold_label-WM_desc-preproc_mask", - "space-bold_label-WM_mask"], - ["space-bold_label-GM_desc-eroded_mask", "space-bold_label-GM_desc-preproc_mask", - "space-bold_label-GM_mask"], - "from-EPItemplate_to-bold_mode-image_desc-linear_xfm", - "from-bold_to-EPItemplate_mode-image_desc-linear_xfm"), - "lateral-ventricles-mask", - "TR"], - "outputs": ["regressors", "censor-indices"]} - ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-EPItemplate_to-bold_mode-image_desc-linear_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - use_ants = reg_tool == 'ants' - ventricle = strat_pool.check_rpool('lateral-ventricles-mask') - csf_mask = strat_pool.check_rpool(["space-bold_label-CSF_desc-eroded_mask", - "space-bold_label-CSF_desc-preproc_mask", - "space-bold_label-CSF_mask"]) - - regressors = create_regressor_workflow(opt, use_ants, - ventricle_mask_exist=ventricle, - all_bold=True, - csf_mask_exist = csf_mask, - name='nuisance_regressors_' - f'{opt["Name"]}_{pipe_num}') - - node, out = strat_pool.get_data("desc-preproc_bold") - wf.connect(node, out, regressors, 'inputspec.functional_file_path') - - node, out = strat_pool.get_data('space-bold_desc-brain_mask') - wf.connect(node, out, regressors, 'inputspec.functional_brain_mask_file_path') - - node, out = strat_pool.get_data('desc-brain_bold') - wf.connect(node, out, regressors, 'inputspec.anatomical_file_path') - - node, out = strat_pool.get_data(["space-bold_desc-eroded_mask", - "space-bold_desc-brain_mask"]) - wf.connect(node, out, regressors, 'inputspec.anatomical_eroded_brain_mask_file_path') - - if strat_pool.check_rpool(["space-bold_label-CSF_desc-eroded_mask", - "space-bold_label-CSF_desc-preproc_mask", - "space-bold_label-CSF_mask"]): - node, out = strat_pool.get_data(["space-bold_label-CSF_desc-eroded_mask", - "space-bold_label-CSF_desc-preproc_mask", - "space-bold_label-CSF_mask"]) - wf.connect(node, out, regressors, 'inputspec.csf_mask_file_path') - - if strat_pool.check_rpool(["space-bold_label-WM_desc-eroded_mask", - "space-bold_label-WM_desc-preproc_mask", - "space-bold_label-WM_mask"]): - node, out = strat_pool.get_data(["space-bold_label-WM_desc-eroded_mask", - "space-bold_label-WM_desc-preproc_mask", - "space-bold_label-WM_mask"]) - wf.connect(node, out, regressors, 'inputspec.wm_mask_file_path') - - if strat_pool.check_rpool(["space-bold_label-GM_desc-eroded_mask", - "space-bold_label-GM_desc-preproc_mask", - "space-bold_label-GM_mask"]): - node, out = strat_pool.get_data(["space-bold_label-GM_desc-eroded_mask", - "space-bold_label-GM_desc-preproc_mask", - "space-bold_label-GM_mask"]) - wf.connect(node, out, regressors, 'inputspec.gm_mask_file_path') - - if ventricle: - node, out = strat_pool.get_data('lateral-ventricles-mask') - wf.connect(node, out, - regressors, 'inputspec.lat_ventricles_mask_file_path') - - if strat_pool.check_rpool('from-EPItemplate_to-bold_mode-image_desc-linear_xfm'): - node, out = strat_pool.get_data('from-EPItemplate_to-bold_mode-image_desc-linear_xfm') - wf.connect(node, out, regressors, 'inputspec.mni_to_anat_linear_xfm_file_path') - wf.connect(node, out, regressors, 'inputspec.anat_to_func_linear_xfm_file_path') - - if strat_pool.check_rpool('from-bold_to-EPItemplate_mode-image_desc-linear_xfm'): - node, out = strat_pool.get_data('from-bold_to-EPItemplate_mode-image_desc-linear_xfm') - wf.connect(node, out, regressors, 'inputspec.anat_to_mni_linear_xfm_file_path') - wf.connect(node, out, regressors, 'inputspec.func_to_anat_linear_xfm_file_path') - - if strat_pool.check_rpool('movement-parameters'): - node, out = strat_pool.get_data('movement-parameters') - wf.connect(node, out, regressors, 'inputspec.motion_parameters_file_path') - - if strat_pool.check_rpool('framewise-displacement-jenkinson'): - node, out = strat_pool.get_data('framewise-displacement-jenkinson') - wf.connect(node, out, regressors, 'inputspec.fd_j_file_path') - - if strat_pool.check_rpool('framewise-displacement-power'): - node, out = strat_pool.get_data('framewise-displacement-power') - wf.connect(node, out, regressors, 'inputspec.fd_p_file_path') - - if strat_pool.check_rpool('dvars'): - node, out = strat_pool.get_data('dvars') - wf.connect(node, out, regressors, 'inputspec.dvars_file_path') - - node, out = strat_pool.get_data('TR') - wf.connect(node, out, regressors, 'inputspec.tr') - - outputs = { - 'regressors': (regressors, 'outputspec.regressors_file_path'), - 'censor-indices': (regressors, 'outputspec.censor_indices') + 'space-bold_label-WM_desc-eroded_mask': (erode, + 'outputspec.eroded_mask') } return (wf, outputs) diff --git a/CPAC/pipeline/__init__.py b/CPAC/pipeline/__init__.py index 7fde15df3e..34d05e7728 100755 --- a/CPAC/pipeline/__init__.py +++ b/CPAC/pipeline/__init__.py @@ -28,4 +28,5 @@ if preconfig != 'benchmark-ANTS' and not preconfig.startswith('regtest-')] + __all__ = ['ALL_PIPELINE_CONFIGS', 'AVAILABLE_PIPELINE_CONFIGS'] diff --git a/CPAC/pipeline/check_outputs.py b/CPAC/pipeline/check_outputs.py index d35f5a30cc..1ddabafe06 100755 --- a/CPAC/pipeline/check_outputs.py +++ b/CPAC/pipeline/check_outputs.py @@ -1,33 +1,34 @@ -"""Test to check if all expected outputs were generated +# Copyright (C) 2022 C-PAC Developers -Copyright (C) 2022 C-PAC Developers +# This file is part of C-PAC. -This file is part of C-PAC. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .""" -import fnmatch -import os +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +"""Test to check if all expected outputs were generated""" +from itertools import chain from logging import Logger - +import os +from pathlib import Path +import re import yaml - +from CPAC.utils.bids_utils import with_key, without_key from CPAC.utils.datasource import bidsier_prefix from CPAC.utils.monitoring.custom_logging import getLogger, MockLogger, \ set_up_logger -def check_outputs(output_dir, log_dir, pipe_name, unique_id): +def check_outputs(output_dir: str, log_dir: str, pipe_name: str, + unique_id: str) -> str: """Check if all expected outputs were generated Parameters @@ -38,38 +39,45 @@ def check_outputs(output_dir, log_dir, pipe_name, unique_id): log_dir : str Path to the log directory for the participant pipeline - pipe_name : str - - unique_id : str + pipe_name, unique_id : str Returns ------- - message :str + message : str """ + output_dir = Path(output_dir) outputs_logger = getLogger(f'{unique_id}_expectedOutputs') missing_outputs = ExpectedOutputs() - container = os.path.join(f'cpac_{pipe_name}', unique_id) - if ( - isinstance(outputs_logger, (Logger, MockLogger)) and - len(outputs_logger.handlers) - ): + subject, session = unique_id.split('_', 1) + # allow any combination of keyed/unkeyed subject and session directories + containers = [os.path.join(f'pipeline_{pipe_name}', + '/'.join((sub, ses))) for sub in [ + fxn(subject, 'sub') for fxn in (with_key, without_key) + ] for ses in [fxn(session, 'ses') for fxn in + (with_key, without_key)]] + if (isinstance(outputs_logger, (Logger, MockLogger)) and + len(outputs_logger.handlers)): outputs_log = getattr(outputs_logger.handlers[0], 'baseFilename', None) else: outputs_log = None if outputs_log is None: message = 'Could not find expected outputs log file' else: - with open(outputs_log, 'r') as expected_outputs_file: + with open(outputs_log, 'r', encoding='utf-8') as expected_outputs_file: expected_outputs = yaml.safe_load(expected_outputs_file.read()) for subdir, filenames in expected_outputs.items(): - full_dir = os.path.join(output_dir, container, subdir) - observed_outputs = os.listdir(full_dir) if os.path.exists( - full_dir) else [] + observed_outputs = list(chain.from_iterable([ + output_dir.glob(f'{container}/{subdir}') for + container in containers])) for filename in filenames: - if not fnmatch.filter(observed_outputs, - f'*{unique_id}*' - f'{filename.replace(unique_id, "")}*'): - missing_outputs += (subdir, filename) + try: + if not (observed_outputs and list( + observed_outputs[0].glob( + re.sub(r'\*\**', r'*', f'*{filename}*')))): + missing_outputs += (subdir, filename) + except Exception as exception: # pylint: disable=broad-except + logger = getLogger('nipype.workflow') + logger.error(str(exception)) if missing_outputs: missing_log = set_up_logger(f'missingOutputs_{unique_id}', filename='_'.join([ @@ -115,23 +123,25 @@ class ExpectedOutputs: >>> expected_outputs.add('func', 'desc-preproc_bold.json') >>> expected_outputs.add('func', 'desc-sm-1_reho') >>> dict(expected_outputs)['anat'] - ['T1w'] + ['T1w*'] >>> dict(expected_outputs)['func'] - ['desc-preproc*_bold.json', 'desc-sm*-1*_reho', 'task-rest*_bold.nii.gz'] + ['desc-preproc*_bold.json*', 'desc-sm*-1*_reho*', 'task-rest*_bold.nii.gz*'] >>> str(expected_outputs) - 'anat:\n- T1w\nfunc:\n- desc-preproc*_bold.json\n- desc-sm*-1*_reho\n- task-rest*_bold.nii.gz\n' + 'anat:\n- T1w*\nfunc:\n- desc-preproc*_bold.json*\n- desc-sm*-1*_reho*\n- task-rest*_bold.nii.gz*\n' >>> expected_outputs anat: - - T1w + - T1w* func: - - desc-preproc*_bold.json - - desc-sm*-1*_reho - - task-rest*_bold.nii.gz + - desc-preproc*_bold.json* + - desc-sm*-1*_reho* + - task-rest*_bold.nii.gz* >>> len(expected_outputs) 4 ''' # noqa: E501 # pylint: disable=line-too-long - def __init__(self): - self.expected_outputs = {} + def __init__(self, expected=None): + self.expected_outputs = {} if expected is None else expected + if not isinstance(self.expected_outputs, dict): + raise TypeError("ExpectedOutputs.expected_outputs must be a dict") def __bool__(self): return bool(len(self)) @@ -141,7 +151,7 @@ def __iter__(self): subdir, filename in self.expected_outputs.items()}.items() def __iadd__(self, other): - if not isinstance(other, tuple) or not len(other) == 2: + if not isinstance(other, tuple) or len(other) != 2: raise TypeError( f'{self.__module__}.{self.__class__.__name__} requires a ' "tuple of ('subdir', 'output') for addition") @@ -178,7 +188,7 @@ def add(self, subdir, output): key, value = entity.split('-', 1) entity = '-'.join([key, value.replace('-', '*-')]) new_output.append(entity) - output = '*_'.join(new_output) + output = f"{'*_'.join(new_output)}*".replace('**', '*') del new_output if subdir in self.expected_outputs: self.expected_outputs[subdir].add(output) diff --git a/CPAC/pipeline/cpac_group_runner.py b/CPAC/pipeline/cpac_group_runner.py index 3e8b4082a2..e58cb2602a 100755 --- a/CPAC/pipeline/cpac_group_runner.py +++ b/CPAC/pipeline/cpac_group_runner.py @@ -16,7 +16,6 @@ License along with C-PAC. If not, see .""" import os import fnmatch -import pandas from CPAC.pipeline.nipype_pipeline_engine.plugins import MultiProcPlugin from CPAC.utils.monitoring import log_nodes_cb @@ -34,14 +33,13 @@ def load_config_yml(config_file, individual=False): import os import yaml import yamlordereddictloader - from CPAC.utils import Configuration try: config_path = os.path.realpath(config_file) config_dict = yaml.safe_load(open(config_path, 'r')) - config = Configuration(config_dict) + config = config_dict except Exception as e: err = "\n\n[!] CPAC says: Could not load or read the configuration " \ @@ -49,10 +47,10 @@ def load_config_yml(config_file, individual=False): raise Exception(err) if individual: - config.pipeline_setup['log_directory']['path'] = os.path.abspath(config.pipeline_setup['log_directory']['path']) - config.pipeline_setup['working_directory']['path'] = os.path.abspath(config.pipeline_setup['working_directory']['path']) - config.pipeline_setup['output_directory']['path'] = os.path.abspath(config.pipeline_setup['output_directory']['path']) - config.pipeline_setup['crash_log_directory']['path'] = os.path.abspath(config.pipeline_setup['crash_log_directory']['path']) + config.logDirectory = os.path.abspath(config["pipeline_setup"]["log_directory"]["path"]) + config.workingDirectory = os.path.abspath(config["pipeline_setup"]["working_directory"]["path"]) + config.outputDirectory = os.path.abspath(config["pipeline_setup"]["output_directory"]["output_path"]) + config.crashLogDirectory = os.path.abspath(config["pipeline_setup"]["crash_log_directory"]["path"]) return config @@ -133,29 +131,26 @@ def gather_nifti_globs(pipeline_output_folder, resource_list, import glob import pandas as pd import pkg_resources as p - from __builtin__ import any as b_any - ext = ".nii" + exts = ".nii" nifti_globs = [] - keys_csv = p.resource_filename('CPAC', 'resources/cpac_outputs.csv') + keys_tsv = p.resource_filename('CPAC', 'resources/cpac_outputs.tsv') try: - keys = pd.read_csv(keys_csv) + keys = pd.read_csv(keys_tsv, delimiter='\t') except Exception as e: - err = "\n[!] Could not access or read the cpac_outputs.csv " \ - "resource file:\n{0}\n\nError details {1}\n".format(keys_csv, e) + err = "\n[!] Could not access or read the cpac_outputs.tsv " \ + "resource file:\n{0}\n\nError details {1}\n".format(keys_tsv, e) raise Exception(err) derivative_list = list( - keys[keys['Derivative'] == 'yes'][keys['Space'] == 'template'][ - keys['Values'] == 'z-score']['Resource']) + keys[keys['Sub-Directory'] == 'func']['Resource']) derivative_list = derivative_list + list( - keys[keys['Derivative'] == 'yes'][keys['Space'] == 'template'][ - keys['Values'] == 'z-stat']['Resource']) + keys[keys['Sub-Directory'] == 'anat']['Resource']) if pull_func: derivative_list = derivative_list + list( - keys[keys['Functional timeseries'] == 'yes']['Resource']) + keys[keys['Space'] == 'functional']['Resource']) if len(resource_list) == 0: err = "\n\n[!] No derivatives selected!\n\n" @@ -176,25 +171,21 @@ def gather_nifti_globs(pipeline_output_folder, resource_list, dirs_to_grab.append(derivative_name) # grab MeanFD_Jenkinson just in case - dirs_to_grab.append("power_params") + dirs_to_grab.append("framewise-displacement-jenkinson") for resource_name in dirs_to_grab: - glob_string = os.path.join(pipeline_output_folder, "*", - resource_name, "*", "*") - + glob_string = os.path.join(pipeline_output_folder, "*", "*", + f"*{resource_name}*") # get all glob strings that result in a list of paths where every path # ends with a NIFTI file - prog_string = ".." - while len(glob.glob(glob_string)) != 0: - if b_any(ext in x for x in glob.glob(glob_string)) == True: + if any(exts in x for x in glob.glob(glob_string)) == True: nifti_globs.append(glob_string) glob_string = os.path.join(glob_string, "*") prog_string = prog_string + "." - print(prog_string) if len(nifti_globs) == 0: err = "\n\n[!] No output filepaths found in the pipeline output " \ @@ -339,23 +330,22 @@ def create_output_dict_list(nifti_globs, pipeline_output_folder, if derivatives is None: - keys_csv = p.resource_filename('CPAC', 'resources/cpac_outputs.csv') + keys_tsv = p.resource_filename('CPAC', 'resources/cpac_outputs.tsv') try: - keys = pd.read_csv(keys_csv) + keys = pd.read_csv(keys_tsv,delimiter='\t') except Exception as e: err = "\n[!] Could not access or read the cpac_outputs.csv " \ - "resource file:\n{0}\n\nError details {1}\n".format(keys_csv, e) + "resource file:\n{0}\n\nError details {1}\n".format(keys_tsv, e) raise Exception(err) derivatives = list( - keys[keys['Derivative'] == 'yes'][keys['Space'] == 'template'][ - keys['Values'] == 'z-score']['Resource']) + keys[keys['Sub-Directory'] == 'func']['Resource']) derivatives = derivatives + list( - keys[keys['Derivative'] == 'yes'][keys['Space'] == 'template'][ - keys['Values'] == 'z-stat']['Resource']) + keys[keys['Sub-Directory'] == 'anat']['Resource']) if pull_func: - derivatives = derivatives + list(keys[keys['Functional timeseries'] == 'yes']['Resource']) + derivatives = derivatives + list( + keys[keys['Space'] == 'functional']['Resource']) # remove any extra /'s pipeline_output_folder = pipeline_output_folder.rstrip("/") @@ -381,7 +371,7 @@ def create_output_dict_list(nifti_globs, pipeline_output_folder, ''' # grab MeanFD_Jenkinson just in case - search_dirs += ["power_params"] + search_dirs += ["framewise-displacement-jenkinson"] exts = ['.' + ext.lstrip('.') for ext in exts] @@ -392,23 +382,21 @@ def create_output_dict_list(nifti_globs, pipeline_output_folder, for filename in files: filepath = os.path.join(root, filename) - if not any(fnmatch.fnmatch(filepath, pattern) for pattern in nifti_globs): continue if not any(filepath.endswith(ext) for ext in exts): continue - relative_filepath = filepath.split(pipeline_output_folder)[1] filepath_pieces = [_f for _f in relative_filepath.split("/") if _f] - resource_id = filepath_pieces[1] + resource_id = '_'.join(filepath_pieces[2].split(".")[0].split("_")[3:]) if resource_id not in search_dirs: continue - series_id_string = filepath_pieces[2] - strat_info = "_".join(filepath_pieces[3:])[:-len(ext)] + series_id_string = filepath_pieces[2].split("_")[1] + strat_info = "_".join(filepath_pieces[2].split("_")[2:3]) unique_resource_id = (resource_id, strat_info) @@ -429,7 +417,7 @@ def create_output_dict_list(nifti_globs, pipeline_output_folder, new_row_dict["Filepath"] = filepath print('{0} - {1} - {2}'.format( - unique_id, + unique_id.split("_")[0], series_id, resource_id )) @@ -525,14 +513,12 @@ def pheno_sessions_to_repeated_measures(pheno_df, sessions_list): More info: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FEAT/ UserGuide#Paired_Two-Group_Difference_.28Two-Sample_Paired_T-Test.29 - Sample input: pheno_df sub01 sub02 sessions_list [ses01, ses02] - Expected output: pheno_df Sessions participant_sub01 participant_sub02 sub01 ses01 1 0 @@ -718,12 +704,12 @@ def prep_feat_inputs(group_config_file): import pandas as pd import pkg_resources as p - keys_csv = p.resource_filename('CPAC', 'resources/cpac_outputs.csv') + keys_tsv = p.resource_filename('CPAC', 'resources/cpac_outputs.tsv') try: - keys = pd.read_csv(keys_csv) + keys = pd.read_csv(keys_tsv, delimiter='\t') except Exception as e: - err = "\n[!] Could not access or read the cpac_outputs.csv " \ - "resource file:\n{0}\n\nError details {1}\n".format(keys_csv, e) + err = "\n[!] Could not access or read the cpac_outputs.tsv " \ + "resource file:\n{0}\n\nError details {1}\n".format(keys_tsv, e) raise Exception(err) derivatives = list(keys[keys['Derivative'] == 'yes'][keys['Space'] == 'template'][keys['Values'] == 'z-score']['Resource']) @@ -1113,9 +1099,9 @@ def run_feat(group_config_file, feat=True): # get group pipeline config loaded c = load_config_yml(group_config_file) - pipeline_dir = c.pipeline_dir - model_name = c.model_name - out_dir = c.output_dir + pipeline_dir = c["pipeline_setup"]["output_directory"]["source_outputs_path"] + model_name = c["fsl_feat"]["model_name"] + out_dir = c["pipeline_setup"]["output_directory"]["output_path"] pipeline_name = pipeline_dir.rstrip('/').split('/')[-1] @@ -1178,7 +1164,7 @@ def run_feat(group_config_file, feat=True): models[id_tuple]['dir_path'].replace(out_dir, '').lstrip('/')) work_dir = work_dir.replace('cpac_group_analysis', 'cpac_group_analysis_workdir') work_dir = work_dir.replace('model_files/', '') - log_dir = os.path.join(c.log_dir, + log_dir = os.path.join(c["pipeline_setup"]["log_directory"]["path"], models[id_tuple]['dir_path'].replace(out_dir, '').lstrip('/')) log_dir = log_dir.replace('cpac_group_analysis', 'cpac_group_analysis_logdir') log_dir = log_dir.replace('model_files/', '') @@ -1204,9 +1190,9 @@ def run_feat(group_config_file, feat=True): design_matrix.columns, None, None, custom_contrasts_csv, - None, c.group_sep, + None, c["fsl_feat"]["group_sep"], grp_vector, - c.coding_scheme, + c["fsl_feat"]["coding_scheme"], model_name, id_tuple[0], input_files_dir) @@ -1245,17 +1231,18 @@ def run_feat(group_config_file, feat=True): f_test, mat, con, grp, model_out_dir, work_dir, log_dir, model_name, fts))) - manage_processes(procss, out_dir, c.num_models_at_once) + manage_processes(procss, out_dir, c["fsl_feat"]["num_models_at_once"]) def run_cwas_group(pipeline_dir, out_dir, working_dir, crash_dir, roi_file, regressor_file, participant_column, columns, - permutations, parallel_nodes, inclusion=None): + permutations, parallel_nodes, plugin_args, z_score, inclusion=None): import os import numpy as np from multiprocessing import pool from CPAC.cwas.pipeline import create_cwas + from nipype import config pipeline_dir = os.path.abspath(pipeline_dir) @@ -1269,12 +1256,13 @@ def run_cwas_group(pipeline_dir, out_dir, working_dir, crash_dir, roi_file, os.path.basename(pipeline_dir)) inclusion_list = None + if inclusion: inclusion_list = load_text_file(inclusion, "MDMR participant " "inclusion list") output_df_dct = gather_outputs(pipeline_dir, - ["functional_to_standard"], + ['space-template_desc-preproc_bold'], inclusion_list, False, False, get_func=True) @@ -1293,7 +1281,6 @@ def run_cwas_group(pipeline_dir, out_dir, working_dir, crash_dir, roi_file, df_dct[strat_scan] = strat_df[strat_df["Series"] == strat_scan] else: df_dct[list(set(strat_df["Series"]))[0]] = strat_df - for df_scan in df_dct.keys(): func_paths = { p.split("_")[0]: f @@ -1303,7 +1290,12 @@ def run_cwas_group(pipeline_dir, out_dir, working_dir, crash_dir, roi_file, df_dct[df_scan].Filepath ) } - + + if plugin_args['n_procs'] == 1: + plugin = 'Linear' + else: + plugin = 'MultiProc' + cwas_wf = create_cwas(name="MDMR_{0}".format(df_scan), working_dir=working_dir, crash_dir=crash_dir) @@ -1314,7 +1306,8 @@ def run_cwas_group(pipeline_dir, out_dir, working_dir, crash_dir, roi_file, cwas_wf.inputs.inputspec.columns = columns cwas_wf.inputs.inputspec.permutations = permutations cwas_wf.inputs.inputspec.parallel_nodes = parallel_nodes - cwas_wf.run() + cwas_wf.inputs.inputspec.z_score = z_score + cwas_wf.run(plugin=plugin, plugin_args=plugin_args) def run_cwas(pipeline_config): @@ -1325,37 +1318,44 @@ def run_cwas(pipeline_config): pipeline_config = os.path.abspath(pipeline_config) pipeconfig_dct = yaml.safe_load(open(pipeline_config, 'r')) - - pipeline = pipeconfig_dct["pipeline_dir"] - output_dir = pipeconfig_dct["output_dir"] - working_dir = pipeconfig_dct["work_dir"] - crash_dir = pipeconfig_dct["log_dir"] - - roi_file = pipeconfig_dct["mdmr_roi_file"] - regressor_file = pipeconfig_dct["mdmr_regressor_file"] - participant_column = pipeconfig_dct["mdmr_regressor_participant_column"] - columns = pipeconfig_dct["mdmr_regressor_columns"] - permutations = pipeconfig_dct["mdmr_permutations"] - parallel_nodes = pipeconfig_dct["mdmr_parallel_nodes"] - inclusion = pipeconfig_dct["participant_list"] + + num_cpus = pipeconfig_dct["pipeline_setup"]["system_config"]["num_cpus"] + mem_gb = pipeconfig_dct["pipeline_setup"]["system_config"]["num_memory"] + + plugin_args = {'n_procs' : num_cpus, 'memory_gb' : mem_gb} + + pipeline = pipeconfig_dct["pipeline_setup"]["output_directory"]["source_outputs_path"] + output_dir = pipeconfig_dct["pipeline_setup"]["output_directory"]["output_path"] + working_dir = pipeconfig_dct["pipeline_setup"]["working_directory"]["path"] + crash_dir = pipeconfig_dct["pipeline_setup"]["log_directory"]["path"] + + roi_file = pipeconfig_dct["mdmr"]["roi_file"] + regressor_file = pipeconfig_dct["mdmr"]["regressor_file"] + participant_column = pipeconfig_dct["mdmr"]["regressor_participant_column"] + columns = pipeconfig_dct["mdmr"]["regressor_columns"] + permutations = pipeconfig_dct["mdmr"]["permutations"] + parallel_nodes = pipeconfig_dct["mdmr"]["parallel_nodes"] + inclusion = pipeconfig_dct["mdmr"]["inclusion_list"] + z_score = pipeconfig_dct["mdmr"]["zscore"] if not inclusion or "None" in inclusion or "none" in inclusion: inclusion = None run_cwas_group(pipeline, output_dir, working_dir, crash_dir, roi_file, regressor_file, participant_column, columns, - permutations, parallel_nodes, + permutations, parallel_nodes, plugin_args, z_score, inclusion=inclusion) def find_other_res_template(template_path, new_resolution): - """Find the same template/standard file in another resolution, if it + """ + Find the same template/standard file in another resolution, if it exists. - template_path: file path to the template NIfTI file + new_resolution: (int) the resolution of the template file you need - NOTE: Makes an assumption regarding the filename format of the files. + """ # TODO: this is assuming there is a mm resolution in the file path - not @@ -1373,8 +1373,8 @@ def find_other_res_template(template_path, new_resolution): template_parts[0] = str(new_resolution).join(template_parts[0].rsplit(template_parts[0][-1], 1)) ref_file = "{0}{1}".format(template_parts[0], template_parts[1]) - elif "${func_resolution}" in template_path: - ref_file = template_path.replace("${func_resolution}", + elif "${resolution_for_func_preproc}" in template_path: + ref_file = template_path.replace("${resolution_for_func_preproc}", "{0}mm".format(new_resolution)) if ref_file: @@ -1474,11 +1474,11 @@ def launch_PyBASC(pybasc_config): def run_basc(pipeline_config): - """Run the PyBASC module. - + """ + Run the PyBASC module. + PyBASC is a separate Python package built and maintained by Aki Nikolaidis which implements the BASC analysis via Python. - PyBASC is based off of the following work: - Garcia-Garcia, M., Nikolaidis, A., Bellec, P., Craddock, R. C., Cheung, B., Castellanos, F. X., & Milham, M. P. (2017). Detecting stable individual differences in the functional organization of the human basal ganglia. NeuroImage. @@ -1486,16 +1486,12 @@ def run_basc(pipeline_config): Multi-level bootstrap analysis of stable clusters in resting-state fMRI. Neuroimage, 51(3), 1126-1139. - Bellec, P., Marrelec, G., & Benali, H. (2008). A bootstrap test to investigate changes in brain connectivity for functional MRI. Statistica Sinica, 1253-1268. - PyBASC GitHub repository: https://github.com/AkiNikolaidis/PyBASC - PyBASC author: https://www.researchgate.net/profile/Aki_Nikolaidis - Inputs pipeline_config: path to C-PAC pipeline configuration YAML file - Steps (of the C-PAC interface for PyBASC, not PyBASC itself) 1. Read in the PyBASC-relevant pipeline config items and create a new PyBASC config dictionary. @@ -1508,7 +1504,7 @@ def run_basc(pipeline_config): selected to run PyBASC for (preprocessed and template-space functional time series are pulled from each pipeline output directory, for input into PyBASC). - 6. Gather functional_to_standard outputs from each pipeline. + 6. Gather space-template_bold outputs from each pipeline. 7. Create further sub-directories for each nuisance regression strategy and functional scan within each C-PAC pipeline, and separate the functional outputs by strategy and scan as well. @@ -1518,7 +1514,6 @@ def run_basc(pipeline_config): into a config YAML file for each pipeline-strategy-scan we are running. 10. Launch PyBASC for each configuration generated. - """ import os @@ -1530,27 +1525,28 @@ def run_basc(pipeline_config): pipeconfig_dct = yaml.safe_load(open(pipeline_config, 'r')) - output_dir = os.path.abspath(pipeconfig_dct["output_dir"]) - working_dir = os.path.abspath(pipeconfig_dct['work_dir']) - if pipeconfig_dct['pipeline_setup']['Amazon-AWS']['aws_output_bucket_credentials']: - creds_path = os.path.abspath(pipeconfig_dct['pipeline_setup']['Amazon-AWS']['aws_output_bucket_credentials']) + output_dir = os.path.abspath(pipeconfig_dct["pipeline_setup"]["output_directory"]["output_path"]) + working_dir = os.path.abspath(pipeconfig_dct["pipeline_setup"]["working_directory"]["path"]) + if pipeconfig_dct["pipeline_setup"]["Amazon-AWS"]['aws_output_bucket_credentials']: + creds_path = os.path.abspath( + pipeconfig_dct["pipeline_setup"]["Amazon-AWS"]['aws_output_bucket_credentials']) - func_template = pipeconfig_dct["template_brain_only_for_func"] + func_template = pipeconfig_dct["basc"]["template_brain_only_for_func"] if '$FSLDIR' in func_template: if os.environ.get('FSLDIR'): func_template = func_template.replace('$FSLDIR', os.environ['FSLDIR']) - basc_inclusion = pipeconfig_dct["participant_list"] - basc_scan_inclusion = pipeconfig_dct["basc_scan_inclusion"] - basc_resolution = pipeconfig_dct["basc_resolution"] + basc_inclusion = pipeconfig_dct["pipeline_setup"]["output_directory"]["participant_list"] + basc_scan_inclusion = pipeconfig_dct["basc"]["scan_inclusion"] + basc_resolution = pipeconfig_dct["basc"]["resolution"] basc_config_dct = {'run': True, 'reruns': 1} for key in pipeconfig_dct.keys(): if 'basc' in key: - basc_config_dct[key.replace('basc_', '')] = pipeconfig_dct[key] + basc_config_dct = pipeconfig_dct[key] iterables = ['dataset_bootstrap_list', 'timeseries_bootstrap_list', 'blocklength_list', 'n_clusters_list', 'output_sizes'] @@ -1610,7 +1606,8 @@ def run_basc(pipeline_config): roi_file_two = resample_cpac_output_image(roi_two_cmd_args) basc_config_dct['cross_cluster_mask_file'] = roi_file_two - pipeline_dir = os.path.abspath(pipeconfig_dct["pipeline_dir"]) + pipeline_dir = os.path.abspath(pipeconfig_dct["pipeline_setup"] + ["output_directory"]["source_outputs_path"]) out_dir = os.path.join(output_dir, 'cpac_group_analysis', 'PyBASC', '{0}mm_resolution'.format(basc_resolution), @@ -1638,8 +1635,7 @@ def run_basc(pipeline_config): # - each dataframe will contain output filepaths and their associated # information, and each dataframe will include ALL SERIES/SCANS output_df_dct = gather_outputs(pipeline_dir, - ["functional_to_standard", - "functional_mni"], + ["space-template_bold"], inclusion_list, False, False, get_func=True) @@ -1671,8 +1667,8 @@ def run_basc(pipeline_config): if df_scan not in scan_inclusion: continue - basc_config_dct['analysis_ID'] = '{0}_{1}'.format(os.path.basename(pipeline_dir), - df_scan) + basc_config_dct['analysis_ID'] = '{0}_{1}'.format( + os.path.basename(pipeline_dir), df_scan) # add scan label and nuisance regression strategy label to the # output directory path @@ -1688,7 +1684,7 @@ def run_basc(pipeline_config): # affinity threshold is an iterable, and must match the number of # functional file paths for the MapNodes - affinity_thresh = pipeconfig_dct['basc_affinity_thresh'] * len(func_paths) + affinity_thresh = pipeconfig_dct["basc"]["affinity_thresh"] * len(func_paths) # resampling if necessary # each run should take the file, resample it and write it @@ -1746,11 +1742,12 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, output_df_dct = gather_outputs( pipeline_dir, - ["functional_to_standard", "roi_timeseries"], + ["space-template_bold", "space-template_desc-Mean_timeseries"], inclusion_list=None, get_motion=False, get_raw_score=False, get_func=True, - derivatives=["functional_to_standard", "roi_timeseries"], - exts=['nii', 'nii.gz', 'csv'] + derivatives=["space-template_bold", + "space-template_desc-Mean_timeseries"], + # exts=['nii', 'nii.gz', 'csv'] ) iteration_ids = [] @@ -1759,13 +1756,14 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, derivative, _ = preproc_strat - if "voxel" not in levels and derivative == "functional_to_standard": + if "voxel" not in levels and derivative == "space-template_bold": continue - if "roi" not in levels and derivative == "roi_timeseries": + if ("roi" not in levels and + derivative == "space-template_desc-Mean_timeseries"): continue - if derivative == "roi_timeseries": + if derivative == "space-template_desc-Mean_timeseries": if roi_inclusion: # backwards because ROI labels embedded as substrings for roi_label in roi_inclusion: @@ -1776,7 +1774,6 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, "{1}/{2}\n".format(roi_label, derivative, _)) continue - df_dct = {} strat_df = output_df_dct[preproc_strat] @@ -1803,10 +1800,12 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, ) } - unique_out_dir = os.path.join(out_dir, "ISC", derivative, _, df_scan) + unique_out_dir = os.path.join(out_dir, "ISC", derivative, _, + df_scan) it_id = "ISC_{0}_{1}_{2}".format(df_scan, derivative, - _.replace('.', '').replace('+', '')) + _.replace('.', '').replace( + '+', '')) isc_wf = create_isc(name=it_id, output_dir=unique_out_dir, @@ -1816,10 +1815,8 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, isc_wf.inputs.inputspec.permutations = permutations isc_wf.inputs.inputspec.std = std_filter isc_wf.inputs.inputspec.collapse_subj = False - plugin_args = {'n_procs': num_cpus, - 'status_callback': log_nodes_cb} - isc_wf.run(plugin=MultiProcPlugin(plugin_args), - plugin_args=plugin_args) + isc_wf.run(plugin='MultiProc', + plugin_args={'n_procs': num_cpus}) if isfc: for df_scan in df_dct.keys(): @@ -1835,10 +1832,12 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, ) } - unique_out_dir = os.path.join(out_dir, "ISFC", derivative, _, df_scan) + unique_out_dir = os.path.join(out_dir, "ISFC", derivative, _, + df_scan) it_id = "ISFC_{0}_{1}_{2}".format(df_scan, derivative, - _.replace('.', '').replace('+', '')) + _.replace('.', '').replace( + '+', '')) isfc_wf = create_isfc(name=it_id, output_dir=unique_out_dir, @@ -1848,10 +1847,8 @@ def run_isc_group(pipeline_dir, out_dir, working_dir, crash_dir, isfc_wf.inputs.inputspec.permutations = permutations isfc_wf.inputs.inputspec.std = std_filter isfc_wf.inputs.inputspec.collapse_subj = False - plugin_args = {'n_procs': num_cpus, - 'status_callback': log_nodes_cb} - isfc_wf.run(plugin=MultiProcPlugin(plugin_args), - plugin_args=plugin_args) + isfc_wf.run(plugin='MultiProc', + plugin_args={'n_procs': num_cpus}) def run_isc(pipeline_config): @@ -1863,23 +1860,23 @@ def run_isc(pipeline_config): pipeconfig_dct = yaml.safe_load(open(pipeline_config, 'r')) - pipeline_dir = pipeconfig_dct["pipeline_dir"] + pipeline_dir = pipeconfig_dct["pipeline_setup"]["output_directory"]["source_outputs_path"] - output_dir = pipeconfig_dct["output_dir"] - working_dir = pipeconfig_dct["work_dir"] - crash_dir = pipeconfig_dct["log_dir"] + output_dir = pipeconfig_dct["pipeline_setup"]["output_directory"]["output_path"] + working_dir = pipeconfig_dct["pipeline_setup"]["working_directory"]["path"] + crash_dir = pipeconfig_dct["pipeline_setup"]["log_directory"]["path"] scan_inclusion = None if "scan_inclusion" in pipeconfig_dct.keys(): - scan_inclusion = pipeconfig_dct["scan_inclusion"] + scan_inclusion = pipeconfig_dct["pipeline_setup"]["system_config"]["scan_inclusion"] roi_inclusion = None if "isc_roi_inclusion" in pipeconfig_dct.keys(): - roi_inclusion = pipeconfig_dct["isc_roi_inclusion"] + roi_inclusion = pipeconfig_dct["isc_isfc"]["roi_inclusion"] num_cpus = 1 if "num_cpus" in pipeconfig_dct.keys(): - num_cpus = pipeconfig_dct["num_cpus"] + num_cpus = pipeconfig_dct["pipeline_setup"]["system_config"]["num_cpus"] isc = 1 in pipeconfig_dct.get("runISC", []) isfc = 1 in pipeconfig_dct.get("runISFC", []) @@ -1933,12 +1930,12 @@ def run_qpp(group_config_file): c = load_config_yml(group_config_file) - pipeline_dir = os.path.abspath(c.pipeline_dir) - out_dir = os.path.join(c.output_dir, 'cpac_group_analysis', 'QPP', + pipeline_dir = os.path.abspath(c["pipeline_setup"]["output_directory"]["source_outputs_path"]) + out_dir = os.path.join(c["pipeline_setup"]["output_directory"]["output_path"], 'cpac_group_analysis', 'QPP', os.path.basename(pipeline_dir)) - working_dir = os.path.join(c.work_dir, 'cpac_group_analysis', 'QPP', + working_dir = os.path.join(c["pipeline_setup"]["working_directory"]["path"], 'cpac_group_analysis', 'QPP', os.path.basename(pipeline_dir)) - crash_dir = os.path.join(c.log_dir, 'cpac_group_analysis', 'QPP', + crash_dir = os.path.join(c["pipeline_setup"]["crash_log_directory"]["path"], 'cpac_group_analysis', 'QPP', os.path.basename(pipeline_dir)) try: @@ -1950,28 +1947,29 @@ def run_qpp(group_config_file): outputs = gather_outputs( pipeline_dir, - ["functional_to_standard"], - inclusion_list=c.participant_list, + ["space-template_bold"], + inclusion_list=c["pipeline_setup"]["output_directory"] + ["participant_list"], get_motion=False, get_raw_score=False, get_func=True, - derivatives=["functional_to_standard"], - exts=['nii', 'nii.gz'] + derivatives=["space-template_bold"], + #exts=['nii', 'nii.gz'] ) - if c.qpp_stratification == 'Scan': + if c["qpp"]["stratification"] == 'Scan': qpp_stratification = ['Series'] - elif c.qpp_stratification == 'Session': + elif c["qpp"]["stratification"] == 'Session': qpp_stratification = ['Sessions'] - elif c.qpp_stratification in ['Session and Scan', 'Scan and Session']: + elif c["qpp"]["stratification"] in ['Session and Scan', 'Scan and Session']: qpp_stratification = ['Sessions', 'Series'] else: qpp_stratification = [] for (resource_id, strat_info), output_df in outputs.items(): - if c.qpp_session_inclusion: - output_df = output_df[output_df["Sessions"].isin(c.qpp_session_inclusion)] - if c.qpp_scan_inclusion: - output_df = output_df[output_df["Series"].isin(c.qpp_scan_inclusion)] + if c["qpp"]["session_inclusion"]: + output_df = output_df[output_df["Sessions"].isin(c["qpp"]["session_inclusion"])] + if c["qpp"]["scan_inclusion"]: + output_df = output_df[output_df["Series"].isin(c["qpp"]["scan_inclusion"])] if qpp_stratification: output_df_groups = output_df.groupby(by=qpp_stratification) @@ -2000,12 +1998,12 @@ def run_qpp(group_config_file): wf = create_qpp(name="QPP", working_dir=group_working_dir, crash_dir=group_crash_dir) - wf.inputs.inputspec.window_length = c.qpp_window - wf.inputs.inputspec.permutations = c.qpp_permutations - wf.inputs.inputspec.lower_correlation_threshold = c.qpp_initial_threshold - wf.inputs.inputspec.higher_correlation_threshold = c.qpp_final_threshold - wf.inputs.inputspec.iterations = c.qpp_iterations - wf.inputs.inputspec.correlation_threshold_iteration = c.qpp_initial_threshold_iterations + wf.inputs.inputspec.window_length = c["qpp"]["window"] + wf.inputs.inputspec.permutations = c["qpp"]["permutations"] + wf.inputs.inputspec.lower_correlation_threshold = c["qpp"]["initial_threshold"] + wf.inputs.inputspec.higher_correlation_threshold = c["qpp"]["final_threshold"] + wf.inputs.inputspec.iterations = c["qpp"]["iterations"] + wf.inputs.inputspec.correlation_threshold_iteration = c["qpp"]["initial_threshold_iterations"] wf.inputs.inputspec.convergence_iterations = 1 wf.inputs.inputspec.datasets = output_df_group.Filepath.tolist() @@ -2069,25 +2067,25 @@ def run(config_file): c = load_config_yml(config_file) # Run MDMR, if selected - if 1 in c.runMDMR: + if 1 in c["mdmr"]["run"]: run_cwas(config_file) # Run ISC, if selected - if 1 in c.runISC or 1 in c.runISFC: + if 1 in c["isc_isfc"]["runISC"] or 1 in c["isc_isfc"]["runISFC"]: run_isc(config_file) # Run PyBASC, if selected - if 1 in c.run_basc: + if 1 in c["basc"]["run"]: run_basc(config_file) # Run FSL FEAT group analysis, if selected - if 1 in c.run_fsl_feat: + if 1 in c["fsl_feat"]["run"]: run_feat(config_file) # Run randomise, if selected - if 1 in c.run_randomise: + if 1 in c["fsl_randomise"]["run"]: run_feat(config_file, feat=False) #Run QPP, if selected - if 1 in c.run_qpp: - run_qpp(config_file) + if 1 in c["qpp"]["run"]: + run_qpp(config_file) \ No newline at end of file diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py index 8ecf5e4bbc..84ba5d6031 100755 --- a/CPAC/pipeline/cpac_pipeline.py +++ b/CPAC/pipeline/cpac_pipeline.py @@ -1,19 +1,19 @@ -"""Copyright (C) 2022 C-PAC Developers +# Copyright (C) 2012-2023 C-PAC Developers -This file is part of C-PAC. +# This file is part of C-PAC. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .""" +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import os import sys import time @@ -28,12 +28,11 @@ import nipype import yaml - +# pylint: disable=wrong-import-order from CPAC.pipeline import nipype_pipeline_engine as pe from CPAC.pipeline.nipype_pipeline_engine.plugins import \ LegacyMultiProcPlugin, MultiProcPlugin -from nipype import config -from nipype import logging +from nipype import config, logging from indi_aws import aws_utils, fetch_creds @@ -42,7 +41,7 @@ from CPAC.pipeline.check_outputs import check_outputs from CPAC.pipeline.engine import NodeBlock, initiate_rpool from CPAC.anat_preproc.anat_preproc import ( - freesurfer_preproc, + freesurfer_reconall, freesurfer_abcd_preproc, anatomical_init, acpc_align_head, @@ -82,7 +81,7 @@ brain_mask_T2, brain_mask_acpc_T2, brain_extraction_temp_T2, - brain_extraction_T2 + brain_extraction_T2, ) from CPAC.registration.registration import ( @@ -99,10 +98,16 @@ coregistration, create_func_to_T1template_xfm, create_func_to_T1template_symmetric_xfm, + warp_wholeheadT1_to_template, + warp_T1mask_to_template, + apply_phasediff_to_timeseries_separately, + apply_blip_to_timeseries_separately, warp_timeseries_to_T1template, - warp_bold_mean_to_T1template, + warp_timeseries_to_T1template_deriv, + warp_sbref_to_T1template, warp_bold_mask_to_T1template, warp_deriv_mask_to_T1template, + warp_denoiseNofilt_to_T1template, warp_timeseries_to_EPItemplate, warp_bold_mean_to_EPItemplate, warp_bold_mask_to_EPItemplate, @@ -110,8 +115,8 @@ warp_timeseries_to_T1template_abcd, single_step_resample_timeseries_to_T1template, warp_timeseries_to_T1template_dcan_nhp, - warp_Tissuemask_to_T1template, - warp_Tissuemask_to_EPItemplate + warp_tissuemask_to_T1template, + warp_tissuemask_to_EPItemplate ) from CPAC.seg_preproc.seg_preproc import ( @@ -126,6 +131,7 @@ func_scaling, func_truncate, func_despike, + func_despike_template, func_slice_time, func_reorient, bold_mask_afni, @@ -166,7 +172,8 @@ erode_mask_bold, erode_mask_boldCSF, erode_mask_boldGM, - erode_mask_boldWM + erode_mask_boldWM, + nuisance_regression_template ) from CPAC.surface.surf_preproc import surface_postproc @@ -187,8 +194,9 @@ multiple_regression ) -from CPAC.alff.alff import alff_falff -from CPAC.reho.reho import reho +from CPAC.alff.alff import alff_falff, alff_falff_space_template +from CPAC.reho.reho import reho, reho_space_template +from CPAC.utils.serialization import save_workflow_json, WorkflowJSONMeta from CPAC.vmhc.vmhc import ( smooth_func_vmhc, @@ -201,16 +209,16 @@ ) from CPAC.pipeline.random_state import set_up_random_state_logger -from CPAC.utils.datasource import bidsier_prefix, gather_extraction_maps from CPAC.pipeline.schema import valid_options from CPAC.utils.trimmer import the_trimmer -from CPAC.utils import Configuration +from CPAC.utils import Configuration, set_subject from CPAC.qc.pipeline import create_qc_workflow from CPAC.qc.xcp import qc_xcp from CPAC.utils.monitoring import log_nodes_cb, log_nodes_initial, \ - set_up_logger + LOGTAIL, set_up_logger, \ + WARNING_FREESURFER_OFF_WITH_DATA from CPAC.utils.monitoring.draw_gantt_chart import resource_report from CPAC.utils.utils import ( check_config_resources, @@ -252,6 +260,8 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, the prepared nipype workflow object containing the parameters specified in the config ''' + from CPAC.utils.datasource import bidsier_prefix + if plugin is not None and not isinstance(plugin, str): raise TypeError( 'CPAC.pipeline.cpac_pipeline.run_workflow requires a ' @@ -262,18 +272,9 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, # Assure that changes on config will not affect other parts c = copy.copy(c) - subject_id = sub_dict['subject_id'] - if sub_dict['unique_id']: - subject_id += "_" + sub_dict['unique_id'] - + subject_id, p_name, log_dir = set_subject(sub_dict, c) c['subject_id'] = subject_id - log_dir = os.path.join(c.pipeline_setup['log_directory']['path'], - f'pipeline_{c.pipeline_setup["pipeline_name"]}', - subject_id) - if not os.path.exists(log_dir): - os.makedirs(os.path.join(log_dir)) - set_up_logger(f'{subject_id}_expectedOutputs', filename=f'{bidsier_prefix(c["subject_id"])}_' 'expectedOutputs.yml', @@ -290,10 +291,9 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, }, 'execution': { 'crashfile_format': 'txt', - 'resource_monitor_frequency': 0.2 - } - }) - + 'resource_monitor_frequency': 0.2, + 'stop_on_first_crash': c['pipeline_setup', 'system_config', + 'fail_fast']}}) config.enable_resource_monitor() logging.update_logging(config) @@ -434,8 +434,9 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, check_centrality_lfcd=check_centrality_lfcd) # absolute paths of the dirs - c.pipeline_setup['working_directory']['path'] = os.path.abspath( - c.pipeline_setup['working_directory']['path']) + c.pipeline_setup['working_directory']['path'] = os.path.join( + os.path.abspath(c.pipeline_setup['working_directory']['path']), + p_name) if 's3://' not in c.pipeline_setup['output_directory']['path']: c.pipeline_setup['output_directory']['path'] = os.path.abspath( c.pipeline_setup['output_directory']['path']) @@ -443,9 +444,39 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, if c.pipeline_setup['system_config']['random_seed'] is not None: set_up_random_state_logger(log_dir) - workflow = build_workflow( - subject_id, sub_dict, c, p_name, num_ants_cores - ) + try: + workflow = build_workflow( + subject_id, sub_dict, c, p_name, num_ants_cores + ) + except Exception as exception: + logger.exception('Building workflow failed') + raise exception + + wf_graph = c['pipeline_setup', 'log_directory', 'graphviz', + 'entire_workflow'] + if wf_graph.get('generate'): + for graph2use in wf_graph.get('graph2use'): + dotfilename = os.path.join(log_dir, f'{p_name}_{graph2use}.dot') + for graph_format in wf_graph.get('format'): + try: + workflow.write_graph(dotfilename=dotfilename, + graph2use=graph2use, + format=graph_format, + simple_form=wf_graph.get( + 'simple_form', True)) + except Exception as exception: + raise RuntimeError(f'Failed to visualize {p_name} (' + f'{graph2use}, {graph_format})' + ) from exception + + workflow_save = c.pipeline_setup['log_directory'].get('save_workflow', False) + if workflow_save: + workflow_meta = WorkflowJSONMeta(pipeline_name=p_name, stage='pre') + save_workflow_json( + filename=os.path.join(log_dir, workflow_meta.filename()), + workflow=workflow, + meta=workflow_meta + ) if test_config: logger.info('This has been a test of the pipeline configuration ' @@ -728,7 +759,6 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, Timing information saved in {log_dir}/cpac_individual_timing_{pipeline}.csv System time of start: {run_start} {output_check} - """ finally: @@ -751,6 +781,18 @@ def run_workflow(sub_dict, c, run, pipeline_timing_info=None, p_name=None, c['subject_id']) )) + if workflow_save: + workflow_meta.stage = "post" + workflow_filename = os.path.join( + log_dir, + workflow_meta.filename() + ) + save_workflow_json( + filename=workflow_filename, + workflow=workflow, + meta=workflow_meta + ) + # Remove working directory when done if c.pipeline_setup['working_directory'][ 'remove_working_dir']: @@ -828,40 +870,29 @@ def build_anat_preproc_stack(rpool, cfg, pipeline_blocks=None): pipeline_blocks += anat_init_blocks if not rpool.check_rpool('freesurfer-subject-dir'): - pipeline_blocks += [freesurfer_preproc] + pipeline_blocks += [freesurfer_reconall] # includes postproc if not rpool.check_rpool('desc-preproc_T1w'): # brain masking for ACPC alignment if cfg.anatomical_preproc['acpc_alignment']['acpc_target'] == 'brain': - if rpool.check_rpool('space-T1w_desc-brain_mask') or \ - cfg.surface_analysis['freesurfer']['run']: - acpc_blocks = [ - brain_extraction_temp, - acpc_align_brain_with_mask - # outputs space-T1w_desc-brain_mask for later - keep the mask (the user provided) - ] - acpc_blocks.append( - [brain_mask_acpc_freesurfer_fsl_tight, - brain_mask_acpc_freesurfer_fsl_loose] - ) - else: acpc_blocks = [ [brain_mask_acpc_afni, brain_mask_acpc_fsl, brain_mask_acpc_niworkflows_ants, brain_mask_acpc_unet, - brain_mask_acpc_freesurfer_abcd], - # brain_mask_acpc_freesurfer - # we don't want these masks to be used later + brain_mask_acpc_freesurfer_abcd, + brain_mask_acpc_freesurfer, + brain_mask_acpc_freesurfer_fsl_tight, + brain_mask_acpc_freesurfer_fsl_loose], + acpc_align_brain_with_mask, brain_extraction_temp, acpc_align_brain ] - elif cfg.anatomical_preproc['acpc_alignment'][ - 'acpc_target'] == 'whole-head': + elif cfg.anatomical_preproc['acpc_alignment']['acpc_target'] == 'whole-head': if (rpool.check_rpool('space-T1w_desc-brain_mask') and \ cfg.anatomical_preproc['acpc_alignment']['align_brain_mask']) or \ - cfg.surface_analysis['freesurfer']['run']: + cfg.surface_analysis['freesurfer']['run_reconall']: acpc_blocks = [ acpc_align_head_with_mask # outputs space-T1w_desc-brain_mask for later - keep the mask (the user provided) @@ -870,6 +901,7 @@ def build_anat_preproc_stack(rpool, cfg, pipeline_blocks=None): acpc_blocks = [ acpc_align_head # does not output nor generate a mask ] + anat_preproc_blocks = [ (non_local_means, ('T1w', ['desc-preproc_T1w', @@ -884,22 +916,21 @@ def build_anat_preproc_stack(rpool, cfg, pipeline_blocks=None): pipeline_blocks += anat_blocks - if not rpool.check_rpool('freesurfer-subject-dir'): - pipeline_blocks += [freesurfer_abcd_preproc] + pipeline_blocks += [freesurfer_abcd_preproc] # Anatomical T1 brain masking - if not rpool.check_rpool('space-T1w_desc-brain_mask') or \ - cfg.surface_analysis['freesurfer']['run']: - anat_brain_mask_blocks = [ - [brain_mask_afni, - brain_mask_fsl, - brain_mask_niworkflows_ants, - brain_mask_unet, - brain_mask_freesurfer_abcd, - brain_mask_freesurfer_fsl_tight, - brain_mask_freesurfer_fsl_loose] - ] - pipeline_blocks += anat_brain_mask_blocks + + anat_brain_mask_blocks = [ + [brain_mask_afni, + brain_mask_fsl, + brain_mask_niworkflows_ants, + brain_mask_unet, + brain_mask_freesurfer_abcd, + brain_mask_freesurfer, + brain_mask_freesurfer_fsl_tight, + brain_mask_freesurfer_fsl_loose] + ] + pipeline_blocks += anat_brain_mask_blocks # T2w Anatomical Preprocessing if rpool.check_rpool('T2w'): @@ -987,9 +1018,10 @@ def build_T1w_registration_stack(rpool, cfg, pipeline_blocks=None): reg_blocks = [ [register_ANTs_anat_to_template, register_FSL_anat_to_template], overwrite_transform_anat_to_template, + warp_wholeheadT1_to_template, + warp_T1mask_to_template ] - if not rpool.check_rpool('desc-restore-brain_T1w'): reg_blocks.append(correct_restore_brain_intensity_abcd) @@ -1011,7 +1043,8 @@ def build_segmentation_stack(rpool, cfg, pipeline_blocks=None): not rpool.check_rpool('label-WM_mask'): seg_blocks = [ [tissue_seg_fsl_fast, - tissue_seg_ants_prior] + tissue_seg_ants_prior, + tissue_seg_freesurfer] ] if 'T1_Template' in cfg.segmentation['tissue_segmentation'][ 'Template_Based']['template_for_segmentation']: @@ -1024,7 +1057,7 @@ def build_segmentation_stack(rpool, cfg, pipeline_blocks=None): if cfg.registration_workflows['anatomical_registration']['run'] and 'T1_Template' in cfg.segmentation[ 'tissue_segmentation']['Template_Based']['template_for_segmentation']: - pipeline_blocks.append(warp_Tissuemask_to_T1template) + pipeline_blocks.append(warp_tissuemask_to_T1template) return pipeline_blocks @@ -1064,9 +1097,14 @@ def connect_pipeline(wf, cfg, rpool, pipeline_blocks): previous_nb = None for block in pipeline_blocks: try: - nb = NodeBlock(block) + nb = NodeBlock(block, debug=cfg['pipeline_setup', 'Debugging', + 'verbose']) wf = nb.connect_block(wf, cfg, rpool) except LookupError as e: + if nb.name == 'freesurfer_postproc': + logger.warning(WARNING_FREESURFER_OFF_WITH_DATA) + LOGTAIL['warnings'].append(WARNING_FREESURFER_OFF_WITH_DATA) + continue previous_nb_str = ( f"after node block '{previous_nb.get_name()}': " ) if previous_nb else 'at beginning:' @@ -1088,6 +1126,7 @@ def connect_pipeline(wf, cfg, rpool, pipeline_blocks): def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, num_ants_cores=1): + from CPAC.utils.datasource import gather_extraction_maps # Workflow setup wf = initialize_nipype_wf(cfg, sub_dict) @@ -1128,13 +1167,13 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, # Functional Preprocessing, including motion correction and BOLD masking if cfg.functional_preproc['run']: func_init_blocks = [ + func_reorient, func_scaling, func_truncate ] func_preproc_blocks = [ func_despike, - func_slice_time, - func_reorient + func_slice_time ] if not rpool.check_rpool('desc-mean_bold'): @@ -1150,17 +1189,26 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, func_prep_blocks = [ calc_motion_stats, - func_normalize + func_normalize, + [coregistration_prep_vol, + coregistration_prep_mean, + coregistration_prep_fmriprep] ] # Distortion/Susceptibility Correction distcor_blocks = [] - if rpool.check_rpool('diffphase') and rpool.check_rpool('diffmag'): - distcor_blocks.append(distcor_phasediff_fsl_fugue) - - if rpool.check_rpool('epi-1'): - distcor_blocks.append(distcor_blip_afni_qwarp) - distcor_blocks.append(distcor_blip_fsl_topup) + if 'fmap' in sub_dict: + fmap_keys = sub_dict['fmap'] + if 'phasediff' in fmap_keys or 'phase1' in fmap_keys: + if 'magnitude' in fmap_keys or 'magnitude1' in fmap_keys: + distcor_blocks.append(distcor_phasediff_fsl_fugue) + if len(fmap_keys) == 2: + for key in fmap_keys: + if 'epi_' not in key: + break + else: + distcor_blocks.append(distcor_blip_afni_qwarp) + distcor_blocks.append(distcor_blip_fsl_topup) if distcor_blocks: if len(distcor_blocks) > 1: @@ -1198,10 +1246,9 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, # BOLD to T1 coregistration if cfg.registration_workflows['functional_registration'][ 'coregistration']['run'] and \ - (not rpool.check_rpool('space-T1w_desc-mean_bold') or + (not rpool.check_rpool('space-T1w_sbref') or not rpool.check_rpool('from-bold_to-T1w_mode-image_desc-linear_xfm')): coreg_blocks = [ - [coregistration_prep_vol, coregistration_prep_mean, coregistration_prep_fmriprep], coregistration ] pipeline_blocks += coreg_blocks @@ -1215,11 +1262,11 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, ] pipeline_blocks += EPI_reg_blocks - if cfg.registration_workflows['functional_registration']['EPI_registration']['run' - ] and 'EPI_Template' in cfg.segmentation['tissue_segmentation']['Template_Based']['template_for_segmentation']: - pipeline_blocks.append(warp_Tissuemask_to_EPItemplate) - - + if (cfg['registration_workflows', 'functional_registration', + 'EPI_registration', 'run'] and + 'EPI_Template' in cfg['segmentation', 'tissue_segmentation', + 'Template_Based', 'template_for_segmentation']): + pipeline_blocks.append(warp_tissuemask_to_EPItemplate) # Generate the composite transform for BOLD-to-template for the T1 # anatomical template (the BOLD-to- EPI template is already created above) @@ -1234,6 +1281,8 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, pipeline_blocks += [create_func_to_T1template_symmetric_xfm] # Nuisance Correction + generate_only = True not in cfg['nuisance_corrections', + '2-nuisance_regression', 'run'] if not rpool.check_rpool('desc-cleaned_bold'): nuisance = [ICA_AROMA_ANTsreg, ICA_AROMA_FSLreg, ICA_AROMA_ANTsEPIreg, ICA_AROMA_FSLEPIreg] @@ -1246,7 +1295,7 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, erode_mask_boldCSF, erode_mask_boldGM, erode_mask_boldWM] - nuisance += nuisance_masks + choose_nuisance_blocks(cfg) + nuisance += nuisance_masks + choose_nuisance_blocks(cfg, generate_only) pipeline_blocks += nuisance @@ -1257,9 +1306,6 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, _r_w_f_r['coregistration']['run'] and _r_w_f_r['func_registration_to_template']['run']) template_funcs = [ - 'space-template_desc-cleaned_bold', - 'space-template_desc-brain_bold', - 'space-template_desc-motion_bold', 'space-template_desc-preproc_bold', 'space-template_bold' ] @@ -1267,32 +1313,48 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, if rpool.check_rpool(func): apply_func_warp['T1'] = False + target_space_nuis = cfg.nuisance_corrections['2-nuisance_regression'][ + 'space'] + target_space_alff = cfg.amplitude_low_frequency_fluctuation['target_space'] + target_space_reho = cfg.regional_homogeneity['target_space'] + if apply_func_warp['T1']: - ts_to_T1template_block = [warp_timeseries_to_T1template, + ts_to_T1template_block = [apply_phasediff_to_timeseries_separately, + apply_blip_to_timeseries_separately, + warp_timeseries_to_T1template, warp_timeseries_to_T1template_dcan_nhp] + if 'Template' in target_space_alff or 'Template' in target_space_reho: + ts_to_T1template_block += [warp_timeseries_to_T1template_deriv] + if cfg.nuisance_corrections['2-nuisance_regression']['create_regressors']: - ts_to_T1template_block += [(warp_timeseries_to_T1template_abcd, ('desc-cleaned_bold', 'bold'))] + ts_to_T1template_block += [(warp_timeseries_to_T1template_abcd, ('desc-preproc_bold', 'bold'))] ts_to_T1template_block.append(single_step_resample_timeseries_to_T1template) else: ts_to_T1template_block.append(warp_timeseries_to_T1template_abcd) ts_to_T1template_block.append(single_step_resample_timeseries_to_T1template) pipeline_blocks += [ts_to_T1template_block, - warp_bold_mean_to_T1template, - warp_bold_mean_to_EPItemplate] + warp_sbref_to_T1template] if not rpool.check_rpool('space-template_desc-bold_mask'): pipeline_blocks += [warp_bold_mask_to_T1template, warp_deriv_mask_to_T1template] - template = cfg.registration_workflows['functional_registration']['func_registration_to_template']['target_template']['using'] + pipeline_blocks += [func_despike_template] + + if 'Template' in target_space_alff and 'Native' in target_space_nuis: + pipeline_blocks += [warp_denoiseNofilt_to_T1template] + + template = cfg.registration_workflows['functional_registration'][ + 'func_registration_to_template']['target_template']['using'] if 'T1_template' in template: apply_func_warp['EPI'] = (_r_w_f_r['coregistration']['run'] and _r_w_f_r['func_registration_to_template']['run_EPI']) else: apply_func_warp['EPI'] = (_r_w_f_r['func_registration_to_template']['run_EPI']) + del _r_w_f_r template_funcs = [ @@ -1314,8 +1376,17 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, pipeline_blocks += [warp_bold_mask_to_EPItemplate, warp_deriv_mask_to_EPItemplate] + # Template-space nuisance regression + nuisance_template = 'template' in cfg[ + 'nuisance_corrections', '2-nuisance_regression', 'space' + ] and not generate_only + if nuisance_template: + pipeline_blocks += [(nuisance_regression_template, + ("desc-preproc_bold", "desc-stc_bold"))] + # PostFreeSurfer and fMRISurface if not rpool.check_rpool('space-fsLR_den-32k_bold.dtseries'): + pipeline_blocks += [surface_postproc] if not rpool.check_rpool('surf_falff'): @@ -1335,7 +1406,7 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, cfg.timeseries_extraction['tse_atlases'] = tse_atlases cfg.seed_based_correlation_analysis['sca_atlases'] = sca_atlases - if not rpool.check_rpool('desc-Mean_timeseries') and \ + if not rpool.check_rpool('space-template_desc-Mean_timeseries') and \ 'Avg' in tse_atlases: pipeline_blocks += [timeseries_extraction_AVG] @@ -1347,23 +1418,36 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None, 'SpatialReg' in tse_atlases: pipeline_blocks += [spatial_regression] - if not rpool.check_rpool('desc-MeanSCA_correlations') and \ + if not rpool.check_rpool('space-template_desc-MeanSCA_correlations') and \ 'Avg' in sca_atlases: pipeline_blocks += [SCA_AVG] - if not rpool.check_rpool('desc-DualReg_correlations') and \ + if not rpool.check_rpool('space-template_desc-DualReg_correlations') and \ 'DualReg' in sca_atlases: pipeline_blocks += [dual_regression] - if not rpool.check_rpool('desc-MultReg_correlations') and \ + if not rpool.check_rpool('space-template_desc-MultReg_correlations') and \ 'MultReg' in sca_atlases: pipeline_blocks += [multiple_regression] - if not rpool.check_rpool('alff'): - pipeline_blocks += [alff_falff] + if 'Native' in target_space_alff: + if not rpool.check_rpool('alff'): + pipeline_blocks += [alff_falff] + + if 'Template' in target_space_alff: + if not nuisance_template and not rpool.check_rpool( + 'space-template_desc-denoisedNofilt_bold'): + pipeline_blocks += [warp_denoiseNofilt_to_T1template] + if not rpool.check_rpool('space-template_alff'): + pipeline_blocks += [alff_falff_space_template] + + if 'Native' in target_space_reho: + if not rpool.check_rpool('reho'): + pipeline_blocks += [reho] - if not rpool.check_rpool('reho'): - pipeline_blocks += [reho] + if 'Template' in target_space_reho: + if not rpool.check_rpool('space-template_reho'): + pipeline_blocks += [reho_space_template] if not rpool.check_rpool('vmhc'): pipeline_blocks += [smooth_func_vmhc, diff --git a/CPAC/pipeline/cpac_runner.py b/CPAC/pipeline/cpac_runner.py index e99e45108e..30d6b0fc18 100755 --- a/CPAC/pipeline/cpac_runner.py +++ b/CPAC/pipeline/cpac_runner.py @@ -17,20 +17,16 @@ import os import sys import warnings -import yaml from multiprocessing import Process from time import strftime +import yaml from voluptuous.error import Invalid - -from CPAC.utils.configuration import Configuration +from CPAC.utils.configuration import check_pname, Configuration, set_subject from CPAC.utils.ga import track_run -from CPAC.utils.monitoring import log_nodes_cb -from CPAC.longitudinal_pipeline.longitudinal_workflow import ( - anat_longitudinal_wf, - func_preproc_longitudinal_wf, - func_longitudinal_template_wf -) -from CPAC.utils.yaml_template import upgrade_pipeline_to_1_8 +from CPAC.utils.monitoring import failed_to_start, log_nodes_cb +from CPAC.longitudinal_pipeline.longitudinal_workflow import \ + anat_longitudinal_wf +from CPAC.utils.configuration.yaml_template import upgrade_pipeline_to_1_8 # Run condor jobs @@ -221,7 +217,13 @@ def run_T1w_longitudinal(sublist, cfg): # Run C-PAC subjects via job queue def run(subject_list_file, config_file=None, p_name=None, plugin=None, plugin_args=None, tracking=True, num_subs_at_once=None, debug=False, - test_config=False): + test_config=False) -> int: + """ + Returns + ------- + int + exit code + """ exitcode = 0 # Import packages @@ -255,8 +257,8 @@ def run(subject_list_file, config_file=None, p_name=None, plugin=None, sublist = bids_gen_cpac_sublist(subject_list_file, file_paths, config, None) if not sublist: - print("Did not find data in {0}".format(subject_list_file)) - sys.exit(1) + print(f"Did not find data in {subject_list_file}") + return 1 # take date+time stamp for run identification purposes unique_pipeline_id = strftime("%Y%m%d%H%M%S") @@ -325,10 +327,11 @@ def run(subject_list_file, config_file=None, p_name=None, plugin=None, warnings.warn("We recommend that the working directory full path " "should have less then 70 characters. " "Long paths might not work in your operating system.") - warnings.warn("Current working directory: %s" % c.pipeline_setup['working_directory']['path']) + warnings.warn("Current working directory: " + f"{c.pipeline_setup['working_directory']['path']}") # Get the pipeline name - p_name = p_name or c.pipeline_setup['pipeline_name'] + p_name = check_pname(p_name, c) # Load in subject list try: @@ -338,7 +341,7 @@ def run(subject_list_file, config_file=None, p_name=None, plugin=None, print("Subject list is not in proper YAML format. Please check " \ "your file") raise Exception - + # Populate subject scan map sub_scan_map = {} try: @@ -542,7 +545,6 @@ def replace_index(target1, target2, file_path): ses['resource_pool'][strat_key].update({ keys[-2]: f }) - for key in subject_specific_dict: ses_list = [subj for subj in sublist if key in subj['anat']] for ses in ses_list: @@ -560,7 +562,6 @@ def replace_index(target1, target2, file_path): pass yaml.dump(sublist, open(os.path.join(c.pipeline_setup['working_directory']['path'],'data_config_longitudinal.yml'), 'w'), default_flow_style=False) - print('\n\n' + 'Longitudinal pipeline completed.' + '\n\n') # skip main preprocessing @@ -578,66 +579,91 @@ def replace_index(target1, target2, file_path): try: run_workflow(sub, c, True, pipeline_timing_info, p_name, plugin, plugin_args, test_config) - except Exception as e: + except Exception as exception: # pylint: disable=broad-except exitcode = 1 - raise e + failed_to_start(set_subject(sub, c)[2], exception) return exitcode - pid = open(os.path.join( - c.pipeline_setup['working_directory']['path'], 'pid.txt' - ), 'w') - # Init job queue job_queue = [] # Allocate processes - processes = [ - Process(target=run_workflow, - args=(sub, c, True, pipeline_timing_info, - p_name, plugin, plugin_args, test_config)) - for sub in sublist - ] - - # If we're allocating more processes than are subjects, run them all - if len(sublist) <= c.pipeline_setup['system_config']['num_participants_at_once']: - for p in processes: - p.start() - print(p.pid, file=pid) - - # Otherwise manage resources to run processes incrementally - else: - idx = 0 - while idx < len(sublist): - # If the job queue is empty and we haven't started indexing - if len(job_queue) == 0 and idx == 0: - # Init subject process index - idc = idx - # Launch processes (one for each subject) - for p in processes[idc: idc+c.pipeline_setup['system_config']['num_participants_at_once']]: - p.start() - print(p.pid, file=pid) - job_queue.append(p) - idx += 1 - # Otherwise, jobs are running - check them - else: - # Check every job in the queue's status - for job in job_queue: - # If the job is not alive - if not job.is_alive(): - # Find job and delete it from queue - print('found dead job ', job) - loc = job_queue.index(job) - del job_queue[loc] - # ...and start the next available process - # (subject) - processes[idx].start() - # Append this to job queue and increment index - job_queue.append(processes[idx]) - idx += 1 - # Add sleep so while loop isn't consuming 100% of CPU - time.sleep(2) - # set exitcode to 1 if any exception - exitcode = exitcode or pid.exitcode - # Close PID txt file to indicate finish - pid.close() - sys.exit(exitcode) + processes = [Process(target=run_workflow, + args=(sub, c, True, pipeline_timing_info, p_name, + plugin, plugin_args, test_config)) for + sub in sublist] + working_dir = os.path.join(c['pipeline_setup', 'working_directory', + 'path'], p_name) + # Create pipeline-specific working dir if not exists + if not os.path.exists(working_dir): + os.makedirs(working_dir) + # Set PID context to pipeline-specific file + with open(os.path.join(working_dir, 'pid.txt'), 'w', encoding='utf-8' + ) as pid: + # If we're allocating more processes than are subjects, run + # them all + if len(sublist) <= c.pipeline_setup['system_config'][ + 'num_participants_at_once']: + for i, _p in enumerate(processes): + try: + _p.start() + print(_p.pid, file=pid) + # pylint: disable=broad-except + except Exception as exception: + exitcode = 1 + failed_to_start(set_subject(sublist[i], c)[2], + exception) + # Otherwise manage resources to run processes incrementally + else: + idx = 0 + while idx < len(sublist): + # If the job queue is empty and we haven't started indexing + if len(job_queue) == 0 and idx == 0: + # Init subject process index + idc = idx + # Launch processes (one for each subject) + for _p in processes[idc: idc + c.pipeline_setup[ + 'system_config']['num_participants_at_once']]: + try: + _p.start() + print(_p.pid, file=pid) + job_queue.append(_p) + idx += 1 + # pylint: disable=broad-except + except Exception as exception: + exitcode = 1 + failed_to_start(set_subject(sublist[idx], + c)[2], exception) + # Otherwise, jobs are running - check them + else: + # Check every job in the queue's status + for job in job_queue: + # If the job is not alive + if not job.is_alive(): + # Find job and delete it from queue + print('found dead job ', job) + loc = job_queue.index(job) + del job_queue[loc] + # ...and start the next available + # process (subject) + try: + processes[idx].start() + # Append this to job queue and + # increment index + # pylint: disable=modified-iterating-list + job_queue.append(processes[idx]) + idx += 1 + # pylint: disable=broad-except + except Exception as exception: + exitcode = 1 + failed_to_start(set_subject(sublist[idx], + c)[2], + exception) + # Add sleep so while loop isn't consuming 100% of CPU + time.sleep(2) + # set exitcode to 1 if any exception + if hasattr(pid, 'exitcode'): + exitcode = exitcode or pid.exitcode + # Close PID txt file to indicate finish + pid.close() + return exitcode diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 998b7eb688..94573f9fbb 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1,38 +1,43 @@ -"""Copyright (C) 2022 C-PAC Developers +# Copyright (C) 2021-2023 C-PAC Developers -This file is part of C-PAC. +# This file is part of C-PAC. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .""" +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import ast +import copy +from itertools import chain import logging import os +import re +from types import FunctionType +from typing import Tuple, Union import warnings -import copy -import yaml from CPAC.pipeline import \ nipype_pipeline_engine as pe # pylint: disable=ungrouped-imports +from nipype import config, logging # pylint: disable=wrong-import-order from nipype.interfaces.utility import \ Rename # pylint: disable=wrong-import-order - +from CPAC.func_preproc.func_preproc import motion_estimate_filter from CPAC.image_utils.spatial_smoothing import spatial_smoothing from CPAC.image_utils.statistical_transforms import z_score_standardize, \ fisher_z_score_standardize from CPAC.pipeline.check_outputs import ExpectedOutputs +from CPAC.pipeline.utils import source_set from CPAC.registration.registration import transform_derivative -from CPAC.utils import Outputs +from CPAC.utils.bids_utils import insert_entity, res_in_filename from CPAC.utils.datasource import ( create_anat_datasource, create_func_datasource, @@ -43,9 +48,13 @@ from CPAC.utils.docs import grab_docstring_dct from CPAC.utils.interfaces.function import Function from CPAC.utils.interfaces.datasink import DataSink -from CPAC.utils.monitoring.custom_logging import getLogger -from CPAC.utils.utils import read_json, create_id_string, write_output_json, \ - get_last_prov_entry, check_prov_for_regtool +from CPAC.utils.monitoring import getLogger, LOGTAIL, \ + WARNING_FREESURFER_OFF_WITH_DATA +from CPAC.utils.outputs import Outputs +from CPAC.utils.utils import check_prov_for_regtool, \ + create_id_string, get_last_prov_entry, read_json, write_output_json + +from CPAC.resources.templates.lookup_table import lookup_identifier logger = logging.getLogger('nipype.workflow') verbose_logger = logging.getLogger('engine') @@ -89,8 +98,10 @@ def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None): self.run_smoothing = 'smoothed' in cfg.post_processing[ 'spatial_smoothing']['output'] + self.smoothing_bool = cfg.post_processing['spatial_smoothing']['run'] self.run_zscoring = 'z-scored' in cfg.post_processing[ 'z-scoring']['output'] + self.zscoring_bool = cfg.post_processing['z-scoring']['run'] self.fwhm = cfg.post_processing['spatial_smoothing']['fwhm'] self.smooth_opts = cfg.post_processing['spatial_smoothing'][ 'smoothing_method'] @@ -105,6 +116,44 @@ def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None): def append_name(self, name): self.name.append(name) + def back_propogate_template_name(self, resource_idx: str, json_info: dict, + id_string: 'pe.Node') -> None: + """Find and apply the template name from a resource's provenance + + Parameters + ---------- + resource_idx : str + + json_info : dict + + id_string : pe.Node + + Returns + ------- + None + """ + if 'Template' in json_info: + id_string.inputs.template_desc = json_info['Template'] + elif ('template' in resource_idx and + len(json_info.get('CpacProvenance', [])) > 1): + for resource in source_set(json_info['CpacProvenance']): + source, value = resource.split(':', 1) + if value.startswith('template_' + ) and source != 'FSL-AFNI-bold-ref': + # 'FSL-AFNI-bold-ref' is currently allowed to be in + # a different space, so don't use it as the space for + # descendents + try: + anscestor_json = list(self.rpool.get(source).items() + )[0][1].get('json', {}) + if 'Description' in anscestor_json: + id_string.inputs.template_desc = anscestor_json[ + 'Description'] + return + except (IndexError, KeyError): + pass + return + def get_name(self): return self.name @@ -172,6 +221,9 @@ def set_json_info(self, resource, pipe_idx, key, val): def get_json_info(self, resource, pipe_idx, key): #TODO: key checks + if not pipe_idx: + for pipe_idx, val in self.rpool[resource].items(): + return val['json'][key] return self.rpool[resource][pipe_idx][key] def get_resource_from_prov(self, prov): @@ -668,7 +720,8 @@ def derivative_xfm(self, wf, label, connection, json_info, pipe_idx, wf.connect(node, out, xfm, 'inputspec.transform') label = f'space-template_{label}' - + json_info['Template'] = self.get_json_info('T1w-brain-template-deriv', + None, 'Description') new_prov = json_info['CpacProvenance'] + xfm_prov json_info['CpacProvenance'] = new_prov new_pipe_idx = self.generate_prov_string(new_prov) @@ -684,7 +737,10 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x, post_labels = [(label, connection[0], connection[1])] - if 'centrality' in label or 'lfcd' in label: + if re.match(r'(.*_)?[ed]c[bw]$', label) or re.match(r'(.*_)?lfcd[bw]$', + label): + # suffix: [eigenvector or degree] centrality [binarized or weighted] + # or lfcd [binarized or weighted] mask = 'template-specification-file' elif 'space-template' in label: mask = 'space-template_res-derivative_desc-bold_mask' @@ -699,7 +755,7 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x, mask_idx = self.generate_prov_string(mask_prov)[1] break - if self.run_smoothing: + if self.smoothing_bool: if label in Outputs.to_smooth: for smooth_opt in self.smooth_opts: @@ -738,7 +794,7 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x, pipe_idx, f'spatial_smoothing_{smooth_opt}', fork=True) - if self.run_zscoring: + if self.zscoring_bool: for label_con_tpl in post_labels: label = label_con_tpl[0] connection = (label_con_tpl[1], label_con_tpl[2]) @@ -779,7 +835,7 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x, wf.connect(connection[0], connection[1], zstd, 'inputspec.correlation_file') - # if the output is 'desc-MeanSCA_correlations', we want + # if the output is 'space-template_desc-MeanSCA_correlations', we want # 'desc-MeanSCA_timeseries' oned = label.replace('correlations', 'timeseries') @@ -800,6 +856,8 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): substring_excl = [] outputs_logger = getLogger(f'{cfg["subject_id"]}_expectedOutputs') expected_outputs = ExpectedOutputs() + movement_filter_keys = grab_docstring_dct(motion_estimate_filter).get( + 'outputs', []) if add_excl: excl += add_excl @@ -814,10 +872,11 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): excl += Outputs.template_raw if not cfg.pipeline_setup['output_directory']['write_debugging_outputs']: - substring_excl.append(['desc-reginput', 'bold']) + # substring_excl.append(['bold']) excl += Outputs.debugging for resource in self.rpool.keys(): + if resource not in Outputs.any: continue @@ -852,11 +911,17 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): for pipe_idx in self.rpool[resource]: unique_id = self.get_name() + part_id = unique_id.split('_')[0] + ses_id = unique_id.split('_')[1] + + if 'ses-' not in ses_id: + ses_id = f"ses-{ses_id}" out_dir = cfg.pipeline_setup['output_directory']['path'] pipe_name = cfg.pipeline_setup['pipeline_name'] - container = os.path.join(f'cpac_{pipe_name}', unique_id) - filename = f'{unique_id}_{resource}' + container = os.path.join(f'pipeline_{pipe_name}', part_id, + ses_id) + filename = f'{unique_id}_{res_in_filename(self.cfg, resource)}' out_path = os.path.join(out_dir, container, subdir, filename) @@ -872,8 +937,7 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): # TODO: have to link the pipe_idx's here. and call up 'desc-preproc_T1w' from a Sources in a json and replace. here. # TODO: can do the pipeline_description.json variants here too! - #print(Outputs.any) - #print(self.rpool.keys()) + for resource in self.rpool.keys(): if resource not in Outputs.any: @@ -903,18 +967,46 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): num_variant = 0 if len(self.rpool[resource]) == 1: num_variant = "" + all_jsons = [self.rpool[resource][pipe_idx]['json'] for pipe_idx in + self.rpool[resource]] + unlabelled = set(key for json_info in all_jsons for key in + json_info.get('CpacVariant', {}).keys() if + key not in (*movement_filter_keys, 'regressors')) + if 'bold' in unlabelled: + all_bolds = list( + chain.from_iterable(json_info['CpacVariant']['bold'] for + json_info in all_jsons if + 'CpacVariant' in json_info and + 'bold' in json_info['CpacVariant'])) + # not any(not) because all is overloaded as a parameter here + if not any(not re.match(r'apply_(phasediff|blip)_to_' + r'timeseries_separately_.*', _bold) + for _bold in all_bolds): + # this fork point should only result in 0 or 1 forks + unlabelled.remove('bold') + del all_bolds + all_forks = {key: set( + chain.from_iterable(json_info['CpacVariant'][key] for + json_info in all_jsons if + 'CpacVariant' in json_info and + key in json_info['CpacVariant'])) for + key in unlabelled} + # del all_jsons + for key, forks in all_forks.items(): + if len(forks) < 2: # no int suffix needed if only one fork + unlabelled.remove(key) + # del all_forks for pipe_idx in self.rpool[resource]: - pipe_x = self.get_pipe_number(pipe_idx) + json_info = self.rpool[resource][pipe_idx]['json'] + out_dct = self.rpool[resource][pipe_idx]['out'] try: - num_variant += 1 + if unlabelled: + num_variant += 1 except TypeError: pass - json_info = self.rpool[resource][pipe_idx]['json'] - out_dct = self.rpool[resource][pipe_idx]['out'] - try: del json_info['subjson'] except KeyError: @@ -924,44 +1016,85 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): continue unique_id = out_dct['unique_id'] - - if num_variant: - for key in out_dct['filename'].split('_'): - if 'desc-' in key: - out_dct['filename'] = out_dct[ - 'filename'].replace(key, - f'{key}-{num_variant}') - resource_idx = resource.replace(key, f'{key}-' - f'{num_variant}') - break + resource_idx = resource + + if isinstance(num_variant, int): + if True in cfg['functional_preproc', + 'motion_estimates_and_correction', + 'motion_estimate_filter', 'run']: + filt_value = None + _motion_variant = { + _key: json_info['CpacVariant'][_key] + for _key in movement_filter_keys + if _key in json_info.get('CpacVariant', {})} + try: + filt_value = [ + json_info['CpacVariant'][_k][0].replace( + 'motion_estimate_filter_', '' + ) for _k, _v in _motion_variant.items() + if _v][0] + except IndexError: + filt_value = 'none' + if filt_value is not None: + resource_idx = insert_entity(resource_idx, 'filt', + filt_value) + out_dct['filename'] = insert_entity( + out_dct['filename'], 'filt', filt_value) + if True in cfg['nuisance_corrections', + '2-nuisance_regression', 'run']: + reg_value = None + if ('regressors' in json_info.get('CpacVariant', {}) + and json_info['CpacVariant']['regressors']): + reg_value = json_info['CpacVariant'][ + 'regressors' + ][0].replace('nuisance_regressors_generation_', '') + elif False in cfg['nuisance_corrections', + '2-nuisance_regression', 'run']: + reg_value = 'Off' + if reg_value is not None: + out_dct['filename'] = insert_entity( + out_dct['filename'], 'reg', reg_value) + resource_idx = insert_entity(resource_idx, 'reg', + reg_value) + if unlabelled: + if 'desc-' in out_dct['filename']: + for key in out_dct['filename'].split('_')[::-1]: + if key.startswith('desc-'): # final `desc` entity + out_dct['filename'] = out_dct['filename' + ].replace( + key, f'{key}-{num_variant}') + resource_idx = resource_idx.replace( + key, f'{key}-{num_variant}') + break else: suff = resource.split('_')[-1] newdesc_suff = f'desc-{num_variant}_{suff}' - resource_idx = resource.replace(suff, - newdesc_suff) - else: - resource_idx = resource - expected_outputs += (out_dct['subdir'], - out_dct['filename'][len(unique_id)+1:]) - - id_string = pe.Node(Function(input_names=['unique_id', + resource_idx = resource_idx.replace(suff, + newdesc_suff) + id_string = pe.Node(Function(input_names=['cfg', 'unique_id', 'resource', 'scan_id', + 'template_desc', 'atlas_id', 'fwhm', - 'extension'], + 'subdir'], output_names=['out_filename'], function=create_id_string), name=f'id_string_{resource_idx}_{pipe_x}') + id_string.inputs.cfg = self.cfg id_string.inputs.unique_id = unique_id id_string.inputs.resource = resource_idx + id_string.inputs.subdir = out_dct['subdir'] # grab the iterable scan ID if out_dct['subdir'] == 'func': node, out = self.rpool['scan']["['scan:func_ingress']"][ 'data'] wf.connect(node, out, id_string, 'scan_id') - + + self.back_propogate_template_name(resource_idx, json_info, + id_string) + # grab the FWHM if smoothed for tag in resource.split('_'): if 'desc-' in tag and '-sm' in tag: @@ -974,9 +1107,9 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): # engine.py smoothing pass break - atlas_suffixes = ['timeseries', 'correlations', 'statmap'] # grab the iterable atlas ID + atlas_id = None if resource.split('_')[-1] in atlas_suffixes: atlas_idx = pipe_idx.replace(resource, 'atlas_name') # need the single quote and the colon inside the double @@ -1019,7 +1152,6 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): wf.connect(id_string, 'out_filename', nii_name, 'format_string') - node, out = self.rpool[resource][pipe_idx]['data'] try: @@ -1051,12 +1183,14 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): 'aws_output_bucket_credentials']: ds.inputs.creds_path = cfg.pipeline_setup['Amazon-AWS'][ 'aws_output_bucket_credentials'] - + expected_outputs += (out_dct['subdir'], create_id_string( + self.cfg, unique_id, resource_idx, + template_desc=id_string.inputs.template_desc, + atlas_id=atlas_id, subdir=out_dct['subdir'])) wf.connect(nii_name, 'out_file', ds, f'{out_dct["subdir"]}.@data') wf.connect(write_json, 'json_file', ds, f'{out_dct["subdir"]}.@json') - outputs_logger.info(expected_outputs) def node_data(self, resource, **kwargs): @@ -1074,8 +1208,7 @@ def node_data(self, resource, **kwargs): class NodeBlock: - def __init__(self, node_block_functions): - + def __init__(self, node_block_functions, debug=False): if not isinstance(node_block_functions, list): node_block_functions = [node_block_functions] @@ -1124,6 +1257,19 @@ def __init__(self, node_block_functions): if 'options' in init_dct: self.options = init_dct['options'] + logger.info('Connecting %s...', name) + if debug: + config.update_config( + {'logging': {'workflow_level': 'DEBUG'}}) + logging.update_logging(config) + logger.debug('"inputs": %s\n\t "outputs": %s%s', + init_dct["inputs"], list(self.outputs.keys()), + f'\n\t"options": {self.options}' + if self.options != ['base'] else '') + config.update_config( + {'logging': {'workflow_level': 'INFO'}}) + logging.update_logging(config) + def get_name(self): return self.name @@ -1275,7 +1421,6 @@ def connect_block(self, wf, cfg, rpool): switch = [switch] if True in switch: - logger.info('Connecting %s...', name) for pipe_idx, strat_pool in rpool.get_strats( inputs, debug).items(): # strat_pool is a ResourcePool like {'desc-preproc_T1w': { 'json': info, 'data': (node, out) }, 'desc-brain_mask': etc.} fork = False in switch # keep in mind rpool.get_strats(inputs) = {pipe_idx1: {'desc-preproc_T1w': etc.}, pipe_idx2: {..} } @@ -1306,6 +1451,12 @@ def connect_block(self, wf, cfg, rpool): continue if not outs: + if (block_function.__name__ == 'freesurfer_' + 'postproc'): + logger.warning( + WARNING_FREESURFER_OFF_WITH_DATA) + LOGTAIL['warnings'].append( + WARNING_FREESURFER_OFF_WITH_DATA) continue if opt and len(option_val) > 1: @@ -1339,7 +1490,7 @@ def connect_block(self, wf, cfg, rpool): for label, connection in outs.items(): self.check_output(outputs, label, name) new_json_info = copy.deepcopy(strat_pool.get('json')) - + # transfer over data-specific json info # for example, if the input data json is _bold and the output is also _bold data_type = label.split('_')[-1] @@ -1400,9 +1551,9 @@ def connect_block(self, wf, cfg, rpool): new_json_info, pipe_idx, node_name, fork) - wf, post_labels = rpool.post_process(wf, label, connection, - new_json_info, pipe_idx, - pipe_x, outs) + wf, post_labels = rpool.post_process( + wf, label, connection, new_json_info, pipe_idx, + pipe_x, outs) if rpool.func_reg: for postlabel in post_labels: @@ -1416,6 +1567,40 @@ def connect_block(self, wf, cfg, rpool): return wf +def flatten_list(node_block_function: Union[FunctionType, list, Tuple], + key: str = 'inputs') -> list: + """Take a Node Block function or list of inputs and return a flat list + + Parameters + ---------- + node_block_function : function, list or tuple + a Node Block function or a list or tuple for recursion + + key : str + 'inputs' or 'outputs' + + Returns + ------- + list + """ + flat_list = [] + resource_list = [] + if isinstance(node_block_function, (list, tuple)): + resource_list = node_block_function + elif isinstance(node_block_function, FunctionType): + resource_list = grab_docstring_dct(node_block_function).get(key, []) + elif isinstance(node_block_function, str): + resource_list = [node_block_function] + if isinstance(resource_list, dict): + resource_list = list(resource_list.keys()) + for resource in resource_list: + if isinstance(resource, str): + flat_list.append(resource) + else: + flat_list += flatten_list(resource, key) + return flat_list + + def wrap_block(node_blocks, interface, wf, cfg, strat_pool, pipe_num, opt): """Wrap a list of node block functions to make them easier to use within other node blocks. @@ -1524,6 +1709,57 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, rpool.set_data('T2w', anat_flow_T2, 'outputspec.anat', {}, "", "anat_ingress") + ingress_fs = cfg.surface_analysis['freesurfer']['ingress_reconall'] + + if 'freesurfer_dir' in data_paths['anat'] and ingress_fs: + anat['freesurfer_dir'] = data_paths['anat']['freesurfer_dir'] + + fs_ingress = create_general_datasource('gather_freesurfer_dir') + fs_ingress.inputs.inputnode.set( + unique_id=unique_id, + data=data_paths['anat']['freesurfer_dir'], + creds_path=data_paths['creds_path'], + dl_dir=cfg.pipeline_setup['working_directory']['path']) + rpool.set_data("freesurfer-subject-dir", fs_ingress, 'outputspec.data', + {}, "", "freesurfer_config_ingress") + + recon_outs = { + 'pipeline-fs_raw-average': 'mri/rawavg.mgz', + 'pipeline-fs_subcortical-seg': 'mri/aseg.mgz', + 'pipeline-fs_brainmask': 'mri/brainmask.mgz', + 'pipeline-fs_wmparc': 'mri/wmparc.mgz', + 'pipeline-fs_T1': 'mri/T1.mgz', + 'pipeline-fs_hemi-L_desc-surface_curv': 'surf/lh.curv', + 'pipeline-fs_hemi-R_desc-surface_curv': 'surf/rh.curv', + 'pipeline-fs_hemi-L_desc-surfaceMesh_pial': 'surf/lh.pial', + 'pipeline-fs_hemi-R_desc-surfaceMesh_pial': 'surf/rh.pial', + 'pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm': 'surf/lh.smoothwm', + 'pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm': 'surf/rh.smoothwm', + 'pipeline-fs_hemi-L_desc-surfaceMesh_sphere': 'surf/lh.sphere', + 'pipeline-fs_hemi-R_desc-surfaceMesh_sphere': 'surf/rh.sphere', + 'pipeline-fs_hemi-L_desc-surfaceMap_sulc': 'surf/lh.sulc', + 'pipeline-fs_hemi-R_desc-surfaceMap_sulc': 'surf/rh.sulc', + 'pipeline-fs_hemi-L_desc-surfaceMap_thickness': 'surf/lh.thickness', + 'pipeline-fs_hemi-R_desc-surfaceMap_thickness': 'surf/rh.thickness', + 'pipeline-fs_hemi-L_desc-surfaceMap_volume': 'surf/lh.volume', + 'pipeline-fs_hemi-R_desc-surfaceMap_volume': 'surf/rh.volume', + 'pipeline-fs_hemi-L_desc-surfaceMesh_white': 'surf/lh.white', + 'pipeline-fs_hemi-R_desc-surfaceMesh_white': 'surf/rh.white', + } + + for key, outfile in recon_outs.items(): + fullpath = os.path.join(data_paths['anat']['freesurfer_dir'], + outfile) + if os.path.exists(fullpath): + fs_ingress = create_general_datasource(f'gather_fs_{key}_dir') + fs_ingress.inputs.inputnode.set( + unique_id=unique_id, + data=fullpath, + creds_path=data_paths['creds_path'], + dl_dir=cfg.pipeline_setup['working_directory']['path']) + rpool.set_data(key, fs_ingress, 'outputspec.data', + {}, "", f"fs_{key}_ingress") + return rpool @@ -1608,9 +1844,9 @@ def ingress_output_dir(cfg, rpool, unique_id, creds_path=None): print(f"\nOutput directory {out_dir} does not exist yet, " f"initializing.") return rpool - - cpac_dir = os.path.join(out_dir, - f'cpac_{cfg.pipeline_setup["pipeline_name"]}', + + cpac_dir = os.path.join(out_dir, 'pipeline_' + f'{cfg.pipeline_setup["pipeline_name"]}', unique_id) else: if os.path.isdir(out_dir): @@ -1775,11 +2011,10 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): if not val: continue - + if resolution: res_keys = [x.lstrip() for x in resolution.split(',')] tag = res_keys[-1] - json_info = {} if '$FSLDIR' in val: @@ -1793,11 +2028,15 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): if '${resolution_for_anat}' in val: val = val.replace('${resolution_for_anat}', cfg.registration_workflows['anatomical_registration']['resolution_for_anat']) if '${func_resolution}' in val: - val = val.replace('func_resolution', tag) + val = val.replace('${func_resolution}', cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'output_resolution'][tag]) if desc: - json_info['Description'] = f"{desc} - {val}" - + template_name, _template_desc = lookup_identifier(val) + if template_name: + desc = f"{template_name} - {desc}" + json_info['Description'] = f"{desc} - {val}" if resolution: resolution = cfg.get_nested(cfg, res_keys) json_info['Resolution'] = resolution @@ -1836,9 +2075,9 @@ def ingress_pipeconfig_paths(cfg, rpool, unique_id, creds_path=None): creds_path=creds_path, dl_dir=cfg.pipeline_setup['working_directory']['path'] ) - rpool.set_data(key, config_ingress, 'outputspec.data', json_info, - "", f"{key}_config_ingress") - + rpool.set_data(key, config_ingress, 'outputspec.data', + json_info, "", f"{key}_config_ingress") + # templates, resampling from config ''' template_keys = [ @@ -1984,7 +2223,7 @@ def initiate_rpool(wf, cfg, data_paths=None, part_id=None): def run_node_blocks(blocks, data_paths, cfg=None): import os from CPAC.pipeline import nipype_pipeline_engine as pe - from CPAC.utils.strategy import NodeBlock + from CPAC.pipeline.engine import NodeBlock if not cfg: cfg = { @@ -1999,7 +2238,7 @@ def run_node_blocks(blocks, data_paths, cfg=None): } # TODO: WE HAVE TO PARSE OVER UNIQUE ID'S!!! - rpool = initiate_rpool(cfg, data_paths) + _, rpool = initiate_rpool(cfg, data_paths) wf = pe.Workflow(name='node_blocks') wf.base_dir = cfg.pipeline_setup['working_directory']['path'] @@ -2019,7 +2258,9 @@ def run_node_blocks(blocks, data_paths, cfg=None): run_blocks += blocks[1] for block in run_blocks: - wf = NodeBlock(block).connect_block(wf, cfg, rpool) + wf = NodeBlock(block, debug=cfg['pipeline_setup', 'Debugging', + 'verbose']).connect_block( + wf, cfg, rpool) rpool.gather_pipes(wf, cfg) wf.run() diff --git a/CPAC/pipeline/nipype_pipeline_engine/__init__.py b/CPAC/pipeline/nipype_pipeline_engine/__init__.py index 48b445241b..fc346b5068 100755 --- a/CPAC/pipeline/nipype_pipeline_engine/__init__.py +++ b/CPAC/pipeline/nipype_pipeline_engine/__init__.py @@ -1,35 +1,34 @@ -'''Module to import Nipype Pipeline engine and override some Classes. -See https://fcp-indi.github.io/docs/developer/nodes -for C-PAC-specific documentation. -See https://nipype.readthedocs.io/en/latest/api/generated/nipype.pipeline.engine.html -for Nipype's documentation. - -Copyright (C) 2022 C-PAC Developers +# Copyright (C) 2022 C-PAC Developers -This file is part of C-PAC. +# This file is part of C-PAC. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .''' # noqa: E501 +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +'''Module to import Nipype Pipeline engine and override some Classes. +See https://fcp-indi.github.io/docs/developer/nodes +for C-PAC-specific documentation. +See https://nipype.readthedocs.io/en/latest/api/generated/nipype.pipeline.engine.html +for Nipype's documentation.''' # noqa: E501 # pylint: disable=line-too-long from nipype.pipeline import engine as pe # import everything in nipype.pipeline.engine.__all__ from nipype.pipeline.engine import * # noqa: F401,F403 # import our DEFAULT_MEM_GB and override Node, MapNode -from .engine import DEFAULT_MEM_GB, get_data_size, Node, MapNode, \ - UNDEFINED_SIZE, Workflow +from .engine import DEFAULT_MEM_GB, export_graph, get_data_size, Node, \ + MapNode, UNDEFINED_SIZE, Workflow __all__ = [ interface for interface in dir(pe) if not interface.startswith('_') -] + ['DEFAULT_MEM_GB', 'get_data_size', 'Node', 'MapNode', 'UNDEFINED_SIZE', - 'Workflow'] +] + ['DEFAULT_MEM_GB', 'export_graph', 'get_data_size', 'Node', 'MapNode', + 'UNDEFINED_SIZE', 'Workflow'] del pe diff --git a/CPAC/pipeline/nipype_pipeline_engine/engine.py b/CPAC/pipeline/nipype_pipeline_engine/engine.py index 12e8808f1f..899f69bbcf 100755 --- a/CPAC/pipeline/nipype_pipeline_engine/engine.py +++ b/CPAC/pipeline/nipype_pipeline_engine/engine.py @@ -1,58 +1,80 @@ -'''Module to import Nipype Pipeline engine and override some Classes. -See https://fcp-indi.github.io/docs/developer/nodes -for C-PAC-specific documentation. -See https://nipype.readthedocs.io/en/latest/api/generated/nipype.pipeline.engine.html -for Nipype's documentation. +# STATEMENT OF CHANGES: +# This file is derived from sources licensed under the Apache-2.0 terms, +# and this file has been changed. + +# CHANGES: +# * Supports just-in-time dynamic memory allocation +# * Skips doctests that require files that we haven't copied over +# * Applies a random seed +# * Supports overriding memory estimates via a log file and a buffer +# * Adds quotation marks around strings in dotfiles -STATEMENT OF CHANGES: - This file is derived from sources licensed under the Apache-2.0 terms, - and this file has been changed. +# ORIGINAL WORK'S ATTRIBUTION NOTICE: +# Copyright (c) 2009-2016, Nipype developers -CHANGES: - * Supports just-in-time dynamic memory allocation - * Skips doctests that require files that we haven't copied over - * Applies a random seed - * Supports overriding memory estimates via a log file and a buffer +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at -ORIGINAL WORK'S ATTRIBUTION NOTICE: - Copyright (c) 2009-2016, Nipype developers +# http://www.apache.org/licenses/LICENSE-2.0 - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. - http://www.apache.org/licenses/LICENSE-2.0 +# Prior to release 0.12, Nipype was licensed under a BSD license. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +# Modifications Copyright (C) 2022-2023 C-PAC Developers - Prior to release 0.12, Nipype was licensed under a BSD license. +# This file is part of C-PAC. -Modifications Copyright (C) 2022 C-PAC Developers +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -This file is part of C-PAC.''' # noqa: E501 +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +'''Module to import Nipype Pipeline engine and override some Classes. +See https://fcp-indi.github.io/docs/developer/nodes +for C-PAC-specific documentation. +See https://nipype.readthedocs.io/en/latest/api/generated/nipype.pipeline.engine.html +for Nipype's documentation.''' # noqa: E501 # pylint: disable=line-too-long import os import re -from logging import getLogger +from copy import deepcopy from inspect import Parameter, Signature, signature from nibabel import load -from nipype import logging from nipype.interfaces.utility import Function from nipype.pipeline import engine as pe -from nipype.pipeline.engine.utils import load_resultfile as _load_resultfile +from nipype.pipeline.engine.utils import ( + _create_dot_graph, + format_dot, + generate_expanded_graph, + get_print_name, + load_resultfile as _load_resultfile, + _replacefunk, + _run_dot +) +from nipype.utils.filemanip import fname_presuffix from nipype.utils.functions import getsource from numpy import prod from traits.trait_base import Undefined from traits.trait_handlers import TraitListObject +from CPAC.utils.monitoring.custom_logging import getLogger # set global default mem_gb DEFAULT_MEM_GB = 2.0 UNDEFINED_SIZE = (42, 42, 42, 1200) -random_state_logger = getLogger('random') +logger = getLogger("nipype.workflow") def _check_mem_x_path(mem_x_path): @@ -135,7 +157,7 @@ def __init__(self, *args, mem_gb=DEFAULT_MEM_GB, **kwargs): # pylint: disable=import-outside-toplevel from CPAC.pipeline.random_state import random_seed super().__init__(*args, mem_gb=mem_gb, **kwargs) - self.logger = logging.getLogger("nipype.workflow") + self.logger = getLogger("nipype.workflow") self.seed = random_seed() self.seed_applied = False self.input_data_shape = Undefined @@ -399,10 +421,10 @@ def run(self, updatehash=False): if self.seed is not None: self._apply_random_seed() if self.seed_applied: - random_state_logger.info('%s', - '%s # (Atropos constant)' % - self.name if 'atropos' in - self.name else self.name) + random_state_logger = getLogger('random') + random_state_logger.info('%s\t%s', '# (Atropos constant)' if + 'atropos' in self.name else + str(self.seed), self.name) return super().run(updatehash) @@ -415,6 +437,8 @@ class MapNode(Node, pe.MapNode): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + if not self.name.endswith('_'): + self.name = f'{self.name}_' __init__.__signature__ = Signature(parameters=[ p[1] if p[0] != 'mem_gb' else ( @@ -483,6 +507,119 @@ def _configure_exec_nodes(self, graph): TypeError): self._handle_just_in_time_exception(node) + def _get_dot( + self, prefix=None, hierarchy=None, colored=False, simple_form=True, + level=0 + ): + """Create a dot file with connection info""" + # pylint: disable=invalid-name,protected-access + import networkx as nx + + if prefix is None: + prefix = " " + if hierarchy is None: + hierarchy = [] + colorset = [ + "#FFFFC8", # Y + "#0000FF", + "#B4B4FF", + "#E6E6FF", # B + "#FF0000", + "#FFB4B4", + "#FFE6E6", # R + "#00A300", + "#B4FFB4", + "#E6FFE6", # G + "#0000FF", + "#B4B4FF", + ] # loop B + if level > len(colorset) - 2: + level = 3 # Loop back to blue + quoted_prefix = f'"{prefix}"' if len(prefix.strip()) else prefix + dotlist = [f'{quoted_prefix}label="{self.name}";'] + for node in nx.topological_sort(self._graph): + fullname = ".".join(hierarchy + [node.fullname]) + nodename = fullname.replace(".", "_") + if not isinstance(node, Workflow): + node_class_name = get_print_name(node, simple_form=simple_form) + if not simple_form: + node_class_name = ".".join(node_class_name.split(".")[1:]) + if hasattr(node, "iterables") and node.iterables: + dotlist.append(f'"{nodename}"[label="{node_class_name}", ' + "shape=box3d, style=filled, color=black, " + "colorscheme=greys7 fillcolor=2];") + else: + if colored: + dotlist.append(f'"{nodename}"[label="' + f'{node_class_name}", style=filled,' + f' fillcolor="{colorset[level]}"];') + else: + dotlist.append(f'"{nodename}"[label="' + f'{node_class_name}"];') + + for node in nx.topological_sort(self._graph): + if isinstance(node, Workflow): + fullname = ".".join(hierarchy + [node.fullname]) + nodename = fullname.replace(".", "_") + dotlist.append(f"subgraph \"cluster_{nodename}\" {{") + if colored: + dotlist.append(f'{prefix}{prefix}edge [color="' + f'{colorset[level + 1]}"];') + dotlist.append(f"{prefix}{prefix}style=filled;") + dotlist.append(f'{prefix}{prefix}fillcolor=' + f'"{colorset[level + 2]}";') + dotlist.append( + node._get_dot( + prefix=prefix + prefix, + hierarchy=hierarchy + [self.name], + colored=colored, + simple_form=simple_form, + level=level + 3, + ) + ) + dotlist.append("}") + else: + for subnode in self._graph.successors(node): + if node._hierarchy != subnode._hierarchy: + continue + if not isinstance(subnode, Workflow): + nodefullname = ".".join(hierarchy + [node.fullname]) + subnodefullname = ".".join( + hierarchy + [subnode.fullname]) + nodename = nodefullname.replace(".", "_") + subnodename = subnodefullname.replace(".", "_") + for _ in self._graph.get_edge_data( + node, subnode + )["connect"]: + dotlist.append(f'"{nodename}" -> "{subnodename}";') + logger.debug("connection: %s", dotlist[-1]) + # add between workflow connections + for u, v, d in self._graph.edges(data=True): + uname = ".".join(hierarchy + [u.fullname]) + vname = ".".join(hierarchy + [v.fullname]) + for src, dest in d["connect"]: + uname1 = uname + vname1 = vname + if isinstance(src, tuple): + srcname = src[0] + else: + srcname = src + if "." in srcname: + uname1 += "." + ".".join(srcname.split(".")[:-1]) + if "." in dest and "@" not in dest: + if not isinstance(v, Workflow): + if "datasink" not in str( + v._interface.__class__ + ).lower(): + vname1 += "." + ".".join(dest.split(".")[:-1]) + else: + vname1 += "." + ".".join(dest.split(".")[:-1]) + if uname1.split(".")[:-1] != vname1.split(".")[:-1]: + dotlist.append(f'"{uname1.replace(".", "_")}" -> ' + f'"{vname1.replace(".", "_")}";') + logger.debug("cross connection: %s", dotlist[-1]) + return ("\n" + prefix).join(dotlist) + def _handle_just_in_time_exception(self, node): # pylint: disable=protected-access if hasattr(self, '_local_func_scans'): @@ -492,6 +629,75 @@ def _handle_just_in_time_exception(self, node): # TODO: handle S3 files node._apply_mem_x(UNDEFINED_SIZE) # noqa: W0212 + def write_graph( + self, + dotfilename="graph.dot", + graph2use="hierarchical", + format="png", + simple_form=True, + ): + graphtypes = ["orig", "flat", "hierarchical", "exec", "colored"] + if graph2use not in graphtypes: + raise ValueError( + "Unknown graph2use keyword. Must be one of: " + str(graphtypes) + ) + base_dir, dotfilename = os.path.split(dotfilename) + if base_dir == "": + if self.base_dir: + base_dir = self.base_dir + if self.name: + base_dir = os.path.join(base_dir, self.name) + else: + base_dir = os.getcwd() + os.makedirs(base_dir, exist_ok=True) + if graph2use in ["hierarchical", "colored"]: + if self.name[:1].isdigit(): # these graphs break if int + raise ValueError(f"{graph2use} graph failed, workflow name " + "cannot begin with a number") + dotfilename = os.path.join(base_dir, dotfilename) + self.write_hierarchical_dotfile( + dotfilename=dotfilename, + colored=graph2use == "colored", + simple_form=simple_form, + ) + outfname = format_dot(dotfilename, format=format) + else: + graph = self._graph + if graph2use in ["flat", "exec"]: + graph = self._create_flat_graph() + if graph2use == "exec": + graph = generate_expanded_graph(deepcopy(graph)) + outfname = export_graph( + graph, + base_dir, + dotfilename=dotfilename, + format=format, + simple_form=simple_form, + ) + + logger.info("Generated workflow graph: %s " + "(graph2use=%s, simple_form=%s).", + outfname, graph2use, simple_form) + return outfname + + write_graph.__doc__ = pe.Workflow.write_graph.__doc__ + + def write_hierarchical_dotfile( + self, dotfilename=None, colored=False, simple_form=True + ): + # pylint: disable=invalid-name + dotlist = [f"digraph \"{self.name}\"{{"] + dotlist.append(self._get_dot(prefix=" ", colored=colored, + simple_form=simple_form)) + dotlist.append("}") + dotstr = "\n".join(dotlist) + if dotfilename: + with open(dotfilename, "wt", encoding="utf-8") as fp: + fp.writelines(dotstr) + fp.close() + else: + logger.info(dotstr) + def get_data_size(filepath, mode='xyzt'): """Function to return the size of a functional image (x * y * z * t) @@ -527,3 +733,140 @@ def get_data_size(filepath, mode='xyzt'): if mode == 'xyz': return prod(data_shape[0:3]).item() return prod(data_shape).item() + + +def export_graph( + graph_in, + base_dir=None, + show=False, + use_execgraph=False, + show_connectinfo=False, + dotfilename="graph.dot", + format="png", + simple_form=True, +): + """Displays the graph layout of the pipeline + This function requires that pygraphviz and matplotlib are available on + the system. + Parameters + ---------- + show : boolean + Indicate whether to generate pygraphviz output fromn + networkx. default [False] + use_execgraph : boolean + Indicates whether to use the specification graph or the + execution graph. default [False] + show_connectioninfo : boolean + Indicates whether to show the edge data on the graph. This + makes the graph rather cluttered. default [False] + """ + import networkx as nx + + graph = deepcopy(graph_in) + if use_execgraph: + graph = generate_expanded_graph(graph) + logger.debug("using execgraph") + else: + logger.debug("using input graph") + if base_dir is None: + base_dir = os.getcwd() + + os.makedirs(base_dir, exist_ok=True) + out_dot = fname_presuffix(dotfilename, suffix="_detailed.dot", + use_ext=False, newpath=base_dir) + _write_detailed_dot(graph, out_dot) + + # Convert .dot if format != 'dot' + outfname, res = _run_dot(out_dot, format_ext=format) + if res is not None and res.runtime.returncode: + logger.warning("dot2png: %s", res.runtime.stderr) + + pklgraph = _create_dot_graph(graph, show_connectinfo, simple_form) + simple_dot = fname_presuffix(dotfilename, suffix=".dot", use_ext=False, + newpath=base_dir) + nx.drawing.nx_pydot.write_dot(pklgraph, simple_dot) + + # Convert .dot if format != 'dot' + simplefname, res = _run_dot(simple_dot, format_ext=format) + if res is not None and res.runtime.returncode: + logger.warning("dot2png: %s", res.runtime.stderr) + + if show: + pos = nx.graphviz_layout(pklgraph, prog="dot") + nx.draw(pklgraph, pos) + if show_connectinfo: + nx.draw_networkx_edge_labels(pklgraph, pos) + + return simplefname if simple_form else outfname + + +def _write_detailed_dot(graph, dotfilename): + r""" + Create a dot file with connection info :: + digraph structs { + node [shape=record]; + struct1 [label=" left| middle| right"]; + struct2 [label=" one| two"]; + struct3 [label="hello\nworld |{ b |{c| d|e}| f}| g | h"]; + struct1:f1 -> struct2:f0; + struct1:f0 -> struct2:f1; + struct1:f2 -> struct3:here; + } + """ + # pylint: disable=invalid-name + import networkx as nx + + text = ["digraph structs {", "node [shape=record];"] + # write nodes + edges = [] + for n in nx.topological_sort(graph): + nodename = n.itername + inports = [] + for u, v, d in graph.in_edges(nbunch=n, data=True): + for cd in d["connect"]: + if isinstance(cd[0], (str, bytes)): + outport = cd[0] + else: + outport = cd[0][0] + inport = cd[1] + ipstrip = f"in{_replacefunk(inport)}" + opstrip = f"out{_replacefunk(outport)}" + edges.append(f'"{u.itername.replace(".", "")}":' + f'"{opstrip}":e -> ' + f'"{v.itername.replace(".", "")}":' + f'"{ipstrip}":w;') + if inport not in inports: + inports.append(inport) + inputstr = (["{IN"] + + [f"| {ip}" for + ip in sorted(inports)] + ["}"]) + outports = [] + for u, v, d in graph.out_edges(nbunch=n, data=True): + for cd in d["connect"]: + if isinstance(cd[0], (str, bytes)): + outport = cd[0] + else: + outport = cd[0][0] + if outport not in outports: + outports.append(outport) + outputstr = ( + ["{OUT"] + + [f"| {oport}" for + oport in sorted(outports)] + ["}"]) + srcpackage = "" + if hasattr(n, "_interface"): + pkglist = n.interface.__class__.__module__.split(".") + if len(pkglist) > 2: + srcpackage = pkglist[2] + srchierarchy = ".".join(nodename.split(".")[1:-1]) + nodenamestr = (f"{{ {nodename.split('.')[-1]} | {srcpackage} | " + f"{srchierarchy} }}") + text += [f'"{nodename.replace(".", "")}" [label=' + f'"{"".join(inputstr)}|{nodenamestr}|{"".join(outputstr)}"];'] + # write edges + for edge in sorted(edges): + text.append(edge) + text.append("}") + with open(dotfilename, "wt", encoding="utf-8") as filep: + filep.write("\n".join(text)) + return text diff --git a/CPAC/pipeline/random_state/seed.py b/CPAC/pipeline/random_state/seed.py index 370a9427dd..8a2591b7d7 100755 --- a/CPAC/pipeline/random_state/seed.py +++ b/CPAC/pipeline/random_state/seed.py @@ -1,7 +1,22 @@ +# Copyright (C) 2022-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . '''Functions to set, check, and log random seed''' import os import random -from logging import getLogger import numpy as np from nipype.interfaces.ants.registration import Registration @@ -10,9 +25,8 @@ from nipype.interfaces.fsl.maths import MathsCommand from nipype.interfaces.fsl.utils import ImageMaths -from CPAC.registration.utils import hardcoded_reg from CPAC.utils.interfaces.ants import AI -from CPAC.utils.monitoring.custom_logging import set_up_logger +from CPAC.utils.monitoring.custom_logging import getLogger, set_up_logger _seed = {'seed': None} @@ -92,6 +106,7 @@ def random_seed_flags(): ... 'functions', 'interfaces']]) True ''' + from CPAC.registration.utils import hardcoded_reg seed = random_seed() if seed is None: return {'functions': {}, 'interfaces': {}} @@ -121,7 +136,7 @@ def random_seed_flags(): [f'--use-random-seed{one}', f'-r{one}']]), # FreeSurfer ReconAll: ['-norandomness', f'-rng-seed {seed}'], - ApplyVolTransform: _reusable_flags()['FSL'], + ApplyVolTransform: [f'--seed {seed}'], # FSL ImageMaths: _reusable_flags()['FSL'], MathsCommand: _reusable_flags()['FSL'] @@ -166,16 +181,15 @@ def set_up_random_state(seed): if seed is not None: if seed == 'random': seed = random_random_seed() - if (seed != 'random' and not ( - isinstance(seed, int) and - (0 < int(seed) <= np.iinfo(np.int32).max) - )): - raise ValueError('Valid random seeds are positive integers up to ' - f'2147483647, "random", or None, not {seed}') - try: - _seed['seed'] = int(seed) - except (TypeError, ValueError): - _seed['seed'] = seed + else: + try: + seed = int(seed) + assert 0 < seed <= np.iinfo(np.int32).max + except(ValueError, TypeError, AssertionError): + raise ValueError('Valid random seeds are positive integers up to ' + f'2147483647, "random", or None, not {seed}') + + _seed['seed'] = seed return random_seed() @@ -186,5 +200,5 @@ def set_up_random_state_logger(log_dir): ---------- log_dir : str ''' - set_up_logger('random', level='info', log_dir=log_dir) + set_up_logger('random', level='info', log_dir=log_dir, mock=True) getLogger('random').info('seed: %s', random_seed()) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 3ae7283541..23c9618f3a 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -1,32 +1,32 @@ -'''Validation schema for C-PAC pipeline configurations +# Copyright (C) 2022 C-PAC Developers -Copyright (C) 2022 C-PAC Developers +# This file is part of C-PAC. -This file is part of C-PAC. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .''' +"""Validation schema for C-PAC pipeline configurations""" # pylint: disable=too-many-lines +import re from itertools import chain, permutations - import numpy as np -from voluptuous import All, ALLOW_EXTRA, Any, In, Length, Match, Optional, \ - Range, Required, Schema -from voluptuous.validators import ExactSequence, Maybe - +from pathvalidate import sanitize_filename +from voluptuous import All, ALLOW_EXTRA, Any, Capitalize, Coerce, \ + ExclusiveInvalid, In, Length, Lower, Match, Maybe, \ + Optional, Range, Required, Schema, Title from CPAC import docs_prefix -from CPAC.utils.utils import delete_nested_value, lookup_nested_value, \ - set_nested_value +from CPAC.utils.datatypes import ListFromItem +from CPAC.utils.utils import YAML_BOOLS # 1 or more digits, optional decimal, 'e', optional '-', 1 or more digits scientific_notation_str_regex = r'^([0-9]+(\.[0-9]*)*(e)-{0,1}[0-9]+)*$' @@ -39,7 +39,35 @@ r'(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*$' Number = Any(float, int, All(str, Match(scientific_notation_str_regex))) -forkable = Any(bool, [bool]) + + +def str_to_bool1_1(x): # pylint: disable=invalid-name + '''Convert strings to Booleans for YAML1.1 syntax + + Ref https://yaml.org/type/bool.html + + Parameters + ---------- + x : any + + Returns + ------- + bool + ''' + if isinstance(x, str): + try: + x = float(x) + if x == 0: + return False + except ValueError: + pass + x = (True if str(x).lower() in YAML_BOOLS[True] else + False if str(x).lower() in YAML_BOOLS[False] else x) + return bool(x) + + +bool1_1 = All(str_to_bool1_1, bool) +forkable = All(Coerce(ListFromItem), [bool1_1], Length(max=2)) valid_options = { 'acpc': { 'target': ['brain', 'whole-head'] @@ -47,7 +75,7 @@ 'brain_extraction': { 'using': ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', - 'FreeSurfer-ABCD'] + 'FreeSurfer-ABCD', 'FreeSurfer-Brainmask'] }, 'centrality': { 'method_options': ['degree_centrality', 'eigenvector_centrality', @@ -75,7 +103,7 @@ 'Regressors': { 'CompCor': { 'degree': int, - 'erode_mask_mm': bool, + 'erode_mask_mm': bool1_1, 'summary': { 'method': str, 'components': int, @@ -86,18 +114,19 @@ 'extraction_resolution': int }, 'segmentation': { - 'erode_mask': bool, + 'erode_mask': bool1_1, 'extraction_resolution': Any( int, float, 'Functional', All(str, Match(resolution_regex)) ), - 'include_delayed': bool, - 'include_delayed_squared': bool, - 'include_squared': bool, + 'include_delayed': bool1_1, + 'include_delayed_squared': bool1_1, + 'include_squared': bool1_1, 'summary': Any( str, {'components': int, 'method': str} ), }, - } + }, + 'target_space': ['Native', 'Template'] } mutex = { # mutually exclusive booleans 'FSL-BET': { @@ -107,18 +136,18 @@ # the remaining keys: validators for FSL-BET 'rem': { 'frac': float, - 'mesh_boolean': bool, - 'outline': bool, + 'mesh_boolean': bool1_1, + 'outline': bool1_1, 'radius': int, - 'skull': bool, - 'threshold': bool, + 'skull': bool1_1, + 'threshold': bool1_1, 'vertical_gradient': Range(min=-1, max=1, min_included=False, max_included=False), 'functional_mean_thr': { - 'run': bool, + 'run': bool1_1, 'threshold_value': Maybe(int), }, - 'functional_mean_bias_correction': bool, + 'functional_mean_bias_correction': bool1_1, } } } @@ -139,7 +168,7 @@ }, 'smoothing-sigmas': All(str, Match(resolution_regex)), 'shrink-factors': All(str, Match(resolution_regex)), - 'use-histogram-matching': bool, + 'use-histogram-matching': bool1_1, 'updateFieldVarianceInVoxelSpace': Number, 'totalFieldVarianceInVoxelSpace': Number, 'winsorize-image-intensities': { @@ -165,20 +194,128 @@ 'SyN': ANTs_parameter_transforms, })], }, { - 'verbose': Any(bool, In({0, 1})), + 'verbose': Any(Coerce(int), In({0, 1})), }, { - 'float': Any(bool, In({0, 1})), + 'float': Any(Coerce(int), In({0, 1})), }, { 'masks': { - 'fixed_image_mask': bool, - 'moving_image_mask': bool, + 'fixed_image_mask': bool1_1, + 'moving_image_mask': bool1_1, }, }, dict # TODO: specify other valid ANTs parameters )] +motion_estimate_filter = Any({ # notch filter with breathing_rate_* set + Required('filter_type'): 'notch', + Required('filter_order'): int, + Required('breathing_rate_min'): Number, + 'breathing_rate_max': Number, + 'center_frequency': Maybe(Number), + 'filter_bandwidth': Maybe(Number), + 'lowpass_cutoff': Maybe(Number), + 'Name': Maybe(str) + }, { # notch filter with manual parameters set + Required('filter_type'): 'notch', + Required('filter_order'): int, + 'breathing_rate_min': None, + 'breathing_rate_max': None, + Required('center_frequency'): Number, + Required('filter_bandwidth'): Number, + 'lowpass_cutoff': Maybe(Number), + 'Name': Maybe(str) + }, { # lowpass filter with breathing_rate_min + Required('filter_type'): 'lowpass', + Required('filter_order'): int, + Required('breathing_rate_min'): Number, + 'breathing_rate_max': Maybe(Number), + 'center_frequency': Maybe(Number), + 'filter_bandwidth': Maybe(Number), + 'lowpass_cutoff': Maybe(Number), + 'Name': Maybe(str) + }, { # lowpass filter with lowpass_cutoff + Required('filter_type'): 'lowpass', + Required('filter_order'): int, + Required('breathing_rate_min', default=None): None, + 'breathing_rate_max': Maybe(Number), + 'center_frequency': Maybe(Number), + 'filter_bandwidth': Maybe(Number), + Required('lowpass_cutoff'): Number, + 'Name': Maybe(str)}, + msg='`motion_estimate_filter` configuration is invalid.\nSee ' + f'{docs_prefix}/user/' + 'func#motion-estimate-filter-valid-options for details.\n') +target_space = All(Coerce(ListFromItem), + [All(Title, In(valid_options['target_space']))]) + + +def name_motion_filter(mfilter, mfilters=None): + '''Given a motion filter, create a short string for the filename + + Parameters + ---------- + mfilter : dict + + mfliters : list or None + + Returns + ------- + str + + Examples + -------- + >>> name_motion_filter({'filter_type': 'notch', 'filter_order': 2, + ... 'center_frequency': 0.31, 'filter_bandwidth': 0.12}) + 'notch2fc0p31bw0p12' + >>> name_motion_filter({'filter_type': 'notch', 'filter_order': 4, + ... 'breathing_rate_min': 0.19, 'breathing_rate_max': 0.43}) + 'notch4fl0p19fu0p43' + >>> name_motion_filter({'filter_type': 'lowpass', 'filter_order': 4, + ... 'lowpass_cutoff': .0032}) + 'lowpass4fc0p0032' + >>> name_motion_filter({'filter_type': 'lowpass', 'filter_order': 2, + ... 'breathing_rate_min': 0.19}) + 'lowpass2fl0p19' + >>> name_motion_filter({'filter_type': 'lowpass', 'filter_order': 2, + ... 'breathing_rate_min': 0.19}, [{'Name': 'lowpass2fl0p19'}]) + 'lowpass2fl0p19dup1' + >>> name_motion_filter({'filter_type': 'lowpass', 'filter_order': 2, + ... 'breathing_rate_min': 0.19}, [{'Name': 'lowpass2fl0p19'}, + ... {'Name': 'lowpass2fl0p19dup1'}]) + 'lowpass2fl0p19dup2' + ''' + if mfilters is None: + mfilters = [] + if 'Name' in mfilter: + name = mfilter['Name'] + else: + if mfilter['filter_type'] == 'notch': + if mfilter.get('breathing_rate_min'): + range_str = (f'fl{mfilter["breathing_rate_min"]}' + f'fu{mfilter["breathing_rate_max"]}') + else: + range_str = (f'fc{mfilter["center_frequency"]}' + f'bw{mfilter["filter_bandwidth"]}') + else: + if mfilter.get('breathing_rate_min'): + range_str = f'fl{mfilter["breathing_rate_min"]}' + else: + range_str = f'fc{mfilter["lowpass_cutoff"]}' + range_str = range_str.replace('.', 'p') + name = f'{mfilter["filter_type"]}{mfilter["filter_order"]}{range_str}' + dupes = 'Name' not in mfilter and len([_ for _ in (_.get('Name', '') for + _ in mfilters) if + _.startswith(name)]) + if dupes: + dup = re.search('(?=[A-Za-z0-9]*)(dup[0-9]*)', name) + if dup: # Don't chain 'dup' suffixes + name = name.replace(dup.group(), f'dup{dupes}') + else: + name = f'{name}dup{dupes}' + return name def permutation_message(key, options): - '''Function to give a clean, human-readable error message for keys that accept permutation values + '''Function to give a clean, human-readable error message for keys + that accept permutation values Parameters ---------- @@ -203,197 +340,54 @@ def permutation_message(key, options): ''' -def _combine_labels(config_dict, list_to_combine, new_key): - ''' - Helper function to combine formerly separate keys into a - combined key. - - Parameters - ---------- - config_dict: dict - - key_sequence: iterable of lists or tuples - - new_key: list or tuple - - Returns - ------- - updated_config_dict: dict - ''' - new_value = [] - any_old_values = False - for _to_combine in list_to_combine: - try: - old_value = lookup_nested_value(config_dict, _to_combine) - except KeyError: - old_value = None - if old_value is not None: - any_old_values = True - if isinstance(old_value, (list, set, tuple)): - for value in old_value: - new_value.append(value) - else: - new_value.append(old_value) - config_dict = delete_nested_value(config_dict, _to_combine) - if any_old_values: - return set_nested_value(config_dict, new_key, new_value) - return config_dict - - -def _now_runswitch(config_dict, key_sequence): - ''' - Helper function to convert a formerly forkable value to a - runswitch. - - Parameters - ---------- - config_dict: dict - - key_sequence: list or tuple - - Returns - ------- - updated_config_dict: dict - ''' - try: - old_forkable = lookup_nested_value(config_dict, key_sequence) - except KeyError: - return config_dict - if isinstance(old_forkable, bool) or isinstance(old_forkable, list): - return set_nested_value( - config_dict, key_sequence, {'run': old_forkable}) - return config_dict - - -def _changes_1_8_0_to_1_8_1(config_dict): - ''' - Examples - -------- - Starting with 1.8.0 - >>> zero = {'anatomical_preproc': { - ... 'non_local_means_filtering': True, - ... 'n4_bias_field_correction': True - ... }, 'functional_preproc': { - ... 'motion_estimates_and_correction': { - ... 'calculate_motion_first': False - ... } - ... }, 'segmentation': { - ... 'tissue_segmentation': { - ... 'ANTs_Prior_Based': { - ... 'CSF_label': 0, - ... 'left_GM_label': 1, - ... 'right_GM_label': 2, - ... 'left_WM_label': 3, - ... 'right_WM_label': 4}}}} - >>> updated_apb = _changes_1_8_0_to_1_8_1(zero)[ - ... 'segmentation']['tissue_segmentation']['ANTs_Prior_Based'] - >>> updated_apb['CSF_label'] - [0] - >>> updated_apb['GM_label'] - [1, 2] - >>> updated_apb['WM_label'] - [3, 4] - - Starting with 1.8.1 - >>> one = {'anatomical_preproc': { - ... 'non_local_means_filtering': True, - ... 'n4_bias_field_correction': True - ... }, 'functional_preproc': { - ... 'motion_estimates_and_correction': { - ... 'calculate_motion_first': False - ... } - ... }, 'segmentation': { - ... 'tissue_segmentation': { - ... 'ANTs_Prior_Based': { - ... 'CSF_label': [0], - ... 'GM_label': [1, 2], - ... 'WM_label': [3, 4]}}}} - >>> updated_apb = _changes_1_8_0_to_1_8_1(one)[ - ... 'segmentation']['tissue_segmentation']['ANTs_Prior_Based'] - >>> updated_apb['CSF_label'] - [0] - >>> updated_apb['GM_label'] - [1, 2] - >>> updated_apb['WM_label'] - [3, 4] - ''' - for key_sequence in { - ('anatomical_preproc', 'non_local_means_filtering'), - ('anatomical_preproc', 'n4_bias_field_correction') - }: - config_dict = _now_runswitch(config_dict, key_sequence) - for combiners in { - (( - ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'CSF_label'), - ), ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'CSF_label')), - (( - ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'left_GM_label'), - ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'right_GM_label') - ), ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'GM_label')), - (( - ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'left_WM_label'), - ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'right_WM_label') - ), ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', - 'WM_label')) - }: - config_dict = _combine_labels(config_dict, *combiners) - try: - calculate_motion_first = lookup_nested_value( - config_dict, - ['functional_preproc', 'motion_estimates_and_correction', - 'calculate_motion_first'] - ) - except KeyError: - calculate_motion_first = None - if calculate_motion_first is not None: - del config_dict['functional_preproc'][ - 'motion_estimates_and_correction']['calculate_motion_first'] - config_dict = set_nested_value(config_dict, [ - 'functional_preproc', 'motion_estimates_and_correction', - 'motion_estimates', 'calculate_motion_first' - ], calculate_motion_first) - - return config_dict +def sanitize(filename): + '''Sanitize a filename and replace whitespaces with underscores''' + return re.sub(r'\s+', '_', sanitize_filename(filename)) latest_schema = Schema({ 'FROM': Maybe(str), 'pipeline_setup': { - 'pipeline_name': All(str, Length(min=1)), + 'pipeline_name': All(str, Length(min=1), sanitize), 'output_directory': { 'path': str, 'source_outputs_dir': Maybe(str), - 'pull_source_once': bool, - 'write_func_outputs': bool, - 'write_debugging_outputs': bool, + 'pull_source_once': bool1_1, + 'write_func_outputs': bool1_1, + 'write_debugging_outputs': bool1_1, 'output_tree': str, 'quality_control': { - 'generate_quality_control_images': bool, - 'generate_xcpqc_files': bool, + 'generate_quality_control_images': bool1_1, + 'generate_xcpqc_files': bool1_1, }, }, 'working_directory': { 'path': str, - 'remove_working_dir': bool, + 'remove_working_dir': bool1_1, }, 'log_directory': { - 'run_logging': bool, + 'run_logging': bool1_1, 'path': str, + 'graphviz': { + 'entire_workflow': { + 'generate': bool, + 'graph2use': Maybe(All(Coerce(ListFromItem), + [All(Lower, + In(('orig', 'hierarchical', 'flat', + 'exec', 'colored')))])), + 'format': Maybe(All(Coerce(ListFromItem), + [All(Lower, In(('png', 'svg')))])), + 'simple_form': Maybe(bool)}}, + 'save_workflow': Maybe(bool), }, 'crash_log_directory': { 'path': Maybe(str), }, 'system_config': { + 'fail_fast': bool1_1, 'FSLDIR': Maybe(str), 'on_grid': { - 'run': bool, + 'run': bool1_1, 'resource_manager': Maybe(str), 'SGE': { 'parallel_environment': Maybe(str), @@ -401,7 +395,7 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'maximum_memory_per_participant': Number, - 'raise_insufficient': bool, + 'raise_insufficient': bool1_1, 'max_cores_per_participant': int, 'num_ants_threads': int, 'num_OMP_threads': int, @@ -416,15 +410,15 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, 'Amazon-AWS': { 'aws_output_bucket_credentials': Maybe(str), - 's3_encryption': bool, + 's3_encryption': bool1_1, }, 'Debugging': { - 'verbose': bool, + 'verbose': bool1_1, }, }, 'anatomical_preproc': { - 'run': bool, - 'run_t2': bool, + 'run': bool1_1, + 'run_t2': bool1_1, 'non_local_means_filtering': { 'run': forkable, 'noise_model': Maybe(str), @@ -443,38 +437,39 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'BiasFieldSmoothingSigma': Maybe(int), },), ), + 'acpc_alignment': Required( # require 'T1w_brain_ACPC_template' and # 'T2w_brain_ACPC_template' if 'acpc_target' is 'brain' Any({ 'run': False, - 'run_before_preproc': Maybe(bool), + 'run_before_preproc': Maybe(bool1_1), 'brain_size': Maybe(int), 'FOV_crop': Maybe(In({'robustfov', 'flirt'})), 'acpc_target': Maybe(In(valid_options['acpc']['target'])), - 'align_brain_mask': Maybe(bool), + 'align_brain_mask': Maybe(bool1_1), 'T1w_ACPC_template': Maybe(str), 'T1w_brain_ACPC_template': Maybe(str), 'T2w_ACPC_template': Maybe(str), 'T2w_brain_ACPC_template': Maybe(str), }, { 'run': True, - 'run_before_preproc': bool, + 'run_before_preproc': bool1_1, 'brain_size': int, 'FOV_crop': In({'robustfov', 'flirt'}), 'acpc_target': valid_options['acpc']['target'][1], - 'align_brain_mask': Maybe(bool), + 'align_brain_mask': Maybe(bool1_1), 'T1w_ACPC_template': str, 'T1w_brain_ACPC_template': Maybe(str), 'T2w_ACPC_template': Maybe(str), 'T2w_brain_ACPC_template': Maybe(str), }, { 'run': True, - 'run_before_preproc': bool, + 'run_before_preproc': bool1_1, 'brain_size': int, 'FOV_crop': In({'robustfov', 'flirt'}), 'acpc_target': valid_options['acpc']['target'][0], - 'align_brain_mask': Maybe(bool), + 'align_brain_mask': Maybe(bool1_1), 'T1w_ACPC_template': str, 'T1w_brain_ACPC_template': str, 'T2w_ACPC_template': Maybe(str), @@ -485,30 +480,30 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'be populated if \'run\' is not set to Off', ), 'brain_extraction': { - 'run': bool, + 'run': bool1_1, 'using': [In(valid_options['brain_extraction']['using'])], 'AFNI-3dSkullStrip': { - 'mask_vol': bool, + 'mask_vol': bool1_1, 'shrink_factor': Number, - 'var_shrink_fac': bool, + 'var_shrink_fac': bool1_1, 'shrink_factor_bot_lim': Number, - 'avoid_vent': bool, + 'avoid_vent': bool1_1, 'n_iterations': int, - 'pushout': bool, - 'touchup': bool, + 'pushout': bool1_1, + 'touchup': bool1_1, 'fill_hole': int, 'NN_smooth': int, 'smooth_final': int, - 'avoid_eyes': bool, - 'use_edge': bool, + 'avoid_eyes': bool1_1, + 'use_edge': bool1_1, 'exp_frac': Number, - 'push_to_edge': bool, - 'use_skull': bool, + 'push_to_edge': bool1_1, + 'use_skull': bool1_1, 'perc_int': Number, 'max_inter_iter': int, 'fac': Number, 'blur_fwhm': Number, - 'monkey': bool, + 'monkey': bool1_1, }, 'FSL-FNIRT': { 'interpolation': In({ @@ -517,17 +512,17 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, 'FSL-BET': { 'frac': Number, - 'mask_boolean': bool, - 'mesh_boolean': bool, - 'outline': bool, - 'padding': bool, + 'mask_boolean': bool1_1, + 'mesh_boolean': bool1_1, + 'outline': bool1_1, + 'padding': bool1_1, 'radius': int, - 'reduce_bias': bool, - 'remove_eyes': bool, - 'robust': bool, - 'skull': bool, - 'surfaces': bool, - 'threshold': bool, + 'reduce_bias': bool1_1, + 'remove_eyes': bool1_1, + 'robust': bool1_1, + 'skull': bool1_1, + 'surfaces': bool1_1, + 'threshold': bool1_1, 'vertical_gradient': Range(min=-1, max=1) }, 'UNet': { @@ -544,7 +539,7 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'segmentation': { - 'run': bool, + 'run': bool1_1, 'tissue_segmentation': { 'using': [In( {'FSL-FAST', 'FreeSurfer', 'ANTs_Prior_Based', @@ -560,7 +555,7 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'use_priors': { - 'run': bool, + 'run': bool1_1, 'priors_path': Maybe(str), 'WM_path': Maybe(str), 'GM_path': Maybe(str), @@ -594,16 +589,16 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, 'registration_workflows': { 'anatomical_registration': { - 'run': bool, + 'run': bool1_1, 'resolution_for_anat': All(str, Match(resolution_regex)), 'T1w_brain_template': Maybe(str), 'T1w_template': Maybe(str), 'T1w_brain_template_mask': Maybe(str), - 'reg_with_skull': bool, + 'reg_with_skull': bool1_1, 'registration': { 'using': [In({'ANTS', 'FSL', 'FSL-linear'})], 'ANTs': { - 'use_lesion_mask': bool, + 'use_lesion_mask': bool1_1, 'T1_registration': Maybe(ANTs_parameters), 'interpolation': In({ 'Linear', 'BSpline', 'LanczosWindowedSinc' @@ -624,28 +619,28 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'overwrite_transform': { - 'run': bool, + 'run': bool1_1, 'using': In({'FSL'}), }, }, 'functional_registration': { 'coregistration': { - 'run': bool, + 'run': bool1_1, 'reference': In({'brain', 'restore-brain'}), 'interpolation': In({'trilinear', 'sinc', 'spline'}), 'using': str, 'input': str, - 'interpolation': str, 'cost': str, 'dof': int, 'arguments': Maybe(str), 'func_input_prep': { - 'reg_with_skull': bool, + 'reg_with_skull': bool1_1, 'input': [In({ - 'Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference' + 'Mean_Functional', 'Selected_Functional_Volume', + 'fmriprep_reference' })], 'Mean Functional': { - 'n4_correct_func': bool + 'n4_correct_func': bool1_1 }, 'Selected Functional Volume': { 'func_reg_input_volume': int @@ -660,7 +655,7 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'EPI_registration': { - 'run': bool, + 'run': bool1_1, 'using': [In({'ANTS', 'FSL', 'FSL-linear'})], 'EPI_template': Maybe(str), 'EPI_template_mask': Maybe(str), @@ -677,8 +672,8 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'func_registration_to_template': { - 'run': bool, - 'run_EPI': bool, + 'run': bool1_1, + 'run_EPI': bool1_1, 'output_resolution': { 'func_preproc_outputs': All( str, Match(resolution_regex)), @@ -709,20 +704,21 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'identity_matrix': Maybe(str), }, 'apply_transform': { - 'using': In({'default', 'single_step_resampling', 'abcd', - 'single_step_resampling_from_stc', 'dcan_nhp'}), + 'using': In({'default', 'abcd', 'dcan_nhp', + 'single_step_resampling_from_stc'}), }, }, }, }, 'surface_analysis': { 'freesurfer': { - 'run': bool, + 'run_reconall': bool1_1, 'reconall_args': Maybe(str), - 'freesurfer_dir': Maybe(str) + # 'generate_masks': bool1_1, + 'ingress_reconall': bool1_1, }, 'post_freesurfer': { - 'run': bool, + 'run': bool1_1, 'surf_atlas_dir': Maybe(str), 'gray_ordinates_dir': Maybe(str), 'gray_ordinates_res': Maybe(int), @@ -735,7 +731,7 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'longitudinal_template_generation': { - 'run': bool, + 'run': bool1_1, 'average_method': In({'median', 'mean', 'std'}), 'dof': In({12, 9, 7, 6}), 'interp': In({'trilinear', 'nearestneighbour', 'sinc', 'spline'}), @@ -746,17 +742,18 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'convergence_threshold': Number, }, 'functional_preproc': { - 'run': bool, + 'run': bool1_1, 'truncation': { 'start_tr': int, - 'stop_tr': Maybe(Any(int, 'End')) + 'stop_tr': Maybe(Any(int, All(Capitalize, 'End'))) }, 'scaling': { - 'run': bool, + 'run': bool1_1, 'scaling_factor': Number }, 'despiking': { - 'run': forkable + 'run': forkable, + 'space': In({'native', 'template'}) }, 'slice_timing_correction': { 'run': forkable, @@ -764,71 +761,26 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'tzero': Maybe(int), }, 'motion_estimates_and_correction': { - 'run': bool, + 'run': bool1_1, 'motion_estimates': { - 'calculate_motion_first': bool, - 'calculate_motion_after': bool, + 'calculate_motion_first': bool1_1, + 'calculate_motion_after': bool1_1, }, 'motion_correction': { 'using': [In({'3dvolreg', 'mcflirt'})], 'AFNI-3dvolreg': { - 'functional_volreg_twopass': bool, + 'functional_volreg_twopass': bool1_1, }, 'motion_correction_reference': [In({ - 'mean', 'median', 'selected_volume', 'fmriprep_reference'})], + 'mean', 'median', 'selected_volume', + 'fmriprep_reference'})], 'motion_correction_reference_volume': int, }, 'motion_estimate_filter': Required( - Any({ # no motion estimate filter - 'run': Maybe(Any( - ExactSequence([False]), ExactSequence([]), False)), - 'filter_type': Maybe(In({'notch', 'lowpass'})), - 'filter_order': Maybe(int), - 'breathing_rate_min': Maybe(Number), - 'breathing_rate_max': Maybe(Number), - 'center_frequency': Maybe(Number), - 'filter_bandwidth': Maybe(Number), - 'lowpass_cutoff': Maybe(Number), - }, { # notch filter with breathing_rate_* set - Required('run'): forkable, - Required('filter_type'): 'notch', - Required('filter_order'): int, - Required('breathing_rate_min'): Number, - 'breathing_rate_max': Number, - 'center_frequency': Maybe(Number), - 'filter_bandwidth': Maybe(Number), - 'lowpass_cutoff': Maybe(Number), - }, { # notch filter with manual parameters set - Required('run'): forkable, - Required('filter_type'): 'notch', - Required('filter_order'): int, - 'breathing_rate_min': None, - 'breathing_rate_max': None, - Required('center_frequency'): Number, - Required('filter_bandwidth'): Number, - 'lowpass_cutoff': Maybe(Number), - }, { # lowpass filter with breathing_rate_min - Required('run'): forkable, - Required('filter_type'): 'lowpass', - Required('filter_order'): int, - Required('breathing_rate_min'): Number, - 'breathing_rate_max': Maybe(Number), - 'center_frequency': Maybe(Number), - 'filter_bandwidth': Maybe(Number), - 'lowpass_cutoff': Maybe(Number), - }, { # lowpass filter with lowpass_cutoff - Required('run'): forkable, - Required('filter_type'): 'lowpass', - Required('filter_order'): int, - Required('breathing_rate_min', default=None): None, - 'breathing_rate_max': Maybe(Number), - 'center_frequency': Maybe(Number), - 'filter_bandwidth': Maybe(Number), - Required('lowpass_cutoff'): Number, - },), - msg='`motion_estimate_filter` configuration is invalid. See ' - f'{docs_prefix}/user/' - 'func#motion_estimate_filter_valid_options for details.\n', + Any({'run': forkable, + 'filters': [motion_estimate_filter]}, + {'run': All(forkable, [In([False], [])]), + 'filters': Maybe(list)}) ), }, 'distortion_correction': { @@ -879,7 +831,7 @@ def _changes_1_8_0_to_1_8_1(config_dict): # no mutually-exclusive options on [{ **mutex['FSL-BET']['rem'], - 'functional_mean_boolean': bool, + 'functional_mean_boolean': bool1_1, **{k: False for k in mutex['FSL-BET']['mutex']} }])) ), @@ -889,15 +841,15 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'brain_probseg': Maybe(str), }, 'Anatomical_Refined': { - 'anatomical_mask_dilation': Maybe(bool), + 'anatomical_mask_dilation': Maybe(bool1_1), }, - 'apply_func_mask_in_native_space': bool, + 'apply_func_mask_in_native_space': bool1_1, }, 'generate_func_mean': { - 'run': bool, + 'run': bool1_1, }, 'normalize_func': { - 'run': bool, + 'run': bool1_1, }, }, 'nuisance_corrections': { @@ -907,7 +859,9 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, '2-nuisance_regression': { 'run': forkable, - 'create_regressors': bool, + 'space': All(Coerce(ListFromItem), + [All(Lower, In({'native', 'template'}))]), + 'create_regressors': bool1_1, 'Regressors': Maybe([Schema({ 'Name': Required(str), 'Censor': { @@ -920,9 +874,9 @@ def _changes_1_8_0_to_1_8_1(config_dict): 'number_of_subsequent_trs_to_censor': Maybe(int), }, 'Motion': { - 'include_delayed': bool, - 'include_squared': bool, - 'include_delayed_squared': bool + 'include_delayed': bool1_1, + 'include_squared': bool1_1, + 'include_delayed_squared': bool1_1 }, 'aCompCor': valid_options['Regressors']['CompCor'], 'tCompCor': valid_options['Regressors']['CompCor'], @@ -948,25 +902,25 @@ def _changes_1_8_0_to_1_8_1(config_dict): In({'After', 'Before'})), 'regressor_masks': { 'erode_anatomical_brain_mask': { - 'run': bool, + 'run': bool1_1, 'brain_mask_erosion_prop': Maybe(Number), 'brain_mask_erosion_mm': Maybe(Number), 'brain_erosion_mm': Maybe(Number) }, 'erode_csf': { - 'run': bool, + 'run': bool1_1, 'csf_erosion_prop': Maybe(Number), 'csf_mask_erosion_mm': Maybe(Number), 'csf_erosion_mm': Maybe(Number), }, 'erode_wm': { - 'run': bool, + 'run': bool1_1, 'wm_erosion_prop': Maybe(Number), 'wm_mask_erosion_mm': Maybe(Number), 'wm_erosion_mm': Maybe(Number), }, 'erode_gm': { - 'run': bool, + 'run': bool1_1, 'gm_erosion_prop': Maybe(Number), 'gm_mask_erosion_mm': Maybe(Number), 'gm_erosion_mm': Maybe(Number), @@ -975,43 +929,49 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'amplitude_low_frequency_fluctuation': { - 'run': bool, + 'run': bool1_1, + 'target_space': target_space, 'highpass_cutoff': [float], 'lowpass_cutoff': [float], }, 'voxel_mirrored_homotopic_connectivity': { - 'run': bool, + 'run': bool1_1, 'symmetric_registration': { 'T1w_brain_template_symmetric': Maybe(str), + 'T1w_brain_template_symmetric_funcreg': Maybe(str), 'T1w_brain_template_symmetric_for_resample': Maybe(str), 'T1w_template_symmetric': Maybe(str), + 'T1w_template_symmetric_funcreg': Maybe(str), 'T1w_template_symmetric_for_resample': Maybe(str), 'dilated_symmetric_brain_mask': Maybe(str), 'dilated_symmetric_brain_mask_for_resample': Maybe(str), }, }, 'regional_homogeneity': { - 'run': bool, + 'run': bool1_1, + 'target_space': target_space, 'cluster_size': In({7, 19, 27}), }, 'post_processing': { 'spatial_smoothing': { + 'run': bool1_1, 'output': [In({'smoothed', 'nonsmoothed'})], 'smoothing_method': [In({'FSL', 'AFNI'})], 'fwhm': [int] }, 'z-scoring': { + 'run': bool1_1, 'output': [In({'z-scored', 'raw'})], }, }, 'timeseries_extraction': { - 'run': bool, - Optional('roi_paths_fully_specified'): bool, + 'run': bool1_1, + Optional('roi_paths_fully_specified'): bool1_1, 'tse_roi_paths': Optional( Maybe({ - str: In({', '.join([ - option for option in options - ]) for options in list(chain.from_iterable([list( + str: In({', '.join( + list(options) + ) for options in list(chain.from_iterable([list( permutations(valid_options['timeseries']['roi_paths'], number_of) ) for number_of in range(1, 6)]))}), @@ -1027,23 +987,23 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, 'surface_connectivity': {'run': bool}, 'seed_based_correlation_analysis': { - 'run': bool, - Optional('roi_paths_fully_specified'): bool, + 'run': bool1_1, + Optional('roi_paths_fully_specified'): bool1_1, 'sca_roi_paths': Optional( Maybe({ - str: In({', '.join([ - option for option in options - ]) for options in list(chain.from_iterable([list( + str: In({', '.join(list( + options + )) for options in list(chain.from_iterable([list( permutations(valid_options['sca']['roi_paths'], number_of) ) for number_of in range(1, 4)]))}) }), msg=permutation_message( 'sca_roi_paths', valid_options['sca']['roi_paths']) ), - 'norm_timeseries_for_DR': bool, + 'norm_timeseries_for_DR': bool1_1, }, 'network_centrality': { - 'run': bool, + 'run': bool1_1, 'memory_allocation': Number, 'template_specification_file': Maybe(str), 'degree_centrality': { @@ -1075,14 +1035,14 @@ def _changes_1_8_0_to_1_8_1(config_dict): }, }, 'PyPEER': { - 'run': bool, + 'run': bool1_1, 'eye_scan_names': Maybe(Any([str], [])), 'data_scan_names': Maybe(Any([str], [])), 'eye_mask_path': Maybe(str), 'stimulus_path': Maybe(str), 'minimal_nuisance_correction': { - 'peer_gsr': bool, - 'peer_scrub': bool, + 'peer_gsr': bool1_1, + 'peer_scrub': bool1_1, 'scrub_thresh': float, }, }, @@ -1090,7 +1050,62 @@ def _changes_1_8_0_to_1_8_1(config_dict): def schema(config_dict): - return latest_schema(_changes_1_8_0_to_1_8_1(config_dict)) + '''Validate a pipeline configuration against the latest validation schema + by first applying backwards-compatibility patches, then applying + Voluptuous validation, then handling complex configuration interaction + checks before returning validated config_dict. + + Parameters + ---------- + config_dict : dict + + Returns + ------- + dict + ''' + from CPAC.utils.utils import _changes_1_8_0_to_1_8_1 + partially_validated = latest_schema(_changes_1_8_0_to_1_8_1(config_dict)) + try: + if (partially_validated['registration_workflows'][ + 'functional_registration' + ]['func_registration_to_template']['apply_transform'][ + 'using' + ] == 'single_step_resampling_from_stc'): + or_else = ('or choose a different option for ' + '``registration_workflows: functional_registration: ' + 'func_registration_to_template: apply_transform: ' + 'using``') + if True in partially_validated['nuisance_corrections'][ + '2-nuisance_regression']['run'] and partially_validated[ + 'nuisance_corrections' + ]['2-nuisance_regression']['space'] != ['template']: + raise ExclusiveInvalid( + '``single_step_resampling_from_stc`` requires ' + 'template-space nuisance regression. Either set ' + '``nuisance_corrections: 2-nuisance_regression: space`` ' + f'to ``template`` {or_else}') + if any(registration != 'ANTS' for registration in + partially_validated['registration_workflows'][ + 'anatomical_registration']['registration']['using']): + raise ExclusiveInvalid( + '``single_step_resampling_from_stc`` requires ' + 'ANTS registration. Either set ' + '``registration_workflows: anatomical_registration: ' + f'registration: using`` to ``ANTS`` {or_else}') + except KeyError: + pass + try: + motion_filters = partially_validated['functional_preproc'][ + 'motion_estimates_and_correction']['motion_estimate_filter'] + if True in motion_filters['run']: + for motion_filter in motion_filters['filters']: + motion_filter['Name'] = name_motion_filter( + motion_filter, motion_filters['filters']) + else: + motion_filters['filters'] = [] + except KeyError: + pass + return partially_validated schema.schema = latest_schema.schema diff --git a/CPAC/pipeline/test/test_cpac_runner.py b/CPAC/pipeline/test/test_cpac_runner.py index 24ecb896ae..79510d824a 100755 --- a/CPAC/pipeline/test/test_cpac_runner.py +++ b/CPAC/pipeline/test/test_cpac_runner.py @@ -1,7 +1,7 @@ import os import pytest - +import pkg_resources as p from CPAC.pipeline.cpac_runner import run_T1w_longitudinal from CPAC.pipeline.cpac_pipeline import load_cpac_pipe_config from CPAC.utils.bids_utils import create_cpac_data_config @@ -23,7 +23,8 @@ def test_run_T1w_longitudinal(bids_dir, cfg, test_dir, part_id): run_T1w_longitudinal(sub_data_list, cfg) -cfg = "/code/default_pipeline.yml" +cfg = p.resource_filename("CPAC", os.path.join( + "resources", "configs", "pipeline_config_default.yml")) bids_dir = "/Users/steven.giavasis/data/neurodata_hnu" test_dir = "/test_dir" part_id = "0025427" diff --git a/CPAC/pipeline/test/test_engine.py b/CPAC/pipeline/test/test_engine.py index 2f13bd215e..3988a61f95 100755 --- a/CPAC/pipeline/test/test_engine.py +++ b/CPAC/pipeline/test/test_engine.py @@ -1,9 +1,13 @@ import os import pytest from CPAC.pipeline.cpac_pipeline import initialize_nipype_wf, \ - load_cpac_pipe_config, connect_pipeline, build_anat_preproc_stack, build_workflow -from CPAC.pipeline.engine import ResourcePool, ingress_raw_anat_data, ingress_raw_func_data, \ - ingress_pipeconfig_paths, initiate_rpool + load_cpac_pipe_config, \ + connect_pipeline, \ + build_anat_preproc_stack, \ + build_workflow +from CPAC.pipeline.engine import ResourcePool, ingress_raw_anat_data, \ + ingress_raw_func_data, \ + ingress_pipeconfig_paths, initiate_rpool from CPAC.utils.bids_utils import create_cpac_data_config @@ -149,7 +153,7 @@ def test_build_workflow(pipe_config, bids_dir, test_dir): rpool.gather_pipes(wf, cfg) wf.run() -# cfg = "/code/default_pipeline.yml" + # bids_dir = "/Users/steven.giavasis/data/HBN-SI_dataset/rawdata" # test_dir = "/test_dir" diff --git a/CPAC/pipeline/test/test_schema_validation.py b/CPAC/pipeline/test/test_schema_validation.py index 97f3946313..7f24ba057d 100755 --- a/CPAC/pipeline/test/test_schema_validation.py +++ b/CPAC/pipeline/test/test_schema_validation.py @@ -1,28 +1,68 @@ '''Tests for schema.py''' +from itertools import combinations import pytest - +from voluptuous.error import ExclusiveInvalid, Invalid from CPAC.utils.configuration import Configuration -from voluptuous.error import Invalid @pytest.mark.parametrize('run_value', [ - True, False, [True], [False], [True, False], [False, True], None, []]) + True, False, [True], [False], [True, False], [False, True]]) def test_motion_estimates_and_correction(run_value): '''Test that any truthy forkable option for 'run' throws the custom human-readable exception for an invalid motion_estimate_filter. ''' - d = { - 'FROM': 'default', - 'functional_preproc': {'motion_estimates_and_correction': { + # pylint: disable=invalid-name + d = {'FROM': 'default', + 'functional_preproc': {'motion_estimates_and_correction': { 'motion_estimate_filter': {'run': run_value, - 'filter_type': 'notch', - 'filter_order': 0, - 'breathing_rate_min': None, - 'breathing_rate_max': 101.5}}} - } + 'filters': [{ + 'filter_type': 'notch', + 'filter_order': 0, + 'breathing_rate_min': None, + 'breathing_rate_max': 101.5}]}}}} if bool(run_value) and run_value not in [[False], []]: with pytest.raises(Invalid) as e: Configuration(d) - assert "func#motion_estimate_filter_valid_options" in str(e.value) + assert "func#motion-estimate-filter-valid-options" in str(e.value) else: Configuration(d) + d = {'FROM': 'default', + 'functional_preproc': {'motion_estimates_and_correction': { + 'motion_estimate_filter': {'run': run_value, + 'filters': [{ + 'filter_type': 'notch', + 'filter_order': 4, + 'center_frequency': .31, + 'filter_bandwidth': .12}]}}}} + c = Configuration(d) + if c['functional_preproc', 'motion_estimates_and_correction', + 'motion_estimate_filter', 'filters']: + assert c['functional_preproc', 'motion_estimates_and_correction', + 'motion_estimate_filter', 'filters', 0, 'Name' + ] == 'notch4fc0p31bw0p12' + + +@pytest.mark.parametrize('registration_using', + [list(combo) for _ in [list(combinations( + ['ANTS', 'FSL', 'FSL-linear'], i)) for i in + range(1, 4)] for combo in _]) +def test_single_step_vs_registration(registration_using): + '''Test that single-step resampling requires ANTS registration''' + # pylint: disable=invalid-name + d = {'registration_workflows': {'anatomical_registration': { + 'registration': {'using': registration_using}}, + 'functional_registration': { + 'func_registration_to_template': {'apply_transform': { + 'using': 'single_step_resampling_from_stc'}}}}} + if registration_using == ['ANTS']: + Configuration(d) # validates without exception + else: + with pytest.raises(ExclusiveInvalid) as e: + Configuration(d) + assert "requires ANTS registration" in str(e.value) + + +def test_pipeline_name(): + '''Test that pipeline_name sucessfully sanitizes''' + c = Configuration({'pipeline_setup': {'pipeline_name': ':va:lid name'}}) + assert c['pipeline_setup', 'pipeline_name'] == 'valid_name' diff --git a/CPAC/pipeline/utils.py b/CPAC/pipeline/utils.py new file mode 100644 index 0000000000..cb2ec35df3 --- /dev/null +++ b/CPAC/pipeline/utils.py @@ -0,0 +1,90 @@ +# Copyright (C) 2021-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +"""C-PAC pipeline engine utilities""" +from typing import Union + + +def source_set(sources: Union[str, list, set]) -> set: + """Given a CpacProvenance, return a set of {resource}:{source} strings + + Parameters + ---------- + sources: str, list, or set + + Returns + ------- + set + + Examples + -------- + >>> source_set([[[['bold:func_ingress', + ... 'desc-preproc_bold:func_reorient', + ... 'desc-preproc_bold:func_truncate'], + ... ['TR:func_metadata_ingress'], + ... ['tpattern:func_metadata_ingress'], + ... 'desc-preproc_bold:func_slice_time'], + ... [['bold:func_ingress', + ... 'desc-preproc_bold:func_reorient', + ... 'desc-preproc_bold:func_truncate'], + ... ['bold:func_ingress', 'desc-reorient_bold:func_reorient'], + ... 'motion-basefile:get_motion_ref_fmriprep_reference'], + ... 'desc-preproc_bold:motion_correction_only_mcflirt'], + ... [[['bold:func_ingress', + ... 'desc-preproc_bold:func_reorient', + ... 'desc-preproc_bold:func_truncate'], + ... ['bold:func_ingress', 'desc-reorient_bold:func_reorient'], + ... 'motion-basefile:get_motion_ref_fmriprep_reference'], + ... [[['bold:func_ingress', + ... 'desc-preproc_bold:func_reorient', + ... 'desc-preproc_bold:func_truncate'], + ... ['TR:func_metadata_ingress'], + ... ['tpattern:func_metadata_ingress'], + ... 'desc-preproc_bold:func_slice_time'], + ... [['bold:func_ingress', + ... 'desc-preproc_bold:func_reorient', + ... 'desc-preproc_bold:func_truncate'], + ... ['bold:func_ingress', 'desc-reorient_bold:func_reorient'], + ... 'motion-basefile:get_motion_ref_fmriprep_reference'], + ... 'desc-preproc_bold:motion_correction_only_mcflirt'], + ... ['FSL-AFNI-bold-ref:template_resample'], + ... ['FSL-AFNI-brain-mask:template_resample'], + ... ['FSL-AFNI-brain-probseg:template_resample'], + ... 'space-bold_desc-brain_mask:bold_mask_fsl_afni'], + ... 'desc-preproc_bold:bold_masking']) == set({ + ... 'FSL-AFNI-bold-ref:template_resample', + ... 'FSL-AFNI-brain-mask:template_resample', + ... 'FSL-AFNI-brain-probseg:template_resample', + ... 'TR:func_metadata_ingress', + ... 'bold:func_ingress', + ... 'desc-preproc_bold:bold_masking', + ... 'desc-preproc_bold:func_reorient', + ... 'desc-preproc_bold:func_slice_time', + ... 'desc-preproc_bold:func_truncate', + ... 'desc-preproc_bold:motion_correction_only_mcflirt', + ... 'desc-reorient_bold:func_reorient', + ... 'motion-basefile:get_motion_ref_fmriprep_reference', + ... 'space-bold_desc-brain_mask:bold_mask_fsl_afni', + ... 'tpattern:func_metadata_ingress'}) + True + """ + _set = set() + if isinstance(sources, str): + _set.add(sources) + if isinstance(sources, (set, list)): + for item in sources: + _set.update(source_set(item)) + return _set diff --git a/CPAC/qc/pipeline.py b/CPAC/qc/pipeline.py index ad8c87cb93..6c2cc9bcab 100755 --- a/CPAC/qc/pipeline.py +++ b/CPAC/qc/pipeline.py @@ -38,23 +38,21 @@ def qc_snr_plot(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-brain_bold", "desc-motion_bold", "desc-preproc_bold"], + "inputs": [("desc-preproc_bold", "space-bold_desc-brain_mask"), "from-bold_to-T1w_mode-image_desc-linear_xfm", - "desc-brain_T1w", - "space-T1w_desc-mean_bold"], - "outputs": ["bold-snr-axial-qc", - "bold-snr-sagittal-qc", - "bold-snr-hist-qc", - "bold-snr-qc"]} + "desc-preproc_T1w", + "space-T1w_sbref"], + "outputs": ["desc-boldSnrAxial_quality", + "desc-boldSnrSagittal_quality", + "desc-boldSnrHist_quality", + "desc-boldSnr_quality"]} ''' # make SNR plot qc_workflow = create_qc_snr(f'qc_snr_{pipe_num}') - node, out = strat_pool.get_data(["desc-brain_bold", - "desc-motion_bold", - "desc-preproc_bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, qc_workflow, 'inputspec.functional_preprocessed') node, out = strat_pool.get_data("space-bold_desc-brain_mask") @@ -65,19 +63,20 @@ def qc_snr_plot(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, qc_workflow, 'inputspec.functional_to_anat_linear_xfm') - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, qc_workflow, 'inputspec.anatomical_brain') - node, out = strat_pool.get_data('space-T1w_desc-mean_bold') + node, out = strat_pool.get_data('space-T1w_sbref') wf.connect(node, out, qc_workflow, 'inputspec.mean_functional_in_anat') outputs = { - 'bold-snr-axial-qc': (qc_workflow, 'outputspec.snr_axial_image'), - 'bold-snr-sagittal-qc': + 'desc-boldSnrAxial_quality': (qc_workflow, + 'outputspec.snr_axial_image'), + 'desc-boldSnrSagittal_quality': (qc_workflow, 'outputspec.snr_sagittal_image'), - 'bold-snr-hist-qc': ( + 'desc-boldSnrHist_quality': ( qc_workflow, 'outputspec.snr_histogram_image'), - 'bold-snr-qc': (qc_workflow, 'outputspec.snr_mean') + 'desc-boldSnr_quality': (qc_workflow, 'outputspec.snr_mean') } return (wf, outputs) @@ -91,8 +90,8 @@ def qc_motion_plot(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": ["movement-parameters"], - "outputs": ["movement-parameters-trans-qc", - "movement-parameters-rot-qc"]} + "outputs": ["desc-movementParametersTrans_quality", + "desc-movementParametersRot_quality"]} ''' # make motion parameters plot @@ -102,9 +101,9 @@ def qc_motion_plot(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, qc_workflow, 'inputspec.motion_parameters') outputs = { - 'movement-parameters-trans-qc': ( + 'desc-movementParametersTrans_quality': ( qc_workflow, 'outputspec.motion_translation_plot'), - 'movement-parameters-rot-qc': ( + 'desc-movementParametersRot_quality': ( qc_workflow, 'outputspec.motion_rotation_plot') } @@ -119,7 +118,7 @@ def qc_fd_plot(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": ["framewise-displacement-jenkinson"], - "outputs": ["framewise-displacement-jenkinson-plot-qc"]} + "outputs": ["desc-framewiseDisplacementJenkinsonPlot_quality"]} ''' qc_workflow = create_qc_fd(f'qc_fd_{pipe_num}') @@ -128,7 +127,7 @@ def qc_fd_plot(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, qc_workflow, 'inputspec.fd') outputs = { - 'framewise-displacement-jenkinson-plot-qc': + 'desc-framewiseDisplacementJenkinsonPlot_quality': (qc_workflow, 'outputspec.fd_histogram_plot') } @@ -142,10 +141,10 @@ def qc_brain_extraction(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": ["desc-brain_T1w", - "desc-reorient_T1w"], - "outputs": ["desc-brain_T1w-axial-qc", - "desc-brain_T1w-sagittal-qc"]} + "inputs": ["desc-preproc_T1w", + "desc-head_T1w"], + "outputs": ["desc-brain_desc-T1wAxial_quality", + "desc-brain_desc-T1wSagittal_quality"]} ''' # make QC montages for Skull Stripping Visualization @@ -153,15 +152,16 @@ def qc_brain_extraction(wf, cfg, strat_pool, pipe_num, opt=None): f'qc_skullstrip_{pipe_num}' ) - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, qc_workflow, 'inputspec.anatomical_brain') - node, out = strat_pool.get_data('desc-reorient_T1w') + node, out = strat_pool.get_data('desc-head_T1w') wf.connect(node, out, qc_workflow, 'inputspec.anatomical_reorient') outputs = { - 'desc-brain_T1w-axial-qc': (qc_workflow, 'outputspec.axial_image'), - 'desc-brain_T1w-sagittal-qc': + 'desc-brain_desc-T1wAxial_quality': (qc_workflow, + 'outputspec.axial_image'), + 'desc-brain_desc-T1wSagittal_quality': (qc_workflow, 'outputspec.sagittal_image') } @@ -175,10 +175,10 @@ def qc_T1w_standard(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": ["space-template_desc-brain_T1w", + "inputs": ["space-template_desc-preproc_T1w", "T1w-brain-template"], - "outputs": ["space-template_desc-brain_T1w-axial-qc", - "space-template_desc-brain_T1w-sagittal-qc"]} + "outputs": ["space-template_desc-brain_desc-T1wAxial_quality", + "space-template_desc-brain_desc-T1wSagittal_quality"]} ''' # make QC montages for mni normalized anatomical image @@ -186,7 +186,7 @@ def qc_T1w_standard(wf, cfg, strat_pool, pipe_num, opt=None): 'red', 'mni_anat', mapnode=False) - node, out = strat_pool.get_data('space-template_desc-brain_T1w') + node, out = strat_pool.get_data('space-template_desc-preproc_T1w') wf.connect(node, out, montage_mni_anat, 'inputspec.underlay') anat_template_edge = pe.Node(Function(input_names=['in_file'], @@ -202,9 +202,9 @@ def qc_T1w_standard(wf, cfg, strat_pool, pipe_num, opt=None): montage_mni_anat, 'inputspec.overlay') outputs = { - 'space-template_desc-brain_T1w-axial-qc': + 'space-template_desc-brain_desc-T1wAxial_quality': (montage_mni_anat, 'outputspec.axial_png'), - 'space-template_desc-brain_T1w-sagittal-qc': + 'space-template_desc-brain_desc-T1wSagittal_quality': (montage_mni_anat, 'outputspec.sagittal_png') } @@ -218,22 +218,22 @@ def qc_segmentation(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": [("desc-brain_T1w", + "inputs": [("desc-preproc_T1w", ["label-CSF_desc-preproc_mask", "label-CSF_mask"], ["label-WM_desc-preproc_mask", "label-WM_mask"], ["label-GM_desc-preproc_mask", "label-GM_mask"])], - "outputs": ["dseg-axial-qc", - "dseg-sagittal-qc"]} + "outputs": ["desc-dsegAxial_quality", + "desc-dsegSagittal_quality"]} ''' # make QC montages for CSF WM GM montage_csf_gm_wm = create_montage_gm_wm_csf( f'montage_csf_gm_wm_{pipe_num}', 'montage_csf_gm_wm') - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, montage_csf_gm_wm, 'inputspec.underlay') node, out = strat_pool.get_data(['label-CSF_desc-preproc_mask', @@ -249,8 +249,9 @@ def qc_segmentation(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, montage_csf_gm_wm, 'inputspec.overlay_gm') outputs = { - 'dseg-axial-qc': (montage_csf_gm_wm, 'outputspec.axial_png'), - 'dseg-sagittal-qc': (montage_csf_gm_wm, 'outputspec.sagittal_png') + 'desc-dsegAxial_quality': (montage_csf_gm_wm, 'outputspec.axial_png'), + 'desc-dsegSagittal_quality': (montage_csf_gm_wm, + 'outputspec.sagittal_png') } return (wf, outputs) @@ -263,22 +264,22 @@ def qc_epi_segmentation(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": [("desc-brain_bold", + "inputs": [("desc-preproc_bold", ["space-bold_label-CSF_desc-preproc_mask", "space-bold_label-CSF_mask"], ["space-bold_label-WM_desc-preproc_mask", "space-bold_label-WM_mask"], ["space-bold_label-GM_desc-preproc_mask", "space-bold_label-GM_mask"])], - "outputs": ["epi-dseg-axial-qc", - "epi-dseg-sagittal-qc"]} + "outputs": ["epi-desc-dsegAxial_quality", + "epi-desc-dsegSagittal_quality"]} ''' # make QC montages for CSF WM GM montage_csf_gm_wm = create_montage_gm_wm_csf( f'montage_csf_gm_wm_{pipe_num}', 'montage_csf_gm_wm') - node, out = strat_pool.get_data('desc-brain_bold') + node, out = strat_pool.get_data('desc-preproc_bold') wf.connect(node, out, montage_csf_gm_wm, 'inputspec.underlay') node, out = strat_pool.get_data(['space-bold_label-CSF_desc-preproc_mask', @@ -294,8 +295,10 @@ def qc_epi_segmentation(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, montage_csf_gm_wm, 'inputspec.overlay_gm') outputs = { - 'epi-dseg-axial-qc': (montage_csf_gm_wm, 'outputspec.axial_png'), - 'epi-dseg-sagittal-qc': (montage_csf_gm_wm, 'outputspec.sagittal_png') + 'epi-desc-dsegAxial_quality': (montage_csf_gm_wm, + 'outputspec.axial_png'), + 'epi-desc-dsegSagittal_quality': (montage_csf_gm_wm, + 'outputspec.sagittal_png') } return (wf, outputs) @@ -308,33 +311,24 @@ def qc_carpet_plot(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": [(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", - "space-template_bold"], - "space-template_desc-mean_bold"), + "inputs": [("space-template_desc-preproc_bold", + "space-template_sbref"), "GM-path", "WM-path", "CSF-path"], - "outputs": ["space-template_desc-cleaned_bold-carpet-qc", - "space-template_desc-brain_bold-carpet-qc", - "space-template_desc-preproc_bold-carpet-qc", - "space-template_bold-carpet-qc"]} + "outputs": ["space-template_desc-preprocBoldCarpet_quality"]} ''' # make QC Carpet plot carpet_seg = create_qc_carpet(f'carpet_seg_{pipe_num}', 'carpet_seg') connection, resource = \ - strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", - "space-template_bold"], + strat_pool.get_data(["space-template_desc-preproc_bold"], report_fetched=True) node, out = connection wf.connect(node, out, carpet_seg, 'inputspec.functional_to_standard') - node, out = strat_pool.get_data("space-template_desc-mean_bold") + node, out = strat_pool.get_data("space-template_sbref") wf.connect(node, out, carpet_seg, 'inputspec.mean_functional_to_standard') node, out = strat_pool.get_data("GM-path") @@ -346,9 +340,8 @@ def qc_carpet_plot(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data("CSF-path") wf.connect(node, out, carpet_seg, 'inputspec.anatomical_csf_mask') - outputs = { - f'{resource}-carpet-qc': (carpet_seg, 'outputspec.carpet_plot'), - } + outputs = {'space-template_desc-preprocBoldCarpet_quality': ( + carpet_seg, 'outputspec.carpet_plot')} return (wf, outputs) @@ -360,10 +353,10 @@ def qc_coregistration(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["generate_quality_control_images"], "option_key": "None", "option_val": "None", - "inputs": [("desc-brain_T1w", - "space-T1w_desc-mean_bold")], - "outputs": ["space-T1w_desc-mean_bold-axial-qc", - "space-T1w_desc-mean_bold-sagittal-qc"]} + "inputs": [("desc-preproc_T1w", + "space-T1w_sbref")], + "outputs": ["space-T1w_desc-boldAxial_quality", + "space-T1w_desc-boldSagittal_quality"]} ''' # make QC montage for Mean Functional in T1 with T1 edge @@ -373,7 +366,7 @@ def qc_coregistration(wf, cfg, strat_pool, pipe_num, opt=None): as_module=True), name=f'anat_edge_{pipe_num}') - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_edge, 'in_file') montage_anat = create_montage(f'montage_anat_{pipe_num}', 'red', @@ -382,13 +375,13 @@ def qc_coregistration(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(anat_edge, 'out_file', montage_anat, 'inputspec.overlay') - node, out = strat_pool.get_data('space-T1w_desc-mean_bold') + node, out = strat_pool.get_data('space-T1w_sbref') wf.connect(node, out, montage_anat, 'inputspec.underlay') outputs = { - 'space-T1w_desc-mean_bold-axial-qc': + 'space-T1w_desc-boldAxial_quality': (montage_anat, 'outputspec.axial_png'), - 'space-T1w_desc-mean_bold-sagittal-qc': + 'space-T1w_desc-boldSagittal_quality': (montage_anat, 'outputspec.sagittal_png') } @@ -404,10 +397,10 @@ def qc_bold_registration(wf, cfg, strat_pool, pipe_num, opt=None): ["registration_workflows", "anatomical_registration", "run"]], "option_key": "None", "option_val": "None", - "inputs": ["space-template_desc-mean_bold", + "inputs": ["space-template_sbref", "T1w-brain-template-funcreg"], - "outputs": ["space-template_desc-mean_bold-axial-qc", - "space-template_desc-mean_bold-sagittal-qc"]} + "outputs": ["space-template_desc-boldAxial_quality", + "space-template_desc-boldSagittal_quality"]} ''' # make QC montage for Mean Functional in MNI with MNI edge @@ -415,7 +408,7 @@ def qc_bold_registration(wf, cfg, strat_pool, pipe_num, opt=None): 'MNI_edge_on_mean_func_mni', mapnode=False) - node, out = strat_pool.get_data('space-template_desc-mean_bold') + node, out = strat_pool.get_data('space-template_sbref') wf.connect(node, out, montage_mfi, 'inputspec.underlay') func_template_edge = pe.Node(Function(input_names=['in_file'], @@ -431,9 +424,9 @@ def qc_bold_registration(wf, cfg, strat_pool, pipe_num, opt=None): montage_mfi, 'inputspec.overlay') outputs = { - 'space-template_desc-mean_bold-axial-qc': + 'space-template_desc-boldAxial_quality': (montage_mfi, 'outputspec.axial_png'), - 'space-template_desc-mean_bold-sagittal-qc': + 'space-template_desc-boldSagittal_quality': (montage_mfi, 'outputspec.sagittal_png') } @@ -450,10 +443,11 @@ def qc_bold_EPI_registration(wf, cfg, strat_pool, pipe_num, opt=None): "func_registration_to_template", "run_EPI"]], "option_key": "None", "option_val": "None", - "inputs": ["space-EPItemplate_desc-mean_bold", + "inputs": [("space-template_sbref", + "from-bold_to-EPItemplate_mode-image_xfm"), "EPI-template-funcreg"], - "outputs": ["space-EPItemplate_desc-mean_bold-axial-qc", - "space-EPItemplate_desc-mean_bold-sagittal-qc"]} + "outputs": ["space-template_desc-mean_desc-boldAxial_quality", + "space-template_desc-mean_desc-boldSagittal_quality"]} ''' # make QC montage for Mean Functional in MNI with MNI edge @@ -461,7 +455,7 @@ def qc_bold_EPI_registration(wf, cfg, strat_pool, pipe_num, opt=None): 'EPI_MNI_edge_on_mean_func_mni', mapnode=False) - node, out = strat_pool.get_data('space-EPItemplate_desc-mean_bold') + node, out = strat_pool.get_data('space-template_sbref') wf.connect(node, out, montage_mfi, 'inputspec.underlay') func_template_edge = pe.Node(Function(input_names=['in_file'], @@ -477,9 +471,9 @@ def qc_bold_EPI_registration(wf, cfg, strat_pool, pipe_num, opt=None): montage_mfi, 'inputspec.overlay') outputs = { - 'space-EPItemplate_desc-mean_bold-axial-qc': + 'space-template_desc-boldAxial_quality': (montage_mfi, 'outputspec.axial_png'), - 'space-EPItemplate_desc-mean_bold-sagittal-qc': + 'space-template_desc-boldSagittal_quality': (montage_mfi, 'outputspec.sagittal_png') } diff --git a/CPAC/qc/tests/test_qc.py b/CPAC/qc/tests/test_qc.py index 9407da8004..0abf56132d 100755 --- a/CPAC/qc/tests/test_qc.py +++ b/CPAC/qc/tests/test_qc.py @@ -1,14 +1,13 @@ import os import pytest - +from nipype.interfaces import utility as util from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.utility as util - +from CPAC.pipeline.cpac_group_runner import gather_outputs from CPAC.qc.pipeline import create_qc_workflow from CPAC.qc.utils import generate_qc_pages -from CPAC.utils import Configuration, Strategy, Outputs - -from CPAC.pipeline.cpac_group_runner import gather_outputs +from CPAC.utils.configuration import Configuration +from CPAC.utils.outputs import Outputs +from CPAC.utils.strategy import Strategy def file_node(path): diff --git a/CPAC/qc/xcp.py b/CPAC/qc/xcp.py index 6083b249c1..96870d3135 100755 --- a/CPAC/qc/xcp.py +++ b/CPAC/qc/xcp.py @@ -1,56 +1,59 @@ -"""`Generate eXtensible Connectivity Pipeline-style quality control files `_ +""" +.. seealso:: + + `User Guide: Generate eXtensible Connectivity Pipeline-style quality control files `_ Columns ------- sub : str - subject label :cite:`cite-BIDS21` + subject label :footcite:`BIDS21` ses : str - session label :cite:`cite-BIDS21` + session label :footcite:`BIDS21` task : str - task label :cite:`cite-BIDS21` + task label :footcite:`BIDS21` run : int - run index :cite:`cite-BIDS21` + run index :footcite:`BIDS21` desc : str - description :cite:`cite-BIDS21` + description :footcite:`BIDS21` regressors : str 'Name' of regressors in the current fork space : str - space label :cite:`cite-BIDS21` + space label :footcite:`BIDS21` meanFD : float - mean Jenkinson framewise displacement :cite:`cite-Jenk02` :func:`CPAC.generate_motion_statistics.calculate_FD_J` after preprocessing + mean Jenkinson framewise displacement :footcite:`xcp_22,Jenk02` :func:`CPAC.generate_motion_statistics.calculate_FD_J` after preprocessing relMeansRMSMotion : float - "mean value of RMS motion" :cite:`cite-Ciri19` + "mean value of RMS motion" :footcite:`xcp_22,Ciri19` relMaxRMSMotion : float - "maximum vaue of RMS motion" :cite:`cite-Ciri19` + "maximum vaue of RMS motion" :footcite:`xcp_22,Ciri19` meanDVInit : float - "mean DVARS" :cite:`cite-Ciri19` + "mean DVARS" :footcite:`xcp_22,Ciri19` meanDVFinal : float - "mean DVARS" :cite:`cite-Ciri19` + "mean DVARS" :footcite:`xcp_22,Ciri19` nVolCensored : int - "total number of volume(s) censored :cite:`cite-Ciri19` + "total number of volume(s) censored :footcite:`Ciri19` nVolsRemoved : int number of volumes in derivative minus number of volumes in original functional scan motionDVCorrInit : float - "correlation of RMS and DVARS before regresion" :cite:`cite-Ciri19` + "correlation of RMS and DVARS before regresion" :footcite:`Ciri19` motionDVCorrFinal : float - "correlation of RMS and DVARS after regresion" :cite:`cite-Ciri19` + "correlation of RMS and DVARS after regresion" :footcite:`Ciri19` coregDice : float - "Coregsitration of Functional and T1w:[…] Dice index" :cite:`cite-Ciri19` + "Coregsitration of Functional and T1w:[…] Dice index" :footcite:`xcp_22,Ciri19` coregJaccard : float - "Coregsitration of Functional and T1w:[…] Jaccard index" :cite:`cite-Ciri19` + "Coregsitration of Functional and T1w:[…] Jaccard index" :footcite:`xcp_22,Ciri19` coregCrossCorr : float - "Coregsitration of Functional and T1w:[…] cross correlation" :cite:`cite-Ciri19` + "Coregsitration of Functional and T1w:[…] cross correlation" :footcite:`xcp_22,Ciri19` coregCoverag : float - "Coregsitration of Functional and T1w:[…] Coverage index" :cite:`cite-Ciri19` + "Coregsitration of Functional and T1w:[…] Coverage index" :footcite:`xcp_22,Ciri19` normDice : float - "Normalization of T1w/Functional to Template:[…] Dice index" :cite:`cite-Ciri19` + "Normalization of T1w/Functional to Template:[…] Dice index" :footcite:`xcp_22,Ciri19` normJaccard : float - "Normalization of T1w/Functional to Template:[…] Jaccard index" :cite:`cite-Ciri19` + "Normalization of T1w/Functional to Template:[…] Jaccard index" :footcite:`xcp_22,Ciri19` normCrossCorr : float - "Normalization of T1w/Functional to Template:[…] cross correlation" :cite:`cite-Ciri19` + "Normalization of T1w/Functional to Template:[…] cross correlation" :footcite:`xcp_22,Ciri19` normCoverage : float - "Normalization of T1w/Functional to Template:[…] Coverage index" :cite:`cite-Ciri19` + "Normalization of T1w/Functional to Template:[…] Coverage index" :footcite:`xcp_22,Ciri19` """ # noqa: E501 # pylint: disable=line-too-long import os import re @@ -339,7 +342,7 @@ def get_bids_info(subject, scan, wf_name): '1' >>> get_bids_info(subject='sub-colornest035', scan='rest_run-01', ... wf_name='cpac_sub-colornest035_ses-1') - ('colornest035', '1', 'rest', '1') + ('colornest035', '1', 'rest', '01') """ returns = ('subject', 'session', 'task', 'run') ses = wf_name.split('_')[-1] @@ -381,7 +384,7 @@ def qc_xcp(wf, cfg, strat_pool, pipe_num, opt=None): 'option_key': 'None', 'option_val': 'None', 'inputs': [('subject', 'scan', 'bold', 'desc-preproc_bold', - 'space-T1w_desc-mean_bold', 'space-T1w_desc-brain_mask', + 'space-T1w_sbref', 'space-T1w_desc-brain_mask', 'max-displacement', 'space-template_desc-preproc_bold', 'space-bold_desc-brain_mask', ['T1w-brain-template-mask', 'EPI-template-mask'], ['space-template_desc-bold_mask', @@ -389,7 +392,8 @@ def qc_xcp(wf, cfg, strat_pool, pipe_num, opt=None): ['T1w-brain-template-funcreg', 'EPI-brain-template-funcreg'], 'movement-parameters', 'dvars', 'framewise-displacement-jenkinson')], - 'outputs': ['space-template_desc-xcp_quality']} + 'outputs': {'space-template_desc-xcp_quality': { + 'Template': 'T1w-brain-template-mask'}}} """ if cfg['nuisance_corrections', '2-nuisance_regression', 'run' ] and not strat_pool.check_rpool('regressors'): @@ -425,7 +429,7 @@ def qc_xcp(wf, cfg, strat_pool, pipe_num, opt=None): nodes = {key: strat_pool.node_data(key) for key in [ 'bold', 'desc-preproc_bold', 'max-displacement', 'scan', 'space-bold_desc-brain_mask', 'space-T1w_desc-brain_mask', - 'space-T1w_desc-mean_bold', 'space-template_desc-preproc_bold', + 'space-T1w_sbref', 'space-template_desc-preproc_bold', 'subject', *motion_params]} nodes['bold2template_mask'] = strat_pool.node_data([ 'space-template_desc-bold_mask', 'space-EPItemplate_desc-bold_mask']) @@ -442,8 +446,8 @@ def qc_xcp(wf, cfg, strat_pool, pipe_num, opt=None): (nodes['subject'].node, bids_info, [ (nodes['subject'].out, 'subject')]), (nodes['scan'].node, bids_info, [(nodes['scan'].out, 'scan')]), - (nodes['space-T1w_desc-mean_bold'].node, bold_to_T1w_mask, [ - (nodes['space-T1w_desc-mean_bold'].out, 'in_file')]), + (nodes['space-T1w_sbref'].node, bold_to_T1w_mask, [ + (nodes['space-T1w_sbref'].out, 'in_file')]), (nodes['space-T1w_desc-brain_mask'].node, qc_file, [ (nodes['space-T1w_desc-brain_mask'].out, 't1w_mask')]), (bold_to_T1w_mask, qc_file, [('out_file', 'bold2t1w_mask')]), diff --git a/CPAC/randomise/randomise.py b/CPAC/randomise/randomise.py index 77ee89e7c4..188d0fd436 100755 --- a/CPAC/randomise/randomise.py +++ b/CPAC/randomise/randomise.py @@ -1,6 +1,5 @@ from CPAC.pipeline import nipype_pipeline_engine as pe -from CPAC.pipeline.cpac_group_runner import load_config_yml def select(input_list): @@ -122,6 +121,7 @@ def run(group_config_path): import sys import pickle import yaml + from CPAC.pipeline.cpac_group_runner import load_config_yml group_config_obj = load_config_yml(group_config_path) pipeline_output_folder = group_config_obj.pipeline_dir diff --git a/CPAC/registration/registration.py b/CPAC/registration/registration.py index c7dedc966c..5fd7a32591 100755 --- a/CPAC/registration/registration.py +++ b/CPAC/registration/registration.py @@ -1,19 +1,28 @@ -from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.utility as util -import nipype.interfaces.afni as afni -import nipype.interfaces.fsl as fsl -import nipype.interfaces.ants as ants -import nipype.interfaces.afni as afni +# Copyright (C) 2012-2023 C-PAC Developers -from nipype.interfaces.afni import utils as afni_utils +# This file is part of C-PAC. -import nipype.interfaces.c3 as c3 +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -from CPAC.anat_preproc.lesion_preproc import create_lesion_preproc +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +# pylint: disable=too-many-lines,ungrouped-imports,wrong-import-order +# TODO: replace Tuple with tuple, Union with |, once Python >= 3.9, 3.10 +from typing import Optional, Tuple, Union +from CPAC.pipeline import nipype_pipeline_engine as pe +from nipype.interfaces import afni, ants, c3, fsl, utility as util +from nipype.interfaces.afni import utils as afni_utils +from CPAC.anat_preproc.lesion_preproc import create_lesion_preproc from CPAC.func_preproc.utils import chunk_ts, split_ts_chunks - from CPAC.registration.utils import seperate_warps_list, \ check_transforms, \ generate_inverse_transform_flags, \ @@ -22,10 +31,8 @@ change_itk_transform_type, \ hardcoded_reg, \ one_d_to_mat, \ - run_ants_apply_warp, \ run_c3d, \ run_c4d - from CPAC.utils.interfaces.fsl import Merge as fslMerge from CPAC.utils.utils import check_prov_for_motion_tool, check_prov_for_regtool @@ -279,12 +286,16 @@ def transform_derivative(wf_name, label, reg_tool, num_cpus, num_ants_cores, return wf -def convert_pedir(pedir): +def convert_pedir(pedir, convert='xyz_to_int'): '''FSL Flirt requires pedir input encoded as an int''' - conv_dct = {'x': 1, 'y': 2, 'z': 3, 'x-': -1, 'y-': -2, 'z-': -3, - 'i': 1, 'j': 2, 'k': 3, 'i-': -1, 'j-': -2, 'k-': -3, - '-x': -1, '-i': -1, '-y': -2, - '-j': -2, '-z': -3, '-k': -3} + if convert == 'xyz_to_int': + conv_dct = {'x': 1, 'y': 2, 'z': 3, 'x-': -1, 'y-': -2, 'z-': -3, + 'i': 1, 'j': 2, 'k': 3, 'i-': -1, 'j-': -2, 'k-': -3, + '-x': -1, '-i': -1, '-y': -2, + '-j': -2, '-z': -3, '-k': -3} + elif convert == 'ijk_to_xyz': + conv_dct = {'i': 'x', 'j': 'y', 'k': 'z', + 'i-': 'x-', 'j-': 'y-', 'k-': 'z-'} if isinstance(pedir, bytes): pedir = pedir.decode() @@ -295,7 +306,8 @@ def convert_pedir(pedir): if pedir not in conv_dct.keys(): raise Exception("\n\nInvalid phase-encoding direction " "entered: {0}\n\n".format(pedir)) - return conv_dct[pedir] + pedir = conv_dct[pedir] + return pedir def create_fsl_flirt_linear_reg(name='fsl_flirt_linear_reg'): @@ -704,9 +716,18 @@ def create_register_func_to_anat(config, phase_diff_distcor=False, linear_reg.inputs.args = config.registration_workflows['functional_registration']['coregistration']['arguments'] if phase_diff_distcor: - register_func_to_anat.connect( - inputNode_pedir, ('pedir', convert_pedir), - linear_reg, 'pedir') + conv_pedir = \ + pe.Node(interface=util.Function(input_names=['pedir', + 'convert'], + output_names=['pedir'], + function=convert_pedir), + name='coreg_convert_pedir') + conv_pedir.inputs.convert = 'xyz_to_int' + + register_func_to_anat.connect(inputNode_pedir, 'pedir', + conv_pedir, 'pedir') + register_func_to_anat.connect(conv_pedir, 'pedir', + linear_reg, 'pedir') register_func_to_anat.connect(inputspec, 'fieldmap', linear_reg, 'fieldmap') register_func_to_anat.connect(inputspec, 'fieldmapmask', @@ -974,9 +995,18 @@ def bbreg_args(bbreg_target): bbreg_func_to_anat, 'in_matrix_file') if phase_diff_distcor: - register_bbregister_func_to_anat.connect( - inputNode_pedir, ('pedir', convert_pedir), - bbreg_func_to_anat, 'pedir') + conv_pedir = \ + pe.Node(interface=util.Function(input_names=['pedir', + 'convert'], + output_names=['pedir'], + function=convert_pedir), + name='bbreg_convert_pedir') + conv_pedir.inputs.convert = 'xyz_to_int' + + register_bbregister_func_to_anat.connect(inputNode_pedir, 'pedir', + conv_pedir, 'pedir') + register_bbregister_func_to_anat.connect(conv_pedir, 'pedir', + bbreg_func_to_anat, 'pedir') register_bbregister_func_to_anat.connect( inputspec, 'fieldmap', bbreg_func_to_anat, 'fieldmap') @@ -1377,7 +1407,7 @@ def FSL_registration_connector(wf_name, cfg, orig="T1w", opt=None, write_invlin_composite_xfm, 'premat') outputs = { - f'space-{sym}{tmpl}template_desc-brain_{orig}': ( + f'space-{sym}template_desc-preproc_{orig}': ( flirt_reg_anat_mni, 'outputspec.output_brain'), f'from-{orig}_to-{sym}{tmpl}template_mode-image_desc-linear_xfm': ( write_lin_composite_xfm, 'out_file'), @@ -1426,7 +1456,7 @@ def FSL_registration_connector(wf_name, cfg, orig="T1w", opt=None, cfg.registration_workflows['anatomical_registration']['resolution_for_anat']: # NOTE: this is an UPDATE because of the opt block above added_outputs = { - f'space-{sym}{tmpl}template_desc-brain_{orig}': ( + f'space-{sym}template_desc-preproc_{orig}': ( fnirt_reg_anat_mni, 'outputspec.output_brain'), f'from-{orig}_to-{sym}{tmpl}template_mode-image_xfm': ( fnirt_reg_anat_mni, 'outputspec.nonlinear_xfm') @@ -1435,13 +1465,13 @@ def FSL_registration_connector(wf_name, cfg, orig="T1w", opt=None, else: # NOTE: this is an UPDATE because of the opt block above added_outputs = { - f'space-{sym}{tmpl}template_desc-brain_{orig}': ( + f'space-{sym}template_desc-preproc_{orig}': ( fnirt_reg_anat_mni, 'outputspec.output_brain'), - f'space-{sym}{tmpl}template_desc-head_{orig}': ( + f'space-{sym}template_desc-head_{orig}': ( fnirt_reg_anat_mni, 'outputspec.output_head'), - f'space-{sym}{tmpl}template_desc-{orig}_mask': ( + f'space-{sym}template_desc-{orig}_mask': ( fnirt_reg_anat_mni, 'outputspec.output_mask'), - f'space-{sym}{tmpl}template_desc-T1wT2w_biasfield': ( + f'space-{sym}template_desc-T1wT2w_biasfield': ( fnirt_reg_anat_mni, 'outputspec.output_biasfield'), f'from-{orig}_to-{sym}{tmpl}template_mode-image_xfm': ( fnirt_reg_anat_mni, 'outputspec.nonlinear_xfm'), @@ -1768,7 +1798,7 @@ def ANTs_registration_connector(wf_name, cfg, params, orig="T1w", write_composite_inv_xfm, 'invert_transform_flags') outputs = { - f'space-{sym}{tmpl}template_desc-brain_{orig}': ( + f'space-{sym}template_desc-preproc_{orig}': ( ants_reg_anat_mni, 'outputspec.normalized_output_brain'), f'from-{orig}_to-{sym}{tmpl}template_mode-image_xfm': ( write_composite_xfm, 'output_image'), @@ -1787,7 +1817,8 @@ def ANTs_registration_connector(wf_name, cfg, params, orig="T1w", return (wf, outputs) -def bold_to_T1template_xfm_connector(wf_name, cfg, reg_tool, symmetric=False): +def bold_to_T1template_xfm_connector(wf_name, cfg, reg_tool, symmetric=False, + blip=False): wf = pe.Workflow(name=wf_name) @@ -1797,7 +1828,8 @@ def bold_to_T1template_xfm_connector(wf_name, cfg, reg_tool, symmetric=False): 'coreg_xfm', 'T1w-brain-template_funcreg', 'T1w_to_template_xfm', - 'template_to_T1w_xfm']), + 'template_to_T1w_xfm', + 'blip_warp']), name='inputspec') sym = '' @@ -1849,11 +1881,18 @@ def bold_to_T1template_xfm_connector(wf_name, cfg, reg_tool, symmetric=False): cfg.registration_workflows['anatomical_registration'][ 'registration']['ANTs']['interpolation'] - collect_all_transforms = pe.Node(util.Merge(2), - name=f'collect_all_transforms') + if not blip: + collect_all_transforms = pe.Node(util.Merge(2), + name='collect_all_transforms') + else: + collect_all_transforms = pe.Node(util.Merge(3), + name='collect_all_transforms') + + wf.connect(inputNode, 'blip_warp', + collect_all_transforms, 'in3') wf.connect(inputNode, 'T1w_to_template_xfm', - collect_all_transforms, 'in1') + collect_all_transforms, 'in1') wf.connect(change_transform, 'updated_affine_file', collect_all_transforms, 'in2') @@ -1909,10 +1948,18 @@ def bold_to_T1template_xfm_connector(wf_name, cfg, reg_tool, symmetric=False): wf.connect(inputNode, 'T1w-brain-template_funcreg', write_composite_xfm, 'reference') - wf.connect(inputNode, 'coreg_xfm', write_composite_xfm, 'premat') - - wf.connect(inputNode, 'T1w_to_template_xfm', - write_composite_xfm, 'warp1') + if blip: + wf.connect(inputNode, 'coreg_xfm', + write_composite_xfm, 'postmat') + wf.connect(inputNode, 'blip_warp', + write_composite_xfm, 'warp1') + wf.connect(inputNode, 'T1w_to_template_xfm', + write_composite_xfm, 'warp2') + else: + wf.connect(inputNode, 'coreg_xfm', + write_composite_xfm, 'premat') + wf.connect(inputNode, 'T1w_to_template_xfm', + write_composite_xfm, 'warp1') outputs = { f'from-bold_to-{sym}template_mode-image_xfm': @@ -1929,25 +1976,37 @@ def register_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["registration", "using"], "option_val": ["FSL", "FSL-linear"], - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w", + "inputs": [(["desc-preproc_T1w", "space-longitudinal_desc-reorient_T1w"], - ["desc-brain_T1w", "space-longitudinal_desc-brain_T1w"]), + ["desc-brain_T1w", + "space-longitudinal_desc-brain_T1w"]), "T1w-template", "T1w-brain-template", "FNIRT-T1w-template", "FNIRT-T1w-brain-template", "template-ref-mask"], - "outputs": ["space-template_desc-brain_T1w", - "space-template_desc-head_T1w", - "space-template_desc-T1w_mask", - "space-template_desc-T1wT2w_biasfield", - "from-T1w_to-template_mode-image_desc-linear_xfm", - "from-template_to-T1w_mode-image_desc-linear_xfm", - "from-T1w_to-template_mode-image_xfm", - "from-T1w_to-template_mode-image_warp", - "from-longitudinal_to-template_mode-image_desc-linear_xfm", - "from-template_to-longitudinal_mode-image_desc-linear_xfm", - "from-longitudinal_to-template_mode-image_xfm"]} + "outputs": {"space-template_desc-preproc_T1w": { + "Template": "T1w-brain-template"}, + "space-template_desc-head_T1w": { + "Template": "T1w-template"}, + "space-template_desc-T1w_mask": { + "Template": "T1w-template"}, + "space-template_desc-T1wT2w_biasfield": { + "Template": "T1w-template"}, + "from-T1w_to-template_mode-image_desc-linear_xfm": { + "Template": "T1w-template"}, + "from-template_to-T1w_mode-image_desc-linear_xfm": { + "Template": "T1w-template"}, + "from-T1w_to-template_mode-image_xfm": { + "Template": "T1w-template"}, + "from-T1w_to-template_mode-image_warp": { + "Template": "T1w-template"}, + "from-longitudinal_to-template_mode-image_desc-linear_xfm": { + "Template": "T1w-template"}, + "from-template_to-longitudinal_mode-image_desc-linear_xfm": { + "Template": "T1w-template"}, + "from-longitudinal_to-template_mode-image_xfm": { + "Template": "T1w-template"}}} ''' fsl, outputs = FSL_registration_connector(f'register_{opt}_anat_to_' @@ -1985,7 +2044,6 @@ def register_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, fsl, 'inputspec.reference_head') node, out = strat_pool.get_data(["desc-preproc_T1w", - "desc-reorient_T1w", "T1w", "space-longitudinal_desc-reorient_T1w"]) wf.connect(node, out, fsl, 'inputspec.input_head') @@ -2014,19 +2072,26 @@ def register_symmetric_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, "switch": ["run"], "option_key": ["registration", "using"], "option_val": ["FSL", "FSL-linear"], - "inputs": [(["desc-preproc_T1w", "desc-reorient_T1w", "T1w", + "inputs": [(["desc-preproc_T1w", "space-longitudinal_desc-reorient_T1w"], ["desc-brain_T1w", "space-longitudinal_desc-brain_T1w"]), "T1w-template-symmetric", "T1w-brain-template-symmetric", "dilated-symmetric-brain-mask"], - "outputs": ["space-symtemplate_desc-brain_T1w", - "from-T1w_to-symtemplate_mode-image_desc-linear_xfm", - "from-symtemplate_to-T1w_mode-image_desc-linear_xfm", - "from-T1w_to-symtemplate_mode-image_xfm", - "from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm", - "from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm", - "from-longitudinal_to-symtemplate_mode-image_xfm"]} + "outputs": {"space-symtemplate_desc-preproc_T1w": { + "Template": "T1w-brain-template-symmetric"}, + "from-T1w_to-symtemplate_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-T1w_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-T1w_to-symtemplate_mode-image_xfm": { + "Template": "T1w-template-symmetric"}, + "from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-longitudinal_to-symtemplate_mode-image_xfm": { + "Template": "T1w-template-symmetric"}}} ''' fsl, outputs = FSL_registration_connector(f'register_{opt}_anat_to_' @@ -2053,7 +2118,6 @@ def register_symmetric_FSL_anat_to_template(wf, cfg, strat_pool, pipe_num, wf.connect(node, out, fsl, 'inputspec.reference_brain') node, out = strat_pool.get_data(["desc-preproc_T1w", - "desc-reorient_T1w", "T1w", "space-longitudinal_desc-reorient_T1w"]) wf.connect(node, out, fsl, 'inputspec.input_head') @@ -2088,14 +2152,18 @@ def register_FSL_EPI_to_template(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "using", "option_val": ["FSL", "FSL-linear"], - "inputs": [(["desc-reginput_bold", "desc-mean_bold"], + "inputs": [("sbref", "space-bold_desc-brain_mask"), "EPI-template", "EPI-template-mask"], - "outputs": ["space-EPItemplate_desc-brain_bold", - "from-bold_to-EPItemplate_mode-image_desc-linear_xfm", - "from-EPItemplate_to-bold_mode-image_desc-linear_xfm", - "from-bold_to-EPItemplate_mode-image_xfm"]} + "outputs": {"space-template_desc-preproc_bold": { + "Template": "EPI-template"}, + "from-bold_to-EPItemplate_mode-image_desc-linear_xfm": { + "Template": "EPI-template"}, + "from-EPItemplate_to-bold_mode-image_desc-linear_xfm": { + "Template": "EPI-template"}, + "from-bold_to-EPItemplate_mode-image_xfm": { + "Template": "EPI-template"}}} ''' fsl, outputs = FSL_registration_connector(f'register_{opt}_EPI_to_' @@ -2111,13 +2179,13 @@ def register_FSL_EPI_to_template(wf, cfg, strat_pool, pipe_num, opt=None): 'functional_registration']['EPI_registration']['FSL-FNIRT'][ 'fnirt_config'] - node, out = strat_pool.get_data(["desc-reginput_bold", "desc-mean_bold"]) + node, out = strat_pool.get_data('sbref') wf.connect(node, out, fsl, 'inputspec.input_brain') node, out = strat_pool.get_data('EPI-template') wf.connect(node, out, fsl, 'inputspec.reference_brain') - node, out = strat_pool.get_data(["desc-reginput_bold", "desc-mean_bold"]) + node, out = strat_pool.get_data('sbref') wf.connect(node, out, fsl, 'inputspec.input_head') node, out = strat_pool.get_data('EPI-template') @@ -2137,64 +2205,78 @@ def register_ANTs_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["registration", "using"], "option_val": "ANTS", - "inputs": [(["desc-brain_T1w", "space-longitudinal_desc-brain_T1w"], + "inputs": [(["desc-preproc_T1w", "space-longitudinal_desc-brain_T1w"], ["space-T1w_desc-brain_mask", "space-longitudinal_desc-brain_mask", "space-T1w_desc-acpcbrain_mask"], - ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"]), + ["desc-restore_T1w", "desc-head_T1w", "desc-preproc_T1w", + "space-longitudinal_desc-reorient_T1w"], + "space-template_desc-head_T1w", + "space-template_desc-preproc_T1w"), "T1w-template", "T1w-brain-template", "T1w-brain-template-mask", "label-lesion_mask"], - "outputs": {"space-template_desc-brain_T1w": { + "outputs": {"space-template_desc-preproc_T1w": { "Description": "The preprocessed T1w brain transformed " "to template space.", "Template": "T1w-template"}, "from-T1w_to-template_mode-image_desc-linear_xfm": { "Description": "Linear (affine) transform from T1w native" - " space to T1w-template space."}, + " space to T1w-template space.", + "Template": "T1w-template"}, "from-template_to-T1w_mode-image_desc-linear_xfm": { "Description": "Linear (affine) transform from T1w-" - "template space to T1w native space."}, + "template space to T1w native space.", + "Template": "T1w-template"}, "from-T1w_to-template_mode-image_desc-nonlinear_xfm": { "Description": "Nonlinear (warp field) transform from " - "T1w native space to T1w-template space."}, + "T1w native space to T1w-template space.", + "Template": "T1w-template"}, "from-template_to-T1w_mode-image_desc-nonlinear_xfm": { "Description": "Nonlinear (warp field) transform from " - "T1w-template space to T1w native space."}, + "T1w-template space to T1w native space.", + "Template": "T1w-template"}, "from-T1w_to-template_mode-image_xfm": { "Description": "Composite (affine + warp field) " "transform from T1w native space to T1w-" - "template space."}, + "template space.", + "Template": "T1w-template"}, "from-template_to-T1w_mode-image_xfm": { "Description": "Composite (affine + warp field) " "transform from T1w-template space to T1w " - "native space."}, + "native space.", + "Template": "T1w-template"}, "from-longitudinal_to-template_mode-image_desc-linear_xfm": { "Description": "Linear (affine) transform from " "longitudinal-template space to T1w-" - "template space."}, + "template space.", + "Template": "T1w-template"}, "from-template_to-longitudinal_mode-image_desc-linear_xfm": { "Description": "Linear (affine) transform from T1w-" "template space to longitudinal-template " - "space."}, + "space.", + "Template": "T1w-template"}, "from-longitudinal_to-template_mode-image_desc-nonlinear_xfm": { "Description": "Nonlinear (warp field) transform from " "longitudinal-template space to T1w-" - "template space."}, + "template space.", + "Template": "T1w-template"}, "from-template_to-longitudinal_mode-image_desc-nonlinear_xfm": { "Description": "Nonlinear (warp field) transform from " "T1w-template space to longitudinal-" - "template space."}, + "template space.", + "Template": "T1w-template"}, "from-longitudinal_to-template_mode-image_xfm": { "Description": "Composite (affine + warp field) " "transform from longitudinal-template " - "space to T1w-template space."}, + "space to T1w-template space.", + "Template": "T1w-template"}, "from-template_to-longitudinal_mode-image_xfm": { "Description": "Composite (affine + warp field) " "transform from T1w-template space to " - "longitudinal-template space."}}} + "longitudinal-template space.", + "Template": "T1w-template"}}} ''' params = cfg.registration_workflows['anatomical_registration'][ @@ -2208,7 +2290,7 @@ def register_ANTs_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None): 'anatomical_registration']['registration']['ANTs']['interpolation'] connect, brain = \ - strat_pool.get_data(['desc-brain_T1w', + strat_pool.get_data(['desc-preproc_T1w', 'space-longitudinal_desc-brain_T1w'], report_fetched=True) node, out = connect @@ -2219,8 +2301,8 @@ def register_ANTs_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None): ants_rc, 'inputspec.reference_brain') # TODO check the order of T1w - node, out = strat_pool.get_data(["desc-restore_T1w", "desc-preproc_T1w", - "desc-reorient_T1w", "T1w", + node, out = strat_pool.get_data(["desc-restore_T1w", "desc-head_T1w", + "desc-preproc_T1w", "space-longitudinal_desc-reorient_T1w"]) wf.connect(node, out, ants_rc, 'inputspec.input_head') @@ -2263,28 +2345,41 @@ def register_symmetric_ANTs_anat_to_template(wf, cfg, strat_pool, pipe_num, "switch": ["run"], "option_key": ["registration", "using"], "option_val": "ANTS", - "inputs": [(["desc-brain_T1w", "space-longitudinal_desc-brain_T1w"], + "inputs": [(["desc-preproc_T1w", "space-longitudinal_desc-brain_T1w"], ["space-T1w_desc-brain_mask", "space-longitudinal_desc-brain_mask"], - ["desc-preproc_T1w", "desc-reorient_T1w", "T1w", + ["desc-head_T1w", "desc-preproc_T1w", "space-longitudinal_desc-reorient_T1w"]), "T1w-template-symmetric", "T1w-brain-template-symmetric", "dilated-symmetric-brain-mask", "label-lesion_mask"], - "outputs": ["space-symtemplate_desc-brain_T1w", - "from-T1w_to-symtemplate_mode-image_desc-linear_xfm", - "from-symtemplate_to-T1w_mode-image_desc-linear_xfm", - "from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm", - "from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm", - "from-T1w_to-symtemplate_mode-image_xfm", - "from-symtemplate_to-T1w_mode-image_xfm", - "from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm", - "from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm", - "from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm", - "from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm", - "from-longitudinal_to-symtemplate_mode-image_xfm", - "from-symtemplate_to-longitudinal_mode-image_xfm"]} + "outputs": {"space-symtemplate_desc-preproc_T1w": { + "Template": "T1w-brain-template-symmetric"}, + "from-T1w_to-symtemplate_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-T1w_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-T1w_to-symtemplate_mode-image_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-T1w_mode-image_xfm": { + "Template": "T1w-template-symmetric"}, + "from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm": { + "Template": "T1w-template-symmetric"}, + "from-longitudinal_to-symtemplate_mode-image_xfm": { + "Template": "T1w-template-symmetric"}, + "from-symtemplate_to-longitudinal_mode-image_xfm": { + "Template": "T1w-template-symmetric"}}} ''' params = cfg.registration_workflows['anatomical_registration'][ @@ -2299,7 +2394,7 @@ def register_symmetric_ANTs_anat_to_template(wf, cfg, strat_pool, pipe_num, 'anatomical_registration']['registration']['ANTs']['interpolation'] connect, brain = \ - strat_pool.get_data(['desc-brain_T1w', + strat_pool.get_data(['desc-preproc_T1w', 'space-longitudinal_desc-brain_T1w'], report_fetched=True) node, out = connect @@ -2308,8 +2403,7 @@ def register_symmetric_ANTs_anat_to_template(wf, cfg, strat_pool, pipe_num, node, out = strat_pool.get_data('T1w-brain-template-symmetric') wf.connect(node, out, ants, 'inputspec.reference_brain') - node, out = strat_pool.get_data(["desc-preproc_T1w", - "desc-reorient_T1w", "T1w", + node, out = strat_pool.get_data(["desc-head_T1w", "desc-preproc_T1w", "space-longitudinal_desc-reorient_T1w"]) wf.connect(node, out, ants, 'inputspec.input_head') @@ -2352,17 +2446,24 @@ def register_ANTs_EPI_to_template(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "using", "option_val": "ANTS", - "inputs": [(["desc-reginput_bold", "desc-mean_bold"], + "inputs": [("sbref", "space-bold_desc-brain_mask"), "EPI-template", "EPI-template-mask"], - "outputs": ["space-EPItemplate_desc-brain_bold", - "from-bold_to-EPItemplate_mode-image_desc-linear_xfm", - "from-EPItemplate_to-bold_mode-image_desc-linear_xfm", - "from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm", - "from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm", - "from-bold_to-EPItemplate_mode-image_xfm", - "from-EPItemplate_to-bold_mode-image_xfm"]} + "outputs": {"space-template_desc-preproc_bold": { + "Template": "EPI-template"}, + "from-bold_to-EPItemplate_mode-image_desc-linear_xfm": { + "Template": "EPI-template"}, + "from-EPItemplate_to-bold_mode-image_desc-linear_xfm": { + "Template": "EPI-template"}, + "from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm": { + "Template": "EPI-template"}, + "from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm": { + "Template": "EPI-template"}, + "from-bold_to-EPItemplate_mode-image_xfm": { + "Template": "EPI-template"}, + "from-EPItemplate_to-bold_mode-image_xfm": { + "Template": "EPI-template"}}} ''' params = cfg.registration_workflows['functional_registration'][ 'EPI_registration']['ANTs']['parameters'] @@ -2375,13 +2476,13 @@ def register_ANTs_EPI_to_template(wf, cfg, strat_pool, pipe_num, opt=None): 'functional_registration']['EPI_registration']['ANTs'][ 'interpolation'] - node, out = strat_pool.get_data(['desc-reginput_bold', 'desc-mean_bold']) + node, out = strat_pool.get_data('sbref') wf.connect(node, out, ants, 'inputspec.input_brain') node, out = strat_pool.get_data('EPI-template') wf.connect(node, out, ants, 'inputspec.reference_brain') - node, out = strat_pool.get_data(['desc-reginput_bold', 'desc-mean_bold']) + node, out = strat_pool.get_data('sbref') wf.connect(node, out, ants, 'inputspec.input_head') node, out = strat_pool.get_data('EPI-template') @@ -2407,19 +2508,25 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None "overwrite_transform", "using"], "option_val": "FSL", "inputs": [("desc-restore-brain_T1w", - ["desc-brain_T1w", "space-longitudinal_desc-brain_T1w"], + ["desc-preproc_T1w", "space-longitudinal_desc-brain_T1w"], ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w"], ["desc-preproc_T1w", "desc-reorient_T1w", "T1w"], "space-T1w_desc-brain_mask", "T1w-template", "from-T1w_to-template_mode-image_xfm", "from-template_to-T1w_mode-image_xfm", - "space-template_desc-brain_T1w")], - "outputs": ["space-template_desc-brain_T1w", - "space-template_desc-head_T1w", - "space-template_desc-T1w_mask", - "from-T1w_to-template_mode-image_xfm", - "from-template_to-T1w_mode-image_xfm"]} + "space-template_desc-brain_T1w", + "space-template_desc-preproc_T1w")], + "outputs": {"space-template_desc-preproc_T1w": { + "Template": "T1w-template"}, + "space-template_desc-head_T1w": { + "Template": "T1w-template"}, + "space-template_desc-T1w_mask": { + "Template": "T1w-template"}, + "from-T1w_to-template_mode-image_xfm": { + "Template": "T1w-template"}, + "from-template_to-T1w_mode-image_xfm": { + "Template": "T1w-template"}}} ''' xfm_prov = strat_pool.get_cpac_provenance( @@ -2445,7 +2552,7 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None ants_apply_warp_t1_to_template.inputs.print_out_composite_warp_file = True ants_apply_warp_t1_to_template.inputs.output_image = 'ANTs_CombinedWarp.nii.gz' - node, out = strat_pool.get_data(['desc-restore_T1w', 'desc-preproc_T1w', 'desc-reorient_T1w', 'T1w']) + node, out = strat_pool.get_data(['desc-restore_T1w', 'desc-preproc_T1w']) wf.connect(node, out, ants_apply_warp_t1_to_template, 'input_image') node, out = strat_pool.get_data('T1w-template') @@ -2468,7 +2575,7 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None ants_apply_warp_template_to_t1.inputs.print_out_composite_warp_file = True ants_apply_warp_template_to_t1.inputs.output_image = 'ANTs_CombinedInvWarp.nii.gz' - node, out = strat_pool.get_data(['desc-preproc_T1w', 'desc-reorient_T1w', 'T1w']) + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, ants_apply_warp_template_to_t1, 'input_image') node, out = strat_pool.get_data('T1w-template') @@ -2562,7 +2669,7 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None fsl_apply_warp_t1_to_template.inputs.relwarp = True fsl_apply_warp_t1_to_template.inputs.interp = 'spline' - node, out = strat_pool.get_data(['desc-restore_T1w', 'desc-preproc_T1w', 'desc-reorient_T1w', 'T1w']) + node, out = strat_pool.get_data(['desc-restore_T1w', 'desc-preproc_T1w']) wf.connect(node, out, fsl_apply_warp_t1_to_template, 'in_file') node, out = strat_pool.get_data('T1w-template') @@ -2578,7 +2685,7 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None fsl_apply_warp_t1_brain_to_template.inputs.interp = 'nn' # TODO connect T1wRestoreBrain, check T1wRestoreBrain quality - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, fsl_apply_warp_t1_brain_to_template, 'in_file') node, out = strat_pool.get_data('T1w-template') @@ -2612,7 +2719,7 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None apply_mask, 'mask_file') outputs = { - 'space-template_desc-brain_T1w': (apply_mask, 'out_file'), + 'space-template_desc-preproc_T1w': (apply_mask, 'out_file'), 'space-template_desc-head_T1w': (fsl_apply_warp_t1_to_template, 'out_file'), 'space-template_desc-T1w_mask': (fsl_apply_warp_t1_brain_mask_to_template, 'out_file'), 'from-T1w_to-template_mode-image_xfm': (merge_xfms, 'merged_file'), @@ -2625,15 +2732,15 @@ def overwrite_transform_anat_to_template(wf, cfg, strat_pool, pipe_num, opt=None def coregistration_prep_vol(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "coregistration_prep_vol", - "config": ["registration_workflows", "functional_registration", - "coregistration"], - "switch": ["run"], - "option_key": ["func_input_prep", "input"], + "config": "None", + "switch": ["functional_preproc", "run"], + "option_key": ["registration_workflows", "functional_registration", + "coregistration", "func_input_prep", "input"], "option_val": "Selected_Functional_Volume", "inputs": [("desc-brain_bold", ["desc-motion_bold", "bold"], - "desc-reginput_bold")], - "outputs": ["desc-reginput_bold"]} + "sbref")], + "outputs": ["sbref"]} ''' get_func_volume = pe.Node(interface=afni.Calc(), @@ -2659,7 +2766,7 @@ def coregistration_prep_vol(wf, cfg, strat_pool, pipe_num, opt=None): coreg_input = (get_func_volume, 'out_file') outputs = { - 'desc-reginput_bold': coreg_input + 'sbref': coreg_input } return (wf, outputs) @@ -2668,13 +2775,13 @@ def coregistration_prep_vol(wf, cfg, strat_pool, pipe_num, opt=None): def coregistration_prep_mean(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "coregistration_prep_mean", - "config": ["registration_workflows", "functional_registration", - "coregistration"], - "switch": ["run"], - "option_key": ["func_input_prep", "input"], + "config": "None", + "switch": ["functional_preproc", "run"], + "option_key": ["registration_workflows", "functional_registration", + "coregistration", "func_input_prep", "input"], "option_val": "Mean_Functional", "inputs": ["desc-mean_bold"], - "outputs": ["desc-reginput_bold"]} + "outputs": ["sbref"]} ''' coreg_input = strat_pool.get_data("desc-mean_bold") @@ -2698,7 +2805,7 @@ def coregistration_prep_mean(wf, cfg, strat_pool, pipe_num, opt=None): coreg_input = (n4_correct_func, 'output_image') outputs = { - 'desc-reginput_bold': coreg_input + 'sbref': coreg_input } return (wf, outputs) @@ -2707,19 +2814,19 @@ def coregistration_prep_mean(wf, cfg, strat_pool, pipe_num, opt=None): def coregistration_prep_fmriprep(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "coregistration_prep_fmriprep", - "config": ["registration_workflows", "functional_registration", - "coregistration"], - "switch": ["run"], - "option_key": ["func_input_prep", "input"], + "config": "None", + "switch": ["functional_preproc", "run"], + "option_key": ["registration_workflows", "functional_registration", + "coregistration", "func_input_prep", "input"], "option_val": "fmriprep_reference", "inputs": ["desc-ref_bold"], - "outputs": ["desc-reginput_bold"]} + "outputs": ["sbref"]} ''' coreg_input = strat_pool.get_data("desc-ref_bold") outputs = { - 'desc-reginput_bold': coreg_input + 'sbref': coreg_input } return (wf, outputs) @@ -2733,22 +2840,22 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [("desc-reginput_bold", + "inputs": [("sbref", "desc-motion_bold", "space-bold_label-WM_mask", "despiked-fieldmap", - "fieldmap-mask"), - ("desc-brain_T1w", + "fieldmap-mask", + "effectiveEchoSpacing", + "pe-direction"), + ("desc-preproc_T1w", "desc-restore-brain_T1w", "desc-preproc_T2w", - "desc-brain_T2w", + "desc-preproc_T2w", "T2w", ["label-WM_probseg", "label-WM_mask"], ["label-WM_pveseg", "label-WM_mask"], - "T1w"), - "diffphase-dwell", - "diffphase-pedir"], - "outputs": ["space-T1w_desc-mean_bold", + "desc-head_T1w", "desc-head_T2w")], + "outputs": ["space-T1w_sbref", "from-bold_to-T1w_mode-image_desc-linear_xfm", "from-bold_to-T1w_mode-image_desc-linear_warp"]} ''' @@ -2777,13 +2884,13 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(func_mc_mean, 'out_file', func_to_anat, 'inputspec.func') - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, func_to_anat, 'inputspec.T1_brain') - node, out = strat_pool.get_data('desc-preproc_T2w') + node, out = strat_pool.get_data('desc-head_T2w') wf.connect(node, out, func_to_anat, 'inputspec.T2_head') - node, out = strat_pool.get_data('desc-brain_T2w') + node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, func_to_anat, 'inputspec.T2_brain') else: @@ -2799,23 +2906,23 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): func_to_anat.inputs.inputspec.interp = cfg.registration_workflows[ 'functional_registration']['coregistration']['interpolation'] - node, out = strat_pool.get_data('desc-reginput_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, func_to_anat, 'inputspec.func') if cfg.registration_workflows['functional_registration'][ 'coregistration']['reference'] == 'brain': - node, out = strat_pool.get_data('desc-brain_T1w') + # TODO: use JSON meta-data to confirm + node, out = strat_pool.get_data('desc-preproc_T1w') elif cfg.registration_workflows['functional_registration'][ 'coregistration']['reference'] == 'restore-brain': node, out = strat_pool.get_data('desc-restore-brain_T1w') wf.connect(node, out, func_to_anat, 'inputspec.anat') - if diff_complete: - node, out = strat_pool.get_data('diffphase-dwell') + node, out = strat_pool.get_data('effectiveEchoSpacing') wf.connect(node, out, func_to_anat, 'echospacing_input.echospacing') - node, out = strat_pool.get_data('diffphase-pedir') + node, out = strat_pool.get_data('pe-direction') wf.connect(node, out, func_to_anat, 'pedir_input.pedir') node, out = strat_pool.get_data("despiked-fieldmap") @@ -2826,7 +2933,7 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): if strat_pool.check_rpool('T2w') and cfg.anatomical_preproc['run_t2']: outputs = { - 'space-T1w_desc-mean_bold': + 'space-T1w_sbref': (func_to_anat, 'outputspec.anat_func_nobbreg'), 'from-bold_to-T1w_mode-image_desc-linear_xfm': (func_to_anat, 'outputspec.func_to_anat_linear_xfm_nobbreg'), @@ -2835,7 +2942,7 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): } else: outputs = { - 'space-T1w_desc-mean_bold': + 'space-T1w_sbref': (func_to_anat, 'outputspec.anat_func_nobbreg'), 'from-bold_to-T1w_mode-image_desc-linear_xfm': (func_to_anat, 'outputspec.func_to_anat_linear_xfm_nobbreg') @@ -2858,19 +2965,19 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): 'coregistration']['boundary_based_registration'][ 'bbr_wm_mask_args'] - node, out = strat_pool.get_data('desc-reginput_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, func_to_anat_bbreg, 'inputspec.func') if cfg.registration_workflows['functional_registration'][ 'coregistration']['boundary_based_registration'][ 'reference'] == 'whole-head': - node, out = strat_pool.get_data('T1w') + node, out = strat_pool.get_data('desc-head_T1w') wf.connect(node, out, func_to_anat_bbreg, 'inputspec.anat') elif cfg.registration_workflows['functional_registration'][ 'coregistration']['boundary_based_registration'][ 'reference'] == 'brain': - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, func_to_anat_bbreg, 'inputspec.anat') wf.connect(func_to_anat, 'outputspec.func_to_anat_linear_xfm_nobbreg', @@ -2893,11 +3000,11 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): func_to_anat_bbreg, 'inputspec.anat_wm_segmentation') if diff_complete: - node, out = strat_pool.get_data('diffphase-dwell') + node, out = strat_pool.get_data('effectiveEchoSpacing') wf.connect(node, out, func_to_anat_bbreg, 'echospacing_input.echospacing') - node, out = strat_pool.get_data('diffphase-pedir') + node, out = strat_pool.get_data('pe-direction') wf.connect(node, out, func_to_anat_bbreg, 'pedir_input.pedir') node, out = strat_pool.get_data("despiked-fieldmap") @@ -2908,7 +3015,7 @@ def coregistration(wf, cfg, strat_pool, pipe_num, opt=None): func_to_anat_bbreg, 'inputspec.fieldmapmask') outputs = { - 'space-T1w_desc-mean_bold': + 'space-T1w_sbref': (func_to_anat_bbreg, 'outputspec.anat_func'), 'from-bold_to-T1w_mode-image_desc-linear_xfm': (func_to_anat_bbreg, 'outputspec.func_to_anat_linear_xfm') @@ -2928,16 +3035,19 @@ def create_func_to_T1template_xfm(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": ["target_template", "using"], "option_val": "T1_template", - "inputs": [("desc-reginput_bold", - "from-bold_to-T1w_mode-image_desc-linear_xfm"), + "inputs": [("sbref", + "from-bold_to-T1w_mode-image_desc-linear_xfm", + "ants-blip-warp", + "fsl-blip-warp"), ("from-T1w_to-template_mode-image_xfm", "from-template_to-T1w_mode-image_xfm", "desc-brain_T1w"), "T1w-brain-template-funcreg"], - "outputs": ["from-bold_to-template_mode-image_xfm", - "from-template_to-bold_mode-image_xfm"]} + "outputs": {"from-bold_to-template_mode-image_xfm": { + "Template": "T1w-brain-template-funcreg"}, + "from-template_to-bold_mode-image_xfm": { + "Template": "T1w-brain-template-funcreg"}}} ''' - xfm_prov = strat_pool.get_cpac_provenance( 'from-T1w_to-template_mode-image_xfm') reg_tool = check_prov_for_regtool(xfm_prov) @@ -2954,7 +3064,7 @@ def create_func_to_T1template_xfm(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data('desc-brain_T1w') wf.connect(node, out, xfm, 'inputspec.input_brain') - node, out = strat_pool.get_data('desc-reginput_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, xfm, 'inputspec.mean_bold') node, out = strat_pool.get_data('T1w-brain-template-funcreg') @@ -2968,6 +3078,21 @@ def create_func_to_T1template_xfm(wf, cfg, strat_pool, pipe_num, opt=None): node, out = strat_pool.get_data('from-template_to-T1w_mode-image_xfm') wf.connect(node, out, xfm, 'inputspec.template_to_T1w_xfm') + if strat_pool.check_rpool('ants-blip-warp'): + if reg_tool == 'ants': + node, out = strat_pool.get_data('ants-blip-warp') + wf.connect(node, out, xfm, 'inputspec.blip_warp') + elif reg_tool == 'fsl': + # apply the ants blip warp separately + pass + elif strat_pool.check_rpool('fsl-blip-warp'): + if reg_tool == 'fsl': + node, out = strat_pool.get_data('fsl-blip-warp') + wf.connect(node, out, xfm, 'inputspec.blip_warp') + elif reg_tool == 'ants': + # apply the fsl blip warp separately + pass + return (wf, outputs) @@ -2986,11 +3111,13 @@ def create_func_to_T1template_symmetric_xfm(wf, cfg, strat_pool, pipe_num, "inputs": [("from-T1w_to-symtemplate_mode-image_xfm", "from-symtemplate_to-T1w_mode-image_xfm", "desc-brain_T1w"), - ("from-bold_to-T1w_mode-image_desc-linear_xfm", - "desc-mean_bold"), + ("sbref", + "from-bold_to-T1w_mode-image_desc-linear_xfm"), "T1w-brain-template-symmetric-deriv"], - "outputs": ["from-bold_to-symtemplate_mode-image_xfm", - "from-symtemplate_to-bold_mode-image_xfm"]} + "outputs": {"from-bold_to-symtemplate_mode-image_xfm": { + "Template": "T1w-brain-template-symmetric-deriv"}, + "from-symtemplate_to-bold_mode-image_xfm": { + "Template": "T1w-brain-template-symmetric-deriv"}}} ''' xfm_prov = strat_pool.get_cpac_provenance( @@ -3009,7 +3136,7 @@ def create_func_to_T1template_symmetric_xfm(wf, cfg, strat_pool, pipe_num, node, out = strat_pool.get_data('desc-brain_T1w') wf.connect(node, out, xfm, 'inputspec.input_brain') - node, out = strat_pool.get_data('desc-mean_bold') + node, out = strat_pool.get_data('sbref') wf.connect(node, out, xfm, 'inputspec.mean_bold') node, out = strat_pool.get_data('T1w-brain-template-symmetric-deriv') @@ -3027,36 +3154,188 @@ def create_func_to_T1template_symmetric_xfm(wf, cfg, strat_pool, pipe_num, return (wf, outputs) -def warp_timeseries_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): +def apply_phasediff_to_timeseries_separately(wf, cfg, strat_pool, pipe_num, + opt=None): ''' Node Block: - {"name": "transform_timeseries_to_T1template", - "config": ["registration_workflows", "functional_registration", - "func_registration_to_template"], - "switch": ["run"], - "option_key": ["apply_transform", "using"], - "option_val": "default", - "inputs": [(["desc-preproc_bold", "desc-cleaned_bold", - "desc-brain_bold", "desc-motion_bold", "bold"], - "from-bold_to-template_mode-image_xfm"), - "T1w-brain-template-funcreg"], - "outputs": ["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", - "space-template_desc-motion_bold", - "space-template_bold"]} + {"name": "apply_phasediff_to_timeseries_separately", + "config": "None", + "switch": [["registration_workflows", "functional_registration", + "func_registration_to_template", "run"], + ["functional_preproc", "distortion_correction", "run"]], + "option_key": ["registration_workflows", "functional_registration", + "func_registration_to_template", "apply_transform", + "using"], + "option_val": ["default", "single_step_resampling_from_stc", "abcd"], + "inputs": [("sbref", + "desc-preproc_bold", + "desc-stc_bold", + "bold", + "from-bold_to-T1w_mode-image_desc-linear_xfm"), + "despiked-fieldmap", + "pe-direction", + "effectiveEchoSpacing"], + "outputs": ["sbref", + "desc-preproc_bold", + "desc-stc_bold", + "bold"]} + ''' + + outputs = {'desc-preproc_bold': strat_pool.get_data("desc-preproc_bold")} + if not strat_pool.check_rpool("despiked-fieldmap"): + return (wf, outputs) + + invert_coreg_xfm = pe.Node(interface=fsl.ConvertXFM(), + name=f'invert_coreg_xfm_{pipe_num}') + invert_coreg_xfm.inputs.invert_xfm = True + + node, out = strat_pool.get_data("from-bold_to-T1w_mode-image_desc-linear_xfm") + wf.connect(node, out, invert_coreg_xfm, 'in_file') + + warp_fmap = pe.Node(interface=fsl.ApplyWarp(), + name=f'warp_fmap_{pipe_num}') + + node, out = strat_pool.get_data('despiked-fieldmap') + wf.connect(node, out, warp_fmap, 'in_file') + + node, out = strat_pool.get_data('sbref') + wf.connect(node, out, warp_fmap, 'ref_file') + + wf.connect(invert_coreg_xfm, 'out_file', warp_fmap, 'premat') + + mask_fmap = pe.Node(interface=fsl.maths.MathsCommand(), + name=f'mask_fmap_{pipe_num}') + mask_fmap.inputs.args = '-abs -bin' + + wf.connect(warp_fmap, 'out_file', mask_fmap, 'in_file') + + conv_pedir = \ + pe.Node(interface=util.Function(input_names=['pedir', + 'convert'], + output_names=['pedir'], + function=convert_pedir), + name=f'apply_phasediff_convert_pedir_{pipe_num}') + conv_pedir.inputs.convert = 'ijk_to_xyz' + + node, out = strat_pool.get_data('pe-direction') + wf.connect(node, out, conv_pedir, 'pedir') + + fugue_saveshift = pe.Node(interface=fsl.FUGUE(), + name=f'fugue_saveshift_{pipe_num}') + fugue_saveshift.inputs.save_shift = True + + wf.connect(warp_fmap, 'out_file', fugue_saveshift, 'fmap_in_file') + wf.connect(mask_fmap, 'out_file', fugue_saveshift, 'mask_file') + + # FSL calls effective echo spacing = dwell time (not accurate) + node, out = strat_pool.get_data('effectiveEchoSpacing') + wf.connect(node, out, fugue_saveshift, 'dwell_time') + + wf.connect(conv_pedir, 'pedir', fugue_saveshift, 'unwarp_direction') + + shift_warp = pe.Node(interface=fsl.ConvertWarp(), + name=f'shift_warp_{pipe_num}') + shift_warp.inputs.out_relwarp = True + + wf.connect(fugue_saveshift, 'shift_out_file', shift_warp, 'shift_in_file') + + node, out = strat_pool.get_data('sbref') + wf.connect(node, out, shift_warp, 'reference') + + wf.connect(conv_pedir, 'pedir', shift_warp, 'shift_direction') + + warp_bold = pe.Node(interface=fsl.ApplyWarp(), + name=f'warp_bold_phasediff_{pipe_num}') + warp_bold.inputs.relwarp = True + warp_bold.inputs.interp = 'spline' + + if opt == 'default': + node, out = strat_pool.get_data('desc-preproc_bold') + out_label = 'desc-preproc_bold' + elif opt == 'single_step_resampling_from_stc': + node, out = strat_pool.get_data('desc-stc_bold') + out_label = 'desc-stc_bold' + elif opt == 'abcd': + node, out = strat_pool.get_data('bold') + out_label = 'bold' + + wf.connect(node, out, warp_bold, 'in_file') + + node, out = strat_pool.get_data('sbref') + wf.connect(node, out, warp_bold, 'ref_file') + + wf.connect(shift_warp, 'out_file', warp_bold, 'field_file') + + warp_sbref = pe.Node(interface=fsl.ApplyWarp(), + name=f'warp_sbref_phasediff_{pipe_num}') + warp_sbref.inputs.relwarp = True + warp_sbref.inputs.interp = 'spline' + + node, out = strat_pool.get_data('sbref') + wf.connect(node, out, warp_sbref, 'in_file') + wf.connect(node, out, warp_sbref, 'ref_file') + + wf.connect(shift_warp, 'out_file', warp_sbref, 'field_file') + + outputs = { + out_label: (warp_bold, 'out_file'), + 'sbref': (warp_sbref, 'out_file') + } + + return (wf, outputs) + + +def apply_blip_to_timeseries_separately(wf, cfg, strat_pool, pipe_num, + opt=None): + ''' + Node Block: + {"name": "apply_blip_to_timeseries_separately", + "config": "None", + "switch": [["registration_workflows", "functional_registration", + "func_registration_to_template", "run"], + ["functional_preproc", "distortion_correction", "run"]], + "option_key": ["registration_workflows", "functional_registration", + "func_registration_to_template", "apply_transform", + "using"], + "option_val": ["default", "single_step_resampling_from_stc", "abcd"], + "inputs": [("sbref", + "desc-preproc_bold", + "desc-stc_bold", + "bold", + "from-bold_to-template_mode-image_xfm", + "ants-blip-warp", + "fsl-blip-warp")], + "outputs": ["desc-preproc_bold", + "desc-stc_bold", + "bold"]} ''' xfm_prov = strat_pool.get_cpac_provenance( 'from-bold_to-template_mode-image_xfm') reg_tool = check_prov_for_regtool(xfm_prov) + outputs = {'desc-preproc_bold': strat_pool.get_data("desc-preproc_bold")} + if strat_pool.check_rpool("ants-blip-warp"): + if reg_tool == 'fsl': + blip_node, blip_out = strat_pool.get_data("ants-blip-warp") + reg_tool = 'ants' + else: + return (wf, outputs) + elif strat_pool.check_rpool("fsl-blip-warp"): + if reg_tool == 'ants': + blip_node, blip_out = strat_pool.get_data("fsl-blip-warp") + reg_tool = 'fsl' + else: + return (wf, outputs) + else: + return (wf, outputs) + num_cpus = cfg.pipeline_setup['system_config'][ 'max_cores_per_participant'] num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - apply_xfm = apply_transform(f'warp_ts_to_T1template_{pipe_num}', reg_tool, + apply_xfm = apply_transform(f'warp_ts_to_blip_sep_{pipe_num}', reg_tool, time_series=True, num_cpus=num_cpus, num_ants_cores=num_ants_cores) @@ -3069,110 +3348,341 @@ def warp_timeseries_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): 'functional_registration']['func_registration_to_template'][ 'FNIRT_pipelines']['interpolation'] - connect, resource = strat_pool.get_data(["desc-preproc_bold", - "desc-cleaned_bold", - "desc-brain_bold", - "desc-motion_bold", - "bold"], - report_fetched=True) - node, out = connect + connect = strat_pool.get_data("desc-preproc_bold") + + if opt == 'default': + node, out = strat_pool.get_data('desc-preproc_bold') + out_label = 'desc-preproc_bold' + elif opt == 'single_step_resampling_from_stc': + node, out = strat_pool.get_data('desc-stc_bold') + out_label = 'desc-stc_bold' + elif opt == 'abcd': + node, out = strat_pool.get_data('bold') + out_label = 'bold' + wf.connect(node, out, apply_xfm, 'inputspec.input_image') - node, out = strat_pool.get_data("T1w-brain-template-funcreg") + node, out = strat_pool.get_data("sbref") wf.connect(node, out, apply_xfm, 'inputspec.reference') - node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') + wf.connect(blip_node, blip_out, apply_xfm, 'inputspec.transform') outputs = { - f'space-template_{resource}': (apply_xfm, 'outputspec.output_image') + out_label: (apply_xfm, 'outputspec.output_image') } return (wf, outputs) -def warp_timeseries_to_T1template_abcd(wf, cfg, strat_pool, pipe_num, opt=None): - """ - {"name": "transform_timeseries_to_T1template_abcd", - "config": ["registration_workflows", "functional_registration", - "func_registration_to_template"], +def warp_wholeheadT1_to_template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + Node Block: + {"name": "transform_whole_head_T1w_to_T1template", + "config": ["registration_workflows", "anatomical_registration"], "switch": ["run"], - "option_key": ["apply_transform", "using"], - "option_val": "abcd", - "inputs": [["desc-cleaned_bold", "desc-brain_bold", - "desc-motion_bold", "desc-preproc_bold", "bold"], - "bold", - "motion-basefile", - "coordinate-transformation", + "option_key": "None", + "option_val": "None", + "inputs": [("desc-head_T1w", "from-T1w_to-template_mode-image_xfm", - "from-bold_to-T1w_mode-image_desc-linear_xfm", - "from-bold_to-template_mode-image_xfm", - "blip-warp", - "desc-preproc_T1w", - "space-template_res-bold_desc-brain_T1w", - "space-template_desc-bold_mask", - "T1w-brain-template-funcreg"], - "outputs": ["space-template_desc-brain_bold", - "space-template_desc-scout_bold", - "space-template_desc-head_bold"]} - """ + "space-template_desc-head_T1w"), + "T1w-template"], + "outputs": {"space-template_desc-head_T1w": { + "Template": "T1w-template"}}} + ''' - # Apply motion correction, coreg, anat-to-template transforms on raw functional timeseries using ABCD-style registration - # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/OneStepResampling.sh#L168-L197 + xfm_prov = strat_pool.get_cpac_provenance( + 'from-T1w_to-template_mode-image_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) - # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/DistortionCorrectionAndEPIToT1wReg_FLIRTBBRAndFreeSurferBBRbased.sh#L548 - # convertwarp --relout --rel -m ${WD}/fMRI2str.mat --ref=${T1wImage} --out=${WD}/fMRI2str.nii.gz - convert_func_to_anat_linear_warp = pe.Node(interface=fsl.ConvertWarp(), - name=f'convert_func_to_anat_linear_warp_{pipe_num}') + num_cpus = cfg.pipeline_setup['system_config'][ + 'max_cores_per_participant'] - convert_func_to_anat_linear_warp.inputs.out_relwarp = True - convert_func_to_anat_linear_warp.inputs.relwarp = True - - node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, convert_func_to_anat_linear_warp, 'reference') - - if strat_pool.check_rpool('blip-warp'): - node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') - wf.connect(node, out, convert_func_to_anat_linear_warp, 'postmat') + num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - node, out = strat_pool.get_data('blip-warp') - wf.connect(node, out, convert_func_to_anat_linear_warp, 'warp1') - else: - node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') - wf.connect(node, out, convert_func_to_anat_linear_warp, 'premat') + apply_xfm = apply_transform(f'warp_wholehead_T1w_to_T1template_{pipe_num}', + reg_tool, time_series=False, num_cpus=num_cpus, + num_ants_cores=num_ants_cores) - # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/OneStepResampling.sh#L140 - # convertwarp --relout --rel --warp1=${fMRIToStructuralInput} --warp2=${StructuralToStandard} --ref=${WD}/${T1wImageFile}.${FinalfMRIResolution} --out=${OutputTransform} - convert_func_to_standard_warp = pe.Node(interface=fsl.ConvertWarp(), - name=f'convert_func_to_standard_warp_{pipe_num}') + if reg_tool == 'ants': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'ANTs_pipelines']['interpolation'] + elif reg_tool == 'fsl': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'FNIRT_pipelines']['interpolation'] - convert_func_to_standard_warp.inputs.out_relwarp = True - convert_func_to_standard_warp.inputs.relwarp = True + connect = strat_pool.get_data("desc-head_T1w") + node, out = connect + wf.connect(node, out, apply_xfm, 'inputspec.input_image') - wf.connect(convert_func_to_anat_linear_warp, 'out_file', - convert_func_to_standard_warp, 'warp1') + node, out = strat_pool.get_data("T1w-template") + wf.connect(node, out, apply_xfm, 'inputspec.reference') - node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') - wf.connect(node, out, convert_func_to_standard_warp, 'warp2') + node, out = strat_pool.get_data("from-T1w_to-template_mode-image_xfm") + wf.connect(node, out, apply_xfm, 'inputspec.transform') - node, out = strat_pool.get_data('space-template_res-bold_desc-brain_T1w') - wf.connect(node, out, convert_func_to_standard_warp, 'reference') + outputs = { + 'space-template_desc-head_T1w': (apply_xfm, 'outputspec.output_image') + } - # TODO add condition: if no gradient distortion - # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/GenericfMRIVolumeProcessingPipeline.sh#L283-L284 - # fslroi "$fMRIFolder"/"$NameOffMRI"_gdc "$fMRIFolder"/"$NameOffMRI"_gdc_warp 0 3 - extract_func_roi = pe.Node(interface=fsl.ExtractROI(), - name=f'extract_func_roi_{pipe_num}') + return (wf, outputs) - extract_func_roi.inputs.t_min = 0 - extract_func_roi.inputs.t_size = 3 - node, out = strat_pool.get_data('bold') - wf.connect(node, out, extract_func_roi, 'in_file') +def warp_T1mask_to_template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + Node Block: + {"name": "transform_T1mask_to_T1template", + "config": "None", + "switch": [["registration_workflows", "anatomical_registration", "run"], + ["anatomical_preproc", "run"], + ["anatomical_preproc", "brain_extraction", "run"]], + "option_key": "None", + "option_val": "None", + "inputs": [("space-T1w_desc-brain_mask", + "from-T1w_to-template_mode-image_xfm"), + "T1w-template"], + "outputs": {"space-template_desc-brain_mask": { + "Template": "T1w-template"}}} + ''' - # fslmaths "$fMRIFolder"/"$NameOffMRI"_gdc_warp -mul 0 "$fMRIFolder"/"$NameOffMRI"_gdc_warp - multiply_func_roi_by_zero = pe.Node(interface=fsl.maths.MathsCommand(), - name=f'multiply_func_roi_by_zero_{pipe_num}') + xfm_prov = strat_pool.get_cpac_provenance( + 'from-T1w_to-template_mode-image_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) + + num_cpus = cfg.pipeline_setup['system_config'][ + 'max_cores_per_participant'] + + num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] + + apply_xfm = apply_transform(f'warp_T1mask_to_T1template_{pipe_num}', + reg_tool, time_series=False, num_cpus=num_cpus, + num_ants_cores=num_ants_cores) + + apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" + ''' + if reg_tool == 'ants': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'ANTs_pipelines']['interpolation'] + elif reg_tool == 'fsl': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'FNIRT_pipelines']['interpolation'] + ''' + connect = strat_pool.get_data("space-T1w_desc-brain_mask") + node, out = connect + wf.connect(node, out, apply_xfm, 'inputspec.input_image') + + node, out = strat_pool.get_data("T1w-template") + wf.connect(node, out, apply_xfm, 'inputspec.reference') + + node, out = strat_pool.get_data("from-T1w_to-template_mode-image_xfm") + wf.connect(node, out, apply_xfm, 'inputspec.transform') + + outputs = { + 'space-template_desc-brain_mask': (apply_xfm, 'outputspec.output_image') + } + + return (wf, outputs) + + +def warp_timeseries_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + Node Block: + {"name": "transform_timeseries_to_T1template", + "config": ["registration_workflows", "functional_registration", + "func_registration_to_template"], + "switch": ["run"], + "option_key": ["apply_transform", "using"], + "option_val": "default", + "inputs": [("desc-preproc_bold", + "from-bold_to-template_mode-image_xfm"), + "T1w-brain-template-funcreg"], + "outputs": {"space-template_desc-preproc_bold": { + "Template": "T1w-brain-template-funcreg"}}} + ''' + + xfm_prov = strat_pool.get_cpac_provenance( + 'from-bold_to-template_mode-image_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) + + num_cpus = cfg.pipeline_setup['system_config'][ + 'max_cores_per_participant'] + + num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] + + apply_xfm = apply_transform(f'warp_ts_to_T1template_{pipe_num}', reg_tool, + time_series=True, num_cpus=num_cpus, + num_ants_cores=num_ants_cores) + + if reg_tool == 'ants': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'ANTs_pipelines']['interpolation'] + elif reg_tool == 'fsl': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'FNIRT_pipelines']['interpolation'] + + connect = strat_pool.get_data("desc-preproc_bold") + node, out = connect + wf.connect(node, out, apply_xfm, 'inputspec.input_image') + + node, out = strat_pool.get_data("T1w-brain-template-funcreg") + wf.connect(node, out, apply_xfm, 'inputspec.reference') + + node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") + wf.connect(node, out, apply_xfm, 'inputspec.transform') + + outputs = { + 'space-template_desc-preproc_bold': (apply_xfm, 'outputspec.output_image') + } + + return (wf, outputs) + + +def warp_timeseries_to_T1template_deriv(wf, cfg, strat_pool, pipe_num, + opt=None): + ''' + Node Block: + {"name": "transform_timeseries_to_T1template_deriv", + "config": ["registration_workflows", "functional_registration", + "func_registration_to_template"], + "switch": ["run"], + "option_key": ["apply_transform", "using"], + "option_val": "default", + "inputs": [("desc-preproc_bold", + "from-bold_to-template_mode-image_xfm"), + "T1w-brain-template-funcreg"], + "outputs": {"space-template_res-derivative_desc-preproc_bold": { + "Template": "T1w-brain-template-deriv"}}} + ''' + + xfm_prov = strat_pool.get_cpac_provenance( + 'from-bold_to-template_mode-image_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) + + num_cpus = cfg.pipeline_setup['system_config'][ + 'max_cores_per_participant'] + + num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] + + apply_xfm = apply_transform(f'warp_ts_to_T1template_{pipe_num}', reg_tool, + time_series=True, num_cpus=num_cpus, + num_ants_cores=num_ants_cores) + + if reg_tool == 'ants': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'ANTs_pipelines']['interpolation'] + elif reg_tool == 'fsl': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'FNIRT_pipelines']['interpolation'] + + connect = strat_pool.get_data("desc-preproc_bold") + node, out = connect + wf.connect(node, out, apply_xfm, 'inputspec.input_image') + + node, out = strat_pool.get_data("T1w-brain-template-deriv") + wf.connect(node, out, apply_xfm, 'inputspec.reference') + + node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") + wf.connect(node, out, apply_xfm, 'inputspec.transform') + + outputs = { + 'space-template_res-derivative_desc-preproc_bold': + (apply_xfm, 'outputspec.output_image') + } + + return (wf, outputs) + + +def warp_timeseries_to_T1template_abcd(wf, cfg, strat_pool, pipe_num, opt=None): + """ + {"name": "transform_timeseries_to_T1template_abcd", + "config": ["registration_workflows", "functional_registration", + "func_registration_to_template"], + "switch": ["run"], + "option_key": ["apply_transform", "using"], + "option_val": "abcd", + "inputs": [("desc-preproc_bold", + "bold", + "motion-basefile", + "coordinate-transformation"), + "from-T1w_to-template_mode-image_xfm", + "from-bold_to-T1w_mode-image_desc-linear_xfm", + "from-bold_to-template_mode-image_xfm", + "fsl-blip-warp", + "desc-preproc_T1w", + "space-template_res-bold_desc-brain_T1w", + "space-template_desc-bold_mask", + "T1w-brain-template-funcreg"], + "outputs": {"space-template_desc-preproc_bold": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_desc-scout_bold": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_desc-head_bold": { + "Template": "T1w-brain-template-funcreg"}}} + """ + + # Apply motion correction, coreg, anat-to-template transforms on raw functional timeseries using ABCD-style registration + # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/OneStepResampling.sh#L168-L197 + + # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/DistortionCorrectionAndEPIToT1wReg_FLIRTBBRAndFreeSurferBBRbased.sh#L548 + # convertwarp --relout --rel -m ${WD}/fMRI2str.mat --ref=${T1wImage} --out=${WD}/fMRI2str.nii.gz + convert_func_to_anat_linear_warp = pe.Node(interface=fsl.ConvertWarp(), + name=f'convert_func_to_anat_linear_warp_{pipe_num}') + + convert_func_to_anat_linear_warp.inputs.out_relwarp = True + convert_func_to_anat_linear_warp.inputs.relwarp = True + + node, out = strat_pool.get_data('desc-preproc_T1w') + wf.connect(node, out, convert_func_to_anat_linear_warp, 'reference') + + if strat_pool.check_rpool('fsl-blip-warp'): + node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') + wf.connect(node, out, convert_func_to_anat_linear_warp, 'postmat') + + node, out = strat_pool.get_data('fsl-blip-warp') + wf.connect(node, out, convert_func_to_anat_linear_warp, 'warp1') + else: + node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') + wf.connect(node, out, convert_func_to_anat_linear_warp, 'premat') + + # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/scripts/OneStepResampling.sh#L140 + # convertwarp --relout --rel --warp1=${fMRIToStructuralInput} --warp2=${StructuralToStandard} --ref=${WD}/${T1wImageFile}.${FinalfMRIResolution} --out=${OutputTransform} + convert_func_to_standard_warp = pe.Node(interface=fsl.ConvertWarp(), + name=f'convert_func_to_standard_warp_{pipe_num}') + + convert_func_to_standard_warp.inputs.out_relwarp = True + convert_func_to_standard_warp.inputs.relwarp = True + + wf.connect(convert_func_to_anat_linear_warp, 'out_file', + convert_func_to_standard_warp, 'warp1') + + node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') + wf.connect(node, out, convert_func_to_standard_warp, 'warp2') + + node, out = strat_pool.get_data('space-template_res-bold_desc-brain_T1w') + wf.connect(node, out, convert_func_to_standard_warp, 'reference') + + # TODO add condition: if no gradient distortion + # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRIVolume/GenericfMRIVolumeProcessingPipeline.sh#L283-L284 + # fslroi "$fMRIFolder"/"$NameOffMRI"_gdc "$fMRIFolder"/"$NameOffMRI"_gdc_warp 0 3 + extract_func_roi = pe.Node(interface=fsl.ExtractROI(), + name=f'extract_func_roi_{pipe_num}') + + extract_func_roi.inputs.t_min = 0 + extract_func_roi.inputs.t_size = 3 + + node, out = strat_pool.get_data('bold') + wf.connect(node, out, extract_func_roi, 'in_file') + + # fslmaths "$fMRIFolder"/"$NameOffMRI"_gdc_warp -mul 0 "$fMRIFolder"/"$NameOffMRI"_gdc_warp + multiply_func_roi_by_zero = pe.Node(interface=fsl.maths.MathsCommand(), + name=f'multiply_func_roi_by_zero_{pipe_num}') multiply_func_roi_by_zero.inputs.args = '-mul 0' @@ -3368,7 +3878,7 @@ def warp_timeseries_to_T1template_abcd(wf, cfg, strat_pool, pipe_num, opt=None): extract_scout_brain, 'operand_files') outputs = { - 'space-template_desc-brain_bold': (extract_func_brain, 'out_file'), + 'space-template_desc-preproc_bold': (extract_func_brain, 'out_file'), 'space-template_desc-scout_bold': (extract_scout_brain, 'out_file'), 'space-template_desc-head_bold': (merge_func_to_standard, 'merged_file') } @@ -3388,11 +3898,14 @@ def warp_timeseries_to_T1template_dcan_nhp(wf, cfg, strat_pool, pipe_num, opt=No "coordinate-transformation", "from-T1w_to-template_mode-image_warp", "from-bold_to-T1w_mode-image_desc-linear_warp", + "T1w-template", "space-template_desc-head_T1w", "space-template_desc-T1w_mask", "space-template_desc-T1wT2w_biasfield")], - "outputs": ["space-template_desc-brain_bold", - "space-template_desc-bold_mask"]} + "outputs": {"space-template_desc-preproc_bold": { + "Template": "T1w-template"}, + "space-template_desc-bold_mask": { + "Template": "T1w-template"}}} """ # Apply motion correction, coreg, anat-to-template transforms on raw functional timeseries @@ -3650,41 +4163,144 @@ def warp_timeseries_to_T1template_dcan_nhp(wf, cfg, strat_pool, pipe_num, opt=No wf.connect(find_min_mask, 'out_file', func_mask_final, 'operand_files') outputs = { - 'space-template_desc-brain_bold': (extract_func_brain, 'out_file'), + 'space-template_desc-preproc_bold': (extract_func_brain, 'out_file'), 'space-template_desc-bold_mask': (func_mask_final, 'out_file') } return (wf, outputs) +def warp_denoiseNofilt_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + Node Block: + {"name": "transform_denoisedNofilt_to_T1template", + "config": ["amplitude_low_frequency_fluctuation"], + "switch": ["run"], + "option_key": ["target_space"], + "option_val": "Template", + "inputs": [(["desc-denoisedNofilt_bold"], + "from-bold_to-template_mode-image_xfm"), + "T1w-brain-template-deriv"], + "outputs": {"space-template_res-derivative_desc-denoisedNofilt_bold": { + "Template": "T1w-brain-template-deriv"}}} + ''' + + xfm_prov = strat_pool.get_cpac_provenance( + 'from-bold_to-template_mode-image_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) + + num_cpus = cfg.pipeline_setup['system_config'][ + 'max_cores_per_participant'] + + num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] + + apply_xfm = apply_transform(f'warp_denoisedNofilt_to_T1template_{pipe_num}', reg_tool, + time_series=True, num_cpus=num_cpus, + num_ants_cores=num_ants_cores) + + if reg_tool == 'ants': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'ANTs_pipelines']['interpolation'] + elif reg_tool == 'fsl': + apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ + 'functional_registration']['func_registration_to_template'][ + 'FNIRT_pipelines']['interpolation'] + + node, out = strat_pool.get_data("desc-denoisedNofilt_bold") + wf.connect(node, out, apply_xfm, 'inputspec.input_image') + + node, out = strat_pool.get_data("T1w-brain-template-deriv") + wf.connect(node, out, apply_xfm, 'inputspec.reference') + + node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") + wf.connect(node, out, apply_xfm, 'inputspec.transform') + + outputs = { + f'space-template_res-derivative_desc-denoisedNofilt_bold': (apply_xfm, 'outputspec.output_image') + } + + return (wf, outputs) + + def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): - """ - {"name": "single_step_resample_timeseries_to_T1template", + ''' + Apply motion correction, coreg, anat-to-template transforms on + slice-time corrected functional timeseries based on fMRIPrep + pipeline + + Copyright (c) 2015-2018, the CRN developers team. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of fmriprep nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + + Ref: https://github.com/nipreps/fmriprep/blob/84a6005b/fmriprep/workflows/bold/resampling.py#L159-L419 + + Node Block: + {"name": "single_step_resample_stc_timeseries_to_T1template", "config": ["registration_workflows", "functional_registration", "func_registration_to_template"], "switch": ["run"], "option_key": ["apply_transform", "using"], - "option_val": "single_step_resampling", - "inputs": [(["desc-reginput_bold", "desc-mean_bold"], - "desc-preproc_bold", + "option_val": "single_step_resampling_from_stc", + "inputs": [("sbref", + "desc-stc_bold", "motion-basefile", "space-bold_desc-brain_mask", "coordinate-transformation", "from-T1w_to-template_mode-image_xfm", "from-bold_to-T1w_mode-image_desc-linear_xfm", "from-bold_to-template_mode-image_xfm", + "ants-blip-warp", + "fsl-blip-warp", "T1w", - "desc-brain_T1w", - "T1w-brain-template-funcreg")], - "outputs": ["space-template_desc-preproc_bold", - "space-template_desc-brain_bold", - "space-template_desc-bold_mask"]} - """ - - # Apply motion correction, coreg, anat-to-template transforms on raw functional timeseries based on fMRIPrep pipeline - # Ref: https://github.com/nipreps/fmriprep/blob/master/fmriprep/workflows/bold/resampling.py#L159-L419 - + "desc-preproc_T1w", + "T1w-brain-template-funcreg", + "T1w-brain-template-deriv")], + "outputs": {"space-template_desc-preproc_bold": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_desc-brain_bold": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_desc-bold_mask": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_desc-head_bold": { + "Template": "T1w-brain-template-funcreg"}, + "space-template_res-derivative_desc-preproc_bold": { + "Template": "T1w-brain-template-deriv"}, + "space-template_res-derivative_desc-bold_mask": { + "Template": "T1w-brain-template-deriv"}}} + ''' # noqa: 501 + xfm_prov = strat_pool.get_cpac_provenance( + 'from-T1w_to-template_mode-image_xfm') + reg_tool = check_prov_for_regtool(xfm_prov) + bbr2itk = pe.Node(util.Function(input_names=['reference_file', 'source_file', 'transform_file'], @@ -3701,13 +4317,14 @@ def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool, elif cfg.registration_workflows['functional_registration'][ 'coregistration']['boundary_based_registration'][ 'reference'] == 'brain': - node, out = strat_pool.get_data('desc-brain_T1w') + node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, bbr2itk, 'reference_file') - node, out = strat_pool.get_data(['desc-reginput_bold', 'desc-mean_bold']) + node, out = strat_pool.get_data('sbref') wf.connect(node, out, bbr2itk, 'source_file') - node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') + node, out = strat_pool.get_data( + 'from-bold_to-T1w_mode-image_desc-linear_xfm') wf.connect(node, out, bbr2itk, 'transform_file') split_func = pe.Node(interface=fsl.Split(), @@ -3715,7 +4332,7 @@ def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool, split_func.inputs.dimension = 't' - node, out = strat_pool.get_data('desc-preproc_bold') + node, out = strat_pool.get_data('desc-stc_bold') wf.connect(node, out, split_func, 'in_file') ### Loop starts! ### @@ -3748,9 +4365,20 @@ def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool, wf.connect(convert_transform, 'transform_directory', motionxfm2itk, 'transform_file') - collectxfm = pe.MapNode(util.Merge(4), + merge_num = 4 + blip = False + if strat_pool.check_rpool('ants-blip-warp') and reg_tool == 'ants': + blip_node, blip_out = strat_pool.get_data('ants-blip-warp') + merge_num = 5 + blip = True + elif strat_pool.check_rpool('fsl-blip-warp') and reg_tool == 'fsl': + blip_node, blip_out = strat_pool.get_data('fsl-blip-warp') + merge_num = 5 + blip = True + + collectxfm = pe.MapNode(util.Merge(merge_num), name=f'collectxfm_func_to_standard_{pipe_num}', - iterfield=['in4']) + iterfield=[f'in{merge_num}']) node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') wf.connect(node, out, collectxfm, 'in1') @@ -3760,38 +4388,59 @@ def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool, collectxfm.inputs.in3 = 'identity' - wf.connect(motionxfm2itk, 'itk_transform', - collectxfm, 'in4') + if blip: + wf.connect(blip_node, blip_out, collectxfm, 'in4') - applyxfm_func_to_standard = pe.MapNode(interface=ants.ApplyTransforms(), - name=f'applyxfm_func_to_standard_{pipe_num}', - iterfield=['input_image', 'transforms']) + wf.connect(motionxfm2itk, 'itk_transform', + collectxfm, f'in{merge_num}') + applyxfm_func_to_standard = pe.MapNode( + interface=ants.ApplyTransforms(), + name=f'applyxfm_func_to_standard_{pipe_num}', + iterfield=['input_image', 'transforms']) applyxfm_func_to_standard.inputs.float = True applyxfm_func_to_standard.inputs.interpolation = 'LanczosWindowedSinc' + applyxfm_derivfunc_to_standard = pe.MapNode( + interface=ants.ApplyTransforms(), + name=f'applyxfm_derivfunc_to_standard_{pipe_num}', + iterfield=['input_image', 'transforms']) + applyxfm_derivfunc_to_standard.inputs.float = True + applyxfm_derivfunc_to_standard.inputs.interpolation = 'LanczosWindowedSinc' + wf.connect(split_func, 'out_files', applyxfm_func_to_standard, 'input_image') + wf.connect(split_func, 'out_files', + applyxfm_derivfunc_to_standard, 'input_image') node, out = strat_pool.get_data('T1w-brain-template-funcreg') wf.connect(node, out, applyxfm_func_to_standard, 'reference_image') + + node, out = strat_pool.get_data('T1w-brain-template-deriv') + wf.connect(node, out, applyxfm_derivfunc_to_standard, 'reference_image') - wf.connect(collectxfm, 'out', - applyxfm_func_to_standard, 'transforms') + wf.connect(collectxfm, 'out', applyxfm_func_to_standard, 'transforms') + wf.connect(collectxfm, 'out', applyxfm_derivfunc_to_standard, 'transforms') ### Loop ends! ### merge_func_to_standard = pe.Node(interface=fslMerge(), name=f'merge_func_to_standard_{pipe_num}') - merge_func_to_standard.inputs.dimension = 't' wf.connect(applyxfm_func_to_standard, 'output_image', - merge_func_to_standard, 'in_files') + merge_func_to_standard, 'in_files') + + merge_derivfunc_to_standard = pe.Node( + interface=fslMerge(), name=f'merge_derivfunc_to_standard_{pipe_num}') + merge_derivfunc_to_standard.inputs.dimension = 't' - applyxfm_func_mask_to_standard = pe.Node(interface=ants.ApplyTransforms(), - name=f'applyxfm_func_mask_to_standard_{pipe_num}') + wf.connect(applyxfm_derivfunc_to_standard, 'output_image', + merge_derivfunc_to_standard, 'in_files') + applyxfm_func_mask_to_standard = pe.Node( + interface=ants.ApplyTransforms(), + name=f'applyxfm_func_mask_to_standard_{pipe_num}') applyxfm_func_mask_to_standard.inputs.interpolation = 'MultiLabel' node, out = strat_pool.get_data('space-bold_desc-brain_mask') @@ -3800,274 +4449,91 @@ def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool, node, out = strat_pool.get_data('T1w-brain-template-funcreg') wf.connect(node, out, applyxfm_func_mask_to_standard, 'reference_image') - collectxfm_mask = pe.Node(util.Merge(2), - name=f'collectxfm_func_mask_to_standard_{pipe_num}') + collectxfm_mask = pe.Node( + util.Merge(2), name=f'collectxfm_func_mask_to_standard_{pipe_num}') node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') wf.connect(node, out, collectxfm_mask, 'in1') - wf.connect(bbr2itk, 'itk_transform', - collectxfm_mask, 'in2') + wf.connect(bbr2itk, 'itk_transform', collectxfm_mask, 'in2') wf.connect(collectxfm_mask, 'out', - applyxfm_func_mask_to_standard, 'transforms') - - apply_mask = pe.Node(interface=fsl.maths.ApplyMask(), - name=f'get_func_brain_to_standard_{pipe_num}') - - wf.connect(merge_func_to_standard, 'merged_file', - apply_mask, 'in_file') - - wf.connect(applyxfm_func_mask_to_standard, 'output_image', - apply_mask, 'mask_file') + applyxfm_func_mask_to_standard, 'transforms') - outputs = { - 'space-template_desc-preproc_bold': (merge_func_to_standard, - 'merged_file'), - 'space-template_desc-brain_bold': (apply_mask, 'out_file'), - 'space-template_desc-bold_mask': (applyxfm_func_mask_to_standard, - 'output_image'), - } - - return (wf, outputs) - - -def single_step_resample_stc_timeseries_to_T1template(wf, cfg, strat_pool, - pipe_num, opt=None): - """ - {"name": "single_step_resample_stc_timeseries_to_T1template", - "config": ["registration_workflows", "functional_registration", - "func_registration_to_template"], - "switch": ["run"], - "option_key": ["apply_transform", "using"], - "option_val": "single_step_resampling_from_stc", - "inputs": [(["desc-reginput_bold", "desc-mean_bold"], - "desc-stc_bold", - "motion-basefile", - "space-bold_desc-brain_mask", - "coordinate-transformation", - "from-T1w_to-template_mode-image_xfm", - "from-bold_to-T1w_mode-image_desc-linear_xfm", - "from-bold_to-template_mode-image_xfm", - "T1w", - "desc-brain_T1w", - "T1w-brain-template-funcreg")], - "outputs": ["space-template_desc-stc_bold", - "space-template_desc-stc-brain_bold", - "space-template_desc-bold_mask"]} - """ - - # Apply motion correction, coreg, anat-to-template transforms on raw functional timeseries based on fMRIPrep pipeline - # Ref: https://github.com/nipreps/fmriprep/blob/84a6005b/fmriprep/workflows/bold/resampling.py#L159-L419 - - bbr2itk = pe.Node(util.Function(input_names=['reference_file', - 'source_file', - 'transform_file'], - output_names=['itk_transform'], - function=run_c3d), - name=f'convert_bbr2itk_{pipe_num}') - - if cfg.registration_workflows['functional_registration'][ - 'coregistration']['boundary_based_registration'][ - 'reference'] == 'whole-head': - node, out = strat_pool.get_data('T1w') - wf.connect(node, out, bbr2itk, 'reference_file') - - elif cfg.registration_workflows['functional_registration'][ - 'coregistration']['boundary_based_registration'][ - 'reference'] == 'brain': - node, out = strat_pool.get_data('desc-brain_T1w') - wf.connect(node, out, bbr2itk, 'reference_file') - - node, out = strat_pool.get_data(['desc-reginput_bold', 'desc-mean_bold']) - wf.connect(node, out, bbr2itk, 'source_file') - - node, out = strat_pool.get_data('from-bold_to-T1w_mode-image_desc-linear_xfm') - wf.connect(node, out, bbr2itk, 'transform_file') - - split_func = pe.Node(interface=fsl.Split(), - name=f'split_func_{pipe_num}') - - split_func.inputs.dimension = 't' - - node, out = strat_pool.get_data('desc-stc_bold') - wf.connect(node, out, split_func, 'in_file') - - ### Loop starts! ### - motionxfm2itk = pe.MapNode(util.Function( - input_names=['reference_file', - 'source_file', - 'transform_file'], - output_names=['itk_transform'], - function=run_c3d), - name=f'convert_motionxfm2itk_{pipe_num}', - iterfield=['transform_file']) - - node, out = strat_pool.get_data('motion-basefile') - wf.connect(node, out, motionxfm2itk, 'reference_file') - wf.connect(node, out, motionxfm2itk, 'source_file') - - node, out = strat_pool.get_data('coordinate-transformation') - motion_correct_tool = check_prov_for_motion_tool( - strat_pool.get_cpac_provenance('coordinate-transformation')) - if motion_correct_tool == 'mcflirt': - wf.connect(node, out, motionxfm2itk, 'transform_file') - elif motion_correct_tool == '3dvolreg': - convert_transform = pe.Node(util.Function( - input_names=['one_d_filename'], - output_names=['transform_directory'], - function=one_d_to_mat, - imports=['import os', 'import numpy as np']), - name=f'convert_transform_{pipe_num}') - wf.connect(node, out, convert_transform, 'one_d_filename') - wf.connect(convert_transform, 'transform_directory', - motionxfm2itk, 'transform_file') - - collectxfm = pe.MapNode(util.Merge(4), - name=f'collectxfm_func_to_standard_{pipe_num}', - iterfield=['in4']) - - node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') - wf.connect(node, out, collectxfm, 'in1') - - wf.connect(bbr2itk, 'itk_transform', - collectxfm, 'in2') - - collectxfm.inputs.in3 = 'identity' - - wf.connect(motionxfm2itk, 'itk_transform', - collectxfm, 'in4') - - applyxfm_func_to_standard = pe.MapNode(interface=ants.ApplyTransforms(), - name=f'applyxfm_func_to_standard_{pipe_num}', - iterfield=['input_image', 'transforms']) - - applyxfm_func_to_standard.inputs.float = True - applyxfm_func_to_standard.inputs.interpolation = 'LanczosWindowedSinc' - - wf.connect(split_func, 'out_files', - applyxfm_func_to_standard, 'input_image') - - node, out = strat_pool.get_data('T1w-brain-template-funcreg') - wf.connect(node, out, applyxfm_func_to_standard, 'reference_image') - - wf.connect(collectxfm, 'out', - applyxfm_func_to_standard, 'transforms') - - ### Loop ends! ### - - merge_func_to_standard = pe.Node(interface=fslMerge(), - name=f'merge_func_to_standard_{pipe_num}') - - merge_func_to_standard.inputs.dimension = 't' - - wf.connect(applyxfm_func_to_standard, 'output_image', - merge_func_to_standard, 'in_files') - - applyxfm_func_mask_to_standard = pe.Node(interface=ants.ApplyTransforms(), - name=f'applyxfm_func_mask_to_standard_{pipe_num}') - - applyxfm_func_mask_to_standard.inputs.interpolation = 'MultiLabel' + applyxfm_deriv_mask_to_standard = pe.Node( + interface=ants.ApplyTransforms(), + name=f'applyxfm_deriv_mask_to_standard_{pipe_num}') + applyxfm_deriv_mask_to_standard.inputs.interpolation = 'MultiLabel' node, out = strat_pool.get_data('space-bold_desc-brain_mask') - wf.connect(node, out, applyxfm_func_mask_to_standard, 'input_image') + wf.connect(node, out, applyxfm_deriv_mask_to_standard, 'input_image') - node, out = strat_pool.get_data('T1w-brain-template-funcreg') - wf.connect(node, out, applyxfm_func_mask_to_standard, 'reference_image') + node, out = strat_pool.get_data('T1w-brain-template-deriv') + wf.connect(node, out, applyxfm_deriv_mask_to_standard, 'reference_image') - collectxfm_mask = pe.Node(util.Merge(2), - name=f'collectxfm_func_mask_to_standard_{pipe_num}') + collectxfm_deriv_mask = pe.Node( + util.Merge(2), name=f'collectxfm_deriv_mask_to_standard_{pipe_num}') node, out = strat_pool.get_data('from-T1w_to-template_mode-image_xfm') - wf.connect(node, out, collectxfm_mask, 'in1') + wf.connect(node, out, collectxfm_deriv_mask, 'in1') wf.connect(bbr2itk, 'itk_transform', - collectxfm_mask, 'in2') + collectxfm_deriv_mask, 'in2') - wf.connect(collectxfm_mask, 'out', - applyxfm_func_mask_to_standard, 'transforms') + wf.connect(collectxfm_deriv_mask, 'out', + applyxfm_deriv_mask_to_standard, 'transforms') apply_mask = pe.Node(interface=fsl.maths.ApplyMask(), name=f'get_func_brain_to_standard_{pipe_num}') wf.connect(merge_func_to_standard, 'merged_file', - apply_mask, 'in_file') + apply_mask, 'in_file') wf.connect(applyxfm_func_mask_to_standard, 'output_image', - apply_mask, 'mask_file') + apply_mask, 'mask_file') outputs = { - 'space-template_desc-stc_bold': (merge_func_to_standard, - 'merged_file'), - 'space-template_desc-stc-brain_bold': (apply_mask, 'out_file'), + 'space-template_desc-head_bold': (merge_func_to_standard, + 'merged_file'), + 'space-template_desc-brain_bold': (apply_mask, 'out_file'), + 'space-template_desc-preproc_bold': (apply_mask, 'out_file'), 'space-template_desc-bold_mask': (applyxfm_func_mask_to_standard, - 'output_image'), + 'output_image'), + 'space-template_res-derivative_desc-preproc_bold': + (merge_derivfunc_to_standard, 'merged_file'), + 'space-template_res-derivative_desc-bold_mask': + (applyxfm_deriv_mask_to_standard, 'output_image') } return (wf, outputs) - - -def warp_bold_mean_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): +def warp_sbref_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): ''' Node Block: - {"name": "transform_bold_mean_to_T1template", + {"name": "transform_sbref_to_T1template", "config": "None", - "switch": [["registration_workflows", "functional_registration", + "switch": ["registration_workflows", "functional_registration", "func_registration_to_template", "run"], - ["functional_preproc", "generate_func_mean", "run"]], "option_key": "None", "option_val": "None", - "inputs": [("desc-mean_bold", + "inputs": [("sbref", "from-bold_to-template_mode-image_xfm"), "T1w-brain-template-funcreg"], "outputs": { - "space-template_desc-mean_bold": { - "Description": "Single-volume mean of the BOLD time-series " + "space-template_sbref": { + "Description": "Single-volume sbref of the BOLD time-series " "transformed to template space.", "Template": "T1w-brain-template-funcreg"}} } ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-template_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_bold_mask_to_T1template_{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - if reg_tool == 'ants': - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ - 'functional_registration']['func_registration_to_template'][ - 'ANTs_pipelines']['interpolation'] - elif reg_tool == 'fsl': - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ - 'functional_registration']['func_registration_to_template'][ - 'FNIRT_pipelines']['interpolation'] - - node, out = strat_pool.get_data("desc-mean_bold") - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("T1w-brain-template-funcreg") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - 'space-template_desc-mean_bold': - (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) + xfm = 'from-bold_to-template_mode-image_xfm' + wf, apply_xfm = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'sbref', xfm, + reference='T1w-brain-template-funcreg', time_series=False)[:2] + outputs = {'space-template_sbref': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) def warp_bold_mask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): @@ -4081,44 +4547,20 @@ def warp_bold_mask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": ["registration_workflows", "functional_registration", "func_registration_to_template", "apply_transform", "using"], - "option_val": "default", + "option_val": ["default", "abcd", "dcan_nhp"], "inputs": [("space-bold_desc-brain_mask", "from-bold_to-template_mode-image_xfm"), "T1w-brain-template-funcreg"], - "outputs": ["space-template_desc-bold_mask"]} + "outputs": {"space-template_desc-bold_mask": { + "Template": "T1w-brain-template-funcreg"}}} ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-template_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_bold_mask_to_T1template_{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" - - node, out = strat_pool.get_data("space-bold_desc-brain_mask") - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("T1w-brain-template-funcreg") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - 'space-template_desc-bold_mask': - (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) + xfm = 'from-bold_to-template_mode-image_xfm' + wf, apply_xfm = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'space-bold_desc-brain_mask', xfm, + reference='T1w-brain-template-funcreg', time_series=False)[:2] + outputs = {'space-template_desc-bold_mask': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) def warp_deriv_mask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): @@ -4134,44 +4576,20 @@ def warp_deriv_mask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": ["registration_workflows", "functional_registration", "func_registration_to_template", "apply_transform", "using"], - "option_val": "default", + "option_val": ["default", "abcd", "dcan_nhp"], "inputs": [("space-bold_desc-brain_mask", "from-bold_to-template_mode-image_xfm"), "T1w-brain-template-deriv"], - "outputs": ["space-template_res-derivative_desc-bold_mask"]} + "outputs": {"space-template_res-derivative_desc-bold_mask": { + "Template": "T1w-brain-template-deriv"}}} ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-template_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_deriv_mask_to_T1template_{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" - - node, out = strat_pool.get_data("space-bold_desc-brain_mask") - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("T1w-brain-template-deriv") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - f'space-template_res-derivative_desc-bold_mask': - (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) + xfm = 'from-bold_to-template_mode-image_xfm' + wf, apply_xfm = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'space-bold_desc-brain_mask', xfm, + reference='T1w-brain-template-deriv', time_series=False)[:2] + outputs = {'space-template_res-derivative_desc-bold_mask': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) def warp_timeseries_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): @@ -4183,54 +4601,20 @@ def warp_timeseries_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run_EPI"], "option_key": "None", "option_val": "None", - "inputs": [(["desc-preproc_bold", "bold"], + "inputs": [("desc-preproc_bold", "from-bold_to-EPItemplate_mode-image_xfm"), "EPI-template"], - "outputs": ["space-EPItemplate_desc-cleaned_bold", - "space-EPItemplate_desc-brain_bold", - "space-EPItemplate_desc-preproc_bold", - "space-EPItemplate_bold"]} + "outputs": { + "space-template_desc-preproc_bold": { + "Template": "EPI-template"}}} ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-EPItemplate_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_ts_to_EPItemplate_{pipe_num}', reg_tool, - time_series=True, num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - if reg_tool == 'ants': - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ - 'functional_registration']['func_registration_to_template'][ - 'ANTs_pipelines']['interpolation'] - elif reg_tool == 'fsl': - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ - 'functional_registration']['func_registration_to_template'][ - 'FNIRT_pipelines']['interpolation'] - - connect, resource = strat_pool.get_data(["desc-preproc_bold", - "bold"], - report_fetched=True) - node, out = connect - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - f'space-EPItemplate_{resource}': (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) + xfm = 'from-bold_to-EPItemplate_mode-image_xfm' + wf, apply_xfm, resource = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'desc-preproc_bold', xfm, + time_series=True) + outputs = {f'space-template_{resource}': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) def warp_bold_mean_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): @@ -4245,47 +4629,17 @@ def warp_bold_mean_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): "inputs": [("desc-mean_bold", "from-bold_to-EPItemplate_mode-image_xfm"), "EPI-template"], - "outputs": ["space-EPItemplate_desc-mean_bold"]} + "outputs": { + "space-template_desc-mean_bold": { + "Template": "EPI-template"}}} ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-EPItemplate_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_bold_mask_to_EPItemplate_{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - if reg_tool == 'ants': - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ - 'functional_registration']['func_registration_to_template'][ - 'ANTs_pipelines']['interpolation'] - elif reg_tool == 'fsl': - apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[ - 'functional_registration']['func_registration_to_template'][ - 'FNIRT_pipelines']['interpolation'] - - node, out = strat_pool.get_data("desc-mean_bold") - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - 'space-EPItemplate_desc-mean_bold': - (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) + xfm = 'from-bold_to-EPItemplate_mode-image_xfm' + wf, apply_xfm = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'desc-mean_bold', xfm, + time_series=False)[:2] + outputs = {'space-template_desc-mean_bold': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) def warp_bold_mask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): @@ -4300,40 +4654,17 @@ def warp_bold_mask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): "inputs": [("space-bold_desc-brain_mask", "from-bold_to-EPItemplate_mode-image_xfm"), "EPI-template"], - "outputs": ["space-EPItemplate_desc-bold_mask"]} + "outputs": { + "space-template_desc-bold_mask": { + "Template": "EPI-template"}}} ''' - - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-EPItemplate_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_bold_mask_to_EPItemplate_{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" - - node, out = strat_pool.get_data("space-bold_desc-brain_mask") - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - 'space-EPItemplate_desc-bold_mask': - (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) + xfm = 'from-bold_to-EPItemplate_mode-image_xfm' + wf, apply_xfm = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'space-bold_desc-brain_mask', xfm, + time_series=False)[:2] + outputs = {'space-template_desc-bold_mask': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) def warp_deriv_mask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): @@ -4350,47 +4681,23 @@ def warp_deriv_mask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): "inputs": [("space-bold_desc-brain_mask", "from-bold_to-EPItemplate_mode-image_xfm"), "EPI-template"], - "outputs": ["space-EPItemplate_res-derivative_desc-bold_mask"]} + "outputs": { + "space-template_res-derivative_desc-bold_mask": { + "Template": "EPI-template"}}} ''' - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-EPItemplate_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] - - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] - - apply_xfm = apply_transform(f'warp_deriv_mask_to_EPItemplate_{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) - - apply_xfm.inputs.inputspec.interpolation = "NearestNeighbor" - - node, out = strat_pool.get_data("space-bold_desc-brain_mask") - wf.connect(node, out, apply_xfm, 'inputspec.input_image') - - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm, 'inputspec.reference') - - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm, 'inputspec.transform') - - outputs = { - f'space-EPItemplate_res-derivative_desc-bold_mask': - (apply_xfm, 'outputspec.output_image') - } - - return (wf, outputs) - + xfm = 'from-bold_to-EPItemplate_mode-image_xfm' + wf, apply_xfm = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, 'space-bold_desc-brain_mask', xfm, + time_series=False)[:2] + outputs = {'space-template_res-derivative_desc-bold_mask': + (apply_xfm, 'outputspec.output_image')} + return _warp_return(wf, apply_xfm, outputs) - -def warp_Tissuemask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): +def warp_tissuemask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): ''' Node Block: - {"name": "warp_Tissuemask_to_T1template", + {"name": "warp_tissuemask_to_T1template", "config": "None", "switch": ["registration_workflows", "anatomical_registration", "run"], "option_key": "None", @@ -4400,48 +4707,25 @@ def warp_Tissuemask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None): "label-GM_mask", "from-T1w_to-template_mode-image_xfm"), "T1w-template"], - "outputs": ["space-template_label-CSF_mask", - "space-template_label-WM_mask", - "space-template_label-GM_mask"]} + "outputs": {"space-template_label-CSF_mask": { + "Template": "T1w-template"}, + "space-template_label-WM_mask": { + "Template": "T1w-template"}, + "space-template_label-GM_mask": { + "Template": "T1w-template"}}} ''' - xfm_prov = strat_pool.get_cpac_provenance( - 'from-T1w_to-template_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - tissue_types = ['CSF', 'WM', 'GM'] - apply_xfm = { - tissue: apply_transform(f'warp_Tissuemask_to_T1template_{tissue}_' - f'{pipe_num}', reg_tool, time_series=False, - num_cpus=cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'], - num_ants_cores=cfg.pipeline_setup[ - 'system_config']['num_ants_threads']) for - tissue in tissue_types} - for tissue in tissue_types: - if reg_tool == 'ants': - apply_xfm[tissue].inputs.inputspec.interpolation = \ - 'NearestNeighbor' - elif reg_tool == 'fsl': - apply_xfm[tissue].inputs.inputspec.interpolation = 'nn' - if strat_pool.check_rpool(f'label-{tissue}_mask'): - node, out = strat_pool.get_data(f'label-{tissue}_mask') - wf.connect(node, out, apply_xfm[tissue], 'inputspec.input_image') - node, out = strat_pool.get_data('T1w-template') - wf.connect(node, out, apply_xfm[tissue], 'inputspec.reference') - node, out = strat_pool.get_data('from-T1w_to-template_' - 'mode-image_xfm') - wf.connect(node, out, apply_xfm[tissue], 'inputspec.transform') - outputs = {f'space-template_label-{tissue}_mask': (apply_xfm[tissue], - 'outputspec.output_image') for tissue in tissue_types} + return warp_tissuemask_to_template(wf, cfg, strat_pool, pipe_num, + xfm='from-T1w_to-template_mode-image_' + 'xfm', template_space='T1') - return (wf, outputs) - -def warp_Tissuemask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): +def warp_tissuemask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): ''' Node Block: - {"name": "warp_Tissuemask_to_EPItemplate", + {"name": "warp_tissuemask_to_EPItemplate", "config": "None", - "switch": ["registration_workflows", "functional_registration", "EPI_registration", "run"], + "switch": ["registration_workflows", "functional_registration", + "EPI_registration", "run"], "option_key": "None", "option_val": "None", "inputs": [("label-CSF_mask", @@ -4449,85 +4733,143 @@ def warp_Tissuemask_to_EPItemplate(wf, cfg, strat_pool, pipe_num, opt=None): "label-GM_mask", "from-bold_to-EPItemplate_mode-image_xfm"), "EPI-template"], - "outputs": ["space-EPItemplate_label-CSF_mask", - "space-EPItemplate_label-WM_mask", - "space-EPItemplate_label-GM_mask"]} + "outputs": { + "space-template_label-CSF_mask": { + "Template": "EPI-template"}, + "space-template_label-WM_mask": { + "Template": "EPI-template"}, + "space-template_label-GM_mask": { + "Template": "EPI-template"}}} ''' + return warp_tissuemask_to_template(wf, cfg, strat_pool, pipe_num, + xfm='from-bold_to-EPItemplate_' + 'mode-image_xfm', + template_space='EPI') - xfm_prov = strat_pool.get_cpac_provenance( - 'from-bold_to-EPItemplate_mode-image_xfm') - reg_tool = check_prov_for_regtool(xfm_prov) - num_cpus = cfg.pipeline_setup['system_config'][ - 'max_cores_per_participant'] +def warp_tissuemask_to_template(wf, cfg, strat_pool, pipe_num, xfm, + template_space): + '''Function to apply transforms to tissue masks - num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads'] + Parameters + ---------- + wf, cfg, strat_pool, pipe_num + passed through from Node Block - apply_xfm_CSF = apply_transform(f'warp_Tissuemask_to_EPItemplate_CSF{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) + xfm : str + transform - apply_xfm_WM = apply_transform(f'warp_Tissuemask_to_EPItemplate_WM{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) + template_space : str + T1 or EPI - apply_xfm_GM = apply_transform(f'warp_Tissuemask_to_EPItemplate_GM{pipe_num}', - reg_tool, time_series=False, - num_cpus=num_cpus, - num_ants_cores=num_ants_cores) + Returns + ------- + wf : nipype.pipeline.engine.workflows.Workflow - if reg_tool == 'ants': - apply_xfm_CSF.inputs.inputspec.interpolation = 'NearestNeighbor' - apply_xfm_WM.inputs.inputspec.interpolation = 'NearestNeighbor' - apply_xfm_GM.inputs.inputspec.interpolation = 'NearestNeighbor' - elif reg_tool == 'fsl': - apply_xfm_CSF.inputs.inputspec.interpolation = 'nn' - apply_xfm_WM.inputs.inputspec.interpolation = 'nn' - apply_xfm_GM.inputs.inputspec.interpolation = 'nn' + outputs : dict + ''' + tissue_types = ['CSF', 'WM', 'GM'] + apply_xfm = {} + for tissue in tissue_types: + wf, apply_xfm[tissue] = warp_resource_to_template( + wf, cfg, strat_pool, pipe_num, f'label-{tissue}_mask', xfm, + time_series=False)[:2] + if template_space == 'T1': + template_space = '' + outputs = {f'space-{template_space}template_label-{tissue}_mask': ( + apply_xfm[tissue], 'outputspec.output_image') for + tissue in tissue_types} + return _warp_return(wf, apply_xfm, outputs) + + +def warp_resource_to_template(wf: pe.Workflow, cfg, strat_pool, pipe_num: int, + input_resource: Union[list, str], xfm: str, + reference: Optional[str] = None, + time_series: Optional[bool] = False + ) -> Tuple[pe.Workflow, pe.Workflow, str]: + '''Function to warp a resource into a template space - outputs = {} - if strat_pool.check_rpool('label-CSF_mask'): - node, out = strat_pool.get_data("label-CSF_mask") - wf.connect(node, out, apply_xfm_CSF, 'inputspec.input_image') - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm_CSF, 'inputspec.reference') - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm_CSF, 'inputspec.transform') - outputs.update({ - f'space-EPItemplate_label-CSF_mask': + Parameters + ---------- + wf : pe.Workflow - (apply_xfm_CSF, 'outputspec.output_image')}) + cfg : CPAC.utils.configuration.Configuration + strat_pool : CPAC.pipeline.engine.ResourcePool + pipe_num : int - if strat_pool.check_rpool('label-WM_mask'): - node, out = strat_pool.get_data("label-WM_mask") - wf.connect(node, out, apply_xfm_WM, 'inputspec.input_image') - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm_WM, 'inputspec.reference') - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm_WM, 'inputspec.transform') + input_resource : str or list + key for the resource to warp to template - outputs.update({ - f'space-EPItemplate_label-WM_mask': - (apply_xfm_WM, 'outputspec.output_image')}) + xfm : str + key for the transform to apply + reference : str, optional + key for reference if not using f'{template_space}-template' - if strat_pool.check_rpool('label-GM_mask'): - node, out = strat_pool.get_data("label-GM_mask") - wf.connect(node, out, apply_xfm_GM, 'inputspec.input_image') - node, out = strat_pool.get_data("EPI-template") - wf.connect(node, out, apply_xfm_GM, 'inputspec.reference') - node, out = strat_pool.get_data("from-bold_to-EPItemplate_mode-image_xfm") - wf.connect(node, out, apply_xfm_GM, 'inputspec.transform') + time_series : boolean, optional + resource to transform is 4D? - outputs.update({ - f'space-EPItemplate_label-GM_mask': - (apply_xfm_GM, 'outputspec.output_image')}) + Returns + ------- + wf : pe.Workflow + original workflow with subworkflow to warp resource to template + connected + apply_xfm : pe.Workflow + subworkflow added to warp resource to template - return (wf, outputs) + resource : str + key of input resource in strat_pool + ''' + # determine space we're warping to + template_space = xfm.split('_to-', 1)[1].split('template')[0] + if template_space == '': + template_space = 'T1w' + # determine tool used for registration + xfm_prov = strat_pool.get_cpac_provenance(xfm) + reg_tool = check_prov_for_regtool(xfm_prov) + # set 'resource' + if strat_pool.check_rpool(input_resource): + resource, input_resource = strat_pool.get_data(input_resource, + report_fetched=True) + else: + return wf, None, input_resource + # set 'reference' if not passed and determine subworkflow name + if reference is None: + subwf_input_name = input_resource + reference = f'{template_space}-template' + else: + subwf_input_name = '-'.join([ + reference.split('-')[-1].split('_')[-1], + input_resource.split('-')[-1].split('_')[-1]]) + # set up 'apply_transform' subworkflow + apply_xfm = apply_transform(f'warp_{subwf_input_name}_to_' + f'{template_space}template_{pipe_num}', + reg_tool, time_series=time_series, + num_cpus=cfg.pipeline_setup['system_config'][ + 'max_cores_per_participant'], + num_ants_cores=cfg.pipeline_setup[ + 'system_config']['num_ants_threads']) + # set appropriate 'interpolation' input based on registration tool + if reg_tool == 'ants': + apply_xfm.inputs.inputspec.interpolation = 'NearestNeighbor' + elif reg_tool == 'fsl': + apply_xfm.inputs.inputspec.interpolation = 'nn' + # connect nodes to subworkflow + node, out = resource + wf.connect(node, out, apply_xfm, 'inputspec.input_image') + node, out = strat_pool.get_data(reference) + wf.connect(node, out, apply_xfm, 'inputspec.reference') + node, out = strat_pool.get_data(xfm) + wf.connect(node, out, apply_xfm, 'inputspec.transform') + return wf, apply_xfm, input_resource +def _warp_return(wf: pe.Workflow, apply_xfm: Union[pe.Workflow, None], + outputs: dict) -> Tuple[pe.Workflow, dict]: + """Check if we have a transform to apply; if not, don't add the outputs""" + if apply_xfm is None: + return wf, {} + return wf, outputs diff --git a/CPAC/registration/tests/mocks.py b/CPAC/registration/tests/mocks.py index b460fb5675..f3d19bda14 100755 --- a/CPAC/registration/tests/mocks.py +++ b/CPAC/registration/tests/mocks.py @@ -1,9 +1,10 @@ import os +from nipype.interfaces import utility as util from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.utility as util -from CPAC.utils import Configuration, Strategy -from CPAC.utils.interfaces.function import Function +from CPAC.utils.configuration import Configuration from CPAC.utils.datasource import resolve_resolution +from CPAC.utils.interfaces.function import Function +from CPAC.utils.strategy import Strategy def file_node(path, file_node_num=0): input_node = pe.Node( diff --git a/CPAC/reho/reho.py b/CPAC/reho/reho.py index 88287217fa..5b03b7955d 100755 --- a/CPAC/reho/reho.py +++ b/CPAC/reho/reho.py @@ -118,12 +118,10 @@ def reho(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["desc-cleaned_bold", "desc-brain_bold", - "desc-preproc_bold", "bold"], + "inputs": ["desc-preproc_bold", "space-bold_desc-brain_mask"], "outputs": ["reho"]} ''' - cluster_size = cfg.regional_homogeneity['cluster_size'] # Check the cluster size is supported @@ -136,9 +134,7 @@ def reho(wf, cfg, strat_pool, pipe_num, opt=None): reho = create_reho(f'reho_{pipe_num}') reho.inputs.inputspec.cluster_size = cluster_size - - node, out = strat_pool.get_data(["desc-cleaned_bold", "desc-brain_bold", - "desc-preproc_bold", "bold"]) + node, out = strat_pool.get_data("desc-preproc_bold") wf.connect(node, out, reho, 'inputspec.rest_res_filt') node, out_file = strat_pool.get_data('space-bold_desc-brain_mask') @@ -149,3 +145,40 @@ def reho(wf, cfg, strat_pool, pipe_num, opt=None): } return (wf, outputs) + + +def reho_space_template(wf, cfg, strat_pool, pipe_num, opt=None): + ''' + {"name": "ReHo_space_template", + "config": ["regional_homogeneity"], + "switch": ["run"], + "option_key": "None", + "option_val": "None", + "inputs": ["space-template_res-derivative_desc-preproc_bold", + "space-template_res-derivative_desc-bold_mask"], + "outputs": ["space-template_reho"]} + ''' + cluster_size = cfg.regional_homogeneity['cluster_size'] + + # Check the cluster size is supported + if cluster_size not in [7, 19, 27]: + err_msg = 'Cluster size specified: %d, is not ' \ + 'supported. Change to 7, 19, or 27 and try ' \ + 'again' % cluster_size + raise Exception(err_msg) + + reho = create_reho(f'reho_{pipe_num}') + reho.inputs.inputspec.cluster_size = cluster_size + + node, out = strat_pool.get_data("space-template_res-derivative_desc-preproc_bold") + wf.connect(node, out, reho, 'inputspec.rest_res_filt') + + node, out_file = strat_pool.get_data( + 'space-template_res-derivative_desc-bold_mask') + wf.connect(node, out_file, reho, 'inputspec.rest_mask') + + outputs = { + 'space-template_reho': (reho, 'outputspec.raw_reho_map') + } + + return (wf, outputs) diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 261ad36e0e..59b973ddf9 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 7433d6f06a..957757961d 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index adcb6378ff..1d23bd913c 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index b4d524c8ed..bdeff92059 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 0edb7e829e..176a2c1f86 100755 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 4a92517458..91290b595c 100755 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index 38b1004269..e1dee0db7c 100755 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # @@ -7,334 +7,328 @@ # General Group-Level Analysis Settings -############################################################################## -# The main input of group-level analysis- the output directory of your individual-level analysis pipeline run (pre-processing & derivatives for each participant). This should be a path to your C-PAC individual-level run's pipeline folder, which includes the sub-directories labeled with the participant IDs. -pipeline_dir: /path/to/output_dir +pipeline_setup: + # Name for this pipeline configuration - useful for identification. + pipeline_name: cpac-group-template -# (Optional) Full path to a list of participants to be included in the model. You can use this to easily prune participants from your model. In group-level analyses involving phenotype files, this allows you to prune participants without removing them from the phenotype CSV/TSV file. This should be a text file with one subject per line. An easy way to manually create this file is to copy the participant ID column from your phenotype file. -participant_list: None + output_directory: + # The main input of group-level analysis- the output directory of your individual-level analysis pipeline run (pre-processing & derivatives for each participant). This should be a path to your C-PAC individual-level run's pipeline folder, which includes the sub-directories labeled with the participant IDs. + source_outputs_path : /source_output -# Full path to the directory where CPAC should place group-level analysis outputs and any applicable statistical model files. -output_dir: /path/to/output/dir + # (Optional) Full path to a list of participants to be included in the model. You can use this to easily prune participants from your model. In group-level analyses involving phenotype files, this allows you to prune participants without removing them from the phenotype CSV/TSV file. This should be a text file with one subject per line. An easy way to manually create this file is to copy the participant ID column from your phenotype file. + participant_list: None + # Full path to the directory where CPAC should place group-level analysis outputs and any applicable statistical model files. + output_path: /output -#Much like the working directory for individual-level analysis, this is where the intermediate and working files will be stored during your run. This directory can be deleted later on. However, saving this directory allows the group analysis run to skip steps that have been already completed, in the case of re-runs. -work_dir: /path/to/work/dir + working_directory: + #Much like the working directory for individual-level analysis, this is where the intermediate and working files will be stored during your run. This directory can be deleted later on. However, saving this directory allows the group analysis run to skip steps that have been already completed, in the case of re-runs. + path: /tmp -#Where to write out log information for your group analysis run. -log_dir: /path/to/log/dir + #Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: True + log_directory: + + # Whether to write log details of the pipeline run to the logging files. + run_logging: True -# The path to your FSL installation directory. This can be left as 'FSLDIR' to grab your system's default FSL installation. However, if you prefer to use a specific install of FSL, you can enter the path here. -FSLDIR: FSLDIR + #Where to write out log information for your group analysis run. + path: /logs + crash_log_directory: -# Number of CPUs to dedicate to the group-level analysis run. Parallelizes the pipeline where applicable. -num_cpus: 1 + # Directory where CPAC should write crash logs. + path: /crash + system_config: -# Scan inclusion list. For most group-level analyses, a separate model is run for each scan/series in your individual-level analysis pipeline directory. -# Use this list to prune your run to only specific scans. -# Example: -# scan_inclusion: ['rest_run-1', 'rest_run-2'] -scan_inclusion: [] + # The path to your FSL installation directory. This can be left as 'FSLDIR' to grab your system's default FSL installation. However, if you prefer to use a specific install of FSL, you can enter the path here. + FSLDIR: /usr/share/fsl/5.0 + # Number of CPUs to dedicate to the group-level analysis run. Parallelizes the pipeline where applicable. + num_cpus: 1 -# FSL-FEAT -############################################################################## - -# Run FSL FEAT group-level analysis. -run_fsl_feat : [1] - - -# How many statistical models to run in parallel. This number depends on computing resources. -num_models_at_once : 1 - - -# Specify a name for the new model. -model_name: model_name_here - + # The maximum amount of memory each participant's workflow can allocate. + # Use this to place an upper bound of memory usage. + # - Warning: 'Memory Per Participant' multiplied by 'Number of Participants to Run Simultaneously' + # must not be more than the total amount of RAM. + # - Conversely, using too little RAM can impede the speed of a pipeline run. + # - It is recommended that you set this to a value that when multiplied by + # 'Number of Participants to Run Simultaneously' is as much RAM you can safely allocate. + num_memory: 10 -# Phenotype file -# Full path to a .csv or .tsv file containing EV/regressor information for each subject. -pheno_file: /path/to/phenotypic/file.csv + # Scan inclusion list. For most group-level analyses, a separate model is run for each scan/series in your individual-level analysis pipeline directory. + # Use this list to prune your run to only specific scans. + # Example: + # scan_inclusion: ['rest_run-1', 'rest_run-2'] + scan_inclusion: [] + Amazon-AWS: -# Name of the participants column in your phenotype file. -participant_id_label: Participant + # If setting the 'Output Directory' to an S3 bucket, insert the path to your AWS credentials file here. + aws_output_bucket_credentials: + # Enable server-side 256-AES encryption on data to the S3 bucket + s3_encryption: False -# Specify which EVs from your phenotype are categorical or numerical. Of those which are numerical, specify which are to be demeaned. -# ev_selections: {'demean': ['Age'], 'categorical': ['Sex', 'Diagnosis']} -ev_selections: {'demean': [], 'categorical': []} + Debugging: - -# Specify the formula to describe your model design. Essentially, including EVs in this formula inserts them into the model. The most basic format to include each EV you select would be 'EV + EV + EV + ..', etc. You can also select to include MeanFD, Measure_Mean, and Custom_ROI_Mean here. See the C-PAC User Guide for more detailed information regarding formatting your design formula. -# design_formula: Sex + Diagnosis + Age + MeanFD_Jenkinson + Custom_ROI_Mean -design_formula: - - -# Choose the derivatives to run the group model on. -# -# These must be written out as a list, and must be one of the options listed below. -# -# For z-scored analyses: -# 'alff_to_standard_zstd', 'alff_to_standard_smooth_zstd', 'falff_to_standard_zstd', 'falff_to_standard_smooth_zstd', 'reho_to_standard_zstd', 'reho_to_standard_smooth_zstd', 'sca_roi_files_to_standard_fisher_zstd', 'sca_roi_files_to_standard_smooth_fisher_zstd', 'vmhc_fisher_zstd_zstat_map', 'dr_tempreg_maps_zstat_files_to_standard', 'dr_tempreg_maps_zstat_files_to_standard_smooth', 'sca_tempreg_maps_zstat_files', 'sca_tempreg_maps_zstat_files_smooth', 'centrality_outputs_zstd', 'centrality_outputs_smoothed_zstd' -# -# Example input: derivative_list : ['alff_to_standard_smooth_zstd', 'sca_roi_files_to_standard_smooth_fisher_zstd'] -# -derivative_list: [] + # Verbose developer messages. + verbose: Off -# Choose whether to use a group mask or individual-specific mask when calculating the output means to be used as a regressor. -# -# This only takes effect if you include the 'Measure_Mean' regressor in your Design Matrix Formula. -mean_mask: ['Group Mask'] +# FSL-FEAT +fsl_feat: -# Full path to a NIFTI file containing one or more ROI masks. The means of the masked regions will then be computed for each subject's output and will be included in the model as regressors (one for each ROI in the mask file) if you include 'Custom_ROI_Mean' in the Design Matrix Formula. -# custom_roi_mask: /path/to/mask.nii.gz -custom_roi_mask: None + # Run FSL FEAT group-level analysis. + run: Off + # How many statistical models to run in parallel. This number depends on computing resources. + num_models_at_once: 1 -# Choose the coding scheme to use when generating your model. 'Treatment' encoding is generally considered the typical scheme. Consult the User Guide for more information. -# -# Available options: -# 'Treatment', 'Sum' -# -coding_scheme: ['Treatment'] + # Specify a name for the new model. + model_name: model_name_here + # Phenotype file + # Full path to a .csv or .tsv file containing EV/regressor information for each subject. + pheno_file: /path -# Specify whether FSL should model the variance for each group separately. -# -# If this option is enabled, you must specify a grouping variable below. -group_sep: Off - + # Name of the participants column in your phenotype file. + participant_id_label: Participant -# The name of the EV that should be used to group subjects when modeling variances. -# -# If you do not wish to model group variances separately, set this value to None. -grouping_var: None + # Specify which EVs from your phenotype are categorical or numerical. Of those which are numerical, specify which are to be demeaned. + # ev_selections: {'demean': ['Age'], 'categorical': ['Sex', 'Diagnosis']} + ev_selections: {'demean': [], 'categorical': []} + # Specify the formula to describe your model design. Essentially, including EVs in this formula inserts them into the model. The most basic format to include each EV you select would be 'EV + EV + EV + ..', etc. You can also select to include MeanFD, Measure_Mean, and Custom_ROI_Mean here. See the C-PAC User Guide for more detailed information regarding formatting your design formula. + # design_formula: Sex + Diagnosis + Age + MeanFD_Jenkinson + Custom_ROI_Mean + design_formula: -# Only voxels with a Z-score higher than this value will be considered significant. -z_threshold: ['2.3'] + # Choose the derivatives to run the group model on. + # + # These must be written out as a list, and must be one of the options listed below. + # + # For z-scored analyses: + # 'desc-zstd_alff', 'desc-sm-zstd_alff', 'desc-zstd_falff', 'desc-sm-zstd_falff', 'desc-zstd_reho', 'desc-sm-zstd_reho', 'desc-zstd_sca_roi', 'desc-sm-zstd_sca_roi', 'desc-zstd_vmhc', 'desc-zstd_dr_tempreg_maps', 'desc-sm-zstd_dr_tempreg_maps', 'desc-zstd_sca_tempreg_maps', 'desc-sm-zstd_sca_tempreg_maps', 'desc-zstd_centrality', 'desc-sm-zstd_centrality' + # + # Example input: derivative_list : ['desc-sm-zstd_alff', 'desc-sm-zstd_sca_roi'] + # + derivative_list: [] + # Choose whether to use a group mask or individual-specific mask when calculating the output means to be used as a regressor. + # + # This only takes effect if you include the 'Measure_Mean' regressor in your Design Matrix Formula. + mean_mask: ['Group Mask'] -# Significance threshold (P-value) to use when doing cluster correction for multiple comparisons. -p_threshold: ['0.05'] + # Full path to a NIFTI file containing one or more ROI masks. The means of the masked regions will then be computed for each subject's output and will be included in the model as regressors (one for each ROI in the mask file) if you include 'Custom_ROI_Mean' in the Design Matrix Formula. + # custom_roi_mask: /path/to/mask.nii.gz + custom_roi_mask: None + # Choose the coding scheme to use when generating your model. 'Treatment' encoding is generally considered the typical scheme. Consult the User Guide for more information. + # + # Available options: + # 'Treatment', 'Sum' + # + coding_scheme: ['Treatment'] -# For repeated measures only. Enter the session names in your dataset that you wish to include within the same model (this is for repeated measures / within-subject designs).\n\nTip: These will be the names listed as "unique_id" in the original individual-level participant list, or the labels in the original data directories you marked as {session} while creating the CPAC participant list. -# sessions_list: ['ses-01', 'ses-02'] -sessions_list: [] + # Specify whether FSL should model the variance for each group separately. + # + # If this option is enabled, you must specify a grouping variable below. + group_sep: Off + # The name of the EV that should be used to group subjects when modeling variances. + # + # If you do not wish to model group variances separately, set this value to None. + grouping_var: None -# For repeated measures only. Enter the series names in your dataset that you wish to include within the same model (this is for repeated measures / within-subject designs).\n\nTip: These will be the labels listed under "func:" in the original individual-level participant list, or the labels in the original data directories you marked as {series} while creating the CPAC participant list. -# series_list: ['task-rest_run-1', 'task-rest_run-2'] -series_list: [] + # Only voxels with a Z-score higher than this value will be considered significant. + z_threshold: ['2.3'] + # Significance threshold (P-value) to use when doing cluster correction for multiple comparisons. + p_threshold: ['0.05'] -# Specify your contrasts here. For example, if two of your available contrasts are EV1 and EV0, you can enter contrast descriptions such as 'EV1 - EV0 = 0' or 'EV1 = 0'. Consult the User Guide for more information about describing contrasts. Alternatively, you can provide your own custom-written contrasts matrix in a CSV file in the 'Custom Contrasts Matrix' field below. -# contrasts: ['C(Diagnosis)[T.ADHD] - C(Diagnosis)[T.Typical] = 0', 'C(Diagnosis)[T.Typical] - C(Diagnosis)[T.ADHD] = 0'] -contrasts: [] + # For repeated measures only. Enter the session names in your dataset that you wish to include within the same model (this is for repeated measures / within-subject designs).\n\nTip: These will be the names listed as "unique_id" in the original individual-level participant list, or the labels in the original data directories you marked as {session} while creating the CPAC participant list. + # sessions_list: ['ses-01', 'ses-02'] + sessions_list: [] + # For repeated measures only. Enter the series names in your dataset that you wish to include within the same model (this is for repeated measures / within-subject designs).\n\nTip: These will be the labels listed under "func:" in the original individual-level participant list, or the labels in the original data directories you marked as {series} while creating the CPAC participant list. + # series_list: ['task-rest_run-1', 'task-rest_run-2'] + series_list: [] -# Optional: A list of f-test strings containing contrasts. If you do not wish to run f-tests, leave this blank. -f_tests: [] + # Specify your contrasts here. For example, if two of your available contrasts are EV1 and EV0, you can enter contrast descriptions such as 'EV1 - EV0 = 0' or 'EV1 = 0'. Consult the User Guide for more information about describing contrasts. Alternatively, you can provide your own custom-written contrasts matrix in a CSV file in the 'Custom Contrasts Matrix' field below. + # contrasts: ['C(Diagnosis)[T.ADHD] - C(Diagnosis)[T.Typical] = 0', 'C(Diagnosis)[T.Typical] - C(Diagnosis)[T.ADHD] = 0'] + contrasts: [] + # Optional: A list of f-test strings containing contrasts. If you do not wish to run f-tests, leave this blank. + f_tests: [] -# Optional: Full path to a CSV file which specifies the contrasts you wish to run in group analysis. Consult the User Guide for proper formatting. -# If you wish to use the standard contrast builder, leave this field blank. If you provide a path for this option, CPAC will use your custom contrasts matrix instead, and will use the f-tests described in this custom file only (ignoring those you have input in the f-tests field above). -# If you wish to include f-tests, create a new column in your CSV file for each f-test named 'f_test_1', 'f_test_2', .. etc. Then, mark the contrasts you would like to include in each f-test with a 1, and mark the rest 0. Note that you must select at least two contrasts per f-test. -custom_contrasts: None - + # Optional: Full path to a CSV file which specifies the contrasts you wish to run in group analysis. Consult the User Guide for proper formatting. + # If you wish to use the standard contrast builder, leave this field blank. If you provide a path for this option, CPAC will use your custom contrasts matrix instead, and will use the f-tests described in this custom file only (ignoring those you have input in the f-tests field above). + # If you wish to include f-tests, create a new column in your CSV file for each f-test named 'f_test_1', 'f_test_2', .. etc. Then, mark the contrasts you would like to include in each f-test with a 1, and mark the rest 0. Note that you must select at least two contrasts per f-test. + custom_contrasts: None # FSL-Randomise -############################################################################## - -# Run Randomise -run_randomise : [0] - +fsl_randomise: -# Number of permutations you would like to use when building up the null distribution to test against. -randomise_permutation : 500 + # Run Randomise + run: [0] + # Number of permutations you would like to use when building up the null distribution to test against. + permutation: 500 -# Cluster-based thresholding corrected for multiple comparisons by using the null distribution of the max (across the image) cluster mask. -randomise_thresh : 5 + # Cluster-based thresholding corrected for multiple comparisons by using the null distribution of the max (across the image) cluster mask. + thresh: 5 + # Demean data temporally before model fitting. + demean: True -# Demean data temporally before model fitting. -randomise_demean : True - - -# From the FMRIB FSL-Randomise user guide: TFCE (Threshold-Free Cluster Enhancement) is a new method for finding 'clusters' in your data without having to define clusters in a binary way. Cluster-like structures are enhanced but the image remains fundamentally voxelwise. -randomise_tfce : True + # From the FMRIB FSL-Randomise user guide: TFCE (Threshold-Free Cluster Enhancement) is a new method for finding 'clusters' in your data without having to define clusters in a binary way. Cluster-like structures are enhanced but the image remains fundamentally voxelwise. + tfce: True # Bootstrap Analysis of Stable Clusters (BASC) - via PyBASC -############################################################################## - -# Run Bootstrap Analysis of Stable Clusters -run_basc : [0] +basc: + # Run Bootstrap Analysis of Stable Clusters + run: [0] -# If there are multiple series or scans in any of the pipeline outputs for which PyBASC is being run, and you only want to run for some of them, you can list them here - scan labels separated by commas (ex. 'rest_run-1, rest_run-3'). -# If nothing is listed, all available pipelines will be run. -basc_scan_inclusion : None + # If there are multiple series or scans in any of the pipeline outputs for which PyBASC is being run, and you only want to run for some of them, you can list them here - scan labels separated by commas (ex. 'rest_run-1, rest_run-3'). + # If nothing is listed, all available pipelines will be run. + scan_inclusion: None + # The resolution to run PyBASC with. + resolution: 4mm -# The resolution to run PyBASC with. -basc_resolution : 4mm + # Maximum amount of processors to use while performing BASC. + proc: 2 + # Maximum amount of RAM (in GB) to be used when running BASC. + memory: 4 -# Maximum amount of processors to use while performing BASC. -basc_proc : 2 + # Standard FSL Skull Stripped Template. + template_brain_only_for_func: $FSLDIR/data/standard/MNI152_T1_${basc_resolution}_brain.nii.gz + # Full path to a mask file to be used when running BASC. Voxels outside this mask will be excluded from analysis. This is the region that you’d like to parcellate. + # If you do not wish to use a mask, set this field to None. + # Note: BASC is very computationally intensive, we strongly recommend you limit your analysis to specific brain areas of interest. + roi_mask_file: None -# Maximum amount of RAM (in GB) to be used when running BASC. -basc_memory : 4 + # If cross clustering is enabled, then clustering of the first region will be calculated based on pairwise similarity between the timeseries of the ROI Mask File, and this second ROI. + cross_cluster_mask_file: None + # The metric used to compare similarity between voxel timeseries. + # Options: ['correlation', 'euclidean', 'cityblock', 'cosine'] + similarity_metric_list: ['correlation'] -# Standard FSL Skull Stripped Template. -template_brain_only_for_func : $FSLDIR/data/standard/MNI152_T1_${basc_resolution}_brain.nii.gz + # How many times individual level circular block bootstrapping of the timeseries will be applied. + timeseries_bootstrap_list: 100 + # Number of bootstraps to apply to the original dataset. + dataset_bootstrap_list: 30 -# Full path to a mask file to be used when running BASC. Voxels outside this mask will be excluded from analysis. This is the region that you’d like to parcellate. -# If you do not wish to use a mask, set this field to None. -# Note: BASC is very computationally intensive, we strongly recommend you limit your analysis to specific brain areas of interest. -basc_roi_mask_file : None + # Number of clusters to create during clustering at both the individual and group levels. + n_clusters_list: 2 + # The similarity threshold at which the similarity matrices will be set to 0. + affinity_thresh: [0.0] -# If cross clustering is enabled, then clustering of the first region will be calculated based on pairwise similarity between the timeseries of the ROI Mask File, and this second ROI. -basc_cross_cluster_mask_file : None + # This is the amount of feature agglomeration that will be applied. Smaller values mean more feature agglomeration. + output_sizes: 800 + # If set to true, then the ROI Mask file parcellation will be based on the similarity between ROI Mask file voxels based on their connectivity to each voxel in ROI mask file for cross-clustering. + cross_cluster: True -# The metric used to compare similarity between voxel timeseries. -# Options: ['correlation', 'euclidean', 'cityblock', 'cosine'] -basc_similarity_metric_list : ['correlation'] + # This parameter determines the width of the time window used in the circular block bootstrap. + blocklength_list: 1 - -# How many times individual level circular block bootstrapping of the timeseries will be applied. -basc_timeseries_bootstrap_list : 100 - - -# Number of bootstraps to apply to the original dataset. -basc_dataset_bootstrap_list : 30 - - -# Number of clusters to create during clustering at both the individual and group levels. -basc_n_clusters_list : 2 - - -# The similarity threshold at which the similarity matrices will be set to 0. -basc_affinity_thresh : [0.0] - - -# This is the amount of feature agglomeration that will be applied. Smaller values mean more feature agglomeration. -basc_output_sizes : 800 - - -# If set to true, then the ROI Mask file parcellation will be based on the similarity between ROI Mask file voxels based on their connectivity to each voxel in ROI mask file for cross-clustering. -basc_cross_cluster : True - - -# This parameter determines the width of the time window used in the circular block bootstrap. -basc_blocklength_list : 1 - - -# If this is set to true, the all individuals will have feature agglomeration applied together, resulting in the same mapping across subjects. Use this only when memory demands limit ability to process ROIs with a high number of voxels. -basc_group_dim_reduce : False + # If this is set to true, the all individuals will have feature agglomeration applied together, resulting in the same mapping across subjects. Use this only when memory demands limit ability to process ROIs with a high number of voxels. + group_dim_reduce: False # Multivariate Distance Matrix Regression (MDMR) -############################################################################## - -# Used to determine if Multivariate Distance Matrix Regression (MDMR) will be added to the pipeline or not. -runMDMR : [0] - - -# Inclusion list text file listing the participant IDs you wish to include in the MDMR analysis. If left as None, will include all subjects. -mdmr_inclusion : None - - -# Path to a mask file. Voxels outside of the mask will be excluded from MDMR. -mdmr_roi_file : - +mdmr: -# Path to a CSV file containing the phenotypic regressor. -mdmr_regressor_file : + # Used to determine if Multivariate Distance Matrix Regression (MDMR) will be added to the pipeline or not. + run: [0] + # Inclusion list text file listing the participant IDs you wish to include in the MDMR analysis. If left as None, will include all subjects. + inclusion_list : None -# Name of the participants column in your regressor file. -mdmr_regressor_participant_column : + # Path to a mask file. Voxels outside of the mask will be excluded from MDMR. + roi_file: /path + # Path to a CSV file containing the phenotypic regressor. + regressor_file: -# Columns from the CSV file indicating factor variables. Other columns will be handled as covariates. Separated by commas. -mdmr_regressor_columns : + # Name of the participants column in your regressor file. + regressor_participant_column: '' + # Columns from the CSV file indicating factor variables. Other columns will be handled as covariates. Separated by commas. + regressor_columns: '' -# Number of permutation tests to run on the Pseudo-F statistics. -mdmr_permutations : 500 + # Number of permutation tests to run on the Pseudo-F statistics. + permutations: 15000 + # Number of Nipype nodes created while computing MDMR. Dependent upon computing resources. + parallel_nodes: 10 -# Number of Nipype nodes created while computing MDMR. Dependent upon computing resources. -mdmr_parallel_nodes : 1 + # If you want to create zstat maps + zscore: [1] # Inter-Subject Correlation (ISC) & Inter-Subject Functional Correlation (ISFC) -############################################################################### - -# Used to determine if Inter-subject Correlation (ISC) will be added to the pipeline or not. -runISC : [0] - - -# Used to determine if Inter-subject Functional Correlation (ISFC) will be added to the pipeline or not. -runISFC : [0] - - -# Used to determine if the ISC and ISFC will run in the ROI level. -isc_level_roi : [0] - +isc_isfc: -# Used to determine if the ISC and ISFC will run in the voxel level. Depending on the image resolution, it may take several hours and consume a great amount of available memory. -isc_level_voxel : [0] + # Used to determine if Inter-subject Correlation (ISC) will be added to the pipeline or not. + runISC: [0] + # Used to determine if Inter-subject Functional Correlation (ISFC) will be added to the pipeline or not. + runISFC: [0] -# Filter out voxels that, in the correlation distribution, is greater then the informed standard deviation. Zero value will disable the filter. -isc_level_voxel_std_filter : 0.0 + # Used to determine if the ISC and ISFC will run in the ROI level. + level_roi: [0] + # Used to determine if the ISC and ISFC will run in the voxel level. Depending on the image resolution, it may take several hours and consume a great amount of available memory. + level_voxel: [0] -# Number of permutation tests to compute the statistics. -isc_permutations : 1000 + # Filter out voxels that, in the correlation distribution, is greater then the informed standard deviation. Zero value will disable the filter. + level_voxel_std_filter: 0.0 + # Number of permutation tests to compute the statistics. + permutations: 1000 -# ROI/atlases to include in the analysis. For ROI-level ISC/ISFC runs. -# This should be a list of names/strings of the ROI names used in individual-level analysis, if ROI timeseries extraction was performed. -isc_roi_inclusion: [""] + # ROI/atlases to include in the analysis. For ROI-level ISC/ISFC runs. + # This should be a list of names/strings of the ROI names used in individual-level analysis, if ROI timeseries extraction was performed. + roi_inclusion: [""] #Quasi Periodic Patterns (QPP) -############################### +qpp: -# Run Quasi Periodic Pattern Analysis -runQPP : [1] + # Run Quasi Periodic Pattern Analysis + run: [1] + scan_inclusion: -qpp_scan_inclusion : -qpp_session_inclusion : -qpp_stratification : + session_inclusion: + + stratification: -qpp_permutations: 100 -qpp_window: 30 + permutations: 100 + + window: 30 -qpp_initial_threshold: 0.2 -qpp_final_threshold: 0.3 -qpp_initial_threshold_iterations : 20 + initial_threshold: 0.2 + + final_threshold: 0.3 + + initial_threshold_iterations : 20 -qpp_iterations : 15 + qpp_iterations : 15 diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index b562390ee7..d1fcfc08b8 100755 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,25 +1,20 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_abcd-options + system_config: - output_directory: - quality_control: - # Generate quality control pages containing preprocessing and derivative outputs. - generate_quality_control_images: Off - - system_config: # The maximum amount of memory each participant's workflow can allocate. # Use this to place an upper bound of memory usage. # - Warning: 'Memory Per Participant' multiplied by 'Number of Participants to Run Simultaneously' @@ -29,19 +24,45 @@ pipeline_setup: # 'Number of Participants to Run Simultaneously' is as much RAM you can safely allocate. maximum_memory_per_participant: 10.0 +# PREPROCESSING +# ------------- surface_analysis: # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, # select those 'Freesurfer-' labeled options further below in anatomical_preproc. - freesurfer: - run: On + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: On + + # FreeSurfer will run as part of configured brain extraction in this specific configuration, so FreeSurfer's independent run was automatically disabled. + run_reconall: Off # Run ABCD-HCP post FreeSurfer and fMRISurface pipeline - post_freesurfer: + post_freesurfer: run: On -anatomical_preproc: +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + run: On + + # Run ACPC alignment before non-local means filtering or N4 bias + # correction + run_before_preproc: Off + + # ACPC aligned template + T1w_ACPC_template: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_1mm.nii.gz + + brain_extraction: + run: On + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] + # this is a fork option + using: [FreeSurfer-ABCD] + # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: @@ -49,7 +70,7 @@ anatomical_preproc: run: [On] # options: 'Gaussian' or 'Rician' - noise_model: 'Rician' + noise_model: Rician # N4 bias field correction via ANTs n4_bias_field_correction: @@ -60,43 +81,29 @@ anatomical_preproc: # An integer to resample the input image to save computation time. Shrink factors <= 4 are commonly used. shrink_factor: 4 - acpc_alignment: - run: On - - # Run ACPC alignment before non-local means filtering or N4 bias - # correction - run_before_preproc: False - - # ACPC aligned template - T1w_ACPC_template: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_1mm.nii.gz - - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD'] - # this is a fork option - using: [FreeSurfer-ABCD] +segmentation: -registration_workflows: - anatomical_registration: - # The resolution to which anatomical images should be transformed during registration. - # This is the resolution at which processed anatomical files will be output. - resolution_for_anat: 1mm + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${resolution_for_anat}_brain.nii.gz +registration_workflows: + anatomical_registration: + run: On + registration: + FSL-FNIRT: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_2mm_brain_mask_dil.nii.gz - # Register skull-on anatomical image to a template. - reg_with_skull: True + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_2mm.nii.gz - registration: # option parameters - ANTs: + ANTs: + # ANTs parameters for T1-template-based registration - T1_registration: + T1_registration: - verbose: 1 - float: 0 - collapse-output-transforms: 0 @@ -160,53 +167,62 @@ registration_workflows: # Possible values: Linear, BSpline, LanczosWindowedSinc interpolation: Linear - FSL-FNIRT: + overwrite_transform: + run: On - # Configuration file to be used by FSL to set FNIRT parameters. - # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. - fnirt_config: T1_2_MNI152_2mm + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + resolution_for_anat: 1mm - # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. - ref_mask_res-2: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_2mm_brain_mask_dil.nii.gz + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${resolution_for_anat}_brain.nii.gz - # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. - T1w_template_res-2: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_2mm.nii.gz + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - overwrite_transform: + functional_registration: + coregistration: + # functional (BOLD/EPI) registration to anatomical (structural/T1) run: On + func_input_prep: - # Choose the tool to overwrite transform, currently only support 'FSL' to overwrite 'ANTs' transforms in ABCD-options pipeline. - # using: 'FSL' - using: FSL + # Choose whether to use functional brain or skull as the input to functional-to-anatomical registration + reg_with_skull: On + + # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. + # input: ['Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference'] + input: [Selected_Functional_Volume] - functional_registration: - coregistration: # reference: 'brain' or 'restore-brain' # In ABCD-options pipeline, 'restore-brain' is used as coregistration reference reference: restore-brain - # interpolation for coregistration + # Choose coregistration interpolation interpolation: spline - # degree of freedom for coregistration + # Choose coregistration degree of freedom dof: 12 - func_input_prep: - # Choose whether to use functional brain or skull as the input to functional-to-anatomical registration - reg_with_skull: On + func_registration_to_template: - # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. - # input: ['Mean Functional', 'Selected_Functional_Volume'] - input: [Selected_Functional_Volume] + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + apply_transform: + + # options: 'default', 'abcd', 'single_step_resampling_from_stc', 'dcan_nhp' + # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. + # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. + # 'single_step_resampling_from_stc': apply motion correction, func-to-anat and anat-to-template transforms on each of slice-time-corrected functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. + # - if 'single_step_resampling_from_stc', 'template' is the only valid option for ``nuisance_corrections: 2-nuisance_regression: space`` + using: abcd - boundary_based_registration: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + output_resolution: - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -222,101 +238,86 @@ registration_workflows: # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm - target_template: - # option parameters + target_template: T1_template: # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. - T1w_brain_template_funcreg: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${func_resolution}_brain.nii.gz + T1w_brain_template_funcreg: /usr/share/data/fsl-mni152-templates/MNI152_T1_${func_resolution}_brain.nii.gz # Standard Anatomical Brain Image with Skull. # This can be different than the template used as the reference/fixed for T1-to-template registration. - T1w_template_funcreg: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${func_resolution}.nii.gz + T1w_template_funcreg: /usr/share/data/fsl-mni152-templates/MNI152_T1_${func_resolution}.nii.gz # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask_funcreg: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_${func_resolution}_brain_mask.nii.gz + T1w_brain_template_mask_funcreg: /usr/share/data/fsl-mni152-templates/MNI152_T1_${func_resolution}_brain_mask.nii.gz + + ANTs_pipelines: - ANTs_pipelines: # Interpolation method for writing out transformed functional images. # Possible values: Linear, BSpline, LanczosWindowedSinc interpolation: Linear - apply_transform: - - # options: 'default', 'abcd' - # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. - # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume same as ABCD-HCP pipeline. - using: 'abcd' - -functional_preproc: +functional_preproc: run: On + motion_estimates_and_correction: + run: On + motion_estimates: - slice_timing_correction: - # Interpolate voxel time courses so they are sampled at the same time points. - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - motion_estimates_and_correction: - motion_estimates: # calculate motion statistics BEFORE slice-timing correction calculate_motion_first: On # calculate motion statistics AFTER motion correction calculate_motion_after: Off - motion_correction: + motion_correction: + # using: ['3dvolreg', 'mcflirt'] # this is a fork point using: [mcflirt] - # Choose motion correction reference. Options: mean, median, selected_volume - motion_correction_reference: ['selected_volume'] - - # Choose motion correction reference volume - motion_correction_reference_volume: 0 + # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference + motion_correction_reference: [selected_volume] distortion_correction: + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - using: ['PhaseDiff', 'Blip-FSL-TOPUP'] + using: [PhaseDiff, Blip-FSL-TOPUP] - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled'] - # this is a fork point - using: [Anatomical_Resampled] + func_masking: # Apply functional mask in native space apply_func_mask_in_native_space: Off + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. + # this is a fork point + using: [Anatomical_Resampled] + generate_func_mean: # Generate mean functional image run: On - normalize_func: - - # Normalize functional image - run: Off - - -nuisance_corrections: - 2-nuisance_regression: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - # switch to Off if nuisance regression is off and you don't want to write out the regressors - create_regressors: Off +nuisance_corrections: + 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: default + Bandpass: bottom_frequency: 0.01 method: default top_frequency: 0.1 @@ -324,39 +325,76 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: default -timeseries_extraction: - run: Off + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + # switch to Off if nuisance regression is off and you don't want to write out the regressors + create_regressors: Off + +timeseries_extraction: + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + +amplitude_low_frequency_fluctuation: + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: + + # space: Template or Native + target_space: [Native] -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg # available analyses: # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: + sca_roi_paths: /cpac_templates/CC400.nii.gz: Avg - -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off - -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off - -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off - -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index e41d917618..94fcac6ae4 100755 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,29 +1,25 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. - FROM: default +pipeline_setup: -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_anat + system_config: - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off - - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -41,55 +37,48 @@ pipeline_setup: # If you have specified an FSL path in your .bashrc file, this path will be set automatically. FSLDIR: FSLDIR - Amazon-AWS: + working_directory: + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + + Amazon-AWS: + # Enable server-side 256-AES encryption on data to the S3 bucket s3_encryption: On -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: [Off] +anatomical_preproc: + brain_extraction: + FSL-BET: + + # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. + mask_boolean: Off # N4 bias field correction via ANTs n4_bias_field_correction: + + # this is a fork option run: [On] - brain_extraction: - FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off +segmentation: + tissue_segmentation: + Template_Based: -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz +registration_workflows: + anatomical_registration: + registration: + FSL-FNIRT: - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz + # Reference mask for FSL registration. + ref_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz -registration_workflows: - anatomical_registration: # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. T1w_brain_template: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz @@ -101,36 +90,26 @@ registration_workflows: # Register skull-on anatomical image to a template. reg_with_skull: Off - registration: - FSL-FNIRT: - # Reference mask for FSL registration. - ref_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz + functional_registration: + coregistration: - functional_registration: - coregistration: + # functional (BOLD/EPI) registration to anatomical (structural/T1) run: Off + boundary_based_registration: - boundary_based_registration: # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [Off] - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - FSL-FNIRT: - # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: $FSLDIR/etc/flirtsch/ident.mat + func_registration_to_template: - func_registration_to_template: + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data run: Off + target_template: + T1_template: - target_template: - # option parameters - T1_template: # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_brain_template_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz @@ -139,68 +118,62 @@ registration_workflows: # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_template_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}.nii.gz -functional_preproc: + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + + FSL-FNIRT: + + # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: $FSLDIR/etc/flirtsch/ident.mat + +functional_preproc: run: Off + distortion_correction: - distortion_correction: - # using: ['PhaseDiff', 'Blip'] + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - # NOTE: - # this is NOT a fork point - instead, the technique used will depend on what type of distortion correction field data accompanies the dataset - # for example, phase-difference field maps will lead to phase-difference distortion correction, and phase-encoding direction field maps will lead to blip-up/blip-down + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. using: [] -nuisance_corrections: - 2-nuisance_regression: +nuisance_corrections: + 2-nuisance_regression: + # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [Off] # Select which nuisance signal corrections to apply - Regressors: - # Standard Lateral Ventricles Binary Mask - # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: $FSLDIR/data/atlases/HarvardOxford/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz + Regressors: -timeseries_extraction: +timeseries_extraction: run: Off -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off +amplitude_low_frequency_fluctuation: -amplitude_low_frequency_fluctuation: # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. run: Off -regional_homogeneity: +regional_homogeneity: + # ReHo # Calculate Regional Homogeneity (ReHo) for all voxels. run: Off -voxel_mirrored_homotopic_connectivity: +voxel_mirrored_homotopic_connectivity: + # VMHC # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. run: Off - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz +network_centrality: -network_centrality: # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. run: Off @@ -210,15 +183,16 @@ network_centrality: # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -230,8 +204,14 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index df84cce248..b3b53d5862 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,36 +1,39 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: benchmark-ANTS + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. write_func_outputs: On # Include extra outputs in the output directory that may be of interest when more information is needed. write_debugging_outputs: On - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -59,73 +62,109 @@ pipeline_setup: # - This number cannot be greater than the number of cores per participant. num_ants_threads: 2 -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: Off + working_directory: + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: Off + brain_extraction: + run: On + FSL-BET: - brain_extraction: - FSL-BET: # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. mask_boolean: Off -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. +registration_workflows: + anatomical_registration: + run: On - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz + # Register skull-on anatomical image to a template. + reg_with_skull: Off - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz + functional_registration: + coregistration: - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: - functional_registration: - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the registered derivative outputs are written into. # NOTE: # this is for the single-volume functional-space outputs (i.e. derivatives) # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -nuisance_corrections: - 1-ICA-AROMA: +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: [On, Off] + run: [On] + + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] - 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -135,7 +174,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 1 aCompCor: @@ -146,7 +184,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: erode_mask: On extraction_resolution: 2 summary: Mean @@ -156,7 +195,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: On - Name: Regressor-2 aCompCor: extraction_resolution: 2 summary: @@ -164,7 +202,8 @@ nuisance_corrections: method: DetrendPC tissues: - CerebrospinalFluid - - Censor: + - Name: Regressor-3 + Censor: method: Kill number_of_previous_trs_to_censor: 1 number_of_subsequent_trs_to_censor: 1 @@ -175,54 +214,122 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: Off - Name: Regressor-3 -timeseries_extraction: + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + 1-ICA-AROMA: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On, Off] + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, Voxel, SpatialReg -seed_based_correlation_analysis: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: -voxel_mirrored_homotopic_connectivity: - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz + # space: Template or Native + target_space: [Native] - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz +voxel_mirrored_homotopic_connectivity: + + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On -network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. memory_allocation: 3.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -234,8 +341,32 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index da1e85efc4..462f46d76f 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,36 +1,39 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: benchmark-FNIRT + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. write_func_outputs: On # Include extra outputs in the output directory that may be of interest when more information is needed. write_debugging_outputs: On - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -64,80 +67,128 @@ pipeline_setup: # multiplied by the number of cores dedicated to each participant (the 'Maximum Number of Cores Per Participant' setting). num_participants_at_once: 15 -anatomical_preproc: - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] + working_directory: + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + brain_extraction: + run: On + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [BET] -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz +registration_workflows: + anatomical_registration: + run: On + registration: - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off - - registration: # using: ['ANTS', 'FSL', 'FSL-linear'] # this is a fork point # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline using: [FSL] # option parameters - ANTs: + ANTs: + # ANTs parameters for T1-template-based registration - T1_registration: - functional_registration: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - func_registration_to_template: - output_resolution: + T1_registration: + + # Register skull-on anatomical image to a template. + reg_with_skull: Off + + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: + # The resolution (in mm) to which the registered derivative outputs are written into. # NOTE: # this is for the single-volume functional-space outputs (i.e. derivatives) # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -nuisance_corrections: - 1-ICA-AROMA: + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: [On, Off] + run: [On] + + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] - 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -147,7 +198,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 1 aCompCor: @@ -158,7 +208,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: erode_mask: On extraction_resolution: 2 summary: Mean @@ -168,7 +219,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: On - Name: Regressor-2 aCompCor: extraction_resolution: 2 summary: @@ -176,7 +226,8 @@ nuisance_corrections: method: DetrendPC tissues: - CerebrospinalFluid - - Censor: + - Name: Regressor-3 + Censor: method: Kill number_of_previous_trs_to_censor: 1 number_of_subsequent_trs_to_censor: 1 @@ -187,54 +238,122 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: Off - Name: Regressor-3 -timeseries_extraction: + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + 1-ICA-AROMA: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On, Off] + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, Voxel, SpatialReg -seed_based_correlation_analysis: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: -voxel_mirrored_homotopic_connectivity: - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz + # space: Template or Native + target_space: [Native] - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz +voxel_mirrored_homotopic_connectivity: + + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On -network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. memory_allocation: 3.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -246,8 +365,32 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 6eab69e5d3..e233e4ced9 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,24 +1,32 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. - pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac-blank-template - output_directory: + # Quality control outputs + quality_control: + + # Generate eXtensible Connectivity Pipeline-style quality control files + generate_xcpqc_files: Off + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: Off + # Directory where C-PAC should write out processed data, logs, and crash reports. # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary - # name like '/output', and then map (-B/-v) your desired output directory to that label. + # name like '/outputs', and then map (-B/-v) your desired output directory to that label. # - If running outside a container, this should be a full path to a directory. - path: /output + path: /outputs/output # (Optional) Path to a BIDS-Derivatives directory that already has outputs. # - This option is intended to ingress already-existing resources from an output @@ -27,7 +35,7 @@ pipeline_setup: # continue the pipeline from where they leave off. # - If left as 'None', C-PAC will ingress any already-computed outputs from the # output directory you provide above in 'path' instead, the default behavior. - source_outputs_dir: None + source_outputs_dir: # Set to True to make C-PAC ingress the outputs from the primary output directory if they # exist, even if a source_outputs_dir is provided @@ -35,70 +43,62 @@ pipeline_setup: # calculated outputs in the main output directory # - C-PAC will still pull from source_outputs_dir if the main output directory is # empty, however - pull_source_once: True + pull_source_once: On # Include extra versions and intermediate steps of functional preprocessing in the output directory. - write_func_outputs: False + write_func_outputs: Off # Include extra outputs in the output directory that may be of interest when more information is needed. - write_debugging_outputs: False + write_debugging_outputs: Off # Output directory format and structure. # Options: default, ndmg - output_tree: "default" - - quality_control: - # Generate quality control pages containing preprocessing and derivative outputs. - generate_quality_control_images: True - - working_directory: - - # Directory where C-PAC should store temporary and intermediate files. - # - This directory must be saved if you wish to re-run your pipeline from where you left off (if not completed). - # - NOTE: As it stores all intermediate files, this directory can grow to become very - # large, especially for data with a large amount of TRs. - # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary - # name like '/work', and then map (-B/-v) your desired output directory to that label. - # - If running outside a container, this should be a full path to a directory. - # - This can be written to '/tmp' if you do not intend to save your working directory. - path: /tmp + output_tree: default - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: True + system_config: - log_directory: + # Stop worklow execution on first crash? + fail_fast: Off - # Whether to write log details of the pipeline run to the logging files. - run_logging: True + # Random seed used to fix the state of execution. + # If unset, each process uses its own default. + # If set, a `random.log` file will be generated logging the random seed and each node to which that seed was applied. + # If set to a positive integer (up to 2147483647), that integer will be used to seed each process that accepts a random seed. + # If set to 'random', a random positive integer (up to 2147483647) will be generated and that seed will be used to seed each process that accepts a random seed. + random_seed: - path: /output/logs + # Prior to running a pipeline C-PAC makes a rough estimate of a worst-case-scenario maximum concurrent memory usage with high-resoltion data, raising an exception describing the recommended minimum memory allocation for the given configuration. + # Turning this option off will allow pipelines to run without allocating the recommended minimum, allowing for more efficient runs at the risk of out-of-memory crashes (use at your own risk) + raise_insufficient: On - crash_log_directory: + # A callback.log file from a previous run can be provided to estimate memory usage based on that run. + observed_usage: - # Directory where CPAC should write crash logs. - path: /output/crash + # Path to callback log file with previously observed usage. + # Can be overridden with the commandline flag `--runtime_usage`. + callback_log: - system_config: + # Percent. E.g., `buffer: 10` would estimate 1.1 * the observed memory usage from the callback log provided in "usage". + # Can be overridden with the commandline flag `--runtime_buffer`. + buffer: 10 # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. on_grid: - run: Off # Sun Grid Engine (SGE), Portable Batch System (PBS), or Simple Linux Utility for Resource Management (SLURM). # Only applies if you are running on a grid or compute cluster. resource_manager: SGE - SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. - parallel_environment: mpi_smp + parallel_environment: mpi_smp # SGE Queue to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. - queue: all.q + queue: all.q # The maximum amount of memory each participant's workflow can allocate. # Use this to place an upper bound of memory usage. @@ -134,7 +134,52 @@ pipeline_setup: # Full path to the FSL version to be used by CPAC. # If you have specified an FSL path in your .bashrc file, this path will be set automatically. - FSLDIR: /usr/share/fsl/5.0 + FSLDIR: /usr/share/fsl/5.0 + + working_directory: + + # Directory where C-PAC should store temporary and intermediate files. + # - This directory must be saved if you wish to re-run your pipeline from where you left off (if not completed). + # - NOTE: As it stores all intermediate files, this directory can grow to become very + # large, especially for data with a large amount of TRs. + # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary + # name like '/work', and then map (-B/-v) your desired output directory to that label. + # - If running outside a container, this should be a full path to a directory. + # - This can be written to '/tmp' if you do not intend to save your working directory. + path: /outputs/working + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: On + + log_directory: + + # Whether to write log details of the pipeline run to the logging files. + run_logging: On + path: /outputs/logs + + # Configuration options for logging visualizations of the workflow graph + graphviz: + + # Configuration for a graphviz visualization of the entire workflow. See https://fcp-indi.github.io/docs/developer/nodes#CPAC.pipeline.nipype_pipeline_engine.Workflow.write_graph for details about the various options + entire_workflow: + + # Whether to generate the graph visualization + generate: Off + + # Options: [orig, hierarchical, flat, exec, colored] + graph2use: [] + + # Options: [svg, png] + format: [] + + # The node name will be displayed in the form `nodename (package)` when On or `nodename.Class.package` when Off + simple_form: On + + crash_log_directory: + + # Directory where CPAC should write crash logs. + path: /outputs/crash Amazon-AWS: @@ -142,14 +187,13 @@ pipeline_setup: aws_output_bucket_credentials: # Enable server-side 256-AES encryption on data to the S3 bucket - s3_encryption: False + s3_encryption: Off Debugging: # Verbose developer messages. verbose: Off - # PREPROCESSING # ------------- surface_analysis: @@ -157,74 +201,49 @@ surface_analysis: # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, # select those 'Freesurfer-' labeled options further below in anatomical_preproc. - freesurfer: - run: Off - - -longitudinal_template_generation: + freesurfer: + run_reconall: Off - # If you have multiple T1w's, you can generate your own run-specific custom - # T1w template to serve as an intermediate to the standard template for - # anatomical registration. - - # This runs before the main pipeline as it requires multiple T1w sessions - # at once. - run: Off - - # Freesurfer longitudinal template algorithm using FSL FLIRT - # Method to average the dataset at each iteration of the template creation - # Options: median, mean or std - average_method: median - - # Degree of freedom for FLIRT in the template creation - # Options: 12 (affine), 9 (traditional), 7 (global rescale) or 6 (rigid body) - dof: 12 + # Add extra arguments to recon-all command + reconall_args: - # Interpolation parameter for FLIRT in the template creation - # Options: trilinear, nearestneighbour, sinc or spline - interp: trilinear - - # Cost function for FLIRT in the template creation - # Options: corratio, mutualinfo, normmi, normcorr, leastsq, labeldiff or bbr - cost: corratio - - # Number of threads used for one run of the template generation algorithm - thread_pool: 2 - - # Threshold of transformation distance to consider that the loop converged - # (-1 means numpy.finfo(np.float64).eps and is the default) - convergence_threshold: -1 + # Ingress freesurfer recon-all folder + ingress_reconall: Off + # Run ABCD-HCP post FreeSurfer and fMRISurface pipeline + post_freesurfer: + run: Off + subcortical_gray_labels: /opt/dcan-tools/pipeline/global/config/FreeSurferSubcorticalLabelTableLut.txt + freesurfer_labels: /opt/dcan-tools/pipeline/global/config/FreeSurferAllLut.txt + surf_atlas_dir: /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases + gray_ordinates_dir: /opt/dcan-tools/pipeline/global/templates/Greyordinates + gray_ordinates_res: 2 + high_res_mesh: 164 + low_res_mesh: 32 + fmri_res: 2 + smooth_fwhm: 2 anatomical_preproc: - run: Off - - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - - # this is a fork option - run: [Off] - - # options: 'Gaussian' or 'Rician' - noise_model: 'Gaussian' - - # N4 bias field correction via ANTs - n4_bias_field_correction: - - # this is a fork option - run: [Off] - - # An integer to resample the input image to save computation time. Shrink factors <= 4 are commonly used. - shrink_factor: 2 - acpc_alignment: - + T1w_brain_ACPC_template: + + # Choose a tool to crop the FOV in ACPC alignment. + # Using FSL's robustfov or flirt command. + # Default: robustfov for human data, flirt for monkey data. + FOV_crop: robustfov + + # Run ACPC alignment on brain mask + # If the brain mask is in native space, turn it on + # If the brain mask is ACPC aligned, turn it off + align_brain_mask: Off + T2w_ACPC_template: + T2w_brain_ACPC_template: run: Off # Run ACPC alignment before non-local means filtering or N4 bias # correction - run_before_preproc: True + run_before_preproc: On # ACPC size of brain in z-dimension in mm. # Default: 150mm for human data. @@ -233,46 +252,48 @@ anatomical_preproc: # ACPC Target # options: 'brain' or 'whole-head' # note: 'brain' requires T1w_brain_ACPC_template below to be populated - acpc_target: 'whole-head' + acpc_target: whole-head # ACPC aligned template - T1w_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm.nii.gz - T1w_brain_ACPC_template: None + T1w_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm.nii.gz brain_extraction: - - #run: Off + run: Off + FreeSurfer-BET: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] + # Template to be used for FreeSurfer-BET brain extraction in CCS-options pipeline + T1w_brain_template_mask_ccs: /ccs_template/MNI152_T1_1mm_first_brain_mask.nii.gz + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option - using: ['3dSkullStrip'] + using: [3dSkullStrip] # option parameters AFNI-3dSkullStrip: # Output a mask volume instead of a skull-stripped volume. The mask volume containes 0 to 6, which represents voxel's postion. If set to True, C-PAC will use this output to generate anatomical brain mask for further analysis. - mask_vol: False + mask_vol: Off # Set the threshold value controlling the brain vs non-brain voxels. Default is 0.6. shrink_factor: 0.6 # Vary the shrink factor at every iteration of the algorithm. This prevents the likelihood of surface getting stuck in large pools of CSF before reaching the outer surface of the brain. Default is On. - var_shrink_fac: True + var_shrink_fac: On # The shrink factor bottom limit sets the lower threshold when varying the shrink factor. Default is 0.4, for when edge detection is used (which is On by default), otherwise the default value is 0.65. shrink_factor_bot_lim: 0.4 # Avoids ventricles while skullstripping. - avoid_vent: True + avoid_vent: On # Set the number of iterations. Default is 250.The number of iterations should depend upon the density of your mesh. n_iterations: 250 # While expanding, consider the voxels above and not only the voxels below - pushout: True + pushout: On # Perform touchup operations at the end to include areas not covered by surface expansion. - touchup: True + touchup: On # Give the maximum number of pixels on either side of the hole that can be filled. The default is 10 only if 'Touchup' is On - otherwise, the default is 0. fill_hole: 10 @@ -284,16 +305,16 @@ anatomical_preproc: smooth_final: 20 # Avoid eyes while skull stripping. Default is On. - avoid_eyes: True + avoid_eyes: On # Use edge detection to reduce leakage into meninges and eyes. Default is On. - use_edge: True + use_edge: On # Speed of expansion. exp_frac: 0.1 # Perform aggressive push to edge. This might cause leakage. Default is Off. - push_to_edge: False + push_to_edge: Off # Use outer skull to limit expansion of surface into the skull in case of very strong shading artifacts. Use this only if you have leakage into the skull. use_skull: Off @@ -311,7 +332,7 @@ anatomical_preproc: blur_fwhm: 0 # Set it as True if processing monkey data with AFNI - monkey: False + monkey: Off FSL-BET: @@ -352,62 +373,82 @@ anatomical_preproc: threshold: Off # Vertical gradient in fractional intensity threshold (-1,1) - vertical_gradient : 0.0 + vertical_gradient: 0.0 UNet: # UNet model - unet_model : s3://fcp-indi/resources/cpac/resources/Site-All-T-epoch_36.model + unet_model: s3://fcp-indi/resources/cpac/resources/Site-All-T-epoch_36.model niworkflows-ants: # Template to be used during niworkflows-ants. # It is not necessary to change this path unless you intend to use a non-standard template. - # niworkflows-ants Brain extraction template - template_path : /ants_template/oasis/T_template0.nii.gz + template_path: /ants_template/oasis/T_template0.nii.gz # niworkflows-ants probability mask - mask_path : /ants_template/oasis/T_template0_BrainCerebellumProbabilityMask.nii.gz + mask_path: /ants_template/oasis/T_template0_BrainCerebellumProbabilityMask.nii.gz # niworkflows-ants registration mask (can be optional) - regmask_path : /ants_template/oasis/T_template0_BrainCerebellumRegistrationMask.nii.gz + regmask_path: /ants_template/oasis/T_template0_BrainCerebellumRegistrationMask.nii.gz + + run_t2: Off + + # Bias field correction based on square root of T1w * T2w + t1t2_bias_field_correction: + run: Off + BiasFieldSmoothingSigma: 5 + + # Non-local means filtering via ANTs DenoiseImage + non_local_means_filtering: + + # this is a fork option + run: [Off] + # options: 'Gaussian' or 'Rician' + noise_model: Gaussian + + # N4 bias field correction via ANTs + n4_bias_field_correction: + + # this is a fork option + run: [Off] + + # An integer to resample the input image to save computation time. Shrink factors <= 4 are commonly used. + shrink_factor: 2 segmentation: # Automatically segment anatomical images into white matter, gray matter, # and CSF based on prior probability maps. run: Off - tissue_segmentation: - # using: ['FSL-FAST', 'Template_Based', 'FreeSurfer', 'ANTs_Prior_Based'] + # using: ['FSL-FAST', 'Template_Based', 'ANTs_Prior_Based', 'FreeSurfer'] # this is a fork point - using: ['FSL-FAST'] + using: [FSL-FAST] # option parameters FSL-FAST: - thresholding: # thresholding of the tissue segmentation probability maps # options: 'Auto', 'Custom' - use: 'Auto' - + use: Auto Custom: + # Set the threshold value for the segmentation probability masks (CSF, White Matter, and Gray Matter) # The values remaining will become the binary tissue masks. # A good starting point is 0.95. - # CSF (cerebrospinal fluid) threshold. - CSF_threshold_value : 0.95 + CSF_threshold_value: 0.95 # White matter threshold. - WM_threshold_value : 0.95 + WM_threshold_value: 0.95 # Gray matter threshold. - GM_threshold_value : 0.95 + GM_threshold_value: 0.95 use_priors: @@ -437,11 +478,10 @@ segmentation: # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] - template_for_segmentation: ['T1_Template'] + template_for_segmentation: [T1_Template] # These masks are included as part of the 'Image Resource Files' package available # on the Install page of the User Guide. - # Full path to a binarized White Matter mask. WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz @@ -455,9 +495,8 @@ segmentation: # Generate white matter, gray matter, CSF masks based on antsJointLabelFusion # ANTs Prior-based Segmentation workflow that has shown optimal results for non-human primate data. - # The atlas image assumed to be used in ANTs Prior-based Segmentation. - template_brain_list : + template_brain_list: - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_T1w_brain.nii.gz - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_T1w_brain.nii.gz @@ -475,177 +514,188 @@ segmentation: - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_Segmentation.nii.gz - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_Segmentation.nii.gz + # Label values corresponding to Gray Matter in multiatlas file + GM_label: [3, 42] + + # Label values corresponding to White Matter in multiatlas file + WM_label: [2, 41] + # Label values corresponding to CSF/GM/WM in atlas file # It is not necessary to change this values unless your CSF/GM/WM label values are different from Freesurfer Color Lookup Table. # https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/AnatomicalROI/FreeSurferColorLUT - # Label values corresponding to CSF in multiatlas file - CSF_label : [24] - - # Label values corresponding to Gray Matter in multiatlas file - GM_label : [3, 42] + CSF_label: [24] - # Label values corresponding to White Matter in multiatlas file - WM_label : [2, 41] - FreeSurfer: # Use mri_binarize --erode option to erode segmentation masks erode: 0 # Label values corresponding to CSF in FreeSurfer aseg segmentation file - CSF_label : [24] + CSF_label: [24] # Label values corresponding to Gray Matter in FreeSurfer aseg segmentation file - GM_label : [3, 42] + GM_label: [3, 42] # Label values corresponding to White Matter in FreeSurfer aseg segmentation file - WM_label : [2, 41] - + WM_label: [2, 41] registration_workflows: - anatomical_registration: - run: Off + registration: + FSL-FNIRT: - # The resolution to which anatomical images should be transformed during registration. - # This is the resolution at which processed anatomical files will be output. - resolution_for_anat: 2mm + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + # specifically for monkey pipeline + ref_resolution: 2mm - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz + # Template to be used during registration. + # It is for monkey pipeline specifically. + FNIRT_T1w_brain_template: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz + # Template to be used during registration. + # It is for monkey pipeline specifically. + FNIRT_T1w_template: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: $FSLDIR/data/standard/MNI152_T1_2mm_brain_mask_dil.nii.gz - # Register skull-on anatomical image to a template. - reg_with_skull: True + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: $FSLDIR/data/standard/MNI152_T1_2mm.nii.gz - registration: + # Configuration file to be used by FSL to set FNIRT parameters. + # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. + fnirt_config: T1_2_MNI152_2mm + + # Reference mask for FSL registration. + ref_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz + + # Interpolation method for writing out transformed anatomical images. + # Possible values: trilinear, sinc, spline + interpolation: sinc + + # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: $FSLDIR/etc/flirtsch/ident.mat # using: ['ANTS', 'FSL', 'FSL-linear'] # this is a fork point # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline - using: ['ANTS'] + using: [ANTS] # option parameters ANTs: # If a lesion mask is available for a T1w image, use it to improve the ANTs' registration # ANTS registration only. - use_lesion_mask: False + use_lesion_mask: Off # ANTs parameters for T1-template-based registration T1_registration: - - collapse-output-transforms: 0 - dimensionality: 3 - - initial-moving-transform : - initializationFeature: 0 - + - initial-moving-transform: + initializationFeature: 0 - transforms: - - Rigid: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - Affine: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - SyN: - gradientStep : 0.1 - updateFieldVarianceInVoxelSpace : 3.0 - totalFieldVarianceInVoxelSpace : 0.0 - metric: - type : CC - metricWeight: 1 - radius : 4 - convergence: - iteration : 100x100x70x20 - convergenceThreshold : 1e-09 - convergenceWindowSize : 15 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 6x4x2x1 - use-histogram-matching : True - winsorize-image-intensities : - lowerQuantile : 0.01 - upperQuantile : 0.99 + - Rigid: + gradientStep: 0.1 + metric: + type: MI + metricWeight: 1 + numberOfBins: 32 + samplingStrategy: Regular + samplingPercentage: 0.25 + convergence: + iteration: 1000x500x250x100 + convergenceThreshold: 1e-08 + convergenceWindowSize: 10 + smoothing-sigmas: 3.0x2.0x1.0x0.0 + shrink-factors: 8x4x2x1 + use-histogram-matching: On + - Affine: + gradientStep: 0.1 + metric: + type: MI + metricWeight: 1 + numberOfBins: 32 + samplingStrategy: Regular + samplingPercentage: 0.25 + convergence: + iteration: 1000x500x250x100 + convergenceThreshold: 1e-08 + convergenceWindowSize: 10 + smoothing-sigmas: 3.0x2.0x1.0x0.0 + shrink-factors: 8x4x2x1 + use-histogram-matching: On + - SyN: + gradientStep: 0.1 + updateFieldVarianceInVoxelSpace: 3.0 + totalFieldVarianceInVoxelSpace: 0.0 + metric: + type: CC + metricWeight: 1 + radius: 4 + convergence: + iteration: 100x100x70x20 + convergenceThreshold: 1e-09 + convergenceWindowSize: 15 + smoothing-sigmas: 3.0x2.0x1.0x0.0 + shrink-factors: 6x4x2x1 + use-histogram-matching: On + winsorize-image-intensities: + lowerQuantile: 0.01 + upperQuantile: 0.99 # Interpolation method for writing out transformed anatomical images. # Possible values: Linear, BSpline, LanczosWindowedSinc interpolation: LanczosWindowedSinc - FSL-FNIRT: + overwrite_transform: + run: Off - # Configuration file to be used by FSL to set FNIRT parameters. - # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. - fnirt_config: T1_2_MNI152_2mm + # Choose the tool to overwrite transform, currently only support 'FSL' to overwrite 'ANTs' transforms in ABCD-options pipeline. + # using: 'FSL' + using: FSL - # Reference mask for FSL registration. - ref_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + resolution_for_anat: 2mm - # Interpolation method for writing out transformed anatomical images. - # Possible values: trilinear, sinc, spline - interpolation: sinc + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz - # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_template: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz - #applywarp: + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - # using: ANTS or FSL. Choose the applywarp tool regardless of which tool to calculate transforms - #using: ANTS + # Register skull-on anatomical image to a template. + reg_with_skull: On functional_registration: - coregistration: - # functional (BOLD/EPI) registration to anatomical (structural/T1) + # functional (BOLD/EPI) registration to anatomical (structural/T1) run: Off - func_input_prep: - # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. - # input: ['Mean Functional', 'Selected_Functional_Volume'] - input: ['Mean_Functional'] + # Choose whether to use functional brain or skull as the input to functional-to-anatomical registration + reg_with_skull: Off + # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. + # input: ['Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference'] + input: [Mean_Functional] Mean Functional: # Run ANTs’ N4 Bias Field Correction on the input BOLD (EPI) # this can increase tissue contrast which may improve registration quality in some data - n4_correct_func: False + n4_correct_func: Off Selected Functional Volume: @@ -654,124 +704,65 @@ registration_workflows: func_reg_input_volume: 0 boundary_based_registration: + # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [Off] - # Standard FSL 5.0 Scheduler used for Boundary Based Registration. - # It is not necessary to change this path unless you intend to use non-standard MNI registration. - bbr_schedule: /usr/share/fsl/5.0/etc/flirtsch/bbr.sch - - EPI_registration: - - # directly register the mean functional to an EPI template - # instead of applying the anatomical T1-to-template transform to the functional data that has been - # coregistered to anatomical/T1 space - run: Off - - # using: ['ANTS', 'FSL', 'FSL-linear'] - # this is a fork point - # ex. selecting both ['ANTS', 'FSL'] will run both and fork the pipeline - using: ['ANTS'] - - # EPI template for direct functional-to-template registration - # (bypassing coregistration and the anatomical-to-template transforms) - EPI_template: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz + # reference for boundary based registration + # options: 'whole-head' or 'brain' + reference: whole-head - # EPI template mask. - EPI_template_mask: None + # choose which FAST map to generate BBR WM mask + # options: 'probability_map', 'partial_volume_map' + bbr_wm_map: probability_map - ANTs: + # optional FAST arguments to generate BBR WM mask + bbr_wm_mask_args: -thr 0.5 -bin - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: + # Standard FSL 5.0 Scheduler used for Boundary Based Registration. + # It is not necessary to change this path unless you intend to use non-standard MNI registration. + bbr_schedule: $FSLDIR/etc/flirtsch/bbr.sch - - collapse-output-transforms: 0 - - dimensionality: 3 - - initial-moving-transform : - initializationFeature: 0 + # reference: 'brain' or 'restore-brain' + # In ABCD-options pipeline, 'restore-brain' is used as coregistration reference + reference: brain - - transforms: - - Rigid: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - Affine: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - SyN: - gradientStep : 0.1 - updateFieldVarianceInVoxelSpace : 3.0 - totalFieldVarianceInVoxelSpace : 0.0 - metric: - type : CC - metricWeight: 1 - radius : 4 - convergence: - iteration : 100x100x70x20 - convergenceThreshold : 1e-09 - convergenceWindowSize : 15 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 6x4x2x1 - use-histogram-matching : True - winsorize-image-intensities : - lowerQuantile : 0.01 - upperQuantile : 0.99 + # Choose FSL or ABCD as coregistration method + using: FSL - # Interpolation method for writing out transformed EPI images. - # Possible values: Linear, BSpline, LanczosWindowedSinc - interpolation: LanczosWindowedSinc + # Choose brain or whole-head as coregistration input + input: brain - FSL-FNIRT: + # Choose coregistration interpolation + interpolation: trilinear - # Configuration file to be used by FSL to set FNIRT parameters. - # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. - fnirt_config: T1_2_MNI152_2mm + # Choose coregistration cost function + cost: corratio - # Interpolation method for writing out transformed EPI images. - # Possible values: trilinear, sinc, spline - interpolation: sinc + # Choose coregistration degree of freedom + dof: 6 - # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + # Extra arguments for FSL flirt + arguments: func_registration_to_template: # these options modify the application (to the functional data), not the calculation, of the # T1-to-template and EPI-to-template transforms calculated earlier during registration - # apply the functional-to-template (T1 template) registration transform to the functional data run: Off - + # apply the functional-to-template (EPI template) registration transform to the functional data - #run_EPI: Off + run_EPI: Off + apply_transform: + + # options: 'default', 'abcd', 'single_step_resampling_from_stc', 'dcan_nhp' + # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. + # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. + # 'single_step_resampling_from_stc': apply motion correction, func-to-anat and anat-to-template transforms on each of slice-time-corrected functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. + # - if 'single_step_resampling_from_stc', 'template' is the only valid option for ``nuisance_corrections: 2-nuisance_regression: space`` + using: default output_resolution: @@ -793,25 +784,28 @@ registration_workflows: target_template: # choose which template space to transform derivatives towards - # options: ['T1_template', 'EPI_template'] - using: ['T1_template'] - + # using: ['T1_template', 'EPI_template'] + # this is a fork point + # NOTE: + # this will determine which registration transform to use to warp the functional + # outputs and derivatives to template space + using: [T1_template] T1_template: # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. - T1w_brain_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz + T1w_brain_template_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz # Standard Anatomical Brain Image with Skull. # This can be different than the template used as the reference/fixed for T1-to-template registration. - T1w_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}.nii.gz + T1w_template_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}.nii.gz # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz + T1w_brain_template_mask_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz # a standard template for resampling if using float resolution - T1w_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + T1w_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz EPI_template: @@ -820,10 +814,10 @@ registration_workflows: EPI_template_funcreg: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz # EPI template mask. - EPI_template_mask_funcreg: None + EPI_template_mask_funcreg: # a standard template for resampling if using float resolution - EPI_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + EPI_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz ANTs_pipelines: @@ -839,42 +833,105 @@ registration_workflows: # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + identity_matrix: $FSLDIR/etc/flirtsch/ident.mat + EPI_registration: -functional_preproc: + # directly register the mean functional to an EPI template + # instead of applying the anatomical T1-to-template transform to the functional data that has been + # coregistered to anatomical/T1 space + run: Off - run: Off + # using: ['ANTS', 'FSL', 'FSL-linear'] + # this is a fork point + # ex. selecting both ['ANTS', 'FSL'] will run both and fork the pipeline + using: [ANTS] - truncation: + # EPI template for direct functional-to-template registration + # (bypassing coregistration and the anatomical-to-template transforms) + EPI_template: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz - # First timepoint to include in analysis. - # Default is 0 (beginning of timeseries). - # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. - # Note: the selection here applies to all scans of all participants. - start_tr: 0 + # EPI template mask. + EPI_template_mask: + ANTs: - # Last timepoint to include in analysis. - # Default is None or End (end of timeseries). - # Last timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. - # Note: the selection here applies to all scans of all participants. - stop_tr: None + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + - collapse-output-transforms: 0 + - dimensionality: 3 + - initial-moving-transform: + initializationFeature: 0 + - transforms: + - Rigid: + gradientStep: 0.1 + metric: + type: MI + metricWeight: 1 + numberOfBins: 32 + samplingStrategy: Regular + samplingPercentage: 0.25 + convergence: + iteration: 1000x500x250x100 + convergenceThreshold: 1e-08 + convergenceWindowSize: 10 + smoothing-sigmas: 3.0x2.0x1.0x0.0 + shrink-factors: 8x4x2x1 + use-histogram-matching: On + - Affine: + gradientStep: 0.1 + metric: + type: MI + metricWeight: 1 + numberOfBins: 32 + samplingStrategy: Regular + samplingPercentage: 0.25 + convergence: + iteration: 1000x500x250x100 + convergenceThreshold: 1e-08 + convergenceWindowSize: 10 + smoothing-sigmas: 3.0x2.0x1.0x0.0 + shrink-factors: 8x4x2x1 + use-histogram-matching: On + - SyN: + gradientStep: 0.1 + updateFieldVarianceInVoxelSpace: 3.0 + totalFieldVarianceInVoxelSpace: 0.0 + metric: + type: CC + metricWeight: 1 + radius: 4 + convergence: + iteration: 100x100x70x20 + convergenceThreshold: 1e-09 + convergenceWindowSize: 15 + smoothing-sigmas: 3.0x2.0x1.0x0.0 + shrink-factors: 6x4x2x1 + use-histogram-matching: On + winsorize-image-intensities: + lowerQuantile: 0.01 + upperQuantile: 0.99 - scaling: + # Interpolation method for writing out transformed EPI images. + # Possible values: Linear, BSpline, LanczosWindowedSinc + interpolation: LanczosWindowedSinc - # Scale functional raw data, usually used in rodent pipeline - run: Off + FSL-FNIRT: - # Scale the size of the dataset voxels by the factor. - scaling_factor: 10 + # Configuration file to be used by FSL to set FNIRT parameters. + # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. + fnirt_config: T1_2_MNI152_2mm - despiking: + # Interpolation method for writing out transformed EPI images. + # Possible values: trilinear, sinc, spline + interpolation: sinc - # Run AFNI 3dDespike - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: $FSLDIR/etc/flirtsch/ident.mat +functional_preproc: + run: Off slice_timing_correction: # Interpolate voxel time courses so they are sampled at the same time points. @@ -882,9 +939,17 @@ functional_preproc: # run: [On, Off] - this will run both and fork the pipeline run: [Off] + # use specified slice time pattern rather than one in header + tpattern: + + # align each slice to given time offset + # The default alignment time is the average of the 'tpattern' values (either from the dataset header or from the tpattern option). + tzero: + motion_estimates_and_correction: + run: Off + motion_estimates: - motion_estimates: # calculate motion statistics BEFORE slice-timing correction calculate_motion_first: Off @@ -895,7 +960,7 @@ functional_preproc: # using: ['3dvolreg', 'mcflirt'] # this is a fork point - using: ['3dvolreg'] + using: [3dvolreg] # option parameters AFNI-3dvolreg: @@ -903,8 +968,8 @@ functional_preproc: # This option is useful when aligning high-resolution datasets that may need more alignment than a few voxels. functional_volreg_twopass: On - # Choose motion correction reference. Options: mean, median, selected volume - motion_correction_reference: ['mean'] + # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference + motion_correction_reference: [mean] # Choose motion correction reference volume motion_correction_reference_volume: 0 @@ -918,77 +983,69 @@ functional_preproc: # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [Off] + filters: [] - # options: "notch", "lowpass" - filter_type: "notch" + distortion_correction: - # Number of filter coefficients. - filter_order: 4 + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [Off] + Blip-FSL-TOPUP: - # Dataset-wide respiratory rate data from breathing belt. - # Notch filter requires either: - # "breathing_rate_min" and "breathing_rate_max" - # or - # "center_frequency" and "filter_bandwitdh". - # Lowpass filter requires either: - # "breathing_rate_min" - # or - # "lowpass_cutoff". - # If "breathing_rate_min" (for lowpass and notch filter) - # and "breathing_rate_max" (for notch filter) are set, - # the values set in "lowpass_cutoff" (for lowpass filter), - # "center_frequency" and "filter_bandwidth" (for notch filter) - # options are ignored. + # (approximate) resolution (in mm) of warp basis for the different sub-sampling levels, default 10 + warpres: 10 - # Lowest Breaths-Per-Minute in dataset. - # For both notch and lowpass filters. - breathing_rate_min: + # sub-sampling scheme, default 1 + subsamp: 1 - # Highest Breaths-Per-Minute in dataset. - # For notch filter. - breathing_rate_max: + # FWHM (in mm) of gaussian smoothing kernel, default 8 + fwhm: 8 - # notch filter direct customization parameters + # Max # of non-linear iterations, default 5 + miter: 5 - # mutually exclusive with breathing_rate options above. - # If breathing_rate_min and breathing_rate_max are provided, - # the following parameters will be ignored. + # Weight of regularisation, default depending on --ssqlambda and --regmod switches. See user documentation. + lambda: 1 - # the center frequency of the notch filter - center_frequency: + # If set (=1), lambda is weighted by current ssq, default 1 + ssqlambda: 1 - # the width of the notch filter - filter_bandwidth: + # Model for regularisation of warp-field [membrane_energy bending_energy], default bending_energy + regmod: bending_energy - # lowpass filter direct customization parameter + # Estimate movements if set, default 1 (true) + estmov: 1 - # mutually exclusive with breathing_rate options above. - # If breathing_rate_min is provided, the following - # parameter will be ignored. + # Minimisation method 0=Levenberg-Marquardt, 1=Scaled Conjugate Gradient, default 0 (LM) + minmet: 0 - # the frequency cutoff of the filter - lowpass_cutoff: + # Order of spline, 2->Qadratic spline, 3->Cubic spline. Default=3 + splineorder: 3 - distortion_correction: + # Precision for representing Hessian, double or float. Default double + numprec: double - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + # Image interpolation model, linear or spline. Default spline + interp: spline + + # If set (=1), the images are individually scaled to a common mean, default 0 (false) + scale: 0 - # using: ['PhaseDiff', 'Blip'] + # If set (=1), the calculations are done in a different grid, default 1 (true) + regrid: 1 + + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - # NOTE: - # this is NOT a fork point - instead, the technique used will depend on what type of distortion correction field data accompanies the dataset - # for example, phase-difference field maps will lead to phase-difference distortion correction, and phase-encoding direction field maps will lead to blip-up/blip-down - using: ['PhaseDiff', 'Blip'] + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. + using: [PhaseDiff, Blip] # option parameters PhaseDiff: # Since the quality of the distortion heavily relies on the skull-stripping step, we provide a choice of method ('AFNI' for AFNI 3dSkullStrip or 'BET' for FSL BET). # Options: 'BET' or 'AFNI' - fmap_skullstrip_option: 'BET' + fmap_skullstrip_option: BET # Set the fraction value for the skull-stripping of the magnitude file. Depending on the data, a tighter extraction may be necessary in order to prevent noisy voxels from interfering with preparing the field map. # The default value is 0.5. @@ -996,15 +1053,18 @@ functional_preproc: # Set the threshold value for the skull-stripping of the magnitude file. Depending on the data, a tighter extraction may be necessary in order to prevent noisy voxels from interfering with preparing the field map. # The default value is 0.6. - fmap_skullstrip_AFNI_threshold: 0.6 + fmap_skullstrip_AFNI_threshold: 0.6 func_masking: + FSL-BET: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] - # this is a fork point - using: ['AFNI'] + # Set an intensity threshold to improve skull stripping performances of FSL BET on rodent scans. + functional_mean_thr: + run: Off + threshold_value: 98 - FSL-BET: + # Bias correct the functional mean image to improve skull stripping performances of FSL BET on rodent scans + functional_mean_bias_correction: Off # Apply to 4D FMRI data, if bold_bet_functional_mean_boolean : Off. # Mutually exclusive with functional, reduce_bias, robust, padding, remove_eyes, surfaces @@ -1047,152 +1107,189 @@ functional_preproc: # Vertical gradient in fractional intensity threshold (-1,1) vertical_gradient: 0.0 + FSL_AFNI: + bold_ref: + brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + brain_probseg: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + # Apply functional mask in native space + apply_func_mask_in_native_space: On + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. + # this is a fork point + using: [AFNI] Anatomical_Refined: # Choose whether or not to dilate the anatomical mask if you choose 'Anatomical_Refined' as the functional masking option. It will dilate one voxel if enabled. - anatomical_mask_dilation: False + anatomical_mask_dilation: Off + generate_func_mean: -nuisance_corrections: + # Generate mean functional image + run: Off - 1-ICA-AROMA: + normalize_func: + + # Normalize functional image + run: Off + + truncation: + + # First timepoint to include in analysis. + # Default is 0 (beginning of timeseries). + # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. + # Note: the selection here applies to all scans of all participants. + start_tr: 0 + + # Last timepoint to include in analysis. + # Default is None or End (end of timeseries). + # Last timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. + # Note: the selection here applies to all scans of all participants. + stop_tr: + + scaling: + # Scale functional raw data, usually used in rodent pipeline + run: Off + + # Scale the size of the dataset voxels by the factor. + scaling_factor: 10 + + despiking: + + # Run AFNI 3dDespike # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [Off] + space: native - # Types of denoising strategy: - # nonaggr: nonaggressive-partial component regression - # aggr: aggressive denoising - denoising_type: nonaggr - +nuisance_corrections: 2-nuisance_regression: # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [Off] - - # switch to Off if nuisance regression is off and you don't want to write out the regressors - #create_regressors: Off # Select which nuisance signal corrections to apply - Regressors: None - - # Standard Lateral Ventricles Binary Mask - # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: $FSLDIR/data/atlases/HarvardOxford/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz - - # Whether to run frequency filtering before or after nuisance regression. - # Options: 'After' or 'Before' - bandpass_filtering_order: 'After' + Regressors: # Process and refine masks used to produce regressors and time series for # regression. regressor_masks: - erode_anatomical_brain_mask: - # Erode binarized anatomical brain mask. If choosing True, please also set seg_csf_use_erosion: True; regOption: niworkflows-ants. + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: + + # Erode binarized anatomical brain mask. If choosing True, please also set regressor_masks['erode_csf']['run']: True; anatomical_preproc['brain_extraction']['using']: niworkflows-ants. run: Off # Target volume ratio, if using erosion. # Default proportion is None for anatomical brain mask. - # Recommend that do not use erosion in both proportion and millimeter method. - brain_mask_erosion_prop: - - # Erode brain mask in millimeter, default of brain is 30 mm - # brain erosion default is using millimeter erosion method when use erosion for brain. - brain_mask_erosion_mm: + # If using erosion, using both proportion and millimeters is not recommended. + brain_mask_erosion_prop: # Erode binarized brain mask in millimeter brain_erosion_mm: erode_csf: + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: + # Erode binarized csf tissue mask. run: Off # Target volume ratio, if using erosion. - # Default proportion is None for CSF (cerebrospinal fluid) mask. - # Recommend to do not use erosion in both proportion and millimeter method. + # Default proportion is None for cerebrospinal fluid mask. + # If using erosion, using both proportion and millimeters is not recommended. csf_erosion_prop: - # Erode brain mask in millimeter, default of csf is 30 mm - # CSF erosion default is using millimeter erosion method when use erosion for CSF. - csf_mask_erosion_mm: - - # Erode binarized CSF (cerebrospinal fluid) mask in millimeter + # Erode binarized cerebrospinal fluid mask in millimeter csf_erosion_mm: erode_wm: - # Erode WM binarized tissue mask. - run: Off - # Target volume ratio, if using erosion. - # Default proportion is 0.6 for White Matter mask. - # Recommend to do not use erosion in both proportion and millimeter method. - # White Matter erosion default is using proportion erosion method when use erosion for White Matter. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. wm_erosion_prop: - # Erode brain mask in millimeter, default of White Matter is None + # Erode WM binarized tissue mask. + run: Off + + # Erode white matter mask in millimeters, default for white matter is None wm_mask_erosion_mm: - # Erode binarized White Matter mask in millimeter + # Erode binarized white matter mask in millimeters wm_erosion_mm: erode_gm: - # Erode GM binarized tissue mask. - run: Off - # Target volume ratio, if using erosion. - # Recommend to do not use erosion in both proportion and millimeter method. + # If using erosion, using both proportion and millimeters is not recommended. gm_erosion_prop: - # Erode brain mask in millimeter, default of csf is 30 mm + # Erode gray matter binarized tissue mask. + run: Off + + # Erode gray matter mask in millimeters gm_mask_erosion_mm: - # Erode binarized White Matter mask in millimeter + # Erode binarized gray matter mask in millimeters gm_erosion_mm: + # this is a fork point + # Run nuisance regression in native or template space + # - If set to [native, template], the number of outputs will be double what it would be if only one space were chosen. Nuisance regression will only be run once per fork. + # - If set to template, will use the brain mask configured in + # ``functional_preproc: func_masking: FSL_AFNI: brain_mask`` + # - If ``registration_workflows: functional_registration: func_registration_to_template: apply_trasnform: using: single_step_resampling_from_stc``, this must only be set to template + space: [native] -# OUTPUTS AND DERIVATIVES -# ----------------------- -post_processing: + # switch to Off if nuisance regression is off and you don't want to write out the regressors + create_regressors: On - spatial_smoothing: + # Standard Lateral Ventricles Binary Mask + # used in CSF mask refinement for CSF signal-related regressions + lateral_ventricles_mask: $FSLDIR/data/atlases/HarvardOxford/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz - # Smooth the derivative outputs. - # Set as ['nonsmoothed'] to disable smoothing. Set as both to get both. - # - # Options: - # ['smoothed', 'nonsmoothed'] - output: ['smoothed'] + # Whether to run frequency filtering before or after nuisance regression. + # Options: 'After' or 'Before' + bandpass_filtering_order: After - # Tool to use for smoothing. - # 'FSL' for FSL MultiImageMaths for FWHM provided - # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided - smoothing_method: ['FSL'] + 1-ICA-AROMA: - # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. # this is a fork point - # i.e. multiple kernels - fwhm: [4,6,8] - fwhm: [4] - - z-scoring: - - # z-score standardize the derivatives. This may be needed for group-level analysis. - # Set as ['raw'] to disable z-scoring. Set as both to get both. - # - # Options: - # ['z-scored', 'raw'] - output: ['z-scored'] + # run: [On, Off] - this will run both and fork the pipeline + run: [Off] + # Types of denoising strategy: + # nonaggr: nonaggressive-partial component regression + # aggr: aggressive denoising + denoising_type: nonaggr timeseries_extraction: - run: Off + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [] # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg @@ -1214,10 +1311,10 @@ timeseries_extraction: /ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg /ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-1x1x1.nii.gz: Avg /ndmg_atlases/label/Human/MICCAI_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer1000_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer200_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer300_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer400_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-1000Parcels17NetworksOrder.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-200Parcels17NetworksOrder.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-300Parcels17NetworksOrder.nii.gz: Avg + /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-400Parcels17NetworksOrder.nii.gz: Avg /ndmg_atlases/label/Human/Talairach_space-MNI152NLin6_res-1x1x1.nii.gz: Avg /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-1x1x1.nii.gz: Avg /ndmg_atlases/label/Human/Desikan_space-MNI152NLin6_res-1x1x1.nii.gz: Avg @@ -1235,72 +1332,53 @@ timeseries_extraction: # NOTE: in rare cases, realigning the ROI to the functional space may # result in small misalignments for very small ROIs - please double # check your data if you see issues - realignment: 'ROI_to_func' - - -seed_based_correlation_analysis: - - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off - - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg - /cpac_templates/CC400.nii.gz: Avg, MultReg - /cpac_templates/ez_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/aal_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/CC200.nii.gz: Avg, MultReg - /cpac_templates/tt_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/ho_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/rois_3mm.nii.gz: Avg, MultReg - - # Normalize each time series before running Dual Regression SCA. - norm_timeseries_for_DR: True - + realignment: ROI_to_func amplitude_low_frequency_fluctuation: # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. run: Off + # space: Template or Native + target_space: [] + # Frequency cutoff (in Hz) for the high-pass filter used when calculating f/ALFF. highpass_cutoff: [0.01] # Frequency cutoff (in Hz) for the low-pass filter used when calculating f/ALFF lowpass_cutoff: [0.1] - regional_homogeneity: # ReHo # Calculate Regional Homogeneity (ReHo) for all voxels. run: Off + # space: Template or Native + target_space: [] + # Number of neighboring voxels used when calculating ReHo # 7 (Faces) # 19 (Faces + Edges) # 27 (Faces + Edges + Corners) cluster_size: 27 - voxel_mirrored_homotopic_connectivity: # VMHC # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. run: Off - symmetric_registration: # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. # It is not necessary to change this path unless you intend to use a non-standard symmetric template. T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_brain_template_symmetric_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain_symmetric.nii.gz + # A reference symmetric brain template for resampling T1w_brain_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_symmetric.nii.gz @@ -1308,6 +1386,10 @@ voxel_mirrored_homotopic_connectivity: # It is not necessary to change this path unless you intend to use a non-standard symmetric template. T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_template_symmetric_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_symmetric.nii.gz + # A reference symmetric skull template for resampling T1w_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_symmetric.nii.gz @@ -1318,7 +1400,6 @@ voxel_mirrored_homotopic_connectivity: # A reference symmetric brain mask template for resampling dilated_symmetric_brain_mask_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_mask_symmetric_dil.nii.gz - network_centrality: # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. @@ -1326,23 +1407,22 @@ network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. - memory_allocation: 1.0 + memory_allocation: 1.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. - template_specification_file: /cpac_templates/Mask_ABIDE_85Percent_GM.nii.gz - + template_specification_file: /cpac_templates/Mask_ABIDE_85Percent_GM.nii.gz degree_centrality: # Enable/Disable degree centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] - weight_options: ['Binarized', 'Weighted'] + weight_options: [] # Select the type of threshold used when creating the degree centrality adjacency matrix. # options: # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' - correlation_threshold_option: 'Sparsity threshold' + correlation_threshold_option: Sparsity threshold # Based on the Threshold Type selected above, enter a Threshold Value. # P-value for Significance Threshold @@ -1356,12 +1436,12 @@ network_centrality: # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] - weight_options: ['Weighted'] + weight_options: [] # Select the type of threshold used when creating the eigenvector centrality adjacency matrix. # options: # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' - correlation_threshold_option: 'Sparsity threshold' + correlation_threshold_option: Sparsity threshold # Based on the Threshold Type selected above, enter a Threshold Value. # P-value for Significance Threshold @@ -1375,12 +1455,12 @@ network_centrality: # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] - weight_options: ['Binarized', 'Weighted'] + weight_options: [] # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' - correlation_threshold_option: 'Correlation threshold' + correlation_threshold_option: Correlation threshold # Based on the Threshold Type selected above, enter a Threshold Value. # P-value for Significance Threshold @@ -1388,6 +1468,95 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.6 +longitudinal_template_generation: + + # If you have multiple T1w's, you can generate your own run-specific custom + # T1w template to serve as an intermediate to the standard template for + # anatomical registration. + # This runs before the main pipeline as it requires multiple T1w sessions + # at once. + run: Off + + # Freesurfer longitudinal template algorithm using FSL FLIRT + # Method to average the dataset at each iteration of the template creation + # Options: median, mean or std + average_method: median + + # Degree of freedom for FLIRT in the template creation + # Options: 12 (affine), 9 (traditional), 7 (global rescale) or 6 (rigid body) + dof: 12 + + # Interpolation parameter for FLIRT in the template creation + # Options: trilinear, nearestneighbour, sinc or spline + interp: trilinear + + # Cost function for FLIRT in the template creation + # Options: corratio, mutualinfo, normmi, normcorr, leastsq, labeldiff or bbr + cost: corratio + + # Number of threads used for one run of the template generation algorithm + thread_pool: 2 + + # Threshold of transformation distance to consider that the loop converged + # (-1 means numpy.finfo(np.float64).eps and is the default) + convergence_threshold: -1 + +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: Off + + # Smooth the derivative outputs. + # Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both. + # + # Options: + # ['smoothed', 'nonsmoothed'] + output: [smoothed] + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided + smoothing_method: [FSL] + + # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. + # this is a fork point + # i.e. multiple kernels - fwhm: [4,6,8] + fwhm: [4] + + z-scoring: + run: Off + + # z-score standardize the derivatives. This may be needed for group-level analysis. + # Set as ['raw'] to disable z-scoring. Set as ['z-scored', 'raw'] to get both. + # + # Options: + # ['z-scored', 'raw'] + output: [z-scored] + +seed_based_correlation_analysis: + + # SCA - Seed-Based Correlation Analysis + # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. + # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. + run: Off + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + /cpac_templates/CC400.nii.gz: Avg, MultReg + /cpac_templates/ez_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/aal_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/CC200.nii.gz: Avg, MultReg + /cpac_templates/tt_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/ho_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/rois_3mm.nii.gz: Avg, MultReg + + # Normalize each time series before running Dual Regression SCA. + norm_timeseries_for_DR: On # PACKAGE INTEGRATIONS # -------------------- @@ -1409,19 +1578,17 @@ PyPEER: # PyPEER Stimulus File Path # This is a file describing the stimulus locations from the calibration sequence. - stimulus_path: None - + stimulus_path: minimal_nuisance_correction: # PyPEER Minimal nuisance regression # Note: PyPEER employs minimal preprocessing - these choices do not reflect what runs in the main pipeline. # PyPEER uses non-nuisance-regressed data from the main pipeline. - # Global signal regression (PyPEER only) - peer_gsr: True + peer_gsr: On # Motion scrubbing (PyPEER only) - peer_scrub: False + peer_scrub: Off # Motion scrubbing threshold (PyPEER only) scrub_thresh: 0.2 diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index bdc9d8808f..ef9134aad5 100755 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,24 +1,31 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_ccs-options + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. - write_func_outputs: True + write_func_outputs: On + + system_config: - system_config: # The maximum amount of memory each participant's workflow can allocate. # Use this to place an upper bound of memory usage. # - Warning: 'Memory Per Participant' multiplied by 'Number of Participants to Run Simultaneously' @@ -30,105 +37,116 @@ pipeline_setup: # PREPROCESSING # ------------- -surface_analysis: +surface_analysis: + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, # select those 'Freesurfer-' labeled options further below in anatomical_preproc. - freesurfer: - - run: On + freesurfer: + run_reconall: On # Add extra arguments to recon-all command - reconall_args: '-clean-bm -gcut' + reconall_args: -clean-bm -gcut -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: + # Ingress freesurfer recon-all folder + ingress_reconall: On - # this is a fork option - run: [On] +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz brain_extraction: - - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose'] - # this is a fork option - using: ['FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose'] - + run: On FreeSurfer-BET: # Template to be used for FreeSurfer-BET brain extraction in CCS-options pipeline T1w_brain_template_mask_ccs: /code/CPAC/resources/templates/MNI152_T1_1mm_first_brain_mask.nii.gz + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] + # this is a fork option + using: + - FreeSurfer-BET-Tight + - FreeSurfer-BET-Loose + - FreeSurfer-Brainmask + + # Non-local means filtering via ANTs DenoiseImage + non_local_means_filtering: + + # this is a fork option + run: [On] + segmentation: # Automatically segment anatomical images into white matter, gray matter, # and CSF based on prior probability maps. run: On - tissue_segmentation: - FreeSurfer: # Use mri_binarize --erode option to erode segmentation masks erode: 1 - # Label values corresponding to CSF in multiatlas file - CSF_label : [4, 5, 43, 44, 31, 63] - - # Label values corresponding to Gray Matter in multiatlas file - GM_label : [3, 42] + # Label values corresponding to CSF in FreeSurfer aseg segmentation file + CSF_label: [4, 5, 43, 44, 31, 63] - # Label values corresponding to White Matter in multiatlas file - WM_label : [2, 41, 7, 46, 251, 252, 253, 254, 255] + # Label values corresponding to White Matter in FreeSurfer aseg segmentation file + WM_label: [2, 41, 7, 46, 251, 252, 253, 254, 255] +registration_workflows: + anatomical_registration: + run: On + registration: + FSL-FNIRT: -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off + # Interpolation method for writing out transformed anatomical images. + # Possible values: trilinear, sinc, spline + interpolation: trilinear - registration: # using: ['ANTS', 'FSL', 'FSL-linear'] # this is a fork point # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline using: [FSL] - FSL-FNIRT: - # Interpolation method for writing out transformed anatomical images. - # Possible values: trilinear, sinc, spline - interpolation: trilinear + # Register skull-on anatomical image to a template. + reg_with_skull: Off - functional_registration: + functional_registration: coregistration: - # functional (BOLD/EPI) registration to anatomical (structural/T1) + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On func_input_prep: # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. - # input: ['Mean Functional', 'Selected_Functional_Volume'] - input: ['Selected_Functional_Volume'] - + # input: ['Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference'] + input: [Selected_Functional_Volume] Selected Functional Volume: # Only for when 'Use as Functional-to-Anatomical Registration Input' is set to 'Selected Functional Volume'. #Input the index of which volume from the functional 4D timeseries input file you wish to use as the input for functional-to-anatomical registration. func_reg_input_volume: 7 - func_registration_to_template: + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On FNIRT_pipelines: # Interpolation method for writing out transformed functional images. # Possible values: trilinear, sinc, spline interpolation: trilinear -functional_preproc: - despiking: - - # Run AFNI 3dDespike - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [On] - +functional_preproc: + run: On slice_timing_correction: # Interpolate voxel time courses so they are sampled at the same time points. @@ -137,29 +155,54 @@ functional_preproc: run: [On] # use specified slice time pattern rather than one in header - tpattern: 'alt+z' + tpattern: alt+z # align each slice to given time offset # The default alignment time is the average of the 'tpattern' values (either from the dataset header or from the tpattern option). tzero: 0 + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'CCS_Anatomical_Refined'] + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. # this is a fork point - using: ['CCS_Anatomical_Refined'] + using: [CCS_Anatomical_Refined] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + + despiking: -nuisance_corrections: - 2-nuisance_regression: + # Run AFNI 3dDespike # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + run: [On] - # switch to Off if nuisance regression is off and you don't want to write out the regressors - create_regressors: Off +nuisance_corrections: + 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: + Regressors: - Name: Regressor-1 Motion: include_delayed: On @@ -201,37 +244,75 @@ nuisance_corrections: top_frequency: 0.1 method: AFNI -timeseries_extraction: - run: Off + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + # switch to Off if nuisance regression is off and you don't want to write out the regressors + create_regressors: Off + +timeseries_extraction: + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + +amplitude_low_frequency_fluctuation: + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: + + # space: Template or Native + target_space: [Native] + +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg # available analyses: # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: + sca_roi_paths: /cpac_templates/CC400.nii.gz: Avg - -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off - -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off - -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off - -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml new file mode 100644 index 0000000000..ec0bb151b8 --- /dev/null +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -0,0 +1,222 @@ +%YAML 1.1 +--- +# CPAC Pipeline Configuration YAML file +# Version 1.8.5 +# +# http://fcp-indi.github.io for more info. +# +# Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank + +pipeline_setup: + + # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths + pipeline_name: cpac-default-deprecated-pipeline + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On + +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + brain_extraction: + run: On + +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + +registration_workflows: + anatomical_registration: + run: On + + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # Select which nuisance signal corrections to apply + Regressors: + - Name: default + Motion: + include_delayed: On + include_squared: On + include_delayed_squared: On + aCompCor: + summary: + method: DetrendPC + components: 5 + tissues: + - WhiteMatter + - CerebrospinalFluid + extraction_resolution: 2 + CerebrospinalFluid: + summary: Mean + extraction_resolution: 2 + erode_mask: On + GlobalSignal: + summary: Mean + PolyOrt: + degree: 2 + Bandpass: + bottom_frequency: 0.01 + top_frequency: 0.1 + method: default + - Name: defaultNoGSR + Motion: + include_delayed: On + include_squared: On + include_delayed_squared: On + aCompCor: + summary: + method: DetrendPC + components: 5 + tissues: + - WhiteMatter + - CerebrospinalFluid + extraction_resolution: 2 + CerebrospinalFluid: + summary: Mean + extraction_resolution: 2 + erode_mask: On + PolyOrt: + degree: 2 + Bandpass: + bottom_frequency: 0.01 + top_frequency: 0.1 + method: default + + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On + +voxel_mirrored_homotopic_connectivity: + + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index f7de382776..9047ca2028 100755 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,29 +1,25 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_fmriprep-options + system_config: - output_directory: - quality_control: - # Generate quality control pages containing preprocessing and derivative outputs. - generate_quality_control_images: False - - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -41,65 +37,60 @@ pipeline_setup: # If you have specified an FSL path in your .bashrc file, this path will be set automatically. FSLDIR: FSLDIR - Amazon-AWS: + Amazon-AWS: + # Enable server-side 256-AES encryption on data to the S3 bucket s3_encryption: On -anatomical_preproc: +anatomical_preproc: + run: On acpc_alignment: # ACPC aligned template T1w_ACPC_template: - T1w_brain_ACPC_template: - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] + run: On + FreeSurfer-BET: + + # Template to be used for FreeSurfer-BET brain extraction in CCS-options pipeline + T1w_brain_template_mask_ccs: + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [niworkflows-ants] - FSL-BET: + # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. mask_boolean: Off - FreeSurfer-BET: - # Template to be used for FreeSurfer-BET brain extraction in CCS-options pipeline - T1w_brain_template_mask_ccs: +segmentation: -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. - run: Off - - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + # option parameters + FSL-FAST: thresholding: # thresholding of the tissue segmentation probability maps # options: 'Auto', 'Custom' - use: 'Custom' + use: Custom - Custom: - # Set the threshold value for the segmentation probability masks (CSF, White Matter, and Gray Matter) - # The values remaining will become the binary tissue masks. - # A good starting point is 0.95. + use_priors: - # CSF (cerebrospinal fluid) threshold. - CSF_threshold_value : 0.95 + # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. + run: Off - # White matter threshold. - WM_threshold_value : 0.95 + # Full path to a directory containing binarized prior probability maps. + # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use non-standard priors. + priors_path: - # Gray matter threshold. - GM_threshold_value : 0.95 + Template_Based: - Template_Based: # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # @@ -108,7 +99,6 @@ segmentation: # These masks are included as part of the 'Image Resource Files' package available # on the Install page of the User Guide. - # Full path to a binarized White Matter mask. WHITE: @@ -119,44 +109,74 @@ segmentation: CSF: ANTs_Prior_Based: + + # Generate white matter, gray matter, CSF masks based on antsJointLabelFusion + # ANTs Prior-based Segmentation workflow that has shown optimal results for non-human primate data. + # The atlas image assumed to be used in ANTs Prior-based Segmentation. template_brain_list: + + # The atlas segmentation images. + # For performing ANTs Prior-based segmentation method + # the number of specified segmentations should be identical to the number of atlas brain image sets. + # eg. + # ANTs_prior_seg_template_brain_list : + # - atlas1.nii.gz + # - atlas2.nii.gz + # ANTs_prior_seg_template_segmentation_list: + # - segmentation1.nii.gz + # - segmentation1.nii.gz template_segmentation_list: - CSF_label: [] + + # Label values corresponding to Gray Matter in multiatlas file GM_label: [] + + # Label values corresponding to White Matter in multiatlas file WM_label: [] + # Label values corresponding to CSF/GM/WM in atlas file + # It is not necessary to change this values unless your CSF/GM/WM label values are different from Freesurfer Color Lookup Table. + # https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/AnatomicalROI/FreeSurferColorLUT + # Label values corresponding to CSF in multiatlas file + CSF_label: [] + FreeSurfer: + + # Use mri_binarize --erode option to erode segmentation masks erode: + + # Label values corresponding to CSF in FreeSurfer aseg segmentation file CSF_label: [] + + # Label values corresponding to Gray Matter in FreeSurfer aseg segmentation file GM_label: [] + + # Label values corresponding to White Matter in FreeSurfer aseg segmentation file WM_label: [] -registration_workflows: - anatomical_registration: - # The resolution to which anatomical images should be transformed during registration. - # This is the resolution at which processed anatomical files will be output. - resolution_for_anat: 1mm +registration_workflows: + anatomical_registration: + run: On + registration: + FSL-FNIRT: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_T1w.nii.gz + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_template: /code/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz + # Reference mask for FSL registration. + ref_mask: - # Register skull-on anatomical image to a template. - reg_with_skull: Off + # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat - registration: # option parameters - ANTs: + ANTs: + # ANTs parameters for T1-template-based registration - T1_registration: + T1_registration: - collapse-output-transforms: 1 - dimensionality: 3 - initial-moving-transform: @@ -211,23 +231,41 @@ registration_workflows: lowerQuantile: 0.005 upperQuantile: 0.995 - FSL-FNIRT: - # Reference mask for FSL registration. - ref_mask: - ref_mask_res-2: - T1w_template_res-2: + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + resolution_for_anat: 1mm + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_T1w.nii.gz + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_template: /code/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz + + # Register skull-on anatomical image to a template. + reg_with_skull: Off + + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + func_input_prep: - functional_registration: - coregistration: - func_input_prep: # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. # input: ['Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference'] - input: ['fmriprep_reference'] + input: [fmriprep_reference] - boundary_based_registration: - # Standard FSL 5.0 Scheduler used for Boundary Based Registration. - # It is not necessary to change this path unless you intend to use non-standard MNI registration. - bbr_schedule: $FSLDIR/etc/flirtsch/bbr.sch + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] # reference for boundary based registration # options: 'whole-head' or 'brain' @@ -235,23 +273,28 @@ registration_workflows: # choose which FAST map to generate BBR WM mask # options: 'probability_map', 'partial_volume_map' - bbr_wm_map: 'partial_volume_map' + bbr_wm_map: partial_volume_map # optional FAST arguments to generate BBR WM mask - bbr_wm_mask_args: '-bin' + bbr_wm_mask_args: -bin - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - FSL-FNIRT: - # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: $FSLDIR/etc/flirtsch/ident.mat + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + apply_transform: + + # options: 'default', 'abcd', 'single_step_resampling_from_stc', 'dcan_nhp' + # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. + # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. + # 'single_step_resampling_from_stc': apply motion correction, func-to-anat and anat-to-template transforms on each of slice-time-corrected functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. + # - if 'single_step_resampling_from_stc', 'template' is the only valid option for ``nuisance_corrections: 2-nuisance_regression: space`` + using: single_step_resampling_from_stc + + output_resolution: - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -267,9 +310,9 @@ registration_workflows: # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 3.438mmx3.438mmx3.4mm - target_template: - # option parameters - T1_template: + target_template: + T1_template: + # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_brain_template_funcreg: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz @@ -284,67 +327,87 @@ registration_workflows: # a standard template for resampling if using float resolution T1w_template_for_resample: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_T1w.nii.gz + EPI_template: + # EPI template for direct functional-to-template registration # (bypassing coregistration and the anatomical-to-template transforms) EPI_template_funcreg: + # a standard template for resampling if using float resolution EPI_template_for_resample: - apply_transform: + FNIRT_pipelines: - # options: 'default', 'abcd', 'single_step_resampling' - # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. - # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. - # 'single_step_resampling': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. - using: 'single_step_resampling' + # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + motion_estimates_and_correction: + run: On + motion_estimates: -functional_preproc: - motion_estimates_and_correction: - motion_estimates: # calculate motion statistics BEFORE slice-timing correction calculate_motion_first: On - motion_correction: + motion_correction: + # using: ['3dvolreg', 'mcflirt'] # this is a fork point using: [mcflirt] # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference - motion_correction_reference: ['fmriprep_reference'] + motion_correction_reference: [fmriprep_reference] + + distortion_correction: - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] # this is a fork point - using: [FSL_AFNI] + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + func_masking: FSL_AFNI: bold_ref: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz brain_mask: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz brain_probseg: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. + # this is a fork point + using: [FSL_AFNI] + generate_func_mean: # Generate mean functional image run: On - normalize_func: - - # Normalize functional image - run: Off - -nuisance_corrections: - 2-nuisance_regression: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - # switch to Off if nuisance regression is off and you don't want to write out the regressors - create_regressors: On +nuisance_corrections: + 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -357,7 +420,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 2 WhiteMatter: @@ -382,49 +444,82 @@ nuisance_corrections: method: PC threshold: 5PCT - # Standard Lateral Ventricles Binary Mask - # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: # Process and refine masks used to produce regressors and time series for # regression. - regressor_masks: - erode_anatomical_brain_mask: - # Erode binarized anatomical brain mask. If choosing True, please also set seg_csf_use_erosion: True; regOption: niworkflows-ants. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + # Erode binarized anatomical brain mask. If choosing True, please also set regressor_masks['erode_csf']['run']: True; anatomical_preproc['brain_extraction']['using']: niworkflows-ants. run: On - erode_csf: + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + # Erode binarized csf tissue mask. run: On - erode_wm: + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + # Erode WM binarized tissue mask. run: On -timeseries_extraction: - run: Off + erode_gm: -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off + # this is a fork point + # Run nuisance regression in native or template space + # - If set to [native, template], the number of outputs will be double what it would be if only one space were chosen. Nuisance regression will only be run once per fork. + # - If set to template, will use the brain mask configured in + # ``functional_preproc: func_masking: FSL_AFNI: brain_mask`` + # - If ``registration_workflows: functional_registration: func_registration_to_template: apply_trasnform: using: single_step_resampling_from_stc``, this must only be set to template + space: [template] + + # Standard Lateral Ventricles Binary Mask + # used in CSF mask refinement for CSF signal-related regressions + lateral_ventricles_mask: + +timeseries_extraction: + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + +amplitude_low_frequency_fluctuation: + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off + # space: Template or Native + target_space: [Native] -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off +voxel_mirrored_homotopic_connectivity: + symmetric_registration: - symmetric_registration: # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. # It is not necessary to change this path unless you intend to use a non-standard symmetric template. T1w_brain_template_symmetric: @@ -446,9 +541,7 @@ voxel_mirrored_homotopic_connectivity: # A reference symmetric brain mask template for resampling dilated_symmetric_brain_mask_for_resample: -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off +network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. @@ -456,15 +549,16 @@ network_centrality: # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -476,8 +570,30 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + # PACKAGE INTEGRATIONS # -------------------- -PyPEER: +PyPEER: + # Template-space eye mask eye_mask_path: + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 09a7b8b100..c605db3ea8 100755 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,19 +1,18 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. - FROM: fmriprep-options +pipeline_setup: -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_fx-options - output_directory: # Quality control outputs @@ -22,15 +21,13 @@ pipeline_setup: # Generate eXtensible Connectivity Pipeline-style quality control files generate_xcpqc_files: On -nuisance_corrections: - 2-nuisance_regression: +nuisance_corrections: + 2-nuisance_regression: + # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [On] - # switch to Off if nuisance regression is off and you don't want to write out the regressors - create_regressors: On - # Select which nuisance signal corrections to apply Regressors: - Name: Regressor-1 @@ -38,46 +35,39 @@ nuisance_corrections: bottom_frequency: 0.01 top_frequency: 0.08 CerebrospinalFluid: - erode_mask: false + erode_mask: Off extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean GlobalSignal: - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean Motion: - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On WhiteMatter: - erode_mask: false + erode_mask: Off extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean - PolyOrt: + PolyOrt: degree: 2 - # Standard Lateral Ventricles Binary Mask - # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: - # Process and refine masks used to produce regressors and time series for - # regression. - regressor_masks: - erode_anatomical_brain_mask: - # Erode binarized anatomical brain mask. If choosing True, please also set seg_csf_use_erosion: True; regOption: niworkflows-ants. - run: On - - erode_csf: - # Erode binarized csf tissue mask. - run: On +# PREPROCESSING +# ------------- +surface_analysis: - erode_wm: - # Erode WM binarized tissue mask. - run: On + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index cfc9f6bddc..5b788e7ba6 100755 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,29 +1,33 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_default_monkey_skullstrip + output_directory: - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On + + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -46,105 +50,90 @@ pipeline_setup: # If you have specified an FSL path in your .bashrc file, this path will be set automatically. FSLDIR: FSLDIR - Amazon-AWS: - # Enable server-side 256-AES encryption on data to the S3 bucket - s3_encryption: On - -anatomical_preproc: - run_t2: On - - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: Off + working_directory: - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: Off + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off - # Bias field correction based on square root of T1w * T2w - t1t2_bias_field_correction: - run: On + Amazon-AWS: - acpc_alignment: - run: On + # Enable server-side 256-AES encryption on data to the S3 bucket + s3_encryption: On - # ACPC size of brain in z-dimension in mm. - # Default: 150mm for human data. - brain_size: 150 +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm_brain.nii.gz - # Choose a tool to crop the FOV in ACPC alignment. - # Using FSL's robustfov or flirt command. - # Default: robustfov for human data, flirt for monkey data. + # Choose a tool to crop the FOV in ACPC alignment. + # Using FSL's robustfov or flirt command. + # Default: robustfov for human data, flirt for monkey data. FOV_crop: flirt + T2w_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm.nii.gz + T2w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm_brain.nii.gz + run: On # ACPC Target # options: 'brain' or 'whole-head' # note: 'brain' requires T1w_brain_ACPC_template below to be populated - acpc_target: 'brain' + acpc_target: brain # ACPC aligned template T1w_ACPC_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm.nii.gz - T1w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm_brain.nii.gz - T2w_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm.nii.gz - T2w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm_brain.nii.gz - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] - # this is a fork option - using: [3dSkullStrip] #Note, if no mask provide, use UNet. + brain_extraction: + run: On + # option parameters - AFNI-3dSkullStrip: + AFNI-3dSkullStrip: + # Set it as True if processing monkey data with AFNI monkey: On - FSL-BET: + FSL-BET: + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.3 -segmentation: + run_t2: On + + # Bias field correction based on square root of T1w * T2w + t1t2_bias_field_correction: + run: On + +segmentation: + # Automatically segment anatomical images into white matter, gray matter, # and CSF based on prior probability maps. run: On + tissue_segmentation: - tissue_segmentation: - using: ['ANTs_Prior_Based'] + # using: ['FSL-FAST', 'Template_Based', 'ANTs_Prior_Based', 'FreeSurfer'] + # this is a fork point + using: [ANTs_Prior_Based] # option parameters - FSL-FAST: - use_priors: + FSL-FAST: + use_priors: + # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. run: Off - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm + Template_Based: - Template_Based: # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. + ANTs_Prior_Based: - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - - ANTs_Prior_Based: # Generate white matter, gray matter, CSF masks based on antsJointLabelFusion # ANTs Prior-based Segmentation workflow that has shown optimal results for non-human primate data. - # The atlas image assumed to be used in ANTs Prior-based Segmentation. - template_brain_list: + template_brain_list: - s3://fcp-indi/resources/cpac/resources/MacaqueYerkes19_T1w_0.5mm/T1w_brain.nii.gz - s3://fcp-indi/resources/cpac/resources/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm/T1w_brain.nii.gz - s3://fcp-indi/resources/cpac/resources/J_Macaque_11mo_atlas_oACQ_194x252x160space_0.5mm/T1w_brain.nii.gz @@ -167,7 +156,7 @@ segmentation: # ANTs_prior_seg_template_segmentation_list: # - segmentation1.nii.gz # - segmentation1.nii.gz - template_segmentation_list: + template_segmentation_list: - s3://fcp-indi/resources/cpac/resources/MacaqueYerkes19_T1w_0.5mm/Segmentation.nii.gz - s3://fcp-indi/resources/cpac/resources/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm/Segmentation.nii.gz - s3://fcp-indi/resources/cpac/resources/J_Macaque_11mo_atlas_oACQ_194x252x160space_0.5mm/Segmentation.nii.gz @@ -180,8 +169,47 @@ segmentation: - s3://fcp-indi/resources/cpac/resources/J_Macaque_6mo_atlas_nACQ_194x252x160space_0.5mm/Segmentation.nii.gz - s3://fcp-indi/resources/cpac/resources/J_Macaque_6mo_atlas_oACQ_194x252x160space_0.5mm/Segmentation.nii.gz -registration_workflows: - anatomical_registration: +registration_workflows: + anatomical_registration: + run: On + registration: + FSL-FNIRT: + + # The resolution to which anatomical images should be transformed during registration. + # This is the resolution at which processed anatomical files will be output. + # specifically for monkey pipeline + ref_resolution: 1mm + + # Template to be used during registration. + # It is for monkey pipeline specifically. + FNIRT_T1w_brain_template: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain.nii.gz + + # Template to be used during registration. + # It is for monkey pipeline specifically. + FNIRT_T1w_template: /cpac_templates/MacaqueYerkes19_T1w_1.0mm.nii.gz + + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask_dil.nii.gz + + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz + + # Reference mask for FSL registration. + ref_mask: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain_mask.nii.gz + + # Interpolation method for writing out transformed anatomical images. + # Possible values: trilinear, sinc, spline + interpolation: spline + + # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + # using: ['ANTS', 'FSL', 'FSL-linear'] + # this is a fork point + # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline + using: [FSL] + # The resolution to which anatomical images should be transformed during registration. # This is the resolution at which processed anatomical files will be output. resolution_for_anat: 0.5mm @@ -193,7 +221,7 @@ registration_workflows: # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. T1w_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm.nii.gz - + # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. T1w_brain_template_mask: /cpac_templates/MacaqueYerkes19_T1w_0.5mm_brain_mask.nii.gz @@ -201,79 +229,43 @@ registration_workflows: # Register skull-on anatomical image to a template. reg_with_skull: Off - registration: - # using: ['ANTS', 'FSL', 'FSL-linear'] - # this is a fork point - # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline - using: ['FSL'] - - FSL-FNIRT: - # The resolution to which anatomical images should be transformed during registration. - # This is the resolution at which processed anatomical files will be output. - # specifically for monkey pipeline - ref_resolution: 1mm + functional_registration: + coregistration: - # Reference mask for FSL registration. - ref_mask: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain_mask.nii.gz - - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - FNIRT_T1w_brain_template: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain.nii.gz + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - FNIRT_T1w_template: /cpac_templates/MacaqueYerkes19_T1w_1.0mm.nii.gz - - # Interpolation method for writing out transformed anatomical images. - # Possible values: trilinear, sinc, spline - interpolation: spline + # Standard FSL 5.0 Scheduler used for Boundary Based Registration. + # It is not necessary to change this path unless you intend to use non-standard MNI registration. + bbr_schedule: /usr/share/fsl/5.0/etc/flirtsch/bbr.sch - functional_registration: - coregistration: - # Choose coregistration interpolation interpolation: spline # Choose coregistration cost function cost: mutualinfo - - # Extra arguments for FSL flirt - arguments: '-searchrx -30 30 -searchry -30 30 -searchrz -30 30' - func_input_prep: + # Extra arguments for FSL flirt + arguments: -searchrx -30 30 -searchry -30 30 -searchrz -30 30 - # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. - # input: ['Mean_Functional', 'Selected_Functional_Volume'] - input: ['Mean_Functional'] + func_registration_to_template: - Mean Functional: - # Run ANTs’ N4 Bias Field Correction on the input BOLD (EPI) - # this can increase tissue contrast which may improve registration quality in some data - n4_correct_func: Off + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + apply_transform: - Selected Functional Volume: + # options: 'default', 'abcd', 'single_step_resampling_from_stc', 'dcan_nhp' + # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. + # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. + # 'single_step_resampling_from_stc': apply motion correction, func-to-anat and anat-to-template transforms on each of slice-time-corrected functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. + # - if 'single_step_resampling_from_stc', 'template' is the only valid option for ``nuisance_corrections: 2-nuisance_regression: space`` + using: dcan_nhp - # Only for when 'Use as Functional-to-Anatomical Registration Input' is set to 'Selected Functional Volume'. - #Input the index of which volume from the functional 4D timeseries input file you wish to use as the input for functional-to-anatomical registration. - func_reg_input_volume: 0 - - boundary_based_registration: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + output_resolution: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - FSL-FNIRT: - # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: $FSLDIR/etc/flirtsch/ident.mat - - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -289,16 +281,9 @@ registration_workflows: # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 1.5mm - target_template: - # using: ['T1_template', 'EPI_template', 'DCAN_NHP'] - # this is a fork point - # NOTE: - # this will determine which registration transform to use to warp the functional - # outputs and derivatives to template space - using: ['T1_template'] + target_template: + T1_template: - # option parameters - T1_template: # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_brain_template_funcreg: /cpac_templates/MacaqueYerkes19_T1w_1.5mm_brain.nii.gz @@ -312,80 +297,77 @@ registration_workflows: T1w_brain_template_mask_funcreg: /cpac_templates/MacaqueYerkes19_T1w_1.5mm_brain_mask.nii.gz # a standard template for resampling if using float resolution - T1w_template_for_resample: /cpac_templates/MacaqueYerkes19_T1w_0.5mm.nii.gz - + T1w_template_for_resample: /cpac_templates/MacaqueYerkes19_T1w_0.5mm.nii.gz + FNIRT_pipelines: # Interpolation method for writing out transformed functional images. # Possible values: trilinear, sinc, spline interpolation: spline - apply_transform: - - # options: 'default', 'abcd', 'single_step_resampling', 'dcan_nhp' - # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. - # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. - # 'single_step_resampling': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. - using: 'dcan_nhp' - -functional_preproc: - - run: On - - despiking: - # Run AFNI 3dDespike - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat - slice_timing_correction: + EPI_registration: + ANTs: - # Interpolate voxel time courses so they are sampled at the same time points. - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: +functional_preproc: + run: On motion_estimates_and_correction: - + run: On motion_correction: # using: ['3dvolreg', 'mcflirt'] # this is a fork point - using: ['mcflirt'] + using: [mcflirt] - # Choose motion correction reference. Options: mean, median, selected_volume - motion_correction_reference: ['selected_volume'] + # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference + motion_correction_reference: [selected_volume] - # Choose motion correction reference volume - motion_correction_reference_volume: 0 + distortion_correction: - distortion_correction: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - # using: ['PhaseDiff', 'Blip'] + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - # NOTE: - # this is NOT a fork point - instead, the technique used will depend on what type of distortion correction field data accompanies the dataset - # for example, phase-difference field maps will lead to phase-difference distortion correction, and phase-encoding direction field maps will lead to blip-up/blip-down + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. using: [] - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] + func_masking: + FSL_AFNI: + brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. # this is a fork point using: [Anatomical_Based] -nuisance_corrections: - 2-nuisance_regression: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -398,97 +380,100 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 2 WhiteMatter: summary: components: 5 method: PC - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: summary: components: 5 method: PC GlobalSignal: summary: Mean Motion: - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On PolyOrt: degree: 2 WhiteMatter: summary: components: 5 method: PC + + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + # Standard Lateral Ventricles Binary Mask # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: - -# OUTPUTS AND DERIVATIVES -# ----------------------- -post_processing: + lateral_ventricles_mask: - spatial_smoothing: +timeseries_extraction: + connectivity_matrix: - # Smooth the derivative outputs. - # Set as ['nonsmoothed'] to disable smoothing. Set as both to get both. - # + # Create a connectivity matrix from timeseries data # Options: - # ['smoothed', 'nonsmoothed'] - output: ['smoothed', 'nonsmoothed'] + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] - -timeseries_extraction: - run: Off + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_1_thr4.nii.gz: Avg /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_2_thr4.nii.gz: Avg /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_3_thr4.nii.gz: Avg s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_L_0.5mm.nii.gz: Avg s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_R_0.5mm.nii.gz: Avg -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off +amplitude_low_frequency_fluctuation: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - /Template/DMN-Ghahremani2016/HRzstat_DMN_1.nii.gz: DualReg - /Template/DMN-Ghahremani2016/HRzstat_DMN_2.nii.gz: DualReg - /Template/DMN-Ghahremani2016/HRzstat_DMN_3.nii.gz: DualReg - /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_1_thr4.nii.gz: Avg - /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_2_thr4.nii.gz: Avg - /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_3_thr4.nii.gz: Avg - s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_L_0.5mm.nii.gz: Avg - s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_R_0.5mm.nii.gz: Avg + # space: Template or Native + target_space: [Native] -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off +regional_homogeneity: -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off + # space: Template or Native + target_space: [Native] -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off +voxel_mirrored_homotopic_connectivity: + symmetric_registration: - symmetric_registration: # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. # It is not necessary to change this path unless you intend to use a non-standard symmetric template. T1w_brain_template_symmetric: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain.nii.gz @@ -510,9 +495,7 @@ voxel_mirrored_homotopic_connectivity: # A reference symmetric brain mask template for resampling dilated_symmetric_brain_mask_for_resample: /cpac_templates/MacaqueYerkes19_T1w_2mm_brain_mask.nii.gz -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off +network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. @@ -520,15 +503,16 @@ network_centrality: # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -540,8 +524,46 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + # Smooth the derivative outputs. + # Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both. + # + # Options: + # ['smoothed', 'nonsmoothed'] + output: [smoothed, nonsmoothed] + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + /Template/DMN-Ghahremani2016/HRzstat_DMN_1.nii.gz: DualReg + /Template/DMN-Ghahremani2016/HRzstat_DMN_2.nii.gz: DualReg + /Template/DMN-Ghahremani2016/HRzstat_DMN_3.nii.gz: DualReg + /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_1_thr4.nii.gz: Avg + /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_2_thr4.nii.gz: Avg + /Template/DMN-Ghahremani2016/thr_bin_hjin/HRzstat_DMN_3_thr4.nii.gz: Avg + s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_L_0.5mm.nii.gz: Avg + s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_R_0.5mm.nii.gz: Avg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index 2559c10e76..0455df1e74 100755 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,29 +1,33 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_default_monkey_skullstrip + output_directory: - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On + + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -46,114 +50,112 @@ pipeline_setup: # If you have specified an FSL path in your .bashrc file, this path will be set automatically. FSLDIR: FSLDIR - Amazon-AWS: + working_directory: + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + + Amazon-AWS: + # Enable server-side 256-AES encryption on data to the S3 bucket s3_encryption: On -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: On - - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: On +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm_brain.nii.gz - acpc_alignment: + # Choose a tool to crop the FOV in ACPC alignment. + # Using FSL's robustfov or flirt command. + # Default: robustfov for human data, flirt for monkey data. + FOV_crop: flirt + T2w_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm.nii.gz + T2w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm_brain.nii.gz run: On # ACPC size of brain in z-dimension in mm. # Default: 150mm for human data. brain_size: 70 - # Choose a tool to crop the FOV in ACPC alignment. - # Using FSL's robustfov or flirt command. - # Default: robustfov for human data, flirt for monkey data. - FOV_crop: flirt - # ACPC aligned template T1w_ACPC_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm.nii.gz - T1w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T1w_0.5mm_brain.nii.gz - T2w_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm.nii.gz - T2w_brain_ACPC_template: /cpac_templates/MacaqueYerkes19_T2w_0.5mm_brain.nii.gz - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] + brain_extraction: + run: On + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [UNet] # option parameters - AFNI-3dSkullStrip: + AFNI-3dSkullStrip: + # Set it as True if processing monkey data with AFNI monkey: On - FSL-BET: + FSL-BET: + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.3 -segmentation: + # Non-local means filtering via ANTs DenoiseImage + non_local_means_filtering: + + # this is a fork option + run: [On] + + # N4 bias field correction via ANTs + n4_bias_field_correction: + + # this is a fork option + run: [On] + +segmentation: + # Automatically segment anatomical images into white matter, gray matter, # and CSF based on prior probability maps. run: On + tissue_segmentation: - tissue_segmentation: - using: ['ANTs_Prior_Based'] + # using: ['FSL-FAST', 'Template_Based', 'ANTs_Prior_Based', 'FreeSurfer'] + # this is a fork point + using: [ANTs_Prior_Based] # option parameters - FSL-FAST: - use_priors: + FSL-FAST: + use_priors: + # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. run: Off - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm + Template_Based: - Template_Based: # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - - ANTs_Prior_Based: - # Generate white matter, gray matter, CSF masks based on antsJointLabelFusion - # ANTs Prior-based Segmentation workflow that has shown optimal results for non-human primate data. - - # The atlas image assumed to be used in ANTs Prior-based Segmentation. - template_brain_list : - - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_T1w_brain.nii.gz - - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_T1w_brain.nii.gz - - # The atlas segmentation images. - # For performing ANTs Prior-based segmentation method - # the number of specified segmentations should be identical to the number of atlas brain image sets. - # eg. - # ANTs_prior_seg_template_brain_list : - # - atlas1.nii.gz - # - atlas2.nii.gz - # ANTs_prior_seg_template_segmentation_list: - # - segmentation1.nii.gz - # - segmentation1.nii.gz - template_segmentation_list: - - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_Segmentation.nii.gz - - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_Segmentation.nii.gz - -registration_workflows: - anatomical_registration: +registration_workflows: + anatomical_registration: + run: On + registration: + FSL-FNIRT: + + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask_dil.nii.gz + + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz + + # Reference mask for FSL registration. + ref_mask: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain_mask.nii.gz + + # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. T1w_brain_template: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain.nii.gz @@ -162,49 +164,48 @@ registration_workflows: # It is not necessary to change this path unless you intend to use a non-standard template. T1w_template: /cpac_templates/MacaqueYerkes19_T1w_1.0mm.nii.gz + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + # Register skull-on anatomical image to a template. reg_with_skull: Off - registration: - FSL-FNIRT: - # Reference mask for FSL registration. - ref_mask: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain_mask.nii.gz + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + func_input_prep: + Mean Functional: + + # Run ANTs’ N4 Bias Field Correction on the input BOLD (EPI) + # this can increase tissue contrast which may improve registration quality in some data + n4_correct_func: On + + boundary_based_registration: + + # Standard FSL 5.0 Scheduler used for Boundary Based Registration. + # It is not necessary to change this path unless you intend to use non-standard MNI registration. + bbr_schedule: /usr/share/fsl/5.0/etc/flirtsch/bbr.sch - functional_registration: - coregistration: - # Choose coregistration interpolation interpolation: spline # Choose coregistration cost function cost: mutualinfo - - # Extra arguments for FSL flirt - arguments: '-searchrx -30 30 -searchry -30 30 -searchrz -30 30' - func_input_prep: - Mean Functional: - # Run ANTs’ N4 Bias Field Correction on the input BOLD (EPI) - # this can increase tissue contrast which may improve registration quality in some data - n4_correct_func: On + # Extra arguments for FSL flirt + arguments: -searchrx -30 30 -searchry -30 30 -searchrz -30 30 - boundary_based_registration: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + func_registration_to_template: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - FSL-FNIRT: - # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: $FSLDIR/etc/flirtsch/ident.mat + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -220,9 +221,9 @@ registration_workflows: # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm - target_template: - # option parameters - T1_template: + target_template: + T1_template: + # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_brain_template_funcreg: /cpac_templates/MacaqueYerkes19_T1w_2mm_brain.nii.gz @@ -231,32 +232,89 @@ registration_workflows: # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_template_funcreg: /cpac_templates/MacaqueYerkes19_T1w_2mm.nii.gz -functional_preproc: - despiking: - # Run AFNI 3dDespike + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz + + FNIRT_pipelines: + + # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [On] - distortion_correction: - # using: ['PhaseDiff', 'Blip'] + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - # NOTE: - # this is NOT a fork point - instead, the technique used will depend on what type of distortion correction field data accompanies the dataset - # for example, phase-difference field maps will lead to phase-difference distortion correction, and phase-encoding direction field maps will lead to blip-up/blip-down + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. using: [] - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] + func_masking: + FSL_AFNI: + brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. # this is a fork point using: [Anatomical_Refined] -nuisance_corrections: - 2-nuisance_regression: + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + + despiking: + + # Run AFNI 3dDespike + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -269,7 +327,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 2 WhiteMatter: @@ -277,50 +334,73 @@ nuisance_corrections: components: 5 method: PC + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + # Standard Lateral Ventricles Binary Mask # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: -timeseries_extraction: - run: Off + lateral_ventricles_mask: + +timeseries_extraction: + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_L_0.5mm.nii.gz: Avg s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_R_0.5mm.nii.gz: Avg -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off +amplitude_low_frequency_fluctuation: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_L_0.5mm.nii.gz: Avg - s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_R_0.5mm.nii.gz: Avg + # space: Template or Native + target_space: [Native] -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off +regional_homogeneity: -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off + # space: Template or Native + target_space: [Native] -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off +voxel_mirrored_homotopic_connectivity: + symmetric_registration: - symmetric_registration: # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. # It is not necessary to change this path unless you intend to use a non-standard symmetric template. T1w_brain_template_symmetric: /cpac_templates/MacaqueYerkes19_T1w_1.0mm_brain.nii.gz @@ -342,9 +422,7 @@ voxel_mirrored_homotopic_connectivity: # A reference symmetric brain mask template for resampling dilated_symmetric_brain_mask_for_resample: /cpac_templates/MacaqueYerkes19_T1w_2mm_brain_mask.nii.gz -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off +network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. @@ -352,15 +430,16 @@ network_centrality: # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -372,8 +451,33 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_L_0.5mm.nii.gz: Avg + s3://fcp-indi/resources/cpac/resources/parcellation/Markov91_R_0.5mm.nii.gz: Avg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 8ad2bdd7e4..82962a92b0 100755 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,83 +1,90 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: ndmg + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On + + system_config: - system_config: # The number of cores to allocate to ANTS-based anatomical registration per participant. # - Multiple cores can greatly speed up this preprocessing step. # - This number cannot be greater than the number of cores per participant. num_ants_threads: 4 -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: Off - - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: Off - -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + brain_extraction: + run: On + +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz +registration_workflows: + anatomical_registration: + run: On + registration: -registration_workflows: - anatomical_registration: - registration: # using: ['ANTS', 'FSL', 'FSL-linear'] # this is a fork point # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline using: [FSL] # option parameters - ANTs: + ANTs: + # ANTs parameters for T1-template-based registration - T1_registration: - functional_registration: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - func_registration_to_template: - output_resolution: + T1_registration: + + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: + # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -93,27 +100,63 @@ registration_workflows: # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -functional_preproc: - distortion_correction: - # using: ['PhaseDiff', 'Blip'] + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - # NOTE: - # this is NOT a fork point - instead, the technique used will depend on what type of distortion correction field data accompanies the dataset - # for example, phase-difference field maps will lead to phase-difference distortion correction, and phase-encoding direction field maps will lead to blip-up/blip-down + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. using: [] -nuisance_corrections: - 2-nuisance_regression: + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: extraction_resolution: 2 summary: Mean - Name: Regressor-1 PolyOrt: degree: 2 aCompCor: @@ -125,12 +168,54 @@ nuisance_corrections: - WhiteMatter - CerebrospinalFluid -timeseries_extraction: + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: /ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-2x2x2.nii.gz: Avg /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-2x2x2.nii.gz: Avg /ndmg_atlases/label/Human/CPAC200_space-MNI152NLin6_res-2x2x2.nii.gz: Avg @@ -152,55 +237,33 @@ timeseries_extraction: /ndmg_atlases/label/Human/JHU_space-MNI152NLin6_res-2x2x2.nii.gz: Avg /ndmg_atlases/label/Human/Princetonvisual-top_space-MNI152NLin6_res-2x2x2.nii.gz: Avg -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off - -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off - -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off - -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off - - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz - - # A reference symmetric brain template for resampling - T1w_brain_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz - - # A reference symmetric skull template for resampling - T1w_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz - - # A reference symmetric brain mask template for resampling - dilated_symmetric_brain_mask_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_mask_symmetric_dil.nii.gz - -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off - -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +amplitude_low_frequency_fluctuation: + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: + + # space: Template or Native + target_space: [Native] + +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index 73652cb1c4..3ed3d46aa3 100755 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,14 +1,27 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. - FROM: monkey -pipeline_setup: +pipeline_setup: + # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_default_macaque_skullstrip + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index 9a465d29c6..67a40ad067 100755 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,29 +1,25 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. - FROM: default +pipeline_setup: -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: cpac_preproc + system_config: - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off - - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -41,60 +37,43 @@ pipeline_setup: # If you have specified an FSL path in your .bashrc file, this path will be set automatically. FSLDIR: FSLDIR - Amazon-AWS: + working_directory: + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + + Amazon-AWS: + # Enable server-side 256-AES encryption on data to the S3 bucket s3_encryption: On -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: Off - - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: Off - -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: +segmentation: + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz +registration_workflows: + functional_registration: + EPI_registration: + ANTs: - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - -registration_workflows: - functional_registration: - EPI_registration: - ANTs: # EPI registration configuration - synonymous with T1_registration # parameters under anatomical registration above - parameters: -nuisance_corrections: - 2-nuisance_regression: + parameters: + +nuisance_corrections: + 2-nuisance_regression: + # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -107,7 +86,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 2 aCompCor: @@ -118,7 +96,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - Bandpass: + - Name: Regressor-2 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -129,7 +108,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-2 PolyOrt: degree: 2 aCompCor: @@ -141,62 +119,40 @@ nuisance_corrections: - WhiteMatter - CerebrospinalFluid - # Standard Lateral Ventricles Binary Mask - # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: $FSLDIR/data/atlases/HarvardOxford/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz - -timeseries_extraction: +timeseries_extraction: run: Off -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off +amplitude_low_frequency_fluctuation: -amplitude_low_frequency_fluctuation: # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. run: Off -regional_homogeneity: +regional_homogeneity: + # ReHo # Calculate Regional Homogeneity (ReHo) for all voxels. run: Off -voxel_mirrored_homotopic_connectivity: +voxel_mirrored_homotopic_connectivity: + # VMHC # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. run: Off - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz +network_centrality: - # A reference symmetric brain template for resampling - T1w_brain_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz - - # A reference symmetric skull template for resampling - T1w_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz - - # A reference symmetric brain mask template for resampling - dilated_symmetric_brain_mask_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_mask_symmetric_dil.nii.gz - -network_centrality: # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. run: Off -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index 24b16d31df..11a7ccfd01 100755 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,20 +1,31 @@ %YAML 1.1 --- -# CPAC Pipeline Configuration YAML file for RBC options -# Version 1.8.4 +# CPAC Pipeline Configuration YAML file +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. - -FROM: fx-options +FROM: fmriprep-options pipeline_setup: + # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: RBCv0 + output_directory: + + # Quality control outputs + quality_control: + + # Generate eXtensible Connectivity Pipeline-style quality control files + generate_xcpqc_files: On system_config: + # Stop worklow execution on first crash? + fail_fast: On + # Random seed used to fix the state of execution. # If unset, each process uses its own default. # If set, a `random.log` file will be generated logging the random seed and each node to which that seed was applied. @@ -22,40 +33,25 @@ pipeline_setup: # If set to 'random', a random positive integer (up to 2147483647) will be generated and that seed will be used to seed each process that accepts a random seed. random_seed: 77742777 - output_directory: - # Quality control outputs - quality_control: - # Generate eXtensible Connectivity Pipeline-style quality control files - generate_xcpqc_files: On +registration_workflows: + anatomical_registration: - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: On + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz -anatomical_preproc: - # N4 bias field correction via ANTs - n4_bias_field_correction: - # this is a fork option - run: - - On + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_template: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz -registration_workflows: - anatomical_registration: - T1w_brain_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz - T1w_brain_template_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - T1w_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz functional_registration: - coregistration: - func_input_prep: - input: [fmriprep_reference] - func_registration_to_template: - # these options modify the application (to the functional data), not the calculation, of the - # T1-to-template and EPI-to-template transforms calculated earlier during registration - output_resolution: + # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -73,14 +69,38 @@ registration_workflows: target_template: T1_template: - T1w_brain_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz - T1w_brain_template_mask_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz - T1w_template_for_resample: - T1w_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}.nii.gz + # Standard Skull Stripped Template. Used as a reference image for functional registration. + # This can be different than the template used as the reference/fixed for T1-to-template registration. + T1w_brain_template_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz + + # Standard Anatomical Brain Image with Skull. + # This can be different than the template used as the reference/fixed for T1-to-template registration. + T1w_template_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}.nii.gz + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask_funcreg: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz + + # a standard template for resampling if using float resolution + T1w_template_for_resample: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz functional_preproc: + distortion_correction: + + # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] + # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. + # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. + # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. + using: [PhaseDiff, Blip-FSL-TOPUP] + + func_masking: + FSL_AFNI: + brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + truncation: + # First timepoint to include in analysis. # Default is 0 (beginning of timeseries). # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. @@ -88,178 +108,214 @@ functional_preproc: start_tr: 2 despiking: + # Run AFNI 3dDespike # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: - - On - - motion_estimates_and_correction: - motion_correction: - using: [3dvolreg] - - distortion_correction: - using: - - PhaseDiff - - Blip-FSL-TOPUP - - func_masking: - using: [FSL_AFNI] - FSL_AFNI: - bold_ref: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz # different space! - brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + run: [On] + space: template nuisance_corrections: 2-nuisance_regression: - Regressors: - - Name: Motion-regressor-no-GSR-or-aCompCor - Bandpass: - bottom_frequency: 0.01 - top_frequency: 0.1 - CerebrospinalFluid: - erode_mask: false - extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true - summary: Mean - Motion: - include_delayed: true - include_delayed_squared: true - include_squared: true - WhiteMatter: - erode_mask: false - extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true - summary: Mean - - Name: Regressor-with-GSR + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + # Select which nuisance signal corrections to apply + Regressors: + - Name: 36-parameter Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: - erode_mask: false + erode_mask: Off extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean GlobalSignal: - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean Motion: - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On WhiteMatter: - erode_mask: false + erode_mask: Off extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean - - - Name: Regressor-with-aCompCor + - Name: aCompCor Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: - erode_mask: false + erode_mask: Off extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean aCompCor: summary: method: DetrendPC components: 5 tissues: - - WhiteMatter - - CerebrospinalFluid + - WhiteMatter + - CerebrospinalFluid extraction_resolution: 2 Motion: - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On WhiteMatter: - erode_mask: false + erode_mask: Off extraction_resolution: 2 - include_delayed: true - include_delayed_squared: true - include_squared: true + include_delayed: On + include_delayed_squared: On + include_squared: On summary: Mean # Process and refine masks used to produce regressors and time series for # regression. regressor_masks: - erode_csf: - # Target volume ratio, if using erosion. - # Default proportion is None for CSF (cerebrospinal fluid) mask. - # Recommend to do not use erosion in both proportion and millimeter method. - csf_erosion_prop: 0.9 - # Erode brain mask in millimeter, default of csf is 30 mm - # CSF erosion default is using millimeter erosion method when use erosion for CSF. + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. csf_mask_erosion_mm: + # Target volume ratio, if using erosion. + # Default proportion is None for cerebrospinal fluid mask. + # If using erosion, using both proportion and millimeters is not recommended. + csf_erosion_prop: 0.9 timeseries_extraction: run: On connectivity_matrix: - using: - - Nilearn - measure: - - Pearson - - Partial + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn] + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg tse_roi_paths: - # AAL - /ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - # Atlases - /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - # Slab - /ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - # HO: Thresholded - /ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - # Jeulich - /ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - # CC + /ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-2x2x2.nii.gz: Avg /cpac_templates/CC200.nii.gz: Avg /cpac_templates/CC400.nii.gz: Avg - # Schaefer /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-200Parcels17NetworksOrder.nii.gz: Avg /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-300Parcels17NetworksOrder.nii.gz: Avg /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-400Parcels17NetworksOrder.nii.gz: Avg /cpac_templates/Schaefer2018_space-FSLMNI152_res-2mm_desc-1000Parcels17NetworksOrder.nii.gz: Avg - # Networks - # Yeo - /ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - # Smith 2009 (to be included after https://github.com/FCP-INDI/C-PAC/issues/1640 is resolved) - # /cpac_templates/Smith_space-MNI152NLin6_res-3x3x3_desc-thresh3_mask.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-2x2x2.nii.gz: Avg + +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Template] + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On + + # space: Template or Native + target_space: [Template] + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On + + # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. + template_specification_file: /cpac_templates/Mask_ABIDE_85Percent_GM.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized] + + eigenvector_centrality: + + # Enable/Disable eigenvector centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [] + + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] # OUTPUTS AND DERIVATIVES # ----------------------- -post_processing: +post_processing: spatial_smoothing: + + # Smooth the derivative outputs. + # Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both. + # + # Options: + # ['smoothed', 'nonsmoothed'] output: [smoothed, nonsmoothed] + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided smoothing_method: [AFNI] + + # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. + # this is a fork point + # i.e. multiple kernels - fwhm: [4,6,8] fwhm: [6] + z-scoring: + + # z-score standardize the derivatives. This may be needed for group-level analysis. + # Set as ['raw'] to disable z-scoring. Set as ['z-scored', 'raw'] to get both. + # + # Options: + # ['z-scored', 'raw'] output: [z-scored, raw] -seed_based_correlation_analysis: - run: Off +# PREPROCESSING +# ------------- +surface_analysis: -regional_homogeneity: - run: On + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index c43ada7bdc..340aefeddf 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,36 +1,39 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: regtest-1 + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. write_func_outputs: On # Include extra outputs in the output directory that may be of interest when more information is needed. write_debugging_outputs: On - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -59,73 +62,109 @@ pipeline_setup: # - This number cannot be greater than the number of cores per participant. num_ants_threads: 2 -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: Off + working_directory: + + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: Off + brain_extraction: + run: On + FSL-BET: - brain_extraction: - FSL-BET: # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. mask_boolean: Off -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. +registration_workflows: + anatomical_registration: + run: On - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz + # Register skull-on anatomical image to a template. + reg_with_skull: Off - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz + functional_registration: + coregistration: - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: - functional_registration: - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the registered derivative outputs are written into. # NOTE: # this is for the single-volume functional-space outputs (i.e. derivatives) # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -nuisance_corrections: - 1-ICA-AROMA: +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: [On, Off] + run: [On] + + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] - 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -135,7 +174,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 1 aCompCor: @@ -146,7 +184,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: erode_mask: On extraction_resolution: 2 summary: Mean @@ -156,7 +195,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: On - Name: Regressor-2 aCompCor: extraction_resolution: 2 summary: @@ -164,7 +202,8 @@ nuisance_corrections: method: DetrendPC tissues: - CerebrospinalFluid - - Censor: + - Name: Regressor-3 + Censor: method: Kill number_of_previous_trs_to_censor: 1 number_of_subsequent_trs_to_censor: 1 @@ -175,55 +214,122 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: Off - Name: Regressor-3 -timeseries_extraction: + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + 1-ICA-AROMA: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On, Off] + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, Voxel, SpatialReg -seed_based_correlation_analysis: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: -voxel_mirrored_homotopic_connectivity: - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz + # space: Template or Native + target_space: [Native] - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz +voxel_mirrored_homotopic_connectivity: + + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On -network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. memory_allocation: 3.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -235,8 +341,33 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index e2342477bb..601752e84b 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,36 +1,39 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: regtest-2 + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. write_func_outputs: On # Include extra outputs in the output directory that may be of interest when more information is needed. write_debugging_outputs: On - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -64,92 +67,132 @@ pipeline_setup: # multiplied by the number of cores dedicated to each participant (the 'Maximum Number of Cores Per Participant' setting). num_participants_at_once: 15 -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: Off + working_directory: - # N4 bias field correction via ANTs - n4_bias_field_correction: - run: Off + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + brain_extraction: + run: On + + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [BET] + FSL-BET: - FSL-BET: # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. mask_boolean: Off -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off +registration_workflows: + anatomical_registration: + run: On + registration: - registration: # using: ['ANTS', 'FSL', 'FSL-linear'] # this is a fork point # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline using: [FSL] # option parameters - ANTs: + ANTs: + # ANTs parameters for T1-template-based registration - T1_registration: - functional_registration: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - func_registration_to_template: - output_resolution: + T1_registration: + + # Register skull-on anatomical image to a template. + reg_with_skull: Off + + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: + # The resolution (in mm) to which the registered derivative outputs are written into. # NOTE: # this is for the single-volume functional-space outputs (i.e. derivatives) # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -nuisance_corrections: - 1-ICA-AROMA: + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: [On, Off] + run: [On] + + motion_estimates_and_correction: + run: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] - 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -159,7 +202,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 1 aCompCor: @@ -170,7 +212,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: erode_mask: On extraction_resolution: 2 summary: Mean @@ -180,7 +223,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: On - Name: Regressor-2 aCompCor: extraction_resolution: 2 summary: @@ -188,7 +230,8 @@ nuisance_corrections: method: DetrendPC tissues: - CerebrospinalFluid - - Censor: + - Name: Regressor-3 + Censor: method: Kill number_of_previous_trs_to_censor: 1 number_of_subsequent_trs_to_censor: 1 @@ -199,55 +242,122 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: Off - Name: Regressor-3 -timeseries_extraction: + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + + 1-ICA-AROMA: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On, Off] + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, Voxel, SpatialReg -seed_based_correlation_analysis: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On -voxel_mirrored_homotopic_connectivity: - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # space: Template or Native + target_space: [Native] - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz +voxel_mirrored_homotopic_connectivity: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On -network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. memory_allocation: 3.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -259,8 +369,33 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index a663ed31e5..f50095e6b1 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,36 +1,39 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: regtest-3 + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. write_func_outputs: On # Include extra outputs in the output directory that may be of interest when more information is needed. write_debugging_outputs: On - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off - system_config: + # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. on_grid: SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -64,125 +67,185 @@ pipeline_setup: # multiplied by the number of cores dedicated to each participant (the 'Maximum Number of Cores Per Participant' setting). num_participants_at_once: 15 -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: On + working_directory: - # N4 bias field correction via ANTs - n4_bias_field_correction: + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + brain_extraction: run: On - brain_extraction: - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants'] + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [niworkflows-ants] + FSL-BET: - FSL-BET: # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. mask_boolean: Off -segmentation: - tissue_segmentation: - # option parameters - FSL-FAST: - use_priors: - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - Template_Based: + # Non-local means filtering via ANTs DenoiseImage + non_local_means_filtering: + + # this is a fork option + run: [On] + + # N4 bias field correction via ANTs + n4_bias_field_correction: + + # this is a fork option + run: [On] + +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + Template_Based: + # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. +registration_workflows: + anatomical_registration: + run: On - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz + # Register skull-on anatomical image to a template. + reg_with_skull: Off - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz + functional_registration: + coregistration: - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: - functional_registration: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - func_registration_to_template: - output_resolution: # The resolution (in mm) to which the registered derivative outputs are written into. # NOTE: # this is for the single-volume functional-space outputs (i.e. derivatives) # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -functional_preproc: - truncation: - # First timepoint to include in analysis. - # Default is 0 (beginning of timeseries). - # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. - # Note: the selection here applies to all scans of all participants. - start_tr: 5 + EPI_registration: + ANTs: - # Last timepoint to include in analysis. - # Default is None or End (end of timeseries). - # Last timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. - # Note: the selection here applies to all scans of all participants. - stop_tr: 100 + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: - despiking: - # Run AFNI 3dDespike +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [On] - motion_estimates_and_correction: - motion_estimates: + motion_estimates_and_correction: + run: On + motion_estimates: + # calculate motion statistics BEFORE slice-timing correction calculate_motion_first: On - motion_correction: + motion_correction: + # using: ['3dvolreg', 'mcflirt'] # this is a fork point using: [mcflirt] # option parameters - AFNI-3dvolreg: + AFNI-3dvolreg: + # This option is useful when aligning high-resolution datasets that may need more alignment than a few voxels. functional_volreg_twopass: Off - # Choose motion correction reference. Options: mean, median, selected_volume + # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference motion_correction_reference: [median] - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_masking: + FSL_AFNI: + bold_ref: /code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. # this is a fork point using: [FSL_AFNI] -nuisance_corrections: - 1-ICA-AROMA: + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + + truncation: + + # First timepoint to include in analysis. + # Default is 0 (beginning of timeseries). + # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. + # Note: the selection here applies to all scans of all participants. + start_tr: 5 + + # Last timepoint to include in analysis. + # Default is None or End (end of timeseries). + # Last timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. + # Note: the selection here applies to all scans of all participants. + stop_tr: 100 + + despiking: + + # Run AFNI 3dDespike # this is a fork point # run: [On, Off] - this will run both and fork the pipeline - run: [On, Off] + run: [On] + +nuisance_corrections: + 2-nuisance_regression: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] - 2-nuisance_regression: # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -192,7 +255,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 1 aCompCor: @@ -203,7 +265,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: erode_mask: On extraction_resolution: 2 summary: Mean @@ -213,7 +276,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: On - Name: Regressor-2 aCompCor: extraction_resolution: 2 summary: @@ -221,7 +283,8 @@ nuisance_corrections: method: DetrendPC tissues: - CerebrospinalFluid - - Censor: + - Name: Regressor-3 + Censor: method: Kill number_of_previous_trs_to_censor: 1 number_of_subsequent_trs_to_censor: 1 @@ -232,68 +295,126 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: Off - Name: Regressor-3 + + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 # Whether to run frequency filtering before or after nuisance regression. # Options: 'After' or 'Before' bandpass_filtering_order: Before -# OUTPUTS AND DERIVATIVES -# ----------------------- -post_processing: - spatial_smoothing: - # Tool to use for smoothing. - # 'FSL' for FSL MultiImageMaths for FWHM provided - # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided - smoothing_method: [AFNI] + 1-ICA-AROMA: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On, Off] + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] -timeseries_extraction: # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, Voxel, SpatialReg -seed_based_correlation_analysis: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On -voxel_mirrored_homotopic_connectivity: - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # space: Template or Native + target_space: [Native] - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz +voxel_mirrored_homotopic_connectivity: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On -network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. memory_allocation: 3.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -305,8 +426,38 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided + smoothing_method: [AFNI] + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 3e6c56523f..6667f71442 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,36 +1,39 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: regtest-3 + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On - output_directory: # Include extra versions and intermediate steps of functional preprocessing in the output directory. write_func_outputs: On # Include extra outputs in the output directory that may be of interest when more information is needed. write_debugging_outputs: On - working_directory: - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: Off + system_config: - system_config: # Select Off if you intend to run CPAC on a single machine. # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - SGE: + on_grid: + SGE: + # SGE Parallel Environment to use when running CPAC. # Only applies when you are running on a grid or compute cluster using SGE. parallel_environment: cpac @@ -64,18 +67,23 @@ pipeline_setup: # multiplied by the number of cores dedicated to each participant (the 'Maximum Number of Cores Per Participant' setting). num_participants_at_once: 15 -anatomical_preproc: - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - run: On + working_directory: - # N4 bias field correction via ANTs - n4_bias_field_correction: + # Deletes the contents of the Working Directory after running. + # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. + remove_working_dir: Off + +anatomical_preproc: + run: On + acpc_alignment: + T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz + + brain_extraction: run: On - brain_extraction: # option parameters - AFNI-3dSkullStrip: + AFNI-3dSkullStrip: + # Set the threshold value controlling the brain vs non-brain voxels. Default is 0.6. shrink_factor: 0.62 @@ -91,73 +99,135 @@ anatomical_preproc: # Perform final surface smoothing after all iterations. Default is 20. smooth_final: 22 - FSL-BET: + FSL-BET: + # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. mask_boolean: Off -segmentation: - tissue_segmentation: + # Non-local means filtering via ANTs DenoiseImage + non_local_means_filtering: + + # this is a fork option + run: [On] + + # N4 bias field correction via ANTs + n4_bias_field_correction: + + # this is a fork option + run: [On] + +segmentation: + + # Automatically segment anatomical images into white matter, gray matter, + # and CSF based on prior probability maps. + run: On + tissue_segmentation: + # option parameters - FSL-FAST: - use_priors: + FSL-FAST: + use_priors: + # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. run: Off - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm + Template_Based: - Template_Based: # These masks should be in the same space of your registration template, e.g. if # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. # # Options: ['T1_Template', 'EPI_Template'] template_for_segmentation: [] - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - -registration_workflows: - anatomical_registration: - # Register skull-on anatomical image to a template. - reg_with_skull: Off +registration_workflows: + anatomical_registration: + run: On + registration: - registration: # using: ['ANTS', 'FSL', 'FSL-linear'] # this is a fork point # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline using: [ANTS, FSL] - # option parameters - ANTs: - # ANTs parameters for T1-template-based registration - T1_registration: - functional_registration: - EPI_registration: - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - func_registration_to_template: - output_resolution: + # Register skull-on anatomical image to a template. + reg_with_skull: Off + + functional_registration: + coregistration: + + # functional (BOLD/EPI) registration to anatomical (structural/T1) + run: On + boundary_based_registration: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_registration_to_template: + + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + output_resolution: + # The resolution (in mm) to which the registered derivative outputs are written into. # NOTE: # this is for the single-volume functional-space outputs (i.e. derivatives) # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2mm -functional_preproc: - truncation: + EPI_registration: + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + +functional_preproc: + run: On + slice_timing_correction: + + # Interpolate voxel time courses so they are sampled at the same time points. + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + motion_estimates_and_correction: + run: On + motion_estimates: + + # calculate motion statistics BEFORE slice-timing correction + calculate_motion_first: On + + distortion_correction: + + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + + func_masking: + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. + # this is a fork point + using: [Anatomical_Refined] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + + truncation: + # First timepoint to include in analysis. # Default is 0 (beginning of timeseries). # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. @@ -170,25 +240,17 @@ functional_preproc: # Note: the selection here applies to all scans of all participants. stop_tr: 100 - motion_estimates_and_correction: - motion_estimates: - # calculate motion statistics BEFORE slice-timing correction - calculate_motion_first: On - - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] - # this is a fork point - using: [Anatomical_Refined] +nuisance_corrections: + 2-nuisance_regression: -nuisance_corrections: - 2-nuisance_regression: # this is a fork point # run: [On, Off] - this will run both and fork the pipeline run: [On, Off] # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 CerebrospinalFluid: @@ -198,7 +260,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: On include_squared: On - Name: Regressor-1 PolyOrt: degree: 1 aCompCor: @@ -209,7 +270,8 @@ nuisance_corrections: tissues: - WhiteMatter - CerebrospinalFluid - - CerebrospinalFluid: + - Name: Regressor-2 + CerebrospinalFluid: erode_mask: On extraction_resolution: 2 summary: Mean @@ -219,7 +281,6 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: On - Name: Regressor-2 aCompCor: extraction_resolution: 2 summary: @@ -227,7 +288,8 @@ nuisance_corrections: method: DetrendPC tissues: - CerebrospinalFluid - - Censor: + - Name: Regressor-3 + Censor: method: Kill number_of_previous_trs_to_censor: 1 number_of_subsequent_trs_to_censor: 1 @@ -238,64 +300,116 @@ nuisance_corrections: include_delayed: On include_delayed_squared: Off include_squared: Off - Name: Regressor-3 -# OUTPUTS AND DERIVATIVES -# ----------------------- -post_processing: - spatial_smoothing: - # Tool to use for smoothing. - # 'FSL' for FSL MultiImageMaths for FWHM provided - # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided - smoothing_method: [AFNI] + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 + +timeseries_extraction: + run: On + connectivity_matrix: + + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] -timeseries_extraction: # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg # available analyses: # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: + tse_roi_paths: s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, Voxel, SpatialReg -seed_based_correlation_analysis: - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # space: Template or Native + target_space: [Native] + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On -voxel_mirrored_homotopic_connectivity: - symmetric_registration: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + # space: Template or Native + target_space: [Native] - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz +voxel_mirrored_homotopic_connectivity: - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On -network_centrality: # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. memory_allocation: 3.0 # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. template_specification_file: s3://fcp-indi/resources/cpac/resources/mask-thr50-3mm.nii.gz + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + + eigenvector_centrality: - eigenvector_centrality: # Enable/Disable eigenvector centrality by selecting the connectivity weights # weight_options: ['Binarized', 'Weighted'] # disable this type of centrality with: # weight_options: [] weight_options: [Binarized, Weighted] - local_functional_connectivity_density: + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: [Binarized, Weighted] + # Select the type of threshold used when creating the lFCD adjacency matrix. # options: # 'Significance threshold', 'Correlation threshold' @@ -307,8 +421,38 @@ network_centrality: # Pearson's r value for Correlation Threshold correlation_threshold: 0.001 -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided + smoothing_method: [AFNI] + + z-scoring: + run: On + +seed_based_correlation_analysis: + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + s3://fcp-indi/resources/cpac/resources/rois_2mm.nii.gz: Avg, MultReg + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: + + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index 65179e3737..beeb3f2549 100755 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,20 +1,28 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. +FROM: blank -FROM: default +pipeline_setup: - -pipeline_setup: # Name for this pipeline configuration - useful for identification. + # This string will be sanitized and used in filepaths pipeline_name: analysis + output_directory: + + # Quality control outputs + quality_control: + + # Generate quality control pages containing preprocessing and derivative outputs. + generate_quality_control_images: On + + system_config: - system_config: # The maximum amount of memory each participant's workflow can allocate. # Use this to place an upper bound of memory usage. # - Warning: 'Memory Per Participant' multiplied by 'Number of Participants to Run Simultaneously' @@ -43,61 +51,69 @@ pipeline_setup: # If you have specified an FSL path in your .bashrc file, this path will be set automatically. FSLDIR: FSLDIR -anatomical_preproc: - run: Off +anatomical_preproc: + acpc_alignment: + T1w_brain_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm_brain.nii.gz + + # ACPC aligned template + T1w_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm.nii.gz + + brain_extraction: + run: On + +registration_workflows: + anatomical_registration: + registration: + FSL-FNIRT: + + # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + ref_mask_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask_dil.nii.gz + + # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. + T1w_template_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz + + # Reference mask for FSL registration. + ref_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz -segmentation: - run: Off + # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat -registration_workflows: - anatomical_registration: - run: Off + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz - functional_registration: + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz + + # Template to be used during registration. + # It is not necessary to change this path unless you intend to use a non-standard template. + T1w_brain_template_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + functional_registration: coregistration: - run: Off + boundary_based_registration: - EPI_registration: - run: On + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] - EPI_template: /cpac_templates/chd8_functional_template_sk.nii + # Standard FSL 5.0 Scheduler used for Boundary Based Registration. + # It is not necessary to change this path unless you intend to use non-standard MNI registration. + bbr_schedule: /usr/share/fsl/5.0/etc/flirtsch/bbr.sch - ANTs: - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - - dimensionality: 3 - - initial-moving-transform: - initializationFeature: 1 - - transforms: - - Affine: - convergence: - iteration: 100x100x30 - gradientStep: 0.25 - metric: - metricWeight: 1 - radius: 2 - type: CC - shrink-factors: 5x3x1 - smoothing-sigmas: 5x3x0 - - SyN: - convergence: - iteration: 100x100x30 - gradientStep: 0.15 - metric: - metricWeight: 1 - radius: 2 - type: CC - shrink-factors: 5x3x1 - smoothing-sigmas: 5x3x0 - totalFieldVarianceInVoxelSpace: 1 - updateFieldVarianceInVoxelSpace: 5 + func_registration_to_template: - func_registration_to_template: + # these options modify the application (to the functional data), not the calculation, of the + # T1-to-template and EPI-to-template transforms calculated earlier during registration + # apply the functional-to-template (T1 template) registration transform to the functional data + run: On + # apply the functional-to-template (EPI template) registration transform to the functional data run_EPI: On + output_resolution: - output_resolution: # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. # NOTE: # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. @@ -113,12 +129,17 @@ registration_workflows: # thus, a higher resolution may not result in a large increase in RAM needs as above func_derivative_outputs: 2.3mmx2.3mmx6mm - target_template: - + target_template: + + # choose which template space to transform derivatives towards + # using: ['T1_template', 'EPI_template'] + # this is a fork point + # NOTE: + # this will determine which registration transform to use to warp the functional + # outputs and derivatives to template space using: [EPI_template] + T1_template: - # option parameters - T1_template: # Standard Skull Stripped Template. Used as a reference image for functional registration. # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_brain_template_funcreg: /template/study_based_functional_template_sk.nii.gz @@ -126,82 +147,154 @@ registration_workflows: # Standard Anatomical Brain Image with Skull. # This can be different than the template used as the reference/fixed for T1-to-template registration. T1w_template_funcreg: /template/study_based_functional_template.nii.gz - + # Template to be used during registration. # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask_funcreg: None + T1w_brain_template_mask_funcreg: # a standard template for resampling if using float resolution - T1w_template_for_resample: None + T1w_template_for_resample: + + EPI_template: - EPI_template: # EPI template for direct functional-to-template registration # (bypassing coregistration and the anatomical-to-template transforms) EPI_template_funcreg: /cpac_templates/chd8_functional_template_sk.nii - - # EPI template mask. - EPI_template_mask_funcreg: None - + # a standard template for resampling if using float resolution - EPI_template_for_resample: None + EPI_template_for_resample: + + ANTs_pipelines: - ANTs_pipelines: # Interpolation method for writing out transformed functional images. # Possible values: Linear, BSpline, LanczosWindowedSinc interpolation: Linear -functional_preproc: - slice_timing_correction: - # Interpolate voxel time courses so they are sampled at the same time points. - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] + FNIRT_pipelines: + + # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + + EPI_registration: + + # directly register the mean functional to an EPI template + # instead of applying the anatomical T1-to-template transform to the functional data that has been + # coregistered to anatomical/T1 space + run: On + + # EPI template for direct functional-to-template registration + # (bypassing coregistration and the anatomical-to-template transforms) + EPI_template: /cpac_templates/chd8_functional_template_sk.nii + ANTs: + + # EPI registration configuration - synonymous with T1_registration + # parameters under anatomical registration above + parameters: + - dimensionality: 3 + - initial-moving-transform: + initializationFeature: 1 + - transforms: + - Affine: + convergence: + iteration: 100x100x30 + gradientStep: 0.25 + metric: + metricWeight: 1 + radius: 2 + type: CC + shrink-factors: 5x3x1 + smoothing-sigmas: 5x3x0 + - SyN: + convergence: + iteration: 100x100x30 + gradientStep: 0.15 + metric: + metricWeight: 1 + radius: 2 + type: CC + shrink-factors: 5x3x1 + smoothing-sigmas: 5x3x0 + totalFieldVarianceInVoxelSpace: 1 + updateFieldVarianceInVoxelSpace: 5 + + FSL-FNIRT: - motion_estimates_and_correction: + # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. + # It is not necessary to change this path unless you intend to use a different template. + identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat + +functional_preproc: + run: On + motion_estimates_and_correction: + run: On motion_correction: + # using: ['3dvolreg', 'mcflirt'] # this is a fork point - using: ['mcflirt'] + using: [mcflirt] # option parameters - AFNI-3dvolreg: + AFNI-3dvolreg: + # This option is useful when aligning high-resolution datasets that may need more alignment than a few voxels. functional_volreg_twopass: Off - distortion_correction: - run: [Off] + func_masking: + FSL-BET: - func_masking: - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based'] - # this is a fork point - using: [FSL] + # Set an intensity threshold to improve skull stripping performances of FSL BET on rodent scans. + functional_mean_thr: + run: On + + # Bias correct the functional mean image to improve skull stripping performances of FSL BET on rodent scans + functional_mean_bias_correction: On - FSL-BET: # Apply to 4D FMRI data, if bold_bet_functional_mean_boolean : Off. # Mutually exclusive with functional, reduce_bias, robust, padding, remove_eyes, surfaces # It must be 'on' if select 'reduce_bias', 'robust', 'padding', 'remove_eyes', or 'bet_surfaces' on functional_mean_boolean: On - - # Set an intensity threshold to improve skull stripping performances of FSL BET on rodent scans. - functional_mean_thr: - run: On - threshold_value: 98 - # Bias correct the functional mean image to improve skull stripping performances of FSL BET on rodent scans - functional_mean_bias_correction: On - # Integer value of head radius radius: 50 # Robust brain center estimation. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces robust: On -nuisance_corrections: + FSL_AFNI: + brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz + + # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] + # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 + # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask + # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. + # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") + # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. + # this is a fork point + using: [FSL] + + generate_func_mean: + + # Generate mean functional image + run: On + + normalize_func: + + # Normalize functional image + run: On + +nuisance_corrections: 2-nuisance_regression: + # this is a fork point + # run: [On, Off] - this will run both and fork the pipeline + run: [On] + # Select which nuisance signal corrections to apply - Regressors: - - Bandpass: + Regressors: + - Name: Regressor-1 + Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 method: AFNI @@ -214,51 +307,66 @@ nuisance_corrections: include_delayed: Off include_delayed_squared: Off include_squared: Off - Name: Regressor-1 + + # Process and refine masks used to produce regressors and time series for + # regression. + regressor_masks: + erode_anatomical_brain_mask: + + # Erode brain mask in millimeters, default for brain mask is 30 mm + # Brain erosion default is using millimeters. + brain_mask_erosion_mm: 30 + + erode_csf: + + # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm + # Cerebrospinal fluid erosion default is using millimeters. + csf_mask_erosion_mm: 30 + + erode_wm: + + # Target volume ratio, if using erosion. + # Default proportion is 0.6 for white matter mask. + # If using erosion, using both proportion and millimeters is not recommended. + # White matter erosion default is using proportion erosion method when use erosion for white matter. + wm_erosion_prop: 0.6 + + erode_gm: + + # Target volume ratio, if using erosion. + # If using erosion, using both proportion and millimeters is not recommended. + gm_erosion_prop: 0.6 # Standard Lateral Ventricles Binary Mask # used in CSF mask refinement for CSF signal-related regressions lateral_ventricles_mask: /cpac_templates/chd8_functional_template_noise_mask_ag.nii -# OUTPUTS AND DERIVATIVES -# ----------------------- -post_processing: - spatial_smoothing: - # Tool to use for smoothing. - # 'FSL' for FSL MultiImageMaths for FWHM provided - # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided - smoothing_method: [AFNI] +timeseries_extraction: + connectivity_matrix: - # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. - # this is a fork point - # i.e. multiple kernels - fwhm: [4,6,8] - fwhm: [6] + # Create a connectivity matrix from timeseries data + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: [Nilearn, ndmg] + + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: [Pearson, Partial] -timeseries_extraction: - run: Off +amplitude_low_frequency_fluctuation: -seed_based_correlation_analysis: - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off + # space: Template or Native + target_space: [Native] -amplitude_low_frequency_fluctuation: - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and and fractional ALFF (f/ALFF) for all voxels. - run: Off +regional_homogeneity: -regional_homogeneity: - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: Off + # space: Template or Native + target_space: [Native] -voxel_mirrored_homotopic_connectivity: - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: Off +voxel_mirrored_homotopic_connectivity: + symmetric_registration: - symmetric_registration: # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. # It is not necessary to change this path unless you intend to use a non-standard symmetric template. T1w_brain_template_symmetric: /template/study_based_functional_template_sk.nii.gz @@ -280,12 +388,33 @@ voxel_mirrored_homotopic_connectivity: # A reference symmetric brain mask template for resampling dilated_symmetric_brain_mask_for_resample: /template/study_based_functional_template_mask.nii.gz -network_centrality: - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: Off +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + spatial_smoothing: + run: On + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided + smoothing_method: [AFNI] + + # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. + # this is a fork point + # i.e. multiple kernels - fwhm: [4,6,8] + fwhm: [6] + + z-scoring: + run: On + +# PREPROCESSING +# ------------- +surface_analysis: + + # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. + # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, + # select those 'Freesurfer-' labeled options further below in anatomical_preproc. + freesurfer: -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz + # Ingress freesurfer recon-all folder + ingress_reconall: Off diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 6e1e4fb987..8aa3e9acdb 100755 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index 65bcd721b9..86b7b8f305 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 27b6ba4502..b98533729d 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index 5509ab7619..7047bba266 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 9f0b5aaa01..b5fcdde14c 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index 9e13994429..0fc7aeefd2 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 47094e932a..cef30e4ab6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index 108e629865..46399f83c0 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 96fc34c5d7..bb5ea66c41 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 5fecc2a778..82aa1ac2ae 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index 62535e589c..a6491067f5 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index 18c6aa8710..c5e9e532d3 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 326c419e68..664c1d711c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 326c419e68..664c1d711c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 326c419e68..664c1d711c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 326c419e68..664c1d711c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 326c419e68..664c1d711c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 7d73e1153c..8b653b7cae 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index a156683ad5..12ddd5fc6a 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -8,49 +8,48 @@ space-template_desc-sm_alff alff template func NIfTI Yes space-template_desc-sm-zstd_alff alff template func NIfTI space-template_desc-zstd_alff alff template func NIfTI desc-brain_bold bold functional func NIfTI Yes Yes -desc-cleaned_bold bold functional func NifTI Yes Yes desc-mean_bold bold functional func NIfTI desc-motion_bold bold functional func NIfTI Yes Yes desc-preproc_bold bold functional func NIfTI Yes desc-sm_bold bold functional func NIfTI Yes Yes +sbref bold functional func NIfTI space-EPItemplate_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-cleaned_bold bold EPI template func NIfTI Yes +space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes Yes space-EPItemplate_desc-mean_bold bold EPI template func NIfTI space-EPItemplate_desc-preproc_bold bold EPI template func NIfTI Yes space-symtemplate_desc-sm_bold bold symmetric template func NIfTI Yes Yes -space-T1w_desc-mean_bold bold T1w func NIfTI +space-T1w_sbref bold T1w func NIfTI space-template_bold bold template func NIfTI Yes -space-template_desc-brain_bold bold template func NIfTI Yes -space-template_desc-cleaned_bold bold template func NIfTI Yes +space-template_desc-brain_bold bold template func NIfTI Yes Yes space-template_desc-head_bold bold template func NIfTI Yes space-template_desc-mean_bold bold template func NIfTI space-template_desc-preproc_bold bold template func NIfTI Yes space-template_desc-scout_bold bold template func NIfTI -desc-DualReg_correlations correlation template func NIfTI -desc-MeanSCA_correlations correlation template func NIfTI -desc-MultReg_correlations correlation template func NIfTI -desc-ndmg_correlations correlation template func NIfTI -desc-PearsonAfni_correlations correlation template func tsv -desc-PartialAfni_correlations correlation template func tsv -desc-PearsonNilearn_correlations correlation template func tsv -desc-PartialNilearn_correlations correlation template func tsv -space-template_desc-binarized_degree-centrality degree-centrality template func NIfTI Yes Yes -space-template_desc-binarized-sm_degree-centrality degree-centrality template func NIfTI Yes -space-template_desc-binarized-sm-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-binarized-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-weighted_degree-centrality degree-centrality template func NIfTI Yes Yes -space-template_desc-weighted-sm_degree-centrality degree-centrality template func NIfTI Yes -space-template_desc-weighted-sm-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-weighted-zstd_degree-centrality degree-centrality template func NIfTI -space-template_desc-binarized_eigen-centrality eigen-centrality template func NIfTI Yes Yes -space-template_desc-binarized-sm_eigen-centrality eigen-centrality template func NIfTI Yes -space-template_desc-binarized-sm-zstd_eigen-centrality eigen-centrality template func NIfTI -space-template_desc-binarized-zstd_eigen-centrality eigen-centrality template func NIfTI -space-template_desc-weighted_eigen-centrality eigen-centrality template func NIfTI Yes Yes -space-template_desc-weighted-sm_eigen-centrality eigen-centrality template func NIfTI Yes -space-template_desc-weighted-sm-zstd_eigen-centrality eigen-centrality template func NIfTI -space-template_desc-weighted-zstd_eigen-centrality eigen-centrality template func NIfTI +space-template_sbref bold template func NIfTI +space-template_desc-DualReg_correlations correlation template func NIfTI +space-template_desc-MeanSCA_correlations correlation template func NIfTI +space-template_desc-MultReg_correlations correlation template func NIfTI +space-template_desc-ndmg_correlations correlation template func NIfTI +space-template_desc-PearsonAfni_correlations correlation template func tsv +space-template_desc-PartialAfni_correlations correlation template func tsv +space-template_desc-PearsonNilearn_correlations correlation template func tsv +space-template_desc-PartialNilearn_correlations correlation template func tsv +space-template_dcb degree-centrality template func NIfTI Yes Yes +space-template_desc-sm_dcb degree-centrality template func NIfTI Yes +space-template_desc-sm-zstd_dcb degree-centrality template func NIfTI +space-template_desc-zstd_dcb degree-centrality template func NIfTI +space-template_dcw degree-centrality template func NIfTI Yes Yes +space-template_desc-sm_dcw degree-centrality template func NIfTI Yes +space-template_desc-sm-zstd_dcw degree-centrality template func NIfTI +space-template_desc-zstd_dcw degree-centrality template func NIfTI +space-template_ecb eigen-centrality template func NIfTI Yes Yes +space-template_desc-sm_ecb eigen-centrality template func NIfTI Yes +space-template_desc-sm-zstd_ecb eigen-centrality template func NIfTI +space-template_desc-zstd_ecb eigen-centrality template func NIfTI +space-template_ecw eigen-centrality template func NIfTI Yes Yes +space-template_desc-sm_ecw eigen-centrality template func NIfTI Yes +space-template_desc-sm-zstd_ecw eigen-centrality template func NIfTI +space-template_desc-zstd_ecw eigen-centrality template func NIfTI desc-sm_falff falff functional func NIfTI Yes desc-sm-zstd_falff falff functional func NIfTI desc-zstd_falff falff functional func NIfTI @@ -59,14 +58,14 @@ space-template_desc-sm_falff falff template func NIfTI Yes space-template_desc-sm-zstd_falff falff template func NIfTI space-template_desc-zstd_falff falff template func NIfTI space-template_falff falff template func NIfTI Yes Yes -space-template_desc-binarized_lfcd lfcd template func NIfTI Yes Yes -space-template_desc-binarized-sm_lfcd lfcd template func NIfTI Yes -space-template_desc-binarized-sm-zstd_lfcd lfcd template func NIfTI -space-template_desc-binarized-zstd_lfcd lfcd template func NIfTI -space-template_desc-weighted_lfcd lfcd template func NIfTI Yes Yes -space-template_desc-weighted-sm_lfcd lfcd template func NIfTI Yes -space-template_desc-weighted-sm-zstd_lfcd lfcd template func NIfTI -space-template_desc-weighted-zstd_lfcd lfcd template func NIfTI +space-template_lfcdb lfcd template func NIfTI Yes Yes +space-template_desc-sm_lfcdb lfcd template func NIfTI Yes +space-template_desc-sm-zstd_lfcdb lfcd template func NIfTI +space-template_desc-zstd_lfcdb lfcd template func NIfTI +space-template_lfcdw lfcd template func NIfTI Yes Yes +space-template_desc-sm_lfcdw lfcd template func NIfTI Yes +space-template_desc-sm-zstd_lfcdw lfcd template func NIfTI +space-template_desc-zstd_lfcdw lfcd template func NIfTI space-EPItemplate_desc-bold_mask mask EPI template func NIfTI space-EPItemplate_res-derivative_desc-bold_mask mask EPI template func NIfTI space-bold_desc-brain_mask mask functional func NIfTI @@ -96,6 +95,7 @@ label-WM_mask mask T1w anat NIfTI space-T1w_desc-acpcbrain_mask mask T1w anat NIfTI space-T1w_desc-brain_mask mask T1w anat NIfTI space-T1w_desc-eroded_mask mask T1w anat NIfTI +space-template_desc-brain_mask mask template anat NIfTI space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI dvars motion func text @@ -111,20 +111,20 @@ rels-displacement motion func 1D label-CSF_probseg probseg T1w anat NIfTI label-GM_probseg probseg T1w anat NIfTI label-WM_probseg probseg T1w anat NIfTI -T1w-axial-qc qc anat png -T1w-sagittal-qc qc anat png -dseg-axial-qc qc anat png -desg-sagittal-qc qc anat png -bold-axial-qc qc func png -bold-sagittal-qc qc func png -bold-carpet-qc qc func png -framewise-displacement-jenkinson-plot-qc qc func png -movement-parameters-trans-qc qc func png -movement-parameters-rot-qc qc func png -bold-snr-axial-qc qc func png -bold-snr-sagittal-qc qc func png -bold-snr-hist-qc qc func png -bold-snr-qc qc func png +desc-T1wAxial_quality qc anat png +desc-T1wSagittal_quality qc anat png +desc-dsegAxial_quality qc anat png +desc-dsegSagittal_quality qc anat png +desc-boldAxial_quality qc func png +desc-boldSagittal_quality qc func png +desc-boldCarpet_quality qc func png +desc-framewiseDisplacementJenkinsonPlot_quality qc func png +desc-movementParametersTrans_quality qc func png +desc-movementParametersRot_quality qc func png +desc-boldSnrAxial_quality qc func png +desc-boldSnrSagittal_quality qc func png +desc-boldSnrHist_quality qc func png +desc-boldSnr_quality qc func png space-template_desc-xcp_quality qc func tsv regressors regressors func 1D desc-sm_reho reho functional func NIfTI Yes @@ -146,10 +146,10 @@ hemi-R_desc-surfaceMesh_pial surface-derived anat raw-average surface-derived anat hemi-L_desc-surfaceMesh_smoothwm surface-derived anat hemi-R_desc-surfaceMesh_smoothwm surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-32k.dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-32k.dlabel surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-164k.dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-164k.dlabel surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-32k_dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-32k_dlabel surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-164k_dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-164k_dlabel surface-derived anat space-fsLR_den-32k_bold-dtseries surface-derived func hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes @@ -160,16 +160,18 @@ hemi-R_desc-surface_curv surface-derived anat hemi-L_desc-surfaceMesh_white surface-derived anat Yes hemi-R_desc-surfaceMesh_white surface-derived anat Yes wmparc surface-derived anat Yes -space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI -desc-brain_T1w T1w T1w anat NIfTI +space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI Yes +desc-brain_T1w T1w T1w anat NIfTI Yes +desc-head_T1w T1w T1w anat NIfTI desc-preproc_T1w T1w T1w anat NIfTI -desc-reorient_T1w T1w T1w anat NIfTI +desc-reorient_T1w T1w T1w anat NIfTI Yes desc-restore_T1w T1w T1w anat NIfTI desc-restore-brain_T1w T1w T1w anat NIfTI -space-template_desc-brain_T1w T1w template anat NIfTI +space-template_desc-brain_T1w T1w template anat NIfTI Yes +space-template_desc-preproc_T1w T1w template anat NIfTI space-template_desc-head_T1w T1w template anat NIfTI space-template_desc-T1w_mask mask template anat NIfTI -desc-Mean_timeseries timeseries func 1D +space-template_desc-Mean_timeseries timeseries func 1D desc-MeanSCA_timeseries timeseries func 1D desc-SpatReg_timeseries timeseries func 1D desc-Voxel_timeseries timeseries func 1D @@ -217,7 +219,9 @@ space-template_label-WM_mask mask template anat NIfTI space-template_label-GM_mask mask template anat NIfTI space-EPItemplate_label-CSF_mask mask template func NIfTI space-EPItemplate_label-WM_mask mask template func NIfTI -space-EPItemplate_label-GM_mask mask template func NIfTI +space-EPItemplate_label-GM_mask mask template func NIfTI +mdmr group functional group_analysis NIfTI +desc-zstd-mdmr group functional group_analysis NIfTI Yes AtlasSubcortical_s2 surface_derived func space-fsLR_den-32k_bold surface_derived func CIFTI dtseries goodvoxels surface_derived func @@ -306,4 +310,4 @@ atlas-Destrieux_space-fsLR_den-32k surface_derived func CIFTI dlabel atlas-DesikanKilliany_space-fsLR_den-164k surface_derived func CIFTI dlabel atlas-Destrieux_space-fsLR_den-164k surface_derived func CIFTI dlabel surf_alff surface_derived func CIFTI dscalar -surf_falff surface_derived func CIFTI dscalar \ No newline at end of file +surf_falff surface_derived func CIFTI dscalar diff --git a/CPAC/resources/cpac_templates.csv b/CPAC/resources/cpac_templates.csv index 2faaab8cd2..492c43bf1d 100755 --- a/CPAC/resources/cpac_templates.csv +++ b/CPAC/resources/cpac_templates.csv @@ -21,14 +21,14 @@ T1w-brain-template-deriv,"registration_workflows, functional_registration, func_ T1w-brain-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" T1w-brain-template-mask,"registration_workflows, anatomical_registration, T1w_brain_template_mask",Binary brain mask of the T1w template,"registration_workflows, anatomical_registration, resolution_for_anat" T1w-brain-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric",Symmetric version of the T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-symmetric-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg","Symmetric version of the T1w-based skull-stripped template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-brain-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_funcreg","Symmetric version of the T1w-based skull-stripped template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" T1w-brain-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_for_resample",, T1w-template,"registration_workflows, anatomical_registration, T1w_template",T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" T1w-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" T1w-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_for_resample",, T1w-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric",,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-template-symmetric-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg","Symmetric version of the T1w-based whole-head template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric",Symmetric version of the T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_funcreg","Symmetric version of the T1w-based whole-head template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" T1w-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_for_resample",, template-ref-mask,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" template-ref-mask-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask_res-2",, diff --git a/CPAC/resources/templates/BIDS_identifiers.tsv b/CPAC/resources/templates/BIDS_identifiers.tsv new file mode 100644 index 0000000000..168dd9d87b --- /dev/null +++ b/CPAC/resources/templates/BIDS_identifiers.tsv @@ -0,0 +1,31 @@ +/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_T1w_reference.nii.gz MNI152NLin2009cAsym +/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-brain_T1w.nii.gz MNI152NLin2009cAsym +/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-brain_mask.nii.gz MNI152NLin2009cAsym +/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_desc-fMRIPrep_boldref.nii.gz MNI152NLin2009cAsym +/code/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_label-brain_probseg.nii.gz MNI152NLin2009cAsym +/code/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii MNI152NLin2009cAsym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*.nii.gz MNI152NLin6ASym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain.nii.gz MNI152NLin6ASym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask.nii.gz MNI152NLin6ASym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_dil.nii.gz MNI152NLin6ASym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_symmetric.nii.gz MNI152NLin6Sym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_symmetric.nii.gz MNI152NLin6Sym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_symmetric.nii.gz MNI152NLin6Sym +/usr/share/fsl/5.0/data/standard/MNI152_T1_(res-){0,1}[0-9]+(\.[0-9]*){0,1}[a-z]*(x[0-9]+(\.[0-9]*){0,1}[a-z]*)*_brain_mask_symmetric_dil.nii.gz MNI152NLin6Sym +/ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-2x2x2.nii.gz AAL +/ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-2x2x2.nii.gz Brodmann +/cpac_templates/CC200.nii.gz CC 200 +/cpac_templates/CC400.nii.gz CC 400 +/ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-2x2x2.nii.gz Glasser +/ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-2x2x2.nii.gz Slab +/ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-2x2x2.nii.gz HOCPA th25 +/ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-2x2x2.nii.gz HOSPA th25 +/ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-2x2x2.nii.gz Juelich +/ndmg_atlases/label/Human/Schaefer[^_-]*200.*.nii(\.gz){0,1} Schaefer2018 p200n17 +/ndmg_atlases/label/Human/Schaefer[^_-]*300.*.nii(\.gz){0,1} Schaefer2018 p300n17 +/ndmg_atlases/label/Human/Schaefer[^_-]*400.*.nii(\.gz){0,1} Schaefer2018 p400n17 +/ndmg_atlases/label/Human/Schaefer[^_-]*1000.*.nii(\.gz){0,1} Schaefer2018 p1000n17 +/ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 7 +/ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 7liberal +/ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 17 +/ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-2x2x2.nii.gz Yeo 17liberal diff --git a/CPAC/resources/templates/__init__.py b/CPAC/resources/templates/__init__.py new file mode 100644 index 0000000000..35eb3ce592 --- /dev/null +++ b/CPAC/resources/templates/__init__.py @@ -0,0 +1,4 @@ +'''Template resources for C-PAC''' +from .lookup_table import format_identifier, lookup_identifier + +__all__ = ['format_identifier', 'lookup_identifier'] diff --git a/CPAC/resources/templates/lookup_table.py b/CPAC/resources/templates/lookup_table.py new file mode 100644 index 0000000000..7b7a490d5b --- /dev/null +++ b/CPAC/resources/templates/lookup_table.py @@ -0,0 +1,87 @@ +# Copyright (C) 2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +"""Utilities for determining BIDS standard template identifiers +(https://bids-specification.readthedocs.io/en/stable/99-appendices/08-coordinate-systems.html#standard-template-identifiers) +from in-container template paths""" +from os import path as op +from re import search +from typing import Optional, Tuple +from numpy import loadtxt + +LOOKUP_TABLE = {row[0]: (row[1], str(row[2]) if row[2] else None) for row in + loadtxt(op.join(op.dirname(__file__), 'BIDS_identifiers.tsv'), + dtype='str', delimiter='\t')} + + +def format_identifier(identifier: str, desc: Optional[str] = None) -> str: + '''Function to create an identifier string from a name and description + + Parameters + ---------- + identifier : str + + desc : str, optional + + Returns + ------- + str + + Examples + -------- + >>> format_identifier('CC', '200') + 'CC_desc-200' + >>> format_identifier('AAL') + 'AAL' + ''' + if desc: + return f'{identifier}_desc-{desc}' + return identifier + + +def lookup_identifier(template_path: str) -> Tuple[str, None]: + '''Function to return a standard template identifier for a packaged + template, if known. Otherwise, returns the literal string + 'template' + + Parameters + ---------- + template_path : str + + Returns + ------- + identifier : str + + desc : str or None + + Examples + -------- + >>> lookup_identifier('/usr/share/fsl/5.0/data/standard/' + ... 'MNI152_T1_1mm_brain.nii.gz') + ('MNI152NLin6ASym', None) + >>> lookup_identifier('/code/CPAC/resources/templates/' + ... 'tpl-MNI152NLin2009cAsym_res-01_label-brain_' + ... 'probseg.nii.gz') + ('MNI152NLin2009cAsym', None) + >>> lookup_identifier('/cpac_templates/chd8_functional_template_sk.nii') + ('template', None) + >>> lookup_identifier('/cpac_templates/CC200.nii.gz') + ('CC', '200') + ''' + for key, value in LOOKUP_TABLE.items(): + if search(key, template_path) is not None: + return value + return 'template', None diff --git a/CPAC/resources/tests/test_permissions.py b/CPAC/resources/tests/test_permissions.py new file mode 100644 index 0000000000..fe881e0c3e --- /dev/null +++ b/CPAC/resources/tests/test_permissions.py @@ -0,0 +1,29 @@ +# Copyright (C) 2020-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +"""Tests for appropriate permissions on resources""" +from os import environ +from pathlib import Path +import stat +import pytest + + +@pytest.mark.parametrize('template', + list(Path(f'{environ.get("FSLDIR")}/data/standard' + ).glob('*.nii.gz'))) +def test_read_fsl_templates(template): + """For each FSL template, make sure its permissions include 444""" + assert stat.filemode(template.stat().st_mode).count('r') == 3 diff --git a/CPAC/sca/sca.py b/CPAC/sca/sca.py index 64f6fb37db..214ae36b72 100755 --- a/CPAC/sca/sca.py +++ b/CPAC/sca/sca.py @@ -1,3 +1,19 @@ +# Copyright (C) 2022-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . from nipype.interfaces.afni import preprocess from CPAC.pipeline import nipype_pipeline_engine as pe import nipype.algorithms.rapidart as ra @@ -12,7 +28,7 @@ create_roi_mask_dataflow, create_spatial_map_dataflow from CPAC.timeseries.timeseries_analysis import get_roi_timeseries, \ - get_spatial_map_timeseries + get_spatial_map_timeseries, resample_function def create_sca(name_sca='sca'): @@ -389,13 +405,9 @@ def SCA_AVG(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]], + "inputs": ["space-template_desc-preproc_bold"], "outputs": ["desc-MeanSCA_timeseries", - "desc-MeanSCA_correlations", + "space-template_desc-MeanSCA_correlations", "atlas_name"]} ''' @@ -430,11 +442,7 @@ def SCA_AVG(wf, cfg, strat_pool, pipe_num, opt=None): roi_timeseries_for_sca = get_roi_timeseries( f'roi_timeseries_for_sca_{pipe_num}') - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") # resample the input functional file to roi wf.connect(node, out, resample_functional_roi_for_sca, 'in_func') @@ -449,11 +457,7 @@ def SCA_AVG(wf, cfg, strat_pool, pipe_num, opt=None): sca_roi = create_sca(f'sca_roi_{pipe_num}') - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") wf.connect(node, out, sca_roi, 'inputspec.functional_file') wf.connect(roi_timeseries_for_sca, 'outputspec.roi_csv', @@ -465,7 +469,7 @@ def SCA_AVG(wf, cfg, strat_pool, pipe_num, opt=None): (roi_timeseries_for_sca, 'outputspec.roi_csv'), #('outputspec.roi_outputs', # extract_one_d)), - 'desc-MeanSCA_correlations': + 'space-template_desc-MeanSCA_correlations': (sca_roi, 'outputspec.correlation_stack'), 'atlas_name': (roi_dataflow_for_sca, 'outputspec.out_name') } @@ -482,13 +486,9 @@ def dual_regression(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"], + "inputs": ["space-template_desc-preproc_bold", "space-template_desc-bold_mask"], - "outputs": ["desc-DualReg_correlations", + "outputs": ["space-template_desc-DualReg_correlations", "desc-DualReg_statmap", "atlas_name"]} ''' @@ -523,11 +523,7 @@ def dual_regression(wf, cfg, strat_pool, pipe_num, opt=None): # resample the input functional file and functional mask # to spatial map - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") wf.connect(node, out, resample_spatial_map_to_native_space_for_dr, 'reference') wf.connect(node, out, @@ -549,18 +545,14 @@ def dual_regression(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(spatial_map_timeseries_for_dr, 'outputspec.subject_timeseries', dr_temp_reg, 'inputspec.subject_timeseries') - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") wf.connect(node, out, dr_temp_reg, 'inputspec.subject_rest') node, out = strat_pool.get_data("space-template_desc-bold_mask") wf.connect(node, out, dr_temp_reg, 'inputspec.subject_mask') outputs = { - 'desc-DualReg_correlations': + 'space-template_desc-DualReg_correlations': (dr_temp_reg, 'outputspec.temp_reg_map'), 'desc-DualReg_statmap': (dr_temp_reg, 'outputspec.temp_reg_map_z'), @@ -580,13 +572,9 @@ def multiple_regression(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"], + "inputs": ["space-template_desc-preproc_bold", "space-template_desc-bold_mask"], - "outputs": ["desc-MultReg_correlations", + "outputs": ["space-template_desc-MultReg_correlations", "desc-MultReg_statmap", "atlas_name"]} ''' @@ -594,14 +582,7 @@ def multiple_regression(wf, cfg, strat_pool, pipe_num, opt=None): # same workflow, except to run TSE and send it to the resource # pool so that it will not get sent to SCA resample_functional_roi_for_multreg = pe.Node( - util.Function(input_names=['in_func', - 'in_roi', - 'realignment', - 'identity_matrix'], - output_names=['out_func', - 'out_roi'], - function=resample_func_roi, - as_module=True), + resample_function(), name=f'resample_functional_roi_for_multreg_{pipe_num}') resample_functional_roi_for_multreg.inputs.realignment = \ @@ -622,11 +603,7 @@ def multiple_regression(wf, cfg, strat_pool, pipe_num, opt=None): roi_timeseries_for_multreg = get_roi_timeseries( f'roi_timeseries_for_mult_reg_{pipe_num}') - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") # resample the input functional file to roi wf.connect(node, out, resample_functional_roi_for_multreg, 'in_func') wf.connect(roi_dataflow_for_multreg, @@ -666,7 +643,7 @@ def multiple_regression(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(node, out, sc_temp_reg, 'inputspec.subject_mask') outputs = { - 'desc-MultReg_correlations': + 'space-template_desc-MultReg_correlations': (sc_temp_reg, 'outputspec.temp_reg_map'), 'desc-MultReg_statmap': (sc_temp_reg, 'outputspec.temp_reg_map_z'), diff --git a/CPAC/seg_preproc/seg_preproc.py b/CPAC/seg_preproc/seg_preproc.py index e157c52e23..26da08b54d 100755 --- a/CPAC/seg_preproc/seg_preproc.py +++ b/CPAC/seg_preproc/seg_preproc.py @@ -414,116 +414,6 @@ def create_seg_preproc_antsJointLabel_method( return preproc -def create_seg_preproc_freesurfer(config=None, - wf_name='seg_preproc_freesurfer', - pipe_num=0): - """ - Generate the subject's segmentations based on freesurfer. - - Parameters - ---------- - config : CPAC.utils.configuration.Configuration - - wf_name : string - name of the workflow - - pipe_num : int - - Returns - ------- - seg_preproc_freesurfer : workflow - workflow object for segmentation workflow - - hemisphere_outputs : dict - hemisphere-specific FreeSurfer outputs - - Notes - ----- - - Workflow Inputs: :: - - inputspec.subject_dir : string (existing nifti file) - FreeSurfer autorecon1 dir - - Workflow Outputs: :: - - outputspec.wm_mask : string (nifti file) - outputs White Matter mask - """ - preproc = pe.Workflow(name=wf_name) - - inputnode = pe.Node(util.IdentityInterface(fields=['subject_dir']), - name='inputspec') - - outputnode = pe.Node(util.IdentityInterface(fields=['wm_mask', - 'gm_mask', - 'csf_mask', - 'subject_id']), - name='outputspec') - - reconall2 = pe.Node(interface=freesurfer.ReconAll(), - name='anat_autorecon2') - - reconall2.inputs.directive = 'autorecon2' - reconall2.inputs.openmp = config.pipeline_setup['system_config'][ - 'num_omp_threads'] - - preproc.connect(inputnode, 'subject_dir', - reconall2, 'subjects_dir') - - preproc.connect(reconall2, 'subject_id', - outputnode, 'subject_id') - - # register FS segmentations (aseg.mgz) to native space - fs_aseg_to_native = pe.Node(interface=freesurfer.ApplyVolTransform(), - name='fs_aseg_to_native') - - fs_aseg_to_native.inputs.reg_header = True - fs_aseg_to_native.inputs.interp = 'nearest' - - preproc.connect(reconall2, 'aseg', - fs_aseg_to_native, 'source_file') - - preproc.connect(reconall2, 'rawavg', - fs_aseg_to_native, 'target_file') - - preproc.connect(inputnode, 'subject_dir', - fs_aseg_to_native, 'subjects_dir') - - # convert registered FS segmentations from .mgz to .nii.gz - fs_aseg_to_nifti = pe.Node(util.Function(input_names=['in_file'], - output_names=['out_file'], - function=mri_convert), - name='fs_aseg_to_nifti') - - fs_aseg_to_nifti.inputs.args = '-rt nearest' - - preproc.connect(fs_aseg_to_native, 'transformed_file', - fs_aseg_to_nifti, 'in_file') - - pick_tissue = pe.Node( - pick_tissue_from_labels_file_interface( - input_names=['multiatlas_Labels']), - name=f'{wf_name}_tissue_mask') - - preproc.connect(fs_aseg_to_nifti, 'out_file', - pick_tissue, 'multiatlas_Labels') - - preproc.connect(pick_tissue, 'wm_mask', - outputnode, 'wm_mask') - - preproc.connect(pick_tissue, 'gm_mask', - outputnode, 'gm_mask') - - preproc.connect(pick_tissue, 'csf_mask', - outputnode, 'csf_mask') - - preproc, hemisphere_outputs = freesurfer_hemispheres(preproc, reconall2, - pipe_num) - - return preproc, hemisphere_outputs - - def tissue_seg_fsl_fast(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "tissue_seg_fsl_fast", @@ -907,39 +797,69 @@ def tissue_seg_freesurfer(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": ["tissue_segmentation", "using"], "option_val": "FreeSurfer", "inputs": ["freesurfer-subject-dir"], - "outputs": ["hemi-L_desc-surface_curv", - "hemi-R_desc-surface_curv", - "hemi-L_desc-surfaceMesh_pial", - "hemi-R_desc-surfaceMesh_pial", - "hemi-L_desc-surfaceMesh_smoothwm", - "hemi-R_desc-surfaceMesh_smoothwm", - "hemi-L_desc-surfaceMesh_sphere", - "hemi-R_desc-surfaceMesh_sphere", - "hemi-L_desc-surfaceMap_sulc", - "hemi-R_desc-surfaceMap_sulc", - "hemi-L_desc-surfaceMap_thickness", - "hemi-R_desc-surfaceMap_thickness", - "hemi-L_desc-surfaceMap_volume", - "hemi-R_desc-surfaceMap_volume", - "hemi-L_desc-surfaceMesh_white", - "hemi-R_desc-surfaceMesh_white", + "outputs": ["pipeline-fs_hemi-L_desc-surface_curv", + "pipeline-fs_hemi-R_desc-surface_curv", + "pipeline-fs_hemi-L_desc-surfaceMesh_pial", + "pipeline-fs_hemi-R_desc-surfaceMesh_pial", + "pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm", + "pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm", + "pipeline-fs_hemi-L_desc-surfaceMesh_sphere", + "pipeline-fs_hemi-R_desc-surfaceMesh_sphere", + "pipeline-fs_hemi-L_desc-surfaceMap_sulc", + "pipeline-fs_hemi-R_desc-surfaceMap_sulc", + "pipeline-fs_hemi-L_desc-surfaceMap_thickness", + "pipeline-fs_hemi-R_desc-surfaceMap_thickness", + "pipeline-fs_hemi-L_desc-surfaceMap_volume", + "pipeline-fs_hemi-R_desc-surfaceMap_volume", + "pipeline-fs_hemi-L_desc-surfaceMesh_white", + "pipeline-fs_hemi-R_desc-surfaceMesh_white", "label-CSF_mask", "label-GM_mask", "label-WM_mask"]} ''' - fs_seg, hemisphere_outputs = create_seg_preproc_freesurfer( - config=cfg, wf_name=f'seg_preproc_freesurfer_{pipe_num}', - pipe_num=pipe_num) + fs_aseg_to_nifti = pe.Node(util.Function(input_names=['in_file'], + output_names=['out_file'], + function=mri_convert), + name=f'fs_aseg_to_nifti_{pipe_num}') + fs_aseg_to_nifti.inputs.args = '-rt nearest' - node, out = strat_pool.get_data('freesurfer-subject-dir') - wf.connect(node, out, fs_seg, 'inputspec.subject_dir') + pick_tissue = pe.Node(pick_tissue_from_labels_file_interface(), + name=f'select_fs_tissue_{pipe_num}') + + pick_tissue.inputs.csf_label = cfg['segmentation'][ + 'tissue_segmentation']['FreeSurfer']['CSF_label'] + pick_tissue.inputs.gm_label = cfg['segmentation'][ + 'tissue_segmentation']['FreeSurfer']['GM_label'] + pick_tissue.inputs.wm_label = cfg['segmentation'][ + 'tissue_segmentation']['FreeSurfer']['WM_label'] + + wf.connect(fs_aseg_to_nifti, 'out_file', pick_tissue, 'multiatlas_Labels') + + erode_tissues = {} + if cfg['segmentation']['tissue_segmentation']['FreeSurfer']['erode'] > 0: + for tissue in ['csf', 'wm', 'gm']: + erode_tissues[tissue] = pe.Node( + interface=freesurfer.model.Binarize(), + name=f'erode_{tissue}_{pipe_num}') + erode_tissues[tissue].inputs.match = [1] + erode_tissues[tissue].inputs.erode = cfg['segmentation'][ + 'tissue_segmentation']['FreeSurfer']['erode'] + wf.connect(pick_tissue, f'{tissue}_mask', erode_tissues[tissue], + 'in_file') + + if erode_tissues: + outputs = { + 'label-CSF_mask': (erode_tissues['csf'], 'binary_file'), + 'label-WM_mask': (erode_tissues['wm'], 'binary_file'), + 'label-GM_mask': (erode_tissues['gm'], 'binary_file') + } - outputs = { - 'label-CSF_mask': (fs_seg, 'outputspec.csf_mask'), - 'label-GM_mask': (fs_seg, 'outputspec.gm_mask'), - 'label-WM_mask': (fs_seg, 'outputspec.wm_mask'), - **hemisphere_outputs - } + else: + outputs = { + 'label-CSF_mask': (pick_tissue, 'csf_mask'), + 'label-WM_mask': (pick_tissue, 'wm_mask'), + 'label-GM_mask': (pick_tissue, 'gm_mask') + } return (wf, outputs) diff --git a/CPAC/surface/__init__.py b/CPAC/surface/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/CPAC/surface/fMRISurface/SubcorticalProcessing.sh b/CPAC/surface/fMRISurface/SubcorticalProcessing.sh index f63f43d859..ffb11c0c18 100755 --- a/CPAC/surface/fMRISurface/SubcorticalProcessing.sh +++ b/CPAC/surface/fMRISurface/SubcorticalProcessing.sh @@ -48,7 +48,7 @@ unset POSIXLY_CORRECT #mkdir -p $TempSubjectDIR #hj edit: make a temp dir -TempSubjectDIR="/tmp/TempSubjectDIR" +TempSubjectDIR="$ResultsFolder/TempSubjectDIR" mkdir -p $TempSubjectDIR chmod 770 $TempSubjectDIR diff --git a/CPAC/surface/globals.py b/CPAC/surface/globals.py new file mode 100644 index 0000000000..00971808f5 --- /dev/null +++ b/CPAC/surface/globals.py @@ -0,0 +1,5 @@ +"""Global variables related to surface processing""" +DOUBLERUN_GUARD_MESSAGE = ('FreeSurfer will run as part of configured brain ' + 'extraction in this specific configuration, so ' + 'FreeSurfer\'s independent run was automatically ' + 'disabled.') diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index bc3ff4a214..d2d215b89e 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -37,7 +37,10 @@ def run_surface(post_freesurfer_folder, import os import subprocess - freesurfer_folder = os.path.join(freesurfer_folder, 'recon_all') + recon_all_path = os.path.join(freesurfer_folder, 'recon_all') + + if os.path.isdir(recon_all_path): + freesurfer_folder = recon_all_path # # DCAN-HCP PostFreeSurfer # # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh @@ -583,22 +586,23 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): surf.inputs.fmri_res = str(cfg.surface_analysis['post_freesurfer']['fmri_res']) surf.inputs.smooth_fwhm = str(cfg.surface_analysis['post_freesurfer']['smooth_fwhm']) - restore = ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"] - space_temp = ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask",] - atlas_xfm = ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"] - atlas_xfm_inv = ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"] - atlas_space_bold = ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"] - scout_bold = ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"] - + restore = ["pipeline-fs_desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", + "space-longitudinal_desc-reorient_T1w"] + space_temp = ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask"] + atlas_xfm = ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"] + atlas_xfm_inv = ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"] + atlas_space_bold = ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"] + scout_bold = ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", + "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"] node, out = strat_pool.get_data('freesurfer-subject-dir') wf.connect(node, out, surf, 'freesurfer_folder') + node, out = strat_pool.get_data(restore) wf.connect(node, out, surf, 't1w_restore_image') - + + node, out = strat_pool.get_data(space_temp) wf.connect(node, out, surf, 'atlas_space_t1w_image') @@ -749,20 +753,29 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": ["freesurfer-subject-dir", - ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"], - ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask"], - ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"], - ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"], - ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], - ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"]], + "inputs": [("freesurfer-subject-dir", + ["pipeline-fs_desc-restore_T1w", "desc-preproc_T1w", + "desc-reorient_T1w", "T1w", + "space-longitudinal_desc-reorient_T1w"], + ["space-template_desc-head_T1w", + "space-template_desc-brain_T1w", + "space-template_desc-T1w_mask"], + ["from-T1w_to-template_mode-image_xfm", + "from-T1w_to-template_mode-image_desc-linear_xfm"], + ["from-template_to-T1w_mode-image_xfm", + "from-template_to-T1w_mode-image_desc-linear_xfm"], + ["space-template_desc-brain_bold", + "space-template_desc-preproc_bold"], + ["space-template_desc-scout_bold", + "space-template_desc-cleaned_bold", + "space-template_desc-brain_bold", + "space-template_desc-motion_bold", "space-template_bold"])], "outputs": ["space-fsLR_den-32k_bold", - "atlas-DesikanKilliany_space-fsLR_den-32k", - "atlas-Destrieux_space-fsLR_den-32k", - "atlas-DesikanKilliany_space-fsLR_den-164k", - "atlas-Destrieux_space-fsLR_den-164k", + "atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", + "atlas-Destrieux_space-fsLR_den-32k_dlabel", + "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", + "atlas-Destrieux_space-fsLR_den-164k_dlabel", + "space-fsLR_den-32k_bold-dtseries", "AtlasSubcortical_s2", "goodvoxels", "ribbon_only", @@ -850,6 +863,7 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): return (wf, outputs) + def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): falff = pe.Node(util.Function(input_names=['subject','dtseries'], @@ -1101,4 +1115,4 @@ def run_cifticorrelation(subject, ptseries): correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] log_subprocess(cmd) - return correlation_matrix \ No newline at end of file + return correlation_matrix diff --git a/CPAC/surface/tests/test_config.py b/CPAC/surface/tests/test_config.py index e2c2f81808..db5f223b78 100755 --- a/CPAC/surface/tests/test_config.py +++ b/CPAC/surface/tests/test_config.py @@ -9,7 +9,7 @@ from CPAC.pipeline.cpac_pipeline import run_workflow from CPAC.utils.configuration import Configuration - +@pytest.mark.skip(reason='timing out for unrelated reasons') @pytest.mark.timeout(60) def test_duplicate_freesurfer(tmp_path): """The pipeline should build fast if freesurfer is not self-duplicating""" diff --git a/CPAC/timeseries/timeseries_analysis.py b/CPAC/timeseries/timeseries_analysis.py index 415ea6fe09..bdc6b2f1b2 100755 --- a/CPAC/timeseries/timeseries_analysis.py +++ b/CPAC/timeseries/timeseries_analysis.py @@ -1,3 +1,19 @@ +# Copyright (C) 2012-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import nipype.interfaces.utility as util from nipype.interfaces import afni, fsl from nipype.interfaces.utility import Function @@ -759,6 +775,21 @@ def gen_vertices_timeseries(rh_surface_file, return out_list +def resample_function() -> 'Function': + """ + Returns a Function interface for + `CPAC.utils.datasource.resample_func_roi` + + Returns + ------- + Function + """ + return Function(input_names=['in_func', 'in_roi', 'realignment', + 'identity_matrix'], + output_names=['out_func', 'out_roi'], + function=resample_func_roi, as_module=True) + + def timeseries_extraction_AVG(wf, cfg, strat_pool, pipe_num, opt=None): ''' {"name": "timeseries_extraction_AVG", @@ -766,32 +797,21 @@ def timeseries_extraction_AVG(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]], - "outputs": ["desc-Mean_timeseries", - "desc-ndmg_correlations", + "inputs": ["space-template_desc-preproc_bold", + "space-template_desc-brain_mask"], + "outputs": ["space-template_desc-Mean_timeseries", + "space-template_desc-ndmg_correlations", "atlas_name", - "desc-PearsonAfni_correlations", - "desc-PartialAfni_correlations", - "desc-PearsonNilearn_correlations", - "desc-PartialNilearn_correlations"]} + "space-template_desc-PearsonAfni_correlations", + "space-template_desc-PartialAfni_correlations", + "space-template_desc-PearsonNilearn_correlations", + "space-template_desc-PartialNilearn_correlations"]} ''' - resample_functional_roi = pe.Node(Function(input_names=['in_func', - 'in_roi', - 'realignment', - 'identity_matrix'], - output_names=['out_func', - 'out_roi'], - function=resample_func_roi, - as_module=True), - name=f'resample_functional_roi_' + resample_functional_roi = pe.Node(resample_function(), + name='resample_functional_roi_' f'{pipe_num}') - - resample_functional_roi.inputs.realignment = cfg.timeseries_extraction[ - 'realignment'] + realignment = cfg.timeseries_extraction['realignment'] + resample_functional_roi.inputs.realignment = realignment resample_functional_roi.inputs.identity_matrix = \ cfg.registration_workflows['functional_registration'][ 'func_registration_to_template']['FNIRT_pipelines']['identity_matrix'] @@ -809,11 +829,7 @@ def timeseries_extraction_AVG(wf, cfg, strat_pool, pipe_num, opt=None): #roi_timeseries.inputs.inputspec.output_type = cfg.timeseries_extraction[ # 'roi_tse_outputs'] - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") wf.connect(node, out, resample_functional_roi, 'in_func') wf.connect(roi_dataflow, 'outputspec.out_file', @@ -850,9 +866,26 @@ def timeseries_extraction_AVG(wf, cfg, strat_pool, pipe_num, opt=None): pipe_num=pipe_num ) brain_mask_node, brain_mask_out = strat_pool.get_data([ - 'space-template_desc-brain_bold']) - wf.connect(brain_mask_node, brain_mask_out, - timeseries_correlation, 'inputspec.mask') + 'space-template_desc-brain_mask']) + if 'func_to_ROI' in realignment: + resample_brain_mask_roi = pe.Node( + resample_function(), + name=f'resample_brain_mask_roi_{pipe_num}') + resample_brain_mask_roi.inputs.realignment = realignment + resample_brain_mask_roi.inputs.identity_matrix = ( + cfg.registration_workflows['functional_registration'][ + 'func_registration_to_template' + ]['FNIRT_pipelines']['identity_matrix']) + wf.connect([ + (brain_mask_node, resample_brain_mask_roi, [ + (brain_mask_out, 'in_func')]), + (roi_dataflow, resample_brain_mask_roi, [ + ('outputspec.out_file', 'in_roi')]), + (resample_brain_mask_roi, timeseries_correlation, [ + ('out_func', 'inputspec.mask')])]) + else: + wf.connect(brain_mask_node, brain_mask_out, + timeseries_correlation, 'inputspec.mask') timeseries_correlation.inputs.inputspec.method = cm_measure wf.connect([ @@ -864,11 +897,12 @@ def timeseries_extraction_AVG(wf, cfg, strat_pool, pipe_num, opt=None): output_desc = ''.join(term.lower().capitalize() for term in [ cm_measure, cm_tool]) - matrix_outputs[f'desc-{output_desc}_correlations'] = ( - timeseries_correlation, 'outputspec.out_file') + matrix_outputs[f'space-template_desc-{output_desc}_correlations' + ] = (timeseries_correlation, 'outputspec.out_file') outputs = { - 'desc-Mean_timeseries': (roi_timeseries, 'outputspec.roi_csv'), + 'space-template_desc-Mean_timeseries': ( + roi_timeseries, 'outputspec.roi_csv'), 'atlas_name': (roi_dataflow, 'outputspec.out_name'), **matrix_outputs } @@ -891,7 +925,8 @@ def timeseries_extraction_AVG(wf, cfg, strat_pool, pipe_num, opt=None): wf.connect(roi_timeseries, 'outputspec.roi_ts', ndmg_graph, 'ts') wf.connect(roi_dataflow, 'outputspec.out_file', ndmg_graph, 'labels') - outputs['desc-ndmg_correlations'] = (ndmg_graph, 'out_file') + outputs['space-template_desc-ndmg_correlations' + ] = (ndmg_graph, 'out_file') return (wf, outputs) @@ -903,24 +938,13 @@ def timeseries_extraction_Voxel(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]], + "inputs": ["space-template_desc-preproc_bold"], "outputs": ["desc-Voxel_timeseries", "atlas_name"]} ''' - resample_functional_to_mask = pe.Node(Function(input_names=['in_func', - 'in_roi', - 'realignment', - 'identity_matrix'], - output_names=['out_func', - 'out_roi'], - function=resample_func_roi, - as_module=True), - name=f'resample_functional_to_mask_' + resample_functional_to_mask = pe.Node(resample_function(), + name='resample_functional_to_mask_' f'{pipe_num}') resample_functional_to_mask.inputs.realignment = cfg.timeseries_extraction[ @@ -939,11 +963,7 @@ def timeseries_extraction_Voxel(wf, cfg, strat_pool, pipe_num, opt=None): # 'roi_tse_outputs'] - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") # resample the input functional file to mask wf.connect(node, out, resample_functional_to_mask, 'in_func') @@ -979,12 +999,8 @@ def spatial_regression(wf, cfg, strat_pool, pipe_num, opt=None): "switch": ["run"], "option_key": "None", "option_val": "None", - "inputs": [["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"], - "space-template_desc-bold_mask"], + "inputs": ["space-template_desc-preproc_bold", + "space-template_desc-bold_mask"], "outputs": ["desc-SpatReg_timeseries", "atlas_name"]} ''' @@ -1014,11 +1030,7 @@ def spatial_regression(wf, cfg, strat_pool, pipe_num, opt=None): f'spatial_map_timeseries_{pipe_num}') spatial_map_timeseries.inputs.inputspec.demean = True - node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_desc-preproc_bold", - "space-template_bold"]) + node, out = strat_pool.get_data("space-template_desc-preproc_bold") # resample the input functional file and functional mask # to spatial map diff --git a/CPAC/utils/__init__.py b/CPAC/utils/__init__.py index cfaa1b097f..c3d73c22b2 100755 --- a/CPAC/utils/__init__.py +++ b/CPAC/utils/__init__.py @@ -4,15 +4,8 @@ from . import build_data_config from .interfaces import function, masktool from .extract_data import run -from .datasource import create_anat_datasource -from .datasource import create_func_datasource -from .datasource import create_fmap_datasource -from .datasource import create_roi_mask_dataflow -from .datasource import create_grp_analysis_dataflow -from .datasource import create_spatial_map_dataflow -from .configuration import Configuration -from .strategy import Strategy -from .outputs import Outputs +from .datatypes import ListFromItem +from .configuration import check_pname, Configuration, set_subject from .utils import ( get_zscore, @@ -27,7 +20,6 @@ correlation, check, check_random_state, - cl_strip_brackets, try_fetch_parameter, get_scan_params, get_tr, @@ -42,6 +34,5 @@ repickle, ) -__all__ = [ - 'function' -] +__all__ = ['check_pname', 'Configuration', 'function', 'ListFromItem', + 'set_subject'] diff --git a/CPAC/utils/bids_utils.py b/CPAC/utils/bids_utils.py index 5e91585228..bfcfd94284 100755 --- a/CPAC/utils/bids_utils.py +++ b/CPAC/utils/bids_utils.py @@ -1,3 +1,19 @@ +# Copyright (C) 2016-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import json import os import re @@ -5,7 +21,6 @@ from warnings import warn import yaml -from CPAC.utils.utils import cl_strip_brackets def bids_decode_fname(file_path, dbg=False, raise_error=True): @@ -182,6 +197,32 @@ def bids_match_entities(file_list, entities, suffix): return matches +def bids_remove_entity(name, key): + """Remove an entity from a BIDS string by key + + Parameters + ---------- + name : str + BIDS string to remove entity from + key : str + BIDS key of entity to remove + + Returns + ------- + str + BIDS name with entity removed + + Examples + -------- + >>> bids_remove_entity('atlas-Yeo_space-MNI152NLin6_res-2x2x2', 'space') + 'atlas-Yeo_res-2x2x2' + >>> bids_remove_entity('atlas-Yeo_space-MNI152NLin6_res-2x2x2', 'res') + 'atlas-Yeo_space-MNI152NLin6' + """ + return '_'.join(entity for entity in bids_entities_from_filename(name) + if not entity.startswith(f'{key.rstrip("-")}-')) + + def bids_retrieve_params(bids_config_dict, f_dict, dbg=False): """ @@ -534,7 +575,6 @@ def bids_gen_cpac_sublist(bids_dir, paths_list, config_dict, creds_path, raise_error=raise_error) subdict = {} - for p in paths_list: if bids_dir in p: str_list = p.split(bids_dir) @@ -645,17 +685,17 @@ def bids_gen_cpac_sublist(bids_dir, paths_list, config_dict, creds_path, task_key, p)) - if "phasediff" in f_dict["scantype"]: + if "phase" in f_dict["scantype"]: if "fmap" not in subdict[f_dict["sub"]][f_dict["ses"]]: subdict[f_dict["sub"]][f_dict["ses"]]["fmap"] = {} - if "diffphase" not in subdict[f_dict["sub"]][f_dict["ses"]]["fmap"]: - subdict[f_dict["sub"]][f_dict["ses"]]["fmap"]["diffphase"] = task_info + if f_dict["scantype"] not in subdict[f_dict["sub"]][f_dict["ses"]]["fmap"]: + subdict[f_dict["sub"]][f_dict["ses"]]["fmap"][f_dict["scantype"]] = task_info - if "magnitude1" in f_dict["scantype"] or f_dict["scantype"] == "magnitude": + if "magnitude" in f_dict["scantype"]: if "fmap" not in subdict[f_dict["sub"]][f_dict["ses"]]: subdict[f_dict["sub"]][f_dict["ses"]]["fmap"] = {} - if "diffmag" not in subdict[f_dict["sub"]][f_dict["ses"]]["fmap"]: - subdict[f_dict["sub"]][f_dict["ses"]]["fmap"]["diffmag"] = task_info + if f_dict["scantype"] not in subdict[f_dict["sub"]][f_dict["ses"]]["fmap"]: + subdict[f_dict["sub"]][f_dict["ses"]]["fmap"][f_dict["scantype"]] = task_info if "epi" in f_dict["scantype"]: pe_dir = f_dict["dir"] @@ -702,8 +742,8 @@ def collect_bids_files_configs(bids_dir, aws_input_creds=''): file_paths = [] config_dict = {} - suffixes = ['T1w', 'T2w', 'bold', 'acq-fMRI_epi', 'phasediff', 'magnitude', - 'magnitude1', 'magnitude2'] + suffixes = ['T1w', 'T2w', 'bold', 'epi', 'phasediff', 'phase1', + 'phase2', 'magnitude', 'magnitude1', 'magnitude2'] if bids_dir.lower().startswith("s3://"): # s3 paths begin with s3://bucket/ @@ -724,6 +764,8 @@ def collect_bids_files_configs(bids_dir, aws_input_creds=''): for s3_obj in bucket.objects.filter(Prefix=prefix): for suf in suffixes: if suf in str(s3_obj.key): + if suf == 'epi' and 'acq-fMRI' not in s3_obj.key: + continue if str(s3_obj.key).endswith("json"): try: config_dict[s3_obj.key.replace(prefix, "") @@ -743,6 +785,8 @@ def collect_bids_files_configs(bids_dir, aws_input_creds=''): if files: for f in files: for suf in suffixes: + if suf == 'epi' and 'acq-fMRI' not in f: + continue if 'nii' in f and suf in f: file_paths += [os.path.join(root, f) .replace(bids_dir, '').lstrip('/')] @@ -767,6 +811,108 @@ def collect_bids_files_configs(bids_dir, aws_input_creds=''): return file_paths, config_dict +def camelCase(string: str) -> str: # pylint: disable=invalid-name + """Convert a hyphenated string to camelCase + + Paremeters + ---------- + string : str + string to convert to camelCase + + Returns + ------- + str + + Examples + -------- + >>> camelCase('PearsonNilearn-aCompCor') + 'PearsonNilearnACompCor' + >>> camelCase('mean-Pearson-Nilearn-aCompCor') + 'meanPearsonNilearnACompCor' + """ + pieces = string.split('-') + for i in range(1, len(pieces)): # don't change case of first piece + if pieces[i]: # don't do anything to falsy pieces + pieces[i] = f'{pieces[i][0].upper()}{pieces[i][1:]}' + return ''.join(pieces) + + +def combine_multiple_entity_instances(bids_str: str) -> str: + """Combines mutliple instances of a key in a BIDS string to a single + instance by camelCasing and concatenating the values + + Parameters + ---------- + bids_str : str + + Returns + ------- + str + + Examples + -------- + >>> combine_multiple_entity_instances( + ... 'sub-1_ses-HBN_site-RU_task-rest_atlas-AAL_' + ... 'desc-Nilearn_desc-36-param_suffix.ext') + 'sub-1_ses-HBN_site-RU_task-rest_atlas-AAL_desc-Nilearn36Param_suffix.ext' + >>> combine_multiple_entity_instances( + ... 'sub-1_ses-HBN_site-RU_task-rest_' + ... 'run-1_framewise-displacement-power.1D') + 'sub-1_ses-HBN_site-RU_task-rest_run-1_framewiseDisplacementPower.1D' + """ + _entity_list = bids_str.split('_') + entity_list = _entity_list[:-1] + suffixes = [camelCase(_entity_list[-1])] + entities = {} + for entity in entity_list: + if '-' in entity: + key, value = entity.split('-', maxsplit=1) + if key not in entities: + entities[key] = [] + entities[key].append(value) + for key, value in entities.items(): + entities[key] = camelCase('-'.join(value)) + if 'desc' in entities: # make 'desc' final entity + suffixes.insert(0, f'desc-{entities.pop("desc")}') + return '_'.join([f'{key}-{value}' for key, value in entities.items() + ] + suffixes) + + +def insert_entity(resource, key, value): + """Insert a `f'{key}-{value}'` BIDS entity before `desc-` if + present or before the suffix otherwise + + Parameters + ---------- + resource, key, value : str + + Returns + ------- + str + + Examples + -------- + >>> insert_entity('run-1_desc-preproc_bold', 'reg', 'default') + 'run-1_reg-default_desc-preproc_bold' + >>> insert_entity('run-1_bold', 'reg', 'default') + 'run-1_reg-default_bold' + >>> insert_entity('run-1_desc-preproc_bold', 'filt', 'notch4c0p31bw0p12') + 'run-1_filt-notch4c0p31bw0p12_desc-preproc_bold' + >>> insert_entity('run-1_reg-default_bold', 'filt', 'notch4c0p31bw0p12') + 'run-1_reg-default_filt-notch4c0p31bw0p12_bold' + """ + entities = resource.split('_')[:-1] + suff = resource.split('_')[-1] + new_entities = [[], []] + for entity in entities: + if entity.startswith('desc-'): + new_entities[1].append(entity) + else: + new_entities[0].append(entity) + return '_'.join([*new_entities[0], f'{key}-{value}', *new_entities[1], + suff]) + + def load_yaml_config(config_filename, aws_input_creds): if config_filename.lower().startswith('data:'): @@ -806,6 +952,32 @@ def load_yaml_config(config_filename, aws_input_creds): raise +def cl_strip_brackets(arg_list): + """Removes '[' from before first and ']' from after final + arguments in a list of commandline arguments + + Parameters + ---------- + arg_list : list + + Returns + ------- + list + + Examples + -------- + >>> cl_strip_brackets('[a b c]'.split(' ')) + ['a', 'b', 'c'] + >>> cl_strip_brackets('a b c'.split(' ')) + ['a', 'b', 'c'] + >>> cl_strip_brackets('[ a b c ]'.split(' ')) + ['a', 'b', 'c'] + """ + arg_list[0] = arg_list[0].lstrip('[') + arg_list[-1] = arg_list[-1].rstrip(']') + return [arg for arg in arg_list if arg] + + def create_cpac_data_config(bids_dir, participant_labels=None, aws_input_creds=None, skip_bids_validator=False, only_one_anat=True): @@ -914,6 +1086,51 @@ def load_cpac_data_config(data_config_file, participant_labels, return sub_list +def res_in_filename(cfg, label): + """Specify resolution in filename + + Parameters + ---------- + cfg : CPAC.utils.configuration.Configuration + + label : str + + Returns + ------- + label : str + + Examples + -------- + >>> from CPAC.utils.configuration import Configuration + >>> res_in_filename(Configuration({ + ... 'registration_workflows': { + ... 'anatomical_registration': {'resolution_for_anat': '2x2x2'}}}), + ... 'sub-1_res-anat_bold') + 'sub-1_res-2x2x2_bold' + >>> res_in_filename(Configuration({ + ... 'registration_workflows': { + ... 'anatomical_registration': {'resolution_for_anat': '2x2x2'}}}), + ... 'sub-1_res-3mm_bold') + 'sub-1_res-3mm_bold' + """ + if '_res-' in label: + # replace resolution text with actual resolution + resolution = label.split('_res-', 1)[1].split('_', 1)[0] + resolution = { + 'anat': cfg['registration_workflows', 'anatomical_registration', + 'resolution_for_anat'], + 'bold': cfg['registration_workflows', 'functional_registration', + 'func_registration_to_template', 'output_resolution', + 'func_preproc_outputs'], + 'derivative': cfg['registration_workflows', + 'functional_registration', + 'func_registration_to_template', + 'output_resolution', 'func_derivative_outputs'] + }.get(resolution, resolution) + label = re.sub('_res-[A-Za-z0-9]*_', f'_res-{resolution}_', label) + return label + + def sub_list_filter_by_labels(sub_list, labels): """Function to filter a sub_list by provided BIDS labels for specified suffixes @@ -941,6 +1158,56 @@ def sub_list_filter_by_labels(sub_list, labels): return sub_list +def with_key(entity: str, key: str) -> str: + """Return a keyed BIDS entity + + Parameters + ---------- + entity, key : str + + Returns + ------- + str + + Examples + -------- + >>> with_key('sub-1', 'sub') + 'sub-1' + >>> with_key('1', 'sub') + 'sub-1' + """ + if not isinstance(entity, str): + entity = str(entity) + if not entity.startswith(f'{key}-'): + entity = '-'.join((key, entity)) + return entity + + +def without_key(entity: str, key: str) -> str: + """Return a BIDS entity value + + Parameters + ---------- + entity, key : str + + Returns + ------- + str + + Examples + -------- + >>> without_key('sub-1', 'sub') + '1' + >>> without_key('1', 'sub') + '1' + """ + if not isinstance(entity, str): + entity = str(entity) + if entity.startswith(f'{key}-'): + entity = entity.replace(f'{key}-', '') + return entity + + def _t1w_filter(anat, shortest_entity, label): """Helper function to filter T1w paths diff --git a/CPAC/utils/build_data_config.py b/CPAC/utils/build_data_config.py index efd54ce669..f461c0a156 100755 --- a/CPAC/utils/build_data_config.py +++ b/CPAC/utils/build_data_config.py @@ -564,11 +564,11 @@ def get_BIDS_data_dct(bids_base_dir, file_list=None, anat_scan=None, fmap_pedir_sess = os.path.join(bids_base_dir, "sub-{participant}/ses-{session}/fmap/" "sub-{participant}_ses-{session}/" - "dir-*_acq-fMRI_epi.nii.gz") + "*acq-fMR*_epi.nii.gz") fmap_pedir = os.path.join(bids_base_dir, "sub-{participant}/fmap/sub-{participant}" - "_dir-*_acq-fMRI_epi.nii.gz") + "*acq-fMR*_epi.nii.gz") sess_glob = os.path.join(bids_base_dir, "sub-*/ses-*/*") @@ -582,7 +582,7 @@ def get_BIDS_data_dct(bids_base_dir, file_list=None, anat_scan=None, fmap_pedir_scan_glob = os.path.join(bids_base_dir, "sub-*fmap/" - "sub-*_dir-*_acq-fMRI_epi.nii.gz") + "sub-*_*acq-fMR*_epi.nii.gz") part_tsv_glob = os.path.join(bids_base_dir, "*participants.tsv") @@ -648,7 +648,7 @@ def get_BIDS_data_dct(bids_base_dir, file_list=None, anat_scan=None, fmap_mag = os.path.join(bids_base_dir, "sub-{participant}/fmap/sub-{participant}" "*magnitud*.nii.gz") - + ''' if fnmatch.fnmatch(filepath, fmap_pedir_scan_glob): # check if there is a scan level for the fmap magnitude files @@ -1652,51 +1652,44 @@ def get_nonBIDS_data(anat_template, func_template, file_list=None, def util_copy_template(template_type=None): """Copy the data settings YAML file template to the current directory.""" - import os import shutil import pkg_resources as p + from CPAC.utils.configuration import preconfig_yaml - if not template_type: - type = 'data_settings' - else: - type = template_type + template_type = "data_settings" if not template_type else template_type - settings_template = "/cpac_resources/default_pipeline.yml" if ( - type == "pipeline_config" - ) else p.resource_filename("CPAC", - os.path.join("resources", - "configs", - "{0}_template.yml".format(type))) + settings_template = preconfig_yaml('default') if ( + template_type == "pipeline_config" + ) else p.resource_filename("CPAC", os.path.join( + "resources", "configs", f"{template_type}_template.yml")) - settings_file = os.path.join(os.getcwd(), "{0}.yml".format(type)) + settings_file = os.path.join(os.getcwd(), f"{template_type}.yml") try: if os.path.exists(settings_file): settings_file = os.path.join(os.getcwd(), - "{0}_1.yml".format(type)) + f"{template_type}_1.yml") while os.path.exists(settings_file): idx = int( os.path.basename(settings_file).split("_")[2].replace( ".yml", "")) settings_file = os.path.join(os.getcwd(), - "{0}_{1}.yml".format( - type, idx + 1)) + f"{template_type}_{idx + 1}.yml") shutil.copy(settings_template, settings_file) - except: - err = "\n[!] Could not write the {0} file template " \ - "to the current directory.\n".format(type) - raise Exception(err) + except Exception as exception: + raise Exception(f"\n[!] Could not write the {template_type} file " + "template to the current directory.\n") from exception - print("\nGenerated a default {0} YAML file for editing:\n" \ - "{1}\n\n".format(type, settings_file)) + print(f"\nGenerated a default {template_type} YAML file for editing:\n" + f"{settings_file}\n\n") if type == 'data_settings': print("This file can be completed and entered into the C-PAC " - "command-line interface to generate a data configuration file " - "for individual-level analysis by running 'cpac utils " - "data_config build {data settings file}'.\nAdditionally, it can " - "also be loaded into the CPAC data configuration file builder UI " - "using the 'Load Preset' button.\n") + "command-line interface to generate a data configuration file " + "for individual-level analysis by running 'cpac utils " + "data_config build {data settings file}'.\nAdditionally, it can " + "also be loaded into the CPAC data configuration file builder " + "UI using the 'Load Preset' button.\n") elif type == 'pipeline_config': print("This file can be edited and then used in a C-PAC run by " "running 'cpac run --pipe_config {pipeline config file} " diff --git a/CPAC/utils/configuration/__init__.py b/CPAC/utils/configuration/__init__.py new file mode 100644 index 0000000000..654c18cff7 --- /dev/null +++ b/CPAC/utils/configuration/__init__.py @@ -0,0 +1,24 @@ +"""C-PAC Configuration module + +Copyright (C) 2022 C-PAC Developers + +This file is part of C-PAC. + +C-PAC is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +C-PAC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with C-PAC. If not, see .""" +from .configuration import check_pname, Configuration, Preconfiguration, \ + preconfig_yaml, set_subject +from . import configuration, diff + +__all__ = ['check_pname', 'Configuration', 'configuration', 'diff', + 'Preconfiguration', 'preconfig_yaml', 'set_subject'] diff --git a/CPAC/utils/configuration.py b/CPAC/utils/configuration/configuration.py similarity index 59% rename from CPAC/utils/configuration.py rename to CPAC/utils/configuration/configuration.py index 0645b8b228..864d7ee7ec 100755 --- a/CPAC/utils/configuration.py +++ b/CPAC/utils/configuration/configuration.py @@ -1,45 +1,42 @@ -"""C-PAC Configuration class""" -import re -import os -import warnings +"""C-PAC Configuration class and related functions -from itertools import repeat -from warnings import warn +Copyright (C) 2022 C-PAC Developers -import yaml +This file is part of C-PAC. +C-PAC is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +C-PAC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with C-PAC. If not, see .""" +import os +import re +from typing import Optional, Tuple +from warnings import warn +import pkg_resources as p +import yaml +from CPAC.surface.globals import DOUBLERUN_GUARD_MESSAGE from CPAC.utils.utils import load_preconfig +from .diff import dct_diff SPECIAL_REPLACEMENT_STRINGS = {r'${resolution_for_anat}', r'${func_resolution}'} -# Find default config -# in-container location -DEFAULT_PIPELINE_FILE = '/cpac_resources/default_pipeline.yml' -if not os.path.exists(DEFAULT_PIPELINE_FILE): - CPAC_DIRECTORY = os.path.abspath(os.path.join( - __file__, - *repeat(os.path.pardir, 3))) - # package location - DEFAULT_PIPELINE_FILE = os.path.join( - CPAC_DIRECTORY, - 'CPAC/resources/configs/default_pipeline.yml') - # source code (developer) location - if not os.path.exists(DEFAULT_PIPELINE_FILE): - DEFAULT_PIPELINE_FILE = os.path.join( - CPAC_DIRECTORY, - 'dev/docker_data/default_pipeline.yml') - del CPAC_DIRECTORY - -with open(DEFAULT_PIPELINE_FILE, 'r') as dp_fp: - default_config = yaml.safe_load(dp_fp) - class ConfigurationDictUpdateConflation(SyntaxError): + """Custom exception to clarify similar methods""" def __init__(self): self.msg = ( '`Configuration().update` requires a key and a value. ' 'Perhaps you meant `Configuration().dict().update`?') + super().__init__() class Configuration: @@ -72,7 +69,7 @@ class Configuration: -------- >>> c = Configuration({}) >>> c['pipeline_setup', 'pipeline_name'] - 'cpac-default-pipeline' + 'cpac-blank-template' >>> c = Configuration({'pipeline_setup': { ... 'pipeline_name': 'example_pipeline'}}) >>> c['pipeline_setup', 'pipeline_name'] @@ -84,27 +81,25 @@ class Configuration: def __init__(self, config_map=None): from click import BadParameter from CPAC.pipeline.schema import schema - from CPAC.utils.utils import load_preconfig, lookup_nested_value, \ - update_nested_dict + from CPAC.utils.utils import lookup_nested_value, update_nested_dict if config_map is None: config_map = {} - base_config = config_map.get('FROM', 'default_pipeline') - - # import another config (specified with 'FROM' key) - if base_config not in ['default', 'default_pipeline']: + base_config = config_map.pop('FROM', None) + if base_config: + if base_config.lower() in ['default', 'default_pipeline']: + base_config = 'default' + # import another config (specified with 'FROM' key) try: - base_config = load_preconfig(base_config) + base_config = Preconfiguration(base_config) except BadParameter: - pass - from_config = yaml.safe_load(open(base_config, 'r')) - config_map = update_nested_dict( - Configuration(from_config).dict(), config_map) - - # base everything on default pipeline - config_map = _enforce_forkability( - update_nested_dict(default_config, config_map)) + base_config = configuration_from_file(base_config) + config_map = update_nested_dict(base_config.dict(), config_map) + else: + # base everything on blank pipeline for unspecified keys + with open(preconfig_yaml('blank'), 'r', encoding='utf-8') as _f: + config_map = update_nested_dict(yaml.safe_load(_f), config_map) config_map = self._nonestr_to_None(config_map) @@ -127,8 +122,12 @@ def __init__(self, config_map=None): try: if 'FreeSurfer-ABCD' in config_map['anatomical_preproc'][ 'brain_extraction']['using']: - config_map['surface_analysis']['freesurfer']['run'] = False - except TypeError: + self.set_nested(config_map, + ['surface_analysis', 'freesurfer', + 'run_reconall'], + False) + warn(DOUBLERUN_GUARD_MESSAGE) + except (KeyError, TypeError): pass config_map = schema(config_map) @@ -147,19 +146,20 @@ def __init__(self, config_map=None): # set attribute setattr(self, key, set_from_ENV(config_map[key])) - self.__update_attr() + self._update_attr() def __str__(self): - return 'C-PAC Configuration' + return ('C-PAC Configuration ' + f"('{self['pipeline_setup', 'pipeline_name']}')") def __repr__(self): # show Configuration as a dict when accessed directly - return self.__str__() + return str(self.dict()) def __copy__(self): newone = type(self)({}) newone.__dict__.update(self.__dict__) - newone.__update_attr() + newone._update_attr() return newone def __getitem__(self, key): @@ -178,10 +178,49 @@ def __setitem__(self, key, value): else: self.key_type_error(key) + def __sub__(self: 'Configuration', other: 'Configuration'): + '''Return the set difference between two Configurations + + Examples + -------- + >>> diff = (Preconfiguration('fmriprep-options') + ... - Preconfiguration('default')) + >>> diff['pipeline_setup']['pipeline_name'] + ('cpac_fmriprep-options', 'cpac-default-pipeline') + >>> diff['pipeline_setup']['pipeline_name'].s_value + 'cpac_fmriprep-options' + >>> diff['pipeline_setup']['pipeline_name'].t_value + 'cpac-default-pipeline' + >>> diff.s_value['pipeline_setup']['pipeline_name'] + 'cpac_fmriprep-options' + >>> diff.t_value['pipeline_setup']['pipeline_name'] + 'cpac-default-pipeline' + >>> diff['pipeline_setup']['pipeline_name'].left + 'cpac_fmriprep-options' + >>> diff.left['pipeline_setup']['pipeline_name'] + 'cpac_fmriprep-options' + >>> diff['pipeline_setup']['pipeline_name'].minuend + 'cpac_fmriprep-options' + >>> diff.minuend['pipeline_setup']['pipeline_name'] + 'cpac_fmriprep-options' + >>> diff['pipeline_setup']['pipeline_name'].right + 'cpac-default-pipeline' + >>> diff.right['pipeline_setup']['pipeline_name'] + 'cpac-default-pipeline' + >>> diff['pipeline_setup']['pipeline_name'].subtrahend + 'cpac-default-pipeline' + >>> diff.subtrahend['pipeline_setup']['pipeline_name'] + 'cpac-default-pipeline' + ''' + return(dct_diff(self.dict(), other.dict())) + def dict(self): '''Show contents of a C-PAC configuration as a dict''' - return {k: self[k] for k in self.__dict__ if not callable( - self.__dict__[k])} + return {k: v for k, v in self.__dict__.items() if not callable(v)} + + def keys(self): + '''Show toplevel keys of a C-PAC configuration dict''' + return self.dict().keys() def _nonestr_to_None(self, d): '''Recursive method to type convert 'None' to None in nested @@ -249,14 +288,13 @@ def check_pattern(self, orig_key, tags=None): # method to find any pattern ($) in the configuration # and update the attributes with its pattern value - def __update_attr(self): + def _update_attr(self): def check_path(key): - if type(key) is str and '/' in key: + if isinstance(key, str) and '/' in key: if not os.path.exists(key): - warnings.warn( - "Invalid path- %s. Please check your configuration " - "file" % key) + warn(f"Invalid path- {key}. Please check your " + "configuration file") attributes = [(attr, getattr(self, attr)) for attr in dir(self) if not callable(attr) and not attr.startswith("__")] @@ -284,18 +322,20 @@ def update(self, key, val=ConfigurationDictUpdateConflation): setattr(self, key, val) def get_nested(self, d, keys): + if d is None: + d = {} if isinstance(keys, str): return d[keys] - elif isinstance(keys, tuple) or isinstance(keys, list): + if isinstance(keys, (list, tuple)): if len(keys) > 1: return self.get_nested(d[keys[0]], keys[1:]) - else: - return d[keys[0]] + return d[keys[0]] + return d - def set_nested(self, d, keys, value): + def set_nested(self, d, keys, value): # pylint: disable=invalid-name if isinstance(keys, str): d[keys] = value - elif isinstance(keys, tuple) or isinstance(keys, list): + elif isinstance(keys, (list, tuple)): if len(keys) > 1: d[keys[0]] = self.set_nested(d[keys[0]], keys[1:], value) else: @@ -311,6 +351,45 @@ def key_type_error(self, key): ])) +def check_pname(p_name: str, pipe_config: Configuration) -> str: + '''Function to check / set `p_name`, the string representation of a + pipeline for use in filetrees + + Parameters + ---------- + p_name : str or None + + pipe_config : Configuration + + Returns + ------- + p_name + + Examples + -------- + >>> c = Configuration() + >>> check_pname(None, c) + 'pipeline_cpac-blank-template' + >>> check_pname('cpac-default-pipeline', c) + 'pipeline_cpac-default-pipeline' + >>> check_pname('pipeline_cpac-default-pipeline', c) + 'pipeline_cpac-default-pipeline' + >>> check_pname('different-name', Configuration()) + 'pipeline_different-name' + >>> p_name = check_pname(None, Preconfiguration('blank')) + >>> p_name + 'pipeline_cpac-blank-template' + >>> p_name = check_pname(None, Preconfiguration('default')) + >>> p_name + 'pipeline_cpac-default-pipeline' + ''' + if p_name is None: + p_name = f'pipeline_{pipe_config["pipeline_setup", "pipeline_name"]}' + elif not p_name.startswith('pipeline_'): + p_name = f'pipeline_{p_name}' + return p_name + + def collect_key_list(config_dict): '''Function to return a list of lists of keys for a nested dictionary @@ -349,52 +428,30 @@ def configuration_from_file(config_file): ------- Configuration """ - with open(config_file, 'r') as config: + with open(config_file, 'r', encoding='utf-8') as config: return Configuration(yaml.safe_load(config)) -def _enforce_forkability(config_dict): - '''Function to set forkable booleans as lists of booleans. +def preconfig_yaml(preconfig_name='default', load=False): + """Get the path to a preconfigured pipeline's YAML file Parameters ---------- - config_dict : dict + preconfig_name : str + + load : boolean + return dict if True, str if False Returns ------- - config_dict : dict - - Examples - -------- - >>> c = Configuration().dict() - >>> c['functional_preproc']['despiking']['run'] - [False] - >>> c['functional_preproc']['despiking']['run'] = True - >>> c['functional_preproc']['despiking']['run'] - True - >>> _enforce_forkability(c)['functional_preproc']['despiking']['run'] - [True] - ''' - from CPAC.pipeline.schema import schema - from CPAC.utils.utils import lookup_nested_value, set_nested_value - - key_list_list = collect_key_list(config_dict) - for key_list in key_list_list: - try: - schema_check = lookup_nested_value(schema.schema, key_list) - except KeyError: - continue - if hasattr(schema_check, 'validators'): - schema_check = schema_check.validators - if bool in schema_check and [bool] in schema_check: - try: - value = lookup_nested_value(config_dict, key_list) - except KeyError: - continue - if isinstance(value, bool): - config_dict = set_nested_value( - config_dict, key_list, [value]) - return config_dict + str or dict + path to YAML file or dict loaded from YAML + """ + if load: + with open(preconfig_yaml(preconfig_name), 'r', encoding='utf-8') as _f: + return yaml.safe_load(_f) + return p.resource_filename("CPAC", os.path.join( + "resources", "configs", f"pipeline_config_{preconfig_name}.yml")) class Preconfiguration(Configuration): @@ -406,8 +463,7 @@ class Preconfiguration(Configuration): The canonical name of the preconfig to load """ def __init__(self, preconfig): - with open(load_preconfig(preconfig), 'r') as preconfig_yaml: - super().__init__(config_map=yaml.safe_load(preconfig_yaml)) + super().__init__(config_map=preconfig_yaml(preconfig, True)) def set_from_ENV(conf): # pylint: disable=invalid-name @@ -452,3 +508,55 @@ def set_from_ENV(conf): # pylint: disable=invalid-name conf = re.sub( _pattern, os.environ.get(_match, f'${_match}'), conf) return conf + + +def set_subject(sub_dict: dict, pipe_config: 'Configuration', + p_name: Optional[str] = None) -> Tuple[str, str, str]: + '''Function to set pipeline name and log directory path for a given + sub_dict + + Parameters + ---------- + sub_dict : dict + + pipe_config : CPAC.utils.configuration.Configuration + + p_name : str, optional + pipeline name string + + Returns + ------- + subject_id : str + + p_name : str + pipeline name string + + log_dir : str + path to subject log directory + + Examples + -------- + >>> from tempfile import TemporaryDirectory + >>> from CPAC.utils.configuration import Configuration + >>> sub_dict = {'site_id': 'site1', 'subject_id': 'sub1', + ... 'unique_id': 'uid1'} + >>> with TemporaryDirectory() as tmpdir: + ... subject_id, p_name, log_dir = set_subject( + ... sub_dict, Configuration({'pipeline_setup': {'log_directory': + ... {'path': tmpdir}}})) + >>> subject_id + 'sub1_uid1' + >>> p_name + 'pipeline_cpac-blank-template' + >>> log_dir.endswith(f'{p_name}/{subject_id}') + True + ''' + subject_id = sub_dict['subject_id'] + if sub_dict.get('unique_id'): + subject_id += f'_{sub_dict["unique_id"]}' + p_name = check_pname(p_name, pipe_config) + log_dir = os.path.join(pipe_config.pipeline_setup['log_directory']['path'], + p_name, subject_id) + if not os.path.exists(log_dir): + os.makedirs(os.path.join(log_dir)) + return subject_id, p_name, log_dir diff --git a/CPAC/utils/configuration/diff.py b/CPAC/utils/configuration/diff.py new file mode 100644 index 0000000000..bd45429cd9 --- /dev/null +++ b/CPAC/utils/configuration/diff.py @@ -0,0 +1,224 @@ +'''Tools for configuration differences + +Copyright (C) 2022 C-PAC Developers + +This file is part of C-PAC. + +C-PAC is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +C-PAC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with C-PAC. If not, see .''' + + +def dct_diff(dct1, dct2): + '''Function to compare 2 nested dicts, dropping values unspecified + in the second. Adapted from https://github.com/FCP-INDI/CPAC_regtest_pack/blob/9056ef63/cpac_pipe_diff.py#L31-L78 + + Parameters + ---------- + dct1 : dict or CPAC.utils.Configuration + + dct2 : dict or CPAC.utils.Configuration + + Returns + ------- + diff : dict + each value is a DiffValue of values from dct1, dct2 for each + differing key between original dicts or a subdictionary thereof + + Example + ------- + >>> import yaml + >>> from . import Preconfiguration, preconfig_yaml + >>> def read_yaml_file(yaml_file): + ... return yaml.safe_load(open(yaml_file, 'r')) + >>> pipeline = read_yaml_file(preconfig_yaml('default')) + >>> dct_diff(pipeline, pipeline) + {} + >>> pipeline2 = Preconfiguration('fmriprep-options') + >>> dct_diff(pipeline, pipeline2)['pipeline_setup']['pipeline_name'] + ('cpac-default-pipeline', 'cpac_fmriprep-options') + ''' # pylint: disable=line-too-long # noqa: E501 + dcts = [] + for _d in [dct1, dct2]: + if not isinstance(_d, dict): + try: + _d = _d.dict() + except AttributeError: + # pylint: disable=raise-missing-from + raise TypeError(f'{_d} is not a dict.') + dcts.append(_d) + dct1, dct2 = dcts # pylint: disable=unbalanced-tuple-unpacking + del dcts + diff = DiffDict() + for key, dct1_value in dct1.items(): + # handle parts of config where user-defined paths are keys + dct2_value = dct2.get(key, {}) if isinstance(dct2, dict) else None + if key.endswith('_roi_paths') and isinstance(dct1_value, dict): + paths1 = set(dct1_value.keys()) + paths2 = set(dct2_value.keys() if dct2_value else {}) + if paths1 != paths2: + diff[key] = DiffValue(dct1_value, dct2_value) + elif isinstance(dct1_value, dict): + diff[key] = dct_diff(dct1_value, dct2_value) + if diff[key] == {}: + del diff[key] + else: + if dct1_value != dct2_value: + diff[key] = DiffValue(dct1_value, dct2_value) + + # add any new keys + if isinstance(dct2, dict): + for key in dct2: + if key not in dct1: + diff[key] = dct2[key] + + return DiffDict(diff) + + +def diff_dict(diff): + '''Method to return a dict of only changes given a nested dict + of (dict1_value, dict2_value) tuples + + Parameters + ---------- + diff : dict + output of `dct_diff` + + Returns + ------- + dict + dict of only changed values + + Examples + -------- + >>> diff_dict({'anatomical_preproc': { + ... 'brain_extraction': {'extraction': { + ... 'run': DiffValue([True], False), + ... 'using': DiffValue(['3dSkullStrip'], + ... ['niworkflows-ants'])}}}}) + {'anatomical_preproc': {'brain_extraction': {'extraction': {'run': False, 'using': ['niworkflows-ants']}}}} + ''' # noqa: E501 # pylint: disable=line-too-long + if isinstance(diff, DiffValue): + return diff.t_value + if isinstance(diff, dict): + i = DiffDict() + for k, v in diff.items(): + try: + j = diff_dict(v) + if j != {}: + i[k] = j + except KeyError: + continue + return i + return diff + + +class DiffDict(dict): + '''Class to semantically store a dictionary of set differences from + Configuration(S) - Configuration(T) + + Attributes + ---------- + left : dict + dictionary of differing values from Configuration(S) + (alias for s_value) + + minuend : dict + dictionary of differing values from Configuration(S) + (alias for s_value) + + right : dict + dictionary of differing values from Configuration(T) + (alias for t_value) + + subtrahend : dict + dictionary of differing values from Configuration(T) + (alias for t_value) + + s_value : dict + dictionary of differing values from Configuration(S) + + t_value : dict + dictionary of differing values from Configuration(T) + ''' + def __init__(self, *args, **kwargs): + '''Dictionary of difference Configuration(S) - Configuration(T). + + Each value in a DiffDict should be either a DiffDict or a DiffValue. + ''' + super().__init__(*args, **kwargs) + self.left = self.minuend = self.s_value = self._s_value() + self.right = self.subtrahend = self.t_value = self._t_value() + + def _return_one_value(self, which_value): + return_dict = {} + for k, v in self.items(): + if isinstance(v, (DiffDict, DiffValue)): + return_dict[k] = getattr(v, which_value) + else: + return_dict[k] = v + return return_dict + + def _s_value(self): + '''Get a dictionary of only the differing 'S' values that differ + in S - T''' + return self._return_one_value('s_value') + + def _t_value(self): + '''Get a dictionary of only the differing 'T' values that differ + in S - T''' + return self._return_one_value('t_value') + + +class DiffValue: + '''Class to semantically store values of set difference from + Configuration(S) - Configuration(T) + + Attributes + ---------- + left : any + value from Configuration(S) (alias for s_value) + + minuend : dict + value from Configuration(S) (alias for s_value) + + right : dict + value from Configuration(T) (alias for t_value) + + subtrahend : dict + value from Configuration(T) (alias for t_value) + + s_value : any + value from Configuration(S) + + t_value : any + value from Configuration(T) + ''' + def __init__(self, s_value, t_value): + '''Different values from Configuration(S) - Configuration(T) + + Parameters + ---------- + s_value : any + value from Configuration(S) + + t_value : any + value from Configuration(T) + ''' + self.left = self.minuend = self.s_value = s_value + self.right = self.subtrahend = self.t_value = t_value + + def __len__(self): + return 2 # self.__repr__ should always be a 2-tuple + + def __repr__(self): + return str(tuple((self.s_value, self.t_value))) diff --git a/CPAC/utils/configuration/yaml_template.py b/CPAC/utils/configuration/yaml_template.py new file mode 100644 index 0000000000..539bac48a2 --- /dev/null +++ b/CPAC/utils/configuration/yaml_template.py @@ -0,0 +1,513 @@ +"""Copyright (C) 2022 C-PAC Developers + +This file is part of C-PAC. + +C-PAC is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +C-PAC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with C-PAC. If not, see .""" +from copy import deepcopy +import os +import re +from datetime import datetime +from hashlib import sha1 +import yaml +from CPAC.surface.globals import DOUBLERUN_GUARD_MESSAGE +from CPAC.utils.configuration import Configuration, Preconfiguration, \ + preconfig_yaml +from CPAC.utils.utils import set_nested_value, update_config_dict, \ + update_pipeline_values_1_8, YAML_BOOLS + +YAML_LOOKUP = {yaml_str: key for key, value in YAML_BOOLS.items() for + yaml_str in value} + + +class YamlTemplate(): # pylint: disable=too-few-public-methods + """A class to link YAML comments to the contents of a YAML file + + Attributes + ---------- + comments : dict + Flat dictionary with '.'-delimited pseudo-nested structure. + E.g., comments for ``{'pipeline_setup': {'pipeline_name': value}}`` + would be keyed ``{'pipeline_setup': comment0, + 'pipeline_setup.pipeline_name: comment1}`` to + allow comments at each level of depth. + + dump : method + + get_nested : method + + original : str + """ + def __init__(self, original_yaml, base_config=None): + """ + Parameters + ---------- + original_yaml : str + raw YAML or path to YAML file + + base_config : Configuration, optional + """ + preconfig_path = preconfig_yaml(original_yaml) + if os.path.exists(preconfig_path): + original_yaml = preconfig_path + if os.path.exists(original_yaml): + with open(original_yaml, 'r', encoding='utf-8') as _f: + original_yaml = _f.read() + self.comments = {} + self.template = original_yaml + if base_config is None: + self._dict = yaml.safe_load(self.template) + else: + self._dict = base_config.dict() + self._parse_comments() + + get_nested = Configuration.get_nested + + def dump(self, new_dict, parents=None): + """Dump a YAML file from a new dictionary with the comments from + the template dictionary + + Parameters + ---------- + new_dict : dict + + parents : list of str + + Returns + ------- + str + """ + # Initialize variable for automatically updated value + if parents == ['surface_analysis', 'freesurfer'] or parents is None: + freesurfer_extraction = False + try: + brain_extractions = self.get_nested( + new_dict, ['anatomical_preproc', 'brain_extraction', + 'using']) + except KeyError: + brain_extractions = [] + if (brain_extractions is not None and + 'FreeSurfer-ABCD' in brain_extractions): + freesurfer_extraction = True + # SSOT FSLDIR + try: # Get from current config + fsldir = self.get_nested(new_dict, + ['pipeline_setup', 'system_config', + 'FSLDIR']) + except KeyError: # Get from imported base + fsldir = self.get_nested(self._dict, + ['pipeline_setup', 'system_config', + 'FSLDIR']) + + # Add YAML version directive to top of document and ensure + # C-PAC version comment and 'FROM' are at the top of the YAML + # output + if parents is None: + parents = [] + _dump = ['%YAML 1.1', '---'] + if 'pipeline_setup' not in new_dict: + new_dict['pipeline_setup'] = None + # Insert automatically-changed value in original dict + if freesurfer_extraction: + new_dict = set_nested_value( + new_dict, ['surface_analysis', 'freesurfer', + 'run_reconall'], False) + ingress_keys = ['surface_analysis', 'freesurfer', 'ingress_reconall'] + try: + self.get_nested(new_dict, ingress_keys) + except KeyError: + new_dict = set_nested_value(new_dict, ingress_keys, + self.get_nested(self._dict, ingress_keys)) + else: + _dump = [] + # Prepare for indentation + line_level = len(parents) + # Get a safely mutable copy of the dict + loop_dict = deepcopy(self.get_nested(new_dict, parents) if + parents else new_dict) + # Grab special key to print first + import_from = loop_dict.pop('FROM', None) + # Iterate through mutated dict + for key in loop_dict: + # List of progressively-indented key strings + keys = [*parents, key] + # Comments are stored in a flat dictionary with + # '.'-delimited pseudonested keys + comment = self.comments.get('.'.join(keys)) + # This exception should only happen from mutations + # introduced this function + try: + value = self.get_nested(new_dict, keys) + except KeyError: # exclude unincluded keys + continue + # Add comment for automatically changed value + if (keys == ['surface_analysis', 'freesurfer', 'run_reconall'] and + freesurfer_extraction): + if comment is None: + comment = [] + comment.append(f'# {DOUBLERUN_GUARD_MESSAGE}') + # Print comment if there's one above this key in the template + if comment: + if key != 'pipeline_setup': + _dump += [''] # Add a blank line above the comment + _dump += [indent(line_level, 0) + line for line in comment] + # Print 'FROM' between preamble comment and rest of config + # if applicable + if key == 'pipeline_setup' and import_from is not None: + _dump += [f'FROM: {import_from}', ''] + # Apply indentation to key + indented_key = f'{indent(line_level, 0)}{key}:' + # Print YAML-formatted value + if value is not None: + # SSOT FSLDIR + if (isinstance(value, str) and fsldir in value and + key != 'FSLDIR'): + value = re.sub(r'\$*FSLDIR', '$FSLDIR', + value.replace(fsldir, '$FSLDIR')) + if isinstance(value, dict): + _dump += [indented_key, self.dump(new_dict, keys)] + elif isinstance(value, list): + list_line = _format_list_items(value, line_level) + if '\n' in list_line: + _dump += [indented_key, *list_line.split('\n')] + else: + _dump += [f'{indented_key} {list_line}'] + elif isinstance(value, bool) or (isinstance(value, str) and + value.lower() in YAML_LOOKUP): + if isinstance(value, str): + value = YAML_LOOKUP[value.lower()] + value = 'On' if value is True else 'Off' + _dump += [f'{indented_key} {value}'] + else: + _dump += [f'{indented_key} {value}'] + elif key != 'pipeline_setup': + _dump += [indented_key] + # Normalize line spacing and return YAML string + return re.sub('\n{3,}', '\n\n', '\n'.join(_dump)).rstrip() + '\n' + + def _parse_comments(self): + # Split YAML into lines + yaml_lines = self.template.split('\n') + # Initialize comment and key + comment = [] + key = [] + for line in yaml_lines: + # Calculate indentation + line_level = _count_indent(line) + # Remove indentation and trailing whitespace + stripped_line = line.strip() + # Collect a line of a comment + if stripped_line.startswith('#'): + comment.append(stripped_line) + # If a line is not a comment line: + elif not any(stripped_line.startswith(seq) for + seq in ('%YAML', '---')): + # If the line is a key + if ':' in stripped_line: + # Set the key for the comments dictionary + line_key = stripped_line.split(':', 1)[0].strip() + if line_level == 0: + key = [line_key] + else: + key = [*key[:line_level], line_key] + # Store the full list of comment lines + self.comments['.'.join(key)] = comment + # Reset the comment variable to collect the next comment + comment = [] + + +def _count_indent(line): + '''Helper method to determine indentation level + + Parameters + ---------- + line : str + + Returns + ------- + number_of_indents : int + + Examples + -------- + >>> _count_indent('No indent') + 0 + >>> _count_indent(' Four spaces') + 2 + ''' + return (len(line) - len(line.lstrip())) // 2 + + +def create_yaml_from_template(d, # pylint: disable=invalid-name + template='default', import_from=None): + """Save dictionary to a YAML file, keeping the structure + (such as first level comments and ordering) from the template + + It may not be fully robust to YAML structures, but it works + for C-PAC config files! + + Parameters + ---------- + d : dict or Configuration + + template : str + path to template, name of preconfig, or YAML as a string + + import_from : str, optional + name of a preconfig. Full config is generated if omitted + + Examples + -------- + >>> import yaml + >>> from CPAC.utils.configuration import Configuration, Preconfiguration + >>> Configuration(yaml.safe_load(create_yaml_from_template({}))).dict( + ... ) == Configuration({}).dict() + True + >>> fmriprep_options = Preconfiguration('fmriprep-options') + >>> fmriprep_options - Configuration({}) != {} + True + >>> fmriprep_options - fmriprep_options + {} + >>> fmriprep_options - Preconfiguration('fmriprep-options') + {} + >>> fmriprep_options - Configuration({'FROM': 'fmriprep-options'}) + {} + >>> fmriprep_options - Configuration(yaml.safe_load( + ... create_yaml_from_template(fmriprep_options, import_from=None))) + {} + >>> fmriprep_options - Configuration(yaml.safe_load( + ... create_yaml_from_template(fmriprep_options, + ... import_from='default'))) + {} + >>> fmriprep_options - Configuration(yaml.safe_load( + ... create_yaml_from_template(fmriprep_options, import_from='blank'))) + {} + >>> different_sca = Configuration({'pipeline_setup': { + ... 'pipeline_name': 'different_SCA'}, + ... 'seed_based_correlation_analysis': {'run': 'y', + ... 'norm_timeseries_for_DR': 'Off'}}) + >>> (Configuration(yaml.safe_load(create_yaml_from_template( + ... different_sca))) - Configuration()).get( + ... 'seed_based_correlation_analysis') not in (None, {}) + True + """ + if import_from is None: # full config + d = d.dict() if isinstance(d, Configuration) else d + base_config = None + else: # config based on preconfig + d = Configuration(d) if not isinstance(d, Configuration) else d + base_config = Preconfiguration(import_from) + d = (d - base_config).left + d.update({'FROM': import_from}) + yaml_template = YamlTemplate(template, base_config) + return yaml_template.dump(new_dict=d) + + +def _format_list_items(l, # noqa: E741 # pylint:disable=invalid-name + line_level): + '''Helper method to handle lists in the YAML + + Parameters + ---------- + l : list + + line_level : int + + Returns + ------- + yaml : str + + Examples + -------- + >>> print(_format_list_items([1, 2, {'nested': 3}], 0)) + - 1 + - 2 + - nested: 3 + >>> print( + ... _format_list_items([1, 2, {'nested': [3, {'deep': [4]}]}], 1)) + - 1 + - 2 + - nested: + - 3 + - deep: + - 4 + ''' + # keep short, simple lists in square brackets + if all(isinstance(item, (str, bool, int, float)) for item in l): + preformat = str([yaml_bool(item) for item in l]) + if len(preformat) < 50: + return preformat.replace("'", '').replace('"', '') + # list long or complex lists on lines with indented '-' lead-ins + return '\n'.join([ + f'{indent(line_level)}{li}' for li in yaml.dump( + yaml_bool(l), sort_keys=False + ).replace("'On'", 'On').replace("'Off'", 'Off').split('\n') + ]).rstrip() + + +def hash_data_config(sub_list): + '''Function to generate a short SHA1 hash from a data config + subject list of dicts + + Parameters + ---------- + sub_list : list of dicts + + Returns + ------- + data_config_hash : str, len(8) + + Examples + -------- + >>> sub_list = [{'site_id': f'site{i}', 'subject_id': f'sub{i}', + ... 'unique_id': f'uid{i}'} for i in range(1, 4)] + >>> sub_list[0] + {'site_id': 'site1', 'subject_id': 'sub1', 'unique_id': 'uid1'} + >>> hash_data_config(sub_list) + '6f49a278' + ''' + return sha1('_'.join([','.join([run.get(key, '') for run in sub_list]) for + key in ['site_id', 'subject_id', + 'unique_id']]).encode('utf-8')).hexdigest()[:8] + + +def indent(line_level, plus=2): + '''Function to return an indent string for a given level + + Parameters + ---------- + line_level : int + The level of indentation to return + + Returns + ------- + str + The string of spaces to use for indentation + ''' + return " " * (2 * line_level + plus) + + +def yaml_bool(value): + '''Helper function to give On/Off value to bools + + Parameters + ---------- + value : any + + Returns + ------- + value : any + + Examples + -------- + >>> yaml_bool(True) + 'On' + >>> yaml_bool([False, 'On', True]) + ['Off', 'On', 'On'] + ''' + if isinstance(value, str): + lookup_value = value.lower() + if lookup_value in YAML_LOOKUP: + value = YAML_LOOKUP[lookup_value] + elif isinstance(value, list): + return [yaml_bool(item) for item in value] + elif isinstance(value, dict): + # if 'Name' is a key, promote that item to the top + return {**({'Name': value['Name']} if 'Name' in value else {}), + **{k: yaml_bool(value[k]) for k in value if k != 'Name'}} + if isinstance(value, bool): + if value is True: + return 'On' + return 'Off' + return value + + +def upgrade_pipeline_to_1_8(path): + '''Function to upgrade a C-PAC 1.7 pipeline config to C-PAC 1.8 + + Parameters + ---------- + path : str + + Returns + ------- + None + + Outputs + ------- + {path}.{now}.bak + original file + + path + upgraded file + ''' + # back up original config + now = datetime.isoformat(datetime.now()).replace(':', '_') + backup = f'{path}.{now}.bak' + print(f'Backing up {path} to {backup} and upgrading to C-PAC 1.8') + with open(path, 'r', encoding='utf-8') as _f: + original = _f.read() + with open(backup, 'w', encoding='utf-8') as _f: + _f.write(original) + # upgrade and overwrite + orig_dict = yaml.safe_load(original) + # set Regressor 'Name's if not provided + regressors = orig_dict.get('Regressors') + if isinstance(regressors, list): + for i, regressor in enumerate(regressors): + if 'Name' not in regressor: + regressor['Name'] = f'Regressor-{str(i + 1)}' + if 'pipelineName' in orig_dict and len(original.strip()): + middle_dict, leftovers_dict, _complete_dict = update_config_dict( + orig_dict) + with open(path, 'w', encoding='utf-8') as _f: + _f.write(create_yaml_from_template( + update_pipeline_values_1_8(middle_dict))) + if leftovers_dict: + with open(f'{path}.rem', 'w', encoding='utf-8') as _f: + _f.write(yaml.dump(leftovers_dict)) + + +def update_a_preconfig(preconfig, import_from): + """ + Parameters + ---------- + preconfig : str + + import_from : str + """ + import sys + print(f'Updating {preconfig} preconfig…', file=sys.stderr) + updated = create_yaml_from_template(Preconfiguration(preconfig), + import_from=import_from) + with open(preconfig_yaml(preconfig), 'w', encoding='utf-8') as _f: + _f.write(updated) + + +def update_all_preconfigs(): + """Update all other preconfigs with comments from default""" + from CPAC.pipeline import ALL_PIPELINE_CONFIGS + not_from_blank = ('anat-only', 'blank', 'default', 'fx-options', + 'nhp-macaque', 'preproc', 'rbc-options') + update_a_preconfig('blank', None) + for preconfig in ('anat-only', 'preproc'): + update_a_preconfig(preconfig, 'default') + for preconfig in ('fx-options', 'rbc-options'): + update_a_preconfig(preconfig, 'fmriprep-options') + update_a_preconfig('nhp-macaque', 'monkey') + for preconfig in (_ for _ in ALL_PIPELINE_CONFIGS if + _ not in not_from_blank): + update_a_preconfig(preconfig, 'blank') + + +if __name__ == '__main__': + update_all_preconfigs() diff --git a/CPAC/utils/datasource.py b/CPAC/utils/datasource.py index bb660d1ab7..57793faa03 100755 --- a/CPAC/utils/datasource.py +++ b/CPAC/utils/datasource.py @@ -1,12 +1,30 @@ +# Copyright (C) 2012-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import csv import json -import nipype.interfaces.utility as util +import re +from typing import Tuple from nipype import logging -# pylint: disable=ungrouped-imports, wrong-import-order +from nipype.interfaces import utility as util from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.afni as afni - +from CPAC.resources.templates.lookup_table import format_identifier, \ + lookup_identifier from CPAC.utils import function +from CPAC.utils.bids_utils import bids_remove_entity from CPAC.utils.interfaces.function import Function from CPAC.utils.utils import get_scan_params @@ -327,25 +345,49 @@ def create_fmap_datasource(fmap_dct, wf_name='fmap_datasource'): def get_fmap_phasediff_metadata(data_config_scan_params): - if not isinstance(data_config_scan_params, dict) and \ - ".json" in data_config_scan_params: - with open(data_config_scan_params, 'r') as f: - data_config_scan_params = json.load(f) - - echo_time = data_config_scan_params.get("EchoTime") + if (not isinstance(data_config_scan_params, dict) and + ".json" in data_config_scan_params): + with open(data_config_scan_params, 'r', encoding='utf-8') as _f: + data_config_scan_params = json.load(_f) + + echo_time = None + echo_time_one = None + echo_time_two = None + if "EchoTime" in data_config_scan_params: + echo_time = data_config_scan_params.get("EchoTime") + elif "EchoTime1" in data_config_scan_params and "EchoTime2" \ + in data_config_scan_params: + echo_time_one = data_config_scan_params.get("EchoTime1") + echo_time_two = data_config_scan_params.get("EchoTime2") dwell_time = data_config_scan_params.get("DwellTime") pe_direction = data_config_scan_params.get("PhaseEncodingDirection") + total_readout = data_config_scan_params.get("TotalReadoutTime") + + return (dwell_time, pe_direction, total_readout, echo_time, + echo_time_one, echo_time_two) + + +def calc_delta_te_and_asym_ratio(effective_echo_spacing: float, + echo_times: list) -> Tuple[float, float]: + """Calcluate ``deltaTE`` and ``ees_asym_ratio`` from given metadata + + Parameters + ---------- + effective_echo_spacing : float + EffectiveEchoSpacing from sidecar JSON - return (echo_time, dwell_time, pe_direction) + echo_times : list + Returns + ------- + deltaTE : float -def calc_deltaTE_and_asym_ratio(dwell_time, echo_time_one, echo_time_two, - echo_time_three=None): - echo_times = [echo_time_one, echo_time_two] - if echo_time_three: - # get only the two different ones - echo_times = list(dict.fromkeys([echo_time_one, echo_time_two, - echo_time_three])) + ees_asym_ratio : float + """ + if not isinstance(effective_echo_spacing, float): + raise LookupError('C-PAC could not find `EffectiveEchoSpacing` in ' + 'either fmap or func sidecar JSON, but that field ' + 'is required for PhaseDiff distortion correction.') # convert into milliseconds if necessary # these values will/should never be more than 10ms @@ -354,9 +396,19 @@ def calc_deltaTE_and_asym_ratio(dwell_time, echo_time_one, echo_time_two, echo_times[1] = echo_times[1] * 1000 deltaTE = abs(echo_times[0] - echo_times[1]) - dwell_asym_ratio = (dwell_time / deltaTE) + ees_asym_ratio = (effective_echo_spacing / deltaTE) + return deltaTE, ees_asym_ratio - return (deltaTE, dwell_asym_ratio) + +def gather_echo_times(echotime_1, echotime_2, echotime_3=None, echotime_4=None): + echotime_list = [echotime_1, echotime_2, echotime_3, echotime_4] + echotime_list = list(filter(lambda item: item is not None, echotime_list)) + echotime_list = list(set(echotime_list)) + if len(echotime_list) != 2: + raise Exception("\n[!] Something went wrong with the field map echo " + "times - there should be two distinct values.\n\n" + f"Echo Times:\n{echotime_list}\n") + return echotime_list def match_epi_fmaps(bold_pedir, epi_fmap_one, epi_fmap_params_one, @@ -405,24 +457,24 @@ def match_epi_fmaps(bold_pedir, epi_fmap_one, epi_fmap_params_one, def ingress_func_metadata(wf, cfg, rpool, sub_dict, subject_id, - input_creds_path, unique_id=None): + input_creds_path, unique_id=None, num_strat=None): + name_suffix = '' + for suffix_part in (unique_id, num_strat): + if suffix_part is not None: + name_suffix += f'_{suffix_part}' # Grab field maps diff = False blip = False fmap_rp_list = [] fmap_TE_list = [] - if "fmap" in sub_dict: second = False for key in sub_dict["fmap"]: - gather_fmap = create_fmap_datasource(sub_dict["fmap"], - f"fmap_gather_{key}_" - f"{subject_id}") + gather_fmap = create_fmap_datasource( + sub_dict["fmap"], f"fmap_gather_{key}_{subject_id}") gather_fmap.inputs.inputnode.set( - subject=subject_id, - creds_path=input_creds_path, - dl_dir=cfg.pipeline_setup['working_directory']['path'] - ) + subject=subject_id, creds_path=input_creds_path, + dl_dir=cfg.pipeline_setup['working_directory']['path']) gather_fmap.inputs.inputnode.scan = key orig_key = key @@ -443,95 +495,115 @@ def ingress_func_metadata(wf, cfg, rpool, sub_dict, subject_id, get_fmap_metadata_imports = ['import json'] get_fmap_metadata = pe.Node(Function( input_names=['data_config_scan_params'], - output_names=['echo_time', - 'dwell_time', - 'pe_direction'], + output_names=['dwell_time', + 'pe_direction', + 'total_readout', + 'echo_time', + 'echo_time_one', + 'echo_time_two'], function=get_fmap_phasediff_metadata, imports=get_fmap_metadata_imports), - name=f'{key}_get_metadata') + name=f'{key}_get_metadata{name_suffix}') wf.connect(gather_fmap, 'outputspec.scan_params', get_fmap_metadata, 'data_config_scan_params') - rpool.set_data(f'{key}-TE', get_fmap_metadata, 'echo_time', - {}, "", "fmap_TE_ingress") + if "phase" in key: + # leave it open to all three options, in case there is a + # phasediff image with either a single EchoTime field (which + # usually matches one of the magnitude EchoTimes), OR + # a phasediff with an EchoTime1 and EchoTime2 + + # at least one of these rpool keys will have a None value, + # which will be sorted out in gather_echo_times below + rpool.set_data(f'{key}-TE', get_fmap_metadata, 'echo_time', + {}, "", "fmap_TE_ingress") + fmap_TE_list.append(f"{key}-TE") + + rpool.set_data(f'{key}-TE1', + get_fmap_metadata, 'echo_time_one', + {}, "", "fmap_TE1_ingress") + fmap_TE_list.append(f"{key}-TE1") + + rpool.set_data(f'{key}-TE2', + get_fmap_metadata, 'echo_time_two', + {}, "", "fmap_TE2_ingress") + fmap_TE_list.append(f"{key}-TE2") + + elif "magnitude" in key: + rpool.set_data(f'{key}-TE', get_fmap_metadata, 'echo_time', + {}, "", "fmap_TE_ingress") + fmap_TE_list.append(f"{key}-TE") + rpool.set_data(f'{key}-dwell', get_fmap_metadata, 'dwell_time', {}, "", "fmap_dwell_ingress") rpool.set_data(f'{key}-pedir', get_fmap_metadata, 'pe_direction', {}, "", "fmap_pedir_ingress") + rpool.set_data(f'{key}-total-readout', get_fmap_metadata, + 'total_readout', {}, "", "fmap_readout_ingress") - fmap_TE_list.append(f"{key}-TE") - - keywords = ['diffphase', 'diffmag'] - if key in keywords: + if 'phase' in key or 'mag' in key: diff = True - if orig_key == "epi_AP" or orig_key == "epi_PA": + if re.match('epi_[AP]{2}', orig_key): blip = True if diff: calc_delta_ratio = pe.Node(Function( - input_names=['dwell_time', - 'echo_time_one', - 'echo_time_two', - 'echo_time_three'], + input_names=['effective_echo_spacing', + 'echo_times'], output_names=['deltaTE', - 'dwell_asym_ratio'], - function=calc_deltaTE_and_asym_ratio), - name='diff_distcor_calc_delta') - - node, out_file = rpool.get('diffphase-dwell')[ - "['diffphase-dwell:fmap_dwell_ingress']"]['data'] # <--- there will only be one pipe_idx - wf.connect(node, out_file, calc_delta_ratio, 'dwell_time') - - node, out_file = rpool.get(f'{fmap_TE_list[0]}')[ - f"['{fmap_TE_list[0]}:fmap_TE_ingress']"]['data'] - wf.connect(node, out_file, calc_delta_ratio, 'echo_time_one') - - node, out_file = rpool.get(f'{fmap_TE_list[1]}')[ - f"['{fmap_TE_list[1]}:fmap_TE_ingress']"]['data'] - wf.connect(node, out_file, calc_delta_ratio, 'echo_time_two') - - if len(fmap_TE_list) > 2: - node, out_file = rpool.get(f'{fmap_TE_list[2]}')[ - f"['{fmap_TE_list[2]}:fmap_TE_ingress']"]['data'] - wf.connect(node, out_file, - calc_delta_ratio, 'echo_time_three') - - rpool.set_data('deltaTE', calc_delta_ratio, 'deltaTE', {}, "", - "deltaTE_ingress") - rpool.set_data('dwell-asym-ratio', - calc_delta_ratio, 'dwell_asym_ratio', {}, "", - "dwell_asym_ratio_ingress") + 'ees_asym_ratio'], + function=calc_delta_te_and_asym_ratio, + imports=['from typing import Optional, Tuple']), + name=f'diff_distcor_calc_delta{name_suffix}') + + gather_echoes = pe.Node(Function( + input_names=['echotime_1', + 'echotime_2', + 'echotime_3', + 'echotime_4'], + output_names=['echotime_list'], + function=gather_echo_times), + name='fugue_gather_echo_times') + + for idx, fmap_file in enumerate(fmap_TE_list, start=1): + try: + node, out_file = rpool.get(fmap_file)[ + f"['{fmap_file}:fmap_TE_ingress']"]['data'] + wf.connect(node, out_file, gather_echoes, + f'echotime_{idx}') + except KeyError: + pass + + wf.connect(gather_echoes, 'echotime_list', + calc_delta_ratio, 'echo_times') # Add in nodes to get parameters from configuration file # a node which checks if scan_parameters are present for each scan - scan_params_imports = ['from CPAC.utils.utils import check, ' - 'try_fetch_parameter'] - scan_params = \ - pe.Node(Function( - input_names=['data_config_scan_params', - 'subject_id', - 'scan', - 'pipeconfig_tr', - 'pipeconfig_tpattern', - 'pipeconfig_start_indx', - 'pipeconfig_stop_indx'], - output_names=['tr', - 'tpattern', - 'ref_slice', - 'start_indx', - 'stop_indx', - 'pe_direction'], - function=get_scan_params, - imports=scan_params_imports - ), name=f"bold_scan_params_{subject_id}_{unique_id}") + scan_params = pe.Node(Function( + input_names=['data_config_scan_params', + 'subject_id', + 'scan', + 'pipeconfig_tr', + 'pipeconfig_tpattern', + 'pipeconfig_start_indx', + 'pipeconfig_stop_indx'], + output_names=['tr', + 'tpattern', + 'ref_slice', + 'start_indx', + 'stop_indx', + 'pe_direction', + 'effective_echo_spacing'], + function=get_scan_params, + imports=['from CPAC.utils.utils import check, try_fetch_parameter'] + ), name=f"bold_scan_params_{subject_id}{name_suffix}") scan_params.inputs.subject_id = subject_id scan_params.inputs.set( pipeconfig_start_indx=cfg.functional_preproc['truncation'][ 'start_tr'], - pipeconfig_stop_indx=cfg.functional_preproc['truncation']['stop_tr'] - ) + pipeconfig_stop_indx=cfg.functional_preproc['truncation']['stop_tr']) # wire in the scan parameter workflow node, out = rpool.get('scan-params')[ @@ -551,7 +623,21 @@ def ingress_func_metadata(wf, cfg, rpool, sub_dict, subject_id, rpool.set_data('pe-direction', scan_params, 'pe_direction', {}, "", "func_metadata_ingress") - return (wf, rpool, diff, blip, fmap_rp_list) + if diff: + # Connect EffectiveEchoSpacing from functional metadata + rpool.set_data('effectiveEchoSpacing', scan_params, + 'effective_echo_spacing', {}, '', + 'func_metadata_ingress') + node, out_file = rpool.get('effectiveEchoSpacing')[ + "['effectiveEchoSpacing:func_metadata_ingress']"]['data'] + wf.connect(node, out_file, calc_delta_ratio, 'effective_echo_spacing') + rpool.set_data('deltaTE', calc_delta_ratio, 'deltaTE', {}, '', + 'deltaTE_ingress') + rpool.set_data('ees-asym-ratio', calc_delta_ratio, + 'ees_asym_ratio', {}, '', + 'ees_asym_ratio_ingress') + + return wf, rpool, diff, blip, fmap_rp_list def create_general_datasource(wf_name): @@ -836,7 +922,7 @@ def res_string_to_tuple(resolution): def resolve_resolution(resolution, template, template_name, tag=None): - import nipype.interfaces.afni as afni + from nipype.interfaces import afni from CPAC.pipeline import nipype_pipeline_engine as pe from CPAC.utils.datasource import check_for_s3 @@ -932,33 +1018,39 @@ def create_roi_mask_dataflow(masks, wf_name='datasource_roi_mask'): if mask_file.strip() == '' or mask_file.startswith('#'): continue - base_file = os.path.basename(mask_file) + name, desc = lookup_identifier(mask_file) - try: - valid_extensions = ['.nii', '.nii.gz'] + if name == 'template': + base_file = os.path.basename(mask_file) - base_name = [ - base_file[:-len(ext)] - for ext in valid_extensions - if base_file.endswith(ext) - ][0] + try: + valid_extensions = ['.nii', '.nii.gz'] - if base_name in mask_dict: - raise ValueError( - 'Files with same name not allowed: %s %s' % ( - mask_file, - mask_dict[base_name] - ) - ) + base_name = [ + base_file[:-len(ext)] + for ext in valid_extensions + if base_file.endswith(ext) + ][0] - mask_dict[base_name] = mask_file + for key in ['res', 'space']: + base_name = bids_remove_entity(base_name, key) - except IndexError as e: - raise Exception('Error in spatial_map_dataflow: ' - 'File extension not in .nii and .nii.gz') + except IndexError: + # pylint: disable=raise-missing-from + raise ValueError('Error in spatial_map_dataflow: File ' + f'extension of {base_file} not ".nii" or ' + '.nii.gz') + + except Exception as e: + raise e + else: + base_name = format_identifier(name, desc) + + if base_name in mask_dict: + raise ValueError('Duplicate templates/atlases not allowed: ' + f'{mask_file} {mask_dict[base_name]}') - except Exception as e: - raise e + mask_dict[base_name] = mask_file wf = pe.Workflow(name=wf_name) diff --git a/CPAC/utils/datatypes.py b/CPAC/utils/datatypes.py new file mode 100644 index 0000000000..81ae1e52df --- /dev/null +++ b/CPAC/utils/datatypes.py @@ -0,0 +1,35 @@ +"""Custom datatypes for C-PAC""" + + +class ListFromItem(list): + """Subclass of list to coerce non-lists into lists + + Examples + -------- + >>> list('one') + ['o', 'n', 'e'] + >>> ListFromItem('one') + ['one'] + >>> list(['one']) + ['one'] + >>> ListFromItem(['one']) + ['one'] + >>> list() + [] + >>> ListFromItem() + [] + >>> list(None) + Traceback (most recent call last): + ... + TypeError: 'NoneType' object is not iterable + >>> ListFromItem(None) + [] + """ + def __init__(self, *args, **kwargs): + """Initialize ListFromItem""" + if len(args) == 1 and not isinstance(args[0], (list, tuple)): + if args[0] is None: + args = () + else: + args = ([args[0]],) + list.__init__(self, *args, **kwargs) diff --git a/CPAC/utils/docs.py b/CPAC/utils/docs.py index 847106cdb1..466f849afe 100755 --- a/CPAC/utils/docs.py +++ b/CPAC/utils/docs.py @@ -7,6 +7,7 @@ def docstring_parameter(*args, **kwargs): """Decorator to parameterize docstrings. + Use double-curly-braces ({{}}) for literal curly braces. Examples -------- @@ -16,8 +17,16 @@ def docstring_parameter(*args, **kwargs): ... pass >>> print(do_nothing.__doc__) Does this test do anything? Yes it does. + >>> @docstring_parameter('test', answer='It should not.') + ... def how_about_now(): + ... '''How about {{ this }}?''' + ... pass + >>> print(how_about_now.__doc__) + How about { this }? """ def dec(obj): + if obj.__doc__ is None: + obj.__doc__ = '' obj.__doc__ = obj.__doc__.format(*args, **kwargs) return obj return dec @@ -57,7 +66,7 @@ def grab_docstring_dct(fn): 'option_val', 'inputs', 'outputs'] if 'Node Block:' in fn_docstring: fn_docstring = fn_docstring.split('Node Block:')[1] - fn_docstring = fn_docstring.lstrip().replace('\n', '') + fn_docstring = fn_docstring.lstrip().replace('\n', '').rstrip() dct = ast.literal_eval(fn_docstring) for key in init_dct_schema: if key not in dct.keys(): diff --git a/CPAC/utils/monitoring/__init__.py b/CPAC/utils/monitoring/__init__.py index 71d799c261..d78c839771 100755 --- a/CPAC/utils/monitoring/__init__.py +++ b/CPAC/utils/monitoring/__init__.py @@ -2,11 +2,13 @@ See https://fcp-indi.github.io/docs/developer/nodes for C-PAC-specific documentation. See https://nipype.readthedocs.io/en/latest/api/generated/nipype.utils.profiler.html for Nipype's documentation.''' # noqa: E501 # pylint: disable=line-too-long -from .custom_logging import getLogger, set_up_logger +from .config import LOGTAIL, WARNING_FREESURFER_OFF_WITH_DATA +from .custom_logging import failed_to_start, getLogger, set_up_logger from .monitoring import LoggingHTTPServer, LoggingRequestHandler, \ log_nodes_cb, log_nodes_initial, monitor_server, \ recurse_nodes -__all__ = ['getLogger', 'LoggingHTTPServer', 'LoggingRequestHandler', - 'log_nodes_cb', 'log_nodes_initial', 'monitor_server', - 'recurse_nodes', 'set_up_logger'] +__all__ = ['failed_to_start', 'getLogger', 'LoggingHTTPServer', + 'LoggingRequestHandler', 'log_nodes_cb', 'log_nodes_initial', + 'LOGTAIL', 'monitor_server', 'recurse_nodes', 'set_up_logger', + 'WARNING_FREESURFER_OFF_WITH_DATA'] diff --git a/CPAC/utils/monitoring/config.py b/CPAC/utils/monitoring/config.py index 8eca20b0bb..75a345eb20 100755 --- a/CPAC/utils/monitoring/config.py +++ b/CPAC/utils/monitoring/config.py @@ -1 +1,6 @@ -MOCK_LOGGERS = {} \ No newline at end of file +"""Global variables for logging""" +LOGTAIL = {'warnings': []} +MOCK_LOGGERS = {} +WARNING_FREESURFER_OFF_WITH_DATA = ( + 'The provided data configuration includes \'freesurfer_dir\' but the ' + 'provided pipeline config is not configured to use FreeSurfer outputs.') diff --git a/CPAC/utils/monitoring/custom_logging.py b/CPAC/utils/monitoring/custom_logging.py index 1199e957f5..467380dab1 100644 --- a/CPAC/utils/monitoring/custom_logging.py +++ b/CPAC/utils/monitoring/custom_logging.py @@ -1,21 +1,20 @@ -"""Funtions for logging. +# Copyright (C) 2022-2023 C-PAC Developers -Copyright (C) 2022 C-PAC Developers +# This file is part of C-PAC. -This file is part of C-PAC. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .""" +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +"""Funtions for logging.""" import logging import os import subprocess diff --git a/CPAC/utils/monitoring/draw_gantt_chart.py b/CPAC/utils/monitoring/draw_gantt_chart.py index 6b020d3ee5..7695a3a291 100755 --- a/CPAC/utils/monitoring/draw_gantt_chart.py +++ b/CPAC/utils/monitoring/draw_gantt_chart.py @@ -1,3 +1,44 @@ +# STATEMENT OF CHANGES: +# This file is derived from sources licensed under the Apache-2.0 terms, +# and this file has been changed. + +# CHANGES: +# * Resolves bugs preventing the original from generating the chart +# * Handles when chart-drawing is called but no nodes were run (all cached) + +# ORIGINAL WORK'S ATTRIBUTION NOTICE: +# Copyright (c) 2015-2019, Nipype developers + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Prior to release 0.12, Nipype was licensed under a BSD license. + +# Modifications Copyright (C) 2021-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . '''Module to draw an html gantt chart from logfile produced by ``CPAC.utils.monitoring.log_nodes_cb()``. @@ -358,7 +399,11 @@ def generate_gantt_chart( # Only include nodes with timing information, and covert timestamps # from strings to datetimes - nodes_list = _timing(nodes_list) + try: + nodes_list = _timing(nodes_list) + except ProcessLookupError: + warn(str(ProcessLookupError)) + nodes_list = [] if not nodes_list: return @@ -605,6 +650,8 @@ def _timing_timestamp(node): ------- dict """ + if node is None: + raise ProcessLookupError('No logged nodes have timing information.') return {k: (datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.%f") if '.' in v else datetime.fromisoformat(v)) if k in {"start", "finish"} else v for k, v in node.items()} diff --git a/CPAC/utils/outputs.py b/CPAC/utils/outputs.py index 321d156b7c..e04f4ac9dd 100755 --- a/CPAC/utils/outputs.py +++ b/CPAC/utils/outputs.py @@ -27,7 +27,7 @@ class Outputs(): functional_timeseries = list( reference[reference['4D Time Series'] == 'Yes']['Resource'] ) - + anat = list(reference[reference['Sub-Directory'] == 'anat']['Resource']) func = list(reference[reference['Sub-Directory'] == 'func']['Resource']) @@ -42,12 +42,16 @@ class Outputs(): _nonsmoothed_filter = reference['To Smooth'] == 'Yes' _zstd_filter = reference['To z-std'] == 'Yes' _corr_filter = reference['Type'] == 'correlation' - - all_template_filter = _template_filter | _epitemplate_filter | _symtemplate_filter - all_native_filter = _T1w_native_filter | _bold_native_filter | _long_native_filter - native_nonsmooth = list(reference[all_native_filter & _nonsmoothed_filter]['Resource']) - template_nonsmooth = list(reference[all_template_filter & _nonsmoothed_filter]['Resource']) + all_template_filter = (_template_filter | _epitemplate_filter | + _symtemplate_filter) + all_native_filter = (_T1w_native_filter | _bold_native_filter | + _long_native_filter) + + native_nonsmooth = list(reference[all_native_filter & + _nonsmoothed_filter]['Resource']) + template_nonsmooth = list(reference[all_template_filter & + _nonsmoothed_filter]['Resource']) to_smooth = list(reference[_nonsmoothed_filter]['Resource']) to_zstd = list(reference[_zstd_filter & ~_corr_filter]['Resource']) @@ -65,9 +69,11 @@ class Outputs(): # outputs to send into z-scoring, if z-scoring is enabled, and # outputs to write out if user selects to write non-z-scored outputs - native_raw = list( - reference[all_native_filter & - (reference['To z-std'] == 'Yes')]['Resource']) + native_raw = list(reference[all_native_filter & + (reference['To z-std'] == 'Yes')]['Resource']) + + template_raw = list(reference[all_template_filter & + (reference['To z-std'] == 'Yes')]['Resource']) template_raw = list( reference[all_template_filter & @@ -84,3 +90,5 @@ def _is_gifti(_file_key): giftis = reference[reference.File.map(_is_gifti)][['Resource', 'File']] giftis = {gifti.Resource: gifti.File.split(' ')[-1] for gifti in giftis.itertuples() if ' ' in gifti.File} + # motion parameters to rename until FCP-INDI/CPAC#1624 is merged + motion = list(reference[reference['Type'] == 'motion']['Resource']) \ No newline at end of file diff --git a/CPAC/utils/serialization/__init__.py b/CPAC/utils/serialization/__init__.py new file mode 100644 index 0000000000..5e2d31bdca --- /dev/null +++ b/CPAC/utils/serialization/__init__.py @@ -0,0 +1,3 @@ +from .core import VERSION_WORKFLOW +from .workflow_json import save_workflow_json, WorkflowJSONMeta +from .workflow_pickle import save_workflow_pickle diff --git a/CPAC/utils/serialization/core.py b/CPAC/utils/serialization/core.py new file mode 100644 index 0000000000..93b8a1031e --- /dev/null +++ b/CPAC/utils/serialization/core.py @@ -0,0 +1,39 @@ +from typing import Any + +from nipype import __version__ as version_nipype +from nipype.pipeline.engine import Workflow, Node + +from CPAC import __version__ as version_cpac + +WorkflowRaw = Workflow +"""Alias for internal use. CPAC derives: CPAC.pipeline.nipype_pipeline_engine.engine.Workflow""" + +NodeRaw = Node +"""Alias for internal use. CPAC derives: CPAC.pipeline.nipype_pipeline_engine.engine.Node""" + +VERSION_WORKFLOW = 1 +"""Placeholder for version checking. Increase when file structure changes drastically.""" + + +def workflow_container(workflow: Any, meta: Any = None) -> dict: + """ + Construct a container dictionary with some version information to allow version checks when reading. + + Parameters + ---------- + workflow : Workflow object. + meta : Meta information. + + Returns + ------- + + """ + return { + 'version': { + 'workflow': VERSION_WORKFLOW, + 'cpac': version_cpac, + 'nipype': version_nipype + }, + 'meta': {} if meta is None else meta, + 'workflow': workflow, + } diff --git a/CPAC/utils/serialization/workflow_json.py b/CPAC/utils/serialization/workflow_json.py new file mode 100644 index 0000000000..820b499baf --- /dev/null +++ b/CPAC/utils/serialization/workflow_json.py @@ -0,0 +1,128 @@ +import dataclasses +import json +from dataclasses import dataclass +from datetime import datetime, date +from os import PathLike +from typing import List, Dict, Union + +import networkx + +from .core import workflow_container, WorkflowRaw, NodeRaw + + +def _object_as_strdict(obj: object) -> Dict[str, str]: + """Extracts and converts all fields of an object to a {str: str} dict.""" + return {str(k): str(v) for k, v in obj.__dict__.items()} + + +def _workflow_get_graph(wf: WorkflowRaw) -> networkx.DiGraph: + """Get graph from workflow instance.""" + return wf._graph # noqa + + +@dataclass +class EdgeData: + """Data class for serializing workflow edges.""" + + fullname_origin: str + fullname_target: str + + @classmethod + def from_obj(cls, obj): + return cls( + fullname_origin=obj[0].fullname, + fullname_target=obj[1].fullname + ) + + +@dataclass +class NodeData: + """Data class for serializing workflow nodes.""" + + name: str + fullname: str + type: str + repr: str + + inputs: dict + outputs: dict + + nodes: List['NodeData'] = dataclasses.field(default_factory=lambda: []) + edges: List['EdgeData'] = dataclasses.field(default_factory=lambda: []) + + @classmethod + def from_obj(cls, obj): + node_data = cls( + name=obj.name, # There is name, fullname and itername + fullname=obj.fullname, + type='node', + repr=str(obj), + inputs=_object_as_strdict(obj.inputs), + outputs=_object_as_strdict(obj.outputs), + nodes=[], + edges=[] + ) + + if isinstance(obj, NodeRaw): + return node_data + + if isinstance(obj, WorkflowRaw): + node_data.type = 'workflow' + graph = _workflow_get_graph(obj) + + for child_node in graph.nodes: + node_data_child = cls.from_obj(child_node) + node_data.nodes.append(node_data_child) + + for child_edgle in graph.edges: + edge_data_child = EdgeData.from_obj(child_edgle) + node_data.edges.append(edge_data_child) + + return node_data + + raise TypeError(f'Unknown Node type found in graph: {type(obj)}') + + +@dataclass +class WorkflowJSONMeta: + """Data class for meta information.""" + pipeline_name: str + stage: str + time: datetime = dataclasses.field(default_factory=lambda: datetime.now().astimezone()) + + def filename(self) -> str: + """Generate filename from fields""" + timestamp = self.time.strftime("%Y-%m-%d_%H-%M-%S") + return f'workflow_{self.stage}_{timestamp}_{self.pipeline_name}.json' + + +class WorkflowJSONEncoder(json.JSONEncoder): + """Custom JSON encoder. Unpacks dataclasses to dicts.""" + + def default(self, o): + if dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + if isinstance(o, (datetime, date)): + return o.isoformat() + return super().default(o) + + +def save_workflow_json( + filename: Union[str, PathLike], + workflow: WorkflowRaw, + meta: WorkflowJSONMeta +) -> None: + """ + Serialize and save workflow object to a file. + + Parameters + ---------- + filename : Filename to save to. + workflow : Workflow object. + meta : Meta information. + """ + + node_data = NodeData.from_obj(workflow) + obj = workflow_container(workflow=node_data, meta=meta) + with open(filename, 'w', encoding='utf-8') as file: + json.dump(obj, file, indent=2, cls=WorkflowJSONEncoder) diff --git a/CPAC/utils/serialization/workflow_pickle.py b/CPAC/utils/serialization/workflow_pickle.py new file mode 100644 index 0000000000..e5fe25854b --- /dev/null +++ b/CPAC/utils/serialization/workflow_pickle.py @@ -0,0 +1,19 @@ +import pickle +from typing import Any + +from .core import workflow_container + + +def save_workflow_pickle(filename: str, workflow: Any) -> None: + """ + Serialize and save workflow object to a file. + + Parameters + ---------- + filename : Filename to save to. + workflow : Workflow object. (Can be any pickle-able python object.) + """ + + obj = workflow_container(workflow) + with open(filename, 'wb') as handle: + pickle.dump(workflow_container(obj), file=handle, protocol=pickle.HIGHEST_PROTOCOL) diff --git a/CPAC/utils/strategy.py b/CPAC/utils/strategy.py index 8eab5caf19..b176b06073 100755 --- a/CPAC/utils/strategy.py +++ b/CPAC/utils/strategy.py @@ -1,15 +1,29 @@ -import os -import six -import warnings -import logging +# Copyright (C) 2018-2022 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +import logging +import six +from CPAC.pipeline.engine import ResourcePool logger = logging.getLogger('nipype.workflow') -class Strategy(object): +class Strategy: def __init__(self): - self.resource_pool = {} + self._resource_pool = ResourcePool({}) self.leaf_node = None self.leaf_out_file = None self.name = [] @@ -42,6 +56,16 @@ def get_node_from_resource_pool(self, resource_key): logger.error('No node for output: %s', resource_key) raise + @property + def resource_pool(self): + '''Strategy's ResourcePool dict''' + return self._resource_pool.get_entire_rpool() + + @property + def rpool(self): + '''Strategy's ResourcePool''' + return self._resource_pool + def update_resource_pool(self, resources, override=False): for key, value in resources.items(): if key in self.resource_pool and not override: diff --git a/CPAC/utils/test_mocks.py b/CPAC/utils/test_mocks.py index e76ea96750..2c88a10a2f 100755 --- a/CPAC/utils/test_mocks.py +++ b/CPAC/utils/test_mocks.py @@ -1,9 +1,10 @@ import os +from nipype.interfaces import utility as util from CPAC.pipeline import nipype_pipeline_engine as pe -import nipype.interfaces.utility as util -from CPAC.utils import Configuration, Strategy -from CPAC.utils.interfaces.function import Function +from CPAC.utils.configuration import Configuration from CPAC.utils.datasource import resolve_resolution +from CPAC.utils.interfaces.function import Function +from CPAC.utils.strategy import Strategy def file_node(path, file_node_num=0): diff --git a/CPAC/utils/tests/configs/__init__.py b/CPAC/utils/tests/configs/__init__.py new file mode 100644 index 0000000000..83d30f657c --- /dev/null +++ b/CPAC/utils/tests/configs/__init__.py @@ -0,0 +1,14 @@ +"""Configs for testing""" +import os +from pkg_resources import resource_filename +with open(resource_filename("CPAC", + os.path.join('utils', 'tests', 'configs', + 'neurostars_23786.yml')), + 'r', encoding='utf-8') as _f: + NEUROSTARS_23786 = _f.read() +with open(resource_filename("CPAC", + os.path.join('utils', 'tests', 'configs', + 'neurostars_24035.yml')), + 'r', encoding='utf-8') as _f: + NEUROSTARS_24035 = _f.read() +__all__ = ['NEUROSTARS_23786', 'NEUROSTARS_24035'] diff --git a/CPAC/utils/tests/configs/neurostars_23786.yml b/CPAC/utils/tests/configs/neurostars_23786.yml new file mode 100644 index 0000000000..3e02e0659b --- /dev/null +++ b/CPAC/utils/tests/configs/neurostars_23786.yml @@ -0,0 +1,4 @@ +seed_based_correlation_analysis: + run: true + sca_roi_paths: + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg \ No newline at end of file diff --git a/CPAC/utils/tests/configs/neurostars_24035.yml b/CPAC/utils/tests/configs/neurostars_24035.yml new file mode 100644 index 0000000000..8632dd1a67 --- /dev/null +++ b/CPAC/utils/tests/configs/neurostars_24035.yml @@ -0,0 +1,293 @@ +--- +# CPAC Pipeline Configuration YAML file +# Version 1.8.4.dev +# +# http://fcp-indi.github.io for more info. +# + +# OUTPUTS AND DERIVATIVES +# ----------------------- +post_processing: + + spatial_smoothing: + + # Smooth the derivative outputs. + # Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both. + # + # Options: + # ['smoothed', 'nonsmoothed'] + output: ['smoothed'] + + # Tool to use for smoothing. + # 'FSL' for FSL MultiImageMaths for FWHM provided + # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided + smoothing_method: ['FSL'] + + # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. + # this is a fork point + # i.e. multiple kernels - fwhm: [4,6,8] + fwhm: [4] + + z-scoring: + + # z-score standardize the derivatives. This may be needed for group-level analysis. + # Set as ['raw'] to disable z-scoring. Set as ['z-scored', 'raw'] to get both. + # + # Options: + # ['z-scored', 'raw'] + output: ['z-scored'] + + +timeseries_extraction: + roi_paths_fully_specified: False + + run: On + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg + tse_roi_paths: + /cpac_templates/CC400.nii.gz: Avg + /cpac_templates/aal_mask_pad.nii.gz: Avg + /cpac_templates/CC200.nii.gz: Avg + /cpac_templates/tt_mask_pad.nii.gz: Avg + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: SpatialReg + /cpac_templates/ho_mask_pad.nii.gz: Avg + /cpac_templates/rois_3mm.nii.gz: Avg + /ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/CAPRSC_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/DKT_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/DesikanKlein_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/MICCAI_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Schaefer1000_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Schaefer200_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Schaefer300_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Schaefer400_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Talairach_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Desikan_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + /ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-1x1x1.nii.gz: Avg + + # Functional time-series and ROI realignment method: ['ROI_to_func'] or ['func_to_ROI'] + # 'ROI_to_func' will realign the atlas/ROI to functional space (fast) + # 'func_to_ROI' will realign the functional time series to the atlas/ROI space + # + # NOTE: in rare cases, realigning the ROI to the functional space may + # result in small misalignments for very small ROIs - please double + # check your data if you see issues + realignment: 'ROI_to_func' + + connectivity_matrix: + # Create a connectivity matrix from timeseries data + + # Options: + # ['AFNI', 'Nilearn', 'ndmg'] + using: + - Nilearn + - ndmg + # Options: + # ['Pearson', 'Partial'] + # Note: These options are not configurable for ndmg, which will ignore these options + measure: + - Pearson + - Partial + + +seed_based_correlation_analysis: + + roi_paths_fully_specified: False + + # SCA - Seed-Based Correlation Analysis + # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. + # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. + run: On + + # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. + # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg + # available analyses: + # /path/to/atlas.nii.gz: Avg, DualReg, MultReg + sca_roi_paths: + /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg + /cpac_templates/CC400.nii.gz: Avg, MultReg + /cpac_templates/ez_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/aal_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/CC200.nii.gz: Avg, MultReg + /cpac_templates/tt_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/ho_mask_pad.nii.gz: Avg, MultReg + /cpac_templates/rois_3mm.nii.gz: Avg, MultReg + + # Normalize each time series before running Dual Regression SCA. + norm_timeseries_for_DR: True + + +amplitude_low_frequency_fluctuation: + + # ALFF & f/ALFF + # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. + run: On + + # Frequency cutoff (in Hz) for the high-pass filter used when calculating f/ALFF. + highpass_cutoff: [0.01] + + # Frequency cutoff (in Hz) for the low-pass filter used when calculating f/ALFF + lowpass_cutoff: [0.1] + + +regional_homogeneity: + + # ReHo + # Calculate Regional Homogeneity (ReHo) for all voxels. + run: On + + # Number of neighboring voxels used when calculating ReHo + # 7 (Faces) + # 19 (Faces + Edges) + # 27 (Faces + Edges + Corners) + cluster_size: 27 + + +voxel_mirrored_homotopic_connectivity: + + # VMHC + # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. + run: On + + symmetric_registration: + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz + + # A reference symmetric brain template for resampling + T1w_brain_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_symmetric.nii.gz + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz + + # A reference symmetric skull template for resampling + T1w_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_symmetric.nii.gz + + # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. + # It is not necessary to change this path unless you intend to use a non-standard symmetric template. + dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz + + # A reference symmetric brain mask template for resampling + dilated_symmetric_brain_mask_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_mask_symmetric_dil.nii.gz + + +network_centrality: + + # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. + run: On + + # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. + # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. + memory_allocation: 1.0 + + # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. + template_specification_file: /cpac_templates/Mask_ABIDE_85Percent_GM.nii.gz + + degree_centrality: + + # Enable/Disable degree centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: ['Binarized', 'Weighted'] + + # Select the type of threshold used when creating the degree centrality adjacency matrix. + # options: + # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' + correlation_threshold_option: 'Sparsity threshold' + + # Based on the Threshold Type selected above, enter a Threshold Value. + # P-value for Significance Threshold + # Sparsity value for Sparsity Threshold + # Pearson's r value for Correlation Threshold + correlation_threshold: 0.001 + + eigenvector_centrality: + + # Enable/Disable eigenvector centrality by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: ['Weighted'] + + # Select the type of threshold used when creating the eigenvector centrality adjacency matrix. + # options: + # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' + correlation_threshold_option: 'Sparsity threshold' + + # Based on the Threshold Type selected above, enter a Threshold Value. + # P-value for Significance Threshold + # Sparsity value for Sparsity Threshold + # Pearson's r value for Correlation Threshold + correlation_threshold: 0.001 + + local_functional_connectivity_density: + + # Enable/Disable lFCD by selecting the connectivity weights + # weight_options: ['Binarized', 'Weighted'] + # disable this type of centrality with: + # weight_options: [] + weight_options: ['Binarized', 'Weighted'] + + # Select the type of threshold used when creating the lFCD adjacency matrix. + # options: + # 'Significance threshold', 'Correlation threshold' + correlation_threshold_option: 'Correlation threshold' + + # Based on the Threshold Type selected above, enter a Threshold Value. + # P-value for Significance Threshold + # Sparsity value for Sparsity Threshold + # Pearson's r value for Correlation Threshold + correlation_threshold: 0.6 + + +# PACKAGE INTEGRATIONS +# -------------------- +PyPEER: + + # Training of eye-estimation models. Commonly used for movies data/naturalistic viewing. + run: Off + + # PEER scan names to use for training + # Example: ['peer_run-1', 'peer_run-2'] + eye_scan_names: [] + + # Naturalistic viewing data scan names to use for eye estimation + # Example: ['movieDM'] + data_scan_names: [] + + # Template-space eye mask + eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz + + # PyPEER Stimulus File Path + # This is a file describing the stimulus locations from the calibration sequence. + stimulus_path: None + + minimal_nuisance_correction: + + # PyPEER Minimal nuisance regression + # Note: PyPEER employs minimal preprocessing - these choices do not reflect what runs in the main pipeline. + # PyPEER uses non-nuisance-regressed data from the main pipeline. + + # Global signal regression (PyPEER only) + peer_gsr: True + + # Motion scrubbing (PyPEER only) + peer_scrub: False + + # Motion scrubbing threshold (PyPEER only) + scrub_thresh: 0.2 \ No newline at end of file diff --git a/CPAC/utils/tests/test_bids_utils.py b/CPAC/utils/tests/test_bids_utils.py index 109b25585f..0c6cabebbd 100755 --- a/CPAC/utils/tests/test_bids_utils.py +++ b/CPAC/utils/tests/test_bids_utils.py @@ -3,11 +3,11 @@ import pytest import yaml from CPAC.utils.bids_utils import bids_gen_cpac_sublist, \ + cl_strip_brackets, \ collect_bids_files_configs, \ create_cpac_data_config, \ load_cpac_data_config, \ sub_list_filter_by_labels -from CPAC.utils.utils import cl_strip_brackets def create_sample_bids_structure(root_dir): diff --git a/CPAC/utils/tests/test_yaml.py b/CPAC/utils/tests/test_yaml.py index 3ac53d0e84..bfd0bb62c3 100755 --- a/CPAC/utils/tests/test_yaml.py +++ b/CPAC/utils/tests/test_yaml.py @@ -1,37 +1,81 @@ -import pytest +'''Tests for C-PAC YAML + +Copyright (C) 2022 C-PAC Developers + +This file is part of C-PAC. + +C-PAC is free software: you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + +C-PAC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with C-PAC. If not, see .''' +import os import tempfile -import yaml -import yamlordereddictloader +import pytest -from CPAC.utils.yaml_template import create_yaml_from_template +import yaml +from CPAC.utils.configuration import Configuration, Preconfiguration, \ + preconfig_yaml +from CPAC.utils.configuration.yaml_template import create_yaml_from_template +from .configs import NEUROSTARS_23786, NEUROSTARS_24035 -@pytest.mark.skip(reason='needs refactored') -def test_yaml_template(): - config_file = tempfile.mkstemp(suffix='test_yaml_template')[1] +@pytest.mark.parametrize('config', ['blank', 'default', NEUROSTARS_23786, + NEUROSTARS_24035]) +def test_sca_config(config): + '''Test SCA config parsing''' + if '\n' in config: + participant_config = Configuration(yaml.safe_load(config)) + assert participant_config['seed_based_correlation_analysis', + 'run'] is True + else: + participant_config = Preconfiguration(config) + assert participant_config['seed_based_correlation_analysis', + 'run'] is False - # Create a new YAML configuration file based on the default_pipeline.yml file. - config = yaml.safe_load(open('./data/default_pipeline.yml', 'r')) - new_config = create_yaml_from_template(config, './data/default_pipeline.yml') +def test_yaml_template(): + '''Test YAML pipeline template''' + # Create temporary file + config_file = tempfile.mkstemp(suffix='test_yaml_template')[1] - with open(config_file, 'wb') as f: + # Create a new YAML configuration file based on the default pipeline + # YAML file. + pipeline_file = preconfig_yaml('default') + with open(pipeline_file, 'r', encoding='utf-8') as f: + config = yaml.safe_load(f) + new_config = create_yaml_from_template(config, pipeline_file) + with open(config_file, 'w', encoding='utf-8') as f: f.write(new_config) # Verify that the output has preserved blank lines, comments - with open(config_file, 'r') as f: + with open(config_file, 'r', encoding='utf-8') as f: lines = f.readlines() - # Assert first lines starts with a comment - assert lines[0].startswith('# ') - # Assert that there are blank lines - assert lines[6].isspace() - assert lines[7].isspace() + # Delete temporary file + os.remove(config_file) + + # Assert first line declares YAML version + assert lines[0].startswith('%YAML') + assert lines[1] == '---\n' + + # Assert first lines starts with a comment + assert lines[2].startswith('# ') - # Assert that regressors configuration written in block style - assert lines[669].startswith('Regressors:') - assert lines[670].startswith('- Bandpass:') + # Assert that regressors configuration written in block style + assert (line for line in lines if line.strip() == 'Regressors:') + assert (line for line in lines if line.strip() == '- Bandpass:') - # Assert that other configurations that are lists of values are written in flow style - assert lines[764].startswith('roiTSOutputs: [true, true]') + # Assert that short lists of values are written in flow style + # (e.g., "GM_label: [3, 42]") + assert (line for line in lines if + '[' in line and ',' in line and ']' in line and + not line.lstrip().startswith('#')) diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py index 02ead6a778..51d8ea3935 100755 --- a/CPAC/utils/utils.py +++ b/CPAC/utils/utils.py @@ -1,4 +1,21 @@ +# Copyright (C) 2012-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import os +import sys import collections.abc import fnmatch import gzip @@ -16,10 +33,14 @@ CONFIGS_DIR = os.path.abspath(os.path.join( __file__, *repeat(os.path.pardir, 2), 'resources/configs/')) -NESTED_CONFIG_MAPPING = yaml.safe_load(open(os.path.join( - CONFIGS_DIR, '1.7-1.8-nesting-mappings.yml'), 'r')) -NESTED_CONFIG_DEPRECATIONS = yaml.safe_load(open(os.path.join( - CONFIGS_DIR, '1.7-1.8-deprecations.yml'), 'r')) +with open(os.path.join(CONFIGS_DIR, '1.7-1.8-nesting-mappings.yml'), 'r', + encoding='utf-8') as _f: + NESTED_CONFIG_MAPPING = yaml.safe_load(_f) +with open(os.path.join(CONFIGS_DIR, '1.7-1.8-deprecations.yml'), 'r', + encoding='utf-8') as _f: + NESTED_CONFIG_DEPRECATIONS = yaml.safe_load(_f) +YAML_BOOLS = {True: ('on', 't', 'true', 'y', 'yes'), + False: ('f', 'false', 'n', 'no', 'off')} def get_last_prov_entry(prov): @@ -96,30 +117,7 @@ def check_prov_for_motion_tool(prov): return None -def cl_strip_brackets(arg_list): - """Removes '[' from before first and ']' from after final - arguments in a list of commandline arguments - - Parameters - ---------- - arg_list : list - - Returns - ------- - list - Examples - -------- - >>> cl_strip_brackets('[a b c]'.split(' ')) - ['a', 'b', 'c'] - >>> cl_strip_brackets('a b c'.split(' ')) - ['a', 'b', 'c'] - >>> cl_strip_brackets('[ a b c ]'.split(' ')) - ['a', 'b', 'c'] - """ - arg_list[0] = arg_list[0].lstrip('[') - arg_list[-1] = arg_list[-1].rstrip(']') - return [arg for arg in arg_list if arg] def get_flag(in_flag): @@ -151,27 +149,59 @@ def read_json(json_file): return json_dct -def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, - fwhm=None, extension=None): +def create_id_string(cfg, unique_id, resource, scan_id=None, + template_desc=None, atlas_id=None, fwhm=None, subdir=None + ): """Create the unique key-value identifier string for BIDS-Derivatives compliant file names. This is used in the file renaming performed during the Datasink connections. + + Example + ------- + >>> from CPAC.utils.configuration import Configuration + >>> create_id_string(Configuration(), 'sub-1_ses-1', + ... 'res-derivative_desc-Mean-1_timeseries', + ... scan_id='rest', atlas_id='Yeo_desc-7') + 'sub-1_ses-1_task-rest_atlas-Yeo7_res-3mm_desc-Mean1_timeseries' """ + import re + from CPAC.utils.bids_utils import combine_multiple_entity_instances, \ + res_in_filename + from CPAC.utils.outputs import Outputs + + if resource in Outputs.motion: + resource = ( + f'desc-{resource.replace("framewise-displacement", "FD")}_motion') if atlas_id: - if '_' in atlas_id: - atlas_id = atlas_id.replace('_', '') + if '_desc-' in atlas_id: + atlas, desc = atlas_id.split('_desc-') + if not re.match(r'.*[0-9]$', atlas) and re.match(r'[a-z].*', desc): + atlas_id = f'{atlas}{desc[0].upper()}{desc[1:]}' + else: + atlas_id = atlas_id.replace('_desc-', '') resource = f'atlas-{atlas_id}_{resource}' - if 'sub-' not in unique_id: - unique_id = f'sub-{unique_id}' + part_id = unique_id.split('_')[0] + ses_id = unique_id.split('_')[1] + if 'sub-' not in part_id: + part_id = f'sub-{part_id}' + if 'ses-' not in ses_id: + ses_id = f'ses-{ses_id}' if scan_id: - out_filename = f'{unique_id}_task-{scan_id}_{resource}' + out_filename = f'{part_id}_{ses_id}_task-{scan_id}_{resource}' else: - out_filename = f'{unique_id}_{resource}' + out_filename = f'{part_id}_{ses_id}_{resource}' + + template_tag = template_desc.split(' -')[0] if template_desc else '*' + for prefix in ['space-', 'from-', 'to-']: + for bidstag in out_filename.split('_'): + if prefix in bidstag and 'template' in bidstag: + out_filename = out_filename.replace( + bidstag, f'{prefix}{template_tag}') if fwhm: for tag in resource.split('_'): @@ -187,7 +217,14 @@ def create_id_string(unique_id, resource, scan_id=None, atlas_id=None, out_filename = out_filename + "." + str(extension) - return out_filename + # drop space- entities from from native-space filenames + if subdir == 'anat': + out_filename = out_filename.replace('_space-T1w_', '_') + if subdir == 'func': + out_filename = out_filename.replace('_space-bold_', '_') + + return combine_multiple_entity_instances( + res_in_filename(cfg, out_filename)) def write_output_json(json_data, filename, indent=3, basedir=None): @@ -708,6 +745,8 @@ def get_scan_params(subject_id, scan, pipeconfig_start_indx, starting TR or starting volume index last_tr : an integer ending TR or ending volume index + pe_direction : str + effective_echo_spacing : float """ import os @@ -726,6 +765,7 @@ def get_scan_params(subject_id, scan, pipeconfig_start_indx, last_tr = '' unit = 's' pe_direction = '' + effective_echo_spacing = None if isinstance(pipeconfig_stop_indx, str): if "End" in pipeconfig_stop_indx or "end" in pipeconfig_stop_indx: @@ -748,16 +788,23 @@ def get_scan_params(subject_id, scan, pipeconfig_start_indx, # TODO: better handling of errant key values!!! if "RepetitionTime" in params_dct.keys(): TR = float(check(params_dct, subject_id, scan, - 'RepetitionTime', False)) + "RepetitionTime", False)) if "SliceTiming" in params_dct.keys(): pattern = str(check(params_dct, subject_id, scan, - 'SliceTiming', False)) + "SliceTiming", False)) elif "SliceAcquisitionOrder" in params_dct.keys(): pattern = str(check(params_dct, subject_id, scan, - 'SliceAcquisitionOrder', False)) + "SliceAcquisitionOrder", False)) if "PhaseEncodingDirection" in params_dct.keys(): pe_direction = str(check(params_dct, subject_id, scan, - 'PhaseEncodingDirection', False)) + "PhaseEncodingDirection", False)) + try: + "EffectiveEchoSpacing" in params_dct.keys() + effective_echo_spacing = float( + check(params_dct, subject_id, scan, + "EffectiveEchoSpacing", False)) + except TypeError: + pass elif len(data_config_scan_params) > 0 and \ isinstance(data_config_scan_params, dict): @@ -800,17 +847,23 @@ def get_scan_params(subject_id, scan, pipeconfig_start_indx, pe_direction = check(params_dct, subject_id, scan, 'PhaseEncodingDirection', False) + try: + effective_echo_spacing = float( + try_fetch_parameter(params_dct, subject_id, scan, + ["EffectiveEchoSpacing"])) + except TypeError: + pass else: err = "\n\n[!] Could not read the format of the scan parameters " \ "information included in the data configuration file for " \ - "the participant {0}.\n\n".format(subject_id) + f"the participant {subject_id}.\n\n" raise Exception(err) - if first_tr == '' or first_tr == None: + if first_tr == '' or first_tr is None: first_tr = pipeconfig_start_indx - if last_tr == '' or last_tr == None: + if last_tr == '' or last_tr is None: last_tr = pipeconfig_stop_indx unit = 's' @@ -913,14 +966,13 @@ def get_scan_params(subject_id, scan, pipeconfig_start_indx, start_indx = first_tr stop_indx = last_tr - return ( - tr if tr else None, - tpattern if tpattern else None, - ref_slice, - start_indx, - stop_indx, - pe_direction - ) + return (tr if tr else None, + tpattern if tpattern else None, + ref_slice, + start_indx, + stop_indx, + pe_direction, + effective_echo_spacing) def get_tr(tr): @@ -1489,7 +1541,8 @@ def load_preconfig(pipeline_label): ) ) - print("Loading the '{0}' pre-configured pipeline.".format(pipeline_label)) + print(f"Loading the '{pipeline_label}' pre-configured pipeline.", + file=sys.stderr) return pipeline_file @@ -1601,6 +1654,141 @@ def _pickle2(p, z=False): return False +def _changes_1_8_0_to_1_8_1(config_dict): + ''' + Examples + -------- + Starting with 1.8.0 + >>> zero = {'anatomical_preproc': { + ... 'non_local_means_filtering': True, + ... 'n4_bias_field_correction': True + ... }, 'functional_preproc': { + ... 'motion_estimates_and_correction': { + ... 'calculate_motion_first': False + ... } + ... }, 'segmentation': { + ... 'tissue_segmentation': { + ... 'ANTs_Prior_Based': { + ... 'CSF_label': 0, + ... 'left_GM_label': 1, + ... 'right_GM_label': 2, + ... 'left_WM_label': 3, + ... 'right_WM_label': 4}}}} + >>> updated_apb = _changes_1_8_0_to_1_8_1(zero)[ + ... 'segmentation']['tissue_segmentation']['ANTs_Prior_Based'] + >>> updated_apb['CSF_label'] + [0] + >>> updated_apb['GM_label'] + [1, 2] + >>> updated_apb['WM_label'] + [3, 4] + + Starting with 1.8.1 + >>> one = {'anatomical_preproc': { + ... 'non_local_means_filtering': True, + ... 'n4_bias_field_correction': True + ... }, 'functional_preproc': { + ... 'motion_estimates_and_correction': { + ... 'calculate_motion_first': False + ... } + ... }, 'segmentation': { + ... 'tissue_segmentation': { + ... 'ANTs_Prior_Based': { + ... 'CSF_label': [0], + ... 'GM_label': [1, 2], + ... 'WM_label': [3, 4]}}}} + >>> updated_apb = _changes_1_8_0_to_1_8_1(one)[ + ... 'segmentation']['tissue_segmentation']['ANTs_Prior_Based'] + >>> updated_apb['CSF_label'] + [0] + >>> updated_apb['GM_label'] + [1, 2] + >>> updated_apb['WM_label'] + [3, 4] + ''' + for key_sequence in { + ('anatomical_preproc', 'non_local_means_filtering'), + ('anatomical_preproc', 'n4_bias_field_correction') + }: + config_dict = _now_runswitch(config_dict, key_sequence) + for combiners in { + (( + ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'CSF_label'), + ), ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'CSF_label')), + (( + ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'left_GM_label'), + ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'right_GM_label') + ), ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'GM_label')), + (( + ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'left_WM_label'), + ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'right_WM_label') + ), ('segmentation', 'tissue_segmentation', 'ANTs_Prior_Based', + 'WM_label')) + }: + config_dict = _combine_labels(config_dict, *combiners) + try: + calculate_motion_first = lookup_nested_value( + config_dict, + ['functional_preproc', 'motion_estimates_and_correction', + 'calculate_motion_first'] + ) + except KeyError: + calculate_motion_first = None + if calculate_motion_first is not None: + del config_dict['functional_preproc'][ + 'motion_estimates_and_correction']['calculate_motion_first'] + config_dict = set_nested_value(config_dict, [ + 'functional_preproc', 'motion_estimates_and_correction', + 'motion_estimates', 'calculate_motion_first' + ], calculate_motion_first) + + return config_dict + + +def _combine_labels(config_dict, list_to_combine, new_key): + ''' + Helper function to combine formerly separate keys into a + combined key. + + Parameters + ---------- + config_dict: dict + + key_sequence: iterable of lists or tuples + + new_key: list or tuple + + Returns + ------- + updated_config_dict: dict + ''' + new_value = [] + any_old_values = False + for _to_combine in list_to_combine: + try: + old_value = lookup_nested_value(config_dict, _to_combine) + except KeyError: + old_value = None + if old_value is not None: + any_old_values = True + if isinstance(old_value, (list, set, tuple)): + for value in old_value: + new_value.append(value) + else: + new_value.append(old_value) + config_dict = delete_nested_value(config_dict, _to_combine) + if any_old_values: + return set_nested_value(config_dict, new_key, new_value) + return config_dict + + def concat_list(in_list1=None, in_list2=None): """ Parameters @@ -1634,64 +1822,6 @@ def concat_list(in_list1=None, in_list2=None): return out_list -def dct_diff(dct1, dct2): - '''Function to compare 2 nested dicts, dropping values unspecified - in the second. Adapted from https://github.com/sgiavasis/CPAC_regtest_pack/blob/9056ef63cbe693f436c4ea8a5fee669f8d2e35f7/cpac_pipe_diff.py#L31-L78 - - Parameters - ---------- - dct1 : dict - - dct2 : dict - - Returns - ------- - diff : set - a tuple of values from dct1, dct2 for each differing key - - Example - ------- - >>> import yaml - >>> def read_yaml_file(yaml_file): - ... return yaml.safe_load(open(yaml_file, 'r')) - >>> pipeline = read_yaml_file('/code/dev/docker_data/default_pipeline.yml') - >>> dct_diff(pipeline, pipeline) - {} - >>> pipeline2 = read_yaml_file('/code/CPAC/resources/configs/' - ... 'pipeline_config_fmriprep-options.yml') - >>> dct_diff(pipeline, pipeline2)['pipeline_setup']['pipeline_name'] - ('cpac-default-pipeline', 'cpac_fmriprep-options') - ''' - diff = {} - for key in dct1: - if isinstance(dct1[key], dict): - if not isinstance(dct2, dict): - try: - dct2 = dct2.dict() - except AttributeError: - raise TypeError(f'{dct2} is not a dict.') - diff[key] = dct_diff(dct1[key], dct2.get(key, {})) - if diff[key] == {}: - del diff[key] - else: - dct1_val = dct1.get(key) - dct2_val = dct2.get(key) if isinstance(dct2, dict) else None - - if dct1_val != dct2_val: - diff[key] = (dct1_val, dct2_val) - - # add any new keys - if isinstance(dct2, dict): - for key in dct2: - if key not in dct1: - diff[key] = dct2[key] - - # only return non-empty diffs - return {k: v for k, v in diff.items() if k in dct2} - - return {} - - def list_item_replace(l, # noqa: E741 # pylint: disable=invalid-name old, new): '''Function to replace an item in a list @@ -1759,6 +1889,31 @@ def lookup_nested_value(d, keys): raise +def _now_runswitch(config_dict, key_sequence): + ''' + Helper function to convert a formerly forkable value to a + runswitch. + + Parameters + ---------- + config_dict: dict + + key_sequence: list or tuple + + Returns + ------- + updated_config_dict: dict + ''' + try: + old_forkable = lookup_nested_value(config_dict, key_sequence) + except KeyError: + return config_dict + if isinstance(old_forkable, (bool, list)): + return set_nested_value( + config_dict, key_sequence, {'run': old_forkable}) + return config_dict + + def _remove_somethings(value, things_to_remove): '''Helper function to remove instances of any in a given set of values from a list. @@ -2292,18 +2447,18 @@ def update_nested_dict(d_base, d_update, fully_specified=False): # `roi_paths_fully_specified` children if fully_specified: return d_update - if any(k.endswith('_roi_paths') for k in d_update.keys()): - fully_specified = d_update.pop('roi_paths_fully_specified', True) - else: - fully_specified = False d_new = {} if d_base is None else deepcopy(d_base) - for k, v in d_update.items(): - if isinstance(v, collections.abc.Mapping): - d_new[k] = update_nested_dict( - d_new.get(k, {}), v, fully_specified) + if k.endswith('_roi_paths'): + fully_specified = d_update.get('roi_paths_fully_specified', True) else: - d_new[k] = v + fully_specified = False + if k != 'roi_paths_fully_specified': + if isinstance(v, collections.abc.Mapping): + d_new[k] = update_nested_dict(d_new.get(k, {}), v, + fully_specified) + else: + d_new[k] = v return d_new @@ -2506,19 +2661,19 @@ def update_values_from_list(d_old, last_exception=None): if len(observed) == 1: # pylint: disable=no-else-return if isinstance(observed[0], int): value = bool(observed[0]) - elif observed[0] in {'On', 'True'}: + elif observed[0].lower() in YAML_BOOLS[True]: value = True - elif observed[0] in {'Off', 'False'}: + elif observed[0].lower() in YAML_BOOLS[False]: value = False return update_values_from_list(set_nested_value( d, e_path, [value] if list_expected else value), e) else: return update_values_from_list(set_nested_value( d, e_path, [bool(value) for value in observed]), e) - elif observed in {'On', 'True'}: + elif observed.lower() in YAML_BOOLS[True]: return update_values_from_list( set_nested_value(d, e.path, True), e) - elif observed in {'Off', 'False'}: + elif observed.lower() in YAML_BOOLS[False]: return update_values_from_list( set_nested_value(d, e.path, False), e) else: diff --git a/CPAC/utils/yaml_template.py b/CPAC/utils/yaml_template.py deleted file mode 100755 index d333787eb8..0000000000 --- a/CPAC/utils/yaml_template.py +++ /dev/null @@ -1,407 +0,0 @@ -import os -import re -import yaml -from click import BadParameter -from datetime import datetime -from CPAC.utils.configuration import Configuration, DEFAULT_PIPELINE_FILE -from CPAC.utils.utils import dct_diff, load_preconfig, lookup_nested_value, \ - update_config_dict, update_pipeline_values_1_8 - - -def create_yaml_from_template( - d, template=DEFAULT_PIPELINE_FILE, include_all=False -): - """Save dictionary to a YAML file, keeping the structure - (such as first level comments and ordering) from the template - - It may not be fully robust to YAML structures, but it works - for C-PAC config files! - - Parameters - ---------- - d : dict or Configuration - - template : str - path to template or name of preconfig - - include_all : bool - include every key, even those that are unchanged - - Examples - -------- - >>> import yaml - >>> from CPAC.utils.configuration import Configuration - >>> Configuration(yaml.safe_load(create_yaml_from_template({}))).dict( - ... ) == Configuration({}).dict() - True - >>> Configuration(yaml.safe_load(create_yaml_from_template({}, - ... template='Lil BUB'))) - Traceback (most recent call last): - ... - ValueError: 'Lil BUB' is not a valid path nor a defined preconfig. - """ # noqa: E501 # pylint: disable=line-too-long - def _count_indent(line): - '''Helper method to determine indentation level - - Parameters - ---------- - line : str - - Returns - ------- - number_of_indents : int - - Examples - -------- - >>> _count_indent('No indent') - 0 - >>> _count_indent(' Four spaces') - 2 - ''' - return (len(line) - len(line.lstrip())) // 2 - - def _create_import_dict(diff): - '''Method to return a dict of only changes given a nested dict - of (dict1_value, dict2_value) tuples - - Parameters - ---------- - diff : dict - output of `dct_diff` - - Returns - ------- - dict - dict of only changed values - - Examples - -------- - >>> _create_import_dict({'anatomical_preproc': { - ... 'brain_extraction': {'extraction': { - ... 'run': ([True], False), - ... 'using': (['3dSkullStrip'], ['niworkflows-ants'])}}}}) - {'anatomical_preproc': {'brain_extraction': {'extraction': {'run': False, 'using': ['niworkflows-ants']}}}} - ''' # noqa: E501 # pylint: disable=line-too-long - if isinstance(diff, tuple) and len(diff) == 2: - return diff[1] - if isinstance(diff, dict): - i = {} - for k in diff: - try: - j = _create_import_dict(diff[k]) - if j != {}: - i[k] = j - except KeyError: - continue - return i - return diff - - def _format_key(key, level): - '''Helper method to format YAML keys - - Parameters - ---------- - key : str - level : int - - Returns - ------- - yaml : str - - Examples - -------- - >>> _format_key('base', 0) - '\nbase: ' - >>> _format_key('indented', 2) - '\n indented:' - ''' - return f'\n{" " * level * 2}{key}: ' - - def _format_list_items(l, # noqa: E741 # pylint:disable=invalid-name - line_level): - '''Helper method to handle lists in the YAML - - Parameters - ---------- - l : list - - line_level : int - - Returns - ------- - yaml : str - - Examples - -------- - >>> _format_list_items([1, 2, {'nested': 3}], 0) - ' - 1\n - 2\n - nested: 3' - >>> _format_list_items([1, 2, {'nested': [3, {'deep': [4]}]}], 1) - ' - 1\n - 2\n - nested:\n - 3\n - deep:\n - 4' - ''' # noqa: E501 # pylint: disable=line-too-long - # keep short, simple lists in square brackets - if all(isinstance(item, (str, bool, int, float)) for item in l): - if len(str(l)) < 50: - return str(l).replace("'", '').replace('"', '') - # list long or complex lists on lines with indented '-' lead-ins - return '\n' + '\n'.join([ - f'{indent(line_level)}{li}' for li in yaml.dump( - yaml_bool(l) - ).replace("'On'", 'On').replace("'Off'", 'Off').split('\n') - ]).rstrip() - - # set starting values - output = '' - comment = '' - space_match = r'^\s+.*' - level = 0 - nest = [] - list_item = False - list_level = 0 - line_level = 0 - template_name = template - if isinstance(d, Configuration): - d = d.dict() - try: - template = load_preconfig(template) - except BadParameter as bad_parameter: - if 'default' in template.lower(): - template = DEFAULT_PIPELINE_FILE - if not os.path.exists(template) or os.path.islink(template): - raise ValueError(f'\'{template_name}\' is not a valid path nor a ' - 'defined preconfig.') from bad_parameter - template_included = False - - # load default values - d_default = Configuration(yaml.safe_load(open(template, 'r'))).dict() - - if ( - template == DEFAULT_PIPELINE_FILE or - not dct_diff( - yaml.safe_load(open(DEFAULT_PIPELINE_FILE, 'r')), d_default) - ): - template_name = 'default' - - # update values - if include_all: - d_default.update(d) - d = _create_import_dict(dct_diff({}, d_default)) - else: - d = _create_import_dict(dct_diff(d_default, d)) - - # generate YAML from template with updated values - template_dict = yaml.safe_load(open(template, 'r')) - with open(template, 'r') as f: - for line in f: - - # persist comments and frontmatter - if line.startswith('%') or line.startswith('---') or re.match( - r'^\s*#.*$', line - ): - list_item = False - line = line.strip('\n') - comment += f'\n{line}' - elif len(line.strip()): - if re.match(space_match, line): - line_level = _count_indent(line) - else: - line_level = 0 - - # handle lists as a unit - if list_item: - if line_level < list_level - 1: - list_item = False - level = list_level - list_level = 0 - elif line.lstrip().startswith('-'): - list_item = True - list_level = line_level - 1 - - else: - # extract dict key - key_group = re.match( - r'^\s*(([a-z0-9A-Z_]+://){0,1}' - r'[a-z0-9A-Z_/][\sa-z0-9A-Z_/\.-]+)\s*:', line) - if key_group: - if not template_included: - # prepend comment from template - if len(comment.strip()): - comment = re.sub( - r'(?<=# based on )(.* pipeline)', - f'{template_name} pipeline', - comment - ) - output += comment - output += f'\nFROM: {template_name}\n' - comment = '' - template_included = True - key = key_group.group(1).strip() - - # calculate key depth - if line_level == level: - if level > 0: - nest = nest[:-1] + [key] - else: - nest = [key] - elif line_level == level + 1: - nest += [key] - elif line_level < level: - nest = nest[:line_level] + [key] - - # only include updated and new values - try: - # get updated value for key - value = lookup_nested_value(d, nest) - orig_value = lookup_nested_value(d_default, nest) - # Use 'On' and 'Off' for bools - if (isinstance(orig_value, bool) or ( - isinstance(orig_value, str) and - orig_value in {'On', 'Off'} - ) or (isinstance(orig_value, list) and all([( - isinstance(orig_item, bool) or ( - isinstance(orig_item, str) and - orig_item in {'On', 'Off'} - ) - ) for orig_item in orig_value]) - )): - value = yaml_bool(value) - # prepend comment from template - if len(comment.strip()): - output += comment - else: - output += '\n' - - # write YAML - output += _format_key(key, line_level) - if isinstance(value, list): - output += _format_list_items( - value, line_level) - elif isinstance(value, dict): - for k in value.keys(): - try: - lookup_nested_value(template_dict, - nest + [k]) - # include keys not in template - except KeyError: - output += _format_key( - k, line_level + 1) - parsed = _format_list_items( - value[k], - line_level + 1 - ) if isinstance( - value[k], list) else yaml_bool( - value[k]) - if isinstance(parsed, (int, float)): - parsed = str(parsed) - elif parsed is None: - parsed = '' - output += parsed if ( - isinstance(parsed, str) - ) else ( - '\n' + indent(line_level + 1) + - f'\n{indent(line_level + 1)}' + - yaml.dump(parsed) + '\n') - else: - output += str(value) - except KeyError: - # clear comment for excluded key - comment = '\n' - - # reset variables for loop - comment = '\n' - level = line_level - elif len(comment) > 1 and comment[-2] != '\n': - comment += '\n' - while '\n\n\n' in output: - output = output.replace('\n\n\n', '\n\n') - return output.lstrip('\n').replace('null', '') - - -def indent(line_level): - '''Function to return an indent string for a given level - - Parameters - ---------- - line_level : int - The level of indentation to return - - Returns - ------- - str - The string of spaces to use for indentation - ''' - return " " * (2 * line_level + 2) - - -def yaml_bool(value): - '''Helper function to give On/Off value to bools - - Parameters - ---------- - value : any - - Returns - ------- - value : any - - Examples - -------- - >>> yaml_bool(True) - 'On' - >>> yaml_bool([False, 'On', True]) - ['Off', 'On', 'On'] - ''' - yaml_lookup = { - True: 'On', 'True': 'On', 1: 'On', - False: 'Off', 'False': 'Off', 0: 'Off'} - if ( - isinstance(value, bool) or isinstance(value, str) - ) and value in yaml_lookup: - return yaml_lookup[value] - elif isinstance(value, list): - return [yaml_bool(item) for item in value] - elif isinstance(value, dict): - return {k: yaml_bool(value[k]) for k in value} - return value - - -def upgrade_pipeline_to_1_8(path): - '''Function to upgrade a C-PAC 1.7 pipeline config to C-PAC 1.8 - - Parameters - ---------- - path : str - - Returns - ------- - None - - Outputs - ------- - {path}.{now}.bak - original file - - path - upgraded file - ''' - # back up original config - now = datetime.isoformat(datetime.now()).replace(':', '_') - backup = f'{path}.{now}.bak' - print(f'Backing up {path} to {backup} and upgrading to C-PAC 1.8') - original = open(path, 'r').read() - open(backup, 'w').write(original) - # upgrade and overwrite - orig_dict = yaml.safe_load(original) - # set Regressor 'Name's if not provided - regressors = orig_dict.get('Regressors') - if isinstance(regressors, list): - for i, regressor in enumerate(regressors): - if 'Name' not in regressor: - regressor['Name'] = f'Regressor-{str(i + 1)}' - if 'pipelineName' in orig_dict and len(original.strip()): - middle_dict, leftovers_dict, complete_dict = update_config_dict( - orig_dict) - open(path, 'w').write(create_yaml_from_template( - update_pipeline_values_1_8(middle_dict)) - ) - if leftovers_dict: - open(f'{path}.rem', 'w').write(yaml.dump(leftovers_dict)) diff --git a/Dockerfile b/Dockerfile index 57c0ffccb0..ba5b156363 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,8 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.4 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.5.dev LABEL org.opencontainers.image.description "Full C-PAC image" USER root # install C-PAC -COPY dev/docker_data/default_pipeline.yml /cpac_resources/default_pipeline.yml COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code RUN pip install -e /code diff --git a/dev/circleci_data/override_version_tag_list b/dev/circleci_data/override_version_tag_list index 06bc9053dc..cc49c6287d 100755 --- a/dev/circleci_data/override_version_tag_list +++ b/dev/circleci_data/override_version_tag_list @@ -47,7 +47,6 @@ def overwrite_list(file_diff_stats): fd[0] for fd in file_diff_stats if (( re.match(config_pattern, fd[0]) or fd[0] in { - 'dev/docker_data/default_pipeline.yml', 'version' } ) and fd[1] == '2 +-') diff --git a/dev/docker_data/default_pipeline.yml b/dev/docker_data/default_pipeline.yml index b0f83f3ac1..afe3bd37f8 100755 --- a/dev/docker_data/default_pipeline.yml +++ b/dev/docker_data/default_pipeline.yml @@ -1,1745 +1,14 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.4 +# Version 1.8.5.dev # # http://fcp-indi.github.io for more info. # # Tip: This file can be edited manually with a text editor for quick modifications. -pipeline_setup: +# The default C-PAC pipeline was relocated from `dev/docker_data/default_pipeline.yml` to `CPAC/resources/configs/pipeline_config_default.yml` +# This file (`dev/docker_data/default_pipeline.yml`) is included for backwards-compatibility and will be removed in a future version. - # Name for this pipeline configuration - useful for identification. - pipeline_name: cpac-default-pipeline - - output_directory: - - # Directory where C-PAC should write out processed data, logs, and crash reports. - # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary - # name like '/outputs', and then map (-B/-v) your desired output directory to that label. - # - If running outside a container, this should be a full path to a directory. - path: /outputs/output - - # (Optional) Path to a BIDS-Derivatives directory that already has outputs. - # - This option is intended to ingress already-existing resources from an output - # directory without writing new outputs back into the same directory. - # - If provided, C-PAC will ingress the already-computed outputs from this directory and - # continue the pipeline from where they leave off. - # - If left as 'None', C-PAC will ingress any already-computed outputs from the - # output directory you provide above in 'path' instead, the default behavior. - source_outputs_dir: None - - # Set to True to make C-PAC ingress the outputs from the primary output directory if they - # exist, even if a source_outputs_dir is provided - # - Setting to False will pull from source_outputs_dir every time, over-writing any - # calculated outputs in the main output directory - # - C-PAC will still pull from source_outputs_dir if the main output directory is - # empty, however - pull_source_once: True - - # Include extra versions and intermediate steps of functional preprocessing in the output directory. - write_func_outputs: False - - # Include extra outputs in the output directory that may be of interest when more information is needed. - write_debugging_outputs: False - - # Output directory format and structure. - # Options: default, ndmg - output_tree: "default" - - # Quality control outputs - quality_control: - # Generate quality control pages containing preprocessing and derivative outputs. - generate_quality_control_images: True - - # Generate eXtensible Connectivity Pipeline-style quality control files - generate_xcpqc_files: False - - working_directory: - - # Directory where C-PAC should store temporary and intermediate files. - # - This directory must be saved if you wish to re-run your pipeline from where you left off (if not completed). - # - NOTE: As it stores all intermediate files, this directory can grow to become very - # large, especially for data with a large amount of TRs. - # - If running in a container (Singularity/Docker), you can simply set this to an arbitrary - # name like '/work', and then map (-B/-v) your desired output directory to that label. - # - If running outside a container, this should be a full path to a directory. - # - This can be written to '/tmp' if you do not intend to save your working directory. - path: /outputs/working - - # Deletes the contents of the Working Directory after running. - # This saves disk space, but any additional preprocessing or analysis will have to be completely re-run. - remove_working_dir: True - - log_directory: - - # Whether to write log details of the pipeline run to the logging files. - run_logging: True - - path: /outputs/logs - - crash_log_directory: - - # Directory where CPAC should write crash logs. - path: /outputs/crash - - system_config: - - # Random seed used to fix the state of execution. - # If unset, each process uses its own default. - # If set, a `random.log` file will be generated logging the random seed and each node to which that seed was applied. - # If set to a positive integer (up to 2147483647), that integer will be used to seed each process that accepts a random seed. - # If set to 'random', a random positive integer (up to 2147483647) will be generated and that seed will be used to seed each process that accepts a random seed. - random_seed: - - # Select Off if you intend to run CPAC on a single machine. - # If set to On, CPAC will attempt to submit jobs through the job scheduler / resource manager selected below. - on_grid: - - run: Off - - # Sun Grid Engine (SGE), Portable Batch System (PBS), or Simple Linux Utility for Resource Management (SLURM). - # Only applies if you are running on a grid or compute cluster. - resource_manager: SGE - - SGE: - # SGE Parallel Environment to use when running CPAC. - # Only applies when you are running on a grid or compute cluster using SGE. - parallel_environment: mpi_smp - - # SGE Queue to use when running CPAC. - # Only applies when you are running on a grid or compute cluster using SGE. - queue: all.q - - # The maximum amount of memory each participant's workflow can allocate. - # Use this to place an upper bound of memory usage. - # - Warning: 'Memory Per Participant' multiplied by 'Number of Participants to Run Simultaneously' - # must not be more than the total amount of RAM. - # - Conversely, using too little RAM can impede the speed of a pipeline run. - # - It is recommended that you set this to a value that when multiplied by - # 'Number of Participants to Run Simultaneously' is as much RAM you can safely allocate. - maximum_memory_per_participant: 1 - - # Prior to running a pipeline C-PAC makes a rough estimate of a worst-case-scenario maximum concurrent memory usage with high-resoltion data, raising an exception describing the recommended minimum memory allocation for the given configuration. - # Turning this option off will allow pipelines to run without allocating the recommended minimum, allowing for more efficient runs at the risk of out-of-memory crashes (use at your own risk) - raise_insufficient: On - - # A callback.log file from a previous run can be provided to estimate memory usage based on that run. - observed_usage: - # Path to callback log file with previously observed usage. - # Can be overridden with the commandline flag `--runtime_usage`. - callback_log: - # Percent. E.g., `buffer: 10` would estimate 1.1 * the observed memory usage from the callback log provided in "usage". - # Can be overridden with the commandline flag `--runtime_buffer`. - buffer: 10 - - # The maximum amount of cores (on a single machine) or slots on a node (on a cluster/grid) - # to allocate per participant. - # - Setting this above 1 will parallelize each participant's workflow where possible. - # If you wish to dedicate multiple cores to ANTS-based anatomical registration (below), - # this value must be equal or higher than the amount of cores provided to ANTS. - # - The maximum number of cores your run can possibly employ will be this setting multiplied - # by the number of participants set to run in parallel (the 'Number of Participants to Run - # Simultaneously' setting). - max_cores_per_participant: 1 - - # The number of cores to allocate to ANTS-based anatomical registration per participant. - # - Multiple cores can greatly speed up this preprocessing step. - # - This number cannot be greater than the number of cores per participant. - num_ants_threads: 1 - - # The number of cores to allocate to processes that use OpenMP. - num_OMP_threads: 1 - - # The number of participant workflows to run at the same time. - # - The maximum number of cores your run can possibly employ will be this setting - # multiplied by the number of cores dedicated to each participant (the 'Maximum Number of Cores Per Participant' setting). - num_participants_at_once: 1 - - # Full path to the FSL version to be used by CPAC. - # If you have specified an FSL path in your .bashrc file, this path will be set automatically. - FSLDIR: /usr/share/fsl/5.0 - - Amazon-AWS: - - # If setting the 'Output Directory' to an S3 bucket, insert the path to your AWS credentials file here. - aws_output_bucket_credentials: - - # Enable server-side 256-AES encryption on data to the S3 bucket - s3_encryption: False - - Debugging: - - # Verbose developer messages. - verbose: Off - - -# PREPROCESSING -# ------------- -surface_analysis: - - # Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives. - # If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline, - # select those 'Freesurfer-' labeled options further below in anatomical_preproc. - freesurfer: - - # If anatomical_preproc['brain_extraction']['using'] includes FreeSurfer-ABCD and this switch is On, C-PAC will automatically turn this switch Off to avoid running FreeSurfer twice unnecessarily - run: Off - - # Add extra arguments to recon-all command - reconall_args: None - - # (Optional) Provide an already-existing FreeSurfer output directory to ingress already-computed surfaces - freesurfer_dir: None - - # Run ABCD-HCP post FreeSurfer and fMRISurface pipeline - post_freesurfer: - - run: Off - - subcortical_gray_labels: /opt/dcan-tools/pipeline/global/config/FreeSurferSubcorticalLabelTableLut.txt - - freesurfer_labels: /opt/dcan-tools/pipeline/global/config/FreeSurferAllLut.txt - - surf_atlas_dir: /opt/dcan-tools/pipeline/global/templates/standard_mesh_atlases - - gray_ordinates_dir: /opt/dcan-tools/pipeline/global/templates/91282_Greyordinates - - gray_ordinates_res: 2 - - high_res_mesh: 164 - - low_res_mesh: 32 - - fmri_res: 2 - - smooth_fwhm: 2 - - -longitudinal_template_generation: - - # If you have multiple T1w's, you can generate your own run-specific custom - # T1w template to serve as an intermediate to the standard template for - # anatomical registration. - - # This runs before the main pipeline as it requires multiple T1w sessions - # at once. - run: Off - - # Freesurfer longitudinal template algorithm using FSL FLIRT - # Method to average the dataset at each iteration of the template creation - # Options: median, mean or std - average_method: median - - # Degree of freedom for FLIRT in the template creation - # Options: 12 (affine), 9 (traditional), 7 (global rescale) or 6 (rigid body) - dof: 12 - - # Interpolation parameter for FLIRT in the template creation - # Options: trilinear, nearestneighbour, sinc or spline - interp: trilinear - - # Cost function for FLIRT in the template creation - # Options: corratio, mutualinfo, normmi, normcorr, leastsq, labeldiff or bbr - cost: corratio - - # Number of threads used for one run of the template generation algorithm - thread_pool: 2 - - # Threshold of transformation distance to consider that the loop converged - # (-1 means numpy.finfo(np.float64).eps and is the default) - convergence_threshold: -1 - - -anatomical_preproc: - - run: On - - run_t2: Off - - # Non-local means filtering via ANTs DenoiseImage - non_local_means_filtering: - - # this is a fork option - run: [Off] - - # options: 'Gaussian' or 'Rician' - noise_model: 'Gaussian' - - # N4 bias field correction via ANTs - n4_bias_field_correction: - - # this is a fork option - run: [Off] - - # An integer to resample the input image to save computation time. Shrink factors <= 4 are commonly used. - shrink_factor: 2 - - # Bias field correction based on square root of T1w * T2w - t1t2_bias_field_correction: - - run: Off - - BiasFieldSmoothingSigma: 5 - - acpc_alignment: - - run: Off - - # Run ACPC alignment before non-local means filtering or N4 bias - # correction - run_before_preproc: True - - # ACPC size of brain in z-dimension in mm. - # Default: 150mm for human data. - brain_size: 150 - - # Choose a tool to crop the FOV in ACPC alignment. - # Using FSL's robustfov or flirt command. - # Default: robustfov for human data, flirt for monkey data. - FOV_crop: robustfov - - # ACPC Target - # options: 'brain' or 'whole-head' - # note: 'brain' requires T1w_brain_ACPC_template below to be populated - acpc_target: 'whole-head' - - # Run ACPC alignment on brain mask - # If the brain mask is in native space, turn it on - # If the brain mask is ACPC aligned, turn it off - align_brain_mask: Off - - # ACPC aligned template - T1w_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm.nii.gz - T1w_brain_ACPC_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_1mm_brain.nii.gz - T2w_ACPC_template: None - T2w_brain_ACPC_template: None - - brain_extraction: - - run: On - - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose'] - # this is a fork option - using: ['3dSkullStrip'] - - # option parameters - AFNI-3dSkullStrip: - - # Output a mask volume instead of a skull-stripped volume. The mask volume containes 0 to 6, which represents voxel's postion. If set to True, C-PAC will use this output to generate anatomical brain mask for further analysis. - mask_vol: False - - # Set the threshold value controlling the brain vs non-brain voxels. Default is 0.6. - shrink_factor: 0.6 - - # Vary the shrink factor at every iteration of the algorithm. This prevents the likelihood of surface getting stuck in large pools of CSF before reaching the outer surface of the brain. Default is On. - var_shrink_fac: True - - # The shrink factor bottom limit sets the lower threshold when varying the shrink factor. Default is 0.4, for when edge detection is used (which is On by default), otherwise the default value is 0.65. - shrink_factor_bot_lim: 0.4 - - # Avoids ventricles while skullstripping. - avoid_vent: True - - # Set the number of iterations. Default is 250.The number of iterations should depend upon the density of your mesh. - n_iterations: 250 - - # While expanding, consider the voxels above and not only the voxels below - pushout: True - - # Perform touchup operations at the end to include areas not covered by surface expansion. - touchup: True - - # Give the maximum number of pixels on either side of the hole that can be filled. The default is 10 only if 'Touchup' is On - otherwise, the default is 0. - fill_hole: 10 - - # Perform nearest neighbor coordinate interpolation every few iterations. Default is 72. - NN_smooth: 72 - - # Perform final surface smoothing after all iterations. Default is 20. - smooth_final: 20 - - # Avoid eyes while skull stripping. Default is On. - avoid_eyes: True - - # Use edge detection to reduce leakage into meninges and eyes. Default is On. - use_edge: True - - # Speed of expansion. - exp_frac: 0.1 - - # Perform aggressive push to edge. This might cause leakage. Default is Off. - push_to_edge: False - - # Use outer skull to limit expansion of surface into the skull in case of very strong shading artifacts. Use this only if you have leakage into the skull. - use_skull: Off - - # Percentage of segments allowed to intersect surface. It is typically a number between 0 and 0.1, but can include negative values (which implies no testing for intersection). - perc_int: 0 - - # Number of iterations to remove intersection problems. With each iteration, the program automatically increases the amount of smoothing to get rid of intersections. Default is 4. - max_inter_iter: 4 - - # Multiply input dataset by FAC if range of values is too small. - fac: 1 - - # Blur dataset after spatial normalization. Recommended when you have lots of CSF in brain and when you have protruding gyri (finger like). If so, recommended value range is 2-4. Otherwise, leave at 0. - blur_fwhm: 0 - - # Set it as True if processing monkey data with AFNI - monkey: False - - FSL-BET: - - # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 - frac: 0.5 - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: On - - # Mesh created along with skull stripping - mesh_boolean: Off - - # Create a surface outline image - outline: Off - - # Add padding to the end of the image, improving BET.Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - padding: Off - - # Integer value of head radius - radius: 0 - - # Reduce bias and cleanup neck. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - reduce_bias: Off - - # Eyes and optic nerve cleanup. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - remove_eyes: Off - - # Robust brain center estimation. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - robust: Off - - # Create a skull image - skull: Off - - # Gets additional skull and scalp surfaces by running bet2 and betsurf. This is mutually exclusive with reduce_bias, robust, padding, remove_eyes - surfaces: Off - - # Apply thresholding to segmented brain image and mask - threshold: Off - - # Vertical gradient in fractional intensity threshold (-1,1) - vertical_gradient : 0.0 - - UNet: - - # UNet model - unet_model : s3://fcp-indi/resources/cpac/resources/Site-All-T-epoch_36.model - - niworkflows-ants: - - # Template to be used during niworkflows-ants. - # It is not necessary to change this path unless you intend to use a non-standard template. - - # niworkflows-ants Brain extraction template - template_path : /ants_template/oasis/T_template0.nii.gz - - # niworkflows-ants probability mask - mask_path : /ants_template/oasis/T_template0_BrainCerebellumProbabilityMask.nii.gz - - # niworkflows-ants registration mask (can be optional) - regmask_path : /ants_template/oasis/T_template0_BrainCerebellumRegistrationMask.nii.gz - - FreeSurfer-BET: - - # Template to be used for FreeSurfer-BET brain extraction in CCS-options pipeline - T1w_brain_template_mask_ccs: /ccs_template/MNI152_T1_1mm_first_brain_mask.nii.gz - - -segmentation: - - # Automatically segment anatomical images into white matter, gray matter, - # and CSF based on prior probability maps. - run: On - - tissue_segmentation: - - # using: ['FSL-FAST', 'Template_Based', 'ANTs_Prior_Based', 'FreeSurfer'] - # this is a fork point - using: ['FSL-FAST'] - - # option parameters - FSL-FAST: - - thresholding: - - # thresholding of the tissue segmentation probability maps - # options: 'Auto', 'Custom' - use: 'Auto' - - Custom: - # Set the threshold value for the segmentation probability masks (CSF, White Matter, and Gray Matter) - # The values remaining will become the binary tissue masks. - # A good starting point is 0.95. - - # CSF (cerebrospinal fluid) threshold. - CSF_threshold_value : 0.95 - - # White matter threshold. - WM_threshold_value : 0.95 - - # Gray matter threshold. - GM_threshold_value : 0.95 - - use_priors: - - # Use template-space tissue priors to refine the binary tissue masks generated by segmentation. - run: On - - # Full path to a directory containing binarized prior probability maps. - # These maps are included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use non-standard priors. - priors_path: $FSLDIR/data/standard/tissuepriors/2mm - - # Full path to a binarized White Matter prior probability map. - # It is not necessary to change this path unless you intend to use non-standard priors. - WM_path: $priors_path/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter prior probability map. - # It is not necessary to change this path unless you intend to use non-standard priors. - GM_path: $priors_path/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF prior probability map. - # It is not necessary to change this path unless you intend to use non-standard priors. - CSF_path: $priors_path/avg152T1_csf_bin.nii.gz - - Template_Based: - - # These masks should be in the same space of your registration template, e.g. if - # you choose 'EPI Template' , below tissue masks should also be EPI template tissue masks. - # - # Options: ['T1_Template', 'EPI_Template'] - template_for_segmentation: ['T1_Template'] - - # These masks are included as part of the 'Image Resource Files' package available - # on the Install page of the User Guide. - - # Full path to a binarized White Matter mask. - WHITE: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_white_bin.nii.gz - - # Full path to a binarized Gray Matter mask. - GRAY: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_gray_bin.nii.gz - - # Full path to a binarized CSF mask. - CSF: $FSLDIR/data/standard/tissuepriors/2mm/avg152T1_csf_bin.nii.gz - - ANTs_Prior_Based: - - # Generate white matter, gray matter, CSF masks based on antsJointLabelFusion - # ANTs Prior-based Segmentation workflow that has shown optimal results for non-human primate data. - - # The atlas image assumed to be used in ANTs Prior-based Segmentation. - template_brain_list : - - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_T1w_brain.nii.gz - - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_T1w_brain.nii.gz - - # The atlas segmentation images. - # For performing ANTs Prior-based segmentation method - # the number of specified segmentations should be identical to the number of atlas brain image sets. - # eg. - # ANTs_prior_seg_template_brain_list : - # - atlas1.nii.gz - # - atlas2.nii.gz - # ANTs_prior_seg_template_segmentation_list: - # - segmentation1.nii.gz - # - segmentation1.nii.gz - template_segmentation_list: - - /cpac_templates/MacaqueYerkes19_T1w_0.5mm_desc-JLC_Segmentation.nii.gz - - /cpac_templates/J_Macaque_11mo_atlas_nACQ_194x252x160space_0.5mm_desc-JLC_Segmentation.nii.gz - - # Label values corresponding to CSF/GM/WM in atlas file - # It is not necessary to change this values unless your CSF/GM/WM label values are different from Freesurfer Color Lookup Table. - # https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/AnatomicalROI/FreeSurferColorLUT - - # Label values corresponding to CSF in multiatlas file - CSF_label : [24] - - # Label values corresponding to Gray Matter in multiatlas file - GM_label : [3, 42] - - # Label values corresponding to White Matter in multiatlas file - WM_label : [2, 41] - - FreeSurfer: - - # Use mri_binarize --erode option to erode segmentation masks - erode: 0 - - # Label values corresponding to CSF in FreeSurfer aseg segmentation file - CSF_label : [24] - - # Label values corresponding to Gray Matter in FreeSurfer aseg segmentation file - GM_label : [3, 42] - - # Label values corresponding to White Matter in FreeSurfer aseg segmentation file - WM_label : [2, 41] - - -registration_workflows: - - anatomical_registration: - - run: On - - # The resolution to which anatomical images should be transformed during registration. - # This is the resolution at which processed anatomical files will be output. - resolution_for_anat: 2mm - - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain.nii.gz - - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_template: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}.nii.gz - - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - - # Register skull-on anatomical image to a template. - reg_with_skull: True - - registration: - - # using: ['ANTS', 'FSL', 'FSL-linear'] - # this is a fork point - # selecting both ['ANTS', 'FSL'] will run both and fork the pipeline - using: ['ANTS'] - - # option parameters - ANTs: - - # If a lesion mask is available for a T1w image, use it to improve the ANTs' registration - # ANTS registration only. - use_lesion_mask: False - - # ANTs parameters for T1-template-based registration - T1_registration: - - - collapse-output-transforms: 0 - - dimensionality: 3 - - initial-moving-transform : - initializationFeature: 0 - - - transforms: - - Rigid: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - Affine: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - SyN: - gradientStep : 0.1 - updateFieldVarianceInVoxelSpace : 3.0 - totalFieldVarianceInVoxelSpace : 0.0 - metric: - type : CC - metricWeight: 1 - radius : 4 - convergence: - iteration : 100x100x70x20 - convergenceThreshold : 1e-09 - convergenceWindowSize : 15 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 6x4x2x1 - use-histogram-matching : True - winsorize-image-intensities : - lowerQuantile : 0.01 - upperQuantile : 0.99 - - # Interpolation method for writing out transformed anatomical images. - # Possible values: Linear, BSpline, LanczosWindowedSinc - interpolation: LanczosWindowedSinc - - FSL-FNIRT: - - # Configuration file to be used by FSL to set FNIRT parameters. - # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. - fnirt_config: T1_2_MNI152_2mm - - # The resolution to which anatomical images should be transformed during registration. - # This is the resolution at which processed anatomical files will be output. - # specifically for monkey pipeline - ref_resolution: 2mm - - # Reference mask for FSL registration. - ref_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz - - # Template to be used during registration. - # It is for monkey pipeline specifically. - FNIRT_T1w_brain_template: None - - # Template to be used during registration. - # It is for monkey pipeline specifically. - FNIRT_T1w_template: None - - # Interpolation method for writing out transformed anatomical images. - # Possible values: trilinear, sinc, spline - interpolation: sinc - - # Identity matrix used during FSL-based resampling of anatomical-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat - - # Reference mask for FSL registration. - ref_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_dil.nii.gz - - # Reference mask with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. - ref_mask_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm_brain_mask_dil.nii.gz - - # Template with 2mm resolution to be used during FNIRT-based brain extraction in ABCD-options pipeline. - T1w_template_res-2: /usr/share/fsl/5.0/data/standard/MNI152_T1_2mm.nii.gz - - overwrite_transform: - - run: Off - - # Choose the tool to overwrite transform, currently only support 'FSL' to overwrite 'ANTs' transforms in ABCD-options pipeline. - # using: 'FSL' - using: FSL - - functional_registration: - - coregistration: - # functional (BOLD/EPI) registration to anatomical (structural/T1) - - run: On - - # reference: 'brain' or 'restore-brain' - # In ABCD-options pipeline, 'restore-brain' is used as coregistration reference - reference: brain - - # Choose FSL or ABCD as coregistration method - using: FSL - - # Choose brain or whole-head as coregistration input - input: brain - - # Choose coregistration interpolation - interpolation: trilinear - - # Choose coregistration cost function - cost: corratio - - # Choose coregistration degree of freedom - dof: 6 - - # Extra arguments for FSL flirt - arguments: None - - func_input_prep: - - # Choose whether to use functional brain or skull as the input to functional-to-anatomical registration - reg_with_skull: Off - - # Choose whether to use the mean of the functional/EPI as the input to functional-to-anatomical registration or one of the volumes from the functional 4D timeseries that you choose. - # input: ['Mean_Functional', 'Selected_Functional_Volume', 'fmriprep_reference'] - input: ['Mean_Functional'] - - Mean Functional: - - # Run ANTs’ N4 Bias Field Correction on the input BOLD (EPI) - # this can increase tissue contrast which may improve registration quality in some data - n4_correct_func: False - - Selected Functional Volume: - - # Only for when 'Use as Functional-to-Anatomical Registration Input' is set to 'Selected Functional Volume'. - #Input the index of which volume from the functional 4D timeseries input file you wish to use as the input for functional-to-anatomical registration. - func_reg_input_volume: 0 - - boundary_based_registration: - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [On] - - # Standard FSL 5.0 Scheduler used for Boundary Based Registration. - # It is not necessary to change this path unless you intend to use non-standard MNI registration. - bbr_schedule: /usr/share/fsl/5.0/etc/flirtsch/bbr.sch - - # reference for boundary based registration - # options: 'whole-head' or 'brain' - reference: whole-head - - # choose which FAST map to generate BBR WM mask - # options: 'probability_map', 'partial_volume_map' - bbr_wm_map: 'probability_map' - - # optional FAST arguments to generate BBR WM mask - bbr_wm_mask_args: '-thr 0.5 -bin' - - EPI_registration: - - # directly register the mean functional to an EPI template - # instead of applying the anatomical T1-to-template transform to the functional data that has been - # coregistered to anatomical/T1 space - run: Off - - # using: ['ANTS', 'FSL', 'FSL-linear'] - # this is a fork point - # ex. selecting both ['ANTS', 'FSL'] will run both and fork the pipeline - using: ['ANTS'] - - # EPI template for direct functional-to-template registration - # (bypassing coregistration and the anatomical-to-template transforms) - EPI_template: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz - - # EPI template mask. - EPI_template_mask: None - - ANTs: - - # EPI registration configuration - synonymous with T1_registration - # parameters under anatomical registration above - parameters: - - - collapse-output-transforms: 0 - - dimensionality: 3 - - initial-moving-transform : - initializationFeature: 0 - - - transforms: - - Rigid: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - Affine: - gradientStep : 0.1 - metric : - type : MI - metricWeight: 1 - numberOfBins : 32 - samplingStrategy : Regular - samplingPercentage : 0.25 - convergence: - iteration : 1000x500x250x100 - convergenceThreshold : 1e-08 - convergenceWindowSize : 10 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 8x4x2x1 - use-histogram-matching : True - - - SyN: - gradientStep : 0.1 - updateFieldVarianceInVoxelSpace : 3.0 - totalFieldVarianceInVoxelSpace : 0.0 - metric: - type : CC - metricWeight: 1 - radius : 4 - convergence: - iteration : 100x100x70x20 - convergenceThreshold : 1e-09 - convergenceWindowSize : 15 - smoothing-sigmas : 3.0x2.0x1.0x0.0 - shrink-factors : 6x4x2x1 - use-histogram-matching : True - winsorize-image-intensities : - lowerQuantile : 0.01 - upperQuantile : 0.99 - - # Interpolation method for writing out transformed EPI images. - # Possible values: Linear, BSpline, LanczosWindowedSinc - interpolation: LanczosWindowedSinc - - FSL-FNIRT: - - # Configuration file to be used by FSL to set FNIRT parameters. - # It is not necessary to change this path unless you intend to use custom FNIRT parameters or a non-standard template. - fnirt_config: T1_2_MNI152_2mm - - # Interpolation method for writing out transformed EPI images. - # Possible values: trilinear, sinc, spline - interpolation: sinc - - # Identity matrix used during FSL-based resampling of BOLD-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat - - func_registration_to_template: - - # these options modify the application (to the functional data), not the calculation, of the - # T1-to-template and EPI-to-template transforms calculated earlier during registration - - # apply the functional-to-template (T1 template) registration transform to the functional data - run: On - - # apply the functional-to-template (EPI template) registration transform to the functional data - run_EPI: Off - - output_resolution: - - # The resolution (in mm) to which the preprocessed, registered functional timeseries outputs are written into. - # NOTE: - # selecting a 1 mm or 2 mm resolution might substantially increase your RAM needs- these resolutions should be selected with caution. - # for most cases, 3 mm or 4 mm resolutions are suggested. - # NOTE: - # this also includes the single-volume 3D preprocessed functional data, - # such as the mean functional (mean EPI) in template space - func_preproc_outputs: 3mm - - # The resolution (in mm) to which the registered derivative outputs are written into. - # NOTE: - # this is for the single-volume functional-space outputs (i.e. derivatives) - # thus, a higher resolution may not result in a large increase in RAM needs as above - func_derivative_outputs: 3mm - - target_template: - # choose which template space to transform derivatives towards - # using: ['T1_template', 'EPI_template'] - # this is a fork point - # NOTE: - # this will determine which registration transform to use to warp the functional - # outputs and derivatives to template space - using: ['T1_template'] - - T1_template: - - # Standard Skull Stripped Template. Used as a reference image for functional registration. - # This can be different than the template used as the reference/fixed for T1-to-template registration. - T1w_brain_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain.nii.gz - - # Standard Anatomical Brain Image with Skull. - # This can be different than the template used as the reference/fixed for T1-to-template registration. - T1w_template_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}.nii.gz - - # Template to be used during registration. - # It is not necessary to change this path unless you intend to use a non-standard template. - T1w_brain_template_mask_funcreg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${func_resolution}_brain_mask.nii.gz - - # a standard template for resampling if using float resolution - T1w_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz - - EPI_template: - - # EPI template for direct functional-to-template registration - # (bypassing coregistration and the anatomical-to-template transforms) - EPI_template_funcreg: s3://fcp-indi/resources/cpac/resources/epi_hbn.nii.gz - - # EPI template mask. - EPI_template_mask_funcreg: None - - # a standard template for resampling if using float resolution - EPI_template_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz - - ANTs_pipelines: - - # Interpolation method for writing out transformed functional images. - # Possible values: Linear, BSpline, LanczosWindowedSinc - interpolation: LanczosWindowedSinc - - FNIRT_pipelines: - - # Interpolation method for writing out transformed functional images. - # Possible values: trilinear, sinc, spline - interpolation: sinc - - # Identity matrix used during FSL-based resampling of functional-space data throughout the pipeline. - # It is not necessary to change this path unless you intend to use a different template. - identity_matrix: /usr/share/fsl/5.0/etc/flirtsch/ident.mat - - apply_transform: - - # options: 'default', 'abcd', 'single_step_resampling', 'dcan_nhp' - # 'default': apply func-to-anat and anat-to-template transforms on motion corrected functional image. - # 'single_step_resampling': apply motion correction, func-to-anat and anat-to-template transforms on each of PREPROCESSED functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. - # 'abcd': apply motion correction, func-to-anat and anat-to-template transforms on each of raw functional volume using FSL applywarp based on ABCD-HCP pipeline. - # 'single_step_resampling_from_stc': apply motion correction, func-to-anat and anat-to-template transforms on each of slice-time-corrected functional volume using ANTs antsApplyTransform based on fMRIPrep pipeline. - using: 'default' - - -functional_preproc: - - run: On - - truncation: - - # First timepoint to include in analysis. - # Default is 0 (beginning of timeseries). - # First timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. - # Note: the selection here applies to all scans of all participants. - start_tr: 0 - - # Last timepoint to include in analysis. - # Default is None or End (end of timeseries). - # Last timepoint selection in the scan parameters in the data configuration file, if present, will over-ride this selection. - # Note: the selection here applies to all scans of all participants. - stop_tr: None - - scaling: - - # Scale functional raw data, usually used in rodent pipeline - run: Off - - # Scale the size of the dataset voxels by the factor. - scaling_factor: 10 - - despiking: - - # Run AFNI 3dDespike - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - slice_timing_correction: - - # Interpolate voxel time courses so they are sampled at the same time points. - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [On] - - # use specified slice time pattern rather than one in header - tpattern: None - - # align each slice to given time offset - # The default alignment time is the average of the 'tpattern' values (either from the dataset header or from the tpattern option). - tzero: None - - motion_estimates_and_correction: - - run: On - - motion_estimates: - - # calculate motion statistics BEFORE slice-timing correction - calculate_motion_first: Off - - # calculate motion statistics AFTER motion correction - calculate_motion_after: On - - motion_correction: - - # using: ['3dvolreg', 'mcflirt'] - # this is a fork point - using: ['3dvolreg'] - - # option parameters - AFNI-3dvolreg: - - # This option is useful when aligning high-resolution datasets that may need more alignment than a few voxels. - functional_volreg_twopass: On - - # Choose motion correction reference. Options: mean, median, selected_volume, fmriprep_reference - motion_correction_reference: ['mean'] - - # Choose motion correction reference volume - motion_correction_reference_volume: 0 - - motion_estimate_filter: - - # Filter physiological (respiration) artifacts from the head motion estimates. - # Adapted from DCAN Labs filter. - # https://www.ohsu.edu/school-of-medicine/developmental-cognition-and-neuroimaging-lab - # https://www.biorxiv.org/content/10.1101/337360v1.full.pdf - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - # options: "notch", "lowpass" - filter_type: "notch" - - # Number of filter coefficients. - filter_order: 4 - - # Dataset-wide respiratory rate data from breathing belt. - # Notch filter requires either: - # "breathing_rate_min" and "breathing_rate_max" - # or - # "center_frequency" and "filter_bandwitdh". - # Lowpass filter requires either: - # "breathing_rate_min" - # or - # "lowpass_cutoff". - # If "breathing_rate_min" (for lowpass and notch filter) - # and "breathing_rate_max" (for notch filter) are set, - # the values set in "lowpass_cutoff" (for lowpass filter), - # "center_frequency" and "filter_bandwidth" (for notch filter) - # options are ignored. - - # Lowest Breaths-Per-Minute in dataset. - # For both notch and lowpass filters. - breathing_rate_min: - - # Highest Breaths-Per-Minute in dataset. - # For notch filter. - breathing_rate_max: - - # notch filter direct customization parameters - - # mutually exclusive with breathing_rate options above. - # If breathing_rate_min and breathing_rate_max are provided, - # the following parameters will be ignored. - - # the center frequency of the notch filter - center_frequency: - - # the width of the notch filter - filter_bandwidth: - - # lowpass filter direct customization parameter - - # mutually exclusive with breathing_rate options above. - # If breathing_rate_min is provided, the following - # parameter will be ignored. - - # the frequency cutoff of the filter - lowpass_cutoff: - - distortion_correction: - - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [On] - - # using: ['PhaseDiff', 'Blip', 'Blip-FSL-TOPUP'] - # PhaseDiff - Perform field map correction using a single phase difference image, a subtraction of the two phase images from each echo. Default scanner for this method is SIEMENS. - # Blip - Uses AFNI 3dQWarp to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - # Blip-FSL-TOPUP - Uses FSL TOPUP to calculate the distortion unwarp for EPI field maps of opposite/same phase encoding direction. - using: ['PhaseDiff', 'Blip'] - - # option parameters - PhaseDiff: - - # Since the quality of the distortion heavily relies on the skull-stripping step, we provide a choice of method ('AFNI' for AFNI 3dSkullStrip or 'BET' for FSL BET). - # Options: 'BET' or 'AFNI' - fmap_skullstrip_option: 'BET' - - # Set the fraction value for the skull-stripping of the magnitude file. Depending on the data, a tighter extraction may be necessary in order to prevent noisy voxels from interfering with preparing the field map. - # The default value is 0.5. - fmap_skullstrip_BET_frac: 0.5 - - # Set the threshold value for the skull-stripping of the magnitude file. Depending on the data, a tighter extraction may be necessary in order to prevent noisy voxels from interfering with preparing the field map. - # The default value is 0.6. - fmap_skullstrip_AFNI_threshold: 0.6 - - Blip-FSL-TOPUP: - - # (approximate) resolution (in mm) of warp basis for the different sub-sampling levels, default 10 - warpres: 10 - - # sub-sampling scheme, default 1 - subsamp: 1 - - # FWHM (in mm) of gaussian smoothing kernel, default 8 - fwhm: 8 - - # Max # of non-linear iterations, default 5 - miter: 5 - - # Weight of regularisation, default depending on --ssqlambda and --regmod switches. See user documentation. - lambda: 1 - - # If set (=1), lambda is weighted by current ssq, default 1 - ssqlambda: 1 - - # Model for regularisation of warp-field [membrane_energy bending_energy], default bending_energy - regmod: bending_energy - - # Estimate movements if set, default 1 (true) - estmov: 1 - - # Minimisation method 0=Levenberg-Marquardt, 1=Scaled Conjugate Gradient, default 0 (LM) - minmet: 0 - - # Order of spline, 2->Qadratic spline, 3->Cubic spline. Default=3 - splineorder: 3 - - # Precision for representing Hessian, double or float. Default double - numprec: double - - # Image interpolation model, linear or spline. Default spline - interp: spline - - # If set (=1), the images are individually scaled to a common mean, default 0 (false) - scale: 0 - - # If set (=1), the calculations are done in a different grid, default 1 (true) - regrid: 1 - - func_masking: - - # using: ['AFNI', 'FSL', 'FSL_AFNI', 'Anatomical_Refined', 'Anatomical_Based', 'Anatomical_Resampled', 'CCS_Anatomical_Refined'] - - # FSL_AFNI: fMRIPrep-style BOLD mask. Ref: https://github.com/nipreps/niworkflows/blob/a221f612/niworkflows/func/util.py#L246-L514 - # Anatomical_Refined: 1. binarize anat mask, in case it is not a binary mask. 2. fill holes of anat mask 3. init_bold_mask : input raw func → dilate init func brain mask 4. refined_bold_mask : input motion corrected func → dilate anatomical mask 5. get final func mask - # Anatomical_Based: Generate the BOLD mask by basing it off of the anatomical brain mask. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. - # Anatomical_Resampled: Resample anatomical brain mask in standard space to get BOLD brain mask in standard space. Adapted from DCAN Lab's BOLD mask method from the ABCD pipeline. ("Create fMRI resolution standard space files for T1w image, wmparc, and brain mask […] don't use FLIRT to do spline interpolation with -applyisoxfm for the 2mm and 1mm cases because it doesn't know the peculiarities of the MNI template FOVs") - # CCS_Anatomical_Refined: Generate the BOLD mask by basing it off of the anatomical brain. Adapted from the BOLD mask method from the CCS pipeline. - - # this is a fork point - using: ['AFNI'] - - FSL-BET: - - # Apply to 4D FMRI data, if bold_bet_functional_mean_boolean : Off. - # Mutually exclusive with functional, reduce_bias, robust, padding, remove_eyes, surfaces - # It must be 'on' if select 'reduce_bias', 'robust', 'padding', 'remove_eyes', or 'bet_surfaces' on - functional_mean_boolean: Off - - # Set an intensity threshold to improve skull stripping performances of FSL BET on rodent scans. - functional_mean_thr: - run: Off - threshold_value: 98 - - # Bias correct the functional mean image to improve skull stripping performances of FSL BET on rodent scans - functional_mean_bias_correction: Off - - # Set the threshold value controling the brain vs non-brain voxels. - frac: 0.3 - - # Mesh created along with skull stripping - mesh_boolean: Off - - # Create a surface outline image - outline: Off - - # Add padding to the end of the image, improving BET.Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - padding: Off - - # Integer value of head radius - radius: 0 - - # Reduce bias and cleanup neck. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - reduce_bias: Off - - # Eyes and optic nerve cleanup. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - remove_eyes: Off - - # Robust brain center estimation. Mutually exclusive with functional,reduce_bias,robust,padding,remove_eyes,surfaces - robust: Off - - # Create a skull image - skull: Off - - # Gets additional skull and scalp surfaces by running bet2 and betsurf. This is mutually exclusive with reduce_bias, robust, padding, remove_eyes - surfaces: Off - - # Apply thresholding to segmented brain image and mask - threshold: Off - - # Vertical gradient in fractional intensity threshold (-1,1) - vertical_gradient: 0.0 - - FSL_AFNI: - - bold_ref: - - brain_mask: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - - brain_probseg: /usr/share/fsl/5.0/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask.nii.gz - - Anatomical_Refined: - - # Choose whether or not to dilate the anatomical mask if you choose 'Anatomical_Refined' as the functional masking option. It will dilate one voxel if enabled. - anatomical_mask_dilation: False - - # Apply functional mask in native space - apply_func_mask_in_native_space: On - - generate_func_mean: - - # Generate mean functional image - run: On - - normalize_func: - - # Normalize functional image - run: On - - -nuisance_corrections: - - 1-ICA-AROMA: - - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [Off] - - # Types of denoising strategy: - # nonaggr: nonaggressive-partial component regression - # aggr: aggressive denoising - denoising_type: nonaggr - - 2-nuisance_regression: - - # this is a fork point - # run: [On, Off] - this will run both and fork the pipeline - run: [On] - - # switch to Off if nuisance regression is off and you don't want to write out the regressors - create_regressors: On - - # Select which nuisance signal corrections to apply - Regressors: - - - Name: 'default' - - Motion: - include_delayed: true - include_squared: true - include_delayed_squared: true - - aCompCor: - summary: - method: DetrendPC - components: 5 - tissues: - - WhiteMatter - - CerebrospinalFluid - extraction_resolution: 2 - - CerebrospinalFluid: - summary: Mean - extraction_resolution: 2 - erode_mask: true - - GlobalSignal: - summary: Mean - - PolyOrt: - degree: 2 - - Bandpass: - bottom_frequency: 0.01 - top_frequency: 0.1 - method: default - - - Name: 'defaultNoGSR' - - Motion: - include_delayed: true - include_squared: true - include_delayed_squared: true - - aCompCor: - summary: - method: DetrendPC - components: 5 - tissues: - - WhiteMatter - - CerebrospinalFluid - extraction_resolution: 2 - - CerebrospinalFluid: - summary: Mean - extraction_resolution: 2 - erode_mask: true - - PolyOrt: - degree: 2 - - Bandpass: - bottom_frequency: 0.01 - top_frequency: 0.1 - method: default - - # Standard Lateral Ventricles Binary Mask - # used in CSF mask refinement for CSF signal-related regressions - lateral_ventricles_mask: $FSLDIR/data/atlases/HarvardOxford/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz - - # Whether to run frequency filtering before or after nuisance regression. - # Options: 'After' or 'Before' - bandpass_filtering_order: 'After' - - # Process and refine masks used to produce regressors and time series for - # regression. - regressor_masks: - - erode_anatomical_brain_mask: - - # Erode binarized anatomical brain mask. If choosing True, please also set regressor_masks['erode_csf']['run']: True; anatomical_preproc['brain_extraction']['using']: niworkflows-ants. - run: Off - - # Target volume ratio, if using erosion. - # Default proportion is None for anatomical brain mask. - # If using erosion, using both proportion and millimeters is not recommended. - brain_mask_erosion_prop: - - # Erode brain mask in millimeters, default for brain mask is 30 mm - # Brain erosion default is using millimeters. - brain_mask_erosion_mm: 30 - - # Erode binarized brain mask in millimeter - brain_erosion_mm: - - erode_csf: - - # Erode binarized csf tissue mask. - run: Off - - # Target volume ratio, if using erosion. - # Default proportion is None for cerebrospinal fluid mask. - # If using erosion, using both proportion and millimeters is not recommended. - csf_erosion_prop: - - # Erode cerebrospinal fluid mask in millimeters, default for cerebrospinal fluid is 30mm - # Cerebrospinal fluid erosion default is using millimeters. - csf_mask_erosion_mm: 30 - - # Erode binarized cerebrospinal fluid mask in millimeter - csf_erosion_mm: - - erode_wm: - - # Erode WM binarized tissue mask. - run: Off - - # Target volume ratio, if using erosion. - # Default proportion is 0.6 for white matter mask. - # If using erosion, using both proportion and millimeters is not recommended. - # White matter erosion default is using proportion erosion method when use erosion for white matter. - wm_erosion_prop: 0.6 - - # Erode white matter mask in millimeters, default for white matter is None - wm_mask_erosion_mm: - - # Erode binarized white matter mask in millimeters - wm_erosion_mm: - - erode_gm: - - # Erode gray matter binarized tissue mask. - run: Off - - # Target volume ratio, if using erosion. - # If using erosion, using both proportion and millimeters is not recommended. - gm_erosion_prop: 0.6 - - # Erode gray matter mask in millimeters - gm_mask_erosion_mm: - - # Erode binarized gray matter mask in millimeters - gm_erosion_mm: - - -# OUTPUTS AND DERIVATIVES -# ----------------------- -post_processing: - - spatial_smoothing: - - # Smooth the derivative outputs. - # Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both. - # - # Options: - # ['smoothed', 'nonsmoothed'] - output: ['smoothed'] - - # Tool to use for smoothing. - # 'FSL' for FSL MultiImageMaths for FWHM provided - # 'AFNI' for AFNI 3dBlurToFWHM for FWHM provided - smoothing_method: ['FSL'] - - # Full Width at Half Maximum of the Gaussian kernel used during spatial smoothing. - # this is a fork point - # i.e. multiple kernels - fwhm: [4,6,8] - fwhm: [4] - - z-scoring: - - # z-score standardize the derivatives. This may be needed for group-level analysis. - # Set as ['raw'] to disable z-scoring. Set as ['z-scored', 'raw'] to get both. - # - # Options: - # ['z-scored', 'raw'] - output: ['z-scored'] - - -timeseries_extraction: - - run: On - - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for time-series extraction, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and SpatialReg, you would enter: '/path/to/ROI.nii.gz': Avg, SpatialReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, Voxel, SpatialReg - tse_roi_paths: - /cpac_templates/CC400.nii.gz: Avg - /cpac_templates/aal_mask_pad.nii.gz: Avg - /cpac_templates/CC200.nii.gz: Avg - /cpac_templates/tt_mask_pad.nii.gz: Avg - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: SpatialReg - /cpac_templates/ho_mask_pad.nii.gz: Avg - /cpac_templates/rois_3mm.nii.gz: Avg - /ndmg_atlases/label/Human/AAL_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/CAPRSC_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/DKT_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/DesikanKlein_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/HarvardOxfordcort-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/HarvardOxfordsub-maxprob-thr25_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Juelich_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/MICCAI_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer1000_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer200_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer300_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Schaefer400_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Talairach_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Brodmann_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Desikan_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Glasser_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Slab907_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-17-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-17_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-7-liberal_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - /ndmg_atlases/label/Human/Yeo-7_space-MNI152NLin6_res-1x1x1.nii.gz: Avg - - # Functional time-series and ROI realignment method: ['ROI_to_func'] or ['func_to_ROI'] - # 'ROI_to_func' will realign the atlas/ROI to functional space (fast) - # 'func_to_ROI' will realign the functional time series to the atlas/ROI space - # - # NOTE: in rare cases, realigning the ROI to the functional space may - # result in small misalignments for very small ROIs - please double - # check your data if you see issues - realignment: 'ROI_to_func' - - connectivity_matrix: - # Create a connectivity matrix from timeseries data - - # Options: - # ['AFNI', 'Nilearn', 'ndmg'] - using: - - Nilearn - - ndmg - # Options: - # ['Pearson', 'Partial'] - # Note: These options are not configurable for ndmg, which will ignore these options - measure: - - Pearson - - Partial - - -seed_based_correlation_analysis: - - # SCA - Seed-Based Correlation Analysis - # For each extracted ROI Average time series, CPAC will generate a whole-brain correlation map. - # It should be noted that for a given seed/ROI, SCA maps for ROI Average time series will be the same. - run: Off - - # Enter paths to region-of-interest (ROI) NIFTI files (.nii or .nii.gz) to be used for seed-based correlation analysis, and then select which types of analyses to run. - # Denote which analyses to run for each ROI path by listing the names below. For example, if you wish to run Avg and MultReg, you would enter: '/path/to/ROI.nii.gz': Avg, MultReg - # available analyses: - # /path/to/atlas.nii.gz: Avg, DualReg, MultReg - sca_roi_paths: - /cpac_templates/PNAS_Smith09_rsn10.nii.gz: DualReg - /cpac_templates/CC400.nii.gz: Avg, MultReg - /cpac_templates/ez_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/aal_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/CC200.nii.gz: Avg, MultReg - /cpac_templates/tt_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/ho_mask_pad.nii.gz: Avg, MultReg - /cpac_templates/rois_3mm.nii.gz: Avg, MultReg - - # Normalize each time series before running Dual Regression SCA. - norm_timeseries_for_DR: True - - -amplitude_low_frequency_fluctuation: - - # ALFF & f/ALFF - # Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels. - run: On - - # Frequency cutoff (in Hz) for the high-pass filter used when calculating f/ALFF. - highpass_cutoff: [0.01] - - # Frequency cutoff (in Hz) for the low-pass filter used when calculating f/ALFF - lowpass_cutoff: [0.1] - - -regional_homogeneity: - - # ReHo - # Calculate Regional Homogeneity (ReHo) for all voxels. - run: On - - # Number of neighboring voxels used when calculating ReHo - # 7 (Faces) - # 19 (Faces + Edges) - # 27 (Faces + Edges + Corners) - cluster_size: 27 - - -voxel_mirrored_homotopic_connectivity: - - # VMHC - # Calculate Voxel-mirrored Homotopic Connectivity (VMHC) for all voxels. - run: On - - symmetric_registration: - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_brain_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_symmetric.nii.gz - - # A reference symmetric brain template for resampling - T1w_brain_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - T1w_template_symmetric: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_symmetric.nii.gz - - # A reference symmetric skull template for resampling - T1w_template_symmetric_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_symmetric.nii.gz - - # Included as part of the 'Image Resource Files' package available on the Install page of the User Guide. - # It is not necessary to change this path unless you intend to use a non-standard symmetric template. - dilated_symmetric_brain_mask: $FSLDIR/data/standard/MNI152_T1_${resolution_for_anat}_brain_mask_symmetric_dil.nii.gz - - # A reference symmetric brain mask template for resampling - dilated_symmetric_brain_mask_for_resample: $FSLDIR/data/standard/MNI152_T1_1mm_brain_mask_symmetric_dil.nii.gz - - -network_centrality: - - # Calculate Degree, Eigenvector Centrality, or Functional Connectivity Density. - run: On - - # Maximum amount of RAM (in GB) to be used when calculating Degree Centrality. - # Calculating Eigenvector Centrality will require additional memory based on the size of the mask or number of ROI nodes. - memory_allocation: 1.0 - - # Full path to a NIFTI file describing the mask. Centrality will be calculated for all voxels within the mask. - template_specification_file: /cpac_templates/Mask_ABIDE_85Percent_GM.nii.gz - - degree_centrality: - - # Enable/Disable degree centrality by selecting the connectivity weights - # weight_options: ['Binarized', 'Weighted'] - # disable this type of centrality with: - # weight_options: [] - weight_options: ['Binarized', 'Weighted'] - - # Select the type of threshold used when creating the degree centrality adjacency matrix. - # options: - # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' - correlation_threshold_option: 'Sparsity threshold' - - # Based on the Threshold Type selected above, enter a Threshold Value. - # P-value for Significance Threshold - # Sparsity value for Sparsity Threshold - # Pearson's r value for Correlation Threshold - correlation_threshold: 0.001 - - eigenvector_centrality: - - # Enable/Disable eigenvector centrality by selecting the connectivity weights - # weight_options: ['Binarized', 'Weighted'] - # disable this type of centrality with: - # weight_options: [] - weight_options: ['Weighted'] - - # Select the type of threshold used when creating the eigenvector centrality adjacency matrix. - # options: - # 'Significance threshold', 'Sparsity threshold', 'Correlation threshold' - correlation_threshold_option: 'Sparsity threshold' - - # Based on the Threshold Type selected above, enter a Threshold Value. - # P-value for Significance Threshold - # Sparsity value for Sparsity Threshold - # Pearson's r value for Correlation Threshold - correlation_threshold: 0.001 - - local_functional_connectivity_density: - - # Enable/Disable lFCD by selecting the connectivity weights - # weight_options: ['Binarized', 'Weighted'] - # disable this type of centrality with: - # weight_options: [] - weight_options: ['Binarized', 'Weighted'] - - # Select the type of threshold used when creating the lFCD adjacency matrix. - # options: - # 'Significance threshold', 'Correlation threshold' - correlation_threshold_option: 'Correlation threshold' - - # Based on the Threshold Type selected above, enter a Threshold Value. - # P-value for Significance Threshold - # Sparsity value for Sparsity Threshold - # Pearson's r value for Correlation Threshold - correlation_threshold: 0.6 - - -# PACKAGE INTEGRATIONS -# -------------------- -PyPEER: - - # Training of eye-estimation models. Commonly used for movies data/naturalistic viewing. - run: Off - - # PEER scan names to use for training - # Example: ['peer_run-1', 'peer_run-2'] - eye_scan_names: [] - - # Naturalistic viewing data scan names to use for eye estimation - # Example: ['movieDM'] - data_scan_names: [] - - # Template-space eye mask - eye_mask_path: $FSLDIR/data/standard/MNI152_T1_${func_resolution}_eye_mask.nii.gz - - # PyPEER Stimulus File Path - # This is a file describing the stimulus locations from the calibration sequence. - stimulus_path: None - - minimal_nuisance_correction: - - # PyPEER Minimal nuisance regression - # Note: PyPEER employs minimal preprocessing - these choices do not reflect what runs in the main pipeline. - # PyPEER uses non-nuisance-regressed data from the main pipeline. - - # Global signal regression (PyPEER only) - peer_gsr: True - - # Motion scrubbing (PyPEER only) - peer_scrub: False - - # Motion scrubbing threshold (PyPEER only) - scrub_thresh: 0.2 +# import full default pipeline +FROM: default diff --git a/dev/docker_data/required_afni_pkgs.txt b/dev/docker_data/required_afni_pkgs.txt index 27007b6499..b87e81669a 100755 --- a/dev/docker_data/required_afni_pkgs.txt +++ b/dev/docker_data/required_afni_pkgs.txt @@ -7,6 +7,7 @@ linux_openmp_64/3dCM linux_openmp_64/3dDegreeCentrality linux_openmp_64/3dDespike linux_openmp_64/3dDetrend +linux_openmp_64/3ddot linux_openmp_64/3dUnifize linux_openmp_64/3dECM linux_openmp_64/3dedge3 @@ -31,12 +32,19 @@ linux_openmp_64/3dTstat linux_openmp_64/3dvolreg linux_openmp_64/afni linux_openmp_64/libcoxplot.a +linux_openmp_64/libcoxplot.so linux_openmp_64/libf2c.a +linux_openmp_64/libf2c.so linux_openmp_64/libGLws.a +linux_openmp_64/libGLws.so linux_openmp_64/libgts.a +linux_openmp_64/libgts.so linux_openmp_64/libmri.a +linux_openmp_64/libmri.so linux_openmp_64/libmrix.a +linux_openmp_64/libmrix.so linux_openmp_64/libSUMA.a +linux_openmp_64/libSUMA.so linux_openmp_64/model_beta.so linux_openmp_64/model_constant.so linux_openmp_64/model_conv_cosine4.so diff --git a/dev/docker_data/run.py b/dev/docker_data/run.py index cf60e7a2c7..a3a95e1c2c 100755 --- a/dev/docker_data/run.py +++ b/dev/docker_data/run.py @@ -1,20 +1,20 @@ #!/usr/bin/env python -"""Copyright (C) 2022 C-PAC Developers +# Copyright (C) 2018-2023 C-PAC Developers -This file is part of C-PAC. +# This file is part of C-PAC. -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see .""" +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . import argparse import datetime import os @@ -22,37 +22,33 @@ import sys import time import shutil +from warnings import simplefilter +from nipype import logging import yaml - from CPAC import license_notice, __version__ from CPAC.pipeline import AVAILABLE_PIPELINE_CONFIGS from CPAC.pipeline.random_state import set_up_random_state -from CPAC.utils.bids_utils import create_cpac_data_config, \ +from CPAC.pipeline.schema import str_to_bool1_1 +from CPAC.utils.bids_utils import cl_strip_brackets, \ + create_cpac_data_config, \ load_cpac_data_config, \ load_yaml_config, \ sub_list_filter_by_labels -from CPAC.utils.configuration import Configuration +from CPAC.utils.configuration import Configuration, preconfig_yaml, set_subject from CPAC.utils.docs import DOCS_URL_PREFIX -from CPAC.utils.monitoring import log_nodes_cb -from CPAC.utils.yaml_template import create_yaml_from_template, \ - upgrade_pipeline_to_1_8 -from CPAC.utils.utils import cl_strip_brackets, load_preconfig, \ - update_nested_dict - -import yamlordereddictloader -from warnings import simplefilter, warn +from CPAC.utils.monitoring import failed_to_start, log_nodes_cb +from CPAC.utils.configuration.yaml_template import create_yaml_from_template, \ + hash_data_config, \ + upgrade_pipeline_to_1_8 +from CPAC.utils.utils import load_preconfig, update_nested_dict simplefilter(action='ignore', category=FutureWarning) - +logger = logging.getLogger('nipype.workflow') DEFAULT_TMP_DIR = "/tmp" -DEFAULT_PIPELINE = "/cpac_resources/default_pipeline.yml" -if not os.path.exists(DEFAULT_PIPELINE): - DEFAULT_PIPELINE = os.path.join( - os.path.dirname(os.path.realpath(__file__)), - "default_pipeline.yml" - ) -def run(command, env={}): +def run(command, env=None): + if env is None: + env = {} process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, env=env) @@ -66,11 +62,12 @@ def run(command, env={}): def parse_yaml(value): try: config = yaml.safe_load(value) - if type(config) != dict: - raise + if not isinstance(config, dict): + raise TypeError("config must be a dictionary") return config - except: - raise argparse.ArgumentTypeError("Invalid configuration: '%s'" % value) + except Exception: + # pylint: disable=raise-missing-from + raise argparse.ArgumentTypeError(f"Invalid configuration: '{value}'") def resolve_aws_credential(source): @@ -139,7 +136,7 @@ def run_main(): 'pipeline_file to read data directly from an ' 'S3 bucket. This may require AWS S3 credentials ' 'specified via the --aws_input_creds option.', - default=DEFAULT_PIPELINE) + default=preconfig_yaml('default')) parser.add_argument('--group_file', help='Path for the group analysis configuration file ' 'to use. Use the format s3://bucket/path/to/' @@ -251,11 +248,14 @@ def run_main(): parser.add_argument('--save_working_dir', nargs='?', help='Save the contents of the working directory.', default=False) - parser.add_argument('--disable_file_logging', action='store_true', - help='Disable file logging, this is useful for ' - 'clusters that have disabled file locking.', - default=False) + parser.add_argument('--save_workflow', + help='Save a serialized version of the workflow. ' + 'Can be used with `test_config` to save workflow ' + 'without running the pipeline.', + action='store_true') + parser.add_argument('--fail_fast', type=str.title, + help='Stop worklow execution on first crash?') parser.add_argument('--participant_label', help='The label of the participant that should be ' 'analyzed. The label corresponds to ' @@ -361,7 +361,7 @@ def run_main(): output_dir_is_s3 = args.output_dir.lower().startswith("s3://") output_dir = args.output_dir if output_dir_is_s3 else os.path.realpath( args.output_dir) - + exitcode = 0 if args.analysis_level == "cli": from CPAC.__main__ import main main.main(args=sys.argv[sys.argv.index('--') + 1:]) @@ -470,9 +470,8 @@ def run_main(): _url = (f'{DOCS_URL_PREFIX}/user/pipelines/' '1.7-1.8-nesting-mappings') - warn('\nC-PAC changed its pipeline configuration format in ' - f'v1.8.0.\nSee {_url} for details.\n', - category=DeprecationWarning) + logger.warning('\nC-PAC changed its pipeline configuration ' + 'format in v1.8.0.\nSee %s for details.\n', _url) updated_config = os.path.join( output_dir, @@ -599,8 +598,6 @@ def run_main(): c['pipeline_setup']['system_config']['observed_usage'][ 'buffer'] = args.runtime_buffer - c['disable_log'] = args.disable_file_logging - if args.save_working_dir is not False: c['pipeline_setup']['working_directory'][ 'remove_working_dir'] = False @@ -611,10 +608,17 @@ def run_main(): c['pipeline_setup']['working_directory']['path'] = \ os.path.join(output_dir, "working") else: - warn('Cannot write working directory to S3 bucket. ' - 'Either change the output directory to something ' - 'local or turn off the --save_working_dir flag', - category=UserWarning) + logger.warning('Cannot write working directory to S3 bucket. ' + 'Either change the output directory to something ' + 'local or turn off the --save_working_dir flag') + + c['pipeline_setup']['log_directory']['save_workflow'] = \ + args.save_workflow or \ + c['pipeline_setup']['log_directory'].get('save_workflow', False) + + if args.fail_fast is not None: + c['pipeline_setup', 'system_config', + 'fail_fast'] = str_to_bool1_1(args.fail_fast) if c['pipeline_setup']['output_directory']['quality_control'][ 'generate_xcpqc_files']: @@ -655,23 +659,9 @@ def run_main(): c['pipeline_setup']['system_config']['num_ants_threads'])) # create a timestamp for writing config files + # pylint: disable=invalid-name st = datetime.datetime.now().strftime('%Y-%m-%dT%H-%M-%SZ') - # update config file - if not output_dir_is_s3: - pipeline_config_file = os.path.join( - output_dir, "cpac_pipeline_config_{0}.yml".format(st) - ) - else: - pipeline_config_file = os.path.join( - DEFAULT_TMP_DIR, "cpac_pipeline_config_{0}.yml".format(st) - ) - - open(pipeline_config_file, 'w').write( - create_yaml_from_template(c, DEFAULT_PIPELINE, True)) - open(f'{pipeline_config_file[:-4]}_min.yml', 'w').write( - create_yaml_from_template(c, DEFAULT_PIPELINE, False)) - if args.participant_label: args.participant_label = cl_strip_brackets(args.participant_label) args.participant_label = [ @@ -721,8 +711,9 @@ def run_main(): sub_list[participant_ndx]["subject_id"] )) sub_list = [sub_list[participant_ndx]] - data_config_file = "cpac_data_config_idx-%s_%s.yml" % ( - args.participant_ndx, st) + data_hash = hash_data_config(sub_list) + data_config_file = (f"cpac_data_config_{data_hash}_idx-" + f"{args.participant_ndx}_{st}.yml") else: print("Participant ndx {0} is out of bounds [0, {1})".format( participant_ndx, @@ -730,20 +721,40 @@ def run_main(): )) sys.exit(1) else: - # write out the data configuration file - data_config_file = "cpac_data_config_{0}.yml".format(st) - - if not output_dir_is_s3: - data_config_file = os.path.join(output_dir, data_config_file) - else: - data_config_file = os.path.join(DEFAULT_TMP_DIR, data_config_file) + data_hash = hash_data_config(sub_list) + data_config_file = (f"cpac_data_config_{data_hash}_{st}.yml") - with open(data_config_file, 'w') as f: + sublogdirs = [set_subject(sub, c)[2] for sub in sub_list] + # write out the data configuration file + data_config_file = os.path.join(sublogdirs[0], data_config_file) + with open(data_config_file, 'w', encoding='utf-8') as _f: noalias_dumper = yaml.dumper.SafeDumper noalias_dumper.ignore_aliases = lambda self, data: True - yaml.dump(sub_list, f, default_flow_style=False, + yaml.dump(sub_list, _f, default_flow_style=False, Dumper=noalias_dumper) + # update and write out pipeline config file + pipeline_config_file = os.path.join( + sublogdirs[0], f"cpac_pipeline_config_{data_hash}_{st}.yml") + with open(pipeline_config_file, 'w', encoding='utf-8') as _f: + _f.write(create_yaml_from_template(c)) + minimized_config = f'{pipeline_config_file[:-4]}_min.yml' + with open(minimized_config, 'w', encoding='utf-8') as _f: + _f.write(create_yaml_from_template(c, import_from='blank')) + for config_file in (data_config_file, pipeline_config_file, + minimized_config): + os.chmod(config_file, 0o444) # Make config files readonly + + if len(sublogdirs) > 1: + # If more than one run is included in the given data config + # file, an identical copy of the data and pipeline config + # will be included in the log directory for each run + for sublogdir in sublogdirs[1:]: + for config_file in (data_config_file, pipeline_config_file, + minimized_config): + os.link(config_file, config_file.replace( + sublogdirs[0], sublogdir)) + if args.analysis_level in ["participant", "test_config"]: # build pipeline easy way from CPAC.utils.monitoring import monitor_server @@ -777,7 +788,7 @@ def run_main(): 'observed_usage']['buffer']} print("Starting participant level processing") - CPAC.pipeline.cpac_runner.run( + exitcode = CPAC.pipeline.cpac_runner.run( data_config_file, pipeline_config_file, plugin='MultiProc' if plugin_args[ @@ -792,16 +803,26 @@ def run_main(): monitoring.join(10) if args.analysis_level == "test_config": - print( - '\nPipeline and data configuration files should' - ' have been written to {0} and {1} respectively.'.format( - pipeline_config_file, - data_config_file - ) - ) + if exitcode == 0: + logger.info( + '\nPipeline and data configuration files should' + ' have been written to %s and %s respectively.\n', + pipeline_config_file, data_config_file) + + # wait to import `LOGTAIL` here so it has any runtime updates + from CPAC.utils.monitoring import LOGTAIL + for warning in LOGTAIL['warnings']: + logger.warning('%s\n', warning.rstrip()) - sys.exit(0) + sys.exit(exitcode) if __name__ == '__main__': - run_main() + try: + run_main() + except Exception as exception: + # if we hit an exception before the pipeline starts to build but + # we're still able to create a logfile, log the error in the file + failed_to_start(sys.argv[2] if len(sys.argv) > 2 else os.getcwd(), + exception) + raise exception diff --git a/requirements.txt b/requirements.txt index 429bd30465..aa7dbf8b2b 100755 --- a/requirements.txt +++ b/requirements.txt @@ -12,17 +12,19 @@ nilearn==0.4.1 nipype==1.5.1 nose==1.3.7 numpy==1.21.0 -pandas==0.23.4 +pandas==1.0.5 +pathvalidate==2.5.2 patsy==0.5.0 prov==1.5.2 psutil==5.6.6 -pybids==0.13.2 +pybids==0.15.1 git+https://git@github.com/ChildMindInstitute/PyPEER.git#egg=PyPEER python-dateutil==2.7.3 pyyaml==5.4 yamlordereddictloader==0.4.0 requests==2.21.0 -scipy==1.4.1 +scipy==1.6.3 +sdcflows==2.0.5 simplejson==3.15.0 scikit-learn==0.22.1 traits==4.6.0 diff --git a/setup.py b/setup.py index 5dc757a7e9..4a1fd59694 100755 --- a/setup.py +++ b/setup.py @@ -62,10 +62,6 @@ def main(**extra_args): REQUIREMENTS, ) - # copy default pipeline into package - open('CPAC/resources/configs/default_pipeline.yml', 'w').write( - open('dev/docker_data/default_pipeline.yml', 'r').read()) - setup( name=NAME, maintainer=MAINTAINER, diff --git a/variant-ABCD-HCP.Dockerfile b/variant-ABCD-HCP.Dockerfile index 84c623e680..73381a21ee 100755 --- a/variant-ABCD-HCP.Dockerfile +++ b/variant-ABCD-HCP.Dockerfile @@ -1,9 +1,8 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.4 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.5.dev LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" USER root # install C-PAC -COPY dev/docker_data/default_pipeline.yml /cpac_resources/default_pipeline.yml COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code RUN pip install -e /code diff --git a/variant-fMRIPrep-LTS.Dockerfile b/variant-fMRIPrep-LTS.Dockerfile index 1533bcd5e5..8e891ce2d7 100755 --- a/variant-fMRIPrep-LTS.Dockerfile +++ b/variant-fMRIPrep-LTS.Dockerfile @@ -1,9 +1,8 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.4 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.5.dev LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" USER root # install C-PAC & set up runscript -COPY dev/docker_data/default_pipeline.yml /cpac_resources/default_pipeline.yml COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code RUN pip install -e /code diff --git a/version b/version index 5f7363595e..bb667f9c3e 100755 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.4 +v1.8.5 From 34996845eb08d4e729a4eb5f0bb065a353b645a1 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 22 Mar 2023 17:17:24 -0400 Subject: [PATCH 036/213] :pencil2: Remove extra copyright notice --- CPAC/utils/monitoring/custom_logging.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/CPAC/utils/monitoring/custom_logging.py b/CPAC/utils/monitoring/custom_logging.py index f37c2169fb..467380dab1 100644 --- a/CPAC/utils/monitoring/custom_logging.py +++ b/CPAC/utils/monitoring/custom_logging.py @@ -2,8 +2,6 @@ # This file is part of C-PAC. -# Copyright (C) 2022-2023 C-PAC Developers - # C-PAC is free software: you can redistribute it and/or modify it under # the terms of the GNU Lesser General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your From 01ca39990cedfb31653a59d06cd560c2f9d37191 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 22 Mar 2023 17:19:36 -0400 Subject: [PATCH 037/213] fixup! Merge pull request #1911 from shnizzedy/feature/surface_derivatives --- .github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile | 8 ++++---- CPAC/info.py | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile b/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile index e2ad01a017..7be0df66c8 100755 --- a/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile +++ b/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile @@ -133,9 +133,10 @@ ENV PATH="/usr/local/miniconda/bin:$PATH" \ PYTHONNOUSERSITE=1 # install conda dependencies -RUN conda update conda -y && \ - conda install nomkl && \ - conda install -y \ +RUN conda install -n base conda-forge::mamba conda-forge::libarchive==3.5.2 -y && \ + mamba update conda -y && \ + mamba install nomkl -y && \ + mamba install -y \ blas \ cython \ matplotlib==2.2.2 \ @@ -143,7 +144,6 @@ RUN conda update conda -y && \ nose==1.3.7 \ numpy==1.15.4 \ pandas==1.0.5 \ - scipy==1.6.3 \ traits==4.6.0 \ pip diff --git a/CPAC/info.py b/CPAC/info.py index 4dface457e..63bed6f40b 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -178,7 +178,7 @@ def get_cpac_gitversion(): "future", "INDI-Tools", "lockfile==0.12.2", - "joblib==1.0.1", + "joblib==1.1.0", "matplotlib==3.1.3", "networkx==2.4", "nibabel==3.2.1", @@ -203,6 +203,5 @@ def get_cpac_gitversion(): "traits==4.6.0", "PyBASC==0.4.5", "voluptuous>=0.12.0", - "joblib==1.1.0", "ciftify", ] From af7314b7016859dda024c5b70acb239a7c501523 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 23 Mar 2023 19:43:31 +0000 Subject: [PATCH 038/213] made minor modifications to files to correct for run errors --- CPAC/anat_preproc/anat_preproc.py | 4 +++- CPAC/resources/cpac_outputs.tsv | 2 +- CPAC/surface/surf_preproc.py | 8 ++++---- CPAC/utils/utils.py | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index fad2199e0a..3a949e3e7a 100755 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -911,6 +911,7 @@ def freesurfer_brain_connector(wf, cfg, strat_pool, pipe_num, opt): def freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt): + ### ABCD harmonization - anatomical brain mask generation ### # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh#L151-L156 @@ -921,8 +922,9 @@ def freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt): function=mri_convert), name=f'wmparc_to_nifti_{pipe_num}') wmparc_to_nifti.inputs.args = '-rt nearest' - + node, out = strat_pool.get_data('pipeline-fs_wmparc') + wf.connect(node, out, wmparc_to_nifti, 'in_file') node, out = strat_pool.get_data('desc-preproc_T1w') diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 73880cd74f..b948775639 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -295,7 +295,7 @@ hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func CIFTI dscalar hemi-L_space-fsLR_den-32k_sulc surface_derived func GIFTI shape hemi-R_space-fsLR_den-32k_sulc surface_derived func GIFTI shape -"space-fsLR_den-32k_sulc""" surface_derived func CIFTI dscalar +space-fsLR_den-32k_sulc surface_derived func CIFTI dscalar hemi-L_space-fsLR_den-32k_thickness surface_derived func GIFTI shape hemi-R_space-fsLR_den-32k_thickness surface_derived func GIFTI shape space-fsLR_den-32k_thickness surface_derived func CIFTI dscalar diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index d2d215b89e..88e0be305a 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -771,10 +771,10 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): "space-template_desc-brain_bold", "space-template_desc-motion_bold", "space-template_bold"])], "outputs": ["space-fsLR_den-32k_bold", - "atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", - "atlas-Destrieux_space-fsLR_den-32k_dlabel", - "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", - "atlas-Destrieux_space-fsLR_den-164k_dlabel", + "atlas-DesikanKilliany_space-fsLR_den-32k", + "atlas-Destrieux_space-fsLR_den-32k", + "atlas-DesikanKilliany_space-fsLR_den-164k", + "atlas-Destrieux_space-fsLR_den-164k", "space-fsLR_den-32k_bold-dtseries", "AtlasSubcortical_s2", "goodvoxels", diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py index 51d8ea3935..1de9b3aa3a 100755 --- a/CPAC/utils/utils.py +++ b/CPAC/utils/utils.py @@ -150,8 +150,8 @@ def read_json(json_file): def create_id_string(cfg, unique_id, resource, scan_id=None, - template_desc=None, atlas_id=None, fwhm=None, subdir=None - ): + template_desc=None, atlas_id=None, fwhm=None, subdir=None, + extension=None): """Create the unique key-value identifier string for BIDS-Derivatives compliant file names. From f09ff0c8640b4e8204e2f9ce6b0dc272d8878728 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 23 Mar 2023 20:15:38 +0000 Subject: [PATCH 039/213] tissue prior files for base-ABCD-HCP.Dockerfile --- .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile index b70be7e0c0..c6dee59c80 100755 --- a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile +++ b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile @@ -45,6 +45,11 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl /usr/share/fsl COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ COPY --from=FSL /usr/lib/lib*so* /usr/lib/ + +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/2mm /usr/share/fsl/5.0/data/standard/tissuepriors +COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ +COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/3mm /usr/share/fsl/5.0/data/standard/tissuepriors + # set up FSL environment ENV FSLDIR=/usr/share/fsl/5.0 \ FSL_DIR=/usr/share/fsl/5.0 \ From c36c83b7374457dffd22f541da5768598efe7a6b Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 29 Mar 2023 10:33:40 -0400 Subject: [PATCH 040/213] :rewind: Revert "tissue prior files for base-ABCD-HCP.Dockerfile" This reverts commit f09ff0c8640b4e8204e2f9ce6b0dc272d8878728. --- .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile index c6dee59c80..b70be7e0c0 100755 --- a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile +++ b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile @@ -45,11 +45,6 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl /usr/share/fsl COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ COPY --from=FSL /usr/lib/lib*so* /usr/lib/ - -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/2mm /usr/share/fsl/5.0/data/standard/tissuepriors -COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/tissuepriors/3mm /usr/share/fsl/5.0/data/standard/tissuepriors - # set up FSL environment ENV FSLDIR=/usr/share/fsl/5.0 \ FSL_DIR=/usr/share/fsl/5.0 \ From 938d565b581edca7395ec63ce4afa7bdcee2965a Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 29 Mar 2023 10:44:19 -0400 Subject: [PATCH 041/213] :construction_worker: Install workbench with deprecated signature --- .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile index b70be7e0c0..8b923cb024 100755 --- a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile +++ b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile @@ -79,7 +79,7 @@ RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key adv --keyserver keyserver.ubu APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 648ACFD622F3D138 && \ APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DCC9EFBF77E11517 && \ printf '\ndeb http://httpredir.debian.org/debian/ buster main non-free' >> /etc/apt/sources.list && \ - apt-get update && \ + apt-get update --allow-insecure-repositories && \ apt-get install connectome-workbench=1.3.2-1 -y && \ strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 ENV PATH=/usr:$PATH From fbfa207cd171f10896e7448dbc4d9f4426f90df4 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 29 Mar 2023 20:37:22 +0000 Subject: [PATCH 042/213] changed output file name of node surface based falff and alff --- CPAC/surface/surf_preproc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 88e0be305a..c81d5a2d2a 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -876,7 +876,7 @@ def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): wf.connect(node, out, falff, 'dtseries') outputs = { - 'surf_falff': (falff,'surf_falff')} + 'space-fsLR_den-32k_bold_surf_falff': (falff,'surf_falff')} return wf, outputs def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): @@ -890,7 +890,7 @@ def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out,alff, 'dtseries') outputs = { - 'surf_alff': (alff,'surf_alff')} + 'space-fsLR_den-32k_bold_surf_alff': (alff,'surf_alff')} return wf, outputs def cal_reho(wf, cfg, strat_pool, pipe_num, opt): @@ -1001,7 +1001,7 @@ def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": ["space-fsLR_den-32k_bold"], - "outputs": ["surf_falff"]} + "outputs": ["space-fsLR_den-32k_bold_surf_falff"]} ''' wf, outputs = cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt) @@ -1015,7 +1015,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): "option_key": "None", "option_val": "None", "inputs": ["space-fsLR_den-32k_bold"], - "outputs": ["surf_alff"]} + "outputs": ["space-fsLR_den-32k_bold_surf_alff"]} ''' wf, outputs = cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt) From 2591cd7a29e6a2b52d40fd19b1497c0a2fe70d90 Mon Sep 17 00:00:00 2001 From: Teresa George Date: Mon, 17 Apr 2023 10:43:51 -0400 Subject: [PATCH 043/213] Added surface parcellation atlas --- CPAC/pipeline/schema.py | 4 +- CPAC/resources/cpac_templates.csv | 85 ++++++++++++++++--------------- 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 23c9618f3a..2535d0c1f1 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -985,7 +985,9 @@ def sanitize(filename): for option in ['using', 'measure'] }, }, - 'surface_connectivity': {'run': bool}, + 'surface_connectivity': { + 'run': bool, + 'surface_parcellation_template':Maybe(str) }, 'seed_based_correlation_analysis': { 'run': bool1_1, Optional('roi_paths_fully_specified'): bool1_1, diff --git a/CPAC/resources/cpac_templates.csv b/CPAC/resources/cpac_templates.csv index 492c43bf1d..e89df7c08c 100755 --- a/CPAC/resources/cpac_templates.csv +++ b/CPAC/resources/cpac_templates.csv @@ -1,42 +1,43 @@ -Key,Pipeline_Config_Entry,Description,Intended_Resolution_Config_Entry -CSF-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, CSF_path",Template-space CSF tissue prior, -dilated-symmetric-brain-mask,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" -dilated-symmetric-brain-mask-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask_for_resample",, -EPI-template,"registration_workflows, functional_registration, EPI_registration, EPI_template",EPI-based template, -EPI-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -EPI-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_for_resample",, -EPI-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -EPI-template-mask,"registration_workflows, functional_registration, EPI_registration, EPI_template_mask",Binary brain mask of the EPI template, -FSL-AFNI-bold-ref,"functional_preproc, func_masking, FSL_AFNI, bold_ref",bold_ref for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -FSL-AFNI-brain-mask,"functional_preproc, func_masking, FSL_AFNI, brain_mask",brain_mask for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -FSL-AFNI-brain-probseg,"functional_preproc, func_masking, FSL_AFNI, brain_probseg",brain_probseg for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -FNIRT-T1w-brain-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_brain_template",Additional T1w brain-only template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" -FNIRT-T1w-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_template",Additional T1w whole-head template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" -GM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, GM_path",Template-space GM tissue prior, -lateral-ventricles-mask,"nuisance_corrections, 2-nuisance_regression, lateral_ventricles_mask",, -T1w-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_ACPC_template",, -T1w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_brain_ACPC_template",, -T1w-brain-template,"registration_workflows, anatomical_registration, T1w_brain_template",T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-brain-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-brain-template-mask,"registration_workflows, anatomical_registration, T1w_brain_template_mask",Binary brain mask of the T1w template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric",Symmetric version of the T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_funcreg","Symmetric version of the T1w-based skull-stripped template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-brain-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_for_resample",, -T1w-template,"registration_workflows, anatomical_registration, T1w_template",T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_for_resample",, -T1w-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric",Symmetric version of the T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_funcreg","Symmetric version of the T1w-based whole-head template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_for_resample",, -template-ref-mask,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" -template-ref-mask-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask_res-2",, -T1w-template-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, T1w_template_res-2",, -template-specification-file,"network_centrality, template_specification_file",Binary ROI mask for network centrality calculations, -unet-model,"anatomical_preproc, brain_extraction, UNet, unet_model",, -WM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, WM_path",Template-space WM tissue prior, -template-eye-mask,"PyPEER, eye_mask_path",,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-brain-template-mask-ccs,"anatomical_preproc, brain_extraction, FreeSurfer-BET, T1w_brain_template_mask_ccs",, -T2w-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_ACPC_template",Whole-head template for use in ACPC-alignment, -T2w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_brain_ACPC_template",Brain-only template for use in ACPC-alignment, +Key,Pipeline_Config_Entry,Description,Intended_Resolution_Config_Entry +CSF-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, CSF_path",Template-space CSF tissue prior, +dilated-symmetric-brain-mask,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" +dilated-symmetric-brain-mask-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask_for_resample",, +EPI-template,"registration_workflows, functional_registration, EPI_registration, EPI_template",EPI-based template, +EPI-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +EPI-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_for_resample",, +EPI-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +EPI-template-mask,"registration_workflows, functional_registration, EPI_registration, EPI_template_mask",Binary brain mask of the EPI template, +FSL-AFNI-bold-ref,"functional_preproc, func_masking, FSL_AFNI, bold_ref",bold_ref for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +FSL-AFNI-brain-mask,"functional_preproc, func_masking, FSL_AFNI, brain_mask",brain_mask for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +FSL-AFNI-brain-probseg,"functional_preproc, func_masking, FSL_AFNI, brain_probseg",brain_probseg for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +FNIRT-T1w-brain-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_brain_template",Additional T1w brain-only template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" +FNIRT-T1w-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_template",Additional T1w whole-head template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" +GM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, GM_path",Template-space GM tissue prior, +lateral-ventricles-mask,"nuisance_corrections, 2-nuisance_regression, lateral_ventricles_mask",, +T1w-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_ACPC_template",, +T1w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_brain_ACPC_template",, +T1w-brain-template,"registration_workflows, anatomical_registration, T1w_brain_template",T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-brain-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-brain-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +T1w-brain-template-mask,"registration_workflows, anatomical_registration, T1w_brain_template_mask",Binary brain mask of the T1w template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-brain-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric",Symmetric version of the T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-brain-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_funcreg","Symmetric version of the T1w-based skull-stripped template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-brain-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_for_resample",, +T1w-template,"registration_workflows, anatomical_registration, T1w_template",T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_for_resample",, +T1w-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +T1w-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric",Symmetric version of the T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_funcreg","Symmetric version of the T1w-based whole-head template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_for_resample",, +template-ref-mask,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" +template-ref-mask-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask_res-2",, +T1w-template-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, T1w_template_res-2",, +template-specification-file,"network_centrality, template_specification_file",Binary ROI mask for network centrality calculations, +unet-model,"anatomical_preproc, brain_extraction, UNet, unet_model",, +WM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, WM_path",Template-space WM tissue prior, +template-eye-mask,"PyPEER, eye_mask_path",,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +T1w-brain-template-mask-ccs,"anatomical_preproc, brain_extraction, FreeSurfer-BET, T1w_brain_template_mask_ccs",, +T2w-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_ACPC_template",Whole-head template for use in ACPC-alignment, +T2w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_brain_ACPC_template",Brain-only template for use in ACPC-alignment, +surface-parcellation-atlas,"surface_connectivity, surface_parcellation_template",surface space parcellation atlas, \ No newline at end of file From 4f1ed468f154f3bdb8669f26a6ceda70c2ef0ca1 Mon Sep 17 00:00:00 2001 From: Teresa George Date: Mon, 17 Apr 2023 10:53:59 -0400 Subject: [PATCH 044/213] made edits to schema.py --- CPAC/pipeline/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 2535d0c1f1..144a37a83e 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -987,7 +987,7 @@ def sanitize(filename): }, 'surface_connectivity': { 'run': bool, - 'surface_parcellation_template':Maybe(str) }, + 'surface_parcellation_template':Maybe(str) }, 'seed_based_correlation_analysis': { 'run': bool1_1, Optional('roi_paths_fully_specified'): bool1_1, From 0938756990602b6148ff57dd5bbe053095a4a3cc Mon Sep 17 00:00:00 2001 From: Teresa George Date: Wed, 19 Apr 2023 13:33:51 -0400 Subject: [PATCH 045/213] modified surf_preproc and outputs.tsv --- C-PAC_templates | 1 + CPAC/resources/cpac_outputs.tsv | 9 ++++++--- CPAC/surface/surf_preproc.py | 6 +++--- 3 files changed, 10 insertions(+), 6 deletions(-) create mode 160000 C-PAC_templates diff --git a/C-PAC_templates b/C-PAC_templates new file mode 160000 index 0000000000..040483823e --- /dev/null +++ b/C-PAC_templates @@ -0,0 +1 @@ +Subproject commit 040483823ed075bcaa32548c53153bbb0483285f diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index b948775639..c4bd806d40 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -221,7 +221,7 @@ space-EPItemplate_label-CSF_mask mask template func NIfTI space-EPItemplate_label-WM_mask mask template func NIfTI space-EPItemplate_label-GM_mask mask template func NIfTI mdmr group functional group_analysis NIfTI -desc-zstd-mdmr group functional group_analysis NIfTI Yes +desc-zstd-mdmr group functional group_analysis NIfTI Yes AtlasSubcortical_s2 surface_derived func space-fsLR_den-32k_bold surface_derived func CIFTI dtseries goodvoxels surface_derived func @@ -309,5 +309,8 @@ atlas-DesikanKilliany_space-fsLR_den-32k surface_derived func CIFTI dlabel atlas-Destrieux_space-fsLR_den-32k surface_derived func CIFTI dlabel atlas-DesikanKilliany_space-fsLR_den-164k surface_derived func CIFTI dlabel atlas-Destrieux_space-fsLR_den-164k surface_derived func CIFTI dlabel -surf_alff surface_derived func CIFTI dscalar -surf_falff surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf_falff surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf_alff surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf-L_reho surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf-R_reho surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf-correlation_matrix surface_derived func CIFTI dscalar \ No newline at end of file diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index c81d5a2d2a..0119a22cad 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -961,8 +961,8 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): wf.connect(node, out, R_reho, 'dtseries') outputs = { - 'surf-L_reho': (L_reho,'L_reho'), - 'surf-R_reho': (R_reho,'R_reho')} + 'space-fsLR_den-32k_bold_surf-L_reho': (L_reho,'L_reho'), + 'space-fsLR_den-32k_bold_surf-R_reho': (R_reho,'R_reho')} return wf, outputs @@ -1033,7 +1033,7 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", "hemi-R_space-fsLR_den-32k_midthickness", "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask"], - "outputs": ["surf-L_reho", "surf-R_reho"]} + "outputs": ["space-fsLR_den-32k_bold_surf-L_reho", "space-fsLR_den-32k_bold_surf-R_reho"]} ''' wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) From 6236c5374a4c04bdafbaa2d61524bc5a50e0ca2b Mon Sep 17 00:00:00 2001 From: Teresa George Date: Wed, 19 Apr 2023 13:38:17 -0400 Subject: [PATCH 046/213] added dev version to info.py --- CPAC/info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 63bed6f40b..6920535263 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -43,8 +43,8 @@ # version _version_major = 1 _version_minor = 8 -_version_micro = 5 -_version_extra = '' +_version_micro = 6 +_version_extra = 'dev' def get_cpac_gitversion(): From 5ab54c88b12c8f704c701dd90de7d5897d0adf34 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Wed, 19 Apr 2023 17:59:14 +0000 Subject: [PATCH 047/213] :bookmark: Update version to 1.8.6.dev (added dev version to info.py) --- .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-bionic.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml | 2 +- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- CPAC/resources/configs/data_config_cpac_benchmark.yml | 2 +- CPAC/resources/configs/data_settings_template.yml | 2 +- CPAC/resources/configs/group_config_template.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-options.yml | 2 +- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml | 2 +- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_ccs-options.yml | 2 +- CPAC/resources/configs/pipeline_config_default-deprecated.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 2 +- CPAC/resources/configs/pipeline_config_fx-options.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey.yml | 2 +- CPAC/resources/configs/pipeline_config_ndmg.yml | 2 +- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 2 +- CPAC/resources/configs/pipeline_config_preproc.yml | 2 +- CPAC/resources/configs/pipeline_config_rbc-options.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-1.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-2.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-3.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-4.yml | 2 +- CPAC/resources/configs/pipeline_config_rodent.yml | 2 +- CPAC/resources/configs/system_config.yml | 2 +- CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../configs/test_configs/data-test_S3-ADHD200_no-params.yml | 2 +- .../resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-sess.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_ABCD.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_all.yml | 2 +- version | 2 +- 50 files changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 49a5f18eba..0fe6231338 100755 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.5 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile index 66410b0af6..751e18cfbc 100755 --- a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.5 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 4d20a4cd9f..600134d40e 100755 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.5 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 59b973ddf9..289ac2c574 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 957757961d..3672637818 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 1d23bd913c..d0f0c67341 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index bdeff92059..281723fe22 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 176a2c1f86..1be3c08c4d 100755 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 91290b595c..5b6643945b 100755 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index e1dee0db7c..b17756d9d8 100755 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index d1fcfc08b8..61ee4dc19a 100755 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 94fcac6ae4..242a0b9ba8 100755 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index b3b53d5862..49b722761c 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 462f46d76f..b83f925ac4 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index e233e4ced9..fb0e1b3be2 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index ef9134aad5..e8be38cb9a 100755 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index ec0bb151b8..502dd9c97e 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index f5c071624d..ad9726eb36 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index 9047ca2028..c6c7c995ec 100755 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index c605db3ea8..ecd21bd12c 100755 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 5b788e7ba6..a05244abcb 100755 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index 0455df1e74..909a9d74b4 100755 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 82962a92b0..224deddc64 100755 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index 3ed3d46aa3..fed7190478 100755 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index 67a40ad067..0b27798d94 100755 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index 11a7ccfd01..5236a711ca 100755 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index 340aefeddf..ca53b77414 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 601752e84b..0f15590423 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index f50095e6b1..2562b864ae 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 6667f71442..4eec001636 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index beeb3f2549..6f0bd43871 100755 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 8aa3e9acdb..1f27a95b6b 100755 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index 86b7b8f305..efa3278a44 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index b98533729d..0d43554a0e 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index 7047bba266..e52d1bdc8e 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index b5fcdde14c..befd96092b 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index 0fc7aeefd2..2a525907c7 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index cef30e4ab6..7ecd4674e9 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index 46399f83c0..ba11dadf8c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index bb5ea66c41..b9811649b1 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 82aa1ac2ae..e252237e57 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index a6491067f5..36884b2593 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index c5e9e532d3..d07148a28b 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 664c1d711c..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 664c1d711c..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 664c1d711c..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 664c1d711c..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 664c1d711c..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 8b653b7cae..79ab3a2376 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.5 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # diff --git a/version b/version index bb667f9c3e..8e3a967718 100755 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.5 +v1.8.6.dev From cf8543d3a6afc7a12f03ee5cfd13e379cca197cb Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 19 Apr 2023 19:42:26 +0000 Subject: [PATCH 048/213] added fsl robustfov before fsl BET in anat_preproc.py --- CPAC/anat_preproc/anat_preproc.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index fad2199e0a..a4de14837f 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -597,6 +597,10 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'vertical_gradient']), name=f'BET_options_{pipe_num}') + anat_robustfov = pe.Node( + interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + anat_robustfov.inputs.output_type = 'NIFTI_GZ' + anat_skullstrip = pe.Node( interface=fsl.BET(), name=f'anat_BET_skullstrip_{pipe_num}') anat_skullstrip.inputs.output_type = 'NIFTI_GZ' @@ -635,13 +639,15 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, anat_skullstrip, 'in_file') + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - wf.connect(node, out, anat_skullstrip, 'in_file') + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ From f264ecb328a1693a5d5857dea33f2e75bf074489 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 19 Apr 2023 20:47:25 +0000 Subject: [PATCH 049/213] using out_roi to connect anat_robustfov node to the node anat_skullstrip --- CPAC/anat_preproc/anat_preproc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index a4de14837f..85408ae358 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -642,12 +642,12 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ From b9c51d038e1eecd6f92c77391933cc2ffe2780e0 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 24 Apr 2023 17:32:34 +0000 Subject: [PATCH 050/213] modified anat_preproc.py --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 85408ae358..e851d44599 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -639,7 +639,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') From a9a8a857316d7355a73f7908b0ccb7001798ef0b Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 1 May 2023 14:37:34 +0000 Subject: [PATCH 051/213] Created an option key for robustfov that can be turned On/Off by the user in the config --- CPAC/anat_preproc/anat_preproc.py | 14 ++++++++++---- CPAC/pipeline/schema.py | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index e851d44599..7126289ce9 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -641,13 +641,19 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + else : + wf.connect(node, out, anat_skullstrip, 'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + else : + wf.connect(node, out, anat_skullstrip, 'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 0e8f8cc701..4b6ad1d5f4 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -512,6 +512,7 @@ def sanitize(filename): }, 'FSL-BET': { 'frac': Number, + 'Robustfov': bool1_1, 'mask_boolean': bool1_1, 'mesh_boolean': bool1_1, 'outline': bool1_1, From a245e748794a6a01cc6e6eac648ea79b277f4789 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 8 May 2023 15:25:49 +0000 Subject: [PATCH 052/213] added robustfov as an option is pipe config --- CPAC/anat_preproc/anat_preproc.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 7126289ce9..bd90e5a589 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -597,9 +597,6 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'vertical_gradient']), name=f'BET_options_{pipe_num}') - anat_robustfov = pe.Node( - interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') - anat_robustfov.inputs.output_type = 'NIFTI_GZ' anat_skullstrip = pe.Node( interface=fsl.BET(), name=f'anat_BET_skullstrip_{pipe_num}') @@ -638,10 +635,15 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['vertical_gradient'], ) + + anat_robustfov = pe.Node( + interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + anat_robustfov.inputs.output_type = 'NIFTI_GZ' if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') else : @@ -649,7 +651,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') else : From 2b957b8648eee878273b9747078b78d0377c1471 Mon Sep 17 00:00:00 2001 From: Teresa George Date: Fri, 19 May 2023 15:29:50 -0400 Subject: [PATCH 053/213] Added the changes to the config files --- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index e233e4ced9..3d297ad09f 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -335,7 +335,7 @@ anatomical_preproc: monkey: Off FSL-BET: - + Robustfov : On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index a2b015bf17..b32c8c6582 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -405,7 +405,7 @@ anatomical_preproc: monkey: False FSL-BET: - + Robustfov : On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From a14253a5e84058eb9f678df0b2d075ef981e6f7b Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Mon, 22 May 2023 15:27:11 +0000 Subject: [PATCH 054/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_blank.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 3d297ad09f..569a87a6c3 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -335,7 +335,8 @@ anatomical_preproc: monkey: Off FSL-BET: - Robustfov : On + Robustfov: On + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From d0746d971be92bab4f6dcd0136a6767070aca236 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Tue, 27 Jun 2023 20:29:30 +0000 Subject: [PATCH 055/213] resolving merge conflicts --- CPAC/info.py | 35 ------------------- .../configs/pipeline_config_blank.yml | 4 --- 2 files changed, 39 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 441dc1d6d9..baa503ac1f 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -169,40 +169,6 @@ def get_cpac_gitversion(): VERSION = __version__ STATUS = 'stable' REQUIREMENTS = [ -<<<<<<< HEAD - "boto3==1.7.37", - "click==6.7", - "ciftify", - "configparser==3.7.4", - "cython", - "future", - "INDI-Tools", - "lockfile==0.12.2", - "joblib==1.1.0", - "matplotlib==3.1.3", - "networkx==2.4", - "nibabel==3.2.1", - "nilearn==0.4.1", - "nipype==1.5.1", - "nose==1.3.7", - "numpy==1.21.0", - "pandas==1.0.5", - "pathvalidate==2.5.2", - "patsy==0.5.0", - "prov==1.5.2", - "psutil==5.6.6", - "pybids==0.15.1", - "pygraphviz==1.3.1", - "PyPEER", - "python-dateutil==2.7.3", - "pyyaml==5.4", - "scikit-learn==0.22.1", - "scipy==1.6.3", - "sdcflows==2.0.5", - "simplejson==3.15.0", - "traits==4.6.0", - "PyBASC==0.4.5", -======= "boto3", "click", "configparser", @@ -233,7 +199,6 @@ def get_cpac_gitversion(): "sdcflows", "traits", "PyBASC", ->>>>>>> origin/develop "voluptuous>=0.12.0", "ciftify", ] diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index d7d8eda1be..ca2835941a 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # From 6b68d549346fa647643a6666166f8b72ea458ba9 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 28 Jun 2023 16:09:33 +0000 Subject: [PATCH 056/213] Corrected for merge conflicts --- .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 4 --- .../C-PAC.develop-bionic.Dockerfile | 4 --- ...PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 4 --- .../Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 32 ------------------- .../Ubuntu.bionic-non-free.Dockerfile | 8 ----- .../configs/data_config_S3-BIDS-ABIDE.yml | 4 --- .../configs/data_config_S3-BIDS-ADHD200.yml | 4 --- .../data_config_S3-BIDS-ADHD200_only2.yml | 4 --- ...data_config_S3-BIDS-NKI-RocklandSample.yml | 4 --- .../configs/data_config_cpac_benchmark.yml | 4 --- .../configs/data_settings_template.yml | 4 --- .../configs/group_config_template.yml | 4 --- .../configs/pipeline_config_abcd-options.yml | 4 --- .../configs/pipeline_config_anat-only.yml | 4 --- .../pipeline_config_benchmark-ANTS.yml | 4 --- .../pipeline_config_benchmark-FNIRT.yml | 4 --- .../configs/pipeline_config_ccs-options.yml | 4 --- .../pipeline_config_default-deprecated.yml | 4 --- .../configs/pipeline_config_default.yml | 4 --- .../pipeline_config_fmriprep-options.yml | 4 --- .../configs/pipeline_config_fx-options.yml | 4 --- .../configs/pipeline_config_monkey-ABCD.yml | 4 --- .../configs/pipeline_config_monkey.yml | 4 --- .../configs/pipeline_config_ndmg.yml | 4 --- .../configs/pipeline_config_nhp-macaque.yml | 4 --- .../configs/pipeline_config_preproc.yml | 4 --- .../configs/pipeline_config_rbc-options.yml | 4 --- .../configs/pipeline_config_regtest-1.yml | 4 --- .../configs/pipeline_config_regtest-2.yml | 4 --- .../test_configs/data-test_S3-ADHD200_1.yml | 4 --- .../data-test_S3-ADHD200_no-params.yml | 4 --- .../test_configs/data-test_S3-NKI-RS_fmap.yml | 4 --- .../data_config_S3_CoRR_5only_mult-sess.yml | 4 --- .../configs/test_configs/pipe-test_ABCD.yml | 4 --- .../pipe-test_ANTs-3dSk-AllNuis.yml | 4 --- .../pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 4 --- .../pipe-test_ANTs-3dSk-DistCorrBET.yml | 4 --- .../pipe-test_ANTs-BET-AllNuis.yml | 4 --- .../pipe-test_FNIRT-3dSk-AllNuis.yml | 4 --- .../pipe-test_FNIRT-BET-AllNuis-BASC.yml | 4 --- .../pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 4 --- .../pipe-test_FNIRT-BET-AllNuis-ISC.yml | 4 --- .../pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 4 --- .../pipe-test_FNIRT-BET-AllNuis.yml | 4 --- .../configs/test_configs/pipe-test_all.yml | 4 --- 45 files changed, 212 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 46a0d201c5..971b1ea9be 100755 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,8 +1,4 @@ -<<<<<<< HEAD -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 -======= FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile index 7a6b041097..91ee47cedb 100755 --- a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile @@ -1,8 +1,4 @@ -<<<<<<< HEAD -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 -======= FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 06f507c865..d910c2f324 100755 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,8 +1,4 @@ -<<<<<<< HEAD -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 -======= FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile index f397f79a79..fff994087c 100755 --- a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile +++ b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile @@ -1,20 +1,3 @@ -<<<<<<< HEAD -FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free as FSL-Neurodebian - -# install CPAC resources into FSL -USER root -ENV FSLDIR=/usr/share/fsl/5.0 -RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard/tissuepriors/2mm /usr/share/fsl/5.0/data/standard/tissuepriors/3mm \ - && curl -sL http://fcon_1000.projects.nitrc.org/indi/cpac_resources.tar.gz -o /tmp/cpac_resources.tar.gz \ - && tar xfz /tmp/cpac_resources.tar.gz -C /tmp \ - && cp -n /tmp/cpac_image_resources/MNI_3mm/* $FSLDIR/data/standard \ - && cp -n /tmp/cpac_image_resources/MNI_4mm/* $FSLDIR/data/standard \ - && cp -n /tmp/cpac_image_resources/symmetric/* $FSLDIR/data/standard \ - && cp -n /tmp/cpac_image_resources/HarvardOxford-lateral-ventricles-thr25-2mm.nii.gz $FSLDIR/data/atlases/HarvardOxford \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/2mm $FSLDIR/data/standard/tissuepriors \ - && cp -nr /tmp/cpac_image_resources/tissuepriors/3mm $FSLDIR/data/standard/tissuepriors - -======= # Copyright (C) 2021-2023 C-PAC Developers # This file is part of C-PAC. @@ -32,7 +15,6 @@ RUN mkdir -p /usr/share/fsl/5.0/data/atlases /usr/share/fsl/5.0/data/standard/ti # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/fsl:data as data ->>>>>>> origin/develop FROM ghcr.io/fcp-indi/c-pac/ubuntu:bionic-non-free AS FSL USER root @@ -48,21 +30,12 @@ ENV FSLDIR=/usr/share/fsl/5.0 \ PATH=/usr/lib/fsl/5.0:$PATH \ TZ=America/New_York -<<<<<<< HEAD -# # Installing and setting up FSL -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ - && echo $TZ > /etc/timezone \ - && apt-get update \ - && apt-get install -y tclsh wish \ - && echo "Downloading FSL ..." \ -======= # Installing and setting up FSL RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ echo $TZ > /etc/timezone && \ apt-get update && \ apt-get install -y tclsh wish && \ echo "Downloading FSL ..." \ ->>>>>>> origin/develop && mkdir -p /usr/share/fsl/5.0 \ && curl -sSL --retry 5 https://fsl.fmrib.ox.ac.uk/fsldownloads/fsl-5.0.10-centos6_64.tar.gz \ | tar zx -C /usr/share/fsl/5.0 --strip-components=1 \ @@ -87,11 +60,6 @@ COPY --from=FSL /usr/bin/wish /usr/bin/wish COPY --from=FSL /usr/share/fsl/ /usr/share/fsl/ COPY --from=FSL /usr/lib/ /usr/lib/ COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -<<<<<<< HEAD -COPY --from=FSL-Neurodebian /usr/share/fsl/5.0/data/standard/ /usr/share/fsl/5.0/data/standard/ -COPY --from=FSL /lib/x86_64-linux-gnu/lib*so* /lib/x86_64-linux-gnu/ -======= # install C-PAC resources into FSL COPY --from=data /fsl_data/standard /usr/share/fsl/5.0/data/standard COPY --from=data /fsl_data/atlases /usr/share/fsl/5.0/data/atlases ->>>>>>> origin/develop diff --git a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile index 06d138c67e..62add3c5a6 100755 --- a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile +++ b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile @@ -121,19 +121,11 @@ RUN groupadd -r c-pac && \ ENV PATH=/usr/bin/nvm/versions/node/v12.12.0/bin:/usr/local/miniconda/bin:$PATH # Installing conda dependencies, torch & Python dependencies -<<<<<<< HEAD -COPY requirements.txt /opt/requirements.txt -RUN conda install -n base conda-forge::mamba conda-forge::libarchive==3.5.2 -y && \ - mamba update conda -y && \ - mamba install nomkl -y && \ - mamba install -y \ -======= COPY dev/docker_data/unpinned_requirements.txt /opt/requirements.txt RUN conda install -n base conda-forge::mamba conda-forge::libarchive==3.5.2 -y && \ mamba update conda -y && \ mamba install nomkl -y && \ mamba install -y \ ->>>>>>> origin/develop blas \ cython \ matplotlib==3.1.3 \ diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index a6446584b1..289ac2c574 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 297bdd75a5..3672637818 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 93c84a55e7..d0f0c67341 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index 62b15671f3..281723fe22 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index ce2d13bef0..1be3c08c4d 100755 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index dacf20f818..5b6643945b 100755 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,9 +1,5 @@ # CPAC Data Settings File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index 12d9d23304..b17756d9d8 100755 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,9 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index 5575dc941e..d02c17cad4 100755 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 041e9e52a1..51c6410702 100755 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index fbb17e90c6..8afc002730 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 38994a20de..ccc050c912 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index 312610db11..e8be38cb9a 100755 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 1f90b5d7c0..3c366cc761 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index e78f320453..3e8307f008 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index b5ee05cc5f..e5d14a0be0 100755 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 1fff9552c4..338902332a 100755 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 11cdb3f906..14a9666853 100755 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index c97a818251..f02709dc79 100755 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 41254ade38..e01da751ca 100755 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index e6c5c6711a..f37c0b2dc4 100755 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index 37328b065d..b2998982b1 100755 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index b68d456e4f..06277fe3ac 100755 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index 06a83401fa..f20d29fa1b 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index ae474d7c8b..3910ac9d6e 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index b684ee4208..efa3278a44 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 1eaa2d4879..0d43554a0e 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index ee8a7d501a..e52d1bdc8e 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index 5cce8b3749..2a525907c7 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 669e173531..7ecd4674e9 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index 85d8f05c36..ba11dadf8c 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 93b039a139..b9811649b1 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 7700ee4e73..e252237e57 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index e646a78a37..36884b2593 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index ba693d4009..d07148a28b 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 3e45d98eaa..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 3e45d98eaa..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 3e45d98eaa..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 3e45d98eaa..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 3e45d98eaa..26d17993c6 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index fc93120b78..79ab3a2376 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6.dev1 -======= # Version 1.8.6.dev ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # From b6610176be207c956a1afefd53f20a8f38081648 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Wed, 28 Jun 2023 16:13:00 +0000 Subject: [PATCH 057/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index bb189b1c0b..1ec654315c 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6.dev # # http://fcp-indi.github.io for more info. # From 4594e787f3b286138af09a837868aa6dcd4f53b7 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Wed, 28 Jun 2023 16:13:00 +0000 Subject: [PATCH 058/213] :bookmark: Update version to 1.8.6.dev1 (:bulb: Update comments based on default preconfig) --- .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-bionic.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml | 2 +- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- CPAC/resources/configs/data_config_cpac_benchmark.yml | 2 +- CPAC/resources/configs/data_settings_template.yml | 2 +- CPAC/resources/configs/group_config_template.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-options.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 2 +- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml | 2 +- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_ccs-options.yml | 2 +- CPAC/resources/configs/pipeline_config_default-deprecated.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 2 +- CPAC/resources/configs/pipeline_config_fx-options.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey.yml | 2 +- CPAC/resources/configs/pipeline_config_ndmg.yml | 2 +- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 2 +- CPAC/resources/configs/pipeline_config_preproc.yml | 2 +- CPAC/resources/configs/pipeline_config_rbc-options.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-1.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-2.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-3.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-4.yml | 2 +- CPAC/resources/configs/pipeline_config_rodent.yml | 2 +- CPAC/resources/configs/system_config.yml | 2 +- CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../configs/test_configs/data-test_S3-ADHD200_no-params.yml | 2 +- .../resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-sess.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_ABCD.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_all.yml | 2 +- version | 2 +- 53 files changed, 53 insertions(+), 53 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 971b1ea9be..392bb277e7 100755 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile index 91ee47cedb..cadfa017ba 100755 --- a/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index d910c2f324..64de649b85 100755 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile index 7a32a31b1f..f0a4544fd7 100755 --- a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev11 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index 9bbe5b64f3..5277bf99c5 100755 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-bionic as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev11 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 289ac2c574..66206c7df6 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 3672637818..7f3ba4eaa1 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index d0f0c67341..178836e7ea 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index 281723fe22..e49b7b9e80 100755 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 1be3c08c4d..8cfc9fe519 100755 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 5b6643945b..eac7db24c2 100755 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index b17756d9d8..8a76e27537 100755 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index d02c17cad4..260ea015d7 100755 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 1ec654315c..bb189b1c0b 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 51c6410702..65221cab41 100755 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 8afc002730..ada1e552a3 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index ccc050c912..eb2a412289 100755 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index ca2835941a..9e2d1d6473 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index e8be38cb9a..f9c1419f26 100755 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 3c366cc761..6e52076d9e 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 3e8307f008..873701f708 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index e5d14a0be0..3c7c95e92b 100755 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 338902332a..ccb1a4f7bd 100755 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 14a9666853..585eae4aa2 100755 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index f02709dc79..52099f22dc 100755 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index e01da751ca..016728f761 100755 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index f37c0b2dc4..cfaf86d5a8 100755 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index b2998982b1..b016f0cae5 100755 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index 06277fe3ac..7555a43a8e 100755 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index f20d29fa1b..eb2f9d1d17 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 3910ac9d6e..8462295430 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index 1a08403283..c094204ca5 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index da26bde773..adfb0897b1 100755 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index c277a6102b..c96f075c96 100755 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 1f27a95b6b..f9ebe8e080 100755 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index efa3278a44..69e617cb32 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 0d43554a0e..5a4c4c4677 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index e52d1bdc8e..b01d43afcf 100755 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 6ada5565c1..83c5b8deca 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -2,7 +2,7 @@ <<<<<<< HEAD # Version 1.8.6.dev1 ======= -# Version 1.8.6.dev +# Version 1.8.6.dev1 >>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index 2a525907c7..b66a606cea 100755 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 7ecd4674e9..9eea91c8bc 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index ba11dadf8c..d84362d815 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index b9811649b1..61d8d2186a 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index e252237e57..8a546496c4 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index 36884b2593..d1c7ddd7b2 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index d07148a28b..8b0c36100e 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 26d17993c6..45c76d2f7e 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 26d17993c6..45c76d2f7e 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 26d17993c6..45c76d2f7e 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 26d17993c6..45c76d2f7e 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 26d17993c6..45c76d2f7e 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 79ab3a2376..335bc4c6fb 100755 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev +# Version 1.8.6.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/version b/version index 8e3a967718..efed3fdaf4 100755 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.6.dev +v1.8.6.dev1 From a879f23dc0791dfca9febd10f148dfbcb4cba41a Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 28 Jun 2023 17:55:47 +0000 Subject: [PATCH 059/213] correcting for merge conflicts in surf_preproc.py script --- CPAC/surface/surf_preproc.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 6e85cdb4d6..96847b3903 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -36,12 +36,7 @@ def run_surface(post_freesurfer_folder, from CPAC.utils.monitoring.custom_logging import log_subprocess import os -<<<<<<< HEAD - import subprocess - -======= ->>>>>>> origin/develop recon_all_path = os.path.join(freesurfer_folder, 'recon_all') if os.path.isdir(recon_all_path): @@ -150,12 +145,7 @@ def run_surface(post_freesurfer_folder, scout_bold, '--lowresmesh', low_res_mesh, '--grayordinatesres', gray_ordinates_res, '--fmrires', fmri_res, '--smoothingFWHM', smooth_fwhm] -<<<<<<< HEAD - - subprocess.check_output(cmd) -======= log_subprocess(cmd) ->>>>>>> origin/develop dtseries = os.path.join(post_freesurfer_folder, 'MNINonLinear/Results/task-rest01/' @@ -802,7 +792,6 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): ], ) def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): -<<<<<<< HEAD ''' {"name": "surface_postproc", "config": ["surface_analysis", "post_freesurfer"], @@ -915,8 +904,6 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): "hemi-L_space-native_white", "hemi-R_space-native_white"]} ''' -======= ->>>>>>> origin/develop wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) return (wf, outputs) From 3994432daaeb0d6268663c8ad1c7d4aa51eb909a Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 29 Jun 2023 21:31:49 +0000 Subject: [PATCH 060/213] Added surface_connectivity key to pipeline_config_blank.yml and pipeline_config_default.yml --- CPAC/resources/configs/pipeline_config_blank.yml | 3 +++ CPAC/resources/configs/pipeline_config_default.yml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 9e2d1d6473..62b6224984 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1338,6 +1338,9 @@ timeseries_extraction: # check your data if you see issues realignment: ROI_to_func +surface_connectivity: + surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii + amplitude_low_frequency_fluctuation: # ALFF & f/ALFF diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 873701f708..b36a1c8f2a 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1633,6 +1633,8 @@ seed_based_correlation_analysis: # Normalize each time series before running Dual Regression SCA. norm_timeseries_for_DR: True +surface_connectivity: + surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii amplitude_low_frequency_fluctuation: From 80e2ec0cafa0dc8c5e3585238d58e7162a074627 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Thu, 29 Jun 2023 21:33:53 +0000 Subject: [PATCH 061/213] Converted the node blocks in surf_preproc.py to new NodeBlock syntax --- CPAC/surface/surf_preproc.py | 395 +++++++++++++++-------------------- 1 file changed, 170 insertions(+), 225 deletions(-) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 96847b3903..f71f4999b0 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -456,7 +456,136 @@ def run_surface(post_freesurfer_folder, StrainR['MSMSulc']['R'], StrainR['MSMSulc']['dscalar'], sulc['L'], sulc['R'], sulc['dscalar'], thickness['L'], thickness['R'], thickness['dscalar'], white['L'][164], white['L'][32], white['L']['native'], white['R'][164], white['R'][32], white['R']['native']) -def surface_connector(wf, cfg, strat_pool, pipe_num, opt): +@nodeblock( + name="surface_postproc", + config=["surface_analysis", "post_freesurfer"], + switch=["run"], + inputs=[ + ( + "freesurfer-subject-dir", + [ + "pipeline-fs_desc-restore_T1w", + "desc-preproc_T1w", + "desc-reorient_T1w", + "T1w", + "space-longitudinal_desc-reorient_T1w", + ], + [ + "space-template_desc-head_T1w", + "space-template_desc-brain_T1w", + "space-template_desc-T1w_mask", + ], + [ + "from-T1w_to-template_mode-image_xfm", + "from-T1w_to-template_mode-image_desc-linear_xfm", + ], + [ + "from-template_to-T1w_mode-image_xfm", + "from-template_to-T1w_mode-image_desc-linear_xfm", + ], + ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], + [ + "space-template_desc-scout_bold", + "space-template_desc-cleaned_bold", + "space-template_desc-brain_bold", + "space-template_desc-motion_bold", + "space-template_bold", + ], + ) + ], + outputs=[ + "space-fsLR_den-32k_bold", + "atlas-DesikanKilliany_space-fsLR_den-32k", + "atlas-Destrieux_space-fsLR_den-32k", + "atlas-DesikanKilliany_space-fsLR_den-164k", + "atlas-Destrieux_space-fsLR_den-164k", + "space-fsLR_den-32k_bold-dtseries", + "AtlasSubcortical_s2", + "goodvoxels", + "ribbon_only", + "hemi-L_space-fsLR_den-32k_desc-atlasroi_bold", + "hemi-R_space-fsLR_den-32k_desc-atlasroi_bold", + "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", + "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask", + "hemi-L_space-native_bold", + "hemi-R_space-native_bold", + "space-fsLR_den-32k_wb-spec", + "space-native_wb-spec", + "hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion", + "hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion", + "space-fsLR_den-32k_desc-FS_arealdistortion", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion", + "space-fsLR_den-32k_desc-MSMSulc_arealdistortion", + "hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion", + "hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion", + "space-fsLR_den-32k_desc-FS_edgedistortion", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion", + "space-fsLR_den-32k_desc-MSMSulc_edgedistortion", + "hemi-L_space-fsLR_den-32k_curv", + "hemi-R_space-fsLR_den-32k_curv", + "space-fsLR_den-32k_curv", + "hemi-L_space-fsLR_den-32k_flat", + "hemi-R_space-fsLR_den-32k_flat", + "hemi-L_space-fsLR_den-32k_inflated", + "hemi-R_space-fsLR_den-32k_inflated", + "hemi-L_space-fsLR_den-32k_veryinflated", + "hemi-R_space-fsLR_den-32k_veryinflated", + "hemi-L_space-native_inflated", + "hemi-R_space-native_inflated", + "hemi-L_space-native_veryinflated", + "hemi-R_space-native_veryinflated", + "hemi-L_space-fsLR_den-164k_midthickness", + "hemi-R_space-fsLR_den-164k_midthickness", + "hemi-L_space-fsLR_den-32k_midthickness", + "hemi-R_space-fsLR_den-32k_midthickness", + "hemi-L_space-native_midthickness", + "hemi-R_space-native_midthickness", + "hemi-L_space-fsLR_den-32k_pial", + "hemi-R_space-fsLR_den-32k_pial", + "hemi-L_space-native_den-32k_pial", + "hemi-R_space-native_den-32k_pial", + "hemi-L_space-fsLR_den-32k_sphere", + "hemi-R_space-fsLR_den-32k_sphere", + "hemi-L_space-native_desc-MSMSulc_sphere", + "hemi-R_space-native_desc-MSMSulc_sphere", + "hemi-L_space-native_sphere", + "hemi-R_space-native_sphere", + "hemi-L_space-native_desc-reg_sphere", + "hemi-R_space-native_desc-reg_sphere", + "hemi-L_space-native_desc-reg-reg_sphere", + "hemi-R_space-native_desc-reg-reg_sphere", + "hemi-L_space-native_desc-rot_sphere", + "hemi-R_space-native_desc-rot_sphere", + "hemi-L_space-fsLR_den-32k_desc-FS_strainJ", + "hemi-R_space-fsLR_den-32k_desc-FS_strainJ", + "space-fsLR_den-32k_desc-FS_strainJ", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ", + "space-fsLR_den-32k_desc-MSMSulc_strainJ", + "hemi-L_space-fsLR_den-32k_desc-FS_strainR", + "hemi-R_space-fsLR_den-32k_desc-FS_strainR", + "space-fsLR_den-32k_desc-FS_strainR", + "hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR", + "hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR", + "space-fsLR_den-32k_desc-MSMSulc_strainR", + "hemi-L_space-fsLR_den-32k_sulc", + "hemi-R_space-fsLR_den-32k_sulc", + "space-fsLR_den-32k_sulc", + "hemi-L_space-fsLR_den-32k_thickness", + "hemi-R_space-fsLR_den-32k_thickness", + "space-fsLR_den-32k_thickness", + "hemi-L_space-fsLR_den-164k_white", + "hemi-R_space-fsLR_den-164k_white", + "hemi-L_space-fsLR_den-32k_white", + "hemi-R_space-fsLR_den-32k_white", + "hemi-L_space-native_white", + "hemi-R_space-native_white", + ], +) + +def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): surf = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'freesurfer_folder', @@ -747,169 +876,14 @@ def surface_connector(wf, cfg, strat_pool, pipe_num, opt): @nodeblock( - name="surface_postproc", - config=["surface_analysis", "post_freesurfer"], + name="surface_falff", + config=["amplitude_low_frequency_fluctuation"], switch=["run"], - inputs=[ - ( - "freesurfer-subject-dir", - [ - "pipeline-fs_desc-restore_T1w", - "desc-preproc_T1w", - "desc-reorient_T1w", - "T1w", - "space-longitudinal_desc-reorient_T1w", - ], - [ - "space-template_desc-head_T1w", - "space-template_desc-brain_T1w", - "space-template_desc-T1w_mask", - ], - [ - "from-T1w_to-template_mode-image_xfm", - "from-T1w_to-template_mode-image_desc-linear_xfm", - ], - [ - "from-template_to-T1w_mode-image_xfm", - "from-template_to-T1w_mode-image_desc-linear_xfm", - ], - ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], - [ - "space-template_desc-scout_bold", - "space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", - "space-template_bold", - ], - ) - ], + inputs=["space-fsLR_den-32k_bold"], outputs=[ - "atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", - "atlas-Destrieux_space-fsLR_den-32k_dlabel", - "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", - "atlas-Destrieux_space-fsLR_den-164k_dlabel", - "space-fsLR_den-32k_bold-dtseries", - ], + "space-fsLR_den-32k_bold_surf_falff"], ) -def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_postproc", - "config": ["surface_analysis", "post_freesurfer"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": [("freesurfer-subject-dir", - ["pipeline-fs_desc-restore_T1w", "desc-preproc_T1w", - "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"], - ["space-template_desc-head_T1w", - "space-template_desc-brain_T1w", - "space-template_desc-T1w_mask"], - ["from-T1w_to-template_mode-image_xfm", - "from-T1w_to-template_mode-image_desc-linear_xfm"], - ["from-template_to-T1w_mode-image_xfm", - "from-template_to-T1w_mode-image_desc-linear_xfm"], - ["space-template_desc-brain_bold", - "space-template_desc-preproc_bold"], - ["space-template_desc-scout_bold", - "space-template_desc-cleaned_bold", - "space-template_desc-brain_bold", - "space-template_desc-motion_bold", "space-template_bold"])], - "outputs": ["space-fsLR_den-32k_bold", - "atlas-DesikanKilliany_space-fsLR_den-32k", - "atlas-Destrieux_space-fsLR_den-32k", - "atlas-DesikanKilliany_space-fsLR_den-164k", - "atlas-Destrieux_space-fsLR_den-164k", - "space-fsLR_den-32k_bold-dtseries", - "AtlasSubcortical_s2", - "goodvoxels", - "ribbon_only", - "hemi-L_space-fsLR_den-32k_desc-atlasroi_bold", - "hemi-R_space-fsLR_den-32k_desc-atlasroi_bold", - "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", - "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask", - "hemi-L_space-native_bold", - "hemi-R_space-native_bold", - "space-fsLR_den-32k_wb-spec", - "space-native_wb-spec", - "hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion", - "hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion", - "space-fsLR_den-32k_desc-FS_arealdistortion", - "hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion", - "hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion", - "space-fsLR_den-32k_desc-MSMSulc_arealdistortion", - "hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion", - "hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion", - "space-fsLR_den-32k_desc-FS_edgedistortion", - "hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion", - "hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion", - "space-fsLR_den-32k_desc-MSMSulc_edgedistortion", - "hemi-L_space-fsLR_den-32k_curv", - "hemi-R_space-fsLR_den-32k_curv", - "space-fsLR_den-32k_curv", - "hemi-L_space-fsLR_den-32k_flat", - "hemi-R_space-fsLR_den-32k_flat", - "hemi-L_space-fsLR_den-32k_inflated", - "hemi-R_space-fsLR_den-32k_inflated", - "hemi-L_space-fsLR_den-32k_veryinflated", - "hemi-R_space-fsLR_den-32k_veryinflated", - "hemi-L_space-native_inflated", - "hemi-R_space-native_inflated", - "hemi-L_space-native_veryinflated", - "hemi-R_space-native_veryinflated", - "hemi-L_space-fsLR_den-164k_midthickness", - "hemi-R_space-fsLR_den-164k_midthickness", - "hemi-L_space-fsLR_den-32k_midthickness", - "hemi-R_space-fsLR_den-32k_midthickness", - "hemi-L_space-native_midthickness", - "hemi-R_space-native_midthickness", - "hemi-L_space-fsLR_den-32k_pial", - "hemi-R_space-fsLR_den-32k_pial", - "hemi-L_space-native_den-32k_pial", - "hemi-R_space-native_den-32k_pial", - "hemi-L_space-fsLR_den-32k_sphere", - "hemi-R_space-fsLR_den-32k_sphere", - "hemi-L_space-native_desc-MSMSulc_sphere", - "hemi-R_space-native_desc-MSMSulc_sphere", - "hemi-L_space-native_sphere", - "hemi-R_space-native_sphere", - "hemi-L_space-native_desc-reg_sphere", - "hemi-R_space-native_desc-reg_sphere", - "hemi-L_space-native_desc-reg-reg_sphere", - "hemi-R_space-native_desc-reg-reg_sphere", - "hemi-L_space-native_desc-rot_sphere", - "hemi-R_space-native_desc-rot_sphere", - "hemi-L_space-fsLR_den-32k_desc-FS_strainJ", - "hemi-R_space-fsLR_den-32k_desc-FS_strainJ", - "space-fsLR_den-32k_desc-FS_strainJ", - "hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ", - "hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ", - "space-fsLR_den-32k_desc-MSMSulc_strainJ", - "hemi-L_space-fsLR_den-32k_desc-FS_strainR", - "hemi-R_space-fsLR_den-32k_desc-FS_strainR", - "space-fsLR_den-32k_desc-FS_strainR", - "hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR", - "hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR", - "space-fsLR_den-32k_desc-MSMSulc_strainR", - "hemi-L_space-fsLR_den-32k_sulc", - "hemi-R_space-fsLR_den-32k_sulc", - "space-fsLR_den-32k_sulc", - "hemi-L_space-fsLR_den-32k_thickness", - "hemi-R_space-fsLR_den-32k_thickness", - "space-fsLR_den-32k_thickness", - "hemi-L_space-fsLR_den-164k_white", - "hemi-R_space-fsLR_den-164k_white", - "hemi-L_space-fsLR_den-32k_white", - "hemi-R_space-fsLR_den-32k_white", - "hemi-L_space-native_white", - "hemi-R_space-native_white"]} - ''' - wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) - - return (wf, outputs) - - -def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): +def surface_falff(wf, cfg, strat_pool, pipe_num, opt): falff = pe.Node(util.Function(input_names=['subject','dtseries'], output_names=['surf_falff'], @@ -924,7 +898,17 @@ def cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt): 'space-fsLR_den-32k_bold_surf_falff': (falff,'surf_falff')} return wf, outputs -def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): + +@nodeblock( + name="surface_alff", + config=["amplitude_low_frequency_fluctuation"], + switch=["run"], + inputs=["space-fsLR_den-32k_bold"], + outputs=[ + "space-fsLR_den-32k_bold_surf_alff"], +) + +def surface_alff(wf, cfg, strat_pool, pipe_num, opt): alff = pe.Node(util.Function(input_names=['subject','dtseries'], output_names=['surf_alff'], @@ -938,7 +922,21 @@ def cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt): 'space-fsLR_den-32k_bold_surf_alff': (alff,'surf_alff')} return wf, outputs -def cal_reho(wf, cfg, strat_pool, pipe_num, opt): + +@nodeblock( + name="surface_reho", + config=["regional_homogeneity"], + switch=["run"], + inputs=["space-fsLR_den-32k_bold", + "hemi-L_space-fsLR_den-32k_midthickness", + "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", + "hemi-R_space-fsLR_den-32k_midthickness", + "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask"], + outputs=[ + "space-fsLR_den-32k_bold_surf-L_reho", + "space-fsLR_den-32k_bold_surf-R_reho"], +) +def surface_reho(wf, cfg, strat_pool, pipe_num, opt): L_cortex_file = pe.Node(util.Function(input_names=['subject', 'dtseries', 'structure', 'cortex_filename'], output_names=['L_cortex_file'], @@ -1011,7 +1009,15 @@ def cal_reho(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs -def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): +@nodeblock( + name="surface_connectivity_matrix", + config=["surface_connectivity"], + switch=["run"], + inputs=["space-fsLR_den-32k_bold"], + outputs=["space-fsLR_den-32k_bold_surf-correlation_matrix"], +) + +def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], @@ -1038,67 +1044,6 @@ def cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs -def surface_falff(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_falff", - "config": ["amplitude_low_frequency_fluctuation"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold"], - "outputs": ["space-fsLR_den-32k_bold_surf_falff"]} - ''' - wf, outputs = cal_surface_falff(wf, cfg, strat_pool, pipe_num, opt) - - return (wf, outputs) - -def surface_alff(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_alff", - "config": ["amplitude_low_frequency_fluctuation"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold"], - "outputs": ["space-fsLR_den-32k_bold_surf_alff"]} - ''' - wf, outputs = cal_surface_alff(wf, cfg, strat_pool, pipe_num, opt) - - return (wf, outputs) - -def surface_reho(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_reho", - "config": ["regional_homogeneity"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold", - "hemi-L_space-fsLR_den-32k_midthickness", - "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", - "hemi-R_space-fsLR_den-32k_midthickness", - "hemi-R_space-fsLR_den-32k_desc-atlasroi_mask"], - "outputs": ["space-fsLR_den-32k_bold_surf-L_reho", "space-fsLR_den-32k_bold_surf-R_reho"]} - ''' - wf, outputs = cal_reho(wf, cfg, strat_pool, pipe_num, opt) - - return (wf, outputs) - -def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_connectivity_matrix", - "config": ["surface_connectivity"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": ["space-fsLR_den-32k_bold"], - "outputs": ["space-fsLR_den-32k_bold_surf-correlation_matrix"]} - ''' - - wf, outputs = cal_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt) - return (wf, outputs) - - def run_surf_falff(subject,dtseries): import os import subprocess From 0dffec34a73677d805b1605108817e90eca34bb3 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Fri, 30 Jun 2023 17:39:31 +0000 Subject: [PATCH 062/213] correcting version tags v1.8.6.dev11 to v1.8.6.dev1 --- .github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile index f0a4544fd7..7a32a31b1f 100755 --- a/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev11 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index 5277bf99c5..9bbe5b64f3 100755 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-bionic as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev11 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC From 539e0932a3bdb6aef418eb75bd532fc3168e62d4 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Fri, 30 Jun 2023 17:40:55 +0000 Subject: [PATCH 063/213] Adding surface_falff and surface_reho keys to the schema.py --- CPAC/pipeline/schema.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 572773466d..8f72a0fdc7 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -989,6 +989,10 @@ def sanitize(filename): for option in ['using', 'measure'] }, }, + + 'surface_amplitude_low_frequency_fluctuation': {'run': bool}, + 'surface_regional_homogeneity': {'run': bool}, + 'surface_connectivity': { 'run': bool, 'surface_parcellation_template':Maybe(str) }, From 0fe2d1bf8b23ad47856317d1a2e7f6b3087354da Mon Sep 17 00:00:00 2001 From: tergeorge Date: Fri, 30 Jun 2023 17:42:38 +0000 Subject: [PATCH 064/213] Providing path to surface parcellation template file path from pipeline config --- CPAC/surface/surf_preproc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index f71f4999b0..7c459add43 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -877,7 +877,7 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): @nodeblock( name="surface_falff", - config=["amplitude_low_frequency_fluctuation"], + config=["surface_amplitude_low_frequency_fluctuation"], switch=["run"], inputs=["space-fsLR_den-32k_bold"], outputs=[ @@ -901,7 +901,7 @@ def surface_falff(wf, cfg, strat_pool, pipe_num, opt): @nodeblock( name="surface_alff", - config=["amplitude_low_frequency_fluctuation"], + config=["surface_amplitude_low_frequency_fluctuation"], switch=["run"], inputs=["space-fsLR_den-32k_bold"], outputs=[ @@ -925,7 +925,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt): @nodeblock( name="surface_reho", - config=["regional_homogeneity"], + config=["surface_regional_homogeneity"], switch=["run"], inputs=["space-fsLR_den-32k_bold", "hemi-L_space-fsLR_den-32k_midthickness", @@ -1028,7 +1028,7 @@ def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): connectivity_parcellation.inputs.subject = cfg['subject_id'] node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, connectivity_parcellation, 'dtseries') - connectivity_parcellation.inputs.surf_atlaslabel = '/code/CPAC/resources/templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii' + connectivity_parcellation.inputs.surf_atlaslabel = cfg['surface_connectivity']['surface_parcellation_template'] correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], output_names=['correlation_matrix'], From 5a259696b7d83d1130c1638990de5a09d7377208 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Mon, 16 Oct 2023 15:46:43 -0400 Subject: [PATCH 065/213] :wrench: Minor formatting changes --- CPAC/surface/surf_preproc.py | 27 +-- CPAC/surface/surf_preproc_old.py | 376 ------------------------------- 2 files changed, 8 insertions(+), 395 deletions(-) delete mode 100644 CPAC/surface/surf_preproc_old.py diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 7c459add43..9df6459d1a 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -42,18 +42,6 @@ def run_surface(post_freesurfer_folder, if os.path.isdir(recon_all_path): freesurfer_folder = recon_all_path - # # DCAN-HCP PostFreeSurfer - # # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh - # cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/run.sh', '--post_freesurfer_folder', post_freesurfer_folder, \ - # '--freesurfer_folder', freesurfer_folder, '--subject', subject, \ - # '--t1w_restore', t1w_restore_image, '--atlas_t1w', atlas_space_t1w_image, \ - # '--atlas_transform', atlas_transform, '--inverse_atlas_transform', inverse_atlas_transform, \ - # '--surfatlasdir', surf_atlas_dir, '--grayordinatesdir', gray_ordinates_dir, '--grayordinatesres', gray_ordinates_res, \ - # '--hiresmesh', high_res_mesh, '--lowresmesh', low_res_mesh, \ - # '--subcortgraylabels', subcortical_gray_labels, '--freesurferlabels', freesurfer_labels] - - # subprocess.check_output(cmd) - # DCAN-HCP PostFreeSurfer Block1 cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block1.sh', post_freesurfer_folder, \ @@ -699,7 +687,7 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): surf.inputs.subject = cfg['subject_id'] surf.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - 'cpac_'+cfg['subject_id'], + 'cpac_' + cfg['subject_id'], f'post_freesurfer_{pipe_num}') surf.inputs.surf_atlas_dir = cfg.surface_analysis['post_freesurfer']['surf_atlas_dir'] @@ -910,16 +898,16 @@ def surface_falff(wf, cfg, strat_pool, pipe_num, opt): def surface_alff(wf, cfg, strat_pool, pipe_num, opt): - alff = pe.Node(util.Function(input_names=['subject','dtseries'], + alff = pe.Node(util.Function(input_names=['subject', 'dtseries'], output_names=['surf_alff'], function=run_surf_alff), name=f'surf_alff_{pipe_num}') alff.inputs.subject = cfg['subject_id'] node, out = strat_pool.get_data('space-fsLR_den-32k_bold') - wf.connect(node, out,alff, 'dtseries') + wf.connect(node, out, alff, 'dtseries') outputs = { - 'space-fsLR_den-32k_bold_surf_alff': (alff,'surf_alff')} + 'space-fsLR_den-32k_bold_surf_alff': (alff, 'surf_alff')} return wf, outputs @@ -1044,7 +1032,7 @@ def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): return wf, outputs -def run_surf_falff(subject,dtseries): +def run_surf_falff(subject, dtseries): import os import subprocess falff = os.path.join(os.getcwd(), f'{subject}_falff_surf.dscalar.nii') @@ -1052,7 +1040,7 @@ def run_surf_falff(subject,dtseries): subprocess.check_output(cmd) return falff -def run_surf_alff(subject,dtseries): +def run_surf_alff(subject, dtseries): import os import subprocess alff = os.path.join(os.getcwd(), f'{subject}_alff_surf.dscalar.nii') @@ -1079,7 +1067,8 @@ def run_mean_timeseries(subject, dtseries): log_subprocess(cmd) return mean_timeseries -def run_surf_reho(subject, dtseries, mask, cortex_file, surface_file,mean_timeseries,reho_filename,structure_name): +def run_surf_reho(subject, dtseries, mask, cortex_file, \ + surface_file, mean_timeseries, reho_filename, structure_name): import os import subprocess diff --git a/CPAC/surface/surf_preproc_old.py b/CPAC/surface/surf_preproc_old.py deleted file mode 100644 index 982345554a..0000000000 --- a/CPAC/surface/surf_preproc_old.py +++ /dev/null @@ -1,376 +0,0 @@ -from logging import raiseExceptions -import os -import nipype.interfaces.utility as util -from CPAC.utils.interfaces.function import Function -from CPAC.pipeline import nipype_pipeline_engine as pe - - - -def run_surface(post_freesurfer_folder, - freesurfer_folder, - subject, - t1w_restore_image, - atlas_space_t1w_image, - atlas_transform, - inverse_atlas_transform, - atlas_space_bold, - scout_bold, - surf_atlas_dir, - gray_ordinates_dir, - gray_ordinates_res, - high_res_mesh, - low_res_mesh, - subcortical_gray_labels, - freesurfer_labels, - fmri_res, - smooth_fwhm): - """ - Returns - ------- - dtseries : str - Path to the dtseries file. - - desikan_killiany : str - Path to the Desikan-Killiany parcellation file. - - destrieux : str - Path to the Destrieux parcellation file. - """ - - import os - import subprocess - - freesurfer_folder = os.path.join(freesurfer_folder, 'recon_all') - - # DCAN-HCP PostFreeSurfer - # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/PostFreeSurfer/PostFreeSurferPipeline.sh - cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/run.sh', '--post_freesurfer_folder', post_freesurfer_folder, \ - '--freesurfer_folder', freesurfer_folder, '--subject', subject, \ - '--t1w_restore', t1w_restore_image, '--atlas_t1w', atlas_space_t1w_image, \ - '--atlas_transform', atlas_transform, '--inverse_atlas_transform', inverse_atlas_transform, \ - '--surfatlasdir', surf_atlas_dir, '--grayordinatesdir', gray_ordinates_dir, '--grayordinatesres', gray_ordinates_res, \ - '--hiresmesh', high_res_mesh, '--lowresmesh', low_res_mesh, \ - '--subcortgraylabels', subcortical_gray_labels, '--freesurferlabels', freesurfer_labels] - - subprocess.check_output(cmd) - - # DCAN-HCP fMRISurface - # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRISurface/GenericfMRISurfaceProcessingPipeline.sh - cmd = ['bash', '/code/CPAC/surface/fMRISurface/run.sh', - '--post_freesurfer_folder', post_freesurfer_folder, - '--subject', subject, '--fmri', atlas_space_bold, '--scout', - scout_bold, '--lowresmesh', low_res_mesh, '--grayordinatesres', - gray_ordinates_res, '--fmrires', fmri_res, '--smoothingFWHM', - smooth_fwhm] - subprocess.check_output(cmd) - - dtseries = os.path.join(post_freesurfer_folder, - 'MNINonLinear/Results/task-rest01/' - 'task-rest01_Atlas.dtseries.nii') - aparc = {'desikan_killiany': { - 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', - f'{subject}.aparc.164k_fs_LR.dlabel.nii'), - 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', - 'fsaverage_LR32k', - f'{subject}.aparc.32k_fs_LR.dlabel.nii')}, - 'destrieux': { - 164: os.path.join(post_freesurfer_folder, 'MNINonLinear', - f'{subject}.aparc.a2009s.164k_fs_LR.dlabel.nii'), - 32: os.path.join(post_freesurfer_folder, 'MNINonLinear', - 'fsaverage_LR32k', - f'{subject}.aparc.a2009s.32k_fs_LR.dlabel.nii')}} - - return (dtseries, aparc['desikan_killiany'][164], aparc['destrieux'][164], - aparc['desikan_killiany'][32], aparc['destrieux'][32]) - - -def surface_connector(wf, cfg, strat_pool, pipe_num, opt): - - surf = pe.Node(util.Function(input_names=['post_freesurfer_folder', - 'freesurfer_folder', - 'subject', - 't1w_restore_image', - 'atlas_space_t1w_image', - 'atlas_transform', - 'inverse_atlas_transform', - 'atlas_space_bold', - 'scout_bold', - 'surf_atlas_dir', - 'gray_ordinates_dir', - 'gray_ordinates_res', - 'high_res_mesh', - 'low_res_mesh', - 'subcortical_gray_labels', - 'freesurfer_labels', - 'fmri_res', - 'smooth_fwhm'], - output_names=['dtseries', - 'desikan_killiany_164', - 'destrieux_164', - 'desikan_killiany_32', - 'destrieux_32', - ], - function=run_surface), - name=f'post_freesurfer_{pipe_num}') - - surf.inputs.subject = cfg['subject_id'] - - surf.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - 'cpac_'+cfg['subject_id'], - f'post_freesurfer_{pipe_num}') - - surf.inputs.surf_atlas_dir = cfg.surface_analysis['post_freesurfer']['surf_atlas_dir'] - surf.inputs.gray_ordinates_dir = cfg.surface_analysis['post_freesurfer']['gray_ordinates_dir'] - surf.inputs.subcortical_gray_labels = cfg.surface_analysis['post_freesurfer']['subcortical_gray_labels'] - surf.inputs.freesurfer_labels = cfg.surface_analysis['post_freesurfer']['freesurfer_labels'] - - # convert integers to strings as subprocess requires string inputs - surf.inputs.gray_ordinates_res = str(cfg.surface_analysis['post_freesurfer']['gray_ordinates_res']) - surf.inputs.high_res_mesh = str(cfg.surface_analysis['post_freesurfer']['high_res_mesh']) - surf.inputs.low_res_mesh = str(cfg.surface_analysis['post_freesurfer']['low_res_mesh']) - surf.inputs.fmri_res = str(cfg.surface_analysis['post_freesurfer']['fmri_res']) - surf.inputs.smooth_fwhm = str(cfg.surface_analysis['post_freesurfer']['smooth_fwhm']) - - restore = ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"] - space_temp = ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask",] - atlas_xfm = ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"] - atlas_xfm_inv = ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"] - atlas_space_bold = ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"] - scout_bold = ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"] - - - node, out = strat_pool.get_data('freesurfer-subject-dir') - wf.connect(node, out, surf, 'freesurfer_folder') - - node, out = strat_pool.get_data(restore) - wf.connect(node, out, surf, 't1w_restore_image') - - node, out = strat_pool.get_data(space_temp) - wf.connect(node, out, surf, 'atlas_space_t1w_image') - - node, out = strat_pool.get_data(atlas_xfm) - wf.connect(node, out, surf, 'atlas_transform') - - node, out = strat_pool.get_data(atlas_xfm_inv) - wf.connect(node, out, surf, 'inverse_atlas_transform') - - node, out = strat_pool.get_data(atlas_space_bold) - wf.connect(node, out, surf, 'atlas_space_bold') - - node, out = strat_pool.get_data(scout_bold) - wf.connect(node, out, surf, 'scout_bold') - - falff = pe.Node(util.Function(input_names=['dtseries'], - output_names=['falff'], - function=run_surf_falff), - name=f'surf_falff_{pipe_num}') - - - wf.connect(surf, 'dtseries', falff, 'dtseries') - - #alff = pe.Node(util.Function(input_names=['dtseries'], - # output_names=['alff'], - # function=run_surf_alff), - # name=f'surf_alff_{pipe_num}') - - - #wf.connect(surf, 'dtseries', alff, 'dtseries') - - - outputs = { - 'atlas-DesikanKilliany_space-fsLR_den-32k_dlabel': (surf, - 'desikan_' - 'killiany_32'), - 'atlas-Destrieux_space-fsLR_den-32k_dlabel': (surf, 'destrieux_32'), - 'atlas-DesikanKilliany_space-fsLR_den-164k_dlabel': (surf, - 'desikan_' - 'killiany_164'), - 'atlas-Destrieux_space-fsLR_den-164k_dlabel': (surf, 'destrieux_164'), - 'space-fsLR_den-32k_bold-dtseries': (surf, 'dtseries'), - 'falff-surf_dscalar': (falff, 'falff'), - #'alff-surf_dscalar': (alff, 'alff') - - - } - - - - - # L_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], - # output_names=['L_cortex_file'], - # function=run_get_cortex), - # name=f'L_surf_cortex_{pipe_num}') - - # L_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # L_cortex_file.inputs.structure = "LEFT" - # L_cortex_file.inputs.cortex_filename = "L_cortex.func.gii" - # wf.connect(surf, 'dtseries', L_cortex_file, 'dtseries') - - # R_cortex_file = pe.Node(util.Function(input_names=['dtseries', 'structure', 'post_freesurfer_folder', 'cortex_filename'], - # output_names=['R_cortex_file'], - # function=run_get_cortex), - # name=f'R_surf_cortex_{pipe_num}') - - # R_cortex_file.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # R_cortex_file.inputs.structure = "RIGHT" - # R_cortex_file.inputs.cortex_filename = "R_cortex.func.gii" - # wf.connect(surf, 'dtseries', R_cortex_file, 'dtseries') - - - # mean_timeseries = pe.Node(util.Function(input_names=['post_freesurfer_folder', 'dtseries'], - # output_names=['mean_timeseries'], - # function=run_mean_timeseries), - # name=f'mean_timeseries_{pipe_num}') - - # mean_timeseries.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # wf.connect(surf, 'dtseries', mean_timeseries, 'dtseries') - - - # L_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', - # 'post_freesurfer_folder', 'reho_filename'], - # output_names=['L_reho'], - # function=run_surf_reho), - # name=f'surf_reho{pipe_num}') - - # wf.connect(get_L_cortex_file, 'L_cortex_file', L_reho, 'cortex_file') - # wf.connect(surf, 'L_surface_file', L_reho, 'surface_file') - # wf.connect(surf, 'L_mask', L_reho, 'mask') - # wf.connect(mean_timeseries, 'mean_timeseries', L_reho, 'mean_timeseries') - # L_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # L_reho.inputs.reho_filename = L_surf_reho.dscalar.nii - - # R_reho = pe.Node(util.Function(input_names=['dtseries', 'mask' , 'cortex_file', 'surface_file', 'mean_timeseries', - # 'post_freesurfer_folder', 'reho_filename'], - # output_names=['R_reho'], - # function=run_surf_reho), - # name=f'surf_reho{pipe_num}') - - # wf.connect(get_R_cortex_file, 'R_cortex_file', R_reho, 'cortex_file') - # wf.connect(surf, 'R_surface_file', R_reho, 'surface_file') - # wf.connect(surf, 'R_mask', R_reho, 'mask') - # wf.connect(mean_timeseries, 'mean_timeseries', R_reho, 'mean_timeseries') - # R_reho.inputs.post_freesurfer_folder = os.path.join(cfg.pipeline_setup['working_directory']['path'], - # 'cpac_'+cfg['subject_id'], - # f'post_freesurfer_{pipe_num}') - # R_reho.inputs.reho_filename = R_surf_reho.dscalar.nii - - - - # connectivity_parcellation = pe.Node(util.Function(input_names=['dtseries', 'surf_atlaslabel', - # 'post_freesurfer_folder'], - # output_names=['parcellation_file'], - # function=run_ciftiparcellate), - # name=f'connectivity_parcellation{pipe_num}') - - - # wf.connect(surf, 'dtseries', connectivity, 'dtseries') - # connectivity_parcellation.inputs.surf_atlaslabel = ## path to the label file - - # correlation_matrix = pe.Node(util.Function(input_names=['ptseries','post_freesurfer_folder'], - # output_names=['correlation_matrix'], - # function=run_cifticorrelation), - # name=f'correlation_matrix{pipe_num}') - - - # wf.connect(connectivity_parcellation, 'parcellation_file', correlation_matrix 'ptseries') - - return wf, outputs - -def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): - ''' - {"name": "surface_preproc", - "config": ["surface_analysis", "post_freesurfer"], - "switch": ["run"], - "option_key": "None", - "option_val": "None", - "inputs": ["freesurfer-subject-dir", - ["desc-restore_T1w", "desc-preproc_T1w", "desc-reorient_T1w", "T1w", - "space-longitudinal_desc-reorient_T1w"], - ["space-template_desc-head_T1w", "space-template_desc-brain_T1w", "space-template_desc-T1w_mask"], - ["from-T1w_to-template_mode-image_xfm", "from-T1w_to-template_mode-image_desc-linear_xfm"], - ["from-template_to-T1w_mode-image_xfm", "from-template_to-T1w_mode-image_desc-linear_xfm"], - ["space-template_desc-brain_bold", "space-template_desc-preproc_bold"], - ["space-template_desc-scout_bold", "space-template_desc-cleaned_bold", "space-template_desc-brain_bold", - "space-template_desc-preproc_bold", "space-template_desc-motion_bold", "space-template_bold"]], - "outputs": ["atlas-DesikanKilliany_space-fsLR_den-32k_dlabel", - "atlas-Destrieux_space-fsLR_den-32k_dlabel", - "atlas-DesikanKilliany_space-fsLR_den-164k_dlabel", - "atlas-Destrieux_space-fsLR_den-164k_dlabel", - "space-fsLR_den-32k_bold-dtseries", - "falff-surf_dscalar", - "alff-surf_dscalar"]} - ''' - wf, outputs = surface_connector(wf, cfg, strat_pool, pipe_num, opt) - - return (wf, outputs) - - -def run_surf_falff(dtseries): - import os - import subprocess - falff = os.path.join(os.getcwd(), 'falff_surf.nii.gz') - cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] - subprocess.check_output(cmd) - return falff - - -#def run_surf_alff(dtseries): -# import os -# import subprocess -# alff = os.path.join(os.getcwd(), 'alff_surf.dscalar.nii.gz') -# cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] -# subprocess.check_output(cmd) -# return alff - -#cmd = ['ciftify_falff', dtseries , 'alff_surf.dscalar.nii', '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] -# def run_get_cortex(dtseries, structure, post_freesurfer_folder, cortex_filename): -# import os -# import subprocess -# cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-label', structure, cortex_filename] -# subprocess.check_output(cmd) -# cortex_file = os.path.join(post_freesurfer_folder, cortex_filename) -# return cortex_file - -# def run_mean_timeseries(dtseries,post_freesurfer_folder): - -# import os -# import subprocess -# cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', 'mean.dscalar.nii'] -# subprocess.check_output(cmd) -# mean_timeseries = os.path.join(post_freesurfer_folder, mean.dscalar.nii) -# return mean_timeseries - -# def run_surf_reho(dtseries, mask, cortex_file, surface_file,mean_timeseries,post_freesurfer_folder, reho_filename): - -# import os -# import subprocess -# cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, reho_filename] -# subprocess.check_output(cmd) -# surf_reho = os.path.join(post_freesurfer_folder, reho_filename) -# return surf_reho - -# def run_ciftiparcellate(dtseries, surf_atlaslabel): -# import os -# import subprocess -# cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', 'parcellation.ptseries.nii'] -# subprocess.check_output(cmd) -# parcellation_file = os.path.join(post_freesurfer_folder, 'parcellation.ptseries.nii') -# return parcellation_file - -# def run_cifticorrelation(ptseries): -# import os -# import subprocess -# cmd = ['wb_command', '-cifti-correlation ', ptseries , 'cifti_corr.pconn.nii'] -# subprocess.check_output(cmd) -# correlation_matrix = os.path.join(post_freesurfer_folder, 'cifti_corr.pconn.nii') -# return correlation_matrix From 1a0b330f7751cc1f10170f1a1a64813d437950ea Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Mon, 16 Oct 2023 15:51:13 -0400 Subject: [PATCH 066/213] :wrench: Re-name blocks --- CPAC/surface/PostFreeSurfer/block3-5.sh | 276 ------------------------ CPAC/surface/PostFreeSurfer/block3.sh | 234 +++++++++++--------- CPAC/surface/PostFreeSurfer/block4.sh | 177 +++++++++------ CPAC/surface/PostFreeSurfer/block5.sh | 71 ++++-- CPAC/surface/PostFreeSurfer/block6.sh | 63 ++---- CPAC/surface/PostFreeSurfer/block7.sh | 177 +++++++++++++++ CPAC/surface/surf_preproc.py | 8 +- 7 files changed, 503 insertions(+), 503 deletions(-) delete mode 100644 CPAC/surface/PostFreeSurfer/block3-5.sh mode change 100755 => 100644 CPAC/surface/PostFreeSurfer/block3.sh create mode 100755 CPAC/surface/PostFreeSurfer/block7.sh diff --git a/CPAC/surface/PostFreeSurfer/block3-5.sh b/CPAC/surface/PostFreeSurfer/block3-5.sh deleted file mode 100644 index ad52f61cb4..0000000000 --- a/CPAC/surface/PostFreeSurfer/block3-5.sh +++ /dev/null @@ -1,276 +0,0 @@ - #!/bin/bash - -#!/bin/bash - -echo "START" - -StudyFolder="$1" -echo "StudyFolder: ${StudyFolder}" - -FreeSurferFolder="$2" -echo "FreeSurferFolder: ${FreeSurferFolder}" - -Subject="$3" -echo "Subject: ${Subject}" - -T1wRestoreImageCPAC="$4" -echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" - -AtlasSpaceT1wImageCPAC="$5" -echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" - -AtlasTransformCPAC="$6" -echo "AtlasTransformCPAC ${AtlasTransformCPAC}" - -InverseAtlasTransformCPAC="$7" -echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" - -SurfaceAtlasDIR="$8" -echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" - -GrayordinatesSpaceDIR="$9" -echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" - -GrayordinatesResolutions="${10}" -echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" - -HighResMesh="${11}" -echo "HighResMesh: ${HighResMesh}" - -LowResMeshes="${12}" -echo "LowResMeshes: ${LowResMeshes}" - -SubcorticalGrayLabels="${13}" -echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" - -FreeSurferLabels="${14}" -echo "FreeSurferLabels: ${FreeSurferLabels}" - -RegName=MSMSulc -# RegName=FS -useT2=false - -# default parameters -CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) -InflateExtraScale=1 - -#Naming Conventions -T1wImage="T1w_acpc_dc" -T1wFolder="T1w" #Location of T1w images -T2wFolder="T2w" #Location of T1w images -T2wImage="T2w_acpc_dc" -AtlasSpaceFolder="MNINonLinear" -NativeFolder="Native" -FreeSurferInput="T1w_acpc_dc_restore_1mm" -AtlasTransform="acpc_dc2standard" -InverseAtlasTransform="standard2acpc_dc" -AtlasSpaceT1wImage="T1w_restore" -AtlasSpaceT2wImage="T2w_restore" -T1wRestoreImage="T1w_acpc_dc_restore" -T2wRestoreImage="T2w_acpc_dc_restore" -OrginalT1wImage="T1w" -OrginalT2wImage="T2w" -T1wImageBrainMask="brainmask_fs" -InitialT1wTransform="acpc.mat" -dcT1wTransform="T1w_dc.nii.gz" -InitialT2wTransform="acpc.mat" -dcT2wTransform="T2w_reg_dc.nii.gz" -FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" -BiasField="BiasField_acpc_dc" -OutputT1wImage="T1w_acpc_dc" -OutputT1wImageRestore="T1w_acpc_dc_restore" -OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" -OutputMNIT1wImage="T1w" -OutputMNIT1wImageRestore="T1w_restore" -OutputMNIT1wImageRestoreBrain="T1w_restore_brain" -OutputT2wImage="T2w_acpc_dc" -OutputT2wImageRestore="T2w_acpc_dc_restore" -OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" -OutputMNIT2wImage="T2w" -OutputMNIT2wImageRestore="T2w_restore" -OutputMNIT2wImageRestoreBrain="T2w_restore_brain" -OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" -OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix -OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz -OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" -BiasFieldOutput="BiasField" -Jacobian="NonlinearRegJacobians.nii.gz" - - -T1wFolder="$StudyFolder"/"$T1wFolder" -T2wFolder="$StudyFolder"/"$T2wFolder" -AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" -AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" -InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" - -LowResMeshes=${LowResMeshes//@/ } -echo "LowResMeshes: ${LowResMeshes}" - -GrayordinatesResolutions=${GrayordinatesResolutions//@/ } -echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" - -HCPPIPEDIR=/code/CPAC/resources -source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions -echo "HCPPIPEDIR: ${HCPPIPEDIR}" -MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig - -cd ${StudyFolder} - -#Loop through left and right hemispheres -for Hemisphere in L R ; do - #Set a bunch of different ways of saying left and right - if [ $Hemisphere = "L" ] ; then - hemisphere="l" - Structure="CORTEX_LEFT" - elif [ $Hemisphere = "R" ] ; then - hemisphere="r" - Structure="CORTEX_RIGHT" - fi - - #If desired, run MSMSulc folding-based registration to FS_LR initialized with FS affine - if [ ${RegName} = "MSMSulc" ] ; then - #Calculate Affine Transform and Apply - if [ ! -e "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc ] ; then - mkdir "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc - fi - wb_command -surface-affine-regression "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat - wb_command -surface-apply-affine "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii - wb_command -surface-modify-sphere "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii 100 "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii - cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii - DIR=$(pwd) - cd "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc - #Register using FreeSurfer Sulc Folding Map Using MSM Algorithm Configured for Reduced Distortion - #msm --version - #msm --levels=4 --conf=${MSMCONFIGDIR}/allparameterssulcDRconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --trans="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose - # Note: the config is mordified according to acceptable args of msm version in container - XL - msm --conf=${MSMCONFIGDIR}/MSMSulcStrainFinalconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose - cp ${MSMCONFIGDIR}/MSMSulcStrainFinalconf "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.logdir/conf - cd $DIR - #cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.HIGHRES_transformed.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii - cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere.reg.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii ${Structure} - - #Make MSMSulc Registration Areal Distortion Maps - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii - wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_MSMSulc - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 - - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii -edge-method - - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -local-affine-method - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 1 - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 2 - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii - - RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii" - else - RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii" - fi - - #Ensure no zeros in atlas medial wall ROI - wb_command -metric-resample "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ${RegSphere} BARYCENTRIC "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -largest - wb_command -metric-math "(atlas + individual) > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var atlas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -var individual "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii - - - #Populate Highres fs_LR spec file. Deform surfaces and other data according to native to folding-based registration selected above. Regenerate inflated surfaces. - for Surface in white midthickness pial ; do - wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii - done - - #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for high res mesh density - HighResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $HighResMesh / 32" | bc -l) - - wb_command -surface-generate-inflated "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii -iterations-scale $HighResInflationScale - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii - - for Map in thickness curvature ; do - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii - done - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - if [ ${RegName} = "MSMSulc" ] ; then - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - fi - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - - for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly - if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then - wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.label.gii -largest - fi - done - - for LowResMesh in ${LowResMeshes} ; do - #Copy Atlas Files - cp "$SurfaceAtlasDIR"/"$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii - cp "$GrayordinatesSpaceDIR"/"$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii - if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii ] ; then - cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii - fi - - #Create downsampled fs_LR spec files. - for Surface in white midthickness pial ; do - wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - done - - #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh - LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) - - wb_command -surface-generate-inflated "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii - - for Map in sulc thickness curvature ; do - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii - done - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - if [ ${RegName} = "MSMSulc" ] ; then - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - fi - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - - for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly - if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then - wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.label.gii -largest - fi - done - - #Create downsampled fs_LR spec file in structural space. - for Surface in white midthickness pial ; do - wb_command -surface-resample "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - done - - #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh - LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) - - wb_command -surface-generate-inflated "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" - wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii - done -done - diff --git a/CPAC/surface/PostFreeSurfer/block3.sh b/CPAC/surface/PostFreeSurfer/block3.sh old mode 100755 new mode 100644 index d340d49351..ad52f61cb4 --- a/CPAC/surface/PostFreeSurfer/block3.sh +++ b/CPAC/surface/PostFreeSurfer/block3.sh @@ -1,5 +1,4 @@ - -#!/bin/bash + #!/bin/bash #!/bin/bash @@ -127,116 +126,151 @@ for Hemisphere in L R ; do hemisphere="r" Structure="CORTEX_RIGHT" fi - - #native Mesh Processing - #Convert and volumetrically register white and pial surfaces making linear and nonlinear copies, add each to the appropriate spec file - Types="ANATOMICAL@GRAY_WHITE ANATOMICAL@PIAL" - i=1 - for Surface in white pial ; do - Type=$(echo "$Types" | cut -d " " -f $i) - Secondary=$(echo "$Type" | cut -d "@" -f 2) - Type=$(echo "$Type" | cut -d "@" -f 1) - if [ ! $Secondary = $Type ] ; then - Secondary=$(echo " -surface-secondary-type ""$Secondary") - else - Secondary="" + + #If desired, run MSMSulc folding-based registration to FS_LR initialized with FS affine + if [ ${RegName} = "MSMSulc" ] ; then + #Calculate Affine Transform and Apply + if [ ! -e "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc ] ; then + mkdir "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc fi - mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -set-structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type $Type$Secondary - wb_command -surface-apply-affine "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$FreeSurferFolder"/mri/c_ras.mat "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -surface-apply-warpfield "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$InverseAtlasTransform".nii.gz "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii -fnirt "$AtlasTransform".nii.gz - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - i=$(( i+1 )) - done + wb_command -surface-affine-regression "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat + wb_command -surface-apply-affine "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii + wb_command -surface-modify-sphere "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii 100 "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii + cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii + DIR=$(pwd) + cd "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc + #Register using FreeSurfer Sulc Folding Map Using MSM Algorithm Configured for Reduced Distortion + #msm --version + #msm --levels=4 --conf=${MSMCONFIGDIR}/allparameterssulcDRconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --trans="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose + # Note: the config is mordified according to acceptable args of msm version in container - XL + msm --conf=${MSMCONFIGDIR}/MSMSulcStrainFinalconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose + cp ${MSMCONFIGDIR}/MSMSulcStrainFinalconf "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.logdir/conf + cd $DIR + #cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.HIGHRES_transformed.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii + cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere.reg.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii ${Structure} + + #Make MSMSulc Registration Areal Distortion Maps + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_MSMSulc + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii -edge-method + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -local-affine-method + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 1 + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 2 + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii + + RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii" + else + RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii" + fi + #Ensure no zeros in atlas medial wall ROI + wb_command -metric-resample "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ${RegSphere} BARYCENTRIC "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -largest + wb_command -metric-math "(atlas + individual) > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var atlas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -var individual "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii - #Create midthickness by averaging white and pial surfaces and use it to make inflated surfacess - for Folder in "$T1wFolder" "$AtlasSpaceFolder" ; do - wb_command -surface-average "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".white.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".pial.native.surf.gii - wb_command -set-structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii ${Structure} -surface-type ANATOMICAL -surface-secondary-type MIDTHICKNESS - wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii - #get number of vertices from native file - NativeVerts=$(wb_command -file-information "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii | grep 'Number of Vertices:' | cut -f2 -d: | tr -d '[:space:]') + #Populate Highres fs_LR spec file. Deform surfaces and other data according to native to folding-based registration selected above. Regenerate inflated surfaces. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii + done - #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for native mesh density - NativeInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $NativeVerts / 32492" | bc -l) + #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for high res mesh density + HighResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $HighResMesh / 32" | bc -l) - wb_command -surface-generate-inflated "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii -iterations-scale $NativeInflationScale - wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii - wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii - done + wb_command -surface-generate-inflated "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii -iterations-scale $HighResInflationScale + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii - #Convert original and registered spherical surfaces and add them to the nonlinear spec file - for Surface in sphere.reg sphere ; do - mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type SPHERICAL - done - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii - - #Add more files to the spec file and convert other FreeSurfer surface data to metric/GIFTI including sulc, curv, and thickness. - for Map in sulc@sulc@Sulc thickness@thickness@Thickness curv@curvature@Curvature ; do - fsname=$(echo $Map | cut -d "@" -f 1) - wbname=$(echo $Map | cut -d "@" -f 2) - mapname=$(echo $Map | cut -d "@" -f 3) - mris_convert -c "$FreeSurferFolder"/surf/"$hemisphere"h."$fsname" "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii ${Structure} - wb_command -metric-math "var * -1" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -map 1 "$Subject"_"$Hemisphere"_"$mapname" - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + for Map in thickness curvature ; do + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii done - #Thickness specific operations - wb_command -metric-math "abs(thickness)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false - wb_command -metric-math "thickness > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii - wb_command -metric-fill-holes "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-remove-islands "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_ROI - wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -nearest - wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii -nearest - - #Label operations + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + fi + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then - mris_convert --annot "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii $Structure - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii -map 1 "$Subject"_"$Hemisphere"_"$Map" - wb_command -gifti-label-add-prefix "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii "${Hemisphere}_" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii + wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.label.gii -largest fi done - #End main native mesh processing - - #Copy Atlas Files - cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fsaverage."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii - cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fs_"$Hemisphere"-to-fs_LR_fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii - cp "$SurfaceAtlasDIR"/fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii - cp "$SurfaceAtlasDIR"/"$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii - cp "$SurfaceAtlasDIR"/"$Hemisphere".refsulc."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii - if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii ] ; then - cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii - fi - - #Concatenate FS registration to FS --> FS_LR registration - wb_command -surface-sphere-project-unproject "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.native.surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii - #Make FreeSurfer Registration Areal Distortion Maps - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii - wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_FS - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 - - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii -edge-method + for LowResMesh in ${LowResMeshes} ; do + #Copy Atlas Files + cp "$SurfaceAtlasDIR"/"$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii + cp "$GrayordinatesSpaceDIR"/"$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii + if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii ] ; then + cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii + fi - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -local-affine-method - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 1 - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 2 - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii + #Create downsampled fs_LR spec files. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh + LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii + + for Map in sulc thickness curvature ; do + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii + done + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + fi + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then + wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.label.gii -largest + fi + done + + #Create downsampled fs_LR spec file in structural space. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh + LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii + done +done -done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block4.sh b/CPAC/surface/PostFreeSurfer/block4.sh index 5b9ee7b046..d340d49351 100755 --- a/CPAC/surface/PostFreeSurfer/block4.sh +++ b/CPAC/surface/PostFreeSurfer/block4.sh @@ -1,6 +1,8 @@ #!/bin/bash +#!/bin/bash + echo "START" StudyFolder="$1" @@ -49,7 +51,6 @@ RegName=MSMSulc # RegName=FS useT2=false - # default parameters CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) InflateExtraScale=1 @@ -114,6 +115,9 @@ source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions echo "HCPPIPEDIR: ${HCPPIPEDIR}" MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig +cd ${StudyFolder} + +#Loop through left and right hemispheres for Hemisphere in L R ; do #Set a bunch of different ways of saying left and right if [ $Hemisphere = "L" ] ; then @@ -123,71 +127,116 @@ for Hemisphere in L R ; do hemisphere="r" Structure="CORTEX_RIGHT" fi - -cd ${StudyFolder} -STRINGII="" -for LowResMesh in ${LowResMeshes} ; do - STRINGII=$(echo "${STRINGII}${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR@atlasroi ") -done - -#Create CIFTI Files -for STRING in "$AtlasSpaceFolder"/"$NativeFolder"@native@roi "$AtlasSpaceFolder"@"$HighResMesh"k_fs_LR@atlasroi ${STRINGII} ; do - Folder=$(echo $STRING | cut -d "@" -f 1) - Mesh=$(echo $STRING | cut -d "@" -f 2) - ROI=$(echo $STRING | cut -d "@" -f 3) - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.sulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.sulc."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -map 1 "${Subject}_Sulc" - wb_command -cifti-palette "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.curvature."$Mesh".shape.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.curvature."$Mesh".shape.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -map 1 "${Subject}_Curvature" - wb_command -cifti-palette "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.thickness."$Mesh".shape.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.thickness."$Mesh".shape.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -map 1 "${Subject}_Thickness" - wb_command -cifti-palette "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.ArealDistortion_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.ArealDistortion_FS."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -map 1 "${Subject}_ArealDistortion_FS" - wb_command -cifti-palette "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.EdgeDistortion_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.EdgeDistortion_FS."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -map 1 "${Subject}_EdgeDistortion_FS" - wb_command -cifti-palette "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainJ_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainJ_FS."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -map 1 "${Subject}_StrainJ_FS" - wb_command -cifti-palette "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainR_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainR_FS."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -map 1 "${Subject}_StrainR_FS" - wb_command -cifti-palette "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - if [ ${RegName} = "MSMSulc" ] ; then - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.ArealDistortion_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.ArealDistortion_MSMSulc."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_ArealDistortion_MSMSulc" - wb_command -cifti-palette "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.EdgeDistortion_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.EdgeDistortion_MSMSulc."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_EdgeDistortion_MSMSulc" - wb_command -cifti-palette "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainJ_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainJ_MSMSulc."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_StrainJ_MSMSulc" - wb_command -cifti-palette "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - - wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainR_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainR_MSMSulc."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_StrainR_MSMSulc" - wb_command -cifti-palette "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false - fi + #native Mesh Processing + #Convert and volumetrically register white and pial surfaces making linear and nonlinear copies, add each to the appropriate spec file + Types="ANATOMICAL@GRAY_WHITE ANATOMICAL@PIAL" + i=1 + for Surface in white pial ; do + Type=$(echo "$Types" | cut -d " " -f $i) + Secondary=$(echo "$Type" | cut -d "@" -f 2) + Type=$(echo "$Type" | cut -d "@" -f 1) + if [ ! $Secondary = $Type ] ; then + Secondary=$(echo " -surface-secondary-type ""$Secondary") + else + Secondary="" + fi + mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -set-structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type $Type$Secondary + wb_command -surface-apply-affine "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$FreeSurferFolder"/mri/c_ras.mat "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -surface-apply-warpfield "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$InverseAtlasTransform".nii.gz "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii -fnirt "$AtlasTransform".nii.gz + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + i=$(( i+1 )) + done + + + #Create midthickness by averaging white and pial surfaces and use it to make inflated surfacess + for Folder in "$T1wFolder" "$AtlasSpaceFolder" ; do + wb_command -surface-average "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".white.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".pial.native.surf.gii + wb_command -set-structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii ${Structure} -surface-type ANATOMICAL -surface-secondary-type MIDTHICKNESS + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii + + #get number of vertices from native file + NativeVerts=$(wb_command -file-information "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii | grep 'Number of Vertices:' | cut -f2 -d: | tr -d '[:space:]') + #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for native mesh density + NativeInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $NativeVerts / 32492" | bc -l) + + wb_command -surface-generate-inflated "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii -iterations-scale $NativeInflationScale + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii + done + + #Convert original and registered spherical surfaces and add them to the nonlinear spec file + for Surface in sphere.reg sphere ; do + mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type SPHERICAL + done + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii + + #Add more files to the spec file and convert other FreeSurfer surface data to metric/GIFTI including sulc, curv, and thickness. + for Map in sulc@sulc@Sulc thickness@thickness@Thickness curv@curvature@Curvature ; do + fsname=$(echo $Map | cut -d "@" -f 1) + wbname=$(echo $Map | cut -d "@" -f 2) + mapname=$(echo $Map | cut -d "@" -f 3) + mris_convert -c "$FreeSurferFolder"/surf/"$hemisphere"h."$fsname" "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii ${Structure} + wb_command -metric-math "var * -1" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -map 1 "$Subject"_"$Hemisphere"_"$mapname" + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + done + #Thickness specific operations + wb_command -metric-math "abs(thickness)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false + wb_command -metric-math "thickness > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-fill-holes "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-remove-islands "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_ROI + wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -nearest + wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii -nearest + + #Label operations for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly - if [ -e "$Folder"/"$Subject".L.${Map}."$Mesh".label.gii ] ; then - wb_command -cifti-create-label "$Folder"/"$Subject".${Map}."$Mesh".dlabel.nii -left-label "$Folder"/"$Subject".L.${Map}."$Mesh".label.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-label "$Folder"/"$Subject".R.${Map}."$Mesh".label.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii - wb_command -set-map-names "$Folder"/"$Subject".${Map}."$Mesh".dlabel.nii -map 1 "$Subject"_${Map} + if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then + mris_convert --annot "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii $Structure + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii -map 1 "$Subject"_"$Hemisphere"_"$Map" + wb_command -gifti-label-add-prefix "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii "${Hemisphere}_" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii fi done - done -done + #End main native mesh processing + + #Copy Atlas Files + cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fsaverage."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii + cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fs_"$Hemisphere"-to-fs_LR_fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii + cp "$SurfaceAtlasDIR"/fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii + cp "$SurfaceAtlasDIR"/"$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii + cp "$SurfaceAtlasDIR"/"$Hemisphere".refsulc."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii + if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii ] ; then + cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii + fi + + #Concatenate FS registration to FS --> FS_LR registration + wb_command -surface-sphere-project-unproject "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.native.surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii + + #Make FreeSurfer Registration Areal Distortion Maps + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_FS + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii -edge-method + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -local-affine-method + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 1 + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 2 + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii + +done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block5.sh b/CPAC/surface/PostFreeSurfer/block5.sh index 25b5b04b3b..5b9ee7b046 100755 --- a/CPAC/surface/PostFreeSurfer/block5.sh +++ b/CPAC/surface/PostFreeSurfer/block5.sh @@ -49,6 +49,7 @@ RegName=MSMSulc # RegName=FS useT2=false + # default parameters CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) InflateExtraScale=1 @@ -127,20 +128,66 @@ cd ${StudyFolder} STRINGII="" for LowResMesh in ${LowResMeshes} ; do - STRINGII=$(echo "${STRINGII}${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR ${T1wFolder}/fsaverage_LR${LowResMesh}k@${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR ") + STRINGII=$(echo "${STRINGII}${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR@atlasroi ") done -#Add CIFTI Maps to Spec Files -for STRING in "$T1wFolder"/"$NativeFolder"@"$AtlasSpaceFolder"/"$NativeFolder"@native "$AtlasSpaceFolder"/"$NativeFolder"@"$AtlasSpaceFolder"/"$NativeFolder"@native "$AtlasSpaceFolder"@"$AtlasSpaceFolder"@"$HighResMesh"k_fs_LR ${STRINGII} ; do - FolderI=$(echo $STRING | cut -d "@" -f 1) - FolderII=$(echo $STRING | cut -d "@" -f 2) - Mesh=$(echo $STRING | cut -d "@" -f 3) - for STRINGII in sulc@dscalar thickness@dscalar curvature@dscalar aparc@dlabel aparc.a2009s@dlabel ; do #Remove BA@dlabel because it doesn't convert properly - Map=$(echo $STRINGII | cut -d "@" -f 1) - Ext=$(echo $STRINGII | cut -d "@" -f 2) - if [ -e "$FolderII"/"$Subject"."$Map"."$Mesh"."$Ext".nii ] ; then - wb_command -add-to-spec-file "$FolderI"/"$Subject"."$Mesh".wb.spec INVALID "$FolderII"/"$Subject"."$Map"."$Mesh"."$Ext".nii +#Create CIFTI Files +for STRING in "$AtlasSpaceFolder"/"$NativeFolder"@native@roi "$AtlasSpaceFolder"@"$HighResMesh"k_fs_LR@atlasroi ${STRINGII} ; do + Folder=$(echo $STRING | cut -d "@" -f 1) + Mesh=$(echo $STRING | cut -d "@" -f 2) + ROI=$(echo $STRING | cut -d "@" -f 3) + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.sulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.sulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -map 1 "${Subject}_Sulc" + wb_command -cifti-palette "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".sulc."$Mesh".dscalar.nii -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.curvature."$Mesh".shape.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.curvature."$Mesh".shape.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -map 1 "${Subject}_Curvature" + wb_command -cifti-palette "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".curvature."$Mesh".dscalar.nii -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.thickness."$Mesh".shape.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.thickness."$Mesh".shape.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -map 1 "${Subject}_Thickness" + wb_command -cifti-palette "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii MODE_AUTO_SCALE_PERCENTAGE "$Folder"/"$Subject".thickness."$Mesh".dscalar.nii -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.ArealDistortion_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.ArealDistortion_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -map 1 "${Subject}_ArealDistortion_FS" + wb_command -cifti-palette "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".ArealDistortion_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.EdgeDistortion_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.EdgeDistortion_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -map 1 "${Subject}_EdgeDistortion_FS" + wb_command -cifti-palette "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".EdgeDistortion_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainJ_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainJ_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -map 1 "${Subject}_StrainJ_FS" + wb_command -cifti-palette "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainJ_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainR_FS."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainR_FS."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -map 1 "${Subject}_StrainR_FS" + wb_command -cifti-palette "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainR_FS."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.ArealDistortion_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.ArealDistortion_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_ArealDistortion_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".ArealDistortion_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.EdgeDistortion_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.EdgeDistortion_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_EdgeDistortion_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".EdgeDistortion_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainJ_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainJ_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_StrainJ_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainJ_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + + wb_command -cifti-create-dense-scalar "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -left-metric "$Folder"/"$Subject".L.StrainR_MSMSulc."$Mesh".shape.gii -right-metric "$Folder"/"$Subject".R.StrainR_MSMSulc."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -map 1 "${Subject}_StrainR_MSMSulc" + wb_command -cifti-palette "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii MODE_USER_SCALE "$Folder"/"$Subject".StrainR_MSMSulc."$Mesh".dscalar.nii -pos-user 0 1 -neg-user 0 -1 -interpolate true -palette-name ROY-BIG-BL -disp-pos true -disp-neg true -disp-zero false + fi + + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$Folder"/"$Subject".L.${Map}."$Mesh".label.gii ] ; then + wb_command -cifti-create-label "$Folder"/"$Subject".${Map}."$Mesh".dlabel.nii -left-label "$Folder"/"$Subject".L.${Map}."$Mesh".label.gii -roi-left "$Folder"/"$Subject".L."$ROI"."$Mesh".shape.gii -right-label "$Folder"/"$Subject".R.${Map}."$Mesh".label.gii -roi-right "$Folder"/"$Subject".R."$ROI"."$Mesh".shape.gii + wb_command -set-map-names "$Folder"/"$Subject".${Map}."$Mesh".dlabel.nii -map 1 "$Subject"_${Map} fi done + done done -done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block6.sh b/CPAC/surface/PostFreeSurfer/block6.sh index 29e7cc564f..25b5b04b3b 100755 --- a/CPAC/surface/PostFreeSurfer/block6.sh +++ b/CPAC/surface/PostFreeSurfer/block6.sh @@ -113,9 +113,6 @@ source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions echo "HCPPIPEDIR: ${HCPPIPEDIR}" MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig -# Create midthickness Vertex Area (VA) maps -echo "Create midthickness Vertex Area (VA) maps" - for Hemisphere in L R ; do #Set a bunch of different ways of saying left and right if [ $Hemisphere = "L" ] ; then @@ -125,53 +122,25 @@ for Hemisphere in L R ; do hemisphere="r" Structure="CORTEX_RIGHT" fi + cd ${StudyFolder} +STRINGII="" for LowResMesh in ${LowResMeshes} ; do + STRINGII=$(echo "${STRINGII}${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR ${T1wFolder}/fsaverage_LR${LowResMesh}k@${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k@${LowResMesh}k_fs_LR ") +done - echo "Creating midthickness Vertex Area (VA) maps for LowResMesh: ${LowResMesh}" - - # DownSampleT1wFolder - path to folder containing downsampled T1w files - # midthickness_va_file - path to non-normalized midthickness vertex area file - # normalized_midthickness_va_file - path ot normalized midthickness vertex area file - # surface_to_measure - path to surface file on which to measure surface areas - # output_metric - path to metric file generated by -surface-vertex-areas subcommand - - DownSampleT1wFolder=${T1wFolder}/fsaverage_LR${LowResMesh}k - DownSampleFolder=${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k - midthickness_va_file=${DownSampleT1wFolder}/${Subject}.midthickness_va.${LowResMesh}k_fs_LR.dscalar.nii - normalized_midthickness_va_file=${DownSampleT1wFolder}/${Subject}.midthickness_va_norm.${LowResMesh}k_fs_LR.dscalar.nii - - for Hemisphere in L R ; do - surface_to_measure=${DownSampleT1wFolder}/${Subject}.${Hemisphere}.midthickness.${LowResMesh}k_fs_LR.surf.gii - output_metric=${DownSampleT1wFolder}/${Subject}.${Hemisphere}.midthickness_va.${LowResMesh}k_fs_LR.shape.gii - wb_command -surface-vertex-areas ${surface_to_measure} ${output_metric} +#Add CIFTI Maps to Spec Files +for STRING in "$T1wFolder"/"$NativeFolder"@"$AtlasSpaceFolder"/"$NativeFolder"@native "$AtlasSpaceFolder"/"$NativeFolder"@"$AtlasSpaceFolder"/"$NativeFolder"@native "$AtlasSpaceFolder"@"$AtlasSpaceFolder"@"$HighResMesh"k_fs_LR ${STRINGII} ; do + FolderI=$(echo $STRING | cut -d "@" -f 1) + FolderII=$(echo $STRING | cut -d "@" -f 2) + Mesh=$(echo $STRING | cut -d "@" -f 3) + for STRINGII in sulc@dscalar thickness@dscalar curvature@dscalar aparc@dlabel aparc.a2009s@dlabel ; do #Remove BA@dlabel because it doesn't convert properly + Map=$(echo $STRINGII | cut -d "@" -f 1) + Ext=$(echo $STRINGII | cut -d "@" -f 2) + if [ -e "$FolderII"/"$Subject"."$Map"."$Mesh"."$Ext".nii ] ; then + wb_command -add-to-spec-file "$FolderI"/"$Subject"."$Mesh".wb.spec INVALID "$FolderII"/"$Subject"."$Map"."$Mesh"."$Ext".nii + fi done - - # left_metric - path to left hemisphere VA metric file - # roi_left - path to file of ROI vertices to use from left surface - # right_metric - path to right hemisphere VA metric file - # roi_right - path to file of ROI vertices to use from right surface - - left_metric=${DownSampleT1wFolder}/${Subject}.L.midthickness_va.${LowResMesh}k_fs_LR.shape.gii - roi_left=${DownSampleFolder}/${Subject}.L.atlasroi.${LowResMesh}k_fs_LR.shape.gii - right_metric=${DownSampleT1wFolder}/${Subject}.R.midthickness_va.${LowResMesh}k_fs_LR.shape.gii - roi_right=${DownSampleFolder}/${Subject}.R.atlasroi.${LowResMesh}k_fs_LR.shape.gii - - wb_command -cifti-create-dense-scalar ${midthickness_va_file} \ - -left-metric ${left_metric} \ - -roi-left ${roi_left} \ - -right-metric ${right_metric} \ - -roi-right ${roi_right} - - # VAMean - mean of surface area accounted for for each vertex - used for normalization - VAMean=$(wb_command -cifti-stats ${midthickness_va_file} -reduce MEAN) - echo "VAMean: ${VAMean}" - - wb_command -cifti-math "VA / ${VAMean}" ${normalized_midthickness_va_file} -var VA ${midthickness_va_file} - - echo "Done creating midthickness Vertex Area (VA) maps for LowResMesh: ${LowResMesh}" - -done done -echo "Done creating midthickness Vertex Area (VA) maps" +done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block7.sh b/CPAC/surface/PostFreeSurfer/block7.sh new file mode 100755 index 0000000000..29e7cc564f --- /dev/null +++ b/CPAC/surface/PostFreeSurfer/block7.sh @@ -0,0 +1,177 @@ + +#!/bin/bash + +echo "START" + +StudyFolder="$1" +echo "StudyFolder: ${StudyFolder}" + +FreeSurferFolder="$2" +echo "FreeSurferFolder: ${FreeSurferFolder}" + +Subject="$3" +echo "Subject: ${Subject}" + +T1wRestoreImageCPAC="$4" +echo "T1wRestoreImageCPAC: ${T1wRestoreImageCPAC}" + +AtlasSpaceT1wImageCPAC="$5" +echo "AtlasSpaceT1wImageCPAC: ${AtlasSpaceT1wImageCPAC}" + +AtlasTransformCPAC="$6" +echo "AtlasTransformCPAC ${AtlasTransformCPAC}" + +InverseAtlasTransformCPAC="$7" +echo "InverseAtlasTransformCPAC: ${InverseAtlasTransformCPAC}" + +SurfaceAtlasDIR="$8" +echo "SurfaceAtlasDIR: ${SurfaceAtlasDIR}" + +GrayordinatesSpaceDIR="$9" +echo "GrayordinatesSpaceDIR: ${GrayordinatesSpaceDIR}" + +GrayordinatesResolutions="${10}" +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HighResMesh="${11}" +echo "HighResMesh: ${HighResMesh}" + +LowResMeshes="${12}" +echo "LowResMeshes: ${LowResMeshes}" + +SubcorticalGrayLabels="${13}" +echo "SubcorticalGrayLabels: ${SubcorticalGrayLabels}" + +FreeSurferLabels="${14}" +echo "FreeSurferLabels: ${FreeSurferLabels}" + +RegName=MSMSulc +# RegName=FS +useT2=false + +# default parameters +CorrectionSigma=$(echo "sqrt ( 200 )" | bc -l) +InflateExtraScale=1 + +#Naming Conventions +T1wImage="T1w_acpc_dc" +T1wFolder="T1w" #Location of T1w images +T2wFolder="T2w" #Location of T1w images +T2wImage="T2w_acpc_dc" +AtlasSpaceFolder="MNINonLinear" +NativeFolder="Native" +FreeSurferInput="T1w_acpc_dc_restore_1mm" +AtlasTransform="acpc_dc2standard" +InverseAtlasTransform="standard2acpc_dc" +AtlasSpaceT1wImage="T1w_restore" +AtlasSpaceT2wImage="T2w_restore" +T1wRestoreImage="T1w_acpc_dc_restore" +T2wRestoreImage="T2w_acpc_dc_restore" +OrginalT1wImage="T1w" +OrginalT2wImage="T2w" +T1wImageBrainMask="brainmask_fs" +InitialT1wTransform="acpc.mat" +dcT1wTransform="T1w_dc.nii.gz" +InitialT2wTransform="acpc.mat" +dcT2wTransform="T2w_reg_dc.nii.gz" +FinalT2wTransform="${Subject}/mri/transforms/T2wtoT1w.mat" +BiasField="BiasField_acpc_dc" +OutputT1wImage="T1w_acpc_dc" +OutputT1wImageRestore="T1w_acpc_dc_restore" +OutputT1wImageRestoreBrain="T1w_acpc_dc_restore_brain" +OutputMNIT1wImage="T1w" +OutputMNIT1wImageRestore="T1w_restore" +OutputMNIT1wImageRestoreBrain="T1w_restore_brain" +OutputT2wImage="T2w_acpc_dc" +OutputT2wImageRestore="T2w_acpc_dc_restore" +OutputT2wImageRestoreBrain="T2w_acpc_dc_restore_brain" +OutputMNIT2wImage="T2w" +OutputMNIT2wImageRestore="T2w_restore" +OutputMNIT2wImageRestoreBrain="T2w_restore_brain" +OutputOrigT1wToT1w="OrigT1w2T1w.nii.gz" +OutputOrigT1wToStandard="OrigT1w2standard.nii.gz" #File was OrigT2w2standard.nii.gz, regnerate and apply matrix +OutputOrigT2wToT1w="OrigT2w2T1w.nii.gz" #mv OrigT1w2T2w.nii.gz OrigT2w2T1w.nii.gz +OutputOrigT2wToStandard="OrigT2w2standard.nii.gz" +BiasFieldOutput="BiasField" +Jacobian="NonlinearRegJacobians.nii.gz" + + +T1wFolder="$StudyFolder"/"$T1wFolder" +T2wFolder="$StudyFolder"/"$T2wFolder" +AtlasSpaceFolder="$StudyFolder"/"$AtlasSpaceFolder" +AtlasTransform="$AtlasSpaceFolder"/xfms/"$AtlasTransform" +InverseAtlasTransform="$AtlasSpaceFolder"/xfms/"$InverseAtlasTransform" + +LowResMeshes=${LowResMeshes//@/ } +echo "LowResMeshes: ${LowResMeshes}" + +GrayordinatesResolutions=${GrayordinatesResolutions//@/ } +echo "GrayordinatesResolutions: ${GrayordinatesResolutions}" + +HCPPIPEDIR=/code/CPAC/resources +source ${HCPPIPEDIR}/global/scripts/log.shlib # Logging related functions +echo "HCPPIPEDIR: ${HCPPIPEDIR}" +MSMCONFIGDIR=${HCPPIPEDIR}/MSMConfig + +# Create midthickness Vertex Area (VA) maps +echo "Create midthickness Vertex Area (VA) maps" + +for Hemisphere in L R ; do + #Set a bunch of different ways of saying left and right + if [ $Hemisphere = "L" ] ; then + hemisphere="l" + Structure="CORTEX_LEFT" + elif [ $Hemisphere = "R" ] ; then + hemisphere="r" + Structure="CORTEX_RIGHT" + fi +cd ${StudyFolder} + +for LowResMesh in ${LowResMeshes} ; do + + echo "Creating midthickness Vertex Area (VA) maps for LowResMesh: ${LowResMesh}" + + # DownSampleT1wFolder - path to folder containing downsampled T1w files + # midthickness_va_file - path to non-normalized midthickness vertex area file + # normalized_midthickness_va_file - path ot normalized midthickness vertex area file + # surface_to_measure - path to surface file on which to measure surface areas + # output_metric - path to metric file generated by -surface-vertex-areas subcommand + + DownSampleT1wFolder=${T1wFolder}/fsaverage_LR${LowResMesh}k + DownSampleFolder=${AtlasSpaceFolder}/fsaverage_LR${LowResMesh}k + midthickness_va_file=${DownSampleT1wFolder}/${Subject}.midthickness_va.${LowResMesh}k_fs_LR.dscalar.nii + normalized_midthickness_va_file=${DownSampleT1wFolder}/${Subject}.midthickness_va_norm.${LowResMesh}k_fs_LR.dscalar.nii + + for Hemisphere in L R ; do + surface_to_measure=${DownSampleT1wFolder}/${Subject}.${Hemisphere}.midthickness.${LowResMesh}k_fs_LR.surf.gii + output_metric=${DownSampleT1wFolder}/${Subject}.${Hemisphere}.midthickness_va.${LowResMesh}k_fs_LR.shape.gii + wb_command -surface-vertex-areas ${surface_to_measure} ${output_metric} + done + + # left_metric - path to left hemisphere VA metric file + # roi_left - path to file of ROI vertices to use from left surface + # right_metric - path to right hemisphere VA metric file + # roi_right - path to file of ROI vertices to use from right surface + + left_metric=${DownSampleT1wFolder}/${Subject}.L.midthickness_va.${LowResMesh}k_fs_LR.shape.gii + roi_left=${DownSampleFolder}/${Subject}.L.atlasroi.${LowResMesh}k_fs_LR.shape.gii + right_metric=${DownSampleT1wFolder}/${Subject}.R.midthickness_va.${LowResMesh}k_fs_LR.shape.gii + roi_right=${DownSampleFolder}/${Subject}.R.atlasroi.${LowResMesh}k_fs_LR.shape.gii + + wb_command -cifti-create-dense-scalar ${midthickness_va_file} \ + -left-metric ${left_metric} \ + -roi-left ${roi_left} \ + -right-metric ${right_metric} \ + -roi-right ${roi_right} + + # VAMean - mean of surface area accounted for for each vertex - used for normalization + VAMean=$(wb_command -cifti-stats ${midthickness_va_file} -reduce MEAN) + echo "VAMean: ${VAMean}" + + wb_command -cifti-math "VA / ${VAMean}" ${normalized_midthickness_va_file} -var VA ${midthickness_va_file} + + echo "Done creating midthickness Vertex Area (VA) maps for LowResMesh: ${LowResMesh}" + +done +done +echo "Done creating midthickness Vertex Area (VA) maps" diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 9df6459d1a..adf8220bad 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -80,7 +80,7 @@ def run_surface(post_freesurfer_folder, subprocess.check_output(cmd) #DCAN-HCP PostFreeSurfer Block3.5 - cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block3-5.sh', post_freesurfer_folder, \ + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block4.sh', post_freesurfer_folder, \ freesurfer_folder, subject, \ t1w_restore_image, atlas_space_t1w_image, \ atlas_transform, inverse_atlas_transform, \ @@ -92,7 +92,7 @@ def run_surface(post_freesurfer_folder, # DCAN-HCP PostFreeSurfer Block4 - cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block4.sh', post_freesurfer_folder, \ + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block5.sh', post_freesurfer_folder, \ freesurfer_folder, subject, \ t1w_restore_image, atlas_space_t1w_image, \ atlas_transform, inverse_atlas_transform, \ @@ -104,7 +104,7 @@ def run_surface(post_freesurfer_folder, # DCAN-HCP PostFreeSurfer Block5 - cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block5.sh', post_freesurfer_folder, \ + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block6.sh', post_freesurfer_folder, \ freesurfer_folder, subject, \ t1w_restore_image, atlas_space_t1w_image, \ atlas_transform, inverse_atlas_transform, \ @@ -116,7 +116,7 @@ def run_surface(post_freesurfer_folder, # DCAN-HCP PostFreeSurfer Block6 - cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block6.sh', post_freesurfer_folder, \ + cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block7.sh', post_freesurfer_folder, \ freesurfer_folder, subject, \ t1w_restore_image, atlas_space_t1w_image, \ atlas_transform, inverse_atlas_transform, \ From 96cbd80ad59357c934869aca5c310b40c34613a0 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 19 Oct 2023 09:59:37 -0400 Subject: [PATCH 067/213] Clean up surf_reho --- CPAC/surface/PostFreeSurfer/surf_reho.py | 67 +++++++++++++----------- CPAC/surface/surf_preproc.py | 12 +---- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/CPAC/surface/PostFreeSurfer/surf_reho.py b/CPAC/surface/PostFreeSurfer/surf_reho.py index 3e0f09dc52..6c0201a82a 100644 --- a/CPAC/surface/PostFreeSurfer/surf_reho.py +++ b/CPAC/surface/PostFreeSurfer/surf_reho.py @@ -4,15 +4,6 @@ import sys -dtseries = nb.load(sys.argv[1]) # dtseries file -mask = nb.load(sys.argv[2]) # surface mask file -cortex_file = nb.load(sys.argv[3]) # cortex file -surf_file = nb.load(sys.argv[4]) # surface file -scalar_dt = nb.load(sys.argv[5]) # mean_timeseries -structure_name = sys.argv[6] #structure name -surf_reho = sys.argv[7] # Path to reho file - - def get_neighbours(faces, vertex_id, depth=1): fois = np.where(faces == vertex_id)[0] nbrs = list(np.unique(faces[fois])) @@ -65,32 +56,48 @@ def ccs_ReHo(dt_file, surf_file): return(cReHo) -cReHo = ccs_ReHo(cortex_file, surf_file) +def run_surf_reho(subject, dtseries, mask, cortex_file, \ + surface_file, mean_timeseries, reho_filename, structure_name): + + import os + import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess + + dtseries = nb.load(dtseries) # dtseries file + mask = nb.load(mask) # surface mask file + cortex_file = nb.load(cortex_file) # cortex file + surf_file = nb.load(surface_file) # surface file + scalar_dt = nb.load(mean_timeseries) # mean_timeseries + surf_reho = os.path.join(os.getcwd(), f'{subject}_{reho_filename}') + + cReHo = ccs_ReHo(cortex_file, surf_file) + + ## Axes and Header stuff ## + axes = [dtseries.header.get_axis(i) for i in range(dtseries.ndim)] + axes1 = [scalar_dt.header.get_axis(i) for i in range(scalar_dt.ndim)] -## Axes and Header stuff ## -axes = [dtseries.header.get_axis(i) for i in range(dtseries.ndim)] -axes1 = [scalar_dt.header.get_axis(i) for i in range(scalar_dt.ndim)] + time_axis, brain_model_axis = axes #dtseries + time_axis1, brain_axis1 = axes1 #dscalar -time_axis, brain_model_axis = axes #dtseries -time_axis1, brain_axis1 = axes1 #dscalar + # Select the structures you want + structure_names = [structure_name] # List of structure names -# Select the structures you want -structure_names = [structure_name] # List of structure names + brain_models = [bm for bm in brain_model_axis.iter_structures() + if bm[0] in structure_names] -brain_models = [bm for bm in brain_model_axis.iter_structures() - if bm[0] in structure_names] + new_dataobj = np.concatenate([dtseries.dataobj[0, bm[1]] for bm in brain_models], axis=0) + new_dataobj = np.transpose(new_dataobj.reshape(-1,1)) -new_dataobj = np.concatenate([dtseries.dataobj[0, bm[1]] for bm in brain_models], axis=0) -new_dataobj = np.transpose(new_dataobj.reshape(-1,1)) + new_brain_model_axis = sum( + (bm[2] for bm in brain_models[1:]), brain_models[0][2]) -new_brain_model_axis = sum( - (bm[2] for bm in brain_models[1:]), brain_models[0][2]) + new_cifti = nb.Cifti2Image(new_dataobj, + header=(time_axis1, new_brain_model_axis), + nifti_header=dtseries.nifti_header) -new_cifti = nb.Cifti2Image(new_dataobj, - header=(time_axis1, new_brain_model_axis), - nifti_header=dtseries.nifti_header) + ## Saving image ## + img = nb.Cifti2Image(np.transpose(cReHo), header = new_cifti.header, nifti_header=new_cifti.nifti_header) + reho_file = surf_reho + img.to_filename(reho_file) -## Saving image ## -img = nb.Cifti2Image(np.transpose(cReHo), header = new_cifti.header, nifti_header=new_cifti.nifti_header) -reho_file = surf_reho -img.to_filename(reho_file) \ No newline at end of file + return surf_reho \ No newline at end of file diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index adf8220bad..5a74aba56e 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -3,6 +3,7 @@ import nipype.interfaces.utility as util from CPAC.utils.interfaces.function import Function from CPAC.pipeline import nipype_pipeline_engine as pe +from CPAC.surface.PostFreeSurfer.surf_reho import run_surf_reho def run_surface(post_freesurfer_folder, @@ -1067,17 +1068,6 @@ def run_mean_timeseries(subject, dtseries): log_subprocess(cmd) return mean_timeseries -def run_surf_reho(subject, dtseries, mask, cortex_file, \ - surface_file, mean_timeseries, reho_filename, structure_name): - - import os - import subprocess - from CPAC.utils.monitoring.custom_logging import log_subprocess - surf_reho = os.path.join(os.getcwd(), f'{subject}_{reho_filename}') - cmd = ['python', '/code/CPAC/surface/PostFreeSurfer/surf_reho.py', dtseries, mask, cortex_file, surface_file, mean_timeseries, structure_name, surf_reho] - log_subprocess(cmd) - return surf_reho - def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): import os import subprocess From a4fb97d43b9c998f439d4d32f8631ee90331c0a1 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Fri, 20 Oct 2023 14:47:57 -0400 Subject: [PATCH 068/213] Nest surface derivatives under surface_analysis --- CPAC/pipeline/schema.py | 17 ++++++++++------- .../configs/pipeline_config_abcd-options.yml | 9 +++++++++ .../resources/configs/pipeline_config_blank.yml | 12 +++++++++--- CPAC/surface/surf_preproc.py | 10 +++++----- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index e16fdf923e..fa0f0090d5 100755 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -732,6 +732,16 @@ def sanitize(filename): 'fmri_res': Maybe(int), 'smooth_fwhm': Maybe(int), }, + 'amplitude_low_frequency_fluctuation': { + 'run': bool1_1, + }, + 'regional_homogeneity': { + 'run': bool1_1, + }, + 'surface_connectivity': { + 'run': bool1_1, + 'surface_parcellation_template': Maybe(str), + }, }, 'longitudinal_template_generation': { 'run': bool1_1, @@ -992,13 +1002,6 @@ def sanitize(filename): for option in ['using', 'measure'] }, }, - - 'surface_amplitude_low_frequency_fluctuation': {'run': bool}, - 'surface_regional_homogeneity': {'run': bool}, - - 'surface_connectivity': { - 'run': bool, - 'surface_parcellation_template':Maybe(str) }, 'seed_based_correlation_analysis': { 'run': bool1_1, Optional('roi_paths_fully_specified'): bool1_1, diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index b96c0ec79a..0e38d07a55 100755 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -45,6 +45,15 @@ surface_analysis: post_freesurfer: run: On + amplitude_low_frequency_fluctuation: + run: True + + regional_homogeneity: + run: True + + surface_connectivity: + run: True + anatomical_preproc: run: On acpc_alignment: diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index e8c0839f0e..60a1a2a0e0 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -227,6 +227,15 @@ surface_analysis: fmri_res: 2 smooth_fwhm: 2 + amplitude_low_frequency_fluctuation: + run: True + + regional_homogeneity: + run: True + + surface_connectivity: + surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii + anatomical_preproc: run: Off acpc_alignment: @@ -1344,9 +1353,6 @@ timeseries_extraction: # check your data if you see issues realignment: ROI_to_func -surface_connectivity: - surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii - amplitude_low_frequency_fluctuation: # ALFF & f/ALFF diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 5a74aba56e..1f81d9e8d5 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -866,7 +866,7 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): @nodeblock( name="surface_falff", - config=["surface_amplitude_low_frequency_fluctuation"], + config=["surface_analysis", "amplitude_low_frequency_fluctuation"], switch=["run"], inputs=["space-fsLR_den-32k_bold"], outputs=[ @@ -890,7 +890,7 @@ def surface_falff(wf, cfg, strat_pool, pipe_num, opt): @nodeblock( name="surface_alff", - config=["surface_amplitude_low_frequency_fluctuation"], + config=["surface_analysis", "amplitude_low_frequency_fluctuation"], switch=["run"], inputs=["space-fsLR_den-32k_bold"], outputs=[ @@ -914,7 +914,7 @@ def surface_alff(wf, cfg, strat_pool, pipe_num, opt): @nodeblock( name="surface_reho", - config=["surface_regional_homogeneity"], + config=["surface_analysis", "regional_homogeneity"], switch=["run"], inputs=["space-fsLR_den-32k_bold", "hemi-L_space-fsLR_den-32k_midthickness", @@ -1000,7 +1000,7 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt): @nodeblock( name="surface_connectivity_matrix", - config=["surface_connectivity"], + config=["surface_analysis", "surface_connectivity"], switch=["run"], inputs=["space-fsLR_den-32k_bold"], outputs=["space-fsLR_den-32k_bold_surf-correlation_matrix"], @@ -1017,7 +1017,7 @@ def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): connectivity_parcellation.inputs.subject = cfg['subject_id'] node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, connectivity_parcellation, 'dtseries') - connectivity_parcellation.inputs.surf_atlaslabel = cfg['surface_connectivity']['surface_parcellation_template'] + connectivity_parcellation.inputs.surf_atlaslabel = cfg["surface_analysis"]['surface_connectivity']['surface_parcellation_template'] correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], output_names=['correlation_matrix'], From d64522a1c01559d8ad0d67607c61d3a97d9e4fc1 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Fri, 20 Oct 2023 14:50:26 -0400 Subject: [PATCH 069/213] Default values off for surface derivatives --- CPAC/resources/configs/pipeline_config_blank.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 60a1a2a0e0..6ed1b781e5 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -228,12 +228,13 @@ surface_analysis: smooth_fwhm: 2 amplitude_low_frequency_fluctuation: - run: True + run: Off regional_homogeneity: - run: True - + run: Off + surface_connectivity: + run: Off surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii anatomical_preproc: From adc0e3a13ebf5f021104565bd5d63110c2deca19 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Fri, 20 Oct 2023 14:54:14 -0400 Subject: [PATCH 070/213] :wrench: Fix default preconfig --- CPAC/resources/configs/pipeline_config_default.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index f26f15aef4..60ee786da8 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -234,6 +234,8 @@ surface_analysis: smooth_fwhm: 2 + surface_connectivity: + surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii longitudinal_template_generation: @@ -1637,9 +1639,6 @@ seed_based_correlation_analysis: # Normalize each time series before running Dual Regression SCA. norm_timeseries_for_DR: True -surface_connectivity: - surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii - amplitude_low_frequency_fluctuation: # ALFF & f/ALFF From ad968cbb65e77c072e0faf4fd94bfb82e5232e44 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Fri, 20 Oct 2023 18:55:48 +0000 Subject: [PATCH 071/213] :bulb: Update comments based on default preconfig --- .../configs/pipeline_config_abcd-options.yml | 12 ++++++------ CPAC/resources/configs/pipeline_config_blank.yml | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index 0e38d07a55..ce546f73b4 100755 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -45,14 +45,14 @@ surface_analysis: post_freesurfer: run: On - amplitude_low_frequency_fluctuation: - run: True - + amplitude_low_frequency_fluctuation: + run: On + regional_homogeneity: - run: True - + run: On + surface_connectivity: - run: True + run: On anatomical_preproc: run: On diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 6ed1b781e5..0eb999a0f9 100755 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -227,9 +227,9 @@ surface_analysis: fmri_res: 2 smooth_fwhm: 2 - amplitude_low_frequency_fluctuation: - run: Off - + amplitude_low_frequency_fluctuation: + run: Off + regional_homogeneity: run: Off From 8a44aa44ad404b995683f895f279ccb007598f47 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Wed, 22 Nov 2023 11:12:28 -0500 Subject: [PATCH 072/213] dvars output added in cpac_outputs.tsv --- CPAC/resources/cpac_outputs.tsv | 1 + 1 file changed, 1 insertion(+) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 03ddd5de73..e85de5fbe1 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -100,6 +100,7 @@ space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI motion motion func TSV desc-summary_motion motion func TSV +dvars motion func TSV Yes motion-filter-plot motion func png desc-movementParameters_motion motion func TSV desc-movementParametersUnfiltered_motion motion func TSV From 8d1eb2390ab55cef6ac5f6dd52fd2fbe8a947c5d Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 27 Nov 2023 23:22:02 -0500 Subject: [PATCH 073/213] default config -write_debugging_outputs: True --- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 0ad367a48b..100c57c1aa 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -42,7 +42,7 @@ pipeline_setup: write_func_outputs: False # Include extra outputs in the output directory that may be of interest when more information is needed. - write_debugging_outputs: False + write_debugging_outputs: True # Output directory format and structure. # Options: default, ndmg From 8eb926b1c68fbdba9c0ceec1b42677dce62c6735 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 27 Nov 2023 23:50:23 -0500 Subject: [PATCH 074/213] default config restored back to original --- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 100c57c1aa..0ad367a48b 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -42,7 +42,7 @@ pipeline_setup: write_func_outputs: False # Include extra outputs in the output directory that may be of interest when more information is needed. - write_debugging_outputs: True + write_debugging_outputs: False # Output directory format and structure. # Options: default, ndmg From 0501e95bbbb89f9c2000e2c23d20358cecf9ebee Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 7 Dec 2023 13:01:42 -0500 Subject: [PATCH 075/213] :pencil: Minor changes to surf_postproc --- CPAC/pipeline/engine.py | 6 +++--- CPAC/resources/configs/pipeline_config_default.yml | 1 + CPAC/surface/surf_preproc.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 33696f6933..cf4e1aa933 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1268,11 +1268,11 @@ def check_output(self, outputs, label, name): f'{outputs} in Node Block "{name}"\n') def grab_tiered_dct(self, cfg, key_list): - cfg_dct = cfg + cfg_dct = cfg.dict() for key in key_list: try: - cfg_dct = cfg_dct.__getitem__(key) - #print(cfg_dct) + print(key) + cfg_dct = cfg_dct.get(key, {}) except KeyError: raise Exception(f"[!] The config provided to the node block is not valid") return cfg_dct diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 60ee786da8..8ff499d95f 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -235,6 +235,7 @@ surface_analysis: smooth_fwhm: 2 surface_connectivity: + run: On surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii longitudinal_template_generation: diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 1f81d9e8d5..86e3d410cd 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -1009,7 +1009,7 @@ def surface_reho(wf, cfg, strat_pool, pipe_num, opt): def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): - connectivity_parcellation = pe.Node(util.Function(input_names=['subject','dtseries', 'surf_atlaslabel'], + connectivity_parcellation = pe.Node(util.Function(input_names=['subject', 'dtseries', 'surf_atlaslabel'], output_names=['parcellation_file'], function=run_ciftiparcellate), name=f'connectivity_parcellation_{pipe_num}') @@ -1017,7 +1017,7 @@ def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): connectivity_parcellation.inputs.subject = cfg['subject_id'] node, out = strat_pool.get_data('space-fsLR_den-32k_bold') wf.connect(node, out, connectivity_parcellation, 'dtseries') - connectivity_parcellation.inputs.surf_atlaslabel = cfg["surface_analysis"]['surface_connectivity']['surface_parcellation_template'] + connectivity_parcellation.inputs.surf_atlaslabel = cfg.surface_analysis['surface_connectivity']['surface_parcellation_template'] correlation_matrix = pe.Node(util.Function(input_names=['subject','ptseries'], output_names=['correlation_matrix'], From b0a67927d39f514fe5994974f6de8c19675436af Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 12 Dec 2023 15:03:23 -0500 Subject: [PATCH 076/213] Fix merge errors --- CPAC/pipeline/engine.py | 4 ++-- CPAC/utils/outputs.py | 10 ++++++++++ CPAC/utils/utils.py | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 9f783f325b..63175e1328 100755 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1132,7 +1132,8 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): 'template_desc', 'atlas_id', 'fwhm', - 'subdir'], + 'subdir', + 'extension'], output_names=['out_filename'], function=create_id_string), name=f'id_string_{resource_idx}_{pipe_x}') @@ -1348,7 +1349,6 @@ def grab_tiered_dct(self, cfg, key_list): cfg_dct = cfg.dict() for key in key_list: try: - print(key) cfg_dct = cfg_dct.get(key, {}) except KeyError: raise Exception(f"[!] The config provided to the node block is not valid") diff --git a/CPAC/utils/outputs.py b/CPAC/utils/outputs.py index 5aaf022a61..9516320b6e 100755 --- a/CPAC/utils/outputs.py +++ b/CPAC/utils/outputs.py @@ -74,3 +74,13 @@ class Outputs(): template_raw = list(reference[all_template_filter & (reference['To z-std'] == 'Yes')]['Resource']) + + def _is_cifti(_file_key): + return _file_key.upper().startswith('CIFTI ') + ciftis = reference[reference.File.map(_is_cifti)][['Resource', 'File']] + ciftis = {cifti.Resource: cifti.File.split(' ')[-1] for cifti in ciftis.itertuples() if ' ' in cifti.File} + + def _is_gifti(_file_key): + return _file_key.upper().startswith('GIFTI ') + giftis = reference[reference.File.map(_is_gifti)][['Resource', 'File']] + giftis = {gifti.Resource: gifti.File.split(' ')[-1] for gifti in giftis.itertuples() if ' ' in gifti.File} diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py index ab6535e1d4..4bdf3243ce 100755 --- a/CPAC/utils/utils.py +++ b/CPAC/utils/utils.py @@ -149,7 +149,7 @@ def read_json(json_file): def create_id_string(cfg, unique_id, resource, scan_id=None, template_desc=None, atlas_id=None, fwhm=None, - subdir=None): + subdir=None, extension=None): """Create the unique key-value identifier string for BIDS-Derivatives compliant file names. From 2eccabb7f7c83efd1d6758c9925d5e0c639a0050 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 12 Dec 2023 15:23:31 -0500 Subject: [PATCH 077/213] :bug: Fix config switches bug in cpac_templates.csv --- CPAC/resources/cpac_templates.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/cpac_templates.csv b/CPAC/resources/cpac_templates.csv index e89df7c08c..ba21e01e8c 100755 --- a/CPAC/resources/cpac_templates.csv +++ b/CPAC/resources/cpac_templates.csv @@ -40,4 +40,4 @@ template-eye-mask,"PyPEER, eye_mask_path",,"registration_workflows, functional_r T1w-brain-template-mask-ccs,"anatomical_preproc, brain_extraction, FreeSurfer-BET, T1w_brain_template_mask_ccs",, T2w-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_ACPC_template",Whole-head template for use in ACPC-alignment, T2w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_brain_ACPC_template",Brain-only template for use in ACPC-alignment, -surface-parcellation-atlas,"surface_connectivity, surface_parcellation_template",surface space parcellation atlas, \ No newline at end of file +surface-parcellation-atlas,"surface_analysis, surface_connectivity, surface_parcellation_template",surface space parcellation atlas, \ No newline at end of file From 40c5dd638e91770a385648741050c39d1e696fa2 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 14 Dec 2023 10:56:10 -0500 Subject: [PATCH 078/213] Delete extraneous cpac_templates folder --- C-PAC_templates | 1 - 1 file changed, 1 deletion(-) delete mode 160000 C-PAC_templates diff --git a/C-PAC_templates b/C-PAC_templates deleted file mode 160000 index 040483823e..0000000000 --- a/C-PAC_templates +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 040483823ed075bcaa32548c53153bbb0483285f From dd4b10c554a140ad1a91d27356925d4b78bbe528 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Mon, 18 Dec 2023 01:42:55 -0500 Subject: [PATCH 079/213] Update CPAC/resources/cpac_outputs.tsv Co-authored-by: Jon Clucas --- CPAC/resources/cpac_outputs.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index e85de5fbe1..1eed02d823 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -100,7 +100,7 @@ space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI motion motion func TSV desc-summary_motion motion func TSV -dvars motion func TSV Yes +dvars motion func TSV Yes motion-filter-plot motion func png desc-movementParameters_motion motion func TSV desc-movementParametersUnfiltered_motion motion func TSV From 8dd5fb60afa6d4b9ad9ae58984ea57386e2990cf Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 18 Dec 2023 12:13:32 -0500 Subject: [PATCH 080/213] tabs added for even columns --- CPAC/resources/cpac_outputs.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 1eed02d823..db3c5aaffd 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -218,4 +218,4 @@ space-EPItemplate_label-WM_mask mask template func NIfTI space-EPItemplate_label-GM_mask mask template func NIfTI mdmr group functional group_analysis NIfTI desc-zstd-mdmr group functional group_analysis NIfTI Yes -dseg anat +dseg anat \ No newline at end of file From 8c0f9d4b8b2b7af10f4469d75aeda864b2afc7e1 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Tue, 19 Dec 2023 21:24:19 +0000 Subject: [PATCH 081/213] padding to robustfov cropped image added --- CPAC/anat_preproc/anat_preproc.py | 30 ++++++++++++++++++++++++++---- CPAC/anat_preproc/utils.py | 9 +++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index d57f392d15..3adaeb963a 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -33,7 +33,8 @@ wb_command, \ fslmaths_command, \ VolumeRemoveIslands, \ - normalize_wmparc + normalize_wmparc, \ + pad, get_shape from CPAC.utils.interfaces.fsl import Merge as fslMerge @@ -647,16 +648,34 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) + anat_nifti_shape= pe.Node(util.Function(input_names=['nifti_image'], + output_names=['shape'], + function=get_shape), + name=f'anat_nifti_shape_{pipe_num}' + ) + anat_robustfov = pe.Node( interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + #anat_robustfov.brainsize = '%d' anat_robustfov.inputs.output_type = 'NIFTI_GZ' + pad_mask = pe.Node(util.Function(input_names=['cropped_image', 'target_shape'], + output_names=['padded_mask'], + function=pad), + name=f'pad_mask_{pipe_num}' + ) + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') + wf.connect(anat_nifti_shape, 'dim3', anat_robustfov, 'brainsize') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + wf.connect(node, out, anat_nifti_shape, 'nifti_image') + wf.connect(anat_robustfov, 'out_roi', pad_mask, 'cropped_image') + wf.connect(anat_nifti_shape,'shape', pad_mask, 'target_shape') + wf.connect(pad_mask, 'padded_image', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') @@ -664,10 +683,13 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('desc-preproc_T2w') if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + wf.connect(node, out, anat_nifti_shape, 'nifti_image') + wf.connect(anat_robustfov, 'out_roi', pad_mask, 'cropped_image') + wf.connect(anat_nifti_shape,'shape', pad_mask, 'target_shape') + wf.connect(pad_mask, 'padded_image', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') - + wf.connect([ (inputnode_bet, anat_skullstrip, [ ('frac', 'frac'), diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index 1ec23337f2..fe022ab8c3 100644 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -2,7 +2,16 @@ import nipype.interfaces.utility as util from CPAC.pipeline import nipype_pipeline_engine as pe +from nibabel import load as nib_load, Nifti1Image +from numpy import zeros +def get_shape(nifti_image): + return nib_load(nifti_image).shape + +def pad(cropped_image, target_shape): + padded_image = zeros(target_shape) + padded_image[:, :, :cropped_image.shape[2]] = cropped_image.get_data() + return Nifti1Image(padded_image, affine=cropped_image.affine) def fsl_aff_to_rigid(in_xfm, out_name): From 9a8936c7ba3869d2fc379d45cb4ac7c156673588 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:47:46 +0000 Subject: [PATCH 082/213] Bump tj-actions/changed-files in /.github/workflows Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 34.0.0 to 41.0.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v34.0.0...v41.0.0) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/build_stages.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build_stages.yml b/.github/workflows/build_stages.yml index 68e8249f7c..4a705f3b36 100644 --- a/.github/workflows/build_stages.yml +++ b/.github/workflows/build_stages.yml @@ -46,14 +46,14 @@ jobs: with: fetch-depth: 2 - name: Get changed files since fork point - uses: tj-actions/changed-files@v34.0.0 + uses: tj-actions/changed-files@v41.0.0 if: github.event.inputs.base_ref != '' id: changed-files-base with: use_fork_point: "true" files: .github/Dockerfiles/* - name: Get changed files since last commit - uses: tj-actions/changed-files@v34.0.0 + uses: tj-actions/changed-files@v41.0.0 if: github.event.inputs.base_ref == '' id: changed-files with: @@ -116,7 +116,7 @@ jobs: with: fetch-depth: 2 - name: Get changed files since fork point - uses: tj-actions/changed-files@v34.0.0 + uses: tj-actions/changed-files@v41.0.0 if: github.event.inputs.base_ref != '' id: changed-files-base with: @@ -125,7 +125,7 @@ jobs: dev/docker_data/required_afni_pkgs.txt .github/Dockerfiles/* - name: Get changed files since last commit - uses: tj-actions/changed-files@v34.0.0 + uses: tj-actions/changed-files@v41.0.0 if: github.event.inputs.base_ref == '' id: changed-files with: @@ -214,7 +214,7 @@ jobs: echo '.github/workflows/build_stages.yml' >> .github/stage_requirements/${{ matrix.variant }}.txt echo '.github/stage_requirements/${{ matrix.variant }}.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt - name: Get changed files since fork point - uses: tj-actions/changed-files@v34.0.0 + uses: tj-actions/changed-files@v41.0.0 if: github.event.inputs.base_ref != '' id: changed-files-base with: @@ -222,7 +222,7 @@ jobs: files_from_source_file: | .github/stage_requirements/${{ matrix.variant }}.txt - name: Get changed files since last commit - uses: tj-actions/changed-files@v34.0.0 + uses: tj-actions/changed-files@v41.0.0 if: github.event.inputs.base_ref == '' id: changed-files with: From c99738e7218ba4790a508517b9e3db42e26ee0a3 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 2 Jan 2024 13:23:35 -0500 Subject: [PATCH 083/213] =?UTF-8?q?:arrow=5Fup:=20Bump=20`tj-actions/chang?= =?UTF-8?q?ed-files`=20v35.7.6=20=E2=86=92=20v41.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/on_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index c4a5ceacd4..1a957dc6b7 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -105,7 +105,7 @@ jobs: git push origin HEAD:${GITHUB_BRANCH} || true fi - name: Get changed files since last commit - uses: tj-actions/changed-files@v35.7.6 + uses: tj-actions/changed-files@v41.0.0 id: changed-files with: since_last_remote_commit: "true" From 94d08331aa39167421e02170e72054e1addb2d6d Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 19 Apr 2023 19:42:26 +0000 Subject: [PATCH 084/213] added fsl robustfov before fsl BET in anat_preproc.py --- CPAC/anat_preproc/anat_preproc.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 1dcb5b8323..efceba15aa 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -608,6 +608,10 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'vertical_gradient']), name=f'BET_options_{pipe_num}') + anat_robustfov = pe.Node( + interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + anat_robustfov.inputs.output_type = 'NIFTI_GZ' + anat_skullstrip = pe.Node( interface=fsl.BET(), name=f'anat_BET_skullstrip_{pipe_num}') anat_skullstrip.inputs.output_type = 'NIFTI_GZ' @@ -646,13 +650,15 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, anat_skullstrip, 'in_file') + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - wf.connect(node, out, anat_skullstrip, 'in_file') + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ From c1e7f1c4f4800a7be76fbd7883866fed09521b50 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 19 Apr 2023 20:47:25 +0000 Subject: [PATCH 085/213] using out_roi to connect anat_robustfov node to the node anat_skullstrip --- CPAC/anat_preproc/anat_preproc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index efceba15aa..eca0567aff 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -653,12 +653,12 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ From ddf3b106b4b2281662c48e2e0e37d9a8821cb868 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 24 Apr 2023 17:32:34 +0000 Subject: [PATCH 086/213] modified anat_preproc.py --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index eca0567aff..9d7e828eca 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -650,7 +650,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') From 516312b8009e3f8b0ed141d1cdcbd9c28f536de9 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 1 May 2023 14:37:34 +0000 Subject: [PATCH 087/213] Created an option key for robustfov that can be turned On/Off by the user in the config --- CPAC/anat_preproc/anat_preproc.py | 14 ++++++++++---- CPAC/pipeline/schema.py | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 9d7e828eca..59321488b3 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -652,13 +652,19 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + else : + wf.connect(node, out, anat_skullstrip, 'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + else : + wf.connect(node, out, anat_skullstrip, 'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 5b037de003..2f41bd75fc 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -524,6 +524,7 @@ def sanitize(filename): }, 'FSL-BET': { 'frac': Number, + 'Robustfov': bool1_1, 'mask_boolean': bool1_1, 'mesh_boolean': bool1_1, 'outline': bool1_1, From be9752abe6a9ae6ccea7ced7c1dbc6c9206ff60b Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 8 May 2023 15:25:49 +0000 Subject: [PATCH 088/213] added robustfov as an option is pipe config --- CPAC/anat_preproc/anat_preproc.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 59321488b3..d57f392d15 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -608,9 +608,6 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'vertical_gradient']), name=f'BET_options_{pipe_num}') - anat_robustfov = pe.Node( - interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') - anat_robustfov.inputs.output_type = 'NIFTI_GZ' anat_skullstrip = pe.Node( interface=fsl.BET(), name=f'anat_BET_skullstrip_{pipe_num}') @@ -649,10 +646,15 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['vertical_gradient'], ) + + anat_robustfov = pe.Node( + interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + anat_robustfov.inputs.output_type = 'NIFTI_GZ' if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') else : @@ -660,7 +662,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') else : From ede7dd3d0ed9ff35b50d77d0997d153733839c77 Mon Sep 17 00:00:00 2001 From: Teresa George Date: Fri, 19 May 2023 15:29:50 -0400 Subject: [PATCH 089/213] Added the changes to the config files --- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index d99ff4ef53..0d77209f18 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,7 +342,7 @@ anatomical_preproc: monkey: Off FSL-BET: - + Robustfov : On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 0ad367a48b..276277b92e 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,7 +409,7 @@ anatomical_preproc: monkey: False FSL-BET: - + Robustfov : On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From fd92f25f6e36df71b8f9b2c7b308eb14207192a7 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Mon, 22 May 2023 15:27:11 +0000 Subject: [PATCH 090/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_blank.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 0d77209f18..1c5f43291e 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,7 +342,8 @@ anatomical_preproc: monkey: Off FSL-BET: - Robustfov : On + Robustfov: On + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From 1273e1d31e8f16bcdb5f4e7450f87c38194fc276 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 19 Apr 2023 19:42:26 +0000 Subject: [PATCH 091/213] added fsl robustfov before fsl BET in anat_preproc.py --- CPAC/anat_preproc/anat_preproc.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 1dcb5b8323..efceba15aa 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -608,6 +608,10 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'vertical_gradient']), name=f'BET_options_{pipe_num}') + anat_robustfov = pe.Node( + interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + anat_robustfov.inputs.output_type = 'NIFTI_GZ' + anat_skullstrip = pe.Node( interface=fsl.BET(), name=f'anat_BET_skullstrip_{pipe_num}') anat_skullstrip.inputs.output_type = 'NIFTI_GZ' @@ -646,13 +650,15 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, anat_skullstrip, 'in_file') + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - wf.connect(node, out, anat_skullstrip, 'in_file') + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ From 54cc0b427b6b92fd00258c56f0c4194580d0c03b Mon Sep 17 00:00:00 2001 From: tergeorge Date: Wed, 19 Apr 2023 20:47:25 +0000 Subject: [PATCH 092/213] using out_roi to connect anat_robustfov node to the node anat_skullstrip --- CPAC/anat_preproc/anat_preproc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index efceba15aa..eca0567aff 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -653,12 +653,12 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_file', anat_skullstrip,'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ From fe468177b227e67c1721935e671b2e1d49c9c1bf Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 24 Apr 2023 17:32:34 +0000 Subject: [PATCH 093/213] modified anat_preproc.py --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index eca0567aff..9d7e828eca 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -650,7 +650,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - if strat_pool.check_rpool('desc-preproc_T1w'): + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') From f4ab3c0710bdfb5478fbff4e0e136aab01fb2109 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 1 May 2023 14:37:34 +0000 Subject: [PATCH 094/213] Created an option key for robustfov that can be turned On/Off by the user in the config --- CPAC/anat_preproc/anat_preproc.py | 14 ++++++++++---- CPAC/pipeline/schema.py | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 9d7e828eca..59321488b3 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -652,13 +652,19 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + else : + wf.connect(node, out, anat_skullstrip, 'in_file') elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + wf.connect(node, out, anat_robustfov, 'in_file') + wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + else : + wf.connect(node, out, anat_skullstrip, 'in_file') wf.connect([ (inputnode_bet, anat_skullstrip, [ diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 5b037de003..2f41bd75fc 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -524,6 +524,7 @@ def sanitize(filename): }, 'FSL-BET': { 'frac': Number, + 'Robustfov': bool1_1, 'mask_boolean': bool1_1, 'mesh_boolean': bool1_1, 'outline': bool1_1, From efe5ca8b1f79b62b6c39068da3dd93ce2a794961 Mon Sep 17 00:00:00 2001 From: tergeorge Date: Mon, 8 May 2023 15:25:49 +0000 Subject: [PATCH 095/213] added robustfov as an option is pipe config --- CPAC/anat_preproc/anat_preproc.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 59321488b3..d57f392d15 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -608,9 +608,6 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'vertical_gradient']), name=f'BET_options_{pipe_num}') - anat_robustfov = pe.Node( - interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') - anat_robustfov.inputs.output_type = 'NIFTI_GZ' anat_skullstrip = pe.Node( interface=fsl.BET(), name=f'anat_BET_skullstrip_{pipe_num}') @@ -649,10 +646,15 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['vertical_gradient'], ) + + anat_robustfov = pe.Node( + interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + anat_robustfov.inputs.output_type = 'NIFTI_GZ' if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') else : @@ -660,7 +662,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): elif strat_pool.check_rpool('desc-preproc_T2w'): node, out = strat_pool.get_data('desc-preproc_T2w') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov'] == 'True': + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') else : From 7e1cf58241453f5dd41a7e495254d26631bd340c Mon Sep 17 00:00:00 2001 From: Teresa George Date: Fri, 19 May 2023 15:29:50 -0400 Subject: [PATCH 096/213] Added the changes to the config files --- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index d99ff4ef53..0d77209f18 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,7 +342,7 @@ anatomical_preproc: monkey: Off FSL-BET: - + Robustfov : On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 0ad367a48b..276277b92e 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,7 +409,7 @@ anatomical_preproc: monkey: False FSL-BET: - + Robustfov : On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From a098e77f4abef723e8351021695d3ef0c9333640 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Mon, 22 May 2023 15:27:11 +0000 Subject: [PATCH 097/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_blank.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 0d77209f18..1c5f43291e 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,7 +342,8 @@ anatomical_preproc: monkey: Off FSL-BET: - Robustfov : On + Robustfov: On + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From 1f43ffa65fdce2a1490adbd648ceae142515c3d5 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Wed, 22 Nov 2023 11:12:28 -0500 Subject: [PATCH 098/213] dvars output added in cpac_outputs.tsv --- CPAC/resources/cpac_outputs.tsv | 1 + 1 file changed, 1 insertion(+) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 03ddd5de73..e85de5fbe1 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -100,6 +100,7 @@ space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI motion motion func TSV desc-summary_motion motion func TSV +dvars motion func TSV Yes motion-filter-plot motion func png desc-movementParameters_motion motion func TSV desc-movementParametersUnfiltered_motion motion func TSV From b28ea3fcea38fc954305c2564f9571517ee34158 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Tue, 19 Dec 2023 21:24:19 +0000 Subject: [PATCH 099/213] padding to robustfov cropped image added --- CPAC/anat_preproc/anat_preproc.py | 30 ++++++++++++++++++++++++++---- CPAC/anat_preproc/utils.py | 9 +++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index d57f392d15..3adaeb963a 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -33,7 +33,8 @@ wb_command, \ fslmaths_command, \ VolumeRemoveIslands, \ - normalize_wmparc + normalize_wmparc, \ + pad, get_shape from CPAC.utils.interfaces.fsl import Merge as fslMerge @@ -647,16 +648,34 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) + anat_nifti_shape= pe.Node(util.Function(input_names=['nifti_image'], + output_names=['shape'], + function=get_shape), + name=f'anat_nifti_shape_{pipe_num}' + ) + anat_robustfov = pe.Node( interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') + #anat_robustfov.brainsize = '%d' anat_robustfov.inputs.output_type = 'NIFTI_GZ' + pad_mask = pe.Node(util.Function(input_names=['cropped_image', 'target_shape'], + output_names=['padded_mask'], + function=pad), + name=f'pad_mask_{pipe_num}' + ) + if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') + wf.connect(anat_nifti_shape, 'dim3', anat_robustfov, 'brainsize') + if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + wf.connect(node, out, anat_nifti_shape, 'nifti_image') + wf.connect(anat_robustfov, 'out_roi', pad_mask, 'cropped_image') + wf.connect(anat_nifti_shape,'shape', pad_mask, 'target_shape') + wf.connect(pad_mask, 'padded_image', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') @@ -664,10 +683,13 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('desc-preproc_T2w') if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(anat_robustfov, 'out_roi', anat_skullstrip,'in_file') + wf.connect(node, out, anat_nifti_shape, 'nifti_image') + wf.connect(anat_robustfov, 'out_roi', pad_mask, 'cropped_image') + wf.connect(anat_nifti_shape,'shape', pad_mask, 'target_shape') + wf.connect(pad_mask, 'padded_image', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') - + wf.connect([ (inputnode_bet, anat_skullstrip, [ ('frac', 'frac'), diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index 1ec23337f2..fe022ab8c3 100644 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -2,7 +2,16 @@ import nipype.interfaces.utility as util from CPAC.pipeline import nipype_pipeline_engine as pe +from nibabel import load as nib_load, Nifti1Image +from numpy import zeros +def get_shape(nifti_image): + return nib_load(nifti_image).shape + +def pad(cropped_image, target_shape): + padded_image = zeros(target_shape) + padded_image[:, :, :cropped_image.shape[2]] = cropped_image.get_data() + return Nifti1Image(padded_image, affine=cropped_image.affine) def fsl_aff_to_rigid(in_xfm, out_name): From ae4c60a0b1a1e5c0fab62b8634b46bf76ed3757e Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Thu, 28 Dec 2023 19:09:38 +0000 Subject: [PATCH 100/213] Dynamic padding function added --- CPAC/anat_preproc/anat_preproc.py | 34 ++++++++++------------------- CPAC/anat_preproc/utils.py | 36 ++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 3adaeb963a..3f87c80f6e 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -34,7 +34,7 @@ fslmaths_command, \ VolumeRemoveIslands, \ normalize_wmparc, \ - pad, get_shape + pad from CPAC.utils.interfaces.fsl import Merge as fslMerge @@ -648,34 +648,24 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): 'FSL-BET']['vertical_gradient'], ) - anat_nifti_shape= pe.Node(util.Function(input_names=['nifti_image'], - output_names=['shape'], - function=get_shape), - name=f'anat_nifti_shape_{pipe_num}' - ) - anat_robustfov = pe.Node( interface=fsl.RobustFOV(), name=f'anat_RobustFOV_{pipe_num}') - #anat_robustfov.brainsize = '%d' + anat_robustfov.inputs.output_type = 'NIFTI_GZ' - pad_mask = pe.Node(util.Function(input_names=['cropped_image', 'target_shape'], - output_names=['padded_mask'], + anat_pad_mask = pe.Node(util.Function(input_names=['cropped_image_path', 'target_image_path'], + output_names=['padded_image_path'], function=pad), - name=f'pad_mask_{pipe_num}' + name=f'anat_pad_mask_{pipe_num}' ) if strat_pool.check_rpool('desc-preproc_T1w'): node, out = strat_pool.get_data('desc-preproc_T1w') - - wf.connect(anat_nifti_shape, 'dim3', anat_robustfov, 'brainsize') - if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(node, out, anat_nifti_shape, 'nifti_image') - wf.connect(anat_robustfov, 'out_roi', pad_mask, 'cropped_image') - wf.connect(anat_nifti_shape,'shape', pad_mask, 'target_shape') - wf.connect(pad_mask, 'padded_image', anat_skullstrip,'in_file') + wf.connect(node, out, anat_pad_mask, 'target_image_path') + wf.connect(anat_robustfov, 'out_roi', anat_pad_mask, 'cropped_image_path') + wf.connect(anat_pad_mask, 'padded_image_path', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') @@ -683,10 +673,9 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('desc-preproc_T2w') if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(node, out, anat_nifti_shape, 'nifti_image') - wf.connect(anat_robustfov, 'out_roi', pad_mask, 'cropped_image') - wf.connect(anat_nifti_shape,'shape', pad_mask, 'target_shape') - wf.connect(pad_mask, 'padded_image', anat_skullstrip,'in_file') + wf.connect(node, out, anat_pad_mask, 'target_image_path') + wf.connect(anat_robustfov, 'out_roi', anat_pad_mask, 'cropped_image_path') + wf.connect(anat_pad_mask, 'padded_image_path', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') @@ -717,7 +706,6 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): outputs = { 'space-T2w_desc-brain_mask': (anat_skullstrip, 'mask_file') } - return (wf, outputs) diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index fe022ab8c3..88184d3fd6 100644 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -2,16 +2,36 @@ import nipype.interfaces.utility as util from CPAC.pipeline import nipype_pipeline_engine as pe -from nibabel import load as nib_load, Nifti1Image -from numpy import zeros -def get_shape(nifti_image): - return nib_load(nifti_image).shape +def find_sublist(a, b): + len_a = len(a) + len_b = len(b) -def pad(cropped_image, target_shape): - padded_image = zeros(target_shape) - padded_image[:, :, :cropped_image.shape[2]] = cropped_image.get_data() - return Nifti1Image(padded_image, affine=cropped_image.affine) + for f in range(len_b - len_a + 1): + b[f:f+len_a] + if (b[f:f+len_a] == a).all(): + return f + return None + +def pad(cropped_image_path, target_image_path): + import numpy as np + from nibabel import load, save, Nifti1Image + from os import path, getcwd + + cropped_image = np.asanyarray(load(cropped_image_path).dataobj) + target_image = np.asanyarray(load(target_image_path).dataobj) + + r =20 + c= 20 + f = find_sublist(cropped_image[r, c, :], target_image[r, c, :]) + + padded_image_matrix = np.zeros_like(target_image) + print(padded_image_matrix.shape) + cropped_image = load(cropped_image_path) + padded_image_matrix[:, :, f:cropped_image.shape[2]+f] = cropped_image + padded_image_path = path.join(getcwd(),"padded_image_T1w.nii.gz") + save(Nifti1Image(padded_image_matrix, affine=cropped_image.affine), padded_image_path) + return padded_image_path def fsl_aff_to_rigid(in_xfm, out_name): From 0a8e61f51b05cbb9604178501d219b21cff85bf4 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Fri, 29 Dec 2023 17:06:08 +0000 Subject: [PATCH 101/213] Dynamic padding edited --- CPAC/anat_preproc/utils.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index 88184d3fd6..4788e349ab 100644 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -3,16 +3,6 @@ from CPAC.pipeline import nipype_pipeline_engine as pe -def find_sublist(a, b): - len_a = len(a) - len_b = len(b) - - for f in range(len_b - len_a + 1): - b[f:f+len_a] - if (b[f:f+len_a] == a).all(): - return f - return None - def pad(cropped_image_path, target_image_path): import numpy as np from nibabel import load, save, Nifti1Image @@ -23,13 +13,21 @@ def pad(cropped_image_path, target_image_path): r =20 c= 20 - f = find_sublist(cropped_image[r, c, :], target_image[r, c, :]) + a = cropped_image[r, c, :] + b = target_image[r, c, :] + len_a = len(a) + len_b = len(b) + + for f in range(len_b - len_a + 1): + b[f:f+len_a] + if (b[f:f+len_a] == a).all(): + break + print(f) padded_image_matrix = np.zeros_like(target_image) - print(padded_image_matrix.shape) - cropped_image = load(cropped_image_path) padded_image_matrix[:, :, f:cropped_image.shape[2]+f] = cropped_image padded_image_path = path.join(getcwd(),"padded_image_T1w.nii.gz") + cropped_image = load(cropped_image_path) save(Nifti1Image(padded_image_matrix, affine=cropped_image.affine), padded_image_path) return padded_image_path From ef4863874dcba41f65bcf7334d3bdc6e7a362c89 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Sat, 30 Dec 2023 17:33:15 +0000 Subject: [PATCH 102/213] z-dimension shift computation edited --- CPAC/anat_preproc/utils.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index 4788e349ab..be0a3a12ef 100644 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -4,28 +4,25 @@ from CPAC.pipeline import nipype_pipeline_engine as pe def pad(cropped_image_path, target_image_path): - import numpy as np + from numpy import asanyarray, zeros_like from nibabel import load, save, Nifti1Image from os import path, getcwd - cropped_image = np.asanyarray(load(cropped_image_path).dataobj) - target_image = np.asanyarray(load(target_image_path).dataobj) + cropped_image = asanyarray(load(cropped_image_path).dataobj) + target_image = asanyarray(load(target_image_path).dataobj) - r =20 - c= 20 - a = cropped_image[r, c, :] - b = target_image[r, c, :] - len_a = len(a) - len_b = len(b) + # Taking 1 slice to calculate the z dimension shift from top + row =target_image.shape[0]//2 + column= target_image.shape[1]//2 + a = cropped_image[row, column, :] + b = target_image[row, column, :] - for f in range(len_b - len_a + 1): - b[f:f+len_a] - if (b[f:f+len_a] == a).all(): + for z_shift in range(len(b) - len(a) + 1): + if (b[z_shift:z_shift+len(a)] == a).all(): break - print(f) - padded_image_matrix = np.zeros_like(target_image) - padded_image_matrix[:, :, f:cropped_image.shape[2]+f] = cropped_image + padded_image_matrix = zeros_like(target_image) + padded_image_matrix[:, :, z_shift:cropped_image.shape[2]+z_shift] = cropped_image padded_image_path = path.join(getcwd(),"padded_image_T1w.nii.gz") cropped_image = load(cropped_image_path) save(Nifti1Image(padded_image_matrix, affine=cropped_image.affine), padded_image_path) From 1c4bdb4d6e902110f33f79ec15c59ab244619108 Mon Sep 17 00:00:00 2001 From: Biraj Date: Sat, 30 Dec 2023 17:56:31 +0000 Subject: [PATCH 103/213] renamed anat_pad_mask to ..RobustFOV_cropped --- CPAC/anat_preproc/anat_preproc.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 3f87c80f6e..068e1e2203 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -653,7 +653,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): anat_robustfov.inputs.output_type = 'NIFTI_GZ' - anat_pad_mask = pe.Node(util.Function(input_names=['cropped_image_path', 'target_image_path'], + anat_pad_RobustFOV_cropped = pe.Node(util.Function(input_names=['cropped_image_path', 'target_image_path'], output_names=['padded_image_path'], function=pad), name=f'anat_pad_mask_{pipe_num}' @@ -663,9 +663,9 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('desc-preproc_T1w') if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(node, out, anat_pad_mask, 'target_image_path') - wf.connect(anat_robustfov, 'out_roi', anat_pad_mask, 'cropped_image_path') - wf.connect(anat_pad_mask, 'padded_image_path', anat_skullstrip,'in_file') + wf.connect(node, out, anat_pad_RobustFOV_cropped, 'target_image_path') + wf.connect(anat_robustfov, 'out_roi', anat_pad_RobustFOV_cropped, 'cropped_image_path') + wf.connect(anat_pad_RobustFOV_cropped, 'padded_image_path', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') @@ -673,9 +673,9 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): node, out = strat_pool.get_data('desc-preproc_T2w') if cfg.anatomical_preproc['brain_extraction']['FSL-BET']['Robustfov']: wf.connect(node, out, anat_robustfov, 'in_file') - wf.connect(node, out, anat_pad_mask, 'target_image_path') - wf.connect(anat_robustfov, 'out_roi', anat_pad_mask, 'cropped_image_path') - wf.connect(anat_pad_mask, 'padded_image_path', anat_skullstrip,'in_file') + wf.connect(node, out, anat_pad_RobustFOV_cropped, 'target_image_path') + wf.connect(anat_robustfov, 'out_roi', anat_pad_RobustFOV_cropped, 'cropped_image_path') + wf.connect(anat_pad_RobustFOV_cropped, 'padded_image_path', anat_skullstrip,'in_file') else : wf.connect(node, out, anat_skullstrip, 'in_file') From 5791a25a299aa78ed9ce17010913fabaa99e6389 Mon Sep 17 00:00:00 2001 From: Biraj Date: Sat, 30 Dec 2023 18:48:05 +0000 Subject: [PATCH 104/213] added description for RobustFOV in default pipeline config --- CPAC/resources/configs/pipeline_config_default.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 276277b92e..ce4f81d91b 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,7 +409,9 @@ anatomical_preproc: monkey: False FSL-BET: + # Set Robustfov on to crop neck regions before generating the mask for skull stripping. Robustfov : On + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From 317c2315e6498103abdf275f3a99dd5443c47ff6 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Sat, 30 Dec 2023 18:49:07 +0000 Subject: [PATCH 105/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_blank.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 1c5f43291e..3712182a2c 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,6 +342,8 @@ anatomical_preproc: monkey: Off FSL-BET: + + # Set Robustfov on to crop neck regions before generating the mask for skull stripping. Robustfov: On # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 From 0bf389f7b5d6d381090c2be8c0897f68d025ab9e Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Tue, 2 Jan 2024 20:14:38 +0000 Subject: [PATCH 106/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_blank.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 9a7ef41036..3712182a2c 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,6 +342,7 @@ anatomical_preproc: monkey: Off FSL-BET: + # Set Robustfov on to crop neck regions before generating the mask for skull stripping. Robustfov: On From 87296a84b2a87e3264ee5c84aeb3031cfe155389 Mon Sep 17 00:00:00 2001 From: Biraj Date: Wed, 3 Jan 2024 00:48:29 +0000 Subject: [PATCH 107/213] Variables annotated and descriptive in pad function. --- CPAC/anat_preproc/utils.py | 43 +++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py index be0a3a12ef..7ea0b0be9e 100644 --- a/CPAC/anat_preproc/utils.py +++ b/CPAC/anat_preproc/utils.py @@ -4,26 +4,45 @@ from CPAC.pipeline import nipype_pipeline_engine as pe def pad(cropped_image_path, target_image_path): - from numpy import asanyarray, zeros_like + """ + Pad a cropped image to match the dimensions of a target image along the z-axis, + while keeping padded image aligned with target_image. + + Parameters: + - cropped_image_path (str): The file path to the cropped image (NIfTI format). + - target_image_path (str): The file path to the target image (NIfTI format). + + Returns: + - str: The file path to the saved padded image (NIfTI format). + + The function loads cropped and target iamges, calculates the z-dimension shift required for alignment such + that the mask generated from padded image will work correctly on the target image. The result padded image is + saved as an NIfTI file in the working directory/node and file path is returned as output. + + Note: The function assumes that the input images are in NIfTI format and have compatible dimensions. The cropped + and target image should only differ in z-axis dimension. + """ + from numpy import asanyarray, zeros_like, ndarray from nibabel import load, save, Nifti1Image from os import path, getcwd + from typing import Optional - cropped_image = asanyarray(load(cropped_image_path).dataobj) - target_image = asanyarray(load(target_image_path).dataobj) + cropped_image: Optional[ndarray] = asanyarray(load(cropped_image_path).dataobj) + target_image: Optional[ndarray] = asanyarray(load(target_image_path).dataobj) # Taking 1 slice to calculate the z dimension shift from top - row =target_image.shape[0]//2 - column= target_image.shape[1]//2 - a = cropped_image[row, column, :] - b = target_image[row, column, :] + center_row:int =target_image.shape[0]//2 + center_column:int = target_image.shape[1]//2 + z_slice_cropped_image: Optional[ndarray] = cropped_image[center_row, center_column, :] + z_slice_target_image: Optional[ndarray] = target_image[center_row, center_column, :] - for z_shift in range(len(b) - len(a) + 1): - if (b[z_shift:z_shift+len(a)] == a).all(): + for z_shift in range(len(z_slice_target_image) - len(z_slice_cropped_image) + 1): + if (z_slice_target_image[z_shift:z_shift+len(z_slice_cropped_image)] == z_slice_cropped_image).all(): break - - padded_image_matrix = zeros_like(target_image) + + padded_image_matrix: Optional[ndarray] = zeros_like(target_image) padded_image_matrix[:, :, z_shift:cropped_image.shape[2]+z_shift] = cropped_image - padded_image_path = path.join(getcwd(),"padded_image_T1w.nii.gz") + padded_image_path:str = path.join(getcwd(),"padded_image_T1w.nii.gz") cropped_image = load(cropped_image_path) save(Nifti1Image(padded_image_matrix, affine=cropped_image.affine), padded_image_path) return padded_image_path From 4d88fbd16d7b9503521957be41c718c0cddbb876 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 4 Jan 2024 15:23:19 -0500 Subject: [PATCH 108/213] Switched blocks 3 & 4 during renaming --- CPAC/surface/PostFreeSurfer/block3.sh | 233 +++++++++++--------------- CPAC/surface/PostFreeSurfer/block4.sh | 231 ++++++++++++++----------- 2 files changed, 232 insertions(+), 232 deletions(-) mode change 100644 => 100755 CPAC/surface/PostFreeSurfer/block3.sh mode change 100755 => 100644 CPAC/surface/PostFreeSurfer/block4.sh diff --git a/CPAC/surface/PostFreeSurfer/block3.sh b/CPAC/surface/PostFreeSurfer/block3.sh old mode 100644 new mode 100755 index ad52f61cb4..6f7635b9b8 --- a/CPAC/surface/PostFreeSurfer/block3.sh +++ b/CPAC/surface/PostFreeSurfer/block3.sh @@ -1,4 +1,4 @@ - #!/bin/bash +#!/bin/bash #!/bin/bash @@ -126,151 +126,116 @@ for Hemisphere in L R ; do hemisphere="r" Structure="CORTEX_RIGHT" fi - - #If desired, run MSMSulc folding-based registration to FS_LR initialized with FS affine - if [ ${RegName} = "MSMSulc" ] ; then - #Calculate Affine Transform and Apply - if [ ! -e "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc ] ; then - mkdir "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc - fi - wb_command -surface-affine-regression "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat - wb_command -surface-apply-affine "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii - wb_command -surface-modify-sphere "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii 100 "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii - cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii - DIR=$(pwd) - cd "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc - #Register using FreeSurfer Sulc Folding Map Using MSM Algorithm Configured for Reduced Distortion - #msm --version - #msm --levels=4 --conf=${MSMCONFIGDIR}/allparameterssulcDRconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --trans="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose - # Note: the config is mordified according to acceptable args of msm version in container - XL - msm --conf=${MSMCONFIGDIR}/MSMSulcStrainFinalconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose - cp ${MSMCONFIGDIR}/MSMSulcStrainFinalconf "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.logdir/conf - cd $DIR - #cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.HIGHRES_transformed.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii - cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere.reg.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii ${Structure} - - #Make MSMSulc Registration Areal Distortion Maps - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii - wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_MSMSulc - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 - - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii -edge-method - - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -local-affine-method - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 1 - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 2 - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii - - RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii" - else - RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii" - fi - #Ensure no zeros in atlas medial wall ROI - wb_command -metric-resample "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ${RegSphere} BARYCENTRIC "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -largest - wb_command -metric-math "(atlas + individual) > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var atlas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -var individual "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii + #native Mesh Processing + #Convert and volumetrically register white and pial surfaces making linear and nonlinear copies, add each to the appropriate spec file + Types="ANATOMICAL@GRAY_WHITE ANATOMICAL@PIAL" + i=1 + for Surface in white pial ; do + Type=$(echo "$Types" | cut -d " " -f $i) + Secondary=$(echo "$Type" | cut -d "@" -f 2) + Type=$(echo "$Type" | cut -d "@" -f 1) + if [ ! $Secondary = $Type ] ; then + Secondary=$(echo " -surface-secondary-type ""$Secondary") + else + Secondary="" + fi + mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -set-structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type $Type$Secondary + wb_command -surface-apply-affine "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$FreeSurferFolder"/mri/c_ras.mat "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -surface-apply-warpfield "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$InverseAtlasTransform".nii.gz "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii -fnirt "$AtlasTransform".nii.gz + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + i=$(( i+1 )) + done - #Populate Highres fs_LR spec file. Deform surfaces and other data according to native to folding-based registration selected above. Regenerate inflated surfaces. - for Surface in white midthickness pial ; do - wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii - done + #Create midthickness by averaging white and pial surfaces and use it to make inflated surfacess + for Folder in "$T1wFolder" "$AtlasSpaceFolder" ; do + wb_command -surface-average "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".white.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".pial.native.surf.gii + wb_command -set-structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii ${Structure} -surface-type ANATOMICAL -surface-secondary-type MIDTHICKNESS + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii - #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for high res mesh density - HighResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $HighResMesh / 32" | bc -l) + #get number of vertices from native file + NativeVerts=$(wb_command -file-information "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii | grep 'Number of Vertices:' | cut -f2 -d: | tr -d '[:space:]') - wb_command -surface-generate-inflated "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii -iterations-scale $HighResInflationScale - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii + #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for native mesh density + NativeInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $NativeVerts / 32492" | bc -l) - for Map in thickness curvature ; do - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii + wb_command -surface-generate-inflated "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii -iterations-scale $NativeInflationScale + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii + wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii done - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - if [ ${RegName} = "MSMSulc" ] ; then - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii - fi - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + #Convert original and registered spherical surfaces and add them to the nonlinear spec file + for Surface in sphere.reg sphere ; do + mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type SPHERICAL + done + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii + + #Add more files to the spec file and convert other FreeSurfer surface data to metric/GIFTI including sulc, curv, and thickness. + for Map in sulc@sulc@Sulc thickness@thickness@Thickness curv@curvature@Curvature ; do + fsname=$(echo $Map | cut -d "@" -f 1) + wbname=$(echo $Map | cut -d "@" -f 2) + mapname=$(echo $Map | cut -d "@" -f 3) + mris_convert -c "$FreeSurferFolder"/surf/"$hemisphere"h."$fsname" "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii ${Structure} + wb_command -metric-math "var * -1" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -map 1 "$Subject"_"$Hemisphere"_"$mapname" + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + done + #Thickness specific operations + wb_command -metric-math "abs(thickness)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false + wb_command -metric-math "thickness > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-fill-holes "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-remove-islands "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_ROI + wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -nearest + wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii -nearest + + #Label operations for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then - wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.label.gii -largest + mris_convert --annot "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii $Structure + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii -map 1 "$Subject"_"$Hemisphere"_"$Map" + wb_command -gifti-label-add-prefix "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii "${Hemisphere}_" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii fi done + #End main native mesh processing + + #Copy Atlas Files + cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fsaverage."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii + cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fs_"$Hemisphere"-to-fs_LR_fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii + cp "$SurfaceAtlasDIR"/fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii + cp "$SurfaceAtlasDIR"/"$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii + cp "$SurfaceAtlasDIR"/"$Hemisphere".refsulc."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii + if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii ] ; then + cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii + fi - for LowResMesh in ${LowResMeshes} ; do - #Copy Atlas Files - cp "$SurfaceAtlasDIR"/"$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii - cp "$GrayordinatesSpaceDIR"/"$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii - if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii ] ; then - cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii - fi + #Concatenate FS registration to FS --> FS_LR registration + wb_command -surface-sphere-project-unproject "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.native.surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii - #Create downsampled fs_LR spec files. - for Surface in white midthickness pial ; do - wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - done - - #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh - LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) - - wb_command -surface-generate-inflated "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii - - for Map in sulc thickness curvature ; do - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-mask "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii - done - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - if [ ${RegName} = "MSMSulc" ] ; then - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - fi - wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii - - for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly - if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then - wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.label.gii -largest - fi - done - - #Create downsampled fs_LR spec file in structural space. - for Surface in white midthickness pial ; do - wb_command -surface-resample "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii - done - - #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh - LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) - - wb_command -surface-generate-inflated "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" - wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii - done -done + #Make FreeSurfer Registration Areal Distortion Maps + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_FS + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii -edge-method + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -local-affine-method + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 1 + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 2 + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii +done \ No newline at end of file diff --git a/CPAC/surface/PostFreeSurfer/block4.sh b/CPAC/surface/PostFreeSurfer/block4.sh old mode 100755 new mode 100644 index d340d49351..9ad88c8620 --- a/CPAC/surface/PostFreeSurfer/block4.sh +++ b/CPAC/surface/PostFreeSurfer/block4.sh @@ -127,116 +127,151 @@ for Hemisphere in L R ; do hemisphere="r" Structure="CORTEX_RIGHT" fi - - #native Mesh Processing - #Convert and volumetrically register white and pial surfaces making linear and nonlinear copies, add each to the appropriate spec file - Types="ANATOMICAL@GRAY_WHITE ANATOMICAL@PIAL" - i=1 - for Surface in white pial ; do - Type=$(echo "$Types" | cut -d " " -f $i) - Secondary=$(echo "$Type" | cut -d "@" -f 2) - Type=$(echo "$Type" | cut -d "@" -f 1) - if [ ! $Secondary = $Type ] ; then - Secondary=$(echo " -surface-secondary-type ""$Secondary") - else - Secondary="" + + #If desired, run MSMSulc folding-based registration to FS_LR initialized with FS affine + if [ ${RegName} = "MSMSulc" ] ; then + #Calculate Affine Transform and Apply + if [ ! -e "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc ] ; then + mkdir "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc fi - mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -set-structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type $Type$Secondary - wb_command -surface-apply-affine "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$FreeSurferFolder"/mri/c_ras.mat "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -add-to-spec-file "$T1wFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -surface-apply-warpfield "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii "$InverseAtlasTransform".nii.gz "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii -fnirt "$AtlasTransform".nii.gz - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - i=$(( i+1 )) - done + wb_command -surface-affine-regression "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat + wb_command -surface-apply-affine "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.mat "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii + wb_command -surface-modify-sphere "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii 100 "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii + cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere_rot.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii + DIR=$(pwd) + cd "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc + #Register using FreeSurfer Sulc Folding Map Using MSM Algorithm Configured for Reduced Distortion + #msm --version + #msm --levels=4 --conf=${MSMCONFIGDIR}/allparameterssulcDRconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --trans="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose + # Note: the config is mordified according to acceptable args of msm version in container - XL + msm --conf=${MSMCONFIGDIR}/MSMSulcStrainFinalconf --inmesh="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.rot.native.surf.gii --refmesh="$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii --indata="$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sulc.native.shape.gii --refdata="$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii --out="$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}. --verbose + cp ${MSMCONFIGDIR}/MSMSulcStrainFinalconf "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.logdir/conf + cd $DIR + #cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.HIGHRES_transformed.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii + cp "$AtlasSpaceFolder"/"$NativeFolder"/MSMSulc/${Hemisphere}.sphere.reg.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii + wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii ${Structure} + + #Make MSMSulc Registration Areal Distortion Maps + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii + wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/${Subject}.${Hemisphere}.sphere.MSMSulc.native.shape.gii + wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_MSMSulc + wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii -edge-method + + wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.MSMSulc.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -local-affine-method + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 1 + wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii -column 2 + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii + wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii + rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_MSMSulc.native.shape.gii + + RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.MSMSulc.native.surf.gii" + else + RegSphere="${AtlasSpaceFolder}/${NativeFolder}/${Subject}.${Hemisphere}.sphere.reg.reg_LR.native.surf.gii" + fi + #Ensure no zeros in atlas medial wall ROI + wb_command -metric-resample "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ${RegSphere} BARYCENTRIC "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -largest + wb_command -metric-math "(atlas + individual) > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var atlas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".atlasroi.native.shape.gii -var individual "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii - #Create midthickness by averaging white and pial surfaces and use it to make inflated surfacess - for Folder in "$T1wFolder" "$AtlasSpaceFolder" ; do - wb_command -surface-average "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".white.native.surf.gii -surf "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".pial.native.surf.gii - wb_command -set-structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii ${Structure} -surface-type ANATOMICAL -surface-secondary-type MIDTHICKNESS - wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii - #get number of vertices from native file - NativeVerts=$(wb_command -file-information "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii | grep 'Number of Vertices:' | cut -f2 -d: | tr -d '[:space:]') + #Populate Highres fs_LR spec file. Deform surfaces and other data according to native to folding-based registration selected above. Regenerate inflated surfaces. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Surface"."$HighResMesh"k_fs_LR.surf.gii + done - #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for native mesh density - NativeInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $NativeVerts / 32492" | bc -l) + #HCP fsaverage_LR32k used -iterations-scale 0.75. Compute new param value for high res mesh density + HighResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $HighResMesh / 32" | bc -l) - wb_command -surface-generate-inflated "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii -iterations-scale $NativeInflationScale - wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".inflated.native.surf.gii - wb_command -add-to-spec-file "$Folder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$Folder"/"$NativeFolder"/"$Subject"."$Hemisphere".very_inflated.native.surf.gii - done + wb_command -surface-generate-inflated "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii -iterations-scale $HighResInflationScale + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".inflated."$HighResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".very_inflated."$HighResMesh"k_fs_LR.surf.gii - #Convert original and registered spherical surfaces and add them to the nonlinear spec file - for Surface in sphere.reg sphere ; do - mris_convert "$FreeSurferFolder"/surf/"$hemisphere"h."$Surface" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${Structure} -surface-type SPHERICAL - done - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject".native.wb.spec $Structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii - - #Add more files to the spec file and convert other FreeSurfer surface data to metric/GIFTI including sulc, curv, and thickness. - for Map in sulc@sulc@Sulc thickness@thickness@Thickness curv@curvature@Curvature ; do - fsname=$(echo $Map | cut -d "@" -f 1) - wbname=$(echo $Map | cut -d "@" -f 2) - mapname=$(echo $Map | cut -d "@" -f 3) - mris_convert -c "$FreeSurferFolder"/surf/"$hemisphere"h."$fsname" "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii ${Structure} - wb_command -metric-math "var * -1" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii -map 1 "$Subject"_"$Hemisphere"_"$mapname" - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$wbname".native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 2 98 -palette-name Gray_Interp -disp-pos true -disp-neg true -disp-zero true + for Map in thickness curvature ; do + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.shape.gii done - #Thickness specific operations - wb_command -metric-math "abs(thickness)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii MODE_AUTO_SCALE_PERCENTAGE -pos-percent 4 96 -interpolate true -palette-name videen_style -disp-pos true -disp-neg false -disp-zero false - wb_command -metric-math "thickness > 0" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -var thickness "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii - wb_command -metric-fill-holes "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -metric-remove-islands "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_ROI - wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".thickness.native.shape.gii -nearest - wb_command -metric-dilate "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii 10 "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".curvature.native.shape.gii -nearest - - #Label operations + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_FS."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + fi + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sulc."$HighResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".midthickness."$HighResMesh"k_fs_LR.surf.gii + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then - mris_convert --annot "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot "$FreeSurferFolder"/surf/"$hemisphere"h.white "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii - wb_command -set-structure "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii $Structure - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii -map 1 "$Subject"_"$Hemisphere"_"$Map" - wb_command -gifti-label-add-prefix "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii "${Hemisphere}_" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii + wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/"$Subject"."$Hemisphere"."$Map"."$HighResMesh"k_fs_LR.label.gii -largest fi done - #End main native mesh processing - - #Copy Atlas Files - cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fsaverage."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii - cp "$SurfaceAtlasDIR"/fs_"$Hemisphere"/fs_"$Hemisphere"-to-fs_LR_fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii - cp "$SurfaceAtlasDIR"/fsaverage."$Hemisphere"_LR.spherical_std."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_LR.surf.gii - cp "$SurfaceAtlasDIR"/"$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".atlasroi."$HighResMesh"k_fs_LR.shape.gii - cp "$SurfaceAtlasDIR"/"$Hemisphere".refsulc."$HighResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/${Subject}.${Hemisphere}.refsulc."$HighResMesh"k_fs_LR.shape.gii - if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii ] ; then - cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii - wb_command -add-to-spec-file "$AtlasSpaceFolder"/"$Subject"."$HighResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/"$Subject"."$Hemisphere".flat."$HighResMesh"k_fs_LR.surf.gii - fi - - #Concatenate FS registration to FS --> FS_LR registration - wb_command -surface-sphere-project-unproject "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.native.surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/fsaverage/"$Subject"."$Hemisphere".def_sphere."$HighResMesh"k_fs_"$Hemisphere".surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii - - #Make FreeSurfer Registration Areal Distortion Maps - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii - wb_command -surface-vertex-areas "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii - wb_command -metric-math "ln(spherereg / sphere) / ln(2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -var sphere "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii -var spherereg "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.shape.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.shape.gii - wb_command -set-map-names "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii -map 1 "$Subject"_"$Hemisphere"_Areal_Distortion_FS - wb_command -metric-palette "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii MODE_AUTO_SCALE -palette-name ROY-BIG-BL -thresholding THRESHOLD_TYPE_NORMAL THRESHOLD_TEST_SHOW_OUTSIDE -1 1 - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii -edge-method + for LowResMesh in ${LowResMeshes} ; do + #Copy Atlas Files + cp "$SurfaceAtlasDIR"/"$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii + cp "$GrayordinatesSpaceDIR"/"$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii + if [ -e "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii ] ; then + cp "$SurfaceAtlasDIR"/colin.cerebral."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".flat."$LowResMesh"k_fs_LR.surf.gii + fi - wb_command -surface-distortion "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sphere.reg.reg_LR.native.surf.gii "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -local-affine-method - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 1 - wb_command -metric-merge "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -metric "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii -column 2 - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii - wb_command -metric-math "ln(var) / ln (2)" "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii -var var "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii - rm "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".Strain_FS.native.shape.gii + #Create downsampled fs_LR spec files. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh + LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii + + for Map in sulc thickness curvature ; do + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii -current-roi "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".roi.native.shape.gii + wb_command -metric-mask "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".atlasroi."$LowResMesh"k_fs_LR.shape.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.shape.gii + done + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_FS.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_FS."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + if [ ${RegName} = "MSMSulc" ] ; then + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".ArealDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".EdgeDistortion_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainJ_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainJ_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".StrainR_MSMSulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".StrainR_MSMSulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + fi + wb_command -metric-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".sulc.native.shape.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii ADAP_BARY_AREA "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sulc."$LowResMesh"k_fs_LR.shape.gii -area-surfs "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere".midthickness.native.surf.gii "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii + + for Map in aparc aparc.a2009s ; do #Remove BA because it doesn't convert properly + if [ -e "$FreeSurferFolder"/label/"$hemisphere"h."$Map".annot ] ; then + wb_command -label-resample "$AtlasSpaceFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Map".native.label.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Map"."$LowResMesh"k_fs_LR.label.gii -largest + fi + done + + #Create downsampled fs_LR spec file in structural space. + for Surface in white midthickness pial ; do + wb_command -surface-resample "$T1wFolder"/"$NativeFolder"/"$Subject"."$Hemisphere"."$Surface".native.surf.gii ${RegSphere} "$AtlasSpaceFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".sphere."$LowResMesh"k_fs_LR.surf.gii BARYCENTRIC "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere"."$Surface"."$LowResMesh"k_fs_LR.surf.gii + done + + #HCP fsaverage_LR32k used -iterations-scale 0.75. Recalculate in case using a different mesh + LowResInflationScale=$(echo "scale=4; $InflateExtraScale * 0.75 * $LowResMesh / 32" | bc -l) + + wb_command -surface-generate-inflated "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".midthickness."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii -iterations-scale "$LowResInflationScale" + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".inflated."$LowResMesh"k_fs_LR.surf.gii + wb_command -add-to-spec-file "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$LowResMesh"k_fs_LR.wb.spec $Structure "$T1wFolder"/fsaverage_LR"$LowResMesh"k/"$Subject"."$Hemisphere".very_inflated."$LowResMesh"k_fs_LR.surf.gii + done +done -done \ No newline at end of file From 4020a4fe40727b9f437fe2f39fbaae4ba3a183bf Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 4 Jan 2024 15:24:58 -0500 Subject: [PATCH 109/213] Switched ciftify to local fork to test bugfix --- CPAC/info.py | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 5bc8b8153f..d4c470dfb7 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -170,7 +170,7 @@ def get_cpac_gitversion(): STATUS = 'stable' REQUIREMENTS = [ "boto3", - "ciftify", + "ciftify @ git+https://git@github.com/e-kenneally/ciftify.git@bugfix/remove_giftiio#egg=ciftify", "click", "click-aliases", "configparser", diff --git a/requirements.txt b/requirements.txt index ac6a0e894b..223522db5b 100755 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # C-PAC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License along with C-PAC. If not, see . boto3==1.28.4 -ciftify==2.3.3 +ciftify @ git+https://git@github.com/e-kenneally/ciftify.git@bugfix/remove_giftiio click==8.1.5 click-aliases==1.0.1 configparser==5.3.0 From 5faa358b9684eb1d6e320f299f7109afc0ba6ad0 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 4 Jan 2024 15:26:50 -0500 Subject: [PATCH 110/213] :bug: Small bugfixes --- CPAC/surface/PostFreeSurfer/surf_reho.py | 12 ++++++------ CPAC/surface/surf_preproc.py | 24 ++++++++++-------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/CPAC/surface/PostFreeSurfer/surf_reho.py b/CPAC/surface/PostFreeSurfer/surf_reho.py index 6c0201a82a..6c1c3788a5 100644 --- a/CPAC/surface/PostFreeSurfer/surf_reho.py +++ b/CPAC/surface/PostFreeSurfer/surf_reho.py @@ -1,10 +1,6 @@ -import numpy as np -import nibabel as nb -import os -import sys - def get_neighbours(faces, vertex_id, depth=1): + import numpy as np fois = np.where(faces == vertex_id)[0] nbrs = list(np.unique(faces[fois])) if depth > 1: @@ -18,6 +14,7 @@ def get_neighbours(faces, vertex_id, depth=1): def ccs_ReHo(dt_file, surf_file): + import numpy as np #Finding neighbors print(surf_file) #surf = np.array(surf_file.agg_data()) # 2 separate arrays @@ -60,8 +57,11 @@ def run_surf_reho(subject, dtseries, mask, cortex_file, \ surface_file, mean_timeseries, reho_filename, structure_name): import os - import subprocess + import nibabel as nb + import numpy as np from CPAC.utils.monitoring.custom_logging import log_subprocess + from CPAC.surface.PostFreeSurfer.surf_reho import ccs_ReHo + from CPAC.surface.PostFreeSurfer.surf_reho import get_neighbours dtseries = nb.load(dtseries) # dtseries file mask = nb.load(mask) # surface mask file diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index 86e3d410cd..fd532466ce 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -66,7 +66,7 @@ def run_surface(post_freesurfer_folder, high_res_mesh, low_res_mesh, \ subcortical_gray_labels, freesurfer_labels] - subprocess.check_output(cmd) + log_subprocess(cmd) # DCAN-HCP PostFreeSurfer Block3 @@ -78,7 +78,7 @@ def run_surface(post_freesurfer_folder, high_res_mesh, low_res_mesh, \ subcortical_gray_labels, freesurfer_labels] - subprocess.check_output(cmd) + log_subprocess(cmd) #DCAN-HCP PostFreeSurfer Block3.5 cmd = ['bash', '/code/CPAC/surface/PostFreeSurfer/block4.sh', post_freesurfer_folder, \ @@ -89,7 +89,7 @@ def run_surface(post_freesurfer_folder, high_res_mesh, low_res_mesh, \ subcortical_gray_labels, freesurfer_labels] - subprocess.check_output(cmd) + log_subprocess(cmd) # DCAN-HCP PostFreeSurfer Block4 @@ -101,7 +101,7 @@ def run_surface(post_freesurfer_folder, high_res_mesh, low_res_mesh, \ subcortical_gray_labels, freesurfer_labels] - subprocess.check_output(cmd) + log_subprocess(cmd) # DCAN-HCP PostFreeSurfer Block5 @@ -113,7 +113,7 @@ def run_surface(post_freesurfer_folder, high_res_mesh, low_res_mesh, \ subcortical_gray_labels, freesurfer_labels] - subprocess.check_output(cmd) + log_subprocess(cmd) # DCAN-HCP PostFreeSurfer Block6 @@ -125,7 +125,7 @@ def run_surface(post_freesurfer_folder, high_res_mesh, low_res_mesh, \ subcortical_gray_labels, freesurfer_labels] - subprocess.check_output(cmd) + log_subprocess(cmd) # DCAN-HCP fMRISurface # https://github.com/DCAN-Labs/DCAN-HCP/blob/master/fMRISurface/GenericfMRISurfaceProcessingPipeline.sh cmd = ['bash', '/code/CPAC/surface/fMRISurface/run.sh', @@ -1035,23 +1035,22 @@ def surface_connectivity_matrix(wf, cfg, strat_pool, pipe_num, opt): def run_surf_falff(subject, dtseries): import os - import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess falff = os.path.join(os.getcwd(), f'{subject}_falff_surf.dscalar.nii') cmd = ['ciftify_falff', dtseries, falff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1'] - subprocess.check_output(cmd) + log_subprocess(cmd) return falff def run_surf_alff(subject, dtseries): import os - import subprocess + from CPAC.utils.monitoring.custom_logging import log_subprocess alff = os.path.join(os.getcwd(), f'{subject}_alff_surf.dscalar.nii') cmd = ['ciftify_falff', dtseries, alff, '--min-low-freq', '0.01', '--max-low-freq' , '0.1' , '--calc-alff'] - subprocess.check_output(cmd) + log_subprocess(cmd) return alff def run_get_cortex(subject, dtseries, structure, cortex_filename): import os - import subprocess from CPAC.utils.monitoring.custom_logging import log_subprocess cortex_file = os.path.join(os.getcwd(), f'{subject}_{cortex_filename}') cmd = ['wb_command', '-cifti-separate', dtseries , 'COLUMN', '-metric', structure, cortex_file] @@ -1061,7 +1060,6 @@ def run_get_cortex(subject, dtseries, structure, cortex_filename): def run_mean_timeseries(subject, dtseries): import os - import subprocess from CPAC.utils.monitoring.custom_logging import log_subprocess mean_timeseries = os.path.join(os.getcwd(), f'{subject}_mean.dscalar.nii') cmd = ['wb_command', '-cifti-reduce', dtseries, 'MEAN', mean_timeseries] @@ -1070,7 +1068,6 @@ def run_mean_timeseries(subject, dtseries): def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): import os - import subprocess from CPAC.utils.monitoring.custom_logging import log_subprocess parcellation_file = os.path.join(os.getcwd(), f'{subject}_parcellation.ptseries.nii') cmd = ['wb_command', '-cifti-parcellate', dtseries , surf_atlaslabel, 'COLUMN', parcellation_file ] @@ -1079,7 +1076,6 @@ def run_ciftiparcellate(subject, dtseries, surf_atlaslabel): def run_cifticorrelation(subject, ptseries): import os - import subprocess from CPAC.utils.monitoring.custom_logging import log_subprocess correlation_matrix = os.path.join(os.getcwd(), f'{subject}_cifti_corr.pconn.nii') cmd = ['wb_command', '-cifti-correlation', ptseries , correlation_matrix] From 574a61719a3122f952c719d5a95aa7abbce06ae1 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 5 Jan 2024 13:04:34 -0500 Subject: [PATCH 111/213] :construction_worker: Rebuild base stage [rebuild base-lite] From a2465041ccb591e3ff3244b63e4e53bb799473be Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 5 Jan 2024 14:51:31 -0500 Subject: [PATCH 112/213] :construction_worker: Rebuild base stage [rebuild base-standard] From 7b0977545e87f9ab344646aaf24988c30d368328 Mon Sep 17 00:00:00 2001 From: Florian Rupprecht Date: Wed, 10 Jan 2024 17:11:14 +0100 Subject: [PATCH 113/213] Workflow serialization: Remove large internal objects --- CPAC/utils/workflow_serialization.py | 35 +++++++++++++++++++++------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/CPAC/utils/workflow_serialization.py b/CPAC/utils/workflow_serialization.py index 40a3f2919e..4bdc80fc97 100644 --- a/CPAC/utils/workflow_serialization.py +++ b/CPAC/utils/workflow_serialization.py @@ -1,8 +1,33 @@ from typing import Callable +from nipype.interfaces.base.support import Bunch +from traits.has_traits import HasTraits + from . import Configuration +def _truncate_large_cpac_internals(obj: object) -> object: + """Recursively replace json_data values and + Config objects. + """ + if isinstance(obj, Configuration): + return '[C-PAC config]' + if isinstance(obj, list): + return [_truncate_large_cpac_internals(i) for i in obj] + if isinstance(obj, tuple): + return (_truncate_large_cpac_internals(i) for i in obj) + if isinstance(obj, HasTraits): + return _truncate_large_cpac_internals(obj.trait_get()) + if isinstance(obj, (Bunch, dict)): + return { + str(k): _truncate_large_cpac_internals(v) + if k != "json_data" else + "[Truncated]" + for k, v in obj.items() + } + return obj + + def cpac_flowdump_serializer( flowdump_serializer: Callable[[object], object], obj: object @@ -12,12 +37,4 @@ def cpac_flowdump_serializer( and CPAC configs from workflow json files as these are repeated for every node (and increase file size dramatically). """ - if isinstance(obj, dict): - if 'json_data' in obj: - obj_clone = obj.copy() - obj_clone['json_data'] = '[truncated]' - obj = obj_clone - return flowdump_serializer(obj) - if isinstance(obj, Configuration): - return '[C-PAC config]' - return flowdump_serializer(obj) + return flowdump_serializer(_truncate_large_cpac_internals(obj)) From 182f4259d055b2056710ea5ab0c99a401ebba8db Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 18:22:35 -0500 Subject: [PATCH 114/213] :bookmark: Bump version to v1.8.7.dev1 --- CHANGELOG.md | 9 ++++++--- CPAC/info.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9d4c4ff2..3005e5b41c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.8.6] +## [unreleased] -## Added +## [1.8.6] - 2023-01-15 + +### Added - Some automatic handling of user-provided BIDSy atlas names. - `sig_imports` static method decorator for `Function` nodes, to accommodate type hinting in signatures of `Function` node functions. @@ -26,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `switch_is_off`, `switch_is_on` and `switch_is_on_off` methods to `Configuration` class - `__repr__` and `__str__` methods to `ResourcePool`s and `NodeBlockFunction`s -## Fixed +### Fixed - Fixed a bug where some connectivity matrices wouldn't generate if anatomical and functional outputs were in different resolutions. - Handling of `3dECM` outputs for AFNI ≥ 21.1.1. @@ -272,6 +274,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 See [Version 1.8.1 Beta](https://fcp-indi.github.io/docs/user/release_notes/v1.8.1) for release notes for v1.8.1 and [Release Notes](https://fcp-indi.github.io/docs/user/release_notes) for all release notes back to v0.1.1. +[unreleased]: https://github.com/FCP-INDI/C-PAC/compare/v1.8.6...develop [1.8.6]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.6 [1.8.5]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.5 [1.8.4]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.4 diff --git a/CPAC/info.py b/CPAC/info.py index b038bb3b43..a6caf85750 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -42,8 +42,8 @@ # version _version_major = 1 _version_minor = 8 -_version_micro = 6 -_version_extra = '' +_version_micro = 7 +_version_extra = 'dev1' def get_cpac_gitversion(): From 2a22c956e76a76f79722fedf4678f26c4e24b914 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 12 Jan 2024 18:42:16 -0500 Subject: [PATCH 115/213] :technologist: Move autoversioning from CI to pre-commit --- .github/workflows/on_push.yml | 18 ------------- .pre-commit-config.yaml | 25 ++++++++++++++++++ scripts/autoversioning.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 scripts/autoversioning.sh diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 1a957dc6b7..3cbb294878 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -86,24 +86,6 @@ jobs: fi cd .. fi - if [[ "${GITHUB_REF_TYPE}" == "tag" ]] - then - cd $HOME/work/C-PAC/C-PAC - for DOCKERFILE in $(ls .github/Dockerfiles/C-PAC.develop-*.Dockerfile) - do - if [[ "$DOCKERFILE" =~ .*C-PAC.develop-(.*)-(bionic|xenial).Dockerfile ]] - then - cp $DOCKERFILE variant-${BASH_REMATCH[1]}.Dockerfile - else - cp $DOCKERFILE Dockerfile - fi - done - git add *ockerfile - git commit -m ":truck: Copy develop Dockerfiles to root directory \ - \ - [skip ci]" - git push origin HEAD:${GITHUB_BRANCH} || true - fi - name: Get changed files since last commit uses: tj-actions/changed-files@v41.0.0 id: changed-files diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..3fbb45c2bf --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,25 @@ +# Copyright (C) 2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . + +repos: + - repo: local + hooks: + - id: autoversioning + name: Update Dockerfiles and version comments + entry: scripts/autoversioning.sh + language: script + files: '.*Dockerfile$' diff --git a/scripts/autoversioning.sh b/scripts/autoversioning.sh new file mode 100644 index 0000000000..21177f2117 --- /dev/null +++ b/scripts/autoversioning.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright (C) 2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . + +# Update version comment strings +cd CPAC +VERSION=$(python -c "from info import __version__; print(('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__).split('+', 1)[0])") +cd .. +echo "v${VERSION}" > version +find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; +git add version +VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) +export PATTERN="(declare|typeset) -a" +if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] +then + for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") + do + export IFS="" + for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) + do + echo "Updating stage tags in ${DOCKERFILE}" + sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} + done + done + unset IFS +fi +git add CPAC/resources/configs .github/Dockerfiles + +# Overwrite top-level Dockerfiles with the CI Dockerfiles +cp .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile Dockerfile +cp .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile variant-ABCD-HCP.Dockerfile +cp .github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile variant-fMRIPrep-LTS.Dockerfile +cp .github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile variant-lite.Dockerfile +git add *Dockerfile \ No newline at end of file From 216d71e1b1f379a8206e489440410b402096a58b Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 12 Jan 2024 18:42:16 -0500 Subject: [PATCH 116/213] :technologist: Move autoversioning from CI to pre-commit --- {scripts => .github/scripts}/autoversioning.sh | 0 .pre-commit-config.yaml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename {scripts => .github/scripts}/autoversioning.sh (100%) mode change 100644 => 100755 diff --git a/scripts/autoversioning.sh b/.github/scripts/autoversioning.sh old mode 100644 new mode 100755 similarity index 100% rename from scripts/autoversioning.sh rename to .github/scripts/autoversioning.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fbb45c2bf..beffa2686a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,6 @@ repos: hooks: - id: autoversioning name: Update Dockerfiles and version comments - entry: scripts/autoversioning.sh + entry: .github/scripts/autoversioning.sh language: script - files: '.*Dockerfile$' + files: '.*Dockerfile$|.*\.yaml$|^CPAC/info\.py$' From 07e3e4a15b6a0cf15fb122474e63d7fe37422a35 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 15:05:10 -0500 Subject: [PATCH 117/213] :bricks: Handle Mac OS `sed` differently from Linux `sed` --- .github/scripts/autoversioning.sh | 9 ++++++++- CPAC/info.py | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 2 +- .../configs/data_config_S3-BIDS-ADHD200_only2.yml | 2 +- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- CPAC/resources/configs/data_config_cpac_benchmark.yml | 2 +- CPAC/resources/configs/data_settings_template.yml | 2 +- CPAC/resources/configs/group_config_template.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-options.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 2 +- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- .../resources/configs/pipeline_config_benchmark-ANTS.yml | 2 +- .../configs/pipeline_config_benchmark-FNIRT.yml | 2 +- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_ccs-options.yml | 2 +- .../configs/pipeline_config_default-deprecated.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- .../configs/pipeline_config_fmriprep-ingress.yml | 2 +- .../configs/pipeline_config_fmriprep-options.yml | 2 +- CPAC/resources/configs/pipeline_config_fx-options.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey.yml | 2 +- CPAC/resources/configs/pipeline_config_ndmg.yml | 2 +- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 2 +- CPAC/resources/configs/pipeline_config_preproc.yml | 2 +- CPAC/resources/configs/pipeline_config_rbc-options.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-1.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-2.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-3.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-4.yml | 2 +- CPAC/resources/configs/pipeline_config_rodent.yml | 2 +- CPAC/resources/configs/system_config.yml | 2 +- .../configs/test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../test_configs/data-test_S3-ADHD200_no-params.yml | 2 +- .../configs/test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-sess.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_ABCD.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_all.yml | 2 +- version | 2 +- 51 files changed, 58 insertions(+), 51 deletions(-) diff --git a/.github/scripts/autoversioning.sh b/.github/scripts/autoversioning.sh index 21177f2117..220d6af0a9 100755 --- a/.github/scripts/autoversioning.sh +++ b/.github/scripts/autoversioning.sh @@ -22,7 +22,14 @@ cd CPAC VERSION=$(python -c "from info import __version__; print(('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__).split('+', 1)[0])") cd .. echo "v${VERSION}" > version -find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; +export _SED_COMMAND="s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" +if [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + find ./CPAC/resources/configs -name "*.yml" -exec sed -i '' -E "${_SED_COMMAND}" {} \; +else + # Linux and others + find ./CPAC/resources/configs -name "*.yml" -exec sed -i'' -r "${_SED_COMMAND}" {} \; +fi git add version VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) export PATTERN="(declare|typeset) -a" diff --git a/CPAC/info.py b/CPAC/info.py index a6caf85750..a6beb47762 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -90,7 +90,7 @@ def get_cpac_gitversion(): _version_micro) if _version_extra: - __version__ += "%s" % _version_extra + __version__ += ".%s" % _version_extra ga_tracker = 'UA-19224662-10' diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 66206c7df6..d674131633 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 7f3ba4eaa1..cae981cd9a 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 178836e7ea..0ef6d3ccf7 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index e49b7b9e80..77a62527e6 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 8cfc9fe519..15460d264c 100644 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 099c6d70e4..1d6c1b912e 100644 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index ec0c1fe601..996c2386f0 100644 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index a604187cac..2e84020471 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 729c6761b4..7aee4e80ad 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 5d9d8c3212..d5334fcf08 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 85b0e4f729..29214c6685 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 38fd7b4a39..8fb774aa80 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index d99ff4ef53..7c4b19b802 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index 692d0876c3..61207908f0 100644 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 7e37da5390..9a11649dee 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 0ad367a48b..ef94cd0095 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml index fe785863cf..c65af74391 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index ace3bf98a5..adaf7bb5af 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 26fd4e42da..ade6c66940 100644 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 7fadcb9e8f..b598e38df3 100644 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index ccf8e3b4bd..09bf8d48ef 100644 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 9474776ddc..70d27d8f7b 100644 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index cfaf86d5a8..bd4bb18b92 100644 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index cf8b0879ac..8326a41696 100644 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index f8943c73da..eb27e51c8e 100644 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index cc859fb347..867851efde 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 2cb42af05a..c00009687c 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index a5a6fd8948..c1ac7c6a77 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 248053327f..b512844c3a 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index 992d11e746..f829296a26 100644 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 1053f9d26b..291adc19a9 100644 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index 69e617cb32..97679f1f76 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 5a4c4c4677..3d1a4f46ca 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index b01d43afcf..080595f840 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 10624b5022..0d428b0340 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index b66a606cea..1d55f02e82 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 9eea91c8bc..39023ec11d 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index d84362d815..e68f31d827 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 61d8d2186a..510e3a7ef9 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 8a546496c4..e6940dc729 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index d1c7ddd7b2..0e9e8f34c5 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index 8b0c36100e..3326d3427f 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 335bc4c6fb..b6feb9c42c 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/version b/version index efed3fdaf4..f4c717aa49 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.6.dev1 +v1.8.7.dev1 From c4f287324c63f8524cf424c5cdf65371cf2d6ec8 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 17:12:39 -0500 Subject: [PATCH 118/213] :fire: Remove CI autoversioning --- .github/workflows/on_push.yml | 51 ------------ dev/circleci_data/drop_version_bump_commits | 30 ------- .../drop_version_commits_back_to | 9 --- dev/circleci_data/override_version_tag_list | 81 ------------------- dev/circleci_data/prep_merge | 16 ---- 5 files changed, 187 deletions(-) delete mode 100755 dev/circleci_data/drop_version_bump_commits delete mode 100755 dev/circleci_data/drop_version_commits_back_to delete mode 100755 dev/circleci_data/override_version_tag_list delete mode 100755 dev/circleci_data/prep_merge diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 3cbb294878..60f6354dc5 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -35,57 +35,6 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 2 - - uses: actions/setup-python@v4 - with: - python-version: '3.9' - cache: 'pip' - - name: Check if version updated - id: version_updated - run: | - git config --global user.email "CMI_CPAC_Support@childmind.org" - git config --global user.name "Theodore (Machine User)" - GITHUB_BRANCH=$(echo ${GITHUB_REF} | cut -d '/' -f 3-) - export PYTHONPATH=$PWD - pip install -q wheel - pip install -q nipype numpy matplotlib pandas pathvalidate pytz pyyaml voluptuous - python ./CPAC/utils/configuration/yaml_template.py - if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] - then - git add CPAC/resources/configs - git commit -m ":bulb: Update comments based on default preconfig" - fi - COMMIT_MESSAGE=$(git log -1 --pretty=%B) - if [[ ! "$COMMIT_MESSAGE" == *"Update version to"* ]] - then - cd CPAC - VERSION=$(python -c "from info import __version__; print(('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__).split('+', 1)[0])") - cd .. - echo "v${VERSION}" > version - find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; - git add version - VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) - export PATTERN="(declare|typeset) -a" - if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] - then - for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") - do - export IFS="" - for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) - do - echo "Updating stage tags in ${DOCKERFILE}" - sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} - done - done - unset IFS - fi - if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] - then - git add CPAC/resources/configs .github/Dockerfiles - git commit -m ":bookmark: Update version to ${VERSION} ($COMMIT_MESSAGE)" || true - git push origin HEAD:${GITHUB_BRANCH} || true - fi - cd .. - fi - name: Get changed files since last commit uses: tj-actions/changed-files@v41.0.0 id: changed-files diff --git a/dev/circleci_data/drop_version_bump_commits b/dev/circleci_data/drop_version_bump_commits deleted file mode 100755 index b72c7570b0..0000000000 --- a/dev/circleci_data/drop_version_bump_commits +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -""" -Helper to drop auto-tag commits back to a given SHA or branch name ($BASE_BRANCH). -""" -import os -import re - -from sys import argv, stdin - -if __name__ == '__main__': - if stdin.isatty and ( - len(argv) == 1 or (len(argv) > 1 and argv[1] in {'-h', '--help'}) - ): - print("""Usage: -Use `drop_version_commits_back_to` to just give a branch or SHA ($BASE_BRANCH) to drop version-tagging commits back to. - -Direct usage: -GIT_SEQUENCE_EDITOR=drop_version_bump_commits git rebase -X ours -i $BASE_BRANCH --empty drop""") - else: - todo_path = os.path.join( - os.getcwd(), '.git', 'rebase-merge', 'git-rebase-todo' - ) - with open(todo_path, 'r') as etd: - todo = etd.read() - - with open(todo_path, 'w') as etd: - etd.write(re.sub( - r"^pick(?=.*\:bookmark\: Update version to.*)", - 'drop', todo, flags=re.MULTILINE - )) diff --git a/dev/circleci_data/drop_version_commits_back_to b/dev/circleci_data/drop_version_commits_back_to deleted file mode 100755 index bd1f105a75..0000000000 --- a/dev/circleci_data/drop_version_commits_back_to +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Helper script to prepare for merging. Takes the branch name or SHA of the merge base ($BASE_BRANCH).. -if [[ $# -eq 0 || "$1" == "-h" || "$1" == "--help" ]] - then - echo "Usage: drop_version_commits_back_to \$BASE_BRANCH" -else - GIT_SEQUENCE_EDITOR="${BASH_SOURCE%/*}/drop_version_bump_commits" git rebase -X ours -i $1 --empty drop -fi -exit 0 diff --git a/dev/circleci_data/override_version_tag_list b/dev/circleci_data/override_version_tag_list deleted file mode 100755 index cc49c6287d..0000000000 --- a/dev/circleci_data/override_version_tag_list +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -""" -Helper for CI handling of auto-tagged version info. Leaves version-tagged files with other changes. -""" -import re - -from sys import argv, stdin - - -def file_diffs(x): - """ - Takes a git diff --stat (plain text) and returns a list of 2-tuples - of (filename, diff_stat) - - Parameters - ---------- - x : str - git diff --stat output - - Returns - ------- - file_diff_stats : list - of 2-tuples of (filename, diff_stat) - """ - return [ - tuple([ - z.strip() for z in y.split('|') - ]) for y in x.strip().split('\n')[:-1] - ] - - -def overwrite_list(file_diff_stats): - """ - Parameters - ---------- - file_diff_stats : list - of 2-tuples of (filename, diff_stat) - - Returns - ------- - set - of strings - """ - config_pattern = 'CPAC/resources/configs/.*\.yml$' - s = set() - return { - fd[0] for fd in file_diff_stats if (( - re.match(config_pattern, fd[0]) or - fd[0] in { - 'version' - } - ) and fd[1] == '2 +-') - } - - -def print_checkout_file_list(git_diff_stat): - """ - Parameters - ---------- - git_diff_stat : str - git diff --stat output - - Returns - ------- - str - space-delimited list of filepaths to checkout from base branch - """ - print(' '.join(overwrite_list(file_diffs(git_diff_stat)))) - - -if __name__ == '__main__': - if ( - len(argv) > 1 and argv[1] in {'-h', '--help'} - ) or stdin.isatty(): - print("""Usage: -Use `prep_merge` to just give a branch or SHA to prep merging onto. - -Direct usage: -git diff enh/nested_config --stat=99999 | override_version_tag_list""") - else: - print_checkout_file_list(stdin.read()) diff --git a/dev/circleci_data/prep_merge b/dev/circleci_data/prep_merge deleted file mode 100755 index 474870b0f2..0000000000 --- a/dev/circleci_data/prep_merge +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# Helper script to prepare for merging. Takes the branch name or SHA of the merge base ($BASE_BRANCH).. -if [[ $# -eq 0 || "$1" == "-h" || "$1" == "--help" ]] - then - echo "Usage: prep_merge \$BASE_BRANCH" -else - CIRCLECI_DATA=$(dirname $0) - FILES_TO_REVERT=$(git diff $1 --stat=999999 | $CIRCLECI_DATA/override_version_tag_list) - if [[ -n $FILES_TO_REVERT ]] - then - echo "git checkout $1 -- $FILES_TO_REVERT" - git checkout $1 -- $FILES_TO_REVERT - git commit -m ":twisted_rightwards_arrows: Prep for merging" - fi -fi -exit 0 From 84c85c12c5e9b101d5630c7c08e14ffdd701b5fa Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 18:09:18 -0500 Subject: [PATCH 119/213] :memo: Add "pre-commit" section to `CONTRIBUTING.md` --- .markdownlint.yml | 4 ++++ CONTRIBUTING.md | 30 +++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.markdownlint.yml b/.markdownlint.yml index 65bcc1be4c..2b6d69e558 100644 --- a/.markdownlint.yml +++ b/.markdownlint.yml @@ -20,3 +20,7 @@ MD013: false # no duplicate headers MD024: siblings_only: true +# allow specific inline HTML elements +MD033: + allowed_elements: + - span \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3f3069719..54dcc1328f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ - + +# CONTRIBUTING + +## pre-commit + +This project uses [pre-commit](https://pre-commit.com/), a framework for managing and maintaining git hooks. Pre-commit can be used to manage the hooks that run on every commit to automatically point out issues in code such as missing semicolons, trailing whitespace, and debug statements. By using these hooks, you can ensure code quality and prevent bad code from being uploaded. + +To install `pre-commit`, you can use `pip`: + +```bash +pip install pre-commit +``` + +After installation, you can set up your git hooks with this command at the root of this repository: + +```bash +pre-commit install +``` + +This will add a pre-commit script to your `.git/hooks/` directory. This script will run whenever you run `git commit`. + +For more details on how to configure and use pre-commit, please refer to the official documentation. + ## Git branches, tags and continuous integration + GitHub Actions builds C-PAC images for each branch and tag pushed to GitHub; these images are pushed to [GHCR](https://github.com/FCP-INDI/C-PAC/pkgs/container/c-pac/versions) and deleted upon branch deletion on GitHub. If a commit is pushed or merged into [`develop` on GitHub](https://github.com/FCP-INDI/C-PAC/tree/develop), GitHub Actions will push [`nightly` and its variants to Docker Hub](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=nightly). If a tag is pushed to GitHub that matches the regular expression + ```Regular Expression ^v[0-9]+\.[0-9]+\.[0-9]+$ ``` + GitHub Actions will push [`release-${TAG}` and its variants](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=release-) and [`latest` and its variants to Docker Hub](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=latest). ## Software dependencies and variant images + We currently have one main and 3 variant images: + * `ABCD-HCP`: dependency versions matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/releases/tag/v0.1.1) versions * `fMRIPrep-LTS`: dependency versions matched to [fMRIPrep Long-term support](https://reproducibility.stanford.edu/fmriprep-lts/) versions * `lite`: same dependency versions as main image without FreeSurfer (smaller image) From 2156b59c1b439162dc2a5cda792f74d49b855144 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 18:15:43 -0500 Subject: [PATCH 120/213] :memo: Add autoversioning pre-commit to CHANGELOG --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3005e5b41c..02d93e7bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] -## [1.8.6] - 2023-01-15 +## Changed -### Added +- Moved autoversioning from CI to pre-commit + +## [1.8.6] - 2024-01-15 + +## Added - Some automatic handling of user-provided BIDSy atlas names. - `sig_imports` static method decorator for `Function` nodes, to accommodate type hinting in signatures of `Function` node functions. From 25182fdc9d8bb31da3f8aed0758db67cffbdc12b Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Wed, 24 Jan 2024 21:20:34 +0000 Subject: [PATCH 121/213] =?UTF-8?q?:bookmark:=20Update=20version=20to=201.?= =?UTF-8?q?8.6=20(=F0=9F=94=96=20=20Set=20version=5Fextra=20to=20empty=20s?= =?UTF-8?q?tring)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml | 2 +- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- CPAC/resources/configs/data_config_cpac_benchmark.yml | 2 +- CPAC/resources/configs/data_settings_template.yml | 2 +- CPAC/resources/configs/group_config_template.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-options.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 2 +- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml | 2 +- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_ccs-options.yml | 2 +- CPAC/resources/configs/pipeline_config_default-deprecated.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml | 2 +- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 2 +- CPAC/resources/configs/pipeline_config_fx-options.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey.yml | 2 +- CPAC/resources/configs/pipeline_config_ndmg.yml | 2 +- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 2 +- CPAC/resources/configs/pipeline_config_preproc.yml | 2 +- CPAC/resources/configs/pipeline_config_rbc-options.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-1.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-2.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-3.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-4.yml | 2 +- CPAC/resources/configs/pipeline_config_rodent.yml | 2 +- CPAC/resources/configs/system_config.yml | 2 +- CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../configs/test_configs/data-test_S3-ADHD200_no-params.yml | 2 +- .../resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-sess.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_ABCD.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_all.yml | 2 +- version | 2 +- 54 files changed, 54 insertions(+), 54 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 9fd301fb5b..097dad96ab 100644 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 539a4aed25..b67701063e 100644 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile index d67bbfabdf..97622bcb9f 100644 --- a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile index 427a12f628..3abd61c499 100644 --- a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index a03fd9a75a..ea002cd613 100644 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-jammy as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 66206c7df6..9a627da39a 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 7f3ba4eaa1..a7767279c5 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 178836e7ea..e940048821 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index e49b7b9e80..c5fdd6dcfc 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 8cfc9fe519..f34e438ee7 100644 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 099c6d70e4..7113c6e972 100644 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index ec0c1fe601..41a932fa5d 100644 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index a604187cac..24a8299c26 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 729c6761b4..051dc7ad79 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 5d9d8c3212..8ee55df5e9 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 85b0e4f729..6a256c09d7 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 38fd7b4a39..d7ffb92aee 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index d99ff4ef53..4b3e6b0ce2 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index 692d0876c3..b1d26e9e3e 100644 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 7e37da5390..faa72bcd91 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 0ad367a48b..e3dc1c812b 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml index fe785863cf..38d9048f2d 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index ace3bf98a5..aedfcb8758 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 26fd4e42da..a3c031de40 100644 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 7fadcb9e8f..d4679169bc 100644 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index ccf8e3b4bd..853cd3d650 100644 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 9474776ddc..4430ef9f45 100644 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index cfaf86d5a8..fc79244d9a 100644 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index cf8b0879ac..da637a2514 100644 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index f8943c73da..4db27fe1e8 100644 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index cc859fb347..a0d13dd51d 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 2cb42af05a..f5adf88f89 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index a5a6fd8948..2877b2619d 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 248053327f..e03357ac30 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index 992d11e746..9043eb3146 100644 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 1053f9d26b..824b837054 100644 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index 69e617cb32..16f5cda3cd 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 5a4c4c4677..fbf20dda1f 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index b01d43afcf..e464497c03 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 10624b5022..a8ae05e500 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index b66a606cea..ded2fa6798 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 9eea91c8bc..93d788c128 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index d84362d815..1d95890768 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 61d8d2186a..822572eaa8 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 8a546496c4..b8eb492446 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index d1c7ddd7b2..5b6149290b 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index 8b0c36100e..2ecc15363f 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 335bc4c6fb..54d7c6c014 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/version b/version index efed3fdaf4..4e0d755440 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.6.dev1 +v1.8.6 From b5ace3d4109859df98a019fbfcbacf85bf6711dd Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Wed, 24 Jan 2024 16:33:41 -0500 Subject: [PATCH 122/213] mask_boolean -m flag set to default on for BET --- CPAC/anat_preproc/anat_preproc.py | 4 +--- CPAC/resources/configs/pipeline_config_anat-only.yml | 3 --- CPAC/resources/configs/pipeline_config_blank.yml | 3 --- CPAC/resources/configs/pipeline_config_default.yml | 3 --- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 3 --- 5 files changed, 1 insertion(+), 15 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 1dcb5b8323..b10bcde6d5 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -615,9 +615,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): inputnode_bet.inputs.set( frac=cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['frac'], - mask_boolean= - cfg.anatomical_preproc['brain_extraction'][ - 'FSL-BET']['mask_boolean'], + mask_boolean= 'on' mesh_boolean= cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['mesh_boolean'], diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 8ee55df5e9..fc0d5fa4d7 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -48,9 +48,6 @@ anatomical_preproc: brain_extraction: FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off - # N4 bias field correction via ANTs n4_bias_field_correction: diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 4b3e6b0ce2..65c8621a1f 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -346,9 +346,6 @@ anatomical_preproc: # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: On - # Mesh created along with skull stripping mesh_boolean: Off diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index e3dc1c812b..905de8e9ab 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -413,9 +413,6 @@ anatomical_preproc: # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: On - # Mesh created along with skull stripping mesh_boolean: Off diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index aedfcb8758..2dc19ead19 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -55,10 +55,7 @@ anatomical_preproc: # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [niworkflows-ants] - FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off segmentation: From 9db5720465ab770ccfe515585276f522643599da Mon Sep 17 00:00:00 2001 From: Biraj Date: Wed, 24 Jan 2024 22:29:16 +0000 Subject: [PATCH 123/213] mask_boolean permanently on for BET --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index b10bcde6d5..bc585f1d9b 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -615,7 +615,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): inputnode_bet.inputs.set( frac=cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['frac'], - mask_boolean= 'on' + mask_boolean= 'On', mesh_boolean= cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['mesh_boolean'], From 149ffbe55c797230b0d5f1072a17053024ad435b Mon Sep 17 00:00:00 2001 From: Biraj Date: Wed, 24 Jan 2024 22:32:22 +0000 Subject: [PATCH 124/213] mask_boolean permanently on for BET --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index bc585f1d9b..7aae33d3c6 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -615,7 +615,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): inputnode_bet.inputs.set( frac=cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['frac'], - mask_boolean= 'On', + mask_boolean= True, mesh_boolean= cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['mesh_boolean'], From 85a3d372a2f8e8a59a81a6420e24595062b7a100 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Wed, 24 Jan 2024 16:33:41 -0500 Subject: [PATCH 125/213] mask_boolean -m flag set to default on for BET --- CPAC/anat_preproc/anat_preproc.py | 4 +--- CPAC/resources/configs/pipeline_config_anat-only.yml | 3 --- CPAC/resources/configs/pipeline_config_blank.yml | 3 --- CPAC/resources/configs/pipeline_config_default.yml | 3 --- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 3 --- 5 files changed, 1 insertion(+), 15 deletions(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index 1dcb5b8323..b10bcde6d5 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -615,9 +615,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): inputnode_bet.inputs.set( frac=cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['frac'], - mask_boolean= - cfg.anatomical_preproc['brain_extraction'][ - 'FSL-BET']['mask_boolean'], + mask_boolean= 'on' mesh_boolean= cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['mesh_boolean'], diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index d5334fcf08..c8087abee7 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -48,9 +48,6 @@ anatomical_preproc: brain_extraction: FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off - # N4 bias field correction via ANTs n4_bias_field_correction: diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 7c4b19b802..10299a2e83 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -346,9 +346,6 @@ anatomical_preproc: # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: On - # Mesh created along with skull stripping mesh_boolean: Off diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index ef94cd0095..e2afda9ecf 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -413,9 +413,6 @@ anatomical_preproc: # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: On - # Mesh created along with skull stripping mesh_boolean: Off diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index adaf7bb5af..ceb9f71e7d 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -55,10 +55,7 @@ anatomical_preproc: # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [niworkflows-ants] - FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off segmentation: From 435de33237578944d19f8388d289cb9ea21c0d12 Mon Sep 17 00:00:00 2001 From: Biraj Date: Wed, 24 Jan 2024 22:29:16 +0000 Subject: [PATCH 126/213] mask_boolean permanently on for BET --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index b10bcde6d5..bc585f1d9b 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -615,7 +615,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): inputnode_bet.inputs.set( frac=cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['frac'], - mask_boolean= 'on' + mask_boolean= 'On', mesh_boolean= cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['mesh_boolean'], From 96f68367407da005819fc56d5b591415ec2b1682 Mon Sep 17 00:00:00 2001 From: Biraj Date: Wed, 24 Jan 2024 22:32:22 +0000 Subject: [PATCH 127/213] mask_boolean permanently on for BET --- CPAC/anat_preproc/anat_preproc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py index bc585f1d9b..7aae33d3c6 100644 --- a/CPAC/anat_preproc/anat_preproc.py +++ b/CPAC/anat_preproc/anat_preproc.py @@ -615,7 +615,7 @@ def fsl_brain_connector(wf, cfg, strat_pool, pipe_num, opt): inputnode_bet.inputs.set( frac=cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['frac'], - mask_boolean= 'On', + mask_boolean= True, mesh_boolean= cfg.anatomical_preproc['brain_extraction'][ 'FSL-BET']['mesh_boolean'], From c706bf2b2e9e58af10aa6346e3148447a0bbebf9 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 00:43:49 -0500 Subject: [PATCH 128/213] :pencil2: Fix gitversion for PEP440 --- CPAC/info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/info.py b/CPAC/info.py index a6beb47762..7002a07b14 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -82,7 +82,7 @@ def get_cpac_gitversion(): if 'dev' in _version_extra: gitversion = get_cpac_gitversion() if gitversion: - _version_extra = f'dev1+{gitversion}' + _version_extra = f'{_version_extra}+{gitversion}' __version__ = "%s.%s.%s" % (_version_major, From 2bec6713fdee9071d1b9852360b193f8fb5cbedb Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 00:46:23 -0500 Subject: [PATCH 129/213] :necktie: Don't rely on `${GITHUB_BRANCH}` locally --- .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .../C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- .github/scripts/autoversioning.sh | 12 +++++++++--- Dockerfile | 2 +- variant-ABCD-HCP.Dockerfile | 2 +- variant-fMRIPrep-LTS.Dockerfile | 2 +- variant-lite.Dockerfile | 2 +- 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 9fd301fb5b..2a5760ebb7 100644 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 539a4aed25..0e9cd3d899 100644 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile index d67bbfabdf..f9ced12d7b 100644 --- a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile index 427a12f628..1f6f3a9ec9 100644 --- a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index a03fd9a75a..2d0d51ab76 100644 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-jammy as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC diff --git a/.github/scripts/autoversioning.sh b/.github/scripts/autoversioning.sh index 220d6af0a9..0543f626a1 100755 --- a/.github/scripts/autoversioning.sh +++ b/.github/scripts/autoversioning.sh @@ -31,17 +31,23 @@ else find ./CPAC/resources/configs -name "*.yml" -exec sed -i'' -r "${_SED_COMMAND}" {} \; fi git add version -VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) +VERSIONS=( `git show $(git log --pretty=format:'%h' -n 2 version | tail -n 1):version` `cat version` ) export PATTERN="(declare|typeset) -a" if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] then for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") do export IFS="" - for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) + for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]}" ${DOCKERFILE}) do echo "Updating stage tags in ${DOCKERFILE}" - sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} + if [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + sed -i "" "s/\-${VERSIONS[0]}/\-${VERSIONS[1]}/g" ${DOCKERFILE} + else + # Linux and others + sed -i "s/\-${VERSIONS[0]}/\-${VERSIONS[1]}/g" ${DOCKERFILE} + fi done done unset IFS diff --git a/Dockerfile b/Dockerfile index d67bbfabdf..f9ced12d7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/variant-ABCD-HCP.Dockerfile b/variant-ABCD-HCP.Dockerfile index 9fd301fb5b..2a5760ebb7 100644 --- a/variant-ABCD-HCP.Dockerfile +++ b/variant-ABCD-HCP.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/variant-fMRIPrep-LTS.Dockerfile b/variant-fMRIPrep-LTS.Dockerfile index 539a4aed25..0e9cd3d899 100644 --- a/variant-fMRIPrep-LTS.Dockerfile +++ b/variant-fMRIPrep-LTS.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/variant-lite.Dockerfile b/variant-lite.Dockerfile index 427a12f628..1f6f3a9ec9 100644 --- a/variant-lite.Dockerfile +++ b/variant-lite.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root From 9884409e68b0e2aaa13e9eb903ca8e1d74aeb6ec Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 01:18:15 -0500 Subject: [PATCH 130/213] :art: DRY docs URL --- CPAC/__init__.py | 47 +++++++++++++++++++++++------------------ CPAC/pipeline/schema.py | 6 +++--- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/CPAC/__init__.py b/CPAC/__init__.py index 0c14612ed9..c2d0828353 100644 --- a/CPAC/__init__.py +++ b/CPAC/__init__.py @@ -1,3 +1,19 @@ +# Copyright (C) 2022-2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . """ Configurable Pipeline for the Analysis of Connectomes ===================================================== @@ -5,33 +21,22 @@ CPAC is a configurable, open-source, Nipype-based, automated processing pipeline for resting state functional MRI (R-fMRI) data, for use by both novice and expert users. +""" -Copyright (C) 2022 C-PAC Developers - -This file is part of C-PAC. +from .info import __version__ +version = __version__ -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +def _docs_prefix() -> str: + """Get the docs URL prefix for this version""" + from CPAC.utils.docs import DOCS_URL_PREFIX + return DOCS_URL_PREFIX -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see . -""" -from .info import __version__ -version = __version__ -_url_version = 'nightly' if __version__.endswith( - '-dev') or __version__.endswith('.dev') else f'v{__version__.lstrip("v")}' -docs_prefix = f'https://fcp-indi.github.io/docs/{_url_version}' -license_notice = f"""Copyright (C) 2022 C-PAC Developers. +license_notice = f"""Copyright (C) 2022-2024 C-PAC Developers. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. For -details, see {docs_prefix}/license or the COPYING and +details, see {_docs_prefix()}/license or the COPYING and COPYING.LESSER files included in the source code.""" +__all__ = ['license_notice', 'version', '__version__'] diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 5b037de003..f24598dde2 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022 C-PAC Developers +# Copyright (C) 2022-2024 C-PAC Developers # This file is part of C-PAC. @@ -25,8 +25,8 @@ Coerce, CoerceInvalid, ExclusiveInvalid, In, Length, \ LengthInvalid, Lower, Match, Maybe, MultipleInvalid, \ Optional, Range, Required, Schema, Title -from CPAC import docs_prefix from CPAC.utils.datatypes import ItemFromList, ListFromItem +from CPAC.utils.docs import DOCS_URL_PREFIX from CPAC.utils.utils import YAML_BOOLS # 1 or more digits, optional decimal, 'e', optional '-', 1 or more digits @@ -249,7 +249,7 @@ def str_to_bool1_1(x): # pylint: disable=invalid-name Required('lowpass_cutoff'): Number, 'Name': Maybe(str)}, msg='`motion_estimate_filter` configuration is invalid.\nSee ' - f'{docs_prefix}/user/' + f'{DOCS_URL_PREFIX}/user/' 'func#motion-estimate-filter-valid-options for details.\n') target_space = All(Coerce(ListFromItem), [All(Title, In(valid_options['target_space']))]) From 83b2e9c678b0670f2387baf490f8ef921ea9cfe2 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Fri, 26 Jan 2024 13:37:55 -0500 Subject: [PATCH 131/213] FSL-BET empty keys removed --- CPAC/pipeline/schema.py | 1 - CPAC/resources/configs/pipeline_config_anat-only.yml | 2 -- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 7 ------- CPAC/resources/configs/pipeline_config_regtest-1.yml | 6 ------ CPAC/resources/configs/pipeline_config_regtest-2.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-3.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-4.yml | 4 ---- 7 files changed, 28 deletions(-) diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 5b037de003..249f96f07e 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -524,7 +524,6 @@ def sanitize(filename): }, 'FSL-BET': { 'frac': Number, - 'mask_boolean': bool1_1, 'mesh_boolean': bool1_1, 'outline': bool1_1, 'padding': bool1_1, diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index c8087abee7..01e902abc0 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -45,8 +45,6 @@ pipeline_setup: s3_encryption: On anatomical_preproc: - brain_extraction: - FSL-BET: # N4 bias field correction via ANTs n4_bias_field_correction: diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 29214c6685..fcca1ca50c 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -73,13 +73,6 @@ anatomical_preproc: acpc_alignment: T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz - brain_extraction: - run: On - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off - segmentation: # Automatically segment anatomical images into white matter, gray matter, diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index 867851efde..b702743503 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -73,12 +73,6 @@ anatomical_preproc: acpc_alignment: T1w_brain_ACPC_template: $FSLDIR/data/standard/MNI152_T1_1mm_brain.nii.gz - brain_extraction: - run: On - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off segmentation: diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index c00009687c..08d546bdc2 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -84,10 +84,6 @@ anatomical_preproc: # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [BET] - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off segmentation: diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index c1ac7c6a77..77febb731f 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -84,10 +84,6 @@ anatomical_preproc: # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [niworkflows-ants] - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index b512844c3a..62928c1c43 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -99,10 +99,6 @@ anatomical_preproc: # Perform final surface smoothing after all iterations. Default is 20. smooth_final: 22 - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: From 204a36c6ed692229b8c656331a7229068c69f028 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:04:26 +0000 Subject: [PATCH 132/213] :arrow_up: Bump cryptography from 41.0.1 to 41.0.6 Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.1 to 41.0.6. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.1...41.0.6) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ac6a0e894b..1a5f1d5e41 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ voluptuous==0.13.1 # the below are pinned specifically to match what the FSL installer installs botocore==1.31.4 charset-normalizer==3.1.0 -cryptography==41.0.1 +cryptography==41.0.6 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 From 891d43e207d9b22f7846f03ca8608e43f4d0177d Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 18:03:37 -0500 Subject: [PATCH 133/213] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20urllib3=20f?= =?UTF-8?q?rom=201.26.15=20to=201.26.18=20(#2044)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1a5f1d5e41..e9dffcf342 100644 --- a/requirements.txt +++ b/requirements.txt @@ -46,6 +46,6 @@ importlib-metadata==6.8.0 lxml==4.9.2 pip==23.1.2 setuptools==68.0.0 -urllib3==1.26.15 +urllib3==1.26.18 wheel==0.40.0 zipp==3.16.0 From 86190ed2c54ce461e00bce4a68e80bcb8934d399 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:04:59 +0000 Subject: [PATCH 134/213] :arrow_up: Bump pip from 23.1.2 to 23.3 Bumps [pip](https://github.com/pypa/pip) from 23.1.2 to 23.3. - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/23.1.2...23.3) --- updated-dependencies: - dependency-name: pip dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e9dffcf342..55a9ce8af0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,7 +44,7 @@ cryptography==41.0.6 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 -pip==23.1.2 +pip==23.3 setuptools==68.0.0 urllib3==1.26.18 wheel==0.40.0 From 999d8601c74dbfe7287ea8f77b876c8ef4bf8d17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 02:27:03 +0000 Subject: [PATCH 135/213] :arrow_up: Bump cryptography from 41.0.1 to 42.0.0 Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.1 to 42.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.1...42.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 55a9ce8af0..52faa11710 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ voluptuous==0.13.1 # the below are pinned specifically to match what the FSL installer installs botocore==1.31.4 charset-normalizer==3.1.0 -cryptography==41.0.6 +cryptography==42.0.0 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 From 2643cc5176f144c8c1b992807b63118c82e64f7a Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Tue, 6 Feb 2024 13:03:00 -0500 Subject: [PATCH 136/213] Revert default config to have robust off and updated changelog --- CHANGELOG.md | 1 + CPAC/resources/configs/pipeline_config_default.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a3fa30ff8..2a5a10fc7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -228,6 +228,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - if `registration_workflows['anatomical_registration']['run']` is `On` and `segmentation['tissue_segmentation']['Template_Based']['template_for_segmentation']` includes `T1_Template` - Renamed connectivity matrices from `*_connectome.tsv` to `*_correlations.tsv` - Moved some ephemeral logging statements into `pypeline.log` +- Added `Robustfov` option in `FSL-BET` config. This can be turned on to crop out neck and other non-brain regions. ### Fixed diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 276277b92e..2022e75cd0 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,7 +409,7 @@ anatomical_preproc: monkey: False FSL-BET: - Robustfov : On + Robustfov : Off # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From b78adfc0b449067e61a170150552d777fdcd9bd6 Mon Sep 17 00:00:00 2001 From: Biraj Date: Tue, 6 Feb 2024 18:55:49 +0000 Subject: [PATCH 137/213] Rebase --- CPAC/resources/configs/pipeline_config_default.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 27cfdd5d30..2022e75cd0 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,13 +409,7 @@ anatomical_preproc: monkey: False FSL-BET: -<<<<<<< HEAD Robustfov : Off -======= - # Set Robustfov on to crop neck regions before generating the mask for skull stripping. - Robustfov : On - ->>>>>>> upstream/add_fslrobustfov # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From d871814c600ef31b026aef4fb2abc6f0c9766e19 Mon Sep 17 00:00:00 2001 From: Biraj Date: Tue, 6 Feb 2024 19:01:19 +0000 Subject: [PATCH 138/213] :rocket: Robustfov added to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96f8453e92..d2add4dd71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -141,6 +141,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated some output filenaming conventions for human-readability and to move closer to BIDS-derivatives compliance - Changed motion filter from single dictionary to list of dictionaries - Changed CI logic to allow non-release tags +- Added `Robustfov` in the `FSL-BET` config ### Upgraded dependencies From f8c5bd6d0abfab8abb71775e8d1fc7379ec24917 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Tue, 6 Feb 2024 19:04:38 +0000 Subject: [PATCH 139/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_blank.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index a576e72172..1c5f43291e 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -344,9 +344,6 @@ anatomical_preproc: FSL-BET: Robustfov: On - # Set Robustfov on to crop neck regions before generating the mask for skull stripping. - Robustfov: On - # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From a546ee4d0c376a219e928bc08155f6eb2fa09a58 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Tue, 6 Feb 2024 19:04:38 +0000 Subject: [PATCH 140/213] :bookmark: Update version to 1.8.6 (:bulb: Update comments based on default preconfig) --- .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml | 2 +- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- CPAC/resources/configs/data_config_cpac_benchmark.yml | 2 +- CPAC/resources/configs/data_settings_template.yml | 2 +- CPAC/resources/configs/group_config_template.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-options.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 2 +- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml | 2 +- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_ccs-options.yml | 2 +- CPAC/resources/configs/pipeline_config_default-deprecated.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml | 2 +- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 2 +- CPAC/resources/configs/pipeline_config_fx-options.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey.yml | 2 +- CPAC/resources/configs/pipeline_config_ndmg.yml | 2 +- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 2 +- CPAC/resources/configs/pipeline_config_preproc.yml | 2 +- CPAC/resources/configs/pipeline_config_rbc-options.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-1.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-2.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-3.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-4.yml | 2 +- CPAC/resources/configs/pipeline_config_rodent.yml | 2 +- CPAC/resources/configs/system_config.yml | 2 +- CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../configs/test_configs/data-test_S3-ADHD200_no-params.yml | 2 +- .../resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-sess.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_ABCD.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_all.yml | 2 +- version | 2 +- 54 files changed, 54 insertions(+), 54 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 9fd301fb5b..097dad96ab 100644 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 539a4aed25..b67701063e 100644 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile index d67bbfabdf..97622bcb9f 100644 --- a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile index 427a12f628..3abd61c499 100644 --- a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index a03fd9a75a..ea002cd613 100644 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-jammy as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 66206c7df6..9a627da39a 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 7f3ba4eaa1..a7767279c5 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 178836e7ea..e940048821 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index e49b7b9e80..c5fdd6dcfc 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 8cfc9fe519..f34e438ee7 100644 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 099c6d70e4..7113c6e972 100644 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index ec0c1fe601..41a932fa5d 100644 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index a604187cac..24a8299c26 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 729c6761b4..051dc7ad79 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 5d9d8c3212..8ee55df5e9 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 85b0e4f729..6a256c09d7 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 38fd7b4a39..d7ffb92aee 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 1c5f43291e..ccc423d3d7 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index 692d0876c3..b1d26e9e3e 100644 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 7e37da5390..faa72bcd91 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 2022e75cd0..86b1aa9844 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml index fe785863cf..38d9048f2d 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index ace3bf98a5..aedfcb8758 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 26fd4e42da..a3c031de40 100644 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 7fadcb9e8f..d4679169bc 100644 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index ccf8e3b4bd..853cd3d650 100644 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 9474776ddc..4430ef9f45 100644 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index cfaf86d5a8..fc79244d9a 100644 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index cf8b0879ac..da637a2514 100644 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index f8943c73da..4db27fe1e8 100644 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index cc859fb347..a0d13dd51d 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 2cb42af05a..f5adf88f89 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index a5a6fd8948..2877b2619d 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 248053327f..e03357ac30 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index 992d11e746..9043eb3146 100644 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 1053f9d26b..824b837054 100644 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index 69e617cb32..16f5cda3cd 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 5a4c4c4677..fbf20dda1f 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index b01d43afcf..e464497c03 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 10624b5022..a8ae05e500 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index b66a606cea..ded2fa6798 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 9eea91c8bc..93d788c128 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index d84362d815..1d95890768 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 61d8d2186a..822572eaa8 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 8a546496c4..b8eb492446 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index d1c7ddd7b2..5b6149290b 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index 8b0c36100e..2ecc15363f 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 45c76d2f7e..74c38ad409 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 335bc4c6fb..54d7c6c014 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.6 # # http://fcp-indi.github.io for more info. # diff --git a/version b/version index efed3fdaf4..4e0d755440 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.6.dev1 +v1.8.6 From 384a39133f56f92a146e5c27e2b149617933582f Mon Sep 17 00:00:00 2001 From: Biraj Date: Tue, 6 Feb 2024 19:39:10 +0000 Subject: [PATCH 141/213] :package: updating dockerfile --- .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 097dad96ab..2a5760ebb7 100644 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index b67701063e..0e9cd3d899 100644 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile index 97622bcb9f..f9ced12d7b 100644 --- a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile index 3abd61c499..1f6f3a9ec9 100644 --- a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index ea002cd613..2d0d51ab76 100644 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-jammy as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC From afabaf8922fa4564223a29a3e1c58f415f05257a Mon Sep 17 00:00:00 2001 From: Biraj Date: Tue, 6 Feb 2024 19:54:25 +0000 Subject: [PATCH 142/213] :package: updated config files to ckeep rainextraction on --- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 1 + CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-1.yml | 7 +++---- CPAC/resources/configs/pipeline_config_regtest-2.yml | 3 --- CPAC/resources/configs/pipeline_config_regtest-3.yml | 3 --- CPAC/resources/configs/pipeline_config_regtest-4.yml | 4 ---- 7 files changed, 5 insertions(+), 19 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 051dc7ad79..11ca8250b2 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -46,6 +46,7 @@ anatomical_preproc: T1w_ACPC_template: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_1mm.nii.gz brain_extraction: + run: On # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index fc0d5fa4d7..0d86915f2f 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -46,7 +46,7 @@ pipeline_setup: anatomical_preproc: brain_extraction: - FSL-BET: + run: On # N4 bias field correction via ANTs n4_bias_field_correction: diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 6a256c09d7..d5e579609f 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -75,10 +75,6 @@ anatomical_preproc: brain_extraction: run: On - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off segmentation: diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index a0d13dd51d..e4c7eb3f3e 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -75,10 +75,9 @@ anatomical_preproc: brain_extraction: run: On - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] + # this is a fork option + using: [BET] segmentation: diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index f5adf88f89..46192d00f2 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -84,10 +84,7 @@ anatomical_preproc: # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [BET] - FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off segmentation: diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index 2877b2619d..316f2f3865 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -84,10 +84,7 @@ anatomical_preproc: # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [niworkflows-ants] - FSL-BET: - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index e03357ac30..dad92a8dc3 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -99,10 +99,6 @@ anatomical_preproc: # Perform final surface smoothing after all iterations. Default is 20. smooth_final: 22 - FSL-BET: - - # Mask created along with skull stripping. It should be `On`, if selected functionalMasking : ['Anatomical_Refined'] and `FSL` as skull-stripping method. - mask_boolean: Off # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: From 3ecbbe617f518f4ac7bb661ddf20014db962b464 Mon Sep 17 00:00:00 2001 From: "Theodore (Machine User)" Date: Tue, 6 Feb 2024 19:56:54 +0000 Subject: [PATCH 143/213] :bulb: Update comments based on default preconfig --- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 -- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 1 - CPAC/resources/configs/pipeline_config_regtest-1.yml | 1 + CPAC/resources/configs/pipeline_config_regtest-2.yml | 1 - CPAC/resources/configs/pipeline_config_regtest-3.yml | 1 - CPAC/resources/configs/pipeline_config_regtest-4.yml | 1 - 6 files changed, 1 insertion(+), 6 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 0d86915f2f..461190ed29 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -45,8 +45,6 @@ pipeline_setup: s3_encryption: On anatomical_preproc: - brain_extraction: - run: On # N4 bias field correction via ANTs n4_bias_field_correction: diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index 2dc19ead19..ded75d21a0 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -56,7 +56,6 @@ anatomical_preproc: # this is a fork option using: [niworkflows-ants] - segmentation: # Automatically segment anatomical images into white matter, gray matter, diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index e4c7eb3f3e..a0df76dc81 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -75,6 +75,7 @@ anatomical_preproc: brain_extraction: run: On + # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option using: [BET] diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 46192d00f2..9e2c93ac54 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -85,7 +85,6 @@ anatomical_preproc: # this is a fork option using: [BET] - segmentation: # Automatically segment anatomical images into white matter, gray matter, diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index 316f2f3865..7392766e87 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -85,7 +85,6 @@ anatomical_preproc: # this is a fork option using: [niworkflows-ants] - # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index dad92a8dc3..2ac15f0f64 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -99,7 +99,6 @@ anatomical_preproc: # Perform final surface smoothing after all iterations. Default is 20. smooth_final: 22 - # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: From 7ad527f2a3b3ca91400932fc734813fece9209e3 Mon Sep 17 00:00:00 2001 From: Biraj Date: Tue, 6 Feb 2024 19:57:01 +0000 Subject: [PATCH 144/213] :package:mask-boolean default added to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9d4c4ff2..c43c7f82a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -189,6 +189,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated CI to only rebuild software dependencies on change - Replaced deprecated `optparse.OptionError` with to `click.BadParameter` - Relicensed C-PAC from BSD-3-Clause to LGPL-3.0-or-later +- Updated `FSL-BET` config to default `-mask-boolean` flag as on, and removed all removed `mask-boolean` keys from configs. ### Fixed From 6953402be90604ac8bf8d1fa48df8fa0fd5a3925 Mon Sep 17 00:00:00 2001 From: Biraj Date: Wed, 7 Feb 2024 18:24:38 +0000 Subject: [PATCH 145/213] :package: Corrected changelog for FSL mask boolean --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b4c35e8e6..66440ac149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Changed - Moved autoversioning from CI to pre-commit +- Updated `FSL-BET` config to default `-mask-boolean` flag as on, and removed all removed `mask-boolean` keys from configs. ## [1.8.6] - 2024-01-15 From d97eea92c3645e5025fcacccdc9433b19e25a3d1 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 8 Feb 2024 13:38:31 -0500 Subject: [PATCH 146/213] Refactor surf_reho --- CPAC/surface/PostFreeSurfer/surf_reho.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/CPAC/surface/PostFreeSurfer/surf_reho.py b/CPAC/surface/PostFreeSurfer/surf_reho.py index 6c1c3788a5..e9c18eb040 100644 --- a/CPAC/surface/PostFreeSurfer/surf_reho.py +++ b/CPAC/surface/PostFreeSurfer/surf_reho.py @@ -15,8 +15,8 @@ def get_neighbours(faces, vertex_id, depth=1): def ccs_ReHo(dt_file, surf_file): import numpy as np + #Finding neighbors - print(surf_file) #surf = np.array(surf_file.agg_data()) # 2 separate arrays faces = np.array(surf_file.agg_data('triangle')) vertex = np.array(surf_file.agg_data('pointset')) @@ -26,13 +26,13 @@ def ccs_ReHo(dt_file, surf_file): output = get_neighbours(faces, voi, depth = 1) nbrs.append(output) - #Ting ReHo Calculation + #ReHo Calculation tsmat = np.array(dt_file.agg_data()) nsp = (tsmat.shape)[1] #vertex ntp = (tsmat.shape)[0] #timepoints tmp_ts = [] - cReHo = [] + cReHo = np.zeros(nsp) for i in range(0,nsp): tmp_ts = np.squeeze(tsmat[:,i]) tmp_ts = tmp_ts.reshape(-1,1) @@ -48,7 +48,7 @@ def ccs_ReHo(dt_file, surf_file): R = np.argsort(I, axis = 0, kind = 'mergesort') S = (np.sum((np.sum(R, axis = 1)**2))) - (ntp*np.mean(np.sum(R,axis=1))**2) F = m*m*(ntp*ntp*ntp-ntp) - cReHo = np.append(cReHo, (12 * (S/F))) + cReHo[i] = 12 * S / F cReHo = cReHo.reshape(-1,1) return(cReHo) @@ -71,23 +71,25 @@ def run_surf_reho(subject, dtseries, mask, cortex_file, \ surf_reho = os.path.join(os.getcwd(), f'{subject}_{reho_filename}') cReHo = ccs_ReHo(cortex_file, surf_file) + structure_names = [structure_name] - ## Axes and Header stuff ## + ## Get header information from dtseries and mean timeseries ## axes = [dtseries.header.get_axis(i) for i in range(dtseries.ndim)] axes1 = [scalar_dt.header.get_axis(i) for i in range(scalar_dt.ndim)] - time_axis, brain_model_axis = axes #dtseries time_axis1, brain_axis1 = axes1 #dscalar + brain_model_axis = nb.cifti2.cifti2_axes.BrainModelAxis.from_surface( + vertices=cReHo[:, 0], nvertex=cReHo.shape[0], name=structure_name) - # Select the structures you want - structure_names = [structure_name] # List of structure names - + # Only use data from specific region brain_models = [bm for bm in brain_model_axis.iter_structures() if bm[0] in structure_names] + # Extract data from dtseries for every element in brain models and make into dataobj new_dataobj = np.concatenate([dtseries.dataobj[0, bm[1]] for bm in brain_models], axis=0) new_dataobj = np.transpose(new_dataobj.reshape(-1,1)) + # Get axis information for new dataobj new_brain_model_axis = sum( (bm[2] for bm in brain_models[1:]), brain_models[0][2]) @@ -96,7 +98,7 @@ def run_surf_reho(subject, dtseries, mask, cortex_file, \ nifti_header=dtseries.nifti_header) ## Saving image ## - img = nb.Cifti2Image(np.transpose(cReHo), header = new_cifti.header, nifti_header=new_cifti.nifti_header) + img = nb.Cifti2Image(np.transpose(cReHo), header=new_cifti.header, nifti_header=new_cifti.nifti_header) reho_file = surf_reho img.to_filename(reho_file) From f4a281657eec81a5cc59d8abc7db719c5b571a6b Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 8 Feb 2024 13:38:57 -0500 Subject: [PATCH 147/213] Fix outputs naming issue --- CPAC/resources/cpac_outputs.tsv | 4 ++-- CPAC/surface/surf_preproc.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index d69e9bffd7..7ff5f91041 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -223,10 +223,10 @@ space-EPItemplate_label-WM_mask mask template func NIfTI space-EPItemplate_label-GM_mask mask template func NIfTI mdmr group functional group_analysis NIfTI desc-zstd-mdmr group functional group_analysis NIfTI Yes -AtlasSubcortical_s2 surface_derived func +AtlasSubcortical-s2 surface_derived func space-fsLR_den-32k_bold surface_derived func CIFTI dtseries goodvoxels surface_derived func -ribbon_only surface_derived func +ribbon-only surface_derived func hemi-L_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func hemi-R_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func hemi-L_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py index fd532466ce..2b0cb64741 100755 --- a/CPAC/surface/surf_preproc.py +++ b/CPAC/surface/surf_preproc.py @@ -489,9 +489,9 @@ def run_surface(post_freesurfer_folder, "atlas-DesikanKilliany_space-fsLR_den-164k", "atlas-Destrieux_space-fsLR_den-164k", "space-fsLR_den-32k_bold-dtseries", - "AtlasSubcortical_s2", + "AtlasSubcortical-s2", "goodvoxels", - "ribbon_only", + "ribbon-only", "hemi-L_space-fsLR_den-32k_desc-atlasroi_bold", "hemi-R_space-fsLR_den-32k_desc-atlasroi_bold", "hemi-L_space-fsLR_den-32k_desc-atlasroi_mask", @@ -745,9 +745,9 @@ def surface_postproc(wf, cfg, strat_pool, pipe_num, opt=None): 'desikan_' 'killiany_164'), 'atlas-Destrieux_space-fsLR_den-164k': (surf, 'destrieux_164'), - 'AtlasSubcortical_s2': (surf, 'subcortical_atlas'), + 'AtlasSubcortical-s2': (surf, 'subcortical_atlas'), 'goodvoxels': (surf, 'good_voxels'), - 'ribbon_only': (surf, 'ribbon_only'), + 'ribbon-only': (surf, 'ribbon_only'), 'hemi-L_space-fsLR_den-32k_desc-atlasroi_bold': (surf, 'atlas_roi_func_' 'L'), From 6749392ae4c511d3f797408603063733fdac3368 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:47:46 +0000 Subject: [PATCH 148/213] Bump tj-actions/changed-files in /.github/workflows Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 34.0.0 to 41.0.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v34.0.0...v41.0.0) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/build_stages.yml | 288 +++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 .github/workflows/build_stages.yml diff --git a/.github/workflows/build_stages.yml b/.github/workflows/build_stages.yml new file mode 100644 index 0000000000..4a705f3b36 --- /dev/null +++ b/.github/workflows/build_stages.yml @@ -0,0 +1,288 @@ +# Requires secret `ACTIONS_WORKFLOW_TOKEN` with `workflow` scope + +name: Build stages + +on: + workflow_dispatch: + inputs: + base_ref: + description: 'Base reference if triggered by a pull request' + required: false + default: "" + + +jobs: + update-check: + name: Update GitHub check + runs-on: ubuntu-latest + steps: + - name: Update check's target URL + uses: Sibz/github-status-action@v1.1.6 + with: + authToken: ${{ secrets.ACTIONS_WORKFLOW_TOKEN }} + context: "Build C-PAC images" + state: pending + target_url: ${{ github.server_url }}/${{ github.repository}}/actions/runs/${{ github.run_id }} + + Ubuntu: + name: Build C-PAC Ubuntu + needs: + - update-check + strategy: + matrix: + Dockerfile: + - Ubuntu.bionic-non-free + - Ubuntu.xenial-20200114 + runs-on: ubuntu-latest + steps: + - name: Check out C-PAC (depth 0) + if: github.event.inputs.base_ref != '' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Check out C-PAC (depth 2) + if: github.event.inputs.base_ref == '' + uses: actions/checkout@v2 + with: + fetch-depth: 2 + - name: Get changed files since fork point + uses: tj-actions/changed-files@v41.0.0 + if: github.event.inputs.base_ref != '' + id: changed-files-base + with: + use_fork_point: "true" + files: .github/Dockerfiles/* + - name: Get changed files since last commit + uses: tj-actions/changed-files@v41.0.0 + if: github.event.inputs.base_ref == '' + id: changed-files + with: + since_last_remote_commit: "true" + files: .github/Dockerfiles/* + - name: Set tag & see if it exists + continue-on-error: true + run: | + TAG=$(sed 's/\./:/' <(echo ${{ matrix.Dockerfile }})) + DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') + echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV + docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2.2.1 + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + - name: Build and push Docker image + uses: docker/build-push-action@v3.2.0 + with: + file: .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile + push: true + tags: | + ${{ env.DOCKER_TAG }} + cache-from: type=gha + cache-to: type=gha,mode=min + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) + + stages: + name: Build Docker stage images + needs: Ubuntu + strategy: + matrix: + Dockerfile: + - AFNI.16.2.07.neurodocker-xenial + - AFNI.21.1.00-bionic + - ANTs.2.2.0.neurodocker-bionic + - c3d.1.0.0-xenial + - connectome-workbench.1.3.2-1.neurodebian-bionic + - connectome-workbench.1.3.2-2.neurodebian-xenial + - FSL.5.0.9-5.neurodebian-xenial + - FSL.5.0.10-bionic + - ICA-AROMA.0.4.5-xenial + - msm.2.0-bionic + runs-on: ubuntu-latest + steps: + - name: Check out C-PAC (depth 0) + if: github.event.inputs.base_ref != '' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Check out C-PAC (depth 2) + if: github.event.inputs.base_ref == '' + uses: actions/checkout@v2 + with: + fetch-depth: 2 + - name: Get changed files since fork point + uses: tj-actions/changed-files@v41.0.0 + if: github.event.inputs.base_ref != '' + id: changed-files-base + with: + use_fork_point: "true" + files: | + dev/docker_data/required_afni_pkgs.txt + .github/Dockerfiles/* + - name: Get changed files since last commit + uses: tj-actions/changed-files@v41.0.0 + if: github.event.inputs.base_ref == '' + id: changed-files + with: + since_last_remote_commit: "true" + files: | + dev/docker_data/required_afni_pkgs.txt + .github/Dockerfiles/* + - name: Clear up some space on runner + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2.2.1 + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + - name: Set tag & see if it exists + continue-on-error: true + run: | + TAG=$(sed 's/\./:/' <(echo ${{ matrix.Dockerfile }})) + DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') + echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV + docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + - name: Prep Dockerfiles for forked repository + if: github.repository_owner != 'FCP-INDI' && contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + run: | + .github/scripts/local_ghcr .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile ${{ github.repository_owner }} $DOCKER_TAG + cat .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile + - name: See Dockerfile + run: cat .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + - name: Build and push Docker image + uses: docker/build-push-action@v3.2.0 + with: + context: . + file: .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile + push: true + tags: | + ${{ env.DOCKER_TAG }} + cache-from: type=gha + cache-to: type=gha,mode=min + if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) + + build-base: + needs: stages + runs-on: ubuntu-latest + env: + BUILD_CACHE: /home/runner/.docker/buildkit + strategy: + matrix: + variant: + - standard + - ABCD-HCP + - fMRIPrep-LTS + steps: + - name: Maximize build space + uses: easimon/maximize-build-space@v4 + with: + remove-dotnet: 'true' + remove-android: 'true' + remove-haskell: 'true' + overprovision-lvm: 'true' + - name: Check out C-PAC (depth 0) + if: github.event.inputs.base_ref != '' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Check out C-PAC (depth 2) + if: github.event.inputs.base_ref == '' + uses: actions/checkout@v2 + with: + fetch-depth: 2 + - name: Prep source files + run: | + sed -i -e 's/^/\.github\/Dockerfiles\//' .github/stage_requirements/${{ matrix.variant }}.txt + echo 'dev/docker_data/required_afni_pkgs.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt + echo '.github/workflows/build_stages.yml' >> .github/stage_requirements/${{ matrix.variant }}.txt + echo '.github/stage_requirements/${{ matrix.variant }}.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt + - name: Get changed files since fork point + uses: tj-actions/changed-files@v41.0.0 + if: github.event.inputs.base_ref != '' + id: changed-files-base + with: + use_fork_point: "true" + files_from_source_file: | + .github/stage_requirements/${{ matrix.variant }}.txt + - name: Get changed files since last commit + uses: tj-actions/changed-files@v41.0.0 + if: github.event.inputs.base_ref == '' + id: changed-files + with: + since_last_remote_commit: "true" + files_from_source_file: | + .github/stage_requirements/${{ matrix.variant }}.txt + - name: Set tag & see if it exists + continue-on-error: true + run: | + TAG="stage-base:${{ matrix.variant }}-$(cat version)" + DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') + echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV + docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT + id: docker_tag + - name: Clear up some space on runner + if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2.2.1 + if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 + - name: Prep Dockerfiles for forked repository + if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 + run: | + .github/scripts/local_ghcr .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile ${{ github.repository_owner }} $DOCKER_TAG + cat .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile + - name: See Dockerfile + run: cat .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile + if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 + - name: Build and push base image + uses: docker/build-push-action@v3.2.0 + with: + context: . + file: .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile + push: true + tags: | + ${{ env.DOCKER_TAG }} + cache-from: type=gha + cache-to: type=gha,mode=min + if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 + + trigger-next-workflow: + needs: build-base + runs-on: ubuntu-latest + steps: + - name: Check out C-PAC + uses: actions/checkout@v2 + with: + fetch-depth: 2 + - name: Build and test C-PAC + run: gh workflow run build_and_test.yml --ref ${GITHUB_REF_NAME} + env: + GITHUB_TOKEN: ${{ secrets.ACTIONS_WORKFLOW_TOKEN }} From ceb4972ee99c4859cf98471815099b7bed8f646c Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 2 Jan 2024 13:23:35 -0500 Subject: [PATCH 149/213] =?UTF-8?q?:arrow=5Fup:=20Bump=20`tj-actions/chang?= =?UTF-8?q?ed-files`=20v35.7.6=20=E2=86=92=20v41.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/on_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index c4a5ceacd4..1a957dc6b7 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -105,7 +105,7 @@ jobs: git push origin HEAD:${GITHUB_BRANCH} || true fi - name: Get changed files since last commit - uses: tj-actions/changed-files@v35.7.6 + uses: tj-actions/changed-files@v41.0.0 id: changed-files with: since_last_remote_commit: "true" From bd680a9197d455800c55b7dd7ae5ad374685ba76 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Thu, 11 Jan 2024 21:38:11 -0500 Subject: [PATCH 150/213] :bookmark: Tag version in changelog [skip ci] --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ba39f391d..aa9d4c4ff2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [unreleased] +## [1.8.6] ## Added @@ -100,7 +100,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `voluptuous` 0.12.0 → 0.13.1 - `wb_command` neurodebian latest → 1.5.0 -## [1.8.5] +## [1.8.5] - 2023-05-24 ### Added @@ -272,7 +272,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 See [Version 1.8.1 Beta](https://fcp-indi.github.io/docs/user/release_notes/v1.8.1) for release notes for v1.8.1 and [Release Notes](https://fcp-indi.github.io/docs/user/release_notes) for all release notes back to v0.1.1. -[unreleased]: https://github.com/FCP-INDI/C-PAC/compare/v1.8.4...develop +[1.8.6]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.6 +[1.8.5]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.5 [1.8.4]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.4 [1.8.3]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.3 [1.8.2]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.2 From 778156fdab28f48141294b14d5b437e55f37dc5e Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 12 Jan 2024 18:08:47 -0500 Subject: [PATCH 151/213] :bookmark: Set version to 1.8.6rc1 --- CPAC/info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index 5bc8b8153f..bac96de15b 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -43,7 +43,7 @@ _version_major = 1 _version_minor = 8 _version_micro = 6 -_version_extra = 'dev' +_version_extra = 'rc1' def get_cpac_gitversion(): @@ -90,7 +90,7 @@ def get_cpac_gitversion(): _version_micro) if _version_extra: - __version__ += ".%s" % _version_extra + __version__ += "%s" % _version_extra ga_tracker = 'UA-19224662-10' From fb82c6631d55b8fa06d1a50b94f38fa7158ebb1e Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 12 Jan 2024 18:22:45 -0500 Subject: [PATCH 152/213] :package: Update main Dockerfiles from develop --- Dockerfile | 40 ++++++++++++++++++++++---- variant-ABCD-HCP.Dockerfile | 23 +++++++++------ variant-fMRIPrep-LTS.Dockerfile | 27 ++++++++++------- variant-lite.Dockerfile | 51 +++++++++++++++++++++++++++++---- 4 files changed, 112 insertions(+), 29 deletions(-) diff --git a/Dockerfile b/Dockerfile index ba5b156363..d67bbfabdf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,31 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.5.dev +# Copyright (C) 2022-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # install C-PAC COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code -RUN pip install -e /code +RUN pip cache purge && pip install -e /code # set up runscript COPY dev/docker_data /code/docker_data -RUN rm -Rf /code/docker_data/Dockerfiles && \ +RUN rm -Rf /code/docker_data/checksum && \ mv /code/docker_data/* /code && \ rm -Rf /code/docker_data && \ chmod +x /code/run.py && \ @@ -16,9 +33,20 @@ RUN rm -Rf /code/docker_data/Dockerfiles && \ ENTRYPOINT ["/code/run-with-freesurfer.sh"] # link libraries & clean up -RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ - ldconfig && \ - chmod 777 $(ls / | grep -v sys | grep -v proc) +# link libraries & clean up +RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /root/.cache/* \ + && find / -type f -print0 | sort -t/ -k2 | xargs -0 rdfind -makehardlinks true \ + && rm -rf results.txt \ + && apt-get remove rdfind -y \ + && apt-get clean \ + && apt-get autoremove -y \ + && ldconfig \ + && chmod 777 / \ + && chmod 777 $(ls / | grep -v sys | grep -v proc) +ENV PYTHONUSERBASE=/home/c-pac_user/.local +ENV PATH=$PATH:/home/c-pac_user/.local/bin \ + PYTHONPATH=$PYTHONPATH:$PYTHONUSERBASE/lib/python3.10/site-packages # set user +WORKDIR /home/c-pac_user # USER c-pac_user diff --git a/variant-ABCD-HCP.Dockerfile b/variant-ABCD-HCP.Dockerfile index 73381a21ee..9fd301fb5b 100644 --- a/variant-ABCD-HCP.Dockerfile +++ b/variant-ABCD-HCP.Dockerfile @@ -1,14 +1,15 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.5.dev +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # install C-PAC COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code -RUN pip install -e /code +RUN pip cache purge && pip install -e /code # set up runscript COPY dev/docker_data /code/docker_data -RUN rm -Rf /code/docker_data/Dockerfiles && \ +RUN rm -Rf /code/docker_data/checksum && \ mv /code/docker_data/* /code && \ rm -Rf /code/docker_data && \ chmod +x /code/run.py && \ @@ -16,11 +17,17 @@ RUN rm -Rf /code/docker_data/Dockerfiles && \ ENTRYPOINT ["/code/run-with-freesurfer.sh"] # Link libraries for Singularity images -RUN ldconfig - -RUN apt-get clean && \ - apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +RUN ldconfig \ + && apt-get clean \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /root/.cache/pip/* \ + && chmod 777 / \ + && chmod -R 777 /home/c-pac_user \ + && chmod 777 $(ls / | grep -v sys | grep -v proc) +ENV PYTHONUSERBASE=/home/c-pac_user/.local +ENV PATH=$PATH:/home/c-pac_user/.local/bin \ + PYTHONPATH=$PYTHONPATH:$PYTHONUSERBASE/lib/python3.10/site-packages # set user +WORKDIR /home/c-pac_user # USER c-pac_user diff --git a/variant-fMRIPrep-LTS.Dockerfile b/variant-fMRIPrep-LTS.Dockerfile index 8e891ce2d7..539a4aed25 100644 --- a/variant-fMRIPrep-LTS.Dockerfile +++ b/variant-fMRIPrep-LTS.Dockerfile @@ -1,14 +1,15 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.5.dev +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root # install C-PAC & set up runscript COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml COPY . /code -RUN pip install -e /code +RUN pip cache purge && pip install -e /code # set up runscript COPY dev/docker_data /code/docker_data -RUN rm -Rf /code/docker_data/Dockerfiles && \ +RUN rm -Rf /code/docker_data/checksum && \ mv /code/docker_data/* /code && \ rm -Rf /code/docker_data && \ chmod +x /code/run.py && \ @@ -16,13 +17,19 @@ RUN rm -Rf /code/docker_data/Dockerfiles && \ ENTRYPOINT ["/code/run-with-freesurfer.sh"] # link libraries & clean up -RUN sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ - locale-gen && \ - apt-get clean && \ - apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ - ldconfig && \ - chmod 777 $(ls / | grep -v sys | grep -v proc) +RUN sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ + && locale-gen \ + && apt-get clean \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /root/.cache/pip/* \ + && ldconfig \ + && chmod 777 / \ + && chmod -R 777 /home/c-pac_user \ + && chmod 777 $(ls / | grep -v sys | grep -v proc) +ENV PYTHONUSERBASE=/home/c-pac_user/.local +ENV PATH=$PATH:/home/c-pac_user/.local/bin \ + PYTHONPATH=$PYTHONPATH:$PYTHONUSERBASE/lib/python3.10/site-packages # set user +WORKDIR /home/c-pac_user # USER c-pac_user diff --git a/variant-lite.Dockerfile b/variant-lite.Dockerfile index c6a9010778..427a12f628 100644 --- a/variant-lite.Dockerfile +++ b/variant-lite.Dockerfile @@ -1,12 +1,53 @@ -FROM ghcr.io/fcp-indi/c-pac:latest +# Copyright (C) 2022-2023 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" +LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root + +# install C-PAC +COPY dev/circleci_data/pipe-test_ci.yml /cpac_resources/pipe-test_ci.yml +COPY . /code +COPY --from=ghcr.io/fcp-indi/c-pac_templates:latest /cpac_templates /cpac_templates +RUN pip cache purge && pip install -e /code +# set up runscript +COPY dev/docker_data /code/docker_data +RUN rm -Rf /code/docker_data/checksum && \ + mv /code/docker_data/* /code && \ + rm -Rf /code/docker_data && \ + chmod +x /code/run.py && \ + rm -Rf /code/run-with-freesurfer.sh ENTRYPOINT ["/code/run.py"] -# remove FreeSurfer, link libraries & clean up -RUN rm -rf /usr/lib/freesurfer/ /code/run-with-freesurfer.sh /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ - ln -svf /usr/lib/x86_64-linux-gnu/libgsl.so.23 /usr/lib/x86_64-linux-gnu/libgsl.so.0 && ldconfig && \ - chmod 777 $(ls / | grep -v sys | grep -v proc) +# link libraries & clean up +# link libraries & clean up +RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /root/.cache/* \ + && find / -type f -print0 | sort -t/ -k2 | xargs -0 rdfind -makehardlinks true \ + && rm -rf results.txt \ + && apt-get remove rdfind -y \ + && apt-get clean \ + && apt-get autoremove -y \ + && ldconfig \ + && chmod 777 / \ + && chmod 777 $(ls / | grep -v sys | grep -v proc) +ENV PYTHONUSERBASE=/home/c-pac_user/.local +ENV PATH=$PATH:/home/c-pac_user/.local/bin \ + PYTHONPATH=$PYTHONPATH:$PYTHONUSERBASE/lib/python3.10/site-packages # set user +WORKDIR /home/c-pac_user # USER c-pac_user From cc77909d093d769c74817ae2417d36ac47b7105c Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally <113037677+e-kenneally@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:13:38 -0500 Subject: [PATCH 153/213] =?UTF-8?q?=F0=9F=94=96=20=20Set=20version=5Fextra?= =?UTF-8?q?=20to=20empty=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPAC/info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/info.py b/CPAC/info.py index bac96de15b..b038bb3b43 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -43,7 +43,7 @@ _version_major = 1 _version_minor = 8 _version_micro = 6 -_version_extra = 'rc1' +_version_extra = '' def get_cpac_gitversion(): From 16f5073595be018713c8e6a4873e473dc7fdd5d3 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 18:22:35 -0500 Subject: [PATCH 154/213] :bookmark: Bump version to v1.8.7.dev1 --- CHANGELOG.md | 9 ++++++--- CPAC/info.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9d4c4ff2..3005e5b41c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.8.6] +## [unreleased] -## Added +## [1.8.6] - 2023-01-15 + +### Added - Some automatic handling of user-provided BIDSy atlas names. - `sig_imports` static method decorator for `Function` nodes, to accommodate type hinting in signatures of `Function` node functions. @@ -26,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `switch_is_off`, `switch_is_on` and `switch_is_on_off` methods to `Configuration` class - `__repr__` and `__str__` methods to `ResourcePool`s and `NodeBlockFunction`s -## Fixed +### Fixed - Fixed a bug where some connectivity matrices wouldn't generate if anatomical and functional outputs were in different resolutions. - Handling of `3dECM` outputs for AFNI ≥ 21.1.1. @@ -272,6 +274,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 See [Version 1.8.1 Beta](https://fcp-indi.github.io/docs/user/release_notes/v1.8.1) for release notes for v1.8.1 and [Release Notes](https://fcp-indi.github.io/docs/user/release_notes) for all release notes back to v0.1.1. +[unreleased]: https://github.com/FCP-INDI/C-PAC/compare/v1.8.6...develop [1.8.6]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.6 [1.8.5]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.5 [1.8.4]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.4 diff --git a/CPAC/info.py b/CPAC/info.py index b038bb3b43..a6caf85750 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -42,8 +42,8 @@ # version _version_major = 1 _version_minor = 8 -_version_micro = 6 -_version_extra = '' +_version_micro = 7 +_version_extra = 'dev1' def get_cpac_gitversion(): From 0bb8c7639bceee7f97110848f3997328bab23d1f Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 12 Jan 2024 18:42:16 -0500 Subject: [PATCH 155/213] :technologist: Move autoversioning from CI to pre-commit --- .github/workflows/on_push.yml | 18 ------------- .pre-commit-config.yaml | 25 ++++++++++++++++++ scripts/autoversioning.sh | 49 +++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 scripts/autoversioning.sh diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 1a957dc6b7..3cbb294878 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -86,24 +86,6 @@ jobs: fi cd .. fi - if [[ "${GITHUB_REF_TYPE}" == "tag" ]] - then - cd $HOME/work/C-PAC/C-PAC - for DOCKERFILE in $(ls .github/Dockerfiles/C-PAC.develop-*.Dockerfile) - do - if [[ "$DOCKERFILE" =~ .*C-PAC.develop-(.*)-(bionic|xenial).Dockerfile ]] - then - cp $DOCKERFILE variant-${BASH_REMATCH[1]}.Dockerfile - else - cp $DOCKERFILE Dockerfile - fi - done - git add *ockerfile - git commit -m ":truck: Copy develop Dockerfiles to root directory \ - \ - [skip ci]" - git push origin HEAD:${GITHUB_BRANCH} || true - fi - name: Get changed files since last commit uses: tj-actions/changed-files@v41.0.0 id: changed-files diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..3fbb45c2bf --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,25 @@ +# Copyright (C) 2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . + +repos: + - repo: local + hooks: + - id: autoversioning + name: Update Dockerfiles and version comments + entry: scripts/autoversioning.sh + language: script + files: '.*Dockerfile$' diff --git a/scripts/autoversioning.sh b/scripts/autoversioning.sh new file mode 100644 index 0000000000..21177f2117 --- /dev/null +++ b/scripts/autoversioning.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright (C) 2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . + +# Update version comment strings +cd CPAC +VERSION=$(python -c "from info import __version__; print(('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__).split('+', 1)[0])") +cd .. +echo "v${VERSION}" > version +find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; +git add version +VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) +export PATTERN="(declare|typeset) -a" +if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] +then + for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") + do + export IFS="" + for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) + do + echo "Updating stage tags in ${DOCKERFILE}" + sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} + done + done + unset IFS +fi +git add CPAC/resources/configs .github/Dockerfiles + +# Overwrite top-level Dockerfiles with the CI Dockerfiles +cp .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile Dockerfile +cp .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile variant-ABCD-HCP.Dockerfile +cp .github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile variant-fMRIPrep-LTS.Dockerfile +cp .github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile variant-lite.Dockerfile +git add *Dockerfile \ No newline at end of file From ac8d4a4530ab9b98995df840e2bf23b4f50baf75 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 12 Jan 2024 18:42:16 -0500 Subject: [PATCH 156/213] :technologist: Move autoversioning from CI to pre-commit --- {scripts => .github/scripts}/autoversioning.sh | 0 .pre-commit-config.yaml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename {scripts => .github/scripts}/autoversioning.sh (100%) mode change 100644 => 100755 diff --git a/scripts/autoversioning.sh b/.github/scripts/autoversioning.sh old mode 100644 new mode 100755 similarity index 100% rename from scripts/autoversioning.sh rename to .github/scripts/autoversioning.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fbb45c2bf..beffa2686a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,6 @@ repos: hooks: - id: autoversioning name: Update Dockerfiles and version comments - entry: scripts/autoversioning.sh + entry: .github/scripts/autoversioning.sh language: script - files: '.*Dockerfile$' + files: '.*Dockerfile$|.*\.yaml$|^CPAC/info\.py$' From 1b50bb589ad1a329bdec9462e7224fbcefd82a5f Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 15:05:10 -0500 Subject: [PATCH 157/213] :bricks: Handle Mac OS `sed` differently from Linux `sed` --- .github/scripts/autoversioning.sh | 9 ++++++++- CPAC/info.py | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 2 +- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 2 +- .../configs/data_config_S3-BIDS-ADHD200_only2.yml | 2 +- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 2 +- CPAC/resources/configs/data_config_cpac_benchmark.yml | 2 +- CPAC/resources/configs/data_settings_template.yml | 2 +- CPAC/resources/configs/group_config_template.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-options.yml | 2 +- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 2 +- CPAC/resources/configs/pipeline_config_anat-only.yml | 2 +- .../resources/configs/pipeline_config_benchmark-ANTS.yml | 2 +- .../configs/pipeline_config_benchmark-FNIRT.yml | 2 +- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_ccs-options.yml | 2 +- .../configs/pipeline_config_default-deprecated.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- .../configs/pipeline_config_fmriprep-ingress.yml | 2 +- .../configs/pipeline_config_fmriprep-options.yml | 2 +- CPAC/resources/configs/pipeline_config_fx-options.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 2 +- CPAC/resources/configs/pipeline_config_monkey.yml | 2 +- CPAC/resources/configs/pipeline_config_ndmg.yml | 2 +- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 2 +- CPAC/resources/configs/pipeline_config_preproc.yml | 2 +- CPAC/resources/configs/pipeline_config_rbc-options.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-1.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-2.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-3.yml | 2 +- CPAC/resources/configs/pipeline_config_regtest-4.yml | 2 +- CPAC/resources/configs/pipeline_config_rodent.yml | 2 +- CPAC/resources/configs/system_config.yml | 2 +- .../configs/test_configs/data-test_S3-ADHD200_1.yml | 2 +- .../test_configs/data-test_S3-ADHD200_no-params.yml | 2 +- .../configs/test_configs/data-test_S3-NKI-RS_fmap.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 2 +- .../test_configs/data_config_S3_CoRR_5only_mult-sess.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_ABCD.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 2 +- .../test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 2 +- .../test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 2 +- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 2 +- .../test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 2 +- .../pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 2 +- .../test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 2 +- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 2 +- CPAC/resources/configs/test_configs/pipe-test_all.yml | 2 +- version | 2 +- 51 files changed, 58 insertions(+), 51 deletions(-) diff --git a/.github/scripts/autoversioning.sh b/.github/scripts/autoversioning.sh index 21177f2117..220d6af0a9 100755 --- a/.github/scripts/autoversioning.sh +++ b/.github/scripts/autoversioning.sh @@ -22,7 +22,14 @@ cd CPAC VERSION=$(python -c "from info import __version__; print(('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__).split('+', 1)[0])") cd .. echo "v${VERSION}" > version -find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; +export _SED_COMMAND="s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" +if [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + find ./CPAC/resources/configs -name "*.yml" -exec sed -i '' -E "${_SED_COMMAND}" {} \; +else + # Linux and others + find ./CPAC/resources/configs -name "*.yml" -exec sed -i'' -r "${_SED_COMMAND}" {} \; +fi git add version VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) export PATTERN="(declare|typeset) -a" diff --git a/CPAC/info.py b/CPAC/info.py index a6caf85750..a6beb47762 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -90,7 +90,7 @@ def get_cpac_gitversion(): _version_micro) if _version_extra: - __version__ += "%s" % _version_extra + __version__ += ".%s" % _version_extra ga_tracker = 'UA-19224662-10' diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index 66206c7df6..d674131633 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 7f3ba4eaa1..cae981cd9a 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 178836e7ea..0ef6d3ccf7 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index e49b7b9e80..77a62527e6 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 8cfc9fe519..15460d264c 100644 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 099c6d70e4..1d6c1b912e 100644 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,5 +1,5 @@ # CPAC Data Settings File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index ec0c1fe601..996c2386f0 100644 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,5 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index a604187cac..2e84020471 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 729c6761b4..7aee4e80ad 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 5d9d8c3212..d5334fcf08 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 85b0e4f729..29214c6685 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 38fd7b4a39..8fb774aa80 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index d99ff4ef53..7c4b19b802 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index 692d0876c3..61207908f0 100644 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 7e37da5390..9a11649dee 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 0ad367a48b..ef94cd0095 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml index fe785863cf..c65af74391 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index ace3bf98a5..adaf7bb5af 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 26fd4e42da..ade6c66940 100644 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index 7fadcb9e8f..b598e38df3 100644 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index ccf8e3b4bd..09bf8d48ef 100644 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 9474776ddc..70d27d8f7b 100644 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index cfaf86d5a8..bd4bb18b92 100644 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index cf8b0879ac..8326a41696 100644 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index f8943c73da..eb27e51c8e 100644 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index cc859fb347..867851efde 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 2cb42af05a..c00009687c 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index a5a6fd8948..c1ac7c6a77 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 248053327f..b512844c3a 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index 992d11e746..f829296a26 100644 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index 1053f9d26b..291adc19a9 100644 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,5 +1,5 @@ # C-PAC System Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml index 69e617cb32..97679f1f76 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml index 5a4c4c4677..3d1a4f46ca 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml index b01d43afcf..080595f840 100644 --- a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml +++ b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 10624b5022..0d428b0340 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml index b66a606cea..1d55f02e82 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml @@ -1,5 +1,5 @@ # CPAC Data Configuration File -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml index 9eea91c8bc..39023ec11d 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index d84362d815..e68f31d827 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 61d8d2186a..510e3a7ef9 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 8a546496c4..e6940dc729 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index d1c7ddd7b2..0e9e8f34c5 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index 8b0c36100e..3326d3427f 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index 45c76d2f7e..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 335bc4c6fb..b6feb9c42c 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,7 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -# Version 1.8.6.dev1 +# Version 1.8.7.dev1 # # http://fcp-indi.github.io for more info. # diff --git a/version b/version index efed3fdaf4..f4c717aa49 100644 --- a/version +++ b/version @@ -1 +1 @@ -v1.8.6.dev1 +v1.8.7.dev1 From 9e387ef08c6f2cbe70f11893565a4ea742068555 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 17:12:39 -0500 Subject: [PATCH 158/213] :fire: Remove CI autoversioning --- .github/workflows/on_push.yml | 51 ------------ dev/circleci_data/drop_version_bump_commits | 30 ------- .../drop_version_commits_back_to | 9 --- dev/circleci_data/override_version_tag_list | 81 ------------------- dev/circleci_data/prep_merge | 16 ---- 5 files changed, 187 deletions(-) delete mode 100755 dev/circleci_data/drop_version_bump_commits delete mode 100755 dev/circleci_data/drop_version_commits_back_to delete mode 100755 dev/circleci_data/override_version_tag_list delete mode 100755 dev/circleci_data/prep_merge diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 3cbb294878..60f6354dc5 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -35,57 +35,6 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 2 - - uses: actions/setup-python@v4 - with: - python-version: '3.9' - cache: 'pip' - - name: Check if version updated - id: version_updated - run: | - git config --global user.email "CMI_CPAC_Support@childmind.org" - git config --global user.name "Theodore (Machine User)" - GITHUB_BRANCH=$(echo ${GITHUB_REF} | cut -d '/' -f 3-) - export PYTHONPATH=$PWD - pip install -q wheel - pip install -q nipype numpy matplotlib pandas pathvalidate pytz pyyaml voluptuous - python ./CPAC/utils/configuration/yaml_template.py - if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] - then - git add CPAC/resources/configs - git commit -m ":bulb: Update comments based on default preconfig" - fi - COMMIT_MESSAGE=$(git log -1 --pretty=%B) - if [[ ! "$COMMIT_MESSAGE" == *"Update version to"* ]] - then - cd CPAC - VERSION=$(python -c "from info import __version__; print(('.'.join(('.'.join(__version__[::-1].split('-')[1].split('.')[1:])[::-1], __version__.split('-')[1])) if '-' in __version__ else __version__).split('+', 1)[0])") - cd .. - echo "v${VERSION}" > version - find ./CPAC/resources/configs -name "*.yml" -exec sed -i -r "s/^(# [Vv]ersion ).*$/# Version ${VERSION}/g" {} \; - git add version - VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) - export PATTERN="(declare|typeset) -a" - if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] - then - for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") - do - export IFS="" - for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) - do - echo "Updating stage tags in ${DOCKERFILE}" - sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} - done - done - unset IFS - fi - if [[ ! -z $(git diff origin/${GITHUB_BRANCH}) ]] - then - git add CPAC/resources/configs .github/Dockerfiles - git commit -m ":bookmark: Update version to ${VERSION} ($COMMIT_MESSAGE)" || true - git push origin HEAD:${GITHUB_BRANCH} || true - fi - cd .. - fi - name: Get changed files since last commit uses: tj-actions/changed-files@v41.0.0 id: changed-files diff --git a/dev/circleci_data/drop_version_bump_commits b/dev/circleci_data/drop_version_bump_commits deleted file mode 100755 index b72c7570b0..0000000000 --- a/dev/circleci_data/drop_version_bump_commits +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -""" -Helper to drop auto-tag commits back to a given SHA or branch name ($BASE_BRANCH). -""" -import os -import re - -from sys import argv, stdin - -if __name__ == '__main__': - if stdin.isatty and ( - len(argv) == 1 or (len(argv) > 1 and argv[1] in {'-h', '--help'}) - ): - print("""Usage: -Use `drop_version_commits_back_to` to just give a branch or SHA ($BASE_BRANCH) to drop version-tagging commits back to. - -Direct usage: -GIT_SEQUENCE_EDITOR=drop_version_bump_commits git rebase -X ours -i $BASE_BRANCH --empty drop""") - else: - todo_path = os.path.join( - os.getcwd(), '.git', 'rebase-merge', 'git-rebase-todo' - ) - with open(todo_path, 'r') as etd: - todo = etd.read() - - with open(todo_path, 'w') as etd: - etd.write(re.sub( - r"^pick(?=.*\:bookmark\: Update version to.*)", - 'drop', todo, flags=re.MULTILINE - )) diff --git a/dev/circleci_data/drop_version_commits_back_to b/dev/circleci_data/drop_version_commits_back_to deleted file mode 100755 index bd1f105a75..0000000000 --- a/dev/circleci_data/drop_version_commits_back_to +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Helper script to prepare for merging. Takes the branch name or SHA of the merge base ($BASE_BRANCH).. -if [[ $# -eq 0 || "$1" == "-h" || "$1" == "--help" ]] - then - echo "Usage: drop_version_commits_back_to \$BASE_BRANCH" -else - GIT_SEQUENCE_EDITOR="${BASH_SOURCE%/*}/drop_version_bump_commits" git rebase -X ours -i $1 --empty drop -fi -exit 0 diff --git a/dev/circleci_data/override_version_tag_list b/dev/circleci_data/override_version_tag_list deleted file mode 100755 index cc49c6287d..0000000000 --- a/dev/circleci_data/override_version_tag_list +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -""" -Helper for CI handling of auto-tagged version info. Leaves version-tagged files with other changes. -""" -import re - -from sys import argv, stdin - - -def file_diffs(x): - """ - Takes a git diff --stat (plain text) and returns a list of 2-tuples - of (filename, diff_stat) - - Parameters - ---------- - x : str - git diff --stat output - - Returns - ------- - file_diff_stats : list - of 2-tuples of (filename, diff_stat) - """ - return [ - tuple([ - z.strip() for z in y.split('|') - ]) for y in x.strip().split('\n')[:-1] - ] - - -def overwrite_list(file_diff_stats): - """ - Parameters - ---------- - file_diff_stats : list - of 2-tuples of (filename, diff_stat) - - Returns - ------- - set - of strings - """ - config_pattern = 'CPAC/resources/configs/.*\.yml$' - s = set() - return { - fd[0] for fd in file_diff_stats if (( - re.match(config_pattern, fd[0]) or - fd[0] in { - 'version' - } - ) and fd[1] == '2 +-') - } - - -def print_checkout_file_list(git_diff_stat): - """ - Parameters - ---------- - git_diff_stat : str - git diff --stat output - - Returns - ------- - str - space-delimited list of filepaths to checkout from base branch - """ - print(' '.join(overwrite_list(file_diffs(git_diff_stat)))) - - -if __name__ == '__main__': - if ( - len(argv) > 1 and argv[1] in {'-h', '--help'} - ) or stdin.isatty(): - print("""Usage: -Use `prep_merge` to just give a branch or SHA to prep merging onto. - -Direct usage: -git diff enh/nested_config --stat=99999 | override_version_tag_list""") - else: - print_checkout_file_list(stdin.read()) diff --git a/dev/circleci_data/prep_merge b/dev/circleci_data/prep_merge deleted file mode 100755 index 474870b0f2..0000000000 --- a/dev/circleci_data/prep_merge +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# Helper script to prepare for merging. Takes the branch name or SHA of the merge base ($BASE_BRANCH).. -if [[ $# -eq 0 || "$1" == "-h" || "$1" == "--help" ]] - then - echo "Usage: prep_merge \$BASE_BRANCH" -else - CIRCLECI_DATA=$(dirname $0) - FILES_TO_REVERT=$(git diff $1 --stat=999999 | $CIRCLECI_DATA/override_version_tag_list) - if [[ -n $FILES_TO_REVERT ]] - then - echo "git checkout $1 -- $FILES_TO_REVERT" - git checkout $1 -- $FILES_TO_REVERT - git commit -m ":twisted_rightwards_arrows: Prep for merging" - fi -fi -exit 0 From 0776366e6e7f0a71f7bf19216abff807c5a0e7c3 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 18:09:18 -0500 Subject: [PATCH 159/213] :memo: Add "pre-commit" section to `CONTRIBUTING.md` --- .markdownlint.yml | 4 ++++ CONTRIBUTING.md | 30 +++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.markdownlint.yml b/.markdownlint.yml index 65bcc1be4c..2b6d69e558 100644 --- a/.markdownlint.yml +++ b/.markdownlint.yml @@ -20,3 +20,7 @@ MD013: false # no duplicate headers MD024: siblings_only: true +# allow specific inline HTML elements +MD033: + allowed_elements: + - span \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3f3069719..54dcc1328f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ - + +# CONTRIBUTING + +## pre-commit + +This project uses [pre-commit](https://pre-commit.com/), a framework for managing and maintaining git hooks. Pre-commit can be used to manage the hooks that run on every commit to automatically point out issues in code such as missing semicolons, trailing whitespace, and debug statements. By using these hooks, you can ensure code quality and prevent bad code from being uploaded. + +To install `pre-commit`, you can use `pip`: + +```bash +pip install pre-commit +``` + +After installation, you can set up your git hooks with this command at the root of this repository: + +```bash +pre-commit install +``` + +This will add a pre-commit script to your `.git/hooks/` directory. This script will run whenever you run `git commit`. + +For more details on how to configure and use pre-commit, please refer to the official documentation. + ## Git branches, tags and continuous integration + GitHub Actions builds C-PAC images for each branch and tag pushed to GitHub; these images are pushed to [GHCR](https://github.com/FCP-INDI/C-PAC/pkgs/container/c-pac/versions) and deleted upon branch deletion on GitHub. If a commit is pushed or merged into [`develop` on GitHub](https://github.com/FCP-INDI/C-PAC/tree/develop), GitHub Actions will push [`nightly` and its variants to Docker Hub](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=nightly). If a tag is pushed to GitHub that matches the regular expression + ```Regular Expression ^v[0-9]+\.[0-9]+\.[0-9]+$ ``` + GitHub Actions will push [`release-${TAG}` and its variants](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=release-) and [`latest` and its variants to Docker Hub](https://hub.docker.com/repository/registry-1.docker.io/fcpindi/c-pac/tags?page=1&ordering=last_updated&name=latest). ## Software dependencies and variant images + We currently have one main and 3 variant images: + * `ABCD-HCP`: dependency versions matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/releases/tag/v0.1.1) versions * `fMRIPrep-LTS`: dependency versions matched to [fMRIPrep Long-term support](https://reproducibility.stanford.edu/fmriprep-lts/) versions * `lite`: same dependency versions as main image without FreeSurfer (smaller image) From bc91060f84118bc8461e12e7eb6191ed7bfc6777 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Mon, 15 Jan 2024 18:15:43 -0500 Subject: [PATCH 160/213] :memo: Add autoversioning pre-commit to CHANGELOG --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3005e5b41c..02d93e7bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] -## [1.8.6] - 2023-01-15 +## Changed -### Added +- Moved autoversioning from CI to pre-commit + +## [1.8.6] - 2024-01-15 + +## Added - Some automatic handling of user-provided BIDSy atlas names. - `sig_imports` static method decorator for `Function` nodes, to accommodate type hinting in signatures of `Function` node functions. From 6398a352f42b37de0016635773d821db9e3c6a2b Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 00:43:49 -0500 Subject: [PATCH 161/213] :pencil2: Fix gitversion for PEP440 --- CPAC/info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/info.py b/CPAC/info.py index a6beb47762..7002a07b14 100644 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -82,7 +82,7 @@ def get_cpac_gitversion(): if 'dev' in _version_extra: gitversion = get_cpac_gitversion() if gitversion: - _version_extra = f'dev1+{gitversion}' + _version_extra = f'{_version_extra}+{gitversion}' __version__ = "%s.%s.%s" % (_version_major, From e98cf5267e18fc4523db0d6379f91f554b58d8ac Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 00:46:23 -0500 Subject: [PATCH 162/213] :necktie: Don't rely on `${GITHUB_BRANCH}` locally --- .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- .../C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .github/Dockerfiles/C-PAC.develop-jammy.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- .github/scripts/autoversioning.sh | 12 +++++++++--- Dockerfile | 2 +- variant-ABCD-HCP.Dockerfile | 2 +- variant-fMRIPrep-LTS.Dockerfile | 2 +- variant-lite.Dockerfile | 2 +- 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 9fd301fb5b..2a5760ebb7 100644 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index 539a4aed25..0e9cd3d899 100644 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile index d67bbfabdf..f9ced12d7b 100644 --- a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile index 427a12f628..1f6f3a9ec9 100644 --- a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index a03fd9a75a..2d0d51ab76 100644 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-jammy as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC diff --git a/.github/scripts/autoversioning.sh b/.github/scripts/autoversioning.sh index 220d6af0a9..0543f626a1 100755 --- a/.github/scripts/autoversioning.sh +++ b/.github/scripts/autoversioning.sh @@ -31,17 +31,23 @@ else find ./CPAC/resources/configs -name "*.yml" -exec sed -i'' -r "${_SED_COMMAND}" {} \; fi git add version -VERSIONS=($(git diff origin/${GITHUB_BRANCH} -- version | tail -n 2)) +VERSIONS=( `git show $(git log --pretty=format:'%h' -n 2 version | tail -n 1):version` `cat version` ) export PATTERN="(declare|typeset) -a" if [[ "$(declare -p VERSIONS)" =~ $PATTERN ]] then for DOCKERFILE in $(find ./.github/Dockerfiles -name "*.Dockerfile") do export IFS="" - for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]:1}" ${DOCKERFILE}) + for LINE in $(grep "FROM ghcr\.io/fcp\-indi/c\-pac/.*\-${VERSIONS[0]}" ${DOCKERFILE}) do echo "Updating stage tags in ${DOCKERFILE}" - sed -i "s/\-${VERSIONS[0]:1}/\-${VERSIONS[1]:1}/g" ${DOCKERFILE} + if [[ "$OSTYPE" == "darwin"* ]]; then + # Mac OSX + sed -i "" "s/\-${VERSIONS[0]}/\-${VERSIONS[1]}/g" ${DOCKERFILE} + else + # Linux and others + sed -i "s/\-${VERSIONS[0]}/\-${VERSIONS[1]}/g" ${DOCKERFILE} + fi done done unset IFS diff --git a/Dockerfile b/Dockerfile index d67bbfabdf..f9ced12d7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/variant-ABCD-HCP.Dockerfile b/variant-ABCD-HCP.Dockerfile index 9fd301fb5b..2a5760ebb7 100644 --- a/variant-ABCD-HCP.Dockerfile +++ b/variant-ABCD-HCP.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/variant-fMRIPrep-LTS.Dockerfile b/variant-fMRIPrep-LTS.Dockerfile index 539a4aed25..0e9cd3d899 100644 --- a/variant-fMRIPrep-LTS.Dockerfile +++ b/variant-fMRIPrep-LTS.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/variant-lite.Dockerfile b/variant-lite.Dockerfile index 427a12f628..1f6f3a9ec9 100644 --- a/variant-lite.Dockerfile +++ b/variant-lite.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6.dev1 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root From 218dd69ab0540afa271a0f7c73b5b9a378e1d2dd Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 01:18:15 -0500 Subject: [PATCH 163/213] :art: DRY docs URL --- CPAC/__init__.py | 47 +++++++++++++++++++++++------------------ CPAC/pipeline/schema.py | 6 +++--- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/CPAC/__init__.py b/CPAC/__init__.py index 0c14612ed9..c2d0828353 100644 --- a/CPAC/__init__.py +++ b/CPAC/__init__.py @@ -1,3 +1,19 @@ +# Copyright (C) 2022-2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . """ Configurable Pipeline for the Analysis of Connectomes ===================================================== @@ -5,33 +21,22 @@ CPAC is a configurable, open-source, Nipype-based, automated processing pipeline for resting state functional MRI (R-fMRI) data, for use by both novice and expert users. +""" -Copyright (C) 2022 C-PAC Developers - -This file is part of C-PAC. +from .info import __version__ +version = __version__ -C-PAC is free software: you can redistribute it and/or modify it under -the terms of the GNU Lesser General Public License as published by the -Free Software Foundation, either version 3 of the License, or (at your -option) any later version. -C-PAC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. +def _docs_prefix() -> str: + """Get the docs URL prefix for this version""" + from CPAC.utils.docs import DOCS_URL_PREFIX + return DOCS_URL_PREFIX -You should have received a copy of the GNU Lesser General Public -License along with C-PAC. If not, see . -""" -from .info import __version__ -version = __version__ -_url_version = 'nightly' if __version__.endswith( - '-dev') or __version__.endswith('.dev') else f'v{__version__.lstrip("v")}' -docs_prefix = f'https://fcp-indi.github.io/docs/{_url_version}' -license_notice = f"""Copyright (C) 2022 C-PAC Developers. +license_notice = f"""Copyright (C) 2022-2024 C-PAC Developers. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. For -details, see {docs_prefix}/license or the COPYING and +details, see {_docs_prefix()}/license or the COPYING and COPYING.LESSER files included in the source code.""" +__all__ = ['license_notice', 'version', '__version__'] diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 5b037de003..f24598dde2 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022 C-PAC Developers +# Copyright (C) 2022-2024 C-PAC Developers # This file is part of C-PAC. @@ -25,8 +25,8 @@ Coerce, CoerceInvalid, ExclusiveInvalid, In, Length, \ LengthInvalid, Lower, Match, Maybe, MultipleInvalid, \ Optional, Range, Required, Schema, Title -from CPAC import docs_prefix from CPAC.utils.datatypes import ItemFromList, ListFromItem +from CPAC.utils.docs import DOCS_URL_PREFIX from CPAC.utils.utils import YAML_BOOLS # 1 or more digits, optional decimal, 'e', optional '-', 1 or more digits @@ -249,7 +249,7 @@ def str_to_bool1_1(x): # pylint: disable=invalid-name Required('lowpass_cutoff'): Number, 'Name': Maybe(str)}, msg='`motion_estimate_filter` configuration is invalid.\nSee ' - f'{docs_prefix}/user/' + f'{DOCS_URL_PREFIX}/user/' 'func#motion-estimate-filter-valid-options for details.\n') target_space = All(Coerce(ListFromItem), [All(Title, In(valid_options['target_space']))]) From 35ffb859a4ffaf3946d96cd609f7c29afab3eb26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:04:26 +0000 Subject: [PATCH 164/213] :arrow_up: Bump cryptography from 41.0.1 to 41.0.6 Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.1 to 41.0.6. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.1...41.0.6) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ac6a0e894b..1a5f1d5e41 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ voluptuous==0.13.1 # the below are pinned specifically to match what the FSL installer installs botocore==1.31.4 charset-normalizer==3.1.0 -cryptography==41.0.1 +cryptography==41.0.6 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 From 96b84a24d48e5f7039159dcdd1a8e981308a2e3c Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 26 Jan 2024 18:03:37 -0500 Subject: [PATCH 165/213] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20urllib3=20f?= =?UTF-8?q?rom=201.26.15=20to=201.26.18=20(#2044)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1a5f1d5e41..e9dffcf342 100644 --- a/requirements.txt +++ b/requirements.txt @@ -46,6 +46,6 @@ importlib-metadata==6.8.0 lxml==4.9.2 pip==23.1.2 setuptools==68.0.0 -urllib3==1.26.15 +urllib3==1.26.18 wheel==0.40.0 zipp==3.16.0 From b2c45f527e88c4656d44761b4f7ee8b166cc613c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 20:04:59 +0000 Subject: [PATCH 166/213] :arrow_up: Bump pip from 23.1.2 to 23.3 Bumps [pip](https://github.com/pypa/pip) from 23.1.2 to 23.3. - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/23.1.2...23.3) --- updated-dependencies: - dependency-name: pip dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e9dffcf342..55a9ce8af0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,7 +44,7 @@ cryptography==41.0.6 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 -pip==23.1.2 +pip==23.3 setuptools==68.0.0 urllib3==1.26.18 wheel==0.40.0 From 45dfb59ecf341c56b79213edddddd6a565aab6ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 02:27:03 +0000 Subject: [PATCH 167/213] :arrow_up: Bump cryptography from 41.0.1 to 42.0.0 Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.1 to 42.0.0. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.1...42.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 55a9ce8af0..52faa11710 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ voluptuous==0.13.1 # the below are pinned specifically to match what the FSL installer installs botocore==1.31.4 charset-normalizer==3.1.0 -cryptography==41.0.6 +cryptography==42.0.0 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 From 77555504ea7774896d03626bbb2b041b3046d1a6 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Wed, 22 Nov 2023 11:12:28 -0500 Subject: [PATCH 168/213] dvars output added in cpac_outputs.tsv --- CPAC/resources/cpac_outputs.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index db3c5aaffd..d43ecffce8 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -100,7 +100,7 @@ space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI motion motion func TSV desc-summary_motion motion func TSV -dvars motion func TSV Yes +dvars motion func TSV Yes motion-filter-plot motion func png desc-movementParameters_motion motion func TSV desc-movementParametersUnfiltered_motion motion func TSV From b6fcf81f8095b87f6dc16e739922e9d8c2d58350 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 27 Nov 2023 23:22:02 -0500 Subject: [PATCH 169/213] default config -write_debugging_outputs: True --- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index ef94cd0095..9a1651a8a0 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -42,7 +42,7 @@ pipeline_setup: write_func_outputs: False # Include extra outputs in the output directory that may be of interest when more information is needed. - write_debugging_outputs: False + write_debugging_outputs: True # Output directory format and structure. # Options: default, ndmg From 7b3322b8b0771fcafbbd3a97f10e17d1720767be Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 27 Nov 2023 23:50:23 -0500 Subject: [PATCH 170/213] default config restored back to original --- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 9a1651a8a0..ef94cd0095 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -42,7 +42,7 @@ pipeline_setup: write_func_outputs: False # Include extra outputs in the output directory that may be of interest when more information is needed. - write_debugging_outputs: True + write_debugging_outputs: False # Output directory format and structure. # Options: default, ndmg From e2b18ed153c245ec781f02987446b32551463c7b Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Mon, 18 Dec 2023 01:42:55 -0500 Subject: [PATCH 171/213] Update CPAC/resources/cpac_outputs.tsv Co-authored-by: Jon Clucas --- CPAC/resources/cpac_outputs.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index d43ecffce8..db3c5aaffd 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -100,7 +100,7 @@ space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI motion motion func TSV desc-summary_motion motion func TSV -dvars motion func TSV Yes +dvars motion func TSV Yes motion-filter-plot motion func png desc-movementParameters_motion motion func TSV desc-movementParametersUnfiltered_motion motion func TSV From 7c39ad2534f790034c1d8e59d68e1e76dbdf5516 Mon Sep 17 00:00:00 2001 From: Biraj Date: Thu, 8 Feb 2024 23:47:19 +0000 Subject: [PATCH 172/213] :package: Added dvars as optional output --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02d93e7bd3..821033425b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Changed - Moved autoversioning from CI to pre-commit +- Added `dvars` as optional output in `cpac_outputs` ## [1.8.6] - 2024-01-15 From bfb30088f60e2719eb1a9b55f63f9e9c048677b8 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:54:40 -0500 Subject: [PATCH 173/213] Update CHANGELOG.md Co-authored-by: Jon Clucas --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66440ac149..fd201f6363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,7 +196,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated CI to only rebuild software dependencies on change - Replaced deprecated `optparse.OptionError` with to `click.BadParameter` - Relicensed C-PAC from BSD-3-Clause to LGPL-3.0-or-later -- Updated `FSL-BET` config to default `-mask-boolean` flag as on, and removed all removed `mask-boolean` keys from configs. ### Fixed From f8218649a6ff1c44df810d18915aae053ed96519 Mon Sep 17 00:00:00 2001 From: Biraj Date: Fri, 9 Feb 2024 16:19:40 +0000 Subject: [PATCH 174/213] Revert "Bump tj-actions/changed-files in /.github/workflows" This reverts commit 6749392ae4c511d3f797408603063733fdac3368. --- .github/workflows/build_stages.yml | 288 ----------------------------- 1 file changed, 288 deletions(-) delete mode 100644 .github/workflows/build_stages.yml diff --git a/.github/workflows/build_stages.yml b/.github/workflows/build_stages.yml deleted file mode 100644 index 4a705f3b36..0000000000 --- a/.github/workflows/build_stages.yml +++ /dev/null @@ -1,288 +0,0 @@ -# Requires secret `ACTIONS_WORKFLOW_TOKEN` with `workflow` scope - -name: Build stages - -on: - workflow_dispatch: - inputs: - base_ref: - description: 'Base reference if triggered by a pull request' - required: false - default: "" - - -jobs: - update-check: - name: Update GitHub check - runs-on: ubuntu-latest - steps: - - name: Update check's target URL - uses: Sibz/github-status-action@v1.1.6 - with: - authToken: ${{ secrets.ACTIONS_WORKFLOW_TOKEN }} - context: "Build C-PAC images" - state: pending - target_url: ${{ github.server_url }}/${{ github.repository}}/actions/runs/${{ github.run_id }} - - Ubuntu: - name: Build C-PAC Ubuntu - needs: - - update-check - strategy: - matrix: - Dockerfile: - - Ubuntu.bionic-non-free - - Ubuntu.xenial-20200114 - runs-on: ubuntu-latest - steps: - - name: Check out C-PAC (depth 0) - if: github.event.inputs.base_ref != '' - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Check out C-PAC (depth 2) - if: github.event.inputs.base_ref == '' - uses: actions/checkout@v2 - with: - fetch-depth: 2 - - name: Get changed files since fork point - uses: tj-actions/changed-files@v41.0.0 - if: github.event.inputs.base_ref != '' - id: changed-files-base - with: - use_fork_point: "true" - files: .github/Dockerfiles/* - - name: Get changed files since last commit - uses: tj-actions/changed-files@v41.0.0 - if: github.event.inputs.base_ref == '' - id: changed-files - with: - since_last_remote_commit: "true" - files: .github/Dockerfiles/* - - name: Set tag & see if it exists - continue-on-error: true - run: | - TAG=$(sed 's/\./:/' <(echo ${{ matrix.Dockerfile }})) - DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') - echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV - docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.2.1 - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) - - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) - - name: Build and push Docker image - uses: docker/build-push-action@v3.2.0 - with: - file: .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile - push: true - tags: | - ${{ env.DOCKER_TAG }} - cache-from: type=gha - cache-to: type=gha,mode=min - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) - - stages: - name: Build Docker stage images - needs: Ubuntu - strategy: - matrix: - Dockerfile: - - AFNI.16.2.07.neurodocker-xenial - - AFNI.21.1.00-bionic - - ANTs.2.2.0.neurodocker-bionic - - c3d.1.0.0-xenial - - connectome-workbench.1.3.2-1.neurodebian-bionic - - connectome-workbench.1.3.2-2.neurodebian-xenial - - FSL.5.0.9-5.neurodebian-xenial - - FSL.5.0.10-bionic - - ICA-AROMA.0.4.5-xenial - - msm.2.0-bionic - runs-on: ubuntu-latest - steps: - - name: Check out C-PAC (depth 0) - if: github.event.inputs.base_ref != '' - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Check out C-PAC (depth 2) - if: github.event.inputs.base_ref == '' - uses: actions/checkout@v2 - with: - fetch-depth: 2 - - name: Get changed files since fork point - uses: tj-actions/changed-files@v41.0.0 - if: github.event.inputs.base_ref != '' - id: changed-files-base - with: - use_fork_point: "true" - files: | - dev/docker_data/required_afni_pkgs.txt - .github/Dockerfiles/* - - name: Get changed files since last commit - uses: tj-actions/changed-files@v41.0.0 - if: github.event.inputs.base_ref == '' - id: changed-files - with: - since_last_remote_commit: "true" - files: | - dev/docker_data/required_afni_pkgs.txt - .github/Dockerfiles/* - - name: Clear up some space on runner - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.2.1 - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - - name: Set tag & see if it exists - continue-on-error: true - run: | - TAG=$(sed 's/\./:/' <(echo ${{ matrix.Dockerfile }})) - DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') - echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV - docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - - name: Prep Dockerfiles for forked repository - if: github.repository_owner != 'FCP-INDI' && contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - run: | - .github/scripts/local_ghcr .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile ${{ github.repository_owner }} $DOCKER_TAG - cat .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile - - name: See Dockerfile - run: cat .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - - name: Build and push Docker image - uses: docker/build-push-action@v3.2.0 - with: - context: . - file: .github/Dockerfiles/${{ matrix.Dockerfile }}.Dockerfile - push: true - tags: | - ${{ env.DOCKER_TAG }} - cache-from: type=gha - cache-to: type=gha,mode=min - if: contains(steps.changed-files-base.outputs.all_changed_files, matrix.Dockerfile) || contains(steps.changed-files.outputs.all_changed_files, matrix.Dockerfile) || (startsWith(matrix.Dockerfile, 'AFNI') && (contains(steps.changed-files.outputs.all_changed_files, 'dev/docker_data/required_afni_pkgs.txt'))) - - build-base: - needs: stages - runs-on: ubuntu-latest - env: - BUILD_CACHE: /home/runner/.docker/buildkit - strategy: - matrix: - variant: - - standard - - ABCD-HCP - - fMRIPrep-LTS - steps: - - name: Maximize build space - uses: easimon/maximize-build-space@v4 - with: - remove-dotnet: 'true' - remove-android: 'true' - remove-haskell: 'true' - overprovision-lvm: 'true' - - name: Check out C-PAC (depth 0) - if: github.event.inputs.base_ref != '' - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Check out C-PAC (depth 2) - if: github.event.inputs.base_ref == '' - uses: actions/checkout@v2 - with: - fetch-depth: 2 - - name: Prep source files - run: | - sed -i -e 's/^/\.github\/Dockerfiles\//' .github/stage_requirements/${{ matrix.variant }}.txt - echo 'dev/docker_data/required_afni_pkgs.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt - echo '.github/workflows/build_stages.yml' >> .github/stage_requirements/${{ matrix.variant }}.txt - echo '.github/stage_requirements/${{ matrix.variant }}.txt' >> .github/stage_requirements/${{ matrix.variant }}.txt - - name: Get changed files since fork point - uses: tj-actions/changed-files@v41.0.0 - if: github.event.inputs.base_ref != '' - id: changed-files-base - with: - use_fork_point: "true" - files_from_source_file: | - .github/stage_requirements/${{ matrix.variant }}.txt - - name: Get changed files since last commit - uses: tj-actions/changed-files@v41.0.0 - if: github.event.inputs.base_ref == '' - id: changed-files - with: - since_last_remote_commit: "true" - files_from_source_file: | - .github/stage_requirements/${{ matrix.variant }}.txt - - name: Set tag & see if it exists - continue-on-error: true - run: | - TAG="stage-base:${{ matrix.variant }}-$(cat version)" - DOCKER_TAG=$(echo "ghcr.io/${{ github.repository }}/$TAG" | tr '[:upper:]' '[:lower:]') - echo DOCKER_TAG=$DOCKER_TAG >> $GITHUB_ENV - docker manifest inspect $DOCKER_TAG >/dev/null || echo "not_yet_exists=1" >> $GITHUB_OUTPUT - id: docker_tag - - name: Clear up some space on runner - if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - run: | - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" - sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.2.1 - if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - - name: Prep Dockerfiles for forked repository - if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - run: | - .github/scripts/local_ghcr .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile ${{ github.repository_owner }} $DOCKER_TAG - cat .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile - - name: See Dockerfile - run: cat .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile - if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - - name: Build and push base image - uses: docker/build-push-action@v3.2.0 - with: - context: . - file: .github/Dockerfiles/base-${{ matrix.variant }}.Dockerfile - push: true - tags: | - ${{ env.DOCKER_TAG }} - cache-from: type=gha - cache-to: type=gha,mode=min - if: always() && steps.changed-files-base.outputs.any_changed == 'true' || steps.changed-files.outputs.any_changed == 'true' || steps.docker_tag.not_yet_exists == 1 - - trigger-next-workflow: - needs: build-base - runs-on: ubuntu-latest - steps: - - name: Check out C-PAC - uses: actions/checkout@v2 - with: - fetch-depth: 2 - - name: Build and test C-PAC - run: gh workflow run build_and_test.yml --ref ${GITHUB_REF_NAME} - env: - GITHUB_TOKEN: ${{ secrets.ACTIONS_WORKFLOW_TOKEN }} From 52068a50c4659f55a77bd98963babc6033d188d3 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Fri, 9 Feb 2024 13:22:02 -0500 Subject: [PATCH 175/213] Change output type for correlation matrix --- CPAC/resources/cpac_outputs.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 7ff5f91041..a57ce2575c 100755 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -314,4 +314,4 @@ space-fsLR_den-32k_bold_surf_falff surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf_alff surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf-L_reho surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf-R_reho surface_derived func CIFTI dscalar -space-fsLR_den-32k_bold_surf-correlation_matrix surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf-correlation_matrix surface_derived func CIFTI pconn From e8fbff444d772b146eca13b4fa70de8fb6acc885 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Fri, 9 Feb 2024 13:23:22 -0500 Subject: [PATCH 176/213] :package: Change ciftify package location to fcpindi --- CPAC/info.py | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/info.py b/CPAC/info.py index d4c470dfb7..c1b2fdc53e 100755 --- a/CPAC/info.py +++ b/CPAC/info.py @@ -170,7 +170,7 @@ def get_cpac_gitversion(): STATUS = 'stable' REQUIREMENTS = [ "boto3", - "ciftify @ git+https://git@github.com/e-kenneally/ciftify.git@bugfix/remove_giftiio#egg=ciftify", + "ciftify @ git+https://git@github.com/fcp-indi/ciftify#egg=ciftify", "click", "click-aliases", "configparser", diff --git a/requirements.txt b/requirements.txt index 223522db5b..44c8d4ac27 100755 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ # C-PAC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License along with C-PAC. If not, see . boto3==1.28.4 -ciftify @ git+https://git@github.com/e-kenneally/ciftify.git@bugfix/remove_giftiio +ciftify @ git+https://git@github.com/fcp-indi/ciftify click==8.1.5 click-aliases==1.0.1 configparser==5.3.0 From 58622451dcc56c1d3e74bbf98f46bfc74dc40da6 Mon Sep 17 00:00:00 2001 From: Biraj Date: Fri, 9 Feb 2024 19:13:14 +0000 Subject: [PATCH 177/213] :package: reverting changes in config --- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 1 - CPAC/resources/configs/pipeline_config_regtest-1.yml | 4 ---- 2 files changed, 5 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 23f500a3a5..7aee4e80ad 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -46,7 +46,6 @@ anatomical_preproc: T1w_ACPC_template: /opt/dcan-tools/pipeline/global/templates/MNI152_T1_1mm.nii.gz brain_extraction: - run: On # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] # this is a fork option diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index 8727ce330a..fccbb36fc1 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -76,10 +76,6 @@ anatomical_preproc: brain_extraction: run: On - # using: ['3dSkullStrip', 'BET', 'UNet', 'niworkflows-ants', 'FreeSurfer-ABCD', 'FreeSurfer-BET-Tight', 'FreeSurfer-BET-Loose', 'FreeSurfer-Brainmask'] - # this is a fork option - using: [BET] - segmentation: # Automatically segment anatomical images into white matter, gray matter, From 2f4cc716809ccac21a08e0f2c140e5e8b47f083d Mon Sep 17 00:00:00 2001 From: Biraj Date: Fri, 9 Feb 2024 20:23:34 +0000 Subject: [PATCH 178/213] :package: Updated changelog for addition of RobustFOV --- .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 2 +- ...C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 2 +- .../Dockerfiles/C-PAC.develop-jammy.Dockerfile | 2 +- .../C-PAC.develop-lite-jammy.Dockerfile | 2 +- .github/Dockerfiles/base-standard.Dockerfile | 2 +- CHANGELOG.md | 17 +++++++++++++---- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile index 097dad96ab..2a5760ebb7 100644 --- a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:abcd-hcp-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [ABCD-HCP BIDS fMRI Pipeline](https://github.com/DCAN-Labs/abcd-hcp-pipeline/blob/e480a8f99534f1b05f37bf44c64827384b69b383/Dockerfile)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile index b67701063e..0e9cd3d899 100644 --- a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:fmriprep-lts-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image with software dependencies version-matched to [fMRIPrep LTS](https://reproducibility.stanford.edu/fmriprep-lts#long-term-support-lts)" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile index 97622bcb9f..f9ced12d7b 100644 --- a/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:standard-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile index 3abd61c499..1f6f3a9ec9 100644 --- a/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile +++ b/.github/Dockerfiles/C-PAC.develop-lite-jammy.Dockerfile @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "Full C-PAC image without FreeSurfer" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC USER root diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile index ea002cd613..2d0d51ab76 100644 --- a/.github/Dockerfiles/base-standard.Dockerfile +++ b/.github/Dockerfiles/base-standard.Dockerfile @@ -16,7 +16,7 @@ # License along with C-PAC. If not, see . FROM ghcr.io/fcp-indi/c-pac/freesurfer:6.0.0-min.neurodocker-jammy as FreeSurfer -FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.6 +FROM ghcr.io/fcp-indi/c-pac/stage-base:lite-v1.8.7.dev1 LABEL org.opencontainers.image.description "NOT INTENDED FOR USE OTHER THAN AS A STAGE IMAGE IN A MULTI-STAGE BUILD \ Standard software dependencies for C-PAC standard images" LABEL org.opencontainers.image.source https://github.com/FCP-INDI/C-PAC diff --git a/CHANGELOG.md b/CHANGELOG.md index d2add4dd71..413c09bcf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.8.6] +## [unreleased] + +## Added + +- `Robustfov` feature in `FSL-BET` to crop images ensuring removal of neck regions that may appear in the skull-stripped images. + +## Changed + +- Moved autoversioning from CI to pre-commit + +## [1.8.6] - 2024-01-15 ## Added @@ -26,7 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `switch_is_off`, `switch_is_on` and `switch_is_on_off` methods to `Configuration` class - `__repr__` and `__str__` methods to `ResourcePool`s and `NodeBlockFunction`s -## Fixed +### Fixed - Fixed a bug where some connectivity matrices wouldn't generate if anatomical and functional outputs were in different resolutions. - Handling of `3dECM` outputs for AFNI ≥ 21.1.1. @@ -141,7 +151,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated some output filenaming conventions for human-readability and to move closer to BIDS-derivatives compliance - Changed motion filter from single dictionary to list of dictionaries - Changed CI logic to allow non-release tags -- Added `Robustfov` in the `FSL-BET` config ### Upgraded dependencies @@ -229,7 +238,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - if `registration_workflows['anatomical_registration']['run']` is `On` and `segmentation['tissue_segmentation']['Template_Based']['template_for_segmentation']` includes `T1_Template` - Renamed connectivity matrices from `*_connectome.tsv` to `*_correlations.tsv` - Moved some ephemeral logging statements into `pypeline.log` -- Added `Robustfov` option in `FSL-BET` config. This can be turned on to crop out neck and other non-brain regions. ### Fixed @@ -274,6 +282,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 See [Version 1.8.1 Beta](https://fcp-indi.github.io/docs/user/release_notes/v1.8.1) for release notes for v1.8.1 and [Release Notes](https://fcp-indi.github.io/docs/user/release_notes) for all release notes back to v0.1.1. +[unreleased]: https://github.com/FCP-INDI/C-PAC/compare/v1.8.6...develop [1.8.6]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.6 [1.8.5]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.5 [1.8.4]: https://github.com/FCP-INDI/C-PAC/releases/tag/v1.8.4 From 6fd0fe822e52e47045b60bc3e044a54e63332a1a Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Mon, 12 Feb 2024 15:55:12 -0500 Subject: [PATCH 179/213] Revert "commiting all files modified" This reverts commit 982d44eb2c7d7b2da181097a8025465157e3864e. --- .circleci/config.yml | 0 .circleci/main.yml | 0 .dockerignore | 0 .flake8 | 0 .../AFNI.16.2.07.neurodocker-xenial.Dockerfile | 0 .github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile | 0 .../ANTs.2.2.0.neurodocker-bionic.Dockerfile | 0 .../ANTs.2.3.4.neurodocker-xenial.Dockerfile | 0 .../C-PAC.develop-ABCD-HCP-bionic.Dockerfile | 0 .../C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile | 0 .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile | 0 .../FSL.5.0.9-5.neurodebian-xenial.Dockerfile | 0 ...eeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile | 0 .../FreeSurfer.6.0.1-min-xenial.Dockerfile | 0 .../Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile | 0 .../ICA-AROMA.0.4.3-beta-bionic.Dockerfile | 0 .../Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile | 0 .../Dockerfiles/Ubuntu.bionic-non-free.Dockerfile | 0 .../Dockerfiles/Ubuntu.xenial-20200114.Dockerfile | 0 .github/Dockerfiles/base-ABCD-HCP.Dockerfile | 0 .github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile | 0 .github/Dockerfiles/base-standard.Dockerfile | 0 .github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile | 0 .github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile | 0 ...-workbench.1.3.2-1.neurodebian-bionic.Dockerfile | 0 ...-workbench.1.3.2-2.neurodebian-xenial.Dockerfile | 0 .github/Dockerfiles/msm.2.0-bionic.Dockerfile | 0 .../neuroparc.1.0-human-bionic.Dockerfile | 0 .github/scripts/get_package_id.py | 0 .github/scripts/get_pr_base_shas.py | 0 .github/scripts/minify-freesurfer-6.0.1.sh | 0 .github/stage_requirements/ABCD-HCP.txt | 0 .github/stage_requirements/fMRIPrep-LTS.txt | 0 .github/stage_requirements/standard.txt | 0 .github/workflows/build_C-PAC.yml | 0 .github/workflows/build_and_test.yml | 0 .github/workflows/delete_images.yml | 0 .github/workflows/deploy_to_Docker_Hub.yml | 0 .github/workflows/smoke_test_participant.yml | 0 .pylintrc | 0 CHANGELOG.md | 0 CONTRIBUTING.md | 0 COPYING | 0 COPYING.LESSER | 0 CPAC/__init__.py | 0 CPAC/__main__.py | 0 CPAC/alff/__init__.py | 0 CPAC/alff/alff.py | 0 CPAC/alff/utils.py | 0 CPAC/anat_preproc/__init__.py | 0 CPAC/anat_preproc/anat_preproc.py | 0 CPAC/anat_preproc/ants.py | 0 .../antsBrainExtractionNoLaplacian_precise.json | 0 .../antsBrainExtractionNoLaplacian_testing.json | 0 .../data/antsBrainExtraction_precise.json | 0 .../data/antsBrainExtraction_testing.json | 0 CPAC/anat_preproc/lesion_preproc.py | 0 CPAC/anat_preproc/utils.py | 0 CPAC/aroma/__init__.py | 0 CPAC/aroma/aroma.py | 0 CPAC/aroma/aroma_test.py | 0 CPAC/connectome/__init__.py | 0 CPAC/connectome/connectivity_matrix.py | 0 CPAC/connectome/test/test_connectome.py | 0 CPAC/cwas/__init__.py | 0 CPAC/cwas/cwas.py | 0 CPAC/cwas/mdmr.py | 0 CPAC/cwas/pipeline.py | 0 CPAC/cwas/tests/X.csv | 0 CPAC/cwas/tests/Y.csv | 0 CPAC/cwas/tests/test_mdmr_cython.py | 0 CPAC/cwas/tests/test_pipeline_cwas.py | 0 CPAC/distortion_correction/__init__.py | 0 CPAC/distortion_correction/distortion_correction.py | 0 CPAC/distortion_correction/tests/__init__.py | 0 .../tests/test_distortion_correction.py | 0 CPAC/distortion_correction/utils.py | 0 CPAC/easy_thresh/__init__.py | 0 CPAC/easy_thresh/easy_thresh.py | 0 CPAC/func_preproc/__init__.py | 0 CPAC/func_preproc/func_ingress.py | 0 CPAC/func_preproc/func_preproc.py | 0 CPAC/func_preproc/utils.py | 0 CPAC/generate_motion_statistics/__init__.py | 0 .../generate_motion_statistics.py | 0 CPAC/generate_motion_statistics/test/test_dvars.py | 0 CPAC/group_analysis/__init__.py | 0 CPAC/group_analysis/group_analysis.py | 0 CPAC/image_utils/__init__.py | 0 CPAC/image_utils/spatial_smoothing.py | 0 CPAC/image_utils/statistical_transforms.py | 0 CPAC/image_utils/tests/test_smooth.py | 0 CPAC/info.py | 0 CPAC/isc/__init__.py | 0 CPAC/isc/isc.py | 0 CPAC/isc/isfc.py | 0 CPAC/isc/pipeline.py | 0 CPAC/isc/tests/test_pipeline_isc.py | 0 CPAC/isc/utils.py | 0 CPAC/longitudinal_pipeline/longitudinal_preproc.py | 0 CPAC/longitudinal_pipeline/longitudinal_workflow.py | 0 CPAC/median_angle/median_angle.py | 0 CPAC/network_centrality/__init__.py | 0 CPAC/network_centrality/network_centrality.py | 0 CPAC/network_centrality/pipeline.py | 0 CPAC/network_centrality/utils.py | 0 CPAC/nuisance/__init__.py | 0 CPAC/nuisance/bandpass.py | 0 CPAC/nuisance/nuisance.py | 0 CPAC/nuisance/tests/motion_statistics/DVARS.1D | 0 CPAC/nuisance/tests/motion_statistics/FD_J.1D | 0 CPAC/nuisance/tests/motion_statistics/FD_P.1D | 0 .../nuisance/tests/test_nuisance_representations.py | 0 CPAC/nuisance/tests/test_utils.py | 0 CPAC/nuisance/utils/__init__.py | 0 CPAC/nuisance/utils/compcor.py | 0 CPAC/nuisance/utils/convolve.py | 0 CPAC/nuisance/utils/crc.py | 0 CPAC/pipeline/__init__.py | 0 CPAC/pipeline/check_outputs.py | 0 CPAC/pipeline/cpac_basc_pipeline.py | 0 CPAC/pipeline/cpac_cwas_pipeline.py | 0 CPAC/pipeline/cpac_group_runner.py | 0 CPAC/pipeline/cpac_randomise_pipeline.py | 0 CPAC/pipeline/cpac_runner.py | 0 CPAC/pipeline/engine.py | 7 +++++++ CPAC/pipeline/nipype_pipeline_engine/__init__.py | 0 CPAC/pipeline/nipype_pipeline_engine/engine.py | 0 .../nipype_pipeline_engine/plugins/__init__.py | 0 .../plugins/cpac_nipype_custom.py | 0 .../plugins/legacymultiproc.py | 0 .../nipype_pipeline_engine/plugins/multiproc.py | 0 CPAC/pipeline/random_state/__init__.py | 0 CPAC/pipeline/random_state/seed.py | 0 CPAC/pipeline/schema.py | 0 CPAC/pipeline/test/__init__.py | 0 CPAC/pipeline/test/issue_1606_data_config.yml | 0 CPAC/pipeline/test/sample_data.py | 0 CPAC/pipeline/test/test_cpac_group_runner.py | 0 CPAC/pipeline/test/test_cpac_pipeline.py | 0 CPAC/pipeline/test/test_cpac_runner.py | 0 CPAC/pipeline/test/test_engine.py | 0 CPAC/pipeline/test/test_nipype_pipeline_engine.py | 0 CPAC/pipeline/test/test_schema_validation.py | 0 CPAC/pypeer/__init__.py | 0 CPAC/pypeer/peer.py | 0 CPAC/qc/__init__.py | 0 CPAC/qc/colors/blue.txt | 0 CPAC/qc/colors/cyan_to_yellow.txt | 0 CPAC/qc/colors/green.txt | 0 CPAC/qc/colors/red.txt | 0 CPAC/qc/colors/red_to_blue.txt | 0 CPAC/qc/data/index.html | 0 CPAC/qc/pipeline.py | 0 CPAC/qc/qc.py | 0 CPAC/qc/qcmetrics.py | 0 CPAC/qc/tests/test_qc.py | 0 CPAC/qc/utils.py | 0 CPAC/qc/xcp.py | 0 CPAC/qpp/__init__.py | 0 CPAC/qpp/pipeline.py | 0 CPAC/qpp/qpp.py | 0 CPAC/qpp/tests/test_qpp.py | 0 CPAC/randomise/__init__.py | 0 CPAC/randomise/pipeline.py | 0 CPAC/randomise/randomise.py | 0 CPAC/randomise/test_randomise.py | 0 CPAC/registration/__init__.py | 0 CPAC/registration/output_func_to_standard.py | 0 CPAC/registration/registration.py | 0 CPAC/registration/tests/__init__.py | 0 CPAC/registration/tests/mocks.py | 0 CPAC/registration/tests/test_ants_apply_warp.py | 0 CPAC/registration/tests/test_apply_transform.py | 0 .../tests/test_output_func_to_standard.py | 0 CPAC/registration/utils.py | 0 CPAC/reho/__init__.py | 0 CPAC/reho/reho.py | 0 CPAC/reho/utils.py | 0 CPAC/resources/MSMConfig/MSMSulcStrainFinalconf | 0 CPAC/resources/configs/1.7-1.8-deprecations.yml | 0 CPAC/resources/configs/1.7-1.8-nesting-mappings.yml | 0 .../resources/configs/data_config_S3-BIDS-ABIDE.yml | 0 .../configs/data_config_S3-BIDS-ADHD200.yml | 0 .../configs/data_config_S3-BIDS-ADHD200_only2.yml | 0 .../data_config_S3-BIDS-NKI-RocklandSample.yml | 0 .../configs/data_config_cpac_benchmark.yml | 0 CPAC/resources/configs/data_settings_template.yml | 0 CPAC/resources/configs/group_config_template.yml | 0 .../configs/pipeline_config_abcd-options.yml | 0 .../resources/configs/pipeline_config_anat-only.yml | 0 .../configs/pipeline_config_benchmark-ANTS.yml | 0 .../configs/pipeline_config_benchmark-FNIRT.yml | 0 CPAC/resources/configs/pipeline_config_blank.yml | 0 .../configs/pipeline_config_ccs-options.yml | 0 .../configs/pipeline_config_fmriprep-options.yml | 0 .../configs/pipeline_config_fx-options.yml | 0 .../configs/pipeline_config_monkey-ABCD.yml | 0 CPAC/resources/configs/pipeline_config_monkey.yml | 0 CPAC/resources/configs/pipeline_config_ndmg.yml | 0 .../configs/pipeline_config_nhp-macaque.yml | 0 CPAC/resources/configs/pipeline_config_preproc.yml | 0 .../configs/pipeline_config_rbc-options.yml | 0 .../resources/configs/pipeline_config_regtest-1.yml | 0 .../resources/configs/pipeline_config_regtest-2.yml | 0 .../resources/configs/pipeline_config_regtest-3.yml | 0 .../resources/configs/pipeline_config_regtest-4.yml | 0 CPAC/resources/configs/pipeline_config_rodent.yml | 0 CPAC/resources/configs/system_config.yml | 0 .../configs/test_configs/ADHD200_participants.csv | 0 .../test_configs/ADHD200_participants_age.tsv | 0 .../configs/test_configs/data-test_S3-ADHD200_1.yml | 0 .../test_configs/data-test_S3-ADHD200_no-params.yml | 0 .../test_configs/data-test_S3-NKI-RS_fmap.yml | 0 .../configs/test_configs/data-test_human.yml | 0 .../data_config_S3_CoRR_5only_mult-scan.yml | 0 .../data_config_S3_CoRR_5only_mult-sess.yml | 0 .../configs/test_configs/pipe-test_ABCD.yml | 0 .../test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 0 .../pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 0 .../pipe-test_ANTs-3dSk-DistCorrBET.yml | 0 .../test_configs/pipe-test_ANTs-BET-AllNuis.yml | 0 .../test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-BASC.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-ISC.yml | 0 .../pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 0 .../test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 0 .../configs/test_configs/pipe-test_all.yml | 0 CPAC/resources/cpac_templates.csv | 0 CPAC/resources/global/scripts/log.shlib | 0 .../templates/mni_icbm152_t1_tal_nlin_asym_09c.nii | Bin CPAC/resources/templates/ndmg_atlases.csv | 0 ...NI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz | Bin ...52NLin2009cAsym_res-01_desc-brain_probseg.nii.gz | 0 ...2NLin2009cAsym_res-01_label-brain_probseg.nii.gz | Bin ...-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz | Bin ...NI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz | Bin ...Lin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz | Bin CPAC/sca/README.txt | 0 CPAC/sca/__init__.py | 0 CPAC/sca/sca.py | 0 CPAC/sca/utils.py | 0 CPAC/scrubbing/__init__.py | 0 CPAC/scrubbing/scrubbing.py | 0 CPAC/seg_preproc/__init__.py | 0 CPAC/seg_preproc/utils.py | 0 .../FreeSurfer2CaretConvertAndRegisterNonlinear.sh | 0 CPAC/surface/PostFreeSurfer/run.sh | 0 CPAC/surface/fMRISurface/CreateDenseTimeseries.sh | 0 .../fMRISurface/RibbonVolumeToSurfaceMapping.sh | 0 CPAC/surface/fMRISurface/SubcorticalProcessing.sh | 0 CPAC/surface/fMRISurface/SurfaceSmoothing.sh | 0 CPAC/surface/tests/test_config.py | 0 CPAC/timeseries/__init__.py | 0 CPAC/timeseries/timeseries_analysis.py | 0 CPAC/unet/__init__.py | 0 CPAC/unet/function.py | 0 CPAC/utils/README.txt | 0 CPAC/utils/__init__.py | 0 CPAC/utils/build_data_config.py | 0 CPAC/utils/create_flame_model_files.py | 0 CPAC/utils/create_fsl_flame_preset.py | 0 CPAC/utils/create_fsl_model.py | 0 CPAC/utils/create_group_analysis_info_files.py | 0 CPAC/utils/datasource.py | 0 CPAC/utils/docs.py | 0 CPAC/utils/extract_data.py | 0 CPAC/utils/extract_data_multiscan.py | 0 CPAC/utils/extract_parameters.py | 0 CPAC/utils/ga.py | 0 CPAC/utils/interfaces/__init__.py | 0 CPAC/utils/interfaces/ants.py | 0 CPAC/utils/interfaces/brickstat.py | 0 CPAC/utils/interfaces/datasink.py | 0 CPAC/utils/interfaces/fixes.py | 0 CPAC/utils/interfaces/fsl.py | 0 CPAC/utils/interfaces/function/__init__.py | 0 CPAC/utils/interfaces/function/function.py | 0 CPAC/utils/interfaces/function/seg_preproc.py | 0 CPAC/utils/interfaces/masktool.py | 0 CPAC/utils/interfaces/netcorr.py | 0 CPAC/utils/interfaces/pc.py | 0 CPAC/utils/interfaces/tests/__init__.py | 0 CPAC/utils/interfaces/tests/test_fsl.py | 0 CPAC/utils/interfaces/utils.py | 0 CPAC/utils/misc.py | 0 CPAC/utils/monitoring/__init__.py | 0 CPAC/utils/monitoring/config.py | 0 CPAC/utils/monitoring/draw_gantt_chart.py | 0 CPAC/utils/monitoring/monitoring.py | 0 CPAC/utils/ndmg_utils.py | 0 CPAC/utils/nifti_utils.py | 0 CPAC/utils/outputs.py | 0 CPAC/utils/strategy.py | 0 CPAC/utils/symlinks.py | 0 CPAC/utils/test_init.py | 0 CPAC/utils/test_mocks.py | 0 CPAC/utils/test_resources.py | 0 CPAC/utils/tests/__init__.py | 0 CPAC/utils/tests/test_bids_utils.py | 0 CPAC/utils/tests/test_crash.py | 0 CPAC/utils/tests/test_datasource.py | 0 CPAC/utils/tests/test_function.py | 0 CPAC/utils/tests/test_s3.py | 0 CPAC/utils/tests/test_symlinks-outputs.txt | 0 CPAC/utils/tests/test_symlinks.py | 0 CPAC/utils/tests/test_trimmer.py | 0 CPAC/utils/tests/test_utils.py | 0 CPAC/utils/tests/test_yaml.py | 0 CPAC/utils/trimmer.py | 0 CPAC/utils/utils.py | 0 CPAC/vmhc/__init__.py | 0 CPAC/vmhc/tests/test_vmhc.py | 0 CPAC/vmhc/utils.py | 0 CPAC/vmhc/vmhc.py | 0 Dockerfile | 0 README.md | 0 dev/ami_data/setup.sh | 0 dev/ami_data/setup_cpac.sh | 0 dev/circleci_data/__init__.py | 0 ...ta_settings_bids_examples_ds051_default_BIDS.yml | 0 dev/circleci_data/generate_run_command.py | 0 dev/circleci_data/pipe-test_ci.yml | 0 dev/circleci_data/pytest.ini | 0 dev/circleci_data/python_2_pickle.pkl | 0 dev/circleci_data/python_2_pickle.pklz | Bin dev/circleci_data/requirements.txt | 0 dev/circleci_data/test_external_utils.py | 0 dev/circleci_data/test_install.py | 0 dev/docker_data/default_pipeline.yml | 0 dev/docker_data/license.txt | 0 dev/docker_data/required_afni_pkgs.txt | 0 dev/docker_data/required_freesurfer_pkgs.txt | 0 dev/rc_tests/README.md | 0 requirements.txt | 0 scripts/cpac | 0 variant-ABCD-HCP.Dockerfile | 0 variant-fMRIPrep-LTS.Dockerfile | 0 variant-lite.Dockerfile | 0 version | 0 341 files changed, 7 insertions(+) mode change 100755 => 100644 .circleci/config.yml mode change 100755 => 100644 .circleci/main.yml mode change 100755 => 100644 .dockerignore mode change 100755 => 100644 .flake8 mode change 100755 => 100644 .github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/ICA-AROMA.0.4.3-beta-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/base-ABCD-HCP.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/base-standard.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/msm.2.0-bionic.Dockerfile mode change 100755 => 100644 .github/Dockerfiles/neuroparc.1.0-human-bionic.Dockerfile mode change 100755 => 100644 .github/scripts/get_package_id.py mode change 100755 => 100644 .github/scripts/get_pr_base_shas.py mode change 100755 => 100644 .github/scripts/minify-freesurfer-6.0.1.sh mode change 100755 => 100644 .github/stage_requirements/ABCD-HCP.txt mode change 100755 => 100644 .github/stage_requirements/fMRIPrep-LTS.txt mode change 100755 => 100644 .github/stage_requirements/standard.txt mode change 100755 => 100644 .github/workflows/build_C-PAC.yml mode change 100755 => 100644 .github/workflows/build_and_test.yml mode change 100755 => 100644 .github/workflows/delete_images.yml mode change 100755 => 100644 .github/workflows/deploy_to_Docker_Hub.yml mode change 100755 => 100644 .github/workflows/smoke_test_participant.yml mode change 100755 => 100644 .pylintrc mode change 100755 => 100644 CHANGELOG.md mode change 100755 => 100644 CONTRIBUTING.md mode change 100755 => 100644 COPYING mode change 100755 => 100644 COPYING.LESSER mode change 100755 => 100644 CPAC/__init__.py mode change 100755 => 100644 CPAC/__main__.py mode change 100755 => 100644 CPAC/alff/__init__.py mode change 100755 => 100644 CPAC/alff/alff.py mode change 100755 => 100644 CPAC/alff/utils.py mode change 100755 => 100644 CPAC/anat_preproc/__init__.py mode change 100755 => 100644 CPAC/anat_preproc/anat_preproc.py mode change 100755 => 100644 CPAC/anat_preproc/ants.py mode change 100755 => 100644 CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_precise.json mode change 100755 => 100644 CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_testing.json mode change 100755 => 100644 CPAC/anat_preproc/data/antsBrainExtraction_precise.json mode change 100755 => 100644 CPAC/anat_preproc/data/antsBrainExtraction_testing.json mode change 100755 => 100644 CPAC/anat_preproc/lesion_preproc.py mode change 100755 => 100644 CPAC/anat_preproc/utils.py mode change 100755 => 100644 CPAC/aroma/__init__.py mode change 100755 => 100644 CPAC/aroma/aroma.py mode change 100755 => 100644 CPAC/aroma/aroma_test.py mode change 100755 => 100644 CPAC/connectome/__init__.py mode change 100755 => 100644 CPAC/connectome/connectivity_matrix.py mode change 100755 => 100644 CPAC/connectome/test/test_connectome.py mode change 100755 => 100644 CPAC/cwas/__init__.py mode change 100755 => 100644 CPAC/cwas/cwas.py mode change 100755 => 100644 CPAC/cwas/mdmr.py mode change 100755 => 100644 CPAC/cwas/pipeline.py mode change 100755 => 100644 CPAC/cwas/tests/X.csv mode change 100755 => 100644 CPAC/cwas/tests/Y.csv mode change 100755 => 100644 CPAC/cwas/tests/test_mdmr_cython.py mode change 100755 => 100644 CPAC/cwas/tests/test_pipeline_cwas.py mode change 100755 => 100644 CPAC/distortion_correction/__init__.py mode change 100755 => 100644 CPAC/distortion_correction/distortion_correction.py mode change 100755 => 100644 CPAC/distortion_correction/tests/__init__.py mode change 100755 => 100644 CPAC/distortion_correction/tests/test_distortion_correction.py mode change 100755 => 100644 CPAC/distortion_correction/utils.py mode change 100755 => 100644 CPAC/easy_thresh/__init__.py mode change 100755 => 100644 CPAC/easy_thresh/easy_thresh.py mode change 100755 => 100644 CPAC/func_preproc/__init__.py mode change 100755 => 100644 CPAC/func_preproc/func_ingress.py mode change 100755 => 100644 CPAC/func_preproc/func_preproc.py mode change 100755 => 100644 CPAC/func_preproc/utils.py mode change 100755 => 100644 CPAC/generate_motion_statistics/__init__.py mode change 100755 => 100644 CPAC/generate_motion_statistics/generate_motion_statistics.py mode change 100755 => 100644 CPAC/generate_motion_statistics/test/test_dvars.py mode change 100755 => 100644 CPAC/group_analysis/__init__.py mode change 100755 => 100644 CPAC/group_analysis/group_analysis.py mode change 100755 => 100644 CPAC/image_utils/__init__.py mode change 100755 => 100644 CPAC/image_utils/spatial_smoothing.py mode change 100755 => 100644 CPAC/image_utils/statistical_transforms.py mode change 100755 => 100644 CPAC/image_utils/tests/test_smooth.py mode change 100755 => 100644 CPAC/info.py mode change 100755 => 100644 CPAC/isc/__init__.py mode change 100755 => 100644 CPAC/isc/isc.py mode change 100755 => 100644 CPAC/isc/isfc.py mode change 100755 => 100644 CPAC/isc/pipeline.py mode change 100755 => 100644 CPAC/isc/tests/test_pipeline_isc.py mode change 100755 => 100644 CPAC/isc/utils.py mode change 100755 => 100644 CPAC/longitudinal_pipeline/longitudinal_preproc.py mode change 100755 => 100644 CPAC/longitudinal_pipeline/longitudinal_workflow.py mode change 100755 => 100644 CPAC/median_angle/median_angle.py mode change 100755 => 100644 CPAC/network_centrality/__init__.py mode change 100755 => 100644 CPAC/network_centrality/network_centrality.py mode change 100755 => 100644 CPAC/network_centrality/pipeline.py mode change 100755 => 100644 CPAC/network_centrality/utils.py mode change 100755 => 100644 CPAC/nuisance/__init__.py mode change 100755 => 100644 CPAC/nuisance/bandpass.py mode change 100755 => 100644 CPAC/nuisance/nuisance.py mode change 100755 => 100644 CPAC/nuisance/tests/motion_statistics/DVARS.1D mode change 100755 => 100644 CPAC/nuisance/tests/motion_statistics/FD_J.1D mode change 100755 => 100644 CPAC/nuisance/tests/motion_statistics/FD_P.1D mode change 100755 => 100644 CPAC/nuisance/tests/test_nuisance_representations.py mode change 100755 => 100644 CPAC/nuisance/tests/test_utils.py mode change 100755 => 100644 CPAC/nuisance/utils/__init__.py mode change 100755 => 100644 CPAC/nuisance/utils/compcor.py mode change 100755 => 100644 CPAC/nuisance/utils/convolve.py mode change 100755 => 100644 CPAC/nuisance/utils/crc.py mode change 100755 => 100644 CPAC/pipeline/__init__.py mode change 100755 => 100644 CPAC/pipeline/check_outputs.py mode change 100755 => 100644 CPAC/pipeline/cpac_basc_pipeline.py mode change 100755 => 100644 CPAC/pipeline/cpac_cwas_pipeline.py mode change 100755 => 100644 CPAC/pipeline/cpac_group_runner.py mode change 100755 => 100644 CPAC/pipeline/cpac_randomise_pipeline.py mode change 100755 => 100644 CPAC/pipeline/cpac_runner.py mode change 100755 => 100644 CPAC/pipeline/engine.py mode change 100755 => 100644 CPAC/pipeline/nipype_pipeline_engine/__init__.py mode change 100755 => 100644 CPAC/pipeline/nipype_pipeline_engine/engine.py mode change 100755 => 100644 CPAC/pipeline/nipype_pipeline_engine/plugins/__init__.py mode change 100755 => 100644 CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py mode change 100755 => 100644 CPAC/pipeline/nipype_pipeline_engine/plugins/legacymultiproc.py mode change 100755 => 100644 CPAC/pipeline/nipype_pipeline_engine/plugins/multiproc.py mode change 100755 => 100644 CPAC/pipeline/random_state/__init__.py mode change 100755 => 100644 CPAC/pipeline/random_state/seed.py mode change 100755 => 100644 CPAC/pipeline/schema.py mode change 100755 => 100644 CPAC/pipeline/test/__init__.py mode change 100755 => 100644 CPAC/pipeline/test/issue_1606_data_config.yml mode change 100755 => 100644 CPAC/pipeline/test/sample_data.py mode change 100755 => 100644 CPAC/pipeline/test/test_cpac_group_runner.py mode change 100755 => 100644 CPAC/pipeline/test/test_cpac_pipeline.py mode change 100755 => 100644 CPAC/pipeline/test/test_cpac_runner.py mode change 100755 => 100644 CPAC/pipeline/test/test_engine.py mode change 100755 => 100644 CPAC/pipeline/test/test_nipype_pipeline_engine.py mode change 100755 => 100644 CPAC/pipeline/test/test_schema_validation.py mode change 100755 => 100644 CPAC/pypeer/__init__.py mode change 100755 => 100644 CPAC/pypeer/peer.py mode change 100755 => 100644 CPAC/qc/__init__.py mode change 100755 => 100644 CPAC/qc/colors/blue.txt mode change 100755 => 100644 CPAC/qc/colors/cyan_to_yellow.txt mode change 100755 => 100644 CPAC/qc/colors/green.txt mode change 100755 => 100644 CPAC/qc/colors/red.txt mode change 100755 => 100644 CPAC/qc/colors/red_to_blue.txt mode change 100755 => 100644 CPAC/qc/data/index.html mode change 100755 => 100644 CPAC/qc/pipeline.py mode change 100755 => 100644 CPAC/qc/qc.py mode change 100755 => 100644 CPAC/qc/qcmetrics.py mode change 100755 => 100644 CPAC/qc/tests/test_qc.py mode change 100755 => 100644 CPAC/qc/utils.py mode change 100755 => 100644 CPAC/qc/xcp.py mode change 100755 => 100644 CPAC/qpp/__init__.py mode change 100755 => 100644 CPAC/qpp/pipeline.py mode change 100755 => 100644 CPAC/qpp/qpp.py mode change 100755 => 100644 CPAC/qpp/tests/test_qpp.py mode change 100755 => 100644 CPAC/randomise/__init__.py mode change 100755 => 100644 CPAC/randomise/pipeline.py mode change 100755 => 100644 CPAC/randomise/randomise.py mode change 100755 => 100644 CPAC/randomise/test_randomise.py mode change 100755 => 100644 CPAC/registration/__init__.py mode change 100755 => 100644 CPAC/registration/output_func_to_standard.py mode change 100755 => 100644 CPAC/registration/registration.py mode change 100755 => 100644 CPAC/registration/tests/__init__.py mode change 100755 => 100644 CPAC/registration/tests/mocks.py mode change 100755 => 100644 CPAC/registration/tests/test_ants_apply_warp.py mode change 100755 => 100644 CPAC/registration/tests/test_apply_transform.py mode change 100755 => 100644 CPAC/registration/tests/test_output_func_to_standard.py mode change 100755 => 100644 CPAC/registration/utils.py mode change 100755 => 100644 CPAC/reho/__init__.py mode change 100755 => 100644 CPAC/reho/reho.py mode change 100755 => 100644 CPAC/reho/utils.py mode change 100755 => 100644 CPAC/resources/MSMConfig/MSMSulcStrainFinalconf mode change 100755 => 100644 CPAC/resources/configs/1.7-1.8-deprecations.yml mode change 100755 => 100644 CPAC/resources/configs/1.7-1.8-nesting-mappings.yml mode change 100755 => 100644 CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml mode change 100755 => 100644 CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml mode change 100755 => 100644 CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml mode change 100755 => 100644 CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml mode change 100755 => 100644 CPAC/resources/configs/data_config_cpac_benchmark.yml mode change 100755 => 100644 CPAC/resources/configs/data_settings_template.yml mode change 100755 => 100644 CPAC/resources/configs/group_config_template.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_abcd-options.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_anat-only.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_blank.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_ccs-options.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_fmriprep-options.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_fx-options.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_monkey-ABCD.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_monkey.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_ndmg.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_nhp-macaque.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_preproc.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_rbc-options.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_regtest-1.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_regtest-2.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_regtest-3.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_regtest-4.yml mode change 100755 => 100644 CPAC/resources/configs/pipeline_config_rodent.yml mode change 100755 => 100644 CPAC/resources/configs/system_config.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/ADHD200_participants.csv mode change 100755 => 100644 CPAC/resources/configs/test_configs/ADHD200_participants_age.tsv mode change 100755 => 100644 CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/data-test_human.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_ABCD.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml mode change 100755 => 100644 CPAC/resources/configs/test_configs/pipe-test_all.yml mode change 100755 => 100644 CPAC/resources/cpac_templates.csv mode change 100755 => 100644 CPAC/resources/global/scripts/log.shlib mode change 100755 => 100644 CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii mode change 100755 => 100644 CPAC/resources/templates/ndmg_atlases.csv mode change 100755 => 100644 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz mode change 100755 => 100644 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_probseg.nii.gz mode change 100755 => 100644 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz mode change 100755 => 100644 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz mode change 100755 => 100644 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz mode change 100755 => 100644 CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz mode change 100755 => 100644 CPAC/sca/README.txt mode change 100755 => 100644 CPAC/sca/__init__.py mode change 100755 => 100644 CPAC/sca/sca.py mode change 100755 => 100644 CPAC/sca/utils.py mode change 100755 => 100644 CPAC/scrubbing/__init__.py mode change 100755 => 100644 CPAC/scrubbing/scrubbing.py mode change 100755 => 100644 CPAC/seg_preproc/__init__.py mode change 100755 => 100644 CPAC/seg_preproc/utils.py mode change 100755 => 100644 CPAC/surface/PostFreeSurfer/FreeSurfer2CaretConvertAndRegisterNonlinear.sh mode change 100755 => 100644 CPAC/surface/PostFreeSurfer/run.sh mode change 100755 => 100644 CPAC/surface/fMRISurface/CreateDenseTimeseries.sh mode change 100755 => 100644 CPAC/surface/fMRISurface/RibbonVolumeToSurfaceMapping.sh mode change 100755 => 100644 CPAC/surface/fMRISurface/SubcorticalProcessing.sh mode change 100755 => 100644 CPAC/surface/fMRISurface/SurfaceSmoothing.sh mode change 100755 => 100644 CPAC/surface/tests/test_config.py mode change 100755 => 100644 CPAC/timeseries/__init__.py mode change 100755 => 100644 CPAC/timeseries/timeseries_analysis.py mode change 100755 => 100644 CPAC/unet/__init__.py mode change 100755 => 100644 CPAC/unet/function.py mode change 100755 => 100644 CPAC/utils/README.txt mode change 100755 => 100644 CPAC/utils/__init__.py mode change 100755 => 100644 CPAC/utils/build_data_config.py mode change 100755 => 100644 CPAC/utils/create_flame_model_files.py mode change 100755 => 100644 CPAC/utils/create_fsl_flame_preset.py mode change 100755 => 100644 CPAC/utils/create_fsl_model.py mode change 100755 => 100644 CPAC/utils/create_group_analysis_info_files.py mode change 100755 => 100644 CPAC/utils/datasource.py mode change 100755 => 100644 CPAC/utils/docs.py mode change 100755 => 100644 CPAC/utils/extract_data.py mode change 100755 => 100644 CPAC/utils/extract_data_multiscan.py mode change 100755 => 100644 CPAC/utils/extract_parameters.py mode change 100755 => 100644 CPAC/utils/ga.py mode change 100755 => 100644 CPAC/utils/interfaces/__init__.py mode change 100755 => 100644 CPAC/utils/interfaces/ants.py mode change 100755 => 100644 CPAC/utils/interfaces/brickstat.py mode change 100755 => 100644 CPAC/utils/interfaces/datasink.py mode change 100755 => 100644 CPAC/utils/interfaces/fixes.py mode change 100755 => 100644 CPAC/utils/interfaces/fsl.py mode change 100755 => 100644 CPAC/utils/interfaces/function/__init__.py mode change 100755 => 100644 CPAC/utils/interfaces/function/function.py mode change 100755 => 100644 CPAC/utils/interfaces/function/seg_preproc.py mode change 100755 => 100644 CPAC/utils/interfaces/masktool.py mode change 100755 => 100644 CPAC/utils/interfaces/netcorr.py mode change 100755 => 100644 CPAC/utils/interfaces/pc.py mode change 100755 => 100644 CPAC/utils/interfaces/tests/__init__.py mode change 100755 => 100644 CPAC/utils/interfaces/tests/test_fsl.py mode change 100755 => 100644 CPAC/utils/interfaces/utils.py mode change 100755 => 100644 CPAC/utils/misc.py mode change 100755 => 100644 CPAC/utils/monitoring/__init__.py mode change 100755 => 100644 CPAC/utils/monitoring/config.py mode change 100755 => 100644 CPAC/utils/monitoring/draw_gantt_chart.py mode change 100755 => 100644 CPAC/utils/monitoring/monitoring.py mode change 100755 => 100644 CPAC/utils/ndmg_utils.py mode change 100755 => 100644 CPAC/utils/nifti_utils.py mode change 100755 => 100644 CPAC/utils/outputs.py mode change 100755 => 100644 CPAC/utils/strategy.py mode change 100755 => 100644 CPAC/utils/symlinks.py mode change 100755 => 100644 CPAC/utils/test_init.py mode change 100755 => 100644 CPAC/utils/test_mocks.py mode change 100755 => 100644 CPAC/utils/test_resources.py mode change 100755 => 100644 CPAC/utils/tests/__init__.py mode change 100755 => 100644 CPAC/utils/tests/test_bids_utils.py mode change 100755 => 100644 CPAC/utils/tests/test_crash.py mode change 100755 => 100644 CPAC/utils/tests/test_datasource.py mode change 100755 => 100644 CPAC/utils/tests/test_function.py mode change 100755 => 100644 CPAC/utils/tests/test_s3.py mode change 100755 => 100644 CPAC/utils/tests/test_symlinks-outputs.txt mode change 100755 => 100644 CPAC/utils/tests/test_symlinks.py mode change 100755 => 100644 CPAC/utils/tests/test_trimmer.py mode change 100755 => 100644 CPAC/utils/tests/test_utils.py mode change 100755 => 100644 CPAC/utils/tests/test_yaml.py mode change 100755 => 100644 CPAC/utils/trimmer.py mode change 100755 => 100644 CPAC/utils/utils.py mode change 100755 => 100644 CPAC/vmhc/__init__.py mode change 100755 => 100644 CPAC/vmhc/tests/test_vmhc.py mode change 100755 => 100644 CPAC/vmhc/utils.py mode change 100755 => 100644 CPAC/vmhc/vmhc.py mode change 100755 => 100644 Dockerfile mode change 100755 => 100644 README.md mode change 100755 => 100644 dev/ami_data/setup.sh mode change 100755 => 100644 dev/ami_data/setup_cpac.sh mode change 100755 => 100644 dev/circleci_data/__init__.py mode change 100755 => 100644 dev/circleci_data/data_settings_bids_examples_ds051_default_BIDS.yml mode change 100755 => 100644 dev/circleci_data/generate_run_command.py mode change 100755 => 100644 dev/circleci_data/pipe-test_ci.yml mode change 100755 => 100644 dev/circleci_data/pytest.ini mode change 100755 => 100644 dev/circleci_data/python_2_pickle.pkl mode change 100755 => 100644 dev/circleci_data/python_2_pickle.pklz mode change 100755 => 100644 dev/circleci_data/requirements.txt mode change 100755 => 100644 dev/circleci_data/test_external_utils.py mode change 100755 => 100644 dev/circleci_data/test_install.py mode change 100755 => 100644 dev/docker_data/default_pipeline.yml mode change 100755 => 100644 dev/docker_data/license.txt mode change 100755 => 100644 dev/docker_data/required_afni_pkgs.txt mode change 100755 => 100644 dev/docker_data/required_freesurfer_pkgs.txt mode change 100755 => 100644 dev/rc_tests/README.md mode change 100755 => 100644 requirements.txt mode change 100755 => 100644 scripts/cpac mode change 100755 => 100644 variant-ABCD-HCP.Dockerfile mode change 100755 => 100644 variant-fMRIPrep-LTS.Dockerfile mode change 100755 => 100644 variant-lite.Dockerfile mode change 100755 => 100644 version diff --git a/.circleci/config.yml b/.circleci/config.yml old mode 100755 new mode 100644 diff --git a/.circleci/main.yml b/.circleci/main.yml old mode 100755 new mode 100644 diff --git a/.dockerignore b/.dockerignore old mode 100755 new mode 100644 diff --git a/.flake8 b/.flake8 old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile b/.github/Dockerfiles/AFNI.16.2.07.neurodocker-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile b/.github/Dockerfiles/AFNI.21.1.00-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile b/.github/Dockerfiles/ANTs.2.2.0.neurodocker-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile b/.github/Dockerfiles/ANTs.2.3.4.neurodocker-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile b/.github/Dockerfiles/C-PAC.develop-ABCD-HCP-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile b/.github/Dockerfiles/C-PAC.develop-fMRIPrep-LTS-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile b/.github/Dockerfiles/FSL.5.0.10-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile b/.github/Dockerfiles/FSL.5.0.9-5.neurodebian-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.0-min.neurodocker-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.1-min-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile b/.github/Dockerfiles/FreeSurfer.6.0.1-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/ICA-AROMA.0.4.3-beta-bionic.Dockerfile b/.github/Dockerfiles/ICA-AROMA.0.4.3-beta-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile b/.github/Dockerfiles/ICA-AROMA.0.4.5-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile b/.github/Dockerfiles/Ubuntu.bionic-non-free.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile b/.github/Dockerfiles/Ubuntu.xenial-20200114.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/base-ABCD-HCP.Dockerfile b/.github/Dockerfiles/base-ABCD-HCP.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile b/.github/Dockerfiles/base-fMRIPrep-LTS.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/base-standard.Dockerfile b/.github/Dockerfiles/base-standard.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile b/.github/Dockerfiles/c3d.1.0.0-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile b/.github/Dockerfiles/c3d.1.0.0-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.3.2-1.neurodebian-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile b/.github/Dockerfiles/connectome-workbench.1.3.2-2.neurodebian-xenial.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/msm.2.0-bionic.Dockerfile b/.github/Dockerfiles/msm.2.0-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/Dockerfiles/neuroparc.1.0-human-bionic.Dockerfile b/.github/Dockerfiles/neuroparc.1.0-human-bionic.Dockerfile old mode 100755 new mode 100644 diff --git a/.github/scripts/get_package_id.py b/.github/scripts/get_package_id.py old mode 100755 new mode 100644 diff --git a/.github/scripts/get_pr_base_shas.py b/.github/scripts/get_pr_base_shas.py old mode 100755 new mode 100644 diff --git a/.github/scripts/minify-freesurfer-6.0.1.sh b/.github/scripts/minify-freesurfer-6.0.1.sh old mode 100755 new mode 100644 diff --git a/.github/stage_requirements/ABCD-HCP.txt b/.github/stage_requirements/ABCD-HCP.txt old mode 100755 new mode 100644 diff --git a/.github/stage_requirements/fMRIPrep-LTS.txt b/.github/stage_requirements/fMRIPrep-LTS.txt old mode 100755 new mode 100644 diff --git a/.github/stage_requirements/standard.txt b/.github/stage_requirements/standard.txt old mode 100755 new mode 100644 diff --git a/.github/workflows/build_C-PAC.yml b/.github/workflows/build_C-PAC.yml old mode 100755 new mode 100644 diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml old mode 100755 new mode 100644 diff --git a/.github/workflows/delete_images.yml b/.github/workflows/delete_images.yml old mode 100755 new mode 100644 diff --git a/.github/workflows/deploy_to_Docker_Hub.yml b/.github/workflows/deploy_to_Docker_Hub.yml old mode 100755 new mode 100644 diff --git a/.github/workflows/smoke_test_participant.yml b/.github/workflows/smoke_test_participant.yml old mode 100755 new mode 100644 diff --git a/.pylintrc b/.pylintrc old mode 100755 new mode 100644 diff --git a/CHANGELOG.md b/CHANGELOG.md old mode 100755 new mode 100644 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100755 new mode 100644 diff --git a/COPYING b/COPYING old mode 100755 new mode 100644 diff --git a/COPYING.LESSER b/COPYING.LESSER old mode 100755 new mode 100644 diff --git a/CPAC/__init__.py b/CPAC/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/__main__.py b/CPAC/__main__.py old mode 100755 new mode 100644 diff --git a/CPAC/alff/__init__.py b/CPAC/alff/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/alff/alff.py b/CPAC/alff/alff.py old mode 100755 new mode 100644 diff --git a/CPAC/alff/utils.py b/CPAC/alff/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/__init__.py b/CPAC/anat_preproc/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/anat_preproc.py b/CPAC/anat_preproc/anat_preproc.py old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/ants.py b/CPAC/anat_preproc/ants.py old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_precise.json b/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_precise.json old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_testing.json b/CPAC/anat_preproc/data/antsBrainExtractionNoLaplacian_testing.json old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/data/antsBrainExtraction_precise.json b/CPAC/anat_preproc/data/antsBrainExtraction_precise.json old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/data/antsBrainExtraction_testing.json b/CPAC/anat_preproc/data/antsBrainExtraction_testing.json old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/lesion_preproc.py b/CPAC/anat_preproc/lesion_preproc.py old mode 100755 new mode 100644 diff --git a/CPAC/anat_preproc/utils.py b/CPAC/anat_preproc/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/aroma/__init__.py b/CPAC/aroma/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/aroma/aroma.py b/CPAC/aroma/aroma.py old mode 100755 new mode 100644 diff --git a/CPAC/aroma/aroma_test.py b/CPAC/aroma/aroma_test.py old mode 100755 new mode 100644 diff --git a/CPAC/connectome/__init__.py b/CPAC/connectome/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/connectome/connectivity_matrix.py b/CPAC/connectome/connectivity_matrix.py old mode 100755 new mode 100644 diff --git a/CPAC/connectome/test/test_connectome.py b/CPAC/connectome/test/test_connectome.py old mode 100755 new mode 100644 diff --git a/CPAC/cwas/__init__.py b/CPAC/cwas/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/cwas/cwas.py b/CPAC/cwas/cwas.py old mode 100755 new mode 100644 diff --git a/CPAC/cwas/mdmr.py b/CPAC/cwas/mdmr.py old mode 100755 new mode 100644 diff --git a/CPAC/cwas/pipeline.py b/CPAC/cwas/pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/cwas/tests/X.csv b/CPAC/cwas/tests/X.csv old mode 100755 new mode 100644 diff --git a/CPAC/cwas/tests/Y.csv b/CPAC/cwas/tests/Y.csv old mode 100755 new mode 100644 diff --git a/CPAC/cwas/tests/test_mdmr_cython.py b/CPAC/cwas/tests/test_mdmr_cython.py old mode 100755 new mode 100644 diff --git a/CPAC/cwas/tests/test_pipeline_cwas.py b/CPAC/cwas/tests/test_pipeline_cwas.py old mode 100755 new mode 100644 diff --git a/CPAC/distortion_correction/__init__.py b/CPAC/distortion_correction/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/distortion_correction/distortion_correction.py b/CPAC/distortion_correction/distortion_correction.py old mode 100755 new mode 100644 diff --git a/CPAC/distortion_correction/tests/__init__.py b/CPAC/distortion_correction/tests/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/distortion_correction/tests/test_distortion_correction.py b/CPAC/distortion_correction/tests/test_distortion_correction.py old mode 100755 new mode 100644 diff --git a/CPAC/distortion_correction/utils.py b/CPAC/distortion_correction/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/easy_thresh/__init__.py b/CPAC/easy_thresh/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/easy_thresh/easy_thresh.py b/CPAC/easy_thresh/easy_thresh.py old mode 100755 new mode 100644 diff --git a/CPAC/func_preproc/__init__.py b/CPAC/func_preproc/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/func_preproc/func_ingress.py b/CPAC/func_preproc/func_ingress.py old mode 100755 new mode 100644 diff --git a/CPAC/func_preproc/func_preproc.py b/CPAC/func_preproc/func_preproc.py old mode 100755 new mode 100644 diff --git a/CPAC/func_preproc/utils.py b/CPAC/func_preproc/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/generate_motion_statistics/__init__.py b/CPAC/generate_motion_statistics/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/generate_motion_statistics/generate_motion_statistics.py b/CPAC/generate_motion_statistics/generate_motion_statistics.py old mode 100755 new mode 100644 diff --git a/CPAC/generate_motion_statistics/test/test_dvars.py b/CPAC/generate_motion_statistics/test/test_dvars.py old mode 100755 new mode 100644 diff --git a/CPAC/group_analysis/__init__.py b/CPAC/group_analysis/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/group_analysis/group_analysis.py b/CPAC/group_analysis/group_analysis.py old mode 100755 new mode 100644 diff --git a/CPAC/image_utils/__init__.py b/CPAC/image_utils/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/image_utils/spatial_smoothing.py b/CPAC/image_utils/spatial_smoothing.py old mode 100755 new mode 100644 diff --git a/CPAC/image_utils/statistical_transforms.py b/CPAC/image_utils/statistical_transforms.py old mode 100755 new mode 100644 diff --git a/CPAC/image_utils/tests/test_smooth.py b/CPAC/image_utils/tests/test_smooth.py old mode 100755 new mode 100644 diff --git a/CPAC/info.py b/CPAC/info.py old mode 100755 new mode 100644 diff --git a/CPAC/isc/__init__.py b/CPAC/isc/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/isc/isc.py b/CPAC/isc/isc.py old mode 100755 new mode 100644 diff --git a/CPAC/isc/isfc.py b/CPAC/isc/isfc.py old mode 100755 new mode 100644 diff --git a/CPAC/isc/pipeline.py b/CPAC/isc/pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/isc/tests/test_pipeline_isc.py b/CPAC/isc/tests/test_pipeline_isc.py old mode 100755 new mode 100644 diff --git a/CPAC/isc/utils.py b/CPAC/isc/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/longitudinal_pipeline/longitudinal_preproc.py b/CPAC/longitudinal_pipeline/longitudinal_preproc.py old mode 100755 new mode 100644 diff --git a/CPAC/longitudinal_pipeline/longitudinal_workflow.py b/CPAC/longitudinal_pipeline/longitudinal_workflow.py old mode 100755 new mode 100644 diff --git a/CPAC/median_angle/median_angle.py b/CPAC/median_angle/median_angle.py old mode 100755 new mode 100644 diff --git a/CPAC/network_centrality/__init__.py b/CPAC/network_centrality/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/network_centrality/network_centrality.py b/CPAC/network_centrality/network_centrality.py old mode 100755 new mode 100644 diff --git a/CPAC/network_centrality/pipeline.py b/CPAC/network_centrality/pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/network_centrality/utils.py b/CPAC/network_centrality/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/__init__.py b/CPAC/nuisance/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/bandpass.py b/CPAC/nuisance/bandpass.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/nuisance.py b/CPAC/nuisance/nuisance.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/tests/motion_statistics/DVARS.1D b/CPAC/nuisance/tests/motion_statistics/DVARS.1D old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/tests/motion_statistics/FD_J.1D b/CPAC/nuisance/tests/motion_statistics/FD_J.1D old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/tests/motion_statistics/FD_P.1D b/CPAC/nuisance/tests/motion_statistics/FD_P.1D old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/tests/test_nuisance_representations.py b/CPAC/nuisance/tests/test_nuisance_representations.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/tests/test_utils.py b/CPAC/nuisance/tests/test_utils.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/utils/__init__.py b/CPAC/nuisance/utils/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/utils/compcor.py b/CPAC/nuisance/utils/compcor.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/utils/convolve.py b/CPAC/nuisance/utils/convolve.py old mode 100755 new mode 100644 diff --git a/CPAC/nuisance/utils/crc.py b/CPAC/nuisance/utils/crc.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/__init__.py b/CPAC/pipeline/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/check_outputs.py b/CPAC/pipeline/check_outputs.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/cpac_basc_pipeline.py b/CPAC/pipeline/cpac_basc_pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/cpac_cwas_pipeline.py b/CPAC/pipeline/cpac_cwas_pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/cpac_group_runner.py b/CPAC/pipeline/cpac_group_runner.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/cpac_randomise_pipeline.py b/CPAC/pipeline/cpac_randomise_pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/cpac_runner.py b/CPAC/pipeline/cpac_runner.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py old mode 100755 new mode 100644 index 63175e1328..feea236b3b --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1185,6 +1185,10 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): warnings.warn(str( LookupError("\n[!] No atlas ID found for " f"{out_dct['filename']}.\n"))) +<<<<<<< HEAD +======= + +>>>>>>> parent of 982d44eb2 (commiting all files modified) nii_name = pe.Node(Rename(), name=f'nii_{resource_idx}_' f'{pipe_x}') nii_name.inputs.keep_ext = True @@ -1208,7 +1212,10 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): nii_name, 'format_string') node, out = self.rpool[resource][pipe_idx]['data'] +<<<<<<< HEAD +======= +>>>>>>> parent of 982d44eb2 (commiting all files modified) try: wf.connect(node, out, nii_name, 'in_file') except OSError as os_error: diff --git a/CPAC/pipeline/nipype_pipeline_engine/__init__.py b/CPAC/pipeline/nipype_pipeline_engine/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/nipype_pipeline_engine/engine.py b/CPAC/pipeline/nipype_pipeline_engine/engine.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/__init__.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/legacymultiproc.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/legacymultiproc.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/multiproc.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/multiproc.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/random_state/__init__.py b/CPAC/pipeline/random_state/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/random_state/seed.py b/CPAC/pipeline/random_state/seed.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/__init__.py b/CPAC/pipeline/test/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/issue_1606_data_config.yml b/CPAC/pipeline/test/issue_1606_data_config.yml old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/sample_data.py b/CPAC/pipeline/test/sample_data.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/test_cpac_group_runner.py b/CPAC/pipeline/test/test_cpac_group_runner.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/test_cpac_pipeline.py b/CPAC/pipeline/test/test_cpac_pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/test_cpac_runner.py b/CPAC/pipeline/test/test_cpac_runner.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/test_engine.py b/CPAC/pipeline/test/test_engine.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/test_nipype_pipeline_engine.py b/CPAC/pipeline/test/test_nipype_pipeline_engine.py old mode 100755 new mode 100644 diff --git a/CPAC/pipeline/test/test_schema_validation.py b/CPAC/pipeline/test/test_schema_validation.py old mode 100755 new mode 100644 diff --git a/CPAC/pypeer/__init__.py b/CPAC/pypeer/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/pypeer/peer.py b/CPAC/pypeer/peer.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/__init__.py b/CPAC/qc/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/colors/blue.txt b/CPAC/qc/colors/blue.txt old mode 100755 new mode 100644 diff --git a/CPAC/qc/colors/cyan_to_yellow.txt b/CPAC/qc/colors/cyan_to_yellow.txt old mode 100755 new mode 100644 diff --git a/CPAC/qc/colors/green.txt b/CPAC/qc/colors/green.txt old mode 100755 new mode 100644 diff --git a/CPAC/qc/colors/red.txt b/CPAC/qc/colors/red.txt old mode 100755 new mode 100644 diff --git a/CPAC/qc/colors/red_to_blue.txt b/CPAC/qc/colors/red_to_blue.txt old mode 100755 new mode 100644 diff --git a/CPAC/qc/data/index.html b/CPAC/qc/data/index.html old mode 100755 new mode 100644 diff --git a/CPAC/qc/pipeline.py b/CPAC/qc/pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/qc.py b/CPAC/qc/qc.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/qcmetrics.py b/CPAC/qc/qcmetrics.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/tests/test_qc.py b/CPAC/qc/tests/test_qc.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/utils.py b/CPAC/qc/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/qc/xcp.py b/CPAC/qc/xcp.py old mode 100755 new mode 100644 diff --git a/CPAC/qpp/__init__.py b/CPAC/qpp/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/qpp/pipeline.py b/CPAC/qpp/pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/qpp/qpp.py b/CPAC/qpp/qpp.py old mode 100755 new mode 100644 diff --git a/CPAC/qpp/tests/test_qpp.py b/CPAC/qpp/tests/test_qpp.py old mode 100755 new mode 100644 diff --git a/CPAC/randomise/__init__.py b/CPAC/randomise/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/randomise/pipeline.py b/CPAC/randomise/pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/randomise/randomise.py b/CPAC/randomise/randomise.py old mode 100755 new mode 100644 diff --git a/CPAC/randomise/test_randomise.py b/CPAC/randomise/test_randomise.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/__init__.py b/CPAC/registration/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/output_func_to_standard.py b/CPAC/registration/output_func_to_standard.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/registration.py b/CPAC/registration/registration.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/tests/__init__.py b/CPAC/registration/tests/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/tests/mocks.py b/CPAC/registration/tests/mocks.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/tests/test_ants_apply_warp.py b/CPAC/registration/tests/test_ants_apply_warp.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/tests/test_apply_transform.py b/CPAC/registration/tests/test_apply_transform.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/tests/test_output_func_to_standard.py b/CPAC/registration/tests/test_output_func_to_standard.py old mode 100755 new mode 100644 diff --git a/CPAC/registration/utils.py b/CPAC/registration/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/reho/__init__.py b/CPAC/reho/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/reho/reho.py b/CPAC/reho/reho.py old mode 100755 new mode 100644 diff --git a/CPAC/reho/utils.py b/CPAC/reho/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/resources/MSMConfig/MSMSulcStrainFinalconf b/CPAC/resources/MSMConfig/MSMSulcStrainFinalconf old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/1.7-1.8-deprecations.yml b/CPAC/resources/configs/1.7-1.8-deprecations.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/1.7-1.8-nesting-mappings.yml b/CPAC/resources/configs/1.7-1.8-nesting-mappings.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/ADHD200_participants.csv b/CPAC/resources/configs/test_configs/ADHD200_participants.csv old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/ADHD200_participants_age.tsv b/CPAC/resources/configs/test_configs/ADHD200_participants_age.tsv old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_1.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml b/CPAC/resources/configs/test_configs/data-test_S3-ADHD200_no-params.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml b/CPAC/resources/configs/test_configs/data-test_S3-NKI-RS_fmap.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/data-test_human.yml b/CPAC/resources/configs/test_configs/data-test_human.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-sess.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml b/CPAC/resources/configs/test_configs/pipe-test_ABCD.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml old mode 100755 new mode 100644 diff --git a/CPAC/resources/cpac_templates.csv b/CPAC/resources/cpac_templates.csv old mode 100755 new mode 100644 diff --git a/CPAC/resources/global/scripts/log.shlib b/CPAC/resources/global/scripts/log.shlib old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii b/CPAC/resources/templates/mni_icbm152_t1_tal_nlin_asym_09c.nii old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/ndmg_atlases.csv b/CPAC/resources/templates/ndmg_atlases.csv old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_mask.nii.gz old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_probseg.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_desc-brain_probseg.nii.gz old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-01_label-brain_probseg.nii.gz old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_T1w_reference.nii.gz old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz old mode 100755 new mode 100644 diff --git a/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz b/CPAC/resources/templates/tpl-MNI152NLin2009cAsym_res-02_desc-fMRIPrep_boldref.nii.gz old mode 100755 new mode 100644 diff --git a/CPAC/sca/README.txt b/CPAC/sca/README.txt old mode 100755 new mode 100644 diff --git a/CPAC/sca/__init__.py b/CPAC/sca/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/sca/sca.py b/CPAC/sca/sca.py old mode 100755 new mode 100644 diff --git a/CPAC/sca/utils.py b/CPAC/sca/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/scrubbing/__init__.py b/CPAC/scrubbing/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/scrubbing/scrubbing.py b/CPAC/scrubbing/scrubbing.py old mode 100755 new mode 100644 diff --git a/CPAC/seg_preproc/__init__.py b/CPAC/seg_preproc/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/seg_preproc/utils.py b/CPAC/seg_preproc/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/surface/PostFreeSurfer/FreeSurfer2CaretConvertAndRegisterNonlinear.sh b/CPAC/surface/PostFreeSurfer/FreeSurfer2CaretConvertAndRegisterNonlinear.sh old mode 100755 new mode 100644 diff --git a/CPAC/surface/PostFreeSurfer/run.sh b/CPAC/surface/PostFreeSurfer/run.sh old mode 100755 new mode 100644 diff --git a/CPAC/surface/fMRISurface/CreateDenseTimeseries.sh b/CPAC/surface/fMRISurface/CreateDenseTimeseries.sh old mode 100755 new mode 100644 diff --git a/CPAC/surface/fMRISurface/RibbonVolumeToSurfaceMapping.sh b/CPAC/surface/fMRISurface/RibbonVolumeToSurfaceMapping.sh old mode 100755 new mode 100644 diff --git a/CPAC/surface/fMRISurface/SubcorticalProcessing.sh b/CPAC/surface/fMRISurface/SubcorticalProcessing.sh old mode 100755 new mode 100644 diff --git a/CPAC/surface/fMRISurface/SurfaceSmoothing.sh b/CPAC/surface/fMRISurface/SurfaceSmoothing.sh old mode 100755 new mode 100644 diff --git a/CPAC/surface/tests/test_config.py b/CPAC/surface/tests/test_config.py old mode 100755 new mode 100644 diff --git a/CPAC/timeseries/__init__.py b/CPAC/timeseries/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/timeseries/timeseries_analysis.py b/CPAC/timeseries/timeseries_analysis.py old mode 100755 new mode 100644 diff --git a/CPAC/unet/__init__.py b/CPAC/unet/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/unet/function.py b/CPAC/unet/function.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/README.txt b/CPAC/utils/README.txt old mode 100755 new mode 100644 diff --git a/CPAC/utils/__init__.py b/CPAC/utils/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/build_data_config.py b/CPAC/utils/build_data_config.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/create_flame_model_files.py b/CPAC/utils/create_flame_model_files.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/create_fsl_flame_preset.py b/CPAC/utils/create_fsl_flame_preset.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/create_fsl_model.py b/CPAC/utils/create_fsl_model.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/create_group_analysis_info_files.py b/CPAC/utils/create_group_analysis_info_files.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/datasource.py b/CPAC/utils/datasource.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/docs.py b/CPAC/utils/docs.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/extract_data.py b/CPAC/utils/extract_data.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/extract_data_multiscan.py b/CPAC/utils/extract_data_multiscan.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/extract_parameters.py b/CPAC/utils/extract_parameters.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/ga.py b/CPAC/utils/ga.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/__init__.py b/CPAC/utils/interfaces/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/ants.py b/CPAC/utils/interfaces/ants.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/brickstat.py b/CPAC/utils/interfaces/brickstat.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/datasink.py b/CPAC/utils/interfaces/datasink.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/fixes.py b/CPAC/utils/interfaces/fixes.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/fsl.py b/CPAC/utils/interfaces/fsl.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/function/__init__.py b/CPAC/utils/interfaces/function/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/function/function.py b/CPAC/utils/interfaces/function/function.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/function/seg_preproc.py b/CPAC/utils/interfaces/function/seg_preproc.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/masktool.py b/CPAC/utils/interfaces/masktool.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/netcorr.py b/CPAC/utils/interfaces/netcorr.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/pc.py b/CPAC/utils/interfaces/pc.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/tests/__init__.py b/CPAC/utils/interfaces/tests/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/tests/test_fsl.py b/CPAC/utils/interfaces/tests/test_fsl.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/interfaces/utils.py b/CPAC/utils/interfaces/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/misc.py b/CPAC/utils/misc.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/monitoring/__init__.py b/CPAC/utils/monitoring/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/monitoring/config.py b/CPAC/utils/monitoring/config.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/monitoring/draw_gantt_chart.py b/CPAC/utils/monitoring/draw_gantt_chart.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/monitoring/monitoring.py b/CPAC/utils/monitoring/monitoring.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/ndmg_utils.py b/CPAC/utils/ndmg_utils.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/nifti_utils.py b/CPAC/utils/nifti_utils.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/outputs.py b/CPAC/utils/outputs.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/strategy.py b/CPAC/utils/strategy.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/symlinks.py b/CPAC/utils/symlinks.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/test_init.py b/CPAC/utils/test_init.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/test_mocks.py b/CPAC/utils/test_mocks.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/test_resources.py b/CPAC/utils/test_resources.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/__init__.py b/CPAC/utils/tests/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_bids_utils.py b/CPAC/utils/tests/test_bids_utils.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_crash.py b/CPAC/utils/tests/test_crash.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_datasource.py b/CPAC/utils/tests/test_datasource.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_function.py b/CPAC/utils/tests/test_function.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_s3.py b/CPAC/utils/tests/test_s3.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_symlinks-outputs.txt b/CPAC/utils/tests/test_symlinks-outputs.txt old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_symlinks.py b/CPAC/utils/tests/test_symlinks.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_trimmer.py b/CPAC/utils/tests/test_trimmer.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_utils.py b/CPAC/utils/tests/test_utils.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/tests/test_yaml.py b/CPAC/utils/tests/test_yaml.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/trimmer.py b/CPAC/utils/trimmer.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/utils.py b/CPAC/utils/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/vmhc/__init__.py b/CPAC/vmhc/__init__.py old mode 100755 new mode 100644 diff --git a/CPAC/vmhc/tests/test_vmhc.py b/CPAC/vmhc/tests/test_vmhc.py old mode 100755 new mode 100644 diff --git a/CPAC/vmhc/utils.py b/CPAC/vmhc/utils.py old mode 100755 new mode 100644 diff --git a/CPAC/vmhc/vmhc.py b/CPAC/vmhc/vmhc.py old mode 100755 new mode 100644 diff --git a/Dockerfile b/Dockerfile old mode 100755 new mode 100644 diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/dev/ami_data/setup.sh b/dev/ami_data/setup.sh old mode 100755 new mode 100644 diff --git a/dev/ami_data/setup_cpac.sh b/dev/ami_data/setup_cpac.sh old mode 100755 new mode 100644 diff --git a/dev/circleci_data/__init__.py b/dev/circleci_data/__init__.py old mode 100755 new mode 100644 diff --git a/dev/circleci_data/data_settings_bids_examples_ds051_default_BIDS.yml b/dev/circleci_data/data_settings_bids_examples_ds051_default_BIDS.yml old mode 100755 new mode 100644 diff --git a/dev/circleci_data/generate_run_command.py b/dev/circleci_data/generate_run_command.py old mode 100755 new mode 100644 diff --git a/dev/circleci_data/pipe-test_ci.yml b/dev/circleci_data/pipe-test_ci.yml old mode 100755 new mode 100644 diff --git a/dev/circleci_data/pytest.ini b/dev/circleci_data/pytest.ini old mode 100755 new mode 100644 diff --git a/dev/circleci_data/python_2_pickle.pkl b/dev/circleci_data/python_2_pickle.pkl old mode 100755 new mode 100644 diff --git a/dev/circleci_data/python_2_pickle.pklz b/dev/circleci_data/python_2_pickle.pklz old mode 100755 new mode 100644 diff --git a/dev/circleci_data/requirements.txt b/dev/circleci_data/requirements.txt old mode 100755 new mode 100644 diff --git a/dev/circleci_data/test_external_utils.py b/dev/circleci_data/test_external_utils.py old mode 100755 new mode 100644 diff --git a/dev/circleci_data/test_install.py b/dev/circleci_data/test_install.py old mode 100755 new mode 100644 diff --git a/dev/docker_data/default_pipeline.yml b/dev/docker_data/default_pipeline.yml old mode 100755 new mode 100644 diff --git a/dev/docker_data/license.txt b/dev/docker_data/license.txt old mode 100755 new mode 100644 diff --git a/dev/docker_data/required_afni_pkgs.txt b/dev/docker_data/required_afni_pkgs.txt old mode 100755 new mode 100644 diff --git a/dev/docker_data/required_freesurfer_pkgs.txt b/dev/docker_data/required_freesurfer_pkgs.txt old mode 100755 new mode 100644 diff --git a/dev/rc_tests/README.md b/dev/rc_tests/README.md old mode 100755 new mode 100644 diff --git a/requirements.txt b/requirements.txt old mode 100755 new mode 100644 diff --git a/scripts/cpac b/scripts/cpac old mode 100755 new mode 100644 diff --git a/variant-ABCD-HCP.Dockerfile b/variant-ABCD-HCP.Dockerfile old mode 100755 new mode 100644 diff --git a/variant-fMRIPrep-LTS.Dockerfile b/variant-fMRIPrep-LTS.Dockerfile old mode 100755 new mode 100644 diff --git a/variant-lite.Dockerfile b/variant-lite.Dockerfile old mode 100755 new mode 100644 diff --git a/version b/version old mode 100755 new mode 100644 From 9d2d4af92b5b2044c2444b35b85b00979e294dfe Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 13 Feb 2024 10:20:06 -0500 Subject: [PATCH 180/213] :wrench: Fix commit error in engine.py --- CPAC/pipeline/engine.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index feea236b3b..e6d6f63d3f 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1185,10 +1185,6 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): warnings.warn(str( LookupError("\n[!] No atlas ID found for " f"{out_dct['filename']}.\n"))) -<<<<<<< HEAD -======= - ->>>>>>> parent of 982d44eb2 (commiting all files modified) nii_name = pe.Node(Rename(), name=f'nii_{resource_idx}_' f'{pipe_x}') nii_name.inputs.keep_ext = True @@ -1212,10 +1208,6 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): nii_name, 'format_string') node, out = self.rpool[resource][pipe_idx]['data'] -<<<<<<< HEAD - -======= ->>>>>>> parent of 982d44eb2 (commiting all files modified) try: wf.connect(node, out, nii_name, 'in_file') except OSError as os_error: From ab4d4e188882094e69d05da6d07942604292b5d4 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 13 Feb 2024 11:49:04 -0500 Subject: [PATCH 181/213] Minor changes to outputs tsv --- CPAC/resources/cpac_outputs.tsv | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) mode change 100755 => 100644 CPAC/resources/cpac_outputs.tsv diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv old mode 100755 new mode 100644 index a57ce2575c..0054e71367 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -98,17 +98,11 @@ space-T1w_desc-eroded_mask mask T1w anat NIfTI space-template_desc-brain_mask mask template anat NIfTI space-template_desc-bold_mask mask template func NIfTI space-template_res-derivative_desc-bold_mask mask template func NIfTI -dvars motion func text -framewise-displacement-jenkinson motion func 1D -framewise-displacement-power motion func 1D -max-displacement motion func 1D -motion-filter-info motion func text +motion motion func TSV +desc-summary_motion motion func TSV motion-filter-plot motion func png -motion-params motion func text -movement-parameters motion func 1D -filtered-movement-parameters motion func 1D -power-params motion func text -rels-displacement motion func 1D +desc-movementParameters_motion motion func TSV +desc-movementParametersUnfiltered_motion motion func TSV label-CSF_probseg probseg T1w anat NIfTI label-GM_probseg probseg T1w anat NIfTI label-WM_probseg probseg T1w anat NIfTI @@ -127,7 +121,7 @@ desc-boldSnrSagittal_quality qc func png desc-boldSnrHist_quality qc func png desc-boldSnr_quality qc func png space-template_desc-xcp_quality qc func tsv -regressors regressors func 1D +desc-confounds_timeseries regressors func 1D desc-sm_reho reho functional func NIfTI Yes desc-sm-zstd_reho reho functional func NIfTI desc-zstd_reho reho functional func NIfTI @@ -223,6 +217,7 @@ space-EPItemplate_label-WM_mask mask template func NIfTI space-EPItemplate_label-GM_mask mask template func NIfTI mdmr group functional group_analysis NIfTI desc-zstd-mdmr group functional group_analysis NIfTI Yes +dseg anat AtlasSubcortical-s2 surface_derived func space-fsLR_den-32k_bold surface_derived func CIFTI dtseries goodvoxels surface_derived func From 9d69709fdca082b0cda2a54a62a2fe6d07a5942a Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Wed, 14 Feb 2024 11:03:01 -0500 Subject: [PATCH 182/213] Make files not executable --- CPAC/seg_preproc/seg_preproc.py | 0 CPAC/utils/configuration/configuration.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 CPAC/seg_preproc/seg_preproc.py mode change 100755 => 100644 CPAC/utils/configuration/configuration.py diff --git a/CPAC/seg_preproc/seg_preproc.py b/CPAC/seg_preproc/seg_preproc.py old mode 100755 new mode 100644 diff --git a/CPAC/utils/configuration/configuration.py b/CPAC/utils/configuration/configuration.py old mode 100755 new mode 100644 From 9eba69ade3b84489dd409d4ad14bc14acae03660 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Wed, 14 Feb 2024 11:05:16 -0500 Subject: [PATCH 183/213] Remove extraneous files --- run-with-freesurfer.sh | 0 run.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 run-with-freesurfer.sh delete mode 100755 run.py diff --git a/run-with-freesurfer.sh b/run-with-freesurfer.sh deleted file mode 100755 index e69de29bb2..0000000000 diff --git a/run.py b/run.py deleted file mode 100755 index e69de29bb2..0000000000 From 21de213411fc792ae704c88a4df31343870d81ba Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Wed, 14 Feb 2024 11:09:01 -0500 Subject: [PATCH 184/213] :wrench: Fix merge conflict --- .../test_configs/data_config_S3_CoRR_5only_mult-scan.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml index 83c5b8deca..10624b5022 100644 --- a/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml +++ b/CPAC/resources/configs/test_configs/data_config_S3_CoRR_5only_mult-scan.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD # Version 1.8.6.dev1 -======= -# Version 1.8.6.dev1 ->>>>>>> 5ab54c88b12c8f704c701dd90de7d5897d0adf34 # # http://fcp-indi.github.io for more info. # From 373efff10bb5c2933111b703afde2e132debf2da Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 15 Feb 2024 13:08:27 -0500 Subject: [PATCH 185/213] Fix merge error output.tsv --- CPAC/resources/cpac_outputs.tsv | 224 +------------------------------- 1 file changed, 1 insertion(+), 223 deletions(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index f89afb4cb7..9ccf73cded 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -309,226 +309,4 @@ space-fsLR_den-32k_bold_surf_falff surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf_alff surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf-L_reho surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf-R_reho surface_derived func CIFTI dscalar -space-fsLR_den-32k_bold_surf-correlation_matrix surface_derived func CIFTI pconn -======= -Resource Type Space Sub-Directory File To Smooth To z-std 4D Time Series Optional: Debugging Multi-File -alff alff functional func NIfTI Yes Yes -desc-sm_alff alff functional func NIfTI Yes -desc-sm-zstd_alff alff functional func NIfTI -desc-zstd_alff alff functional func NIfTI -space-template_alff alff template func NIfTI Yes Yes -space-template_desc-sm_alff alff template func NIfTI Yes -space-template_desc-sm-zstd_alff alff template func NIfTI -space-template_desc-zstd_alff alff template func NIfTI -desc-brain_bold bold functional func NIfTI Yes Yes -desc-mean_bold bold functional func NIfTI -desc-motion_bold bold functional func NIfTI Yes Yes -desc-preproc_bold bold functional func NIfTI Yes -desc-sm_bold bold functional func NIfTI Yes Yes -sbref bold functional func NIfTI -space-EPItemplate_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes Yes -space-EPItemplate_desc-mean_bold bold EPI template func NIfTI -space-EPItemplate_desc-preproc_bold bold EPI template func NIfTI Yes -space-symtemplate_desc-sm_bold bold symmetric template func NIfTI Yes Yes -space-T1w_sbref bold T1w func NIfTI -space-template_bold bold template func NIfTI Yes -space-template_desc-brain_bold bold template func NIfTI Yes Yes -space-template_desc-head_bold bold template func NIfTI Yes -space-template_desc-mean_bold bold template func NIfTI -space-template_desc-preproc_bold bold template func NIfTI Yes -space-template_desc-scout_bold bold template func NIfTI -space-template_sbref bold template func NIfTI -space-template_desc-DualReg_correlations correlation template func NIfTI -space-template_desc-MeanSCA_correlations correlation template func NIfTI -space-template_desc-MultReg_correlations correlation template func NIfTI -space-template_desc-ndmg_correlations correlation template func NIfTI -space-template_desc-PearsonAfni_correlations correlation template func tsv -space-template_desc-PartialAfni_correlations correlation template func tsv -space-template_desc-PearsonNilearn_correlations correlation template func tsv -space-template_desc-PartialNilearn_correlations correlation template func tsv -space-template_dcb degree-centrality template func NIfTI Yes Yes -space-template_desc-sm_dcb degree-centrality template func NIfTI Yes -space-template_desc-sm-zstd_dcb degree-centrality template func NIfTI -space-template_desc-zstd_dcb degree-centrality template func NIfTI -space-template_dcw degree-centrality template func NIfTI Yes Yes -space-template_desc-sm_dcw degree-centrality template func NIfTI Yes -space-template_desc-sm-zstd_dcw degree-centrality template func NIfTI -space-template_desc-zstd_dcw degree-centrality template func NIfTI -space-template_ecb eigen-centrality template func NIfTI Yes Yes -space-template_desc-sm_ecb eigen-centrality template func NIfTI Yes -space-template_desc-sm-zstd_ecb eigen-centrality template func NIfTI -space-template_desc-zstd_ecb eigen-centrality template func NIfTI -space-template_ecw eigen-centrality template func NIfTI Yes Yes -space-template_desc-sm_ecw eigen-centrality template func NIfTI Yes -space-template_desc-sm-zstd_ecw eigen-centrality template func NIfTI -space-template_desc-zstd_ecw eigen-centrality template func NIfTI -desc-sm_falff falff functional func NIfTI Yes -desc-sm-zstd_falff falff functional func NIfTI -desc-zstd_falff falff functional func NIfTI -falff falff functional func NIfTI Yes Yes -space-template_desc-sm_falff falff template func NIfTI Yes -space-template_desc-sm-zstd_falff falff template func NIfTI -space-template_desc-zstd_falff falff template func NIfTI -space-template_falff falff template func NIfTI Yes Yes -space-template_lfcdb lfcd template func NIfTI Yes Yes -space-template_desc-sm_lfcdb lfcd template func NIfTI Yes -space-template_desc-sm-zstd_lfcdb lfcd template func NIfTI -space-template_desc-zstd_lfcdb lfcd template func NIfTI -space-template_lfcdw lfcd template func NIfTI Yes Yes -space-template_desc-sm_lfcdw lfcd template func NIfTI Yes -space-template_desc-sm-zstd_lfcdw lfcd template func NIfTI -space-template_desc-zstd_lfcdw lfcd template func NIfTI -space-EPItemplate_desc-bold_mask mask EPI template func NIfTI -space-EPItemplate_res-derivative_desc-bold_mask mask EPI template func NIfTI -space-bold_desc-brain_mask mask functional func NIfTI -space-bold_desc-eroded_mask mask functional func NIfTI -space-bold_label-CSF_desc-eroded_mask mask functional func NIfTI -space-bold_label-CSF_mask mask functional func NIfTI -space-bold_label-GM_desc-eroded_mask mask functional func NIfTI -space-bold_label-GM_mask mask functional func NIfTI -space-bold_label-WM_desc-eroded_mask mask functional func NIfTI -space-bold_label-WM_mask mask functional func NIfTI -space-longitudinal_desc-brain_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-CSF_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-CSF_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-GM_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-GM_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-WM_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-WM_mask mask longitudinal T1w anat NIfTI -label-CSF_desc-eroded_mask mask T1w anat NIfTI -label-CSF_desc-preproc_mask mask T1w anat NIfTI -label-CSF_mask mask T1w anat NIfTI -label-GM_desc-eroded_mask mask T1w anat NIfTI -label-GM_desc-preproc_mask mask T1w anat NIfTI -label-GM_mask mask T1w anat NIfTI -label-WM_desc-eroded_mask mask T1w anat NIfTI -label-WM_desc-preproc_mask mask T1w anat NIfTI -label-WM_mask mask T1w anat NIfTI -space-T1w_desc-acpcbrain_mask mask T1w anat NIfTI -space-T1w_desc-brain_mask mask T1w anat NIfTI -space-T1w_desc-eroded_mask mask T1w anat NIfTI -space-template_desc-brain_mask mask template anat NIfTI -space-template_desc-bold_mask mask template func NIfTI -space-template_res-derivative_desc-bold_mask mask template func NIfTI -motion motion func TSV -desc-summary_motion motion func TSV -dvars motion func TSV Yes -motion-filter-plot motion func png -desc-movementParameters_motion motion func TSV -desc-movementParametersUnfiltered_motion motion func TSV -label-CSF_probseg probseg T1w anat NIfTI -label-GM_probseg probseg T1w anat NIfTI -label-WM_probseg probseg T1w anat NIfTI -desc-T1wAxial_quality qc anat png -desc-T1wSagittal_quality qc anat png -desc-dsegAxial_quality qc anat png -desc-dsegSagittal_quality qc anat png -desc-boldAxial_quality qc func png -desc-boldSagittal_quality qc func png -desc-boldCarpet_quality qc func png -desc-framewiseDisplacementJenkinsonPlot_quality qc func png -desc-movementParametersTrans_quality qc func png -desc-movementParametersRot_quality qc func png -desc-boldSnrAxial_quality qc func png -desc-boldSnrSagittal_quality qc func png -desc-boldSnrHist_quality qc func png -desc-boldSnr_quality qc func png -space-template_desc-xcp_quality qc func tsv -desc-confounds_timeseries regressors func 1D -desc-sm_reho reho functional func NIfTI Yes -desc-sm-zstd_reho reho functional func NIfTI -desc-zstd_reho reho functional func NIfTI -reho reho functional func NIfTI Yes Yes -space-template_desc-sm_reho reho template func NIfTI Yes -space-template_desc-sm-zstd_reho reho template func NIfTI -space-template_desc-zstd_reho reho template func NIfTI -space-template_reho reho template func NIfTI Yes Yes -desc-DualReg_statmap statistic template func NIfTI -desc-MultReg_statmap statistic template func NIfTI -hemi-L_desc-surfaceMap_thickness surface-derived anat Yes -hemi-R_desc-surfaceMap_thickness surface-derived anat Yes -hemi-L_desc-surfaceMap_volume surface-derived anat Yes -hemi-R_desc-surfaceMap_volume surface-derived anat Yes -hemi-L_desc-surfaceMesh_pial surface-derived anat -hemi-R_desc-surfaceMesh_pial surface-derived anat -raw-average surface-derived anat -hemi-L_desc-surfaceMesh_smoothwm surface-derived anat -hemi-R_desc-surfaceMesh_smoothwm surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-32k_dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-32k_dlabel surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-164k_dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-164k_dlabel surface-derived anat -space-fsLR_den-32k_bold-dtseries surface-derived func -hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes -hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes -hemi-L_desc-surfaceMap_sulc surface-derived anat Yes -hemi-R_desc-surfaceMap_sulc surface-derived anat Yes -hemi-L_desc-surface_curv surface-derived anat -hemi-R_desc-surface_curv surface-derived anat -hemi-L_desc-surfaceMesh_white surface-derived anat Yes -hemi-R_desc-surfaceMesh_white surface-derived anat Yes -wmparc surface-derived anat Yes -space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI Yes -desc-brain_T1w T1w T1w anat NIfTI Yes -desc-head_T1w T1w T1w anat NIfTI -desc-preproc_T1w T1w T1w anat NIfTI -desc-reorient_T1w T1w T1w anat NIfTI Yes -desc-restore_T1w T1w T1w anat NIfTI -desc-restore-brain_T1w T1w T1w anat NIfTI -space-template_desc-brain_T1w T1w template anat NIfTI Yes -space-template_desc-preproc_T1w T1w template anat NIfTI -space-template_desc-head_T1w T1w template anat NIfTI -space-template_desc-T1w_mask mask template anat NIfTI -space-template_desc-Mean_timeseries timeseries func 1D -desc-MeanSCA_timeseries timeseries func 1D -desc-SpatReg_timeseries timeseries func 1D -desc-Voxel_timeseries timeseries func 1D -space-longitudinal_label-CSF_probseg tissue probability longitudinal T1w anat NIfTI -space-longitudinal_label-GM_probseg tissue probability longitudinal T1w anat NIfTI -space-longitudinal_label-WM_probseg tissue probability longitudinal T1w anat NIfTI -vmhc vmhc symmetric template func NIfTI -blip-warp xfm func NIfTI -from-bold_to-EPItemplate_mode-image_desc-linear_xfm xfm func NIfTI -from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm xfm func NIfTI -from-bold_to-EPItemplate_mode-image_xfm xfm func NIfTI -from-bold_to-symtemplate_mode-image_xfm xfm func NIfTI -from-bold_to-T1w_mode-image_desc-linear_xfm xfm func NIfTI -from-bold_to-template_mode-image_xfm xfm func NIfTI -from-EPItemplate_to-bold_mode-image_desc-linear_xfm xfm func NIfTI -from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm xfm func NIfTI -from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI -from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-longitudinal_to-symtemplate_mode-image_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_desc-linear_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_xfm xfm anat NIfTI -from-symtemplate_to-bold_mode-image_xfm xfm func NIfTI -from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI -from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-symtemplate_to-longitudinal_mode-image_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_desc-linear_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_xfm xfm anat NIfTI -from-template_to-bold_mode-image_xfm xfm func NIfTI -from-template_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI -from-template_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-template_to-longitudinal_mode-image_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_xfm xfm anat NIfTI -space-template_label-CSF_mask mask template anat NIfTI -space-template_label-WM_mask mask template anat NIfTI -space-template_label-GM_mask mask template anat NIfTI -space-EPItemplate_label-CSF_mask mask template func NIfTI -space-EPItemplate_label-WM_mask mask template func NIfTI -space-EPItemplate_label-GM_mask mask template func NIfTI -mdmr group functional group_analysis NIfTI -desc-zstd-mdmr group functional group_analysis NIfTI Yes -dseg anat +space-fsLR_den-32k_bold_surf-correlation_matrix surface_derived func CIFTI pconn \ No newline at end of file From b0ba82b2415d78ab7cfd1e4a83714b68ddf95423 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 15 Feb 2024 13:15:14 -0500 Subject: [PATCH 186/213] Fix tsv line endings --- CPAC/resources/cpac_outputs.tsv | 622 ++++++++++++++++---------------- 1 file changed, 311 insertions(+), 311 deletions(-) diff --git a/CPAC/resources/cpac_outputs.tsv b/CPAC/resources/cpac_outputs.tsv index 9ccf73cded..5a4593c82a 100644 --- a/CPAC/resources/cpac_outputs.tsv +++ b/CPAC/resources/cpac_outputs.tsv @@ -1,312 +1,312 @@ -Resource Type Space Sub-Directory File To Smooth To z-std 4D Time Series Optional: Debugging Multi-File -alff alff functional func NIfTI Yes Yes -desc-sm_alff alff functional func NIfTI Yes -desc-sm-zstd_alff alff functional func NIfTI -desc-zstd_alff alff functional func NIfTI -space-template_alff alff template func NIfTI Yes Yes -space-template_desc-sm_alff alff template func NIfTI Yes -space-template_desc-sm-zstd_alff alff template func NIfTI -space-template_desc-zstd_alff alff template func NIfTI -desc-brain_bold bold functional func NIfTI Yes Yes -desc-mean_bold bold functional func NIfTI -desc-motion_bold bold functional func NIfTI Yes Yes -desc-preproc_bold bold functional func NIfTI Yes -desc-sm_bold bold functional func NIfTI Yes Yes -sbref bold functional func NIfTI -space-EPItemplate_bold bold EPI template func NIfTI Yes -space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes Yes -space-EPItemplate_desc-mean_bold bold EPI template func NIfTI -space-EPItemplate_desc-preproc_bold bold EPI template func NIfTI Yes -space-symtemplate_desc-sm_bold bold symmetric template func NIfTI Yes Yes -space-T1w_sbref bold T1w func NIfTI -space-template_bold bold template func NIfTI Yes -space-template_desc-brain_bold bold template func NIfTI Yes Yes -space-template_desc-head_bold bold template func NIfTI Yes -space-template_desc-mean_bold bold template func NIfTI -space-template_desc-preproc_bold bold template func NIfTI Yes -space-template_desc-scout_bold bold template func NIfTI -space-template_sbref bold template func NIfTI -space-template_desc-DualReg_correlations correlation template func NIfTI -space-template_desc-MeanSCA_correlations correlation template func NIfTI -space-template_desc-MultReg_correlations correlation template func NIfTI -space-template_desc-ndmg_correlations correlation template func NIfTI -space-template_desc-PearsonAfni_correlations correlation template func tsv -space-template_desc-PartialAfni_correlations correlation template func tsv -space-template_desc-PearsonNilearn_correlations correlation template func tsv -space-template_desc-PartialNilearn_correlations correlation template func tsv -space-template_dcb degree-centrality template func NIfTI Yes Yes -space-template_desc-sm_dcb degree-centrality template func NIfTI Yes -space-template_desc-sm-zstd_dcb degree-centrality template func NIfTI -space-template_desc-zstd_dcb degree-centrality template func NIfTI -space-template_dcw degree-centrality template func NIfTI Yes Yes -space-template_desc-sm_dcw degree-centrality template func NIfTI Yes -space-template_desc-sm-zstd_dcw degree-centrality template func NIfTI -space-template_desc-zstd_dcw degree-centrality template func NIfTI -space-template_ecb eigen-centrality template func NIfTI Yes Yes -space-template_desc-sm_ecb eigen-centrality template func NIfTI Yes -space-template_desc-sm-zstd_ecb eigen-centrality template func NIfTI -space-template_desc-zstd_ecb eigen-centrality template func NIfTI -space-template_ecw eigen-centrality template func NIfTI Yes Yes -space-template_desc-sm_ecw eigen-centrality template func NIfTI Yes -space-template_desc-sm-zstd_ecw eigen-centrality template func NIfTI -space-template_desc-zstd_ecw eigen-centrality template func NIfTI -desc-sm_falff falff functional func NIfTI Yes -desc-sm-zstd_falff falff functional func NIfTI -desc-zstd_falff falff functional func NIfTI -falff falff functional func NIfTI Yes Yes -space-template_desc-sm_falff falff template func NIfTI Yes -space-template_desc-sm-zstd_falff falff template func NIfTI -space-template_desc-zstd_falff falff template func NIfTI -space-template_falff falff template func NIfTI Yes Yes -space-template_lfcdb lfcd template func NIfTI Yes Yes -space-template_desc-sm_lfcdb lfcd template func NIfTI Yes -space-template_desc-sm-zstd_lfcdb lfcd template func NIfTI -space-template_desc-zstd_lfcdb lfcd template func NIfTI -space-template_lfcdw lfcd template func NIfTI Yes Yes -space-template_desc-sm_lfcdw lfcd template func NIfTI Yes -space-template_desc-sm-zstd_lfcdw lfcd template func NIfTI -space-template_desc-zstd_lfcdw lfcd template func NIfTI -space-EPItemplate_desc-bold_mask mask EPI template func NIfTI -space-EPItemplate_res-derivative_desc-bold_mask mask EPI template func NIfTI -space-bold_desc-brain_mask mask functional func NIfTI -space-bold_desc-eroded_mask mask functional func NIfTI -space-bold_label-CSF_desc-eroded_mask mask functional func NIfTI -space-bold_label-CSF_mask mask functional func NIfTI -space-bold_label-GM_desc-eroded_mask mask functional func NIfTI -space-bold_label-GM_mask mask functional func NIfTI -space-bold_label-WM_desc-eroded_mask mask functional func NIfTI -space-bold_label-WM_mask mask functional func NIfTI -space-longitudinal_desc-brain_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-CSF_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-CSF_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-GM_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-GM_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-WM_desc-preproc_mask mask longitudinal T1w anat NIfTI -space-longitudinal_label-WM_mask mask longitudinal T1w anat NIfTI -label-CSF_desc-eroded_mask mask T1w anat NIfTI -label-CSF_desc-preproc_mask mask T1w anat NIfTI -label-CSF_mask mask T1w anat NIfTI -label-GM_desc-eroded_mask mask T1w anat NIfTI -label-GM_desc-preproc_mask mask T1w anat NIfTI -label-GM_mask mask T1w anat NIfTI -label-WM_desc-eroded_mask mask T1w anat NIfTI -label-WM_desc-preproc_mask mask T1w anat NIfTI -label-WM_mask mask T1w anat NIfTI -space-T1w_desc-acpcbrain_mask mask T1w anat NIfTI -space-T1w_desc-brain_mask mask T1w anat NIfTI -space-T1w_desc-eroded_mask mask T1w anat NIfTI -space-template_desc-brain_mask mask template anat NIfTI -space-template_desc-bold_mask mask template func NIfTI -space-template_res-derivative_desc-bold_mask mask template func NIfTI -motion motion func TSV -desc-summary_motion motion func TSV -motion-filter-plot motion func png -desc-movementParameters_motion motion func TSV -desc-movementParametersUnfiltered_motion motion func TSV -label-CSF_probseg probseg T1w anat NIfTI -label-GM_probseg probseg T1w anat NIfTI -label-WM_probseg probseg T1w anat NIfTI -desc-T1wAxial_quality qc anat png -desc-T1wSagittal_quality qc anat png -desc-dsegAxial_quality qc anat png -desc-dsegSagittal_quality qc anat png -desc-boldAxial_quality qc func png -desc-boldSagittal_quality qc func png -desc-boldCarpet_quality qc func png -desc-framewiseDisplacementJenkinsonPlot_quality qc func png -desc-movementParametersTrans_quality qc func png -desc-movementParametersRot_quality qc func png -desc-boldSnrAxial_quality qc func png -desc-boldSnrSagittal_quality qc func png -desc-boldSnrHist_quality qc func png -desc-boldSnr_quality qc func png -space-template_desc-xcp_quality qc func tsv -desc-confounds_timeseries regressors func 1D -desc-sm_reho reho functional func NIfTI Yes -desc-sm-zstd_reho reho functional func NIfTI -desc-zstd_reho reho functional func NIfTI -reho reho functional func NIfTI Yes Yes -space-template_desc-sm_reho reho template func NIfTI Yes -space-template_desc-sm-zstd_reho reho template func NIfTI -space-template_desc-zstd_reho reho template func NIfTI -space-template_reho reho template func NIfTI Yes Yes -desc-DualReg_statmap statistic template func NIfTI -desc-MultReg_statmap statistic template func NIfTI -hemi-L_desc-surfaceMap_thickness surface-derived anat Yes -hemi-R_desc-surfaceMap_thickness surface-derived anat Yes -hemi-L_desc-surfaceMap_volume surface-derived anat Yes -hemi-R_desc-surfaceMap_volume surface-derived anat Yes -hemi-L_desc-surfaceMesh_pial surface-derived anat -hemi-R_desc-surfaceMesh_pial surface-derived anat -raw-average surface-derived anat -hemi-L_desc-surfaceMesh_smoothwm surface-derived anat -hemi-R_desc-surfaceMesh_smoothwm surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-32k_dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-32k_dlabel surface-derived anat -atlas-DesikanKilliany_space-fsLR_den-164k_dlabel surface-derived anat -atlas-Destrieux_space-fsLR_den-164k_dlabel surface-derived anat -space-fsLR_den-32k_bold-dtseries surface-derived func -hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes -hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes -hemi-L_desc-surfaceMap_sulc surface-derived anat Yes -hemi-R_desc-surfaceMap_sulc surface-derived anat Yes -hemi-L_desc-surface_curv surface-derived anat -hemi-R_desc-surface_curv surface-derived anat -hemi-L_desc-surfaceMesh_white surface-derived anat Yes -hemi-R_desc-surfaceMesh_white surface-derived anat Yes -wmparc surface-derived anat Yes -space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI Yes -desc-brain_T1w T1w T1w anat NIfTI Yes -desc-head_T1w T1w T1w anat NIfTI -desc-preproc_T1w T1w T1w anat NIfTI -desc-reorient_T1w T1w T1w anat NIfTI Yes -desc-restore_T1w T1w T1w anat NIfTI -desc-restore-brain_T1w T1w T1w anat NIfTI -space-template_desc-brain_T1w T1w template anat NIfTI Yes -space-template_desc-preproc_T1w T1w template anat NIfTI -space-template_desc-head_T1w T1w template anat NIfTI -space-template_desc-T1w_mask mask template anat NIfTI -space-template_desc-Mean_timeseries timeseries func 1D -desc-MeanSCA_timeseries timeseries func 1D -desc-SpatReg_timeseries timeseries func 1D -desc-Voxel_timeseries timeseries func 1D -space-longitudinal_label-CSF_probseg tissue probability longitudinal T1w anat NIfTI -space-longitudinal_label-GM_probseg tissue probability longitudinal T1w anat NIfTI -space-longitudinal_label-WM_probseg tissue probability longitudinal T1w anat NIfTI -vmhc vmhc symmetric template func NIfTI -blip-warp xfm func NIfTI -from-bold_to-EPItemplate_mode-image_desc-linear_xfm xfm func NIfTI -from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm xfm func NIfTI -from-bold_to-EPItemplate_mode-image_xfm xfm func NIfTI -from-bold_to-symtemplate_mode-image_xfm xfm func NIfTI -from-bold_to-T1w_mode-image_desc-linear_xfm xfm func NIfTI -from-bold_to-template_mode-image_xfm xfm func NIfTI -from-EPItemplate_to-bold_mode-image_desc-linear_xfm xfm func NIfTI -from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm xfm func NIfTI -from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI -from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-longitudinal_to-symtemplate_mode-image_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_desc-linear_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-longitudinal_to-template_mode-image_xfm xfm anat NIfTI -from-symtemplate_to-bold_mode-image_xfm xfm func NIfTI -from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI -from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-symtemplate_to-longitudinal_mode-image_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-symtemplate_to-T1w_mode-image_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-T1w_to-symtemplate_mode-image_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_desc-linear_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-T1w_to-template_mode-image_xfm xfm anat NIfTI -from-template_to-bold_mode-image_xfm xfm func NIfTI -from-template_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI -from-template_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-template_to-longitudinal_mode-image_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI -from-template_to-T1w_mode-image_xfm xfm anat NIfTI -space-template_label-CSF_mask mask template anat NIfTI -space-template_label-WM_mask mask template anat NIfTI -space-template_label-GM_mask mask template anat NIfTI -space-EPItemplate_label-CSF_mask mask template func NIfTI -space-EPItemplate_label-WM_mask mask template func NIfTI -space-EPItemplate_label-GM_mask mask template func NIfTI -mdmr group functional group_analysis NIfTI -desc-zstd-mdmr group functional group_analysis NIfTI Yes -dseg anat -AtlasSubcortical-s2 surface_derived func -space-fsLR_den-32k_bold surface_derived func CIFTI dtseries -goodvoxels surface_derived func -ribbon-only surface_derived func -hemi-L_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func -hemi-R_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func -hemi-L_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape -hemi-L_space-native_bold surface_derived func GIFTI func -hemi-R_space-native_bold surface_derived func GIFTI func -space-fsLR_den-32k_wb-spec surface_derived func GIFTI spec -space-native_wb-spec surface_derived func GIFTI spec -hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func GIFTI shape -space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func GIFTI shape -space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func GIFTI shape -space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func GIFTI shape -space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_curv surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_curv surface_derived func GIFTI shape -space-fsLR_den-32k_curv surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_flat surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_flat surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_inflated surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_inflated surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_veryinflated surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_veryinflated surface_derived func GIFTI surf -hemi-L_space-native_inflated surface_derived func GIFTI surf -hemi-R_space-native_inflated surface_derived func GIFTI surf -hemi-L_space-native_veryinflated surface_derived func GIFTI surf -hemi-R_space-native_veryinflated surface_derived func GIFTI surf -hemi-L_space-fsLR_den-164k_midthickness surface_derived func GIFTI surf -hemi-R_space-fsLR_den-164k_midthickness surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_midthickness surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_midthickness surface_derived func GIFTI surf -hemi-L_space-native_midthickness surface_derived func GIFTI surf -hemi-R_space-native_midthickness surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_pial surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_pial surface_derived func GIFTI surf -hemi-L_space-native_den-32k_pial surface_derived func GIFTI surf -hemi-R_space-native_den-32k_pial surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_sphere surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_sphere surface_derived func GIFTI surf -hemi-L_space-native_desc-MSMSulc_sphere surface_derived func GIFTI surf -hemi-R_space-native_desc-MSMSulc_sphere surface_derived func GIFTI surf -hemi-L_space-native_sphere surface_derived func GIFTI surf -hemi-R_space-native_sphere surface_derived func GIFTI surf -hemi-L_space-native_desc-reg_sphere surface_derived func GIFTI surf -hemi-R_space-native_desc-reg_sphere surface_derived func GIFTI surf -hemi-L_space-native_desc-reg-reg_sphere surface_derived func GIFTI surf -hemi-R_space-native_desc-reg-reg_sphere surface_derived func GIFTI surf -hemi-L_space-native_desc-rot_sphere surface_derived func GIFTI surf -hemi-R_space-native_desc-rot_sphere surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_desc-FS_strainJ surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-FS_strainJ surface_derived func GIFTI shape -space-fsLR_den-32k_desc-FS_strainJ surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func GIFTI shape -space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_desc-FS_strainR surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-FS_strainR surface_derived func GIFTI shape -space-fsLR_den-32k_desc-FS_strainR surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape -space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_sulc surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_sulc surface_derived func GIFTI shape -space-fsLR_den-32k_sulc surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-32k_thickness surface_derived func GIFTI shape -hemi-R_space-fsLR_den-32k_thickness surface_derived func GIFTI shape -space-fsLR_den-32k_thickness surface_derived func CIFTI dscalar -hemi-L_space-fsLR_den-164k_white surface_derived func GIFTI surf -hemi-R_space-fsLR_den-164k_white surface_derived func GIFTI surf -hemi-L_space-fsLR_den-32k_white surface_derived func GIFTI surf -hemi-R_space-fsLR_den-32k_white surface_derived func GIFTI surf -hemi-L_space-native_white surface_derived func GIFTI surf -hemi-R_space-native_white surface_derived func GIFTI surf -atlas-DesikanKilliany_space-fsLR_den-32k surface_derived func CIFTI dlabel -atlas-Destrieux_space-fsLR_den-32k surface_derived func CIFTI dlabel -atlas-DesikanKilliany_space-fsLR_den-164k surface_derived func CIFTI dlabel -atlas-Destrieux_space-fsLR_den-164k surface_derived func CIFTI dlabel -space-fsLR_den-32k_bold_surf_falff surface_derived func CIFTI dscalar -space-fsLR_den-32k_bold_surf_alff surface_derived func CIFTI dscalar -space-fsLR_den-32k_bold_surf-L_reho surface_derived func CIFTI dscalar -space-fsLR_den-32k_bold_surf-R_reho surface_derived func CIFTI dscalar +Resource Type Space Sub-Directory File To Smooth To z-std 4D Time Series Optional: Debugging Multi-File +alff alff functional func NIfTI Yes Yes +desc-sm_alff alff functional func NIfTI Yes +desc-sm-zstd_alff alff functional func NIfTI +desc-zstd_alff alff functional func NIfTI +space-template_alff alff template func NIfTI Yes Yes +space-template_desc-sm_alff alff template func NIfTI Yes +space-template_desc-sm-zstd_alff alff template func NIfTI +space-template_desc-zstd_alff alff template func NIfTI +desc-brain_bold bold functional func NIfTI Yes Yes +desc-mean_bold bold functional func NIfTI +desc-motion_bold bold functional func NIfTI Yes Yes +desc-preproc_bold bold functional func NIfTI Yes +desc-sm_bold bold functional func NIfTI Yes Yes +sbref bold functional func NIfTI +space-EPItemplate_bold bold EPI template func NIfTI Yes +space-EPItemplate_desc-brain_bold bold EPI template func NIfTI Yes Yes +space-EPItemplate_desc-mean_bold bold EPI template func NIfTI +space-EPItemplate_desc-preproc_bold bold EPI template func NIfTI Yes +space-symtemplate_desc-sm_bold bold symmetric template func NIfTI Yes Yes +space-T1w_sbref bold T1w func NIfTI +space-template_bold bold template func NIfTI Yes +space-template_desc-brain_bold bold template func NIfTI Yes Yes +space-template_desc-head_bold bold template func NIfTI Yes +space-template_desc-mean_bold bold template func NIfTI +space-template_desc-preproc_bold bold template func NIfTI Yes +space-template_desc-scout_bold bold template func NIfTI +space-template_sbref bold template func NIfTI +space-template_desc-DualReg_correlations correlation template func NIfTI +space-template_desc-MeanSCA_correlations correlation template func NIfTI +space-template_desc-MultReg_correlations correlation template func NIfTI +space-template_desc-ndmg_correlations correlation template func NIfTI +space-template_desc-PearsonAfni_correlations correlation template func tsv +space-template_desc-PartialAfni_correlations correlation template func tsv +space-template_desc-PearsonNilearn_correlations correlation template func tsv +space-template_desc-PartialNilearn_correlations correlation template func tsv +space-template_dcb degree-centrality template func NIfTI Yes Yes +space-template_desc-sm_dcb degree-centrality template func NIfTI Yes +space-template_desc-sm-zstd_dcb degree-centrality template func NIfTI +space-template_desc-zstd_dcb degree-centrality template func NIfTI +space-template_dcw degree-centrality template func NIfTI Yes Yes +space-template_desc-sm_dcw degree-centrality template func NIfTI Yes +space-template_desc-sm-zstd_dcw degree-centrality template func NIfTI +space-template_desc-zstd_dcw degree-centrality template func NIfTI +space-template_ecb eigen-centrality template func NIfTI Yes Yes +space-template_desc-sm_ecb eigen-centrality template func NIfTI Yes +space-template_desc-sm-zstd_ecb eigen-centrality template func NIfTI +space-template_desc-zstd_ecb eigen-centrality template func NIfTI +space-template_ecw eigen-centrality template func NIfTI Yes Yes +space-template_desc-sm_ecw eigen-centrality template func NIfTI Yes +space-template_desc-sm-zstd_ecw eigen-centrality template func NIfTI +space-template_desc-zstd_ecw eigen-centrality template func NIfTI +desc-sm_falff falff functional func NIfTI Yes +desc-sm-zstd_falff falff functional func NIfTI +desc-zstd_falff falff functional func NIfTI +falff falff functional func NIfTI Yes Yes +space-template_desc-sm_falff falff template func NIfTI Yes +space-template_desc-sm-zstd_falff falff template func NIfTI +space-template_desc-zstd_falff falff template func NIfTI +space-template_falff falff template func NIfTI Yes Yes +space-template_lfcdb lfcd template func NIfTI Yes Yes +space-template_desc-sm_lfcdb lfcd template func NIfTI Yes +space-template_desc-sm-zstd_lfcdb lfcd template func NIfTI +space-template_desc-zstd_lfcdb lfcd template func NIfTI +space-template_lfcdw lfcd template func NIfTI Yes Yes +space-template_desc-sm_lfcdw lfcd template func NIfTI Yes +space-template_desc-sm-zstd_lfcdw lfcd template func NIfTI +space-template_desc-zstd_lfcdw lfcd template func NIfTI +space-EPItemplate_desc-bold_mask mask EPI template func NIfTI +space-EPItemplate_res-derivative_desc-bold_mask mask EPI template func NIfTI +space-bold_desc-brain_mask mask functional func NIfTI +space-bold_desc-eroded_mask mask functional func NIfTI +space-bold_label-CSF_desc-eroded_mask mask functional func NIfTI +space-bold_label-CSF_mask mask functional func NIfTI +space-bold_label-GM_desc-eroded_mask mask functional func NIfTI +space-bold_label-GM_mask mask functional func NIfTI +space-bold_label-WM_desc-eroded_mask mask functional func NIfTI +space-bold_label-WM_mask mask functional func NIfTI +space-longitudinal_desc-brain_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-CSF_desc-preproc_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-CSF_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-GM_desc-preproc_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-GM_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-WM_desc-preproc_mask mask longitudinal T1w anat NIfTI +space-longitudinal_label-WM_mask mask longitudinal T1w anat NIfTI +label-CSF_desc-eroded_mask mask T1w anat NIfTI +label-CSF_desc-preproc_mask mask T1w anat NIfTI +label-CSF_mask mask T1w anat NIfTI +label-GM_desc-eroded_mask mask T1w anat NIfTI +label-GM_desc-preproc_mask mask T1w anat NIfTI +label-GM_mask mask T1w anat NIfTI +label-WM_desc-eroded_mask mask T1w anat NIfTI +label-WM_desc-preproc_mask mask T1w anat NIfTI +label-WM_mask mask T1w anat NIfTI +space-T1w_desc-acpcbrain_mask mask T1w anat NIfTI +space-T1w_desc-brain_mask mask T1w anat NIfTI +space-T1w_desc-eroded_mask mask T1w anat NIfTI +space-template_desc-brain_mask mask template anat NIfTI +space-template_desc-bold_mask mask template func NIfTI +space-template_res-derivative_desc-bold_mask mask template func NIfTI +motion motion func TSV +desc-summary_motion motion func TSV +motion-filter-plot motion func png +desc-movementParameters_motion motion func TSV +desc-movementParametersUnfiltered_motion motion func TSV +label-CSF_probseg probseg T1w anat NIfTI +label-GM_probseg probseg T1w anat NIfTI +label-WM_probseg probseg T1w anat NIfTI +desc-T1wAxial_quality qc anat png +desc-T1wSagittal_quality qc anat png +desc-dsegAxial_quality qc anat png +desc-dsegSagittal_quality qc anat png +desc-boldAxial_quality qc func png +desc-boldSagittal_quality qc func png +desc-boldCarpet_quality qc func png +desc-framewiseDisplacementJenkinsonPlot_quality qc func png +desc-movementParametersTrans_quality qc func png +desc-movementParametersRot_quality qc func png +desc-boldSnrAxial_quality qc func png +desc-boldSnrSagittal_quality qc func png +desc-boldSnrHist_quality qc func png +desc-boldSnr_quality qc func png +space-template_desc-xcp_quality qc func tsv +desc-confounds_timeseries regressors func 1D +desc-sm_reho reho functional func NIfTI Yes +desc-sm-zstd_reho reho functional func NIfTI +desc-zstd_reho reho functional func NIfTI +reho reho functional func NIfTI Yes Yes +space-template_desc-sm_reho reho template func NIfTI Yes +space-template_desc-sm-zstd_reho reho template func NIfTI +space-template_desc-zstd_reho reho template func NIfTI +space-template_reho reho template func NIfTI Yes Yes +desc-DualReg_statmap statistic template func NIfTI +desc-MultReg_statmap statistic template func NIfTI +hemi-L_desc-surfaceMap_thickness surface-derived anat Yes +hemi-R_desc-surfaceMap_thickness surface-derived anat Yes +hemi-L_desc-surfaceMap_volume surface-derived anat Yes +hemi-R_desc-surfaceMap_volume surface-derived anat Yes +hemi-L_desc-surfaceMesh_pial surface-derived anat +hemi-R_desc-surfaceMesh_pial surface-derived anat +raw-average surface-derived anat +hemi-L_desc-surfaceMesh_smoothwm surface-derived anat +hemi-R_desc-surfaceMesh_smoothwm surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-32k_dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-32k_dlabel surface-derived anat +atlas-DesikanKilliany_space-fsLR_den-164k_dlabel surface-derived anat +atlas-Destrieux_space-fsLR_den-164k_dlabel surface-derived anat +space-fsLR_den-32k_bold-dtseries surface-derived func +hemi-L_desc-surfaceMesh_sphere surface-derived anat Yes +hemi-R_desc-surfaceMesh_sphere surface-derived anat Yes +hemi-L_desc-surfaceMap_sulc surface-derived anat Yes +hemi-R_desc-surfaceMap_sulc surface-derived anat Yes +hemi-L_desc-surface_curv surface-derived anat +hemi-R_desc-surface_curv surface-derived anat +hemi-L_desc-surfaceMesh_white surface-derived anat Yes +hemi-R_desc-surfaceMesh_white surface-derived anat Yes +wmparc surface-derived anat Yes +space-symtemplate_desc-brain_T1w T1w symmetric template anat NIfTI Yes +desc-brain_T1w T1w T1w anat NIfTI Yes +desc-head_T1w T1w T1w anat NIfTI +desc-preproc_T1w T1w T1w anat NIfTI +desc-reorient_T1w T1w T1w anat NIfTI Yes +desc-restore_T1w T1w T1w anat NIfTI +desc-restore-brain_T1w T1w T1w anat NIfTI +space-template_desc-brain_T1w T1w template anat NIfTI Yes +space-template_desc-preproc_T1w T1w template anat NIfTI +space-template_desc-head_T1w T1w template anat NIfTI +space-template_desc-T1w_mask mask template anat NIfTI +space-template_desc-Mean_timeseries timeseries func 1D +desc-MeanSCA_timeseries timeseries func 1D +desc-SpatReg_timeseries timeseries func 1D +desc-Voxel_timeseries timeseries func 1D +space-longitudinal_label-CSF_probseg tissue probability longitudinal T1w anat NIfTI +space-longitudinal_label-GM_probseg tissue probability longitudinal T1w anat NIfTI +space-longitudinal_label-WM_probseg tissue probability longitudinal T1w anat NIfTI +vmhc vmhc symmetric template func NIfTI +blip-warp xfm func NIfTI +from-bold_to-EPItemplate_mode-image_desc-linear_xfm xfm func NIfTI +from-bold_to-EPItemplate_mode-image_desc-nonlinear_xfm xfm func NIfTI +from-bold_to-EPItemplate_mode-image_xfm xfm func NIfTI +from-bold_to-symtemplate_mode-image_xfm xfm func NIfTI +from-bold_to-T1w_mode-image_desc-linear_xfm xfm func NIfTI +from-bold_to-template_mode-image_xfm xfm func NIfTI +from-EPItemplate_to-bold_mode-image_desc-linear_xfm xfm func NIfTI +from-EPItemplate_to-bold_mode-image_desc-nonlinear_xfm xfm func NIfTI +from-longitudinal_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI +from-longitudinal_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-longitudinal_to-symtemplate_mode-image_xfm xfm anat NIfTI +from-longitudinal_to-template_mode-image_desc-linear_xfm xfm anat NIfTI +from-longitudinal_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-longitudinal_to-template_mode-image_xfm xfm anat NIfTI +from-symtemplate_to-bold_mode-image_xfm xfm func NIfTI +from-symtemplate_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI +from-symtemplate_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-symtemplate_to-longitudinal_mode-image_xfm xfm anat NIfTI +from-symtemplate_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI +from-symtemplate_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-symtemplate_to-T1w_mode-image_xfm xfm anat NIfTI +from-T1w_to-symtemplate_mode-image_desc-linear_xfm xfm anat NIfTI +from-T1w_to-symtemplate_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-T1w_to-symtemplate_mode-image_xfm xfm anat NIfTI +from-T1w_to-template_mode-image_desc-linear_xfm xfm anat NIfTI +from-T1w_to-template_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-T1w_to-template_mode-image_xfm xfm anat NIfTI +from-template_to-bold_mode-image_xfm xfm func NIfTI +from-template_to-longitudinal_mode-image_desc-linear_xfm xfm anat NIfTI +from-template_to-longitudinal_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-template_to-longitudinal_mode-image_xfm xfm anat NIfTI +from-template_to-T1w_mode-image_desc-linear_xfm xfm anat NIfTI +from-template_to-T1w_mode-image_desc-nonlinear_xfm xfm anat NIfTI +from-template_to-T1w_mode-image_xfm xfm anat NIfTI +space-template_label-CSF_mask mask template anat NIfTI +space-template_label-WM_mask mask template anat NIfTI +space-template_label-GM_mask mask template anat NIfTI +space-EPItemplate_label-CSF_mask mask template func NIfTI +space-EPItemplate_label-WM_mask mask template func NIfTI +space-EPItemplate_label-GM_mask mask template func NIfTI +mdmr group functional group_analysis NIfTI +desc-zstd-mdmr group functional group_analysis NIfTI Yes +dseg anat +AtlasSubcortical-s2 surface_derived func +space-fsLR_den-32k_bold surface_derived func CIFTI dtseries +goodvoxels surface_derived func +ribbon-only surface_derived func +hemi-L_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func +hemi-R_space-fsLR_den-32k_desc-atlasroi_bold surface_derived func GIFTI func +hemi-L_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-atlasroi_mask surface_derived func GIFTI shape +hemi-L_space-native_bold surface_derived func GIFTI func +hemi-R_space-native_bold surface_derived func GIFTI func +space-fsLR_den-32k_wb-spec surface_derived func GIFTI spec +space-native_wb-spec surface_derived func GIFTI spec +hemi-L_space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_arealdistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_arealdistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_edgedistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_edgedistortion surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_curv surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_curv surface_derived func GIFTI shape +space-fsLR_den-32k_curv surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_flat surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_flat surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_inflated surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_inflated surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_veryinflated surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_veryinflated surface_derived func GIFTI surf +hemi-L_space-native_inflated surface_derived func GIFTI surf +hemi-R_space-native_inflated surface_derived func GIFTI surf +hemi-L_space-native_veryinflated surface_derived func GIFTI surf +hemi-R_space-native_veryinflated surface_derived func GIFTI surf +hemi-L_space-fsLR_den-164k_midthickness surface_derived func GIFTI surf +hemi-R_space-fsLR_den-164k_midthickness surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_midthickness surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_midthickness surface_derived func GIFTI surf +hemi-L_space-native_midthickness surface_derived func GIFTI surf +hemi-R_space-native_midthickness surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_pial surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_pial surface_derived func GIFTI surf +hemi-L_space-native_den-32k_pial surface_derived func GIFTI surf +hemi-R_space-native_den-32k_pial surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_sphere surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-MSMSulc_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-MSMSulc_sphere surface_derived func GIFTI surf +hemi-L_space-native_sphere surface_derived func GIFTI surf +hemi-R_space-native_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-reg_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-reg_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-reg-reg_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-reg-reg_sphere surface_derived func GIFTI surf +hemi-L_space-native_desc-rot_sphere surface_derived func GIFTI surf +hemi-R_space-native_desc-rot_sphere surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_desc-FS_strainJ surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_strainJ surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_strainJ surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_strainJ surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-FS_strainR surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-FS_strainR surface_derived func GIFTI shape +space-fsLR_den-32k_desc-FS_strainR surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func GIFTI shape +space-fsLR_den-32k_desc-MSMSulc_strainR surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_sulc surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_sulc surface_derived func GIFTI shape +space-fsLR_den-32k_sulc surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-32k_thickness surface_derived func GIFTI shape +hemi-R_space-fsLR_den-32k_thickness surface_derived func GIFTI shape +space-fsLR_den-32k_thickness surface_derived func CIFTI dscalar +hemi-L_space-fsLR_den-164k_white surface_derived func GIFTI surf +hemi-R_space-fsLR_den-164k_white surface_derived func GIFTI surf +hemi-L_space-fsLR_den-32k_white surface_derived func GIFTI surf +hemi-R_space-fsLR_den-32k_white surface_derived func GIFTI surf +hemi-L_space-native_white surface_derived func GIFTI surf +hemi-R_space-native_white surface_derived func GIFTI surf +atlas-DesikanKilliany_space-fsLR_den-32k surface_derived func CIFTI dlabel +atlas-Destrieux_space-fsLR_den-32k surface_derived func CIFTI dlabel +atlas-DesikanKilliany_space-fsLR_den-164k surface_derived func CIFTI dlabel +atlas-Destrieux_space-fsLR_den-164k surface_derived func CIFTI dlabel +space-fsLR_den-32k_bold_surf_falff surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf_alff surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf-L_reho surface_derived func CIFTI dscalar +space-fsLR_den-32k_bold_surf-R_reho surface_derived func CIFTI dscalar space-fsLR_den-32k_bold_surf-correlation_matrix surface_derived func CIFTI pconn \ No newline at end of file From 716d84dba59822f05f7ab0ae1c7138cbd0adb05b Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Thu, 15 Feb 2024 13:16:26 -0500 Subject: [PATCH 187/213] Fix tsv line endings pt. 2 --- CPAC/resources/cpac_templates.csv | 84 +++++++++++++++---------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/CPAC/resources/cpac_templates.csv b/CPAC/resources/cpac_templates.csv index ba21e01e8c..5c2abc9947 100644 --- a/CPAC/resources/cpac_templates.csv +++ b/CPAC/resources/cpac_templates.csv @@ -1,43 +1,43 @@ -Key,Pipeline_Config_Entry,Description,Intended_Resolution_Config_Entry -CSF-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, CSF_path",Template-space CSF tissue prior, -dilated-symmetric-brain-mask,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" -dilated-symmetric-brain-mask-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask_for_resample",, -EPI-template,"registration_workflows, functional_registration, EPI_registration, EPI_template",EPI-based template, -EPI-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -EPI-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_for_resample",, -EPI-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -EPI-template-mask,"registration_workflows, functional_registration, EPI_registration, EPI_template_mask",Binary brain mask of the EPI template, -FSL-AFNI-bold-ref,"functional_preproc, func_masking, FSL_AFNI, bold_ref",bold_ref for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -FSL-AFNI-brain-mask,"functional_preproc, func_masking, FSL_AFNI, brain_mask",brain_mask for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -FSL-AFNI-brain-probseg,"functional_preproc, func_masking, FSL_AFNI, brain_probseg",brain_probseg for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -FNIRT-T1w-brain-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_brain_template",Additional T1w brain-only template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" -FNIRT-T1w-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_template",Additional T1w whole-head template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" -GM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, GM_path",Template-space GM tissue prior, -lateral-ventricles-mask,"nuisance_corrections, 2-nuisance_regression, lateral_ventricles_mask",, -T1w-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_ACPC_template",, -T1w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_brain_ACPC_template",, -T1w-brain-template,"registration_workflows, anatomical_registration, T1w_brain_template",T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-brain-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-brain-template-mask,"registration_workflows, anatomical_registration, T1w_brain_template_mask",Binary brain mask of the T1w template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric",Symmetric version of the T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-brain-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_funcreg","Symmetric version of the T1w-based skull-stripped template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-brain-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_for_resample",, -T1w-template,"registration_workflows, anatomical_registration, T1w_template",T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_for_resample",, -T1w-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric",Symmetric version of the T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" -T1w-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_funcreg","Symmetric version of the T1w-based whole-head template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" -T1w-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_for_resample",, -template-ref-mask,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" -template-ref-mask-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask_res-2",, -T1w-template-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, T1w_template_res-2",, -template-specification-file,"network_centrality, template_specification_file",Binary ROI mask for network centrality calculations, -unet-model,"anatomical_preproc, brain_extraction, UNet, unet_model",, -WM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, WM_path",Template-space WM tissue prior, -template-eye-mask,"PyPEER, eye_mask_path",,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" -T1w-brain-template-mask-ccs,"anatomical_preproc, brain_extraction, FreeSurfer-BET, T1w_brain_template_mask_ccs",, -T2w-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_ACPC_template",Whole-head template for use in ACPC-alignment, -T2w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_brain_ACPC_template",Brain-only template for use in ACPC-alignment, +Key,Pipeline_Config_Entry,Description,Intended_Resolution_Config_Entry +CSF-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, CSF_path",Template-space CSF tissue prior, +dilated-symmetric-brain-mask,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" +dilated-symmetric-brain-mask-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, dilated_symmetric_brain_mask_for_resample",, +EPI-template,"registration_workflows, functional_registration, EPI_registration, EPI_template",EPI-based template, +EPI-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +EPI-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_for_resample",, +EPI-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, EPI_template, EPI_template_funcreg",EPI-based template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +EPI-template-mask,"registration_workflows, functional_registration, EPI_registration, EPI_template_mask",Binary brain mask of the EPI template, +FSL-AFNI-bold-ref,"functional_preproc, func_masking, FSL_AFNI, bold_ref",bold_ref for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +FSL-AFNI-brain-mask,"functional_preproc, func_masking, FSL_AFNI, brain_mask",brain_mask for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +FSL-AFNI-brain-probseg,"functional_preproc, func_masking, FSL_AFNI, brain_probseg",brain_probseg for FSL_AFNI func_masking,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +FNIRT-T1w-brain-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_brain_template",Additional T1w brain-only template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" +FNIRT-T1w-template,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, FNIRT_T1w_template",Additional T1w whole-head template for FSL-FNIRT nonlinear registration (when linear FSL-FLIRT requires a separate template),"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_resolution" +GM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, GM_path",Template-space GM tissue prior, +lateral-ventricles-mask,"nuisance_corrections, 2-nuisance_regression, lateral_ventricles_mask",, +T1w-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_ACPC_template",, +T1w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T1w_brain_ACPC_template",, +T1w-brain-template,"registration_workflows, anatomical_registration, T1w_brain_template",T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-brain-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-brain-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_brain_template_funcreg",T1w-based skull-stripped template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +T1w-brain-template-mask,"registration_workflows, anatomical_registration, T1w_brain_template_mask",Binary brain mask of the T1w template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-brain-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric",Symmetric version of the T1w-based skull-stripped template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-brain-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_funcreg","Symmetric version of the T1w-based skull-stripped template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-brain-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_brain_template_symmetric_for_resample",, +T1w-template,"registration_workflows, anatomical_registration, T1w_template",T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-template-deriv,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired functional derivative resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-template-for-resample,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_for_resample",, +T1w-template-funcreg,"registration_workflows, functional_registration, func_registration_to_template, target_template, T1_template, T1w_template_funcreg",T1w-based whole-head template resampled to the desired preprocessed-functional resolution,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +T1w-template-symmetric,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric",Symmetric version of the T1w-based whole-head template,"registration_workflows, anatomical_registration, resolution_for_anat" +T1w-template-symmetric-deriv,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_funcreg","Symmetric version of the T1w-based whole-head template, resampled to the desired functional derivative resolution","registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_derivative_outputs" +T1w-template-symmetric-for-resample,"voxel_mirrored_homotopic_connectivity, symmetric_registration, T1w_template_symmetric_for_resample",, +template-ref-mask,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask",,"registration_workflows, anatomical_registration, resolution_for_anat" +template-ref-mask-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, ref_mask_res-2",, +T1w-template-res-2,"registration_workflows, anatomical_registration, registration, FSL-FNIRT, T1w_template_res-2",, +template-specification-file,"network_centrality, template_specification_file",Binary ROI mask for network centrality calculations, +unet-model,"anatomical_preproc, brain_extraction, UNet, unet_model",, +WM-path,"segmentation, tissue_segmentation, FSL-FAST, use_priors, WM_path",Template-space WM tissue prior, +template-eye-mask,"PyPEER, eye_mask_path",,"registration_workflows, functional_registration, func_registration_to_template, output_resolution, func_preproc_outputs" +T1w-brain-template-mask-ccs,"anatomical_preproc, brain_extraction, FreeSurfer-BET, T1w_brain_template_mask_ccs",, +T2w-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_ACPC_template",Whole-head template for use in ACPC-alignment, +T2w-brain-ACPC-template,"anatomical_preproc, acpc_alignment, T2w_brain_ACPC_template",Brain-only template for use in ACPC-alignment, surface-parcellation-atlas,"surface_analysis, surface_connectivity, surface_parcellation_template",surface space parcellation atlas, \ No newline at end of file From 68521d76028b368160f0e14be174fe2d50e8e523 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 00:14:00 +0000 Subject: [PATCH 188/213] :arrow_up: Bump cryptography from 41.0.1 to 42.0.2 Bumps [cryptography](https://github.com/pyca/cryptography) from 41.0.1 to 42.0.2. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/41.0.1...42.0.2) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 52faa11710..3c35c6531c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ voluptuous==0.13.1 # the below are pinned specifically to match what the FSL installer installs botocore==1.31.4 charset-normalizer==3.1.0 -cryptography==42.0.0 +cryptography==42.0.2 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 From eda720013629e445a06e2211f34c3cc6e12d3d72 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 16 Feb 2024 22:06:32 -0500 Subject: [PATCH 189/213] :arrow_up: Bump cryptography from 42.0.2 to 42.0.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3c35c6531c..87053d1e07 100644 --- a/requirements.txt +++ b/requirements.txt @@ -40,7 +40,7 @@ voluptuous==0.13.1 # the below are pinned specifically to match what the FSL installer installs botocore==1.31.4 charset-normalizer==3.1.0 -cryptography==42.0.2 +cryptography==42.0.3 h5py==3.8.0 importlib-metadata==6.8.0 lxml==4.9.2 From dbeb057edaf461b2a5f7a6924a9542f178ff38c2 Mon Sep 17 00:00:00 2001 From: birajstha <111654544+birajstha@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:56:16 -0500 Subject: [PATCH 190/213] Update data_config_S3-BIDS-ABIDE.yml --- CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index bc64d296d5..d674131633 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # From 0890c7e7fff82e5b30aa8629cf204d010bd80c3f Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 19 Feb 2024 16:18:38 -0500 Subject: [PATCH 191/213] merging with develop --- CHANGELOG.md | 4 ++++ CPAC/pipeline/schema.py | 1 + CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml | 4 ---- CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml | 4 ---- CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml | 4 ---- .../configs/data_config_S3-BIDS-NKI-RocklandSample.yml | 4 ---- CPAC/resources/configs/data_config_cpac_benchmark.yml | 4 ---- CPAC/resources/configs/data_settings_template.yml | 4 ---- CPAC/resources/configs/group_config_template.yml | 4 ---- CPAC/resources/configs/pipeline_config_abcd-options.yml | 4 ---- CPAC/resources/configs/pipeline_config_abcd-prep.yml | 4 ---- CPAC/resources/configs/pipeline_config_anat-only.yml | 4 ---- CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml | 4 ---- CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml | 4 ---- CPAC/resources/configs/pipeline_config_blank.yml | 4 ---- CPAC/resources/configs/pipeline_config_ccs-options.yml | 4 ---- CPAC/resources/configs/pipeline_config_default-deprecated.yml | 4 ---- CPAC/resources/configs/pipeline_config_default.yml | 4 ---- CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml | 4 ---- CPAC/resources/configs/pipeline_config_fmriprep-options.yml | 4 ---- CPAC/resources/configs/pipeline_config_fx-options.yml | 4 ---- CPAC/resources/configs/pipeline_config_monkey-ABCD.yml | 4 ---- CPAC/resources/configs/pipeline_config_monkey.yml | 4 ---- CPAC/resources/configs/pipeline_config_ndmg.yml | 4 ---- CPAC/resources/configs/pipeline_config_nhp-macaque.yml | 4 ---- CPAC/resources/configs/pipeline_config_preproc.yml | 4 ---- CPAC/resources/configs/pipeline_config_rbc-options.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-1.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-2.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-3.yml | 4 ---- CPAC/resources/configs/pipeline_config_regtest-4.yml | 4 ---- CPAC/resources/configs/pipeline_config_rodent.yml | 4 ---- CPAC/resources/configs/system_config.yml | 4 ---- .../configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml | 4 ---- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml | 4 ---- .../configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml | 4 ---- .../configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml | 4 ---- .../configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml | 4 ---- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml | 4 ---- .../test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml | 4 ---- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml | 4 ---- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml | 4 ---- .../configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml | 4 ---- CPAC/resources/configs/test_configs/pipe-test_all.yml | 4 ---- 44 files changed, 5 insertions(+), 168 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48f2c8d6aa..3a82d99c3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +## Added + +- `Robustfov` feature in `FSL-BET` to crop images ensuring removal of neck regions that may appear in the skull-stripped images. + ## Changed - Moved autoversioning from CI to pre-commit diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 481abd2664..99481c40fa 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -524,6 +524,7 @@ def sanitize(filename): }, 'FSL-BET': { 'frac': Number, + 'Robustfov': bool1_1, 'mesh_boolean': bool1_1, 'outline': bool1_1, 'padding': bool1_1, diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml index bc64d296d5..d674131633 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ABIDE.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml index 78041b063e..cae981cd9a 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml index 036536945f..0ef6d3ccf7 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-ADHD200_only2.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml index b44368294a..77a62527e6 100644 --- a/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml +++ b/CPAC/resources/configs/data_config_S3-BIDS-NKI-RocklandSample.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_config_cpac_benchmark.yml b/CPAC/resources/configs/data_config_cpac_benchmark.yml index 64cb367118..15460d264c 100644 --- a/CPAC/resources/configs/data_config_cpac_benchmark.yml +++ b/CPAC/resources/configs/data_config_cpac_benchmark.yml @@ -1,9 +1,5 @@ # CPAC Data Configuration File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/data_settings_template.yml b/CPAC/resources/configs/data_settings_template.yml index 60124ecbda..1d6c1b912e 100644 --- a/CPAC/resources/configs/data_settings_template.yml +++ b/CPAC/resources/configs/data_settings_template.yml @@ -1,9 +1,5 @@ # CPAC Data Settings File -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/group_config_template.yml b/CPAC/resources/configs/group_config_template.yml index 900de36ca9..996c2386f0 100644 --- a/CPAC/resources/configs/group_config_template.yml +++ b/CPAC/resources/configs/group_config_template.yml @@ -1,9 +1,5 @@ # CPAC Group-Level Analysis Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-options.yml b/CPAC/resources/configs/pipeline_config_abcd-options.yml index 7a34598b63..2e84020471 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-options.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_abcd-prep.yml b/CPAC/resources/configs/pipeline_config_abcd-prep.yml index 3d169038ee..7aee4e80ad 100644 --- a/CPAC/resources/configs/pipeline_config_abcd-prep.yml +++ b/CPAC/resources/configs/pipeline_config_abcd-prep.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_anat-only.yml b/CPAC/resources/configs/pipeline_config_anat-only.yml index 593462b2de..01e902abc0 100644 --- a/CPAC/resources/configs/pipeline_config_anat-only.yml +++ b/CPAC/resources/configs/pipeline_config_anat-only.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml index 97c4d6812a..f59be35958 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-ANTS.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml index 6fd96179c5..8fb774aa80 100644 --- a/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml +++ b/CPAC/resources/configs/pipeline_config_benchmark-FNIRT.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 1a499adff0..e2f74e2f0e 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ccs-options.yml b/CPAC/resources/configs/pipeline_config_ccs-options.yml index cefb044ad7..61207908f0 100644 --- a/CPAC/resources/configs/pipeline_config_ccs-options.yml +++ b/CPAC/resources/configs/pipeline_config_ccs-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default-deprecated.yml b/CPAC/resources/configs/pipeline_config_default-deprecated.yml index 87f75c9b21..9a11649dee 100644 --- a/CPAC/resources/configs/pipeline_config_default-deprecated.yml +++ b/CPAC/resources/configs/pipeline_config_default-deprecated.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 702871a069..d669663d9c 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml index 4fde62edbd..c65af74391 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml index 95a465c851..b432770220 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-options.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_fx-options.yml b/CPAC/resources/configs/pipeline_config_fx-options.yml index 5f7d9f8125..ade6c66940 100644 --- a/CPAC/resources/configs/pipeline_config_fx-options.yml +++ b/CPAC/resources/configs/pipeline_config_fx-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml index fd674dd3a8..b598e38df3 100644 --- a/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml +++ b/CPAC/resources/configs/pipeline_config_monkey-ABCD.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_monkey.yml b/CPAC/resources/configs/pipeline_config_monkey.yml index db3e11abb5..09bf8d48ef 100644 --- a/CPAC/resources/configs/pipeline_config_monkey.yml +++ b/CPAC/resources/configs/pipeline_config_monkey.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_ndmg.yml b/CPAC/resources/configs/pipeline_config_ndmg.yml index 3852261e87..70d27d8f7b 100644 --- a/CPAC/resources/configs/pipeline_config_ndmg.yml +++ b/CPAC/resources/configs/pipeline_config_ndmg.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml index 657eae64b7..bd4bb18b92 100644 --- a/CPAC/resources/configs/pipeline_config_nhp-macaque.yml +++ b/CPAC/resources/configs/pipeline_config_nhp-macaque.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_preproc.yml b/CPAC/resources/configs/pipeline_config_preproc.yml index f6738b3aa1..8326a41696 100644 --- a/CPAC/resources/configs/pipeline_config_preproc.yml +++ b/CPAC/resources/configs/pipeline_config_preproc.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rbc-options.yml b/CPAC/resources/configs/pipeline_config_rbc-options.yml index d16378668f..eb27e51c8e 100644 --- a/CPAC/resources/configs/pipeline_config_rbc-options.yml +++ b/CPAC/resources/configs/pipeline_config_rbc-options.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-1.yml b/CPAC/resources/configs/pipeline_config_regtest-1.yml index da5b80612e..fccbb36fc1 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-1.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-1.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-2.yml b/CPAC/resources/configs/pipeline_config_regtest-2.yml index 715d011237..08d546bdc2 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-2.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-2.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-3.yml b/CPAC/resources/configs/pipeline_config_regtest-3.yml index 0f2cf487d6..77febb731f 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-3.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-3.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 5e330a6dd5..62928c1c43 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/pipeline_config_rodent.yml b/CPAC/resources/configs/pipeline_config_rodent.yml index 35dd71ed42..f829296a26 100644 --- a/CPAC/resources/configs/pipeline_config_rodent.yml +++ b/CPAC/resources/configs/pipeline_config_rodent.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/system_config.yml b/CPAC/resources/configs/system_config.yml index c0452554dc..291adc19a9 100644 --- a/CPAC/resources/configs/system_config.yml +++ b/CPAC/resources/configs/system_config.yml @@ -1,9 +1,5 @@ # C-PAC System Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml index 8082481b07..e68f31d827 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml index 9d20f75a41..510e3a7ef9 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorr3dSk.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml index 34c828ec3b..e6940dc729 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-3dSk-DistCorrBET.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml index 4d67f3ae83..0e9e8f34c5 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_ANTs-BET-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml index aa08997bcd..3326d3427f 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-3dSk-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml index fd2d945c94..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-BASC.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml index fd2d945c94..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC-voxel.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml index fd2d945c94..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-ISC.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml index fd2d945c94..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis-MDMR.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml index fd2d945c94..8f4faae6c1 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_FNIRT-BET-AllNuis.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # diff --git a/CPAC/resources/configs/test_configs/pipe-test_all.yml b/CPAC/resources/configs/test_configs/pipe-test_all.yml index 466b440f98..b6feb9c42c 100644 --- a/CPAC/resources/configs/test_configs/pipe-test_all.yml +++ b/CPAC/resources/configs/test_configs/pipe-test_all.yml @@ -1,11 +1,7 @@ %YAML 1.1 --- # CPAC Pipeline Configuration YAML file -<<<<<<< HEAD -# Version 1.8.6 -======= # Version 1.8.7.dev1 ->>>>>>> origin/develop # # http://fcp-indi.github.io for more info. # From 16320b95f67dbbcb8eb4a1e73cc99182d5e769c0 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 20 Feb 2024 11:46:37 -0500 Subject: [PATCH 192/213] :technologist: Move YAML comment updater to pre-commit hook --- .pre-commit-config.yaml | 11 ++ CPAC/pipeline/schema.py | 11 +- .../configs/pipeline_config_regtest-4.yml | 1 - CPAC/utils/configuration/configuration.py | 163 +++++++++++------- CPAC/utils/configuration/yaml_template.py | 18 +- 5 files changed, 136 insertions(+), 68 deletions(-) mode change 100644 => 100755 CPAC/utils/configuration/yaml_template.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index beffa2686a..7357d71417 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,3 +23,14 @@ repos: entry: .github/scripts/autoversioning.sh language: script files: '.*Dockerfile$|.*\.yaml$|^CPAC/info\.py$' + - id: update-yaml-comments + name: Update YAML comments + entry: CPAC/utils/configuration/yaml_template.py + language: python + files: '^CPAC/resources/configs/pipeline_config_.*\.ya?ml' + additional_dependencies: + - "click" + - "nipype" + - "pathvalidate" + - "pyyaml" + - "voluptuous" diff --git a/CPAC/pipeline/schema.py b/CPAC/pipeline/schema.py index 481abd2664..738502c188 100644 --- a/CPAC/pipeline/schema.py +++ b/CPAC/pipeline/schema.py @@ -21,6 +21,7 @@ from itertools import chain, permutations import numpy as np from pathvalidate import sanitize_filename +from subprocess import CalledProcessError from voluptuous import All, ALLOW_EXTRA, Any, BooleanInvalid, Capitalize, \ Coerce, CoerceInvalid, ExclusiveInvalid, In, Length, \ LengthInvalid, Lower, Match, Maybe, MultipleInvalid, \ @@ -355,6 +356,7 @@ def sanitize(filename): latest_schema = Schema({ 'FROM': Maybe(str), + 'skip env check': Maybe(bool), # flag for skipping an environment check 'pipeline_setup': { 'pipeline_name': All(str, Length(min=1), sanitize), 'output_directory': { @@ -1182,13 +1184,14 @@ def schema(config_dict): except KeyError: pass try: - if 'unet' in [using.lower() for using in - partially_validated['anatomical_preproc'][ - 'brain_extraction']['using']]: + if not partially_validated.get("skip env check" + ) and 'unet' in [using.lower() for using in + partially_validated['anatomical_preproc'][ + 'brain_extraction']['using']]: try: from importlib import import_module import_module('CPAC.unet') - except (ImportError, ModuleNotFoundError, OSError) as error: + except (CalledProcessError, ImportError, ModuleNotFoundError, OSError) as error: import site raise OSError( 'U-Net brain extraction requires torch to be installed, ' diff --git a/CPAC/resources/configs/pipeline_config_regtest-4.yml b/CPAC/resources/configs/pipeline_config_regtest-4.yml index 62928c1c43..308d64cefa 100644 --- a/CPAC/resources/configs/pipeline_config_regtest-4.yml +++ b/CPAC/resources/configs/pipeline_config_regtest-4.yml @@ -99,7 +99,6 @@ anatomical_preproc: # Perform final surface smoothing after all iterations. Default is 20. smooth_final: 22 - # Non-local means filtering via ANTs DenoiseImage non_local_means_filtering: diff --git a/CPAC/utils/configuration/configuration.py b/CPAC/utils/configuration/configuration.py index 72ff3b2363..b66ffa39a9 100644 --- a/CPAC/utils/configuration/configuration.py +++ b/CPAC/utils/configuration/configuration.py @@ -99,12 +99,23 @@ class Configuration: >>> slack_420349_preconfig['pipeline_setup', 'pipeline_name'] 'slack_420349_preconfig' """ - def __init__(self, config_map=None): + def __init__(self, config_map: Optional[dict] = None, + skip_env_check: bool = False) -> None: + """Initialize a Configuration instance. + + Parameters + ---------- + config_map : dict, optional + + skip_env_check : bool, optional + """ from CPAC.pipeline.schema import schema from CPAC.utils.utils import lookup_nested_value, update_nested_dict if config_map is None: config_map = {} + if skip_env_check: + config_map['skip env check'] = True base_config = config_map.pop('FROM', None) if base_config: @@ -112,7 +123,8 @@ def __init__(self, config_map=None): base_config = 'default' # import another config (specified with 'FROM' key) try: - base_config = Preconfiguration(base_config) + base_config = Preconfiguration(base_config, + skip_env_check=skip_env_check) except BadParameter: base_config = configuration_from_file(base_config) config_map = update_nested_dict(base_config.dict(), config_map) @@ -140,20 +152,26 @@ def __init__(self, config_map=None): config_map = schema(config_map) + # remove 'skip env check' now that the config is validated + if "skip env check" in config_map: + del config_map["skip env check"] # remove 'FROM' before setting attributes now that it's imported if 'FROM' in config_map: del config_map['FROM'] - # set FSLDIR to the environment $FSLDIR if the user sets it to - # 'FSLDIR' in the pipeline config file - _FSLDIR = config_map.get('FSLDIR') - if _FSLDIR and bool(re.match(r'^[\$\{]{0,2}?FSLDIR[\}]?$', _FSLDIR)): - config_map['FSLDIR'] = os.environ['FSLDIR'] - - for key in config_map: - # set attribute - setattr(self, key, set_from_ENV(config_map[key])) - + if skip_env_check: + for key in config_map: + # set attribute + setattr(self, key, self.set_without_ENV(config_map[key])) + else: + # set FSLDIR to the environment $FSLDIR if the user sets it to + # 'FSLDIR' in the pipeline config file + _FSLDIR = config_map.get('FSLDIR') + if _FSLDIR and bool(re.match(r'^[\$\{]{0,2}?FSLDIR[\}]?$', _FSLDIR)): + config_map['FSLDIR'] = os.environ['FSLDIR'] + for key in config_map: + # set attribute + setattr(self, key, self.set_from_ENV(config_map[key])) self._update_attr() # set working directory as an environment variable @@ -271,6 +289,78 @@ def return_config_elements(self): ] return attributes + def set_from_ENV(self, conf): # pylint: disable=invalid-name + '''Replace strings like $VAR and ${VAR} with environment variable values. + + Parameters + ---------- + conf : any + + Returns + ------- + conf : any + + Examples + -------- + >>> import os + >>> os.environ['SAMPLE_VALUE_SFE'] = '/example/path' + >>> c = Configuration() + >>> c.set_from_ENV({'key': {'nested_list': [ + ... 1, '1', '$SAMPLE_VALUE_SFE/extended']}}) + {'key': {'nested_list': [1, '1', '/example/path/extended']}} + >>> c.set_from_ENV(['${SAMPLE_VALUE_SFE}', 'SAMPLE_VALUE_SFE']) + ['/example/path', 'SAMPLE_VALUE_SFE'] + >>> del os.environ['SAMPLE_VALUE_SFE'] + ''' + if isinstance(conf, list): + return [self.set_from_ENV(item) for item in conf] + if isinstance(conf, dict): + return {key: self.set_from_ENV(conf[key]) for key in conf} + if isinstance(conf, str): + # set any specified environment variables + # (only matching all-caps plus `-` and `_`) + # like `${VAR}` + _pattern1 = r'\${[A-Z\-_]*}' + # like `$VAR` + _pattern2 = r'\$[A-Z\-_]*(?=/|$)' + # replace with environment variables if they exist + for _pattern in [_pattern1, _pattern2]: + _match = re.search(_pattern, conf) + if _match: + _match = _match.group().lstrip('${').rstrip('}') + conf = re.sub( + _pattern, os.environ.get(_match, f'${_match}'), conf) + return conf + + def set_without_ENV(self, conf): # pylint: disable=invalid-name + '''Retain strings like $VAR and ${VAR} when setting attributes. + + Parameters + ---------- + conf : any + + Returns + ------- + conf : any + + Examples + -------- + >>> import os + >>> os.environ['SAMPLE_VALUE_SFE'] = '/example/path' + >>> c = Configuration() + >>> c.set_without_ENV({'key': {'nested_list': [ + ... 1, '1', '$SAMPLE_VALUE_SFE/extended']}}) + {'key': {'nested_list': [1, '1', '$SAMPLE_VALUE_SFE/extended']}} + >>> c.set_without_ENV(['${SAMPLE_VALUE_SFE}', 'SAMPLE_VALUE_SFE']) + ['${SAMPLE_VALUE_SFE}', 'SAMPLE_VALUE_SFE'] + >>> del os.environ['SAMPLE_VALUE_SFE'] + ''' + if isinstance(conf, list): + return [self.set_without_ENV(item) for item in conf] + if isinstance(conf, dict): + return {key: self.set_without_ENV(conf[key]) for key in conf} + return conf + def sub_pattern(self, pattern, orig_key): return orig_key.replace(pattern, self[pattern[2:-1].split('.')]) @@ -659,52 +749,9 @@ class Preconfiguration(Configuration): preconfig : str The canonical name of the preconfig to load """ - def __init__(self, preconfig): - super().__init__(config_map=preconfig_yaml(preconfig, True)) - - -def set_from_ENV(conf): # pylint: disable=invalid-name - '''Function to replace strings like $VAR and ${VAR} with - environment variable values - - Parameters - ---------- - conf : any - - Returns - ------- - conf : any - - Examples - -------- - >>> import os - >>> os.environ['SAMPLE_VALUE_SFE'] = '/example/path' - >>> set_from_ENV({'key': {'nested_list': [ - ... 1, '1', '$SAMPLE_VALUE_SFE/extended']}}) - {'key': {'nested_list': [1, '1', '/example/path/extended']}} - >>> set_from_ENV(['${SAMPLE_VALUE_SFE}', 'SAMPLE_VALUE_SFE']) - ['/example/path', 'SAMPLE_VALUE_SFE'] - >>> del os.environ['SAMPLE_VALUE_SFE'] - ''' - if isinstance(conf, list): - return [set_from_ENV(item) for item in conf] - if isinstance(conf, dict): - return {key: set_from_ENV(conf[key]) for key in conf} - if isinstance(conf, str): - # set any specified environment variables - # (only matching all-caps plus `-` and `_`) - # like `${VAR}` - _pattern1 = r'\${[A-Z\-_]*}' - # like `$VAR` - _pattern2 = r'\$[A-Z\-_]*(?=/|$)' - # replace with environment variables if they exist - for _pattern in [_pattern1, _pattern2]: - _match = re.search(_pattern, conf) - if _match: - _match = _match.group().lstrip('${').rstrip('}') - conf = re.sub( - _pattern, os.environ.get(_match, f'${_match}'), conf) - return conf + def __init__(self, preconfig, skip_env_check=False): + super().__init__(config_map=preconfig_yaml(preconfig, True), + skip_env_check=skip_env_check) def set_subject(sub_dict: dict, pipe_config: 'Configuration', diff --git a/CPAC/utils/configuration/yaml_template.py b/CPAC/utils/configuration/yaml_template.py old mode 100644 new mode 100755 index 8c43769ab0..7aaf39fc99 --- a/CPAC/utils/configuration/yaml_template.py +++ b/CPAC/utils/configuration/yaml_template.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Copyright (C) 2022 C-PAC Developers # This file is part of C-PAC. @@ -18,6 +19,7 @@ from copy import deepcopy import os import re +from typing import Optional, Union from datetime import datetime from hashlib import sha1 from click import BadParameter @@ -226,8 +228,10 @@ def _count_indent(line): return (len(line) - len(line.lstrip())) // 2 -def create_yaml_from_template(d, # pylint: disable=invalid-name - template='default', import_from=None): +def create_yaml_from_template( + d: Union[Configuration, dict], # pylint: disable=invalid-name + template: str = 'default', import_from: Optional[str] = None, + skip_env_check: Optional[bool] = False) -> str: """Save dictionary to a YAML file, keeping the structure (such as first level comments and ordering) from the template @@ -244,6 +248,9 @@ def create_yaml_from_template(d, # pylint: disable=invalid-name import_from : str, optional name of a preconfig. Full config is generated if omitted + skip_env_check : bool, optional + skip environment check (for validating a config without running) + Examples -------- >>> import yaml @@ -284,7 +291,7 @@ def create_yaml_from_template(d, # pylint: disable=invalid-name base_config = None else: # config based on preconfig d = Configuration(d) if not isinstance(d, Configuration) else d - base_config = Preconfiguration(import_from) + base_config = Preconfiguration(import_from, skip_env_check=skip_env_check) d = (d - base_config).left d.update({'FROM': import_from}) yaml_template = YamlTemplate(template, base_config) @@ -466,8 +473,9 @@ def update_a_preconfig(preconfig, import_from): """ import sys print(f'Updating {preconfig} preconfig…', file=sys.stderr) - updated = create_yaml_from_template(Preconfiguration(preconfig), - import_from=import_from) + updated = create_yaml_from_template(Preconfiguration(preconfig, + skip_env_check=True), + import_from=import_from, skip_env_check=True) with open(preconfig_yaml(preconfig), 'w', encoding='utf-8') as _f: _f.write(updated) From 9e1a3515ed52933604b7265642912c32d8605bef Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 26 Feb 2024 12:53:27 -0500 Subject: [PATCH 193/213] adding comment and setting robustfov off in blank config --- CPAC/resources/configs/pipeline_config_blank.yml | 3 ++- CPAC/resources/configs/pipeline_config_default.yml | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index e2f74e2f0e..1cfca94511 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,7 +342,8 @@ anatomical_preproc: monkey: Off FSL-BET: - Robustfov: On + # Crop out the neck regions before generating the mask + Robustfov: Off # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index d669663d9c..92a157f20c 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,7 +409,9 @@ anatomical_preproc: monkey: False FSL-BET: + # Crop out the neck regions before generating the mask Robustfov : Off + # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 frac: 0.5 From b2bb07ecf15ea95868093017ed08af560cd1c958 Mon Sep 17 00:00:00 2001 From: Biraj Shrestha Date: Mon, 26 Feb 2024 13:05:42 -0500 Subject: [PATCH 194/213] Edited comment to Robustfov switch --- CPAC/resources/configs/pipeline_config_blank.yml | 2 +- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_blank.yml b/CPAC/resources/configs/pipeline_config_blank.yml index 1cfca94511..932d9849c3 100644 --- a/CPAC/resources/configs/pipeline_config_blank.yml +++ b/CPAC/resources/configs/pipeline_config_blank.yml @@ -342,7 +342,7 @@ anatomical_preproc: monkey: Off FSL-BET: - # Crop out the neck regions before generating the mask + # Swich "On" to crop out neck regions before generating the mask (default: Off). Robustfov: Off # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 92a157f20c..afc419f225 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -409,7 +409,7 @@ anatomical_preproc: monkey: False FSL-BET: - # Crop out the neck regions before generating the mask + # Switch "On" to crop out neck regions before generating the mask (default: Off). Robustfov : Off # Set the threshold value controling the brain vs non-brain voxels, default is 0.5 From 611ccee8acd72dedd9a2dd8583230bf521433ee5 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 20 Feb 2024 22:17:29 -0500 Subject: [PATCH 195/213] :sparkles: Add ability to throttle a Node --- .../pipeline/nipype_pipeline_engine/engine.py | 42 +++++++++++++++---- .../plugins/cpac_nipype_custom.py | 4 ++ CPAC/utils/typing.py | 41 +++++++++++------- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/CPAC/pipeline/nipype_pipeline_engine/engine.py b/CPAC/pipeline/nipype_pipeline_engine/engine.py index 899f69bbcf..31092e5269 100644 --- a/CPAC/pipeline/nipype_pipeline_engine/engine.py +++ b/CPAC/pipeline/nipype_pipeline_engine/engine.py @@ -51,6 +51,7 @@ import re from copy import deepcopy from inspect import Parameter, Signature, signature +from typing import ClassVar, Optional, Union from nibabel import load from nipype.interfaces.utility import Function from nipype.pipeline import engine as pe @@ -69,6 +70,7 @@ from traits.trait_base import Undefined from traits.trait_handlers import TraitListObject from CPAC.utils.monitoring.custom_logging import getLogger +from CPAC.utils.typing import DICT # set global default mem_gb DEFAULT_MEM_GB = 2.0 @@ -153,7 +155,13 @@ class Node(pe.Node): {" >>> realign.inputs.in_files = 'functional.nii'"} ) - def __init__(self, *args, mem_gb=DEFAULT_MEM_GB, **kwargs): + def __init__( + self, + *args, + mem_gb: Optional[float] = DEFAULT_MEM_GB, + throttle: Optional[bool] = False, + **kwargs + ) -> None: # pylint: disable=import-outside-toplevel from CPAC.pipeline.random_state import random_seed super().__init__(*args, mem_gb=mem_gb, **kwargs) @@ -162,6 +170,8 @@ def __init__(self, *args, mem_gb=DEFAULT_MEM_GB, **kwargs): self.seed_applied = False self.input_data_shape = Undefined self._debug = False + if throttle: + self.throttle = True self.verbose_logger = None self._mem_x = {} if 'mem_x' in kwargs and isinstance( @@ -195,7 +205,8 @@ def __init__(self, *args, mem_gb=DEFAULT_MEM_GB, **kwargs): Parameter('mem_gb', Parameter.POSITIONAL_OR_KEYWORD, default=DEFAULT_MEM_GB) )[1] for p in orig_sig_params[:-1]] + [ - Parameter('mem_x', Parameter.KEYWORD_ONLY), + Parameter('mem_x', Parameter.KEYWORD_ONLY, default=None), + Parameter("throttle", Parameter.KEYWORD_ONLY, default=False), orig_sig_params[-1][1] ]) @@ -232,7 +243,11 @@ def __init__(self, *args, mem_gb=DEFAULT_MEM_GB, **kwargs): ``mode`` can be any one of * 'xyzt' (spatial * temporal) (default if not specified) * 'xyz' (spatial) - * 't' (temporal)'''])) # noqa: E501 # pylint: disable=line-too-long + * 't' (temporal) + + throttle : bool, optional + Assume this Node will use all available memory if no observation run is + provided.'''])) # noqa: E501 # pylint: disable=line-too-long def _add_flags(self, flags): r''' @@ -440,12 +455,21 @@ def __init__(self, *args, **kwargs): if not self.name.endswith('_'): self.name = f'{self.name}_' - __init__.__signature__ = Signature(parameters=[ - p[1] if p[0] != 'mem_gb' else ( - 'mem_gb', - Parameter('mem_gb', Parameter.POSITIONAL_OR_KEYWORD, - default=DEFAULT_MEM_GB) - )[1] for p in signature(pe.Node).parameters.items()]) + _parameters: ClassVar[DICT[str, Parameter]] = {} + _custom_params: ClassVar[DICT[str, Union[bool, float]]] = { + "mem_gb": DEFAULT_MEM_GB, + "throttle": False, + } + for param, default in _custom_params.items(): + for p in signature(pe.Node).parameters.items(): + if p[0] in _custom_params: + _parameters[p[0]] = Parameter( + param, Parameter.POSITIONAL_OR_KEYWORD, default=default + ) + else: + _parameters[p[0]] = p[1] + __init__.__signature__ = Signature(parameters=list(_parameters.values())) + del _custom_params, _parameters class Workflow(pe.Workflow): diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py index a843931783..3ff81f676f 100644 --- a/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py +++ b/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py @@ -194,6 +194,10 @@ def _prerun_check(self, graph): for node in graph.nodes(): if hasattr(self, 'runtime'): self._override_memory_estimate(node) + elif hasattr(node, "throttle"): + # for a throttled node without an observation run, + # assume all available memory will be needed + node._mem_gb = self.memory_gb try: node_memory_estimate = node.mem_gb except FileNotFoundError: diff --git a/CPAC/utils/typing.py b/CPAC/utils/typing.py index a838a7c76b..cfb6dd0612 100644 --- a/CPAC/utils/typing.py +++ b/CPAC/utils/typing.py @@ -15,39 +15,48 @@ # You should have received a copy of the GNU Lesser General Public # License along with C-PAC. If not, see . """ -Helpers and aliases for handling typing in main and variant Python versions +Helpers and aliases for handling typing in main and variant Python versions. Once all variants (see {DOCS_URL_PREFIX}/user/versions#variants) run Python ≥ 3.10, these global variables can be replaced with the current preferred syntax. """ +from pathlib import Path import sys from typing import Union + from CPAC.utils.docs import DOCS_URL_PREFIX # Set the version-specific documentation URL in the module docstring: -__doc__ = __doc__.replace(r'{DOCS_URL_PREFIX}', DOCS_URL_PREFIX) +__doc__ = __doc__.replace(r"{DOCS_URL_PREFIX}", DOCS_URL_PREFIX) # noqa: A001 if sys.version_info >= (3, 8): - from typing import Literal - LITERAL = Literal + from typing import Literal as LITERAL else: - from typing_extensions import Literal - LITERAL = Literal + from typing_extensions import Literal as LITERAL if sys.version_info >= (3, 9): - from collections.abc import Iterable - LIST = list + from builtins import dict as DICT, list as LIST + from collections.abc import Iterable as ITERABLE else: - from typing import Iterable, List - LIST = List + from typing import Dict as DICT, Iterable as ITERABLE, List as LIST if sys.version_info >= (3, 10): + from builtins import tuple as TUPLE + LIST_OR_STR = LIST[str] | str # pylint: disable=invalid-name - TUPLE = tuple else: - from typing import Tuple + from typing import Tuple as TUPLE + LIST_OR_STR = Union[LIST[str], str] # pylint: disable=invalid-name - TUPLE = Tuple -ITERABLE = Iterable + +PATHSTR = Union[Path, str] ConfigKeyType = Union[str, LIST[str]] -__all__ = ['ConfigKeyType', 'ITERABLE', 'LIST', 'LIST_OR_STR', 'LITERAL', - 'TUPLE'] +__all__ = [ + "ConfigKeyType", + "DICT", + "ITERABLE", + "LIST", + "LIST_OR_STR", + "LITERAL", + "PATHSTR", + "TUPLE", +] From 5f53a37b366fe0ca8b245797ac7a2e1b60cbf368 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 20 Feb 2024 22:19:25 -0500 Subject: [PATCH 196/213] :zap: Throttle `aCompCor_cosine_filter` --- CPAC/nuisance/nuisance.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CPAC/nuisance/nuisance.py b/CPAC/nuisance/nuisance.py index 97b5186f1a..a2beb7d2c6 100644 --- a/CPAC/nuisance/nuisance.py +++ b/CPAC/nuisance/nuisance.py @@ -1281,8 +1281,9 @@ def create_regressor_workflow(nuisance_selectors, output_names=['cosfiltered_img'], function=cosine_filter, imports=cosfilter_imports), - name='{}_cosine_filter'.format(regressor_type), - mem_gb=8.0) + name=f'{regressor_type}_cosine_filter', + mem_gb=8.0, + throttle=regressor_type.lower() == "acompcor") nuisance_wf.connect( summary_filter_input[0], summary_filter_input[1], cosfilter_node, 'input_image_path' From e44dc70038531b22dbfd53b0edd454399254de05 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 20 Feb 2024 22:23:24 -0500 Subject: [PATCH 197/213] :white_check_mark: Test Node throttling --- .../test/test_nipype_pipeline_engine.py | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/CPAC/pipeline/test/test_nipype_pipeline_engine.py b/CPAC/pipeline/test/test_nipype_pipeline_engine.py index f722a839cb..ef0efd282f 100644 --- a/CPAC/pipeline/test/test_nipype_pipeline_engine.py +++ b/CPAC/pipeline/test/test_nipype_pipeline_engine.py @@ -1,11 +1,35 @@ +# Copyright (C) 2021-2024 C-PAC Developers + +# This file is part of C-PAC. + +# C-PAC is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. + +# C-PAC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with C-PAC. If not, see . +"""Tests for C-PAC customizations to nipype.pipeline.engine.""" import os import pytest from nibabel.testing import data_path -from nipype import Function from nipype.interfaces.utility import IdentityInterface +from nipype.utils.profiler import get_system_total_memory_gb from traits.trait_base import Undefined + +from CPAC.nuisance.utils.compcor import cosine_filter from CPAC.pipeline.nipype_pipeline_engine import ( DEFAULT_MEM_GB, get_data_size, Node, MapNode, Workflow) +from CPAC.pipeline.nipype_pipeline_engine.plugins import ( + LegacyMultiProcPlugin, + MultiProcPlugin, +) +from CPAC.utils.interfaces.function import Function def get_sample_data(filepath): @@ -35,6 +59,32 @@ def test_Node(): # pylint: disable=invalid-name assert res.outputs.f_x == 4 +@pytest.mark.parametrize("plugin", [LegacyMultiProcPlugin, MultiProcPlugin]) +@pytest.mark.parametrize("throttle", [True, False]) +def test_throttle(plugin: type, throttle: bool) -> None: + """Test Node throttling.""" + small_estimate = 0.0003 + cosfilter_node = Node( + Function( + input_names=["input_image_path", "timestep"], + output_names=["cosfiltered_img"], + function=cosine_filter, + as_module=True, + ), + name="aCompCor_cosine_filter", + mem_gb=small_estimate, + throttle=throttle, + ) + wf = Workflow(name="aCompCor_cosine_filter_wf") + wf.add_nodes([cosfilter_node]) + plugin(plugin_args={"raise_insufficient": False})._prerun_check(wf._graph) + if throttle: + assert cosfilter_node.mem_gb > small_estimate + assert cosfilter_node.mem_gb <= get_system_total_memory_gb() + else: + assert cosfilter_node.mem_gb == small_estimate + + def test_Workflow(tmpdir): # pylint: disable=invalid-name example_filepath = os.path.join(data_path, 'example4d.nii.gz') pass_in_filepath = IdentityInterface(fields=['x']) From 3a8a4cbb666ba4d6c1ee1c9e68660681e53bde71 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Tue, 20 Feb 2024 22:24:42 -0500 Subject: [PATCH 198/213] :loud_sound: Log `throttle` in `CHANGELOG` --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a82d99c3c..08878d2708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,11 +16,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] -## Added +### Added - `Robustfov` feature in `FSL-BET` to crop images ensuring removal of neck regions that may appear in the skull-stripped images. +- Ability to throttle nodes, estimating all available memory when threading -## Changed +### Changed - Moved autoversioning from CI to pre-commit - Updated `FSL-BET` config to default `-mask-boolean` flag as on, and removed all removed `mask-boolean` keys from configs. @@ -28,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.8.6] - 2024-01-15 -## Added +### Added - Some automatic handling of user-provided BIDSy atlas names. - `sig_imports` static method decorator for `Function` nodes, to accommodate type hinting in signatures of `Function` node functions. From 955155ec004eee918f85570ba50cb4a0f3ed0026 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Fri, 23 Feb 2024 11:20:52 -0500 Subject: [PATCH 199/213] :bug: Don't include overhead in throttled node allocation --- .../nipype_pipeline_engine/plugins/cpac_nipype_custom.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py b/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py index 3ff81f676f..e96f2d0e3a 100644 --- a/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py +++ b/CPAC/pipeline/nipype_pipeline_engine/plugins/cpac_nipype_custom.py @@ -47,6 +47,9 @@ from CPAC.utils.monitoring import log_nodes_cb +OVERHEAD_MEMORY_ESTIMATE: float = 1 # estimate of C-PAC + Nipype overhead (GB) + + def get_peak_usage(): """Function to return peak usage in GB. @@ -189,21 +192,19 @@ def _prerun_check(self, graph): tasks_num_th = [] overrun_message_mem = None overrun_message_th = None - # estimate of C-PAC + Nipype overhead (GB): - overhead_memory_estimate = 1 for node in graph.nodes(): if hasattr(self, 'runtime'): self._override_memory_estimate(node) elif hasattr(node, "throttle"): # for a throttled node without an observation run, # assume all available memory will be needed - node._mem_gb = self.memory_gb + node._mem_gb = self.memory_gb - OVERHEAD_MEMORY_ESTIMATE try: node_memory_estimate = node.mem_gb except FileNotFoundError: # pylint: disable=protected-access node_memory_estimate = node._apply_mem_x(UNDEFINED_SIZE) - node_memory_estimate += overhead_memory_estimate + node_memory_estimate += OVERHEAD_MEMORY_ESTIMATE if node_memory_estimate > self.memory_gb: tasks_mem_gb.append((node.name, node_memory_estimate)) if node.n_procs > self.processors: From 1018f8c47c02ede844dd6bd880e9954014086846 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 13 Mar 2024 14:29:46 -0400 Subject: [PATCH 200/213] :zap: Throttle `calc_ants_warp` --- CPAC/registration/registration.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CPAC/registration/registration.py b/CPAC/registration/registration.py index cd3e69444a..8658aae219 100644 --- a/CPAC/registration/registration.py +++ b/CPAC/registration/registration.py @@ -1209,7 +1209,8 @@ def create_wf_calculate_ants_warp( imports=reg_imports), name='calc_ants_warp', mem_gb=2.8, - mem_x=(2e-7, 'moving_brain', 'xyz')) + mem_x=(2e-7, 'moving_brain', 'xyz'), + throttle=True) calculate_ants_warp.interface.num_threads = num_threads From dab49253641f2804047a39549176e1ab40ba83e7 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 13 Mar 2024 14:31:49 -0400 Subject: [PATCH 201/213] :zap: Throttle `cal_DVARS` --- CPAC/generate_motion_statistics/generate_motion_statistics.py | 3 ++- CPAC/qc/xcp.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CPAC/generate_motion_statistics/generate_motion_statistics.py b/CPAC/generate_motion_statistics/generate_motion_statistics.py index f8400804ef..8d918dd07d 100644 --- a/CPAC/generate_motion_statistics/generate_motion_statistics.py +++ b/CPAC/generate_motion_statistics/generate_motion_statistics.py @@ -207,7 +207,8 @@ def motion_power_statistics(name='motion_stats', name='cal_DVARS', mem_gb=0.4, mem_x=(739971956005215 / 151115727451828646838272, - 'in_file')) + 'in_file'), + throttle=True) cal_DVARS_strip = pe.Node(Function(input_names=['file_1D'], output_names=['out_file', 'DVARS_val'], diff --git a/CPAC/qc/xcp.py b/CPAC/qc/xcp.py index 3104256c02..0f6494a69f 100644 --- a/CPAC/qc/xcp.py +++ b/CPAC/qc/xcp.py @@ -112,7 +112,8 @@ def _connect_motion(wf, nodes, strat_pool, qc_file, pipe_num): name=f'cal_DVARS_{pipe_num}', mem_gb=0.4, mem_x=(739971956005215 / 151115727451828646838272, - 'in_file')) + 'in_file'), + throttle=True) cal_DVARS_strip = pe.Node(Function(input_names=['file_1D'], output_names=['out_file'], function=DVARS_strip_t0, From a469562a43761a92ca7729b86584d85f7983de19 Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Wed, 13 Mar 2024 14:33:12 -0400 Subject: [PATCH 202/213] :zap: Throttle all cosine filters --- CPAC/nuisance/nuisance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/nuisance/nuisance.py b/CPAC/nuisance/nuisance.py index a2beb7d2c6..c19fd26080 100644 --- a/CPAC/nuisance/nuisance.py +++ b/CPAC/nuisance/nuisance.py @@ -1283,7 +1283,7 @@ def create_regressor_workflow(nuisance_selectors, imports=cosfilter_imports), name=f'{regressor_type}_cosine_filter', mem_gb=8.0, - throttle=regressor_type.lower() == "acompcor") + throttle=True) nuisance_wf.connect( summary_filter_input[0], summary_filter_input[1], cosfilter_node, 'input_image_path' From 07dd8e0cc92fabfdaf89c956b11c1d4ea6a9279a Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 19 Mar 2024 13:37:49 -0400 Subject: [PATCH 203/213] Change 'regressors' to 'timeseries' to match new naming --- CPAC/pipeline/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 3675c4035d..e13f9fb74e 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1060,7 +1060,7 @@ def gather_pipes(self, wf, cfg, all=False, add_incl=None, add_excl=None): self.rpool[resource]] unlabelled = set(key for json_info in all_jsons for key in json_info.get('CpacVariant', {}).keys() if - key not in (*MOVEMENT_FILTER_KEYS, 'regressors')) + key not in (*MOVEMENT_FILTER_KEYS, 'timeseries')) if 'bold' in unlabelled: all_bolds = list( chain.from_iterable(json_info['CpacVariant']['bold'] for From d0723419efb4862389732fec1f0ffd60ef5f095a Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 19 Mar 2024 13:38:20 -0400 Subject: [PATCH 204/213] Make default value 'Off' for surface_connectivity --- CPAC/resources/configs/pipeline_config_default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/resources/configs/pipeline_config_default.yml b/CPAC/resources/configs/pipeline_config_default.yml index 7c5416a7cc..71609ce58d 100644 --- a/CPAC/resources/configs/pipeline_config_default.yml +++ b/CPAC/resources/configs/pipeline_config_default.yml @@ -235,7 +235,7 @@ surface_analysis: smooth_fwhm: 2 surface_connectivity: - run: On + run: Off surface_parcellation_template: /cpac_templates/Schaefer2018_200Parcels_17Networks_order.dlabel.nii longitudinal_template_generation: From cff2beac6e4f8e5df596f9358fc4ace3f84042ba Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 19 Mar 2024 13:40:13 -0400 Subject: [PATCH 205/213] Make argument optional --- CPAC/utils/datasource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPAC/utils/datasource.py b/CPAC/utils/datasource.py index 5a550765df..0a45ae37b7 100644 --- a/CPAC/utils/datasource.py +++ b/CPAC/utils/datasource.py @@ -405,7 +405,7 @@ def calc_delta_te_and_asym_ratio(effective_echo_spacing: float, return deltaTE, ees_asym_ratio -def gather_echo_times(echotime_1, echotime_2, echotime_3=None, echotime_4=None): +def gather_echo_times(echotime_1, echotime_2=None, echotime_3=None, echotime_4=None): echotime_list = [echotime_1, echotime_2, echotime_3, echotime_4] echotime_list = list(filter(lambda item: item is not None, echotime_list)) echotime_list = list(set(echotime_list)) From 9f4a3fe959fbc150d47a9859f09c63fd1e46319c Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally Date: Tue, 26 Mar 2024 15:04:32 -0400 Subject: [PATCH 206/213] Make 'regressors' field optional with ingress --- CPAC/pipeline/engine.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index e13f9fb74e..fb87af0eb4 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -266,15 +266,20 @@ def regressor_dct(self, cfg) -> dict: "Try turning on create_regressors or " "ingress_regressors.") _nr = cfg['nuisance_corrections', '2-nuisance_regression'] + if not hasattr(self, 'timeseries'): - self.regressors = {reg["Name"]: reg for reg in _nr['Regressors']} + if _nr['Regressors']: + self.regressors = {reg["Name"]: reg for reg in _nr['Regressors']} + else: + self.regressors = [] if self.check_rpool('parsed_regressors'): # ingressed regressor # name regressor workflow without regressor_prov strat_name = _nr['ingress_regressors']['Regressors']['Name'] if strat_name in self.regressors: self._regressor_dct = self.regressors[strat_name] return self._regressor_dct - raise key_error + self.regressor_dct = _nr['ingress_regressors']['Regressors'] + return self.regressor_dct prov = self.get_cpac_provenance('desc-confounds_timeseries') strat_name_components = prov[-1].split('_') for _ in list(range(prov[-1].count('_'))): From d3eab644141c229eb3a60944efb44b0956eee1c7 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally <113037677+e-kenneally@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:17:22 -0400 Subject: [PATCH 207/213] Remove unused regressors from fmriprep-ingress pipeline --- .../pipeline_config_fmriprep-ingress.yml | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml index c65af74391..cb81ba5958 100644 --- a/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml +++ b/CPAC/resources/configs/pipeline_config_fmriprep-ingress.yml @@ -59,26 +59,6 @@ nuisance_corrections: # Select which nuisance signal corrections to apply Regressors: - Name: default - Motion: - include_delayed: On - include_squared: On - include_delayed_squared: On - aCompCor: - summary: - method: DetrendPC - components: 5 - tissues: - - WhiteMatter - - CerebrospinalFluid - extraction_resolution: 2 - CerebrospinalFluid: - summary: Mean - extraction_resolution: 2 - erode_mask: On - GlobalSignal: - summary: Mean - PolyOrt: - degree: 2 Bandpass: bottom_frequency: 0.01 top_frequency: 0.1 From 5ff7a4ca73074446b67c4e6c75ae07c60ff6007c Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally <113037677+e-kenneally@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:35:25 -0400 Subject: [PATCH 208/213] Enable smoothing & z-scoring with ingress --- CPAC/pipeline/engine.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index fb87af0eb4..08377fe8f0 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -840,7 +840,10 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x, # or lfcd [binarized or weighted] mask = 'template-specification-file' elif 'space-template' in label: - mask = 'space-template_res-derivative_desc-bold_mask' + if 'space-template_res-derivative_desc-bold_mask' in self.rpool.keys(): + mask = 'space-template_res-derivative_desc-bold_mask' + else: + mask = 'space-template_desc-bold_mask' else: mask = 'space-bold_desc-brain_mask' From 1a33ada511ed111f27f6331569a0221f369ae133 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally <113037677+e-kenneally@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:23:29 -0400 Subject: [PATCH 209/213] :sparkles: Make fs ingress configurable from cmdline --- CPAC/pipeline/engine.py | 121 +++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 51 deletions(-) diff --git a/CPAC/pipeline/engine.py b/CPAC/pipeline/engine.py index 08377fe8f0..09be47823a 100644 --- a/CPAC/pipeline/engine.py +++ b/CPAC/pipeline/engine.py @@ -1761,61 +1761,80 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id, def ingress_freesurfer(wf, rpool, cfg, data_paths, unique_id, part_id, ses_id): - if 'anat' not in data_paths: + try: + fs_path = os.path.join(cfg.pipeline_setup['freesurfer_dir'], part_id) + except KeyError: print('No FreeSurfer data present.') return rpool - if 'freesurfer_dir' in data_paths['anat']: - fs_ingress = create_general_datasource('gather_freesurfer_dir') - fs_ingress.inputs.inputnode.set( - unique_id=unique_id, - data=data_paths['anat']['freesurfer_dir'], - creds_path=data_paths['creds_path'], - dl_dir=cfg.pipeline_setup['working_directory']['path']) - rpool.set_data("freesurfer-subject-dir", fs_ingress, 'outputspec.data', - {}, "", "freesurfer_config_ingress") - - recon_outs = { - 'pipeline-fs_raw-average': 'mri/rawavg.mgz', - 'pipeline-fs_subcortical-seg': 'mri/aseg.mgz', - 'pipeline-fs_brainmask': 'mri/brainmask.mgz', - 'pipeline-fs_wmparc': 'mri/wmparc.mgz', - 'pipeline-fs_T1': 'mri/T1.mgz', - 'pipeline-fs_hemi-L_desc-surface_curv': 'surf/lh.curv', - 'pipeline-fs_hemi-R_desc-surface_curv': 'surf/rh.curv', - 'pipeline-fs_hemi-L_desc-surfaceMesh_pial': 'surf/lh.pial', - 'pipeline-fs_hemi-R_desc-surfaceMesh_pial': 'surf/rh.pial', - 'pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm': 'surf/lh.smoothwm', - 'pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm': 'surf/rh.smoothwm', - 'pipeline-fs_hemi-L_desc-surfaceMesh_sphere': 'surf/lh.sphere', - 'pipeline-fs_hemi-R_desc-surfaceMesh_sphere': 'surf/rh.sphere', - 'pipeline-fs_hemi-L_desc-surfaceMap_sulc': 'surf/lh.sulc', - 'pipeline-fs_hemi-R_desc-surfaceMap_sulc': 'surf/rh.sulc', - 'pipeline-fs_hemi-L_desc-surfaceMap_thickness': 'surf/lh.thickness', - 'pipeline-fs_hemi-R_desc-surfaceMap_thickness': 'surf/rh.thickness', - 'pipeline-fs_hemi-L_desc-surfaceMap_volume': 'surf/lh.volume', - 'pipeline-fs_hemi-R_desc-surfaceMap_volume': 'surf/rh.volume', - 'pipeline-fs_hemi-L_desc-surfaceMesh_white': 'surf/lh.white', - 'pipeline-fs_hemi-R_desc-surfaceMesh_white': 'surf/rh.white', - 'pipeline-fs_xfm': 'mri/transforms/talairach.lta' - } + #fs_path = os.path.join(cfg.pipeline_setup['freesurfer_dir'], part_id) + if not os.path.exists(fs_path): + if 'sub' in part_id: + fs_path = os.path.join(cfg.pipeline_setup['freesurfer_dir'], part_id.replace('sub-', '')) + else: + fs_path = os.path.join(cfg.pipeline_setup['freesurfer_dir'], ('sub-' + part_id)) - for key, outfile in recon_outs.items(): - fullpath = os.path.join(data_paths['anat']['freesurfer_dir'], - outfile) - if os.path.exists(fullpath): - fs_ingress = create_general_datasource(f'gather_fs_{key}_dir') - fs_ingress.inputs.inputnode.set( - unique_id=unique_id, - data=fullpath, - creds_path=data_paths['creds_path'], - dl_dir=cfg.pipeline_setup['working_directory']['path']) - rpool.set_data(key, fs_ingress, 'outputspec.data', - {}, "", f"fs_{key}_ingress") - else: - warnings.warn(str( - LookupError("\n[!] Path does not exist for " - f"{fullpath}.\n"))) + # patch for flo-specific data + if not os.path.exists(fs_path): + subj_ses = part_id + '-' + ses_id + fs_path = os.path.join(cfg.pipeline_setup['freesurfer_dir'], subj_ses) + if not os.path.exists(fs_path): + print(f'No FreeSurfer data found for subject {part_id}') + return rpool + + # Check for double nested subj names + if os.path.exists(os.path.join(fs_path, os.path.basename(fs_path))): + fs_path = os.path.join(fs_path, part_id) + + fs_ingress = create_general_datasource('gather_freesurfer_dir') + fs_ingress.inputs.inputnode.set( + unique_id=unique_id, + data=fs_path, + creds_path=data_paths['creds_path'], + dl_dir=cfg.pipeline_setup['working_directory']['path']) + rpool.set_data("freesurfer-subject-dir", fs_ingress, 'outputspec.data', + {}, "", "freesurfer_config_ingress") + + recon_outs = { + 'pipeline-fs_raw-average': 'mri/rawavg.mgz', + 'pipeline-fs_subcortical-seg': 'mri/aseg.mgz', + 'pipeline-fs_brainmask': 'mri/brainmask.mgz', + 'pipeline-fs_wmparc': 'mri/wmparc.mgz', + 'pipeline-fs_T1': 'mri/T1.mgz', + 'pipeline-fs_hemi-L_desc-surface_curv': 'surf/lh.curv', + 'pipeline-fs_hemi-R_desc-surface_curv': 'surf/rh.curv', + 'pipeline-fs_hemi-L_desc-surfaceMesh_pial': 'surf/lh.pial', + 'pipeline-fs_hemi-R_desc-surfaceMesh_pial': 'surf/rh.pial', + 'pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm': 'surf/lh.smoothwm', + 'pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm': 'surf/rh.smoothwm', + 'pipeline-fs_hemi-L_desc-surfaceMesh_sphere': 'surf/lh.sphere', + 'pipeline-fs_hemi-R_desc-surfaceMesh_sphere': 'surf/rh.sphere', + 'pipeline-fs_hemi-L_desc-surfaceMap_sulc': 'surf/lh.sulc', + 'pipeline-fs_hemi-R_desc-surfaceMap_sulc': 'surf/rh.sulc', + 'pipeline-fs_hemi-L_desc-surfaceMap_thickness': 'surf/lh.thickness', + 'pipeline-fs_hemi-R_desc-surfaceMap_thickness': 'surf/rh.thickness', + 'pipeline-fs_hemi-L_desc-surfaceMap_volume': 'surf/lh.volume', + 'pipeline-fs_hemi-R_desc-surfaceMap_volume': 'surf/rh.volume', + 'pipeline-fs_hemi-L_desc-surfaceMesh_white': 'surf/lh.white', + 'pipeline-fs_hemi-R_desc-surfaceMesh_white': 'surf/rh.white', + 'pipeline-fs_xfm': 'mri/transforms/talairach.lta' + } + + for key, outfile in recon_outs.items(): + fullpath = os.path.join(fs_path, outfile) + if os.path.exists(fullpath): + fs_ingress = create_general_datasource(f'gather_fs_{key}_dir') + fs_ingress.inputs.inputnode.set( + unique_id=unique_id, + data=fullpath, + creds_path=data_paths['creds_path'], + dl_dir=cfg.pipeline_setup['working_directory']['path']) + rpool.set_data(key, fs_ingress, 'outputspec.data', + {}, "", f"fs_{key}_ingress") + else: + warnings.warn(str( + LookupError("\n[!] Path does not exist for " + f"{fullpath}.\n"))) return rpool From 9b8bd6ed285dceeb93b746dfeaad2acdad0ba179 Mon Sep 17 00:00:00 2001 From: Elizabeth Kenneally <113037677+e-kenneally@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:30:15 -0400 Subject: [PATCH 210/213] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08878d2708..04610a5ae2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Robustfov` feature in `FSL-BET` to crop images ensuring removal of neck regions that may appear in the skull-stripped images. - Ability to throttle nodes, estimating all available memory when threading +- Ability to configure FreeSurfer ingress from the command line ### Changed From d69f874d1236628bcfdd5c42c22b9ebba4e81b4e Mon Sep 17 00:00:00 2001 From: Steve Giavasis Date: Wed, 1 May 2024 16:40:45 -0400 Subject: [PATCH 211/213] Update CHANGELOG.md --- CHANGELOG.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04610a5ae2..50b4e225cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,19 +14,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [unreleased] +## [1.8.7] - 2024-05-03 ### Added - `Robustfov` feature in `FSL-BET` to crop images ensuring removal of neck regions that may appear in the skull-stripped images. -- Ability to throttle nodes, estimating all available memory when threading -- Ability to configure FreeSurfer ingress from the command line +- Ability to throttle nodes, estimating all available memory when threading. +- Ability to configure FreeSurfer ingress from the command line. ### Changed - Moved autoversioning from CI to pre-commit - Updated `FSL-BET` config to default `-mask-boolean` flag as on, and removed all removed `mask-boolean` keys from configs. -- Added `dvars` as optional output in `cpac_outputs` +- Added `dvars` as optional output in `cpac_outputs`. + +### Fixed + +- Fixed a bug where ingressing fmriprep outputs into C-PAC with a blank nuisance confounds field in the C-PAC pipeline configuration file would cause a crash. +- Fixed a bug where spatial smoothing and z-scoring of final outputs would sometimes fail to run when running a C-PAC pipeline that would ingress fmriprep outputs. +- Fixed a bug where ingress of distortion correction-related field map metadata would sometimes fail to recognize both echo times, when there were two present, leading to an error message claiming an echo time is missing. +- Changed an extraneous default pipeline configuration setting - `surface_connectivity` is now disabled in the default configuration as intended. ## [1.8.6] - 2024-01-15 From ff57b3f4936c71198b9b33737181e20afe0a6718 Mon Sep 17 00:00:00 2001 From: Steve Giavasis Date: Wed, 1 May 2024 16:42:19 -0400 Subject: [PATCH 212/213] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b4e225cd..bd2ad749db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- The ABCD-pipeline based surface post-processing workflows have been modularized to be more robust, resolving a running issue with this part of the pipeline stalling or crashing in some runs. - Moved autoversioning from CI to pre-commit - Updated `FSL-BET` config to default `-mask-boolean` flag as on, and removed all removed `mask-boolean` keys from configs. - Added `dvars` as optional output in `cpac_outputs`. From f4f3ba2ab86c184f23f40a50e742cd2d9245b4cd Mon Sep 17 00:00:00 2001 From: Jon Clucas Date: Thu, 2 May 2024 10:58:12 -0400 Subject: [PATCH 213/213] :rewind: Revert file mode changes from 9e9503d26 & 21911eacf --- CPAC/pipeline/cpac_pipeline.py | 0 CPAC/surface/surf_preproc.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 CPAC/pipeline/cpac_pipeline.py mode change 100755 => 100644 CPAC/surface/surf_preproc.py diff --git a/CPAC/pipeline/cpac_pipeline.py b/CPAC/pipeline/cpac_pipeline.py old mode 100755 new mode 100644 diff --git a/CPAC/surface/surf_preproc.py b/CPAC/surface/surf_preproc.py old mode 100755 new mode 100644