Skip to content

Commit d8cf7b3

Browse files
authored
Merge pull request #1932 from FCP-INDI/bugfix/log_subprocess
🐛 log_subprocess added as local import in function node
2 parents 73f7af2 + 6843889 commit d8cf7b3

File tree

12 files changed

+322
-31
lines changed

12 files changed

+322
-31
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
- Added the ability to ingress FreeSurfer data into CPAC
3232
- Added the ability to toggle FreeSurfer derived masks for brain extraction
3333
- Added an optional volume center to FD-J calculation
34+
- Added new preconfig `abcd-prep`, which performs minimal preprocessing on the T1w data in preparation for Freesurfer Recon-All
3435

3536
### Changed
3637
- Freesurfer output directory ingress moved to the data configuration YAML

CPAC/anat_preproc/anat_preproc.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
mri_convert, \
1717
wb_command, \
1818
fslmaths_command, \
19-
VolumeRemoveIslands
19+
VolumeRemoveIslands, \
20+
normalize_wmparc
2021
from CPAC.pipeline.engine import flatten_list
2122
from CPAC.utils.docs import docstring_parameter
2223
from CPAC.utils.interfaces.fsl import Merge as fslMerge
@@ -925,23 +926,24 @@ def freesurfer_abcd_brain_connector(wf, cfg, strat_pool, pipe_num, opt):
925926
# Register wmparc file if ingressing FreeSurfer data
926927
if strat_pool.check_rpool('pipeline-fs_xfm'):
927928

928-
wmparc_to_native = pe.Node(
929-
interface=freesurfer.ApplyVolTransform(),
930-
name='wmparc_to_native')
929+
wmparc_to_native = pe.Node(util.Function(input_names=['source_file',
930+
'target_file',
931+
'xfm',
932+
'out_file'],
933+
output_names=['transformed_file'],
934+
function=normalize_wmparc),
935+
name=f'wmparc_to_native_{pipe_num}')
931936

932-
wmparc_to_native.inputs.reg_header = True
937+
wmparc_to_native.inputs.out_file = 'wmparc_warped.mgz'
933938

934-
node, out = strat_pool.get_data('pipeline-fs_wmparc')
939+
node, out = strat_pool.get_data('pipeline-fs_wmparc')
935940
wf.connect(node, out, wmparc_to_native, 'source_file')
936941

937942
node, out = strat_pool.get_data('pipeline-fs_raw-average')
938943
wf.connect(node, out, wmparc_to_native, 'target_file')
939944

940945
node, out = strat_pool.get_data('pipeline-fs_xfm')
941-
wf.connect(node, out, wmparc_to_native, 'xfm_reg_file')
942-
943-
node, out = strat_pool.get_data('freesurfer-subject-dir')
944-
wf.connect(node, out, wmparc_to_native, 'subjects_dir')
946+
wf.connect(node, out, wmparc_to_native, 'xfm')
945947

946948
wf.connect(wmparc_to_native, 'transformed_file', wmparc_to_nifti, 'in_file')
947949

@@ -1271,8 +1273,8 @@ def acpc_align_head(wf, cfg, strat_pool, pipe_num, opt=None):
12711273
["anatomical_preproc", "run"]],
12721274
"option_key": "None",
12731275
"option_val": "None",
1274-
"inputs": ["desc-head_T1w",
1275-
"desc-preproc_T1w",
1276+
"inputs": [["desc-preproc_T1w",
1277+
"desc-head_T1w"],
12761278
"T1w-ACPC-template"],
12771279
"outputs": ["desc-head_T1w",
12781280
"desc-preproc_T1w",
@@ -1285,7 +1287,7 @@ def acpc_align_head(wf, cfg, strat_pool, pipe_num, opt=None):
12851287
mask=False,
12861288
wf_name=f'acpc_align_{pipe_num}')
12871289

1288-
node, out = strat_pool.get_data(['desc-head_T1w', 'desc-preproc_T1w'])
1290+
node, out = strat_pool.get_data(['desc-preproc_T1w','desc-head_T1w'])
12891291
wf.connect(node, out, acpc_align, 'inputspec.anat_leaf')
12901292

12911293
node, out = strat_pool.get_data('T1w-ACPC-template')
@@ -2564,10 +2566,10 @@ def brain_extraction_temp_T2(wf, cfg, strat_pool, pipe_num, opt=None):
25642566
def freesurfer_abcd_preproc(wf, cfg, strat_pool, pipe_num, opt=None):
25652567
'''
25662568
{"name": "freesurfer_abcd_preproc",
2567-
"config": ["anatomical_preproc", "brain_extraction"],
2568-
"switch": "None",
2569-
"option_key": "using",
2570-
"option_val": "FreeSurfer-ABCD",
2569+
"config": ["surface_analysis", "abcd_prefreesurfer_prep"],
2570+
"switch": ["run"],
2571+
"option_key": "None",
2572+
"option_val": "None",
25712573
"inputs": ["desc-preproc_T1w",
25722574
"T1w-template",
25732575
"T1w-brain-template-mask",
@@ -2576,16 +2578,17 @@ def freesurfer_abcd_preproc(wf, cfg, strat_pool, pipe_num, opt=None):
25762578
"freesurfer-subject-dir"],
25772579
"outputs": ["desc-restore_T1w",
25782580
"desc-restore-brain_T1w",
2581+
"desc-ABCDpreproc_T1w",
25792582
"pipeline-fs_desc-fast_biasfield",
25802583
"pipeline-fs_hemi-L_desc-surface_curv",
2581-
"pipeline-fs_hemi-R_desc-surface_curv",
2584+
"pipeline-fs_hemi-R_desc-surface_curv",
25822585
"pipeline-fs_hemi-L_desc-surfaceMesh_pial",
25832586
"pipeline-fs_hemi-R_desc-surfaceMesh_pial",
25842587
"pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm",
25852588
"pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm",
25862589
"pipeline-fs_hemi-L_desc-surfaceMesh_sphere",
25872590
"pipeline-fs_hemi-R_desc-surfaceMesh_sphere",
2588-
"pipeline-fs_hemi-L_desc-surfaceMap_sulc",
2591+
"pipeline-fs_hemi-L_desc-surfaceMap_sulc",
25892592
"pipeline-fs_hemi-R_desc-surfaceMap_sulc",
25902593
"pipeline-fs_hemi-L_desc-surfaceMap_thickness",
25912594
"pipeline-fs_hemi-R_desc-surfaceMap_thickness",
@@ -2691,7 +2694,9 @@ def freesurfer_abcd_preproc(wf, cfg, strat_pool, pipe_num, opt=None):
26912694
'desc-restore_T1w': (fast_correction, 'outputspec.anat_restore'),
26922695
'desc-restore-brain_T1w': (fast_correction,
26932696
'outputspec.anat_brain_restore'),
2694-
'pipeline-fs_desc-fast_biasfield': (fast_correction, 'outputspec.bias_field')}
2697+
'pipeline-fs_desc-fast_biasfield': (fast_correction, 'outputspec.bias_field'),
2698+
'desc-ABCDpreproc_T1w': (normalize_head, 'out_file')
2699+
}
26952700
return (wf, outputs)
26962701

26972702
# we're grabbing the postproc outputs and appending them to
@@ -2706,7 +2711,8 @@ def freesurfer_reconall(wf, cfg, strat_pool, pipe_num, opt=None):
27062711
"switch": ["run_reconall"],
27072712
"option_key": "None",
27082713
"option_val": "None",
2709-
"inputs": ["desc-preproc_T1w"],
2714+
"inputs": [["desc-ABCDpreproc_T1w",
2715+
"desc-preproc_T1w"]],
27102716
"outputs": ["freesurfer-subject-dir",
27112717
"pipeline-fs_raw-average",
27122718
"pipeline-fs_subcortical-seg",
@@ -2739,7 +2745,7 @@ def freesurfer_reconall(wf, cfg, strat_pool, pipe_num, opt=None):
27392745
reconall.inputs.args = cfg.surface_analysis['freesurfer'][
27402746
'reconall_args']
27412747

2742-
node, out = strat_pool.get_data("desc-preproc_T1w")
2748+
node, out = strat_pool.get_data(["desc-ABCDpreproc_T1w","desc-preproc_T1w"])
27432749
wf.connect(node, out, reconall, 'T1_files')
27442750

27452751
wf, hemisphere_outputs = freesurfer_hemispheres(wf, reconall, pipe_num)
@@ -2974,9 +2980,9 @@ def fast_bias_field_correction(config=None, wf_name='fast_bias_field_correction'
29742980
def correct_restore_brain_intensity_abcd(wf, cfg, strat_pool, pipe_num, opt=None):
29752981
'''
29762982
{"name": "correct_restore_brain_intensity_abcd",
2977-
"config": ["anatomical_preproc", "brain_extraction"],
2978-
"switch": "None",
2979-
"option_key": "using",
2983+
"config": "None",
2984+
"switch": ["anatomical_preproc", "brain_extraction", "run"],
2985+
"option_key": ["anatomical_preproc", "brain_extraction", "using"],
29802986
"option_val": "FreeSurfer-ABCD",
29812987
"inputs": [("desc-preproc_T1w",
29822988
"desc-n4_T1w",

CPAC/anat_preproc/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,15 @@ def fslmaths_command(in_file, number, out_file_suffix):
420420

421421
return out_file
422422

423+
def normalize_wmparc(source_file, target_file, xfm, out_file):
424+
from CPAC.utils.monitoring.custom_logging import log_subprocess
425+
import os
426+
427+
cmd = ['mri_vol2vol', '--mov', source_file, \
428+
'--targ', target_file, '--o', out_file, '--lta', xfm]
429+
log_subprocess(cmd)
430+
output = os.path.join(os.getcwd(), out_file)
431+
return output
423432

424433
"""This module provides interfaces for workbench -volume-remove-islands commands"""
425434
from nipype.interfaces.base import TraitedSpec, File, traits, CommandLineInputSpec

CPAC/pipeline/cpac_pipeline.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,8 +864,10 @@ def build_anat_preproc_stack(rpool, cfg, pipeline_blocks=None):
864864
anatomical_init
865865
]
866866
pipeline_blocks += anat_init_blocks
867+
868+
using_brain_extraction = cfg.anatomical_preproc['brain_extraction']['using']
867869

868-
if not rpool.check_rpool('freesurfer-subject-dir'):
870+
if not rpool.check_rpool('freesurfer-subject-dir') and 'FreeSurfer-ABCD' not in using_brain_extraction:
869871
pipeline_blocks += [freesurfer_reconall] # includes postproc
870872

871873
if not rpool.check_rpool('desc-preproc_T1w'):
@@ -913,6 +915,9 @@ def build_anat_preproc_stack(rpool, cfg, pipeline_blocks=None):
913915

914916
pipeline_blocks += [freesurfer_abcd_preproc]
915917

918+
if not rpool.check_rpool('freesurfer-subject-dir') and 'FreeSurfer-ABCD' in using_brain_extraction:
919+
pipeline_blocks += [freesurfer_reconall] # includes postproc
920+
916921
# Anatomical T1 brain masking
917922

918923
anat_brain_mask_blocks = [

CPAC/pipeline/engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@ def ingress_raw_anat_data(wf, rpool, cfg, data_paths, unique_id, part_id,
17231723
'pipeline-fs_hemi-R_desc-surfaceMap_volume': 'surf/rh.volume',
17241724
'pipeline-fs_hemi-L_desc-surfaceMesh_white': 'surf/lh.white',
17251725
'pipeline-fs_hemi-R_desc-surfaceMesh_white': 'surf/rh.white',
1726-
'pipeline-fs_xfm': 'mri/transforms/talairach.xfm'
1726+
'pipeline-fs_xfm': 'mri/transforms/talairach.lta'
17271727
}
17281728

17291729
for key, outfile in recon_outs.items():

CPAC/pipeline/schema.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,9 @@ def sanitize(filename):
711711
},
712712
},
713713
'surface_analysis': {
714+
'abcd_prefreesurfer_prep':{
715+
'run': bool1_1,
716+
},
714717
'freesurfer': {
715718
'run_reconall': bool1_1,
716719
'reconall_args': Maybe(str),

CPAC/registration/registration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4547,7 +4547,7 @@ def warp_bold_mask_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None):
45474547
"option_key": ["registration_workflows", "functional_registration",
45484548
"func_registration_to_template", "apply_transform",
45494549
"using"],
4550-
"option_val": ["default", "abcd", "dcan_nhp"],
4550+
"option_val": ["default"],
45514551
"inputs": [("space-bold_desc-brain_mask",
45524552
"from-bold_to-template_mode-image_xfm"),
45534553
"T1w-brain-template-funcreg"],

CPAC/resources/configs/pipeline_config_abcd-options.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ pipeline_setup:
2828
# -------------
2929
surface_analysis:
3030

31+
# Run freesurfer_abcd_preproc to obtain preprocessed T1w for reconall
32+
abcd_prefreesurfer_prep:
33+
run: On
34+
3135
# Will run Freesurfer for surface-based analysis. Will output traditional Freesurfer derivatives.
3236
# If you wish to employ Freesurfer outputs for brain masking or tissue segmentation in the voxel-based pipeline,
3337
# select those 'Freesurfer-' labeled options further below in anatomical_preproc.

0 commit comments

Comments
 (0)