Skip to content

Commit 556034d

Browse files
authored
Merge branch 'develop' into enh/desc-preproc_names
2 parents 546b61e + 4bb27d6 commit 556034d

File tree

9 files changed

+176
-18
lines changed

9 files changed

+176
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Added the ability to ingress TotalReadoutTime from epi field map meta-data from the JSON sidecars.
2222
- Added the ability to use TotalReadoutTime of epi field maps in the calculation of FSL topup distortion correction.
2323
- Difference method (``-``) for ``CPAC.utils.configuration.Configuration`` instances
24+
- Calculate reho and alff when timeseries in template space
2425

2526
### Changed
2627
- Added a level of depth to `working` directories to match `log` and `output` directory structure

CPAC/alff/alff.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,38 @@ def alff_falff(wf, cfg, strat_pool, pipe_num, opt=None):
273273
}
274274

275275
return (wf, outputs)
276+
277+
def alff_falff_space_template(wf, cfg, strat_pool, pipe_num, opt=None):
278+
'''
279+
{"name": "alff_falff_space_template",
280+
"config": ["amplitude_low_frequency_fluctuation"],
281+
"switch": ["run"],
282+
"option_key": "None",
283+
"option_val": "None",
284+
"inputs": [["space-template_desc-denoisedNofilt_bold"],
285+
"space-template_desc-bold_mask"],
286+
"outputs": ["space-template_alff",
287+
"space-template_falff"]}
288+
'''
289+
290+
alff = create_alff(f'alff_falff_{pipe_num}')
291+
292+
alff.inputs.hp_input.hp = \
293+
cfg.amplitude_low_frequency_fluctuation['highpass_cutoff']
294+
alff.inputs.lp_input.lp = \
295+
cfg.amplitude_low_frequency_fluctuation['lowpass_cutoff']
296+
alff.get_node('hp_input').iterables = ('hp', alff.inputs.hp_input.hp)
297+
alff.get_node('lp_input').iterables = ('lp', alff.inputs.lp_input.lp)
298+
299+
node, out = strat_pool.get_data(["space-template_desc-denoisedNofilt_bold"])
300+
wf.connect(node, out, alff, 'inputspec.rest_res')
301+
302+
node, out = strat_pool.get_data("space-template_desc-bold_mask")
303+
wf.connect(node, out, alff, 'inputspec.rest_mask')
304+
305+
outputs = {
306+
'space-template_alff': (alff, 'outputspec.alff_img'),
307+
'space-template_falff': (alff, 'outputspec.falff_img')
308+
}
309+
310+
return (wf, outputs)

CPAC/nuisance/nuisance.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,7 +2534,6 @@ def nuisance_regression(wf, cfg, strat_pool, pipe_num, opt, space):
25342534
outputs = {
25352535
desc_keys[0]: (nuis, 'outputspec.residual_file_path'),
25362536
desc_keys[1]: (nuis, 'outputspec.residual_file_path'),
2537-
desc_keys[2]: (nuis, 'outputspec.residual_file_path')
25382537
}
25392538

25402539
return (wf, outputs)
@@ -2589,13 +2588,10 @@ def nuisance_regression_template(wf, cfg, strat_pool, pipe_num, opt=None):
25892588
"dvars"),
25902589
"TR"],
25912590
"outputs": {"space-template_desc-preproc_bold": {
2592-
"Description": "Preprocessed BOLD image that was nuisance-"
2591+
"Description": "Preprocessed BOLD image that was nusiance-"
25932592
"regressed in template space"},
25942593
"space-template_desc-cleaned_bold": {
2595-
"Description": "Preprocessed BOLD image that was nuisance-"
2596-
"regressed in template space"},
2597-
"space-template_desc-denoisedNofilt_bold": {
2598-
"Description": "Preprocessed BOLD image that was nuisance-"
2594+
"Description": "Preprocessed BOLD image that was nusiance-"
25992595
"regressed in template space"},
26002596
"regressors": {
26012597
"Description": "Regressors that were applied in template space"}}}

CPAC/pipeline/cpac_pipeline.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
warp_bold_mean_to_T1template,
103103
warp_bold_mask_to_T1template,
104104
warp_deriv_mask_to_T1template,
105+
warp_denoiseNofilt_to_T1template,
105106
warp_timeseries_to_EPItemplate,
106107
warp_bold_mean_to_EPItemplate,
107108
warp_bold_mask_to_EPItemplate,
@@ -183,8 +184,8 @@
183184
multiple_regression
184185
)
185186

186-
from CPAC.alff.alff import alff_falff
187-
from CPAC.reho.reho import reho
187+
from CPAC.alff.alff import alff_falff, alff_falff_space_template
188+
from CPAC.reho.reho import reho, reho_space_template
188189

189190
from CPAC.vmhc.vmhc import (
190191
smooth_func_vmhc,
@@ -1281,6 +1282,10 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None,
12811282
if not rpool.check_rpool('space-template_desc-bold_mask'):
12821283
pipeline_blocks += [warp_bold_mask_to_T1template,
12831284
warp_deriv_mask_to_T1template]
1285+
1286+
target_space_alff = cfg.amplitude_low_frequency_fluctuation['target_space']
1287+
if 'Template' in target_space_alff and not rpool.check_rpool('space-template_desc-denoisedNofilt_bold'):
1288+
pipeline_blocks += [warp_denoiseNofilt_to_T1template]
12841289

12851290
template = cfg.registration_workflows['functional_registration']['func_registration_to_template']['target_template']['using']
12861291

@@ -1323,6 +1328,7 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None,
13231328
tse_atlases, sca_atlases = gather_extraction_maps(cfg)
13241329
cfg.timeseries_extraction['tse_atlases'] = tse_atlases
13251330
cfg.seed_based_correlation_analysis['sca_atlases'] = sca_atlases
1331+
target_space_reho = cfg.regional_homogeneity['target_space']
13261332

13271333
if not rpool.check_rpool('desc-Mean_timeseries') and \
13281334
'Avg' in tse_atlases:
@@ -1348,11 +1354,21 @@ def build_workflow(subject_id, sub_dict, cfg, pipeline_name=None,
13481354
'MultReg' in sca_atlases:
13491355
pipeline_blocks += [multiple_regression]
13501356

1351-
if not rpool.check_rpool('alff'):
1352-
pipeline_blocks += [alff_falff]
1353-
1354-
if not rpool.check_rpool('reho'):
1355-
pipeline_blocks += [reho]
1357+
if 'Native' in target_space_alff:
1358+
if not rpool.check_rpool('alff'):
1359+
pipeline_blocks += [alff_falff]
1360+
1361+
if 'Template' in target_space_alff:
1362+
if not rpool.check_rpool('space-template_alff'):
1363+
pipeline_blocks += [alff_falff_space_template]
1364+
1365+
if 'Native' in target_space_reho:
1366+
if not rpool.check_rpool('reho'):
1367+
pipeline_blocks += [reho]
1368+
1369+
if 'Template' in target_space_reho:
1370+
if not rpool.check_rpool('space-template_reho'):
1371+
pipeline_blocks += [reho_space_template]
13561372

13571373
if not rpool.check_rpool('vmhc'):
13581374
pipeline_blocks += [smooth_func_vmhc,

CPAC/pipeline/engine.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ def __init__(self, rpool=None, name=None, cfg=None, pipe_list=None):
8888

8989
self.run_smoothing = 'smoothed' in cfg.post_processing[
9090
'spatial_smoothing']['output']
91+
self.smoothing_bool = cfg.post_processing['spatial_smoothing']['run']
9192
self.run_zscoring = 'z-scored' in cfg.post_processing[
9293
'z-scoring']['output']
94+
self.zscoring_bool = cfg.post_processing['z-scoring']['run']
9395
self.fwhm = cfg.post_processing['spatial_smoothing']['fwhm']
9496
self.smooth_opts = cfg.post_processing['spatial_smoothing'][
9597
'smoothing_method']
@@ -697,7 +699,7 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x,
697699
mask_idx = self.generate_prov_string(mask_prov)[1]
698700
break
699701

700-
if self.run_smoothing:
702+
if self.smoothing_bool:
701703
if label in Outputs.to_smooth:
702704
for smooth_opt in self.smooth_opts:
703705

@@ -736,7 +738,7 @@ def post_process(self, wf, label, connection, json_info, pipe_idx, pipe_x,
736738
pipe_idx, f'spatial_smoothing_{smooth_opt}',
737739
fork=True)
738740

739-
if self.run_zscoring:
741+
if self.zscoring_bool:
740742
for label_con_tpl in post_labels:
741743
label = label_con_tpl[0]
742744
connection = (label_con_tpl[1], label_con_tpl[2])

CPAC/pipeline/schema.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@
9696
str, {'components': int, 'method': str}
9797
),
9898
},
99-
}
99+
},
100+
'target_space': ['Native', 'Template']
100101
}
101102
mutex = { # mutually exclusive booleans
102103
'FSL-BET': {
@@ -823,6 +824,7 @@ def sanitize(filename):
823824
},
824825
'amplitude_low_frequency_fluctuation': {
825826
'run': bool,
827+
'target_space': [In(valid_options['target_space'])],
826828
'highpass_cutoff': [float],
827829
'lowpass_cutoff': [float],
828830
},
@@ -839,15 +841,18 @@ def sanitize(filename):
839841
},
840842
'regional_homogeneity': {
841843
'run': bool,
844+
'target_space': [In(valid_options['target_space'])],
842845
'cluster_size': In({7, 19, 27}),
843846
},
844847
'post_processing': {
845848
'spatial_smoothing': {
849+
'run': bool,
846850
'output': [In({'smoothed', 'nonsmoothed'})],
847851
'smoothing_method': [In({'FSL', 'AFNI'})],
848852
'fwhm': [int]
849853
},
850854
'z-scoring': {
855+
'run': bool,
851856
'output': [In({'z-scored', 'raw'})],
852857
},
853858
},

CPAC/registration/registration.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3651,10 +3651,63 @@ def warp_timeseries_to_T1template_dcan_nhp(wf, cfg, strat_pool, pipe_num, opt=No
36513651

36523652
return (wf, outputs)
36533653

3654+
def warp_denoiseNofilt_to_T1template(wf, cfg, strat_pool, pipe_num, opt=None):
3655+
'''
3656+
Node Block:
3657+
{"name": "transform_denoisedNofilt_to_T1template",
3658+
"config": ["amplitude_low_frequency_fluctuation"],
3659+
"switch": ["run"],
3660+
"option_key": ["target_space"],
3661+
"option_val": "Template",
3662+
"inputs": [(["desc-denoisedNofilt_bold"],
3663+
"from-bold_to-template_mode-image_xfm"),
3664+
"T1w-brain-template-funcreg"],
3665+
"outputs": ["space-template_desc-denoisedNofilt_bold"]}
3666+
'''
3667+
3668+
xfm_prov = strat_pool.get_cpac_provenance(
3669+
'from-bold_to-template_mode-image_xfm')
3670+
reg_tool = check_prov_for_regtool(xfm_prov)
3671+
3672+
num_cpus = cfg.pipeline_setup['system_config'][
3673+
'max_cores_per_participant']
3674+
3675+
num_ants_cores = cfg.pipeline_setup['system_config']['num_ants_threads']
3676+
3677+
apply_xfm = apply_transform(f'warp_denoisedNofilt_to_T1template_{pipe_num}', reg_tool,
3678+
time_series=True, num_cpus=num_cpus,
3679+
num_ants_cores=num_ants_cores)
3680+
3681+
if reg_tool == 'ants':
3682+
apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[
3683+
'functional_registration']['func_registration_to_template'][
3684+
'ANTs_pipelines']['interpolation']
3685+
elif reg_tool == 'fsl':
3686+
apply_xfm.inputs.inputspec.interpolation = cfg.registration_workflows[
3687+
'functional_registration']['func_registration_to_template'][
3688+
'FNIRT_pipelines']['interpolation']
3689+
3690+
connect, resource = strat_pool.get_data(["desc-denoisedNofilt_bold"],
3691+
report_fetched=True)
3692+
node, out = connect
3693+
wf.connect(node, out, apply_xfm, 'inputspec.input_image')
3694+
3695+
node, out = strat_pool.get_data("T1w-brain-template-funcreg")
3696+
wf.connect(node, out, apply_xfm, 'inputspec.reference')
3697+
3698+
node, out = strat_pool.get_data("from-bold_to-template_mode-image_xfm")
3699+
wf.connect(node, out, apply_xfm, 'inputspec.transform')
3700+
3701+
outputs = {
3702+
f'space-template_{resource}': (apply_xfm, 'outputspec.output_image')
3703+
}
3704+
3705+
return (wf, outputs)
3706+
36543707

36553708
def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool,
36563709
pipe_num, opt=None):
3657-
"""
3710+
'''
36583711
Apply motion correction, coreg, anat-to-template transforms on
36593712
slice-time corrected functional timeseries based on fMRIPrep
36603713
pipeline
@@ -3713,7 +3766,7 @@ def single_step_resample_timeseries_to_T1template(wf, cfg, strat_pool,
37133766
"outputs": ["space-template_desc-preproc_bold",
37143767
"space-template_desc-brain_bold",
37153768
"space-template_desc-bold_mask"]}
3716-
""" # noqa: 501
3769+
''' # noqa: 501
37173770
bbr2itk = pe.Node(util.Function(input_names=['reference_file',
37183771
'source_file',
37193772
'transform_file'],

CPAC/reho/reho.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,43 @@ def reho(wf, cfg, strat_pool, pipe_num, opt=None):
147147
}
148148

149149
return (wf, outputs)
150+
151+
152+
def reho_space_template(wf, cfg, strat_pool, pipe_num, opt=None):
153+
'''
154+
{"name": "ReHo_space_template",
155+
"config": ["regional_homogeneity"],
156+
"switch": ["run"],
157+
"option_key": "None",
158+
"option_val": "None",
159+
"inputs": [["space-template_desc-cleaned_bold", "space-template_desc-brain_bold",
160+
"space-template_desc-preproc_bold", "space-template_bold"],
161+
"space-template_desc-bold_mask"],
162+
"outputs": ["space-template_reho"]}
163+
'''
164+
165+
cluster_size = cfg.regional_homogeneity['cluster_size']
166+
167+
# Check the cluster size is supported
168+
if cluster_size not in [7, 19, 27]:
169+
err_msg = 'Cluster size specified: %d, is not ' \
170+
'supported. Change to 7, 19, or 27 and try ' \
171+
'again' % cluster_size
172+
raise Exception(err_msg)
173+
174+
reho = create_reho(f'reho_{pipe_num}')
175+
reho.inputs.inputspec.cluster_size = cluster_size
176+
177+
178+
node, out = strat_pool.get_data(["space-template_desc-cleaned_bold", "space-template_desc-brain_bold",
179+
"space-template_desc-preproc_bold", "space-template_bold"])
180+
wf.connect(node, out, reho, 'inputspec.rest_res_filt')
181+
182+
node, out_file = strat_pool.get_data('space-template_desc-bold_mask')
183+
wf.connect(node, out_file, reho, 'inputspec.rest_mask')
184+
185+
outputs = {
186+
'space-template_reho': (reho, 'outputspec.raw_reho_map')
187+
}
188+
189+
return (wf, outputs)

CPAC/resources/configs/pipeline_config_default.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,8 @@ post_processing:
14721472

14731473
spatial_smoothing:
14741474

1475+
run: On
1476+
14751477
# Smooth the derivative outputs.
14761478
# Set as ['nonsmoothed'] to disable smoothing. Set as ['smoothed', 'nonsmoothed'] to get both.
14771479
#
@@ -1491,6 +1493,8 @@ post_processing:
14911493

14921494
z-scoring:
14931495

1496+
run: On
1497+
14941498
# z-score standardize the derivatives. This may be needed for group-level analysis.
14951499
# Set as ['raw'] to disable z-scoring. Set as ['z-scored', 'raw'] to get both.
14961500
#
@@ -1593,6 +1597,9 @@ amplitude_low_frequency_fluctuation:
15931597
# Calculate Amplitude of Low Frequency Fluctuations (ALFF) and fractional ALFF (f/ALFF) for all voxels.
15941598
run: On
15951599

1600+
# space: Template or Native
1601+
target_space: ['Native']
1602+
15961603
# Frequency cutoff (in Hz) for the high-pass filter used when calculating f/ALFF.
15971604
highpass_cutoff: [0.01]
15981605

@@ -1606,6 +1613,9 @@ regional_homogeneity:
16061613
# Calculate Regional Homogeneity (ReHo) for all voxels.
16071614
run: On
16081615

1616+
# space: Template or Native
1617+
target_space: ['Native']
1618+
16091619
# Number of neighboring voxels used when calculating ReHo
16101620
# 7 (Faces)
16111621
# 19 (Faces + Edges)

0 commit comments

Comments
 (0)