Skip to content

Commit 7673b0d

Browse files
authored
Merge pull request #113 from CoBrALab/updates
Updates
2 parents 5bb9800 + d0b81e9 commit 7673b0d

File tree

12 files changed

+157
-161
lines changed

12 files changed

+157
-161
lines changed

rabies/conf_reg_pkg/confound_regression.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
from nipype import Function
55
from .utils import regress, data_diagnosis, select_timeseries, exec_ICA_AROMA
66

7-
8-
def init_confound_regression_wf(lowpass=None, highpass=None, smoothing_filter=0.3, run_aroma=False, aroma_dim=0, conf_list=[],
9-
TR='1.0s', apply_scrubbing=False, scrubbing_threshold=0.1, timeseries_interval='all', diagnosis_output=False, name="confound_regression_wf"):
7+
def init_confound_regression_wf(cr_opts, name="confound_regression_wf"):
108

119
workflow = pe.Workflow(name=name)
1210
inputnode = pe.Node(niu.IdentityInterface(fields=[
@@ -19,20 +17,20 @@ def init_confound_regression_wf(lowpass=None, highpass=None, smoothing_filter=0.
1917
output_names=['cleaned_path', 'bold_file', 'VE_file'],
2018
function=regress),
2119
name='regress', mem_gb=1)
22-
regress_node.inputs.conf_list = conf_list
23-
regress_node.inputs.TR = float(TR.split('s')[0])
24-
regress_node.inputs.lowpass = lowpass
25-
regress_node.inputs.highpass = highpass
26-
regress_node.inputs.smoothing_filter = smoothing_filter
27-
regress_node.inputs.apply_scrubbing = apply_scrubbing
28-
regress_node.inputs.scrubbing_threshold = scrubbing_threshold
29-
regress_node.inputs.timeseries_interval = timeseries_interval
20+
regress_node.inputs.conf_list = cr_opts.conf_list
21+
regress_node.inputs.TR = float(cr_opts.TR.split('s')[0])
22+
regress_node.inputs.lowpass = cr_opts.lowpass
23+
regress_node.inputs.highpass = cr_opts.highpass
24+
regress_node.inputs.smoothing_filter = cr_opts.smoothing_filter
25+
regress_node.inputs.apply_scrubbing = cr_opts.apply_scrubbing
26+
regress_node.inputs.scrubbing_threshold = cr_opts.scrubbing_threshold
27+
regress_node.inputs.timeseries_interval = cr_opts.timeseries_interval
3028

3129
select_timeseries_node = pe.Node(Function(input_names=['bold_file', 'timeseries_interval'],
3230
output_names=['bold_file'],
3331
function=select_timeseries),
3432
name='select_timeseries', mem_gb=1)
35-
select_timeseries_node.inputs.timeseries_interval = timeseries_interval
33+
select_timeseries_node.inputs.timeseries_interval = cr_opts.timeseries_interval
3634

3735
workflow.connect([
3836
(inputnode, select_timeseries_node, [
@@ -49,13 +47,13 @@ def init_confound_regression_wf(lowpass=None, highpass=None, smoothing_filter=0.
4947
]),
5048
])
5149

52-
if run_aroma:
50+
if cr_opts.run_aroma:
5351
ica_aroma_node = pe.Node(Function(input_names=['inFile', 'mc_file', 'brain_mask', 'csf_mask', 'tr', 'aroma_dim'],
5452
output_names=['cleaned_file', 'aroma_out'],
5553
function=exec_ICA_AROMA),
5654
name='ica_aroma', mem_gb=1)
57-
ica_aroma_node.inputs.tr = float(TR.split('s')[0])
58-
ica_aroma_node.inputs.aroma_dim = aroma_dim
55+
ica_aroma_node.inputs.tr = float(cr_opts.TR.split('s')[0])
56+
ica_aroma_node.inputs.aroma_dim = cr_opts.aroma_dim
5957

6058
workflow.connect([
6159
(inputnode, ica_aroma_node, [
@@ -80,7 +78,7 @@ def init_confound_regression_wf(lowpass=None, highpass=None, smoothing_filter=0.
8078
]),
8179
])
8280

83-
if diagnosis_output:
81+
if cr_opts.diagnosis_output:
8482
data_diagnosis_node = pe.Node(data_diagnosis(),
8583
name='data_diagnosis', mem_gb=1)
8684

rabies/main_wf.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,7 @@ def init_main_wf(data_dir_path, output_folder, opts, cr_opts=None, analysis_opts
343343
name='anat_convert_to_RAS')
344344

345345
# setting anat preprocessing nodes
346-
anat_preproc_wf = init_anat_preproc_wf(reg_script=opts.anat_reg_script,
347-
disable_anat_preproc=opts.disable_anat_preproc, rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory)
346+
anat_preproc_wf = init_anat_preproc_wf(opts=opts)
348347
anat_preproc_wf.inputs.inputnode.template_mask = str(opts.brain_mask)
349348

350349
transform_masks = pe.Node(Function(input_names=['brain_mask_in', 'WM_mask_in', 'CSF_mask_in', 'vascular_mask_in', 'atlas_labels_in', 'reference_image', 'anat_to_template_inverse_warp', 'anat_to_template_affine', 'template_to_common_affine', 'template_to_common_inverse_warp'],
@@ -609,9 +608,7 @@ def integrate_confound_regression(workflow, outputnode, cr_opts, bold_only):
609608
cr_output = os.path.abspath(str(cr_opts.output_dir))
610609

611610
from rabies.conf_reg_pkg.confound_regression import init_confound_regression_wf
612-
confound_regression_wf = init_confound_regression_wf(lowpass=cr_opts.lowpass, highpass=cr_opts.highpass,
613-
smoothing_filter=cr_opts.smoothing_filter, run_aroma=cr_opts.run_aroma, aroma_dim=cr_opts.aroma_dim, conf_list=cr_opts.conf_list, TR=cr_opts.TR, apply_scrubbing=cr_opts.apply_scrubbing,
614-
scrubbing_threshold=cr_opts.scrubbing_threshold, timeseries_interval=cr_opts.timeseries_interval, diagnosis_output=cr_opts.diagnosis_output, name=cr_opts.wf_name)
611+
confound_regression_wf = init_confound_regression_wf(cr_opts=cr_opts, name=cr_opts.wf_name)
615612

616613
workflow.connect([
617614
(outputnode, confound_regression_wf, [

rabies/preprocess_pkg/anat_preproc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
)
77

88

9-
def init_anat_preproc_wf(reg_script, disable_anat_preproc=False, rabies_data_type=8, rabies_mem_scale=1.0, name='anat_preproc_wf'):
9+
def init_anat_preproc_wf(opts, name='anat_preproc_wf'):
1010
'''
1111
This workflow executes anatomical preprocessing based on anat_preproc.sh,
1212
which includes initial N4 bias field correction and Adaptive
@@ -21,8 +21,8 @@ def init_anat_preproc_wf(reg_script, disable_anat_preproc=False, rabies_data_typ
2121
outputnode = pe.Node(niu.IdentityInterface(
2222
fields=['anat_preproc','init_denoise', 'denoise_mask']), name='outputnode')
2323

24-
anat_preproc = pe.Node(AnatPreproc(reg_script=reg_script, disable_anat_preproc=disable_anat_preproc, rabies_data_type=rabies_data_type),
25-
name='Anat_Preproc', mem_gb=0.6*rabies_mem_scale)
24+
anat_preproc = pe.Node(AnatPreproc(reg_script=opts.anat_reg_script, disable_anat_preproc=opts.disable_anat_preproc, rabies_data_type=opts.data_type),
25+
name='Anat_Preproc', mem_gb=0.6*opts.scale_min_memory)
2626

2727
workflow.connect([
2828
(inputnode, anat_preproc, [

rabies/preprocess_pkg/bias_correction.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import os
21
from nipype.pipeline import engine as pe
32
from nipype.interfaces import utility as niu
43
from nipype.interfaces.base import (
@@ -7,7 +6,7 @@
76
)
87

98

10-
def bias_correction_wf(bias_cor_method='otsu_reg', rabies_data_type=8, rabies_mem_scale=1.0, name='bias_correction_wf'):
9+
def bias_correction_wf(opts, name='bias_correction_wf'):
1110

1211
workflow = pe.Workflow(name=name)
1312

@@ -19,17 +18,16 @@ def bias_correction_wf(bias_cor_method='otsu_reg', rabies_data_type=8, rabies_me
1918
fields=['corrected_EPI', 'denoise_mask', 'warped_EPI', 'init_denoise']),
2019
name='outputnode')
2120

22-
if bias_cor_method=='otsu_reg':
23-
bias_correction = pe.Node(OtsuEPIBiasCorrection(rabies_data_type=rabies_data_type),
24-
name='bias_correction', mem_gb=0.3*rabies_mem_scale)
21+
if opts.bias_cor_method=='otsu_reg':
22+
bias_correction = pe.Node(OtsuEPIBiasCorrection(rabies_data_type=opts.data_type),
23+
name='bias_correction', mem_gb=0.3*opts.scale_min_memory)
2524

26-
elif bias_cor_method=='thresh_reg':
27-
bias_correction = pe.Node(EPIBiasCorrection(rabies_data_type=rabies_data_type),
28-
name='bias_correction', mem_gb=0.3*rabies_mem_scale)
25+
elif opts.bias_cor_method=='thresh_reg':
26+
bias_correction = pe.Node(EPIBiasCorrection(rabies_data_type=opts.data_type),
27+
name='bias_correction', mem_gb=0.3*opts.scale_min_memory)
2928
else:
3029
raise ValueError("Wrong --bias_cor_method.")
3130

32-
3331
workflow.connect([
3432
(inputnode, bias_correction, [('ref_EPI', 'input_ref_EPI'),
3533
('anat', 'anat'),

rabies/preprocess_pkg/bold_main_wf.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from nipype.interfaces.utility import Function
1212

1313

14-
def init_bold_main_wf(opts, bias_cor_only=False, aCompCor_method='50%', name='bold_main_wf'):
14+
def init_bold_main_wf(opts, bias_cor_only=False, name='bold_main_wf'):
1515
"""
1616
This workflow controls the functional preprocessing stages of the pipeline when both
1717
functional and anatomical images are provided.
@@ -136,10 +136,8 @@ def init_bold_main_wf(opts, bias_cor_only=False, aCompCor_method='50%', name='bo
136136
name="transitionnode")
137137

138138
if bias_cor_only or (not opts.bold_only):
139-
bold_reference_wf = init_bold_reference_wf(
140-
detect_dummy=opts.detect_dummy, rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc)
141-
bias_cor_wf = bias_correction_wf(
142-
bias_cor_method=opts.bias_cor_method, rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory)
139+
bold_reference_wf = init_bold_reference_wf(opts=opts)
140+
bias_cor_wf = bias_correction_wf(opts=opts)
143141

144142
if opts.apply_despiking:
145143
despike = pe.Node(
@@ -192,12 +190,10 @@ def init_bold_main_wf(opts, bias_cor_only=False, aCompCor_method='50%', name='bo
192190
if opts.bold_only and bias_cor_only:
193191
return workflow
194192

195-
bold_stc_wf = init_bold_stc_wf(
196-
no_STC=opts.no_STC, tr=opts.TR, tpattern=opts.tpattern, rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc)
193+
bold_stc_wf = init_bold_stc_wf(opts=opts)
197194

198195
# HMC on the BOLD
199-
bold_hmc_wf = init_bold_hmc_wf(slice_mc=opts.apply_slice_mc, rabies_data_type=opts.data_type,
200-
rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc, local_threads=opts.local_threads)
196+
bold_hmc_wf = init_bold_hmc_wf(opts=opts)
201197

202198
if not opts.bold_only:
203199
def commonspace_transforms(template_to_common_warp, template_to_common_affine, anat_to_template_warp, anat_to_template_affine, warp_bold2anat, affine_bold2anat):
@@ -218,11 +214,9 @@ def commonspace_transforms(template_to_common_warp, template_to_common_affine, a
218214
function=commonspace_transforms),
219215
name='commonspace_transforms_prep')
220216

221-
bold_commonspace_trans_wf = init_bold_commonspace_trans_wf(resampling_dim=opts.commonspace_resampling, brain_mask=str(opts.brain_mask), WM_mask=str(opts.WM_mask), CSF_mask=str(opts.CSF_mask), vascular_mask=str(opts.vascular_mask), atlas_labels=str(opts.labels),
222-
slice_mc=opts.apply_slice_mc, rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc)
217+
bold_commonspace_trans_wf = init_bold_commonspace_trans_wf(opts=opts)
223218

224-
bold_confs_wf = init_bold_confs_wf(
225-
aCompCor_method=aCompCor_method, name="bold_confs_wf", rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc)
219+
bold_confs_wf = init_bold_confs_wf(opts=opts, name="bold_confs_wf")
226220

227221
# MAIN WORKFLOW STRUCTURE #######################################################
228222
workflow.connect([
@@ -287,8 +281,7 @@ def commonspace_transforms(template_to_common_warp, template_to_common_affine, a
287281
])
288282

289283
if not opts.bold_only:
290-
bold_reg_wf = init_bold_reg_wf(coreg_script=opts.coreg_script, rabies_data_type=opts.data_type,
291-
rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc)
284+
bold_reg_wf = init_bold_reg_wf(opts=opts)
292285

293286
def SyN_coreg_transforms_prep(warp_bold2anat, affine_bold2anat):
294287
# transforms_list,inverses
@@ -300,8 +293,7 @@ def SyN_coreg_transforms_prep(warp_bold2anat, affine_bold2anat):
300293
name='transforms_prep')
301294

302295
# Apply transforms in 1 shot
303-
bold_bold_trans_wf = init_bold_preproc_trans_wf(
304-
resampling_dim=opts.nativespace_resampling, slice_mc=opts.apply_slice_mc, rabies_data_type=opts.data_type, rabies_mem_scale=opts.scale_min_memory, min_proc=opts.min_proc)
296+
bold_bold_trans_wf = init_bold_preproc_trans_wf(opts=opts)
305297

306298
workflow.connect([
307299
(inputnode, bold_reg_wf, [

rabies/preprocess_pkg/confounds.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
)
88

99

10-
def init_bold_confs_wf(aCompCor_method='50%', rabies_data_type=8, rabies_mem_scale=1.0, min_proc=1, name="bold_confs_wf"):
10+
def init_bold_confs_wf(opts, aCompCor_method='50%', name="bold_confs_wf"):
1111

1212
inputnode = pe.Node(niu.IdentityInterface(
1313
fields=['bold', 'ref_bold', 'movpar_file', 't1_mask', 't1_labels', 'WM_mask', 'CSF_mask', 'vascular_mask', 'name_source']),
@@ -31,10 +31,10 @@ def init_bold_confs_wf(aCompCor_method='50%', rabies_data_type=8, rabies_mem_sca
3131
propagate_labels = pe.Node(MaskEPI(), name='prop_labels_EPI')
3232
propagate_labels.inputs.name_spec = 'anat_labels'
3333

34-
estimate_confounds = pe.Node(EstimateConfounds(aCompCor_method=aCompCor_method, rabies_data_type=rabies_data_type),
35-
name='estimate_confounds', mem_gb=2.3*rabies_mem_scale)
34+
estimate_confounds = pe.Node(EstimateConfounds(aCompCor_method=aCompCor_method, rabies_data_type=opts.data_type),
35+
name='estimate_confounds', mem_gb=2.3*opts.scale_min_memory)
3636
estimate_confounds.plugin_args = {
37-
'qsub_args': '-pe smp %s' % (str(2*min_proc)), 'overwrite': True}
37+
'qsub_args': '-pe smp %s' % (str(2*opts.min_proc)), 'overwrite': True}
3838

3939
workflow = pe.Workflow(name=name)
4040
workflow.connect([

rabies/preprocess_pkg/hmc.py

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
traits, TraitedSpec, BaseInterfaceInputSpec,
55
File, BaseInterface
66
)
7-
from .utils import SliceMotionCorrection
7+
from .utils import SliceMotionCorrection, antsMotionCorr
88

9-
10-
def init_bold_hmc_wf(slice_mc=False, rabies_data_type=8, rabies_mem_scale=1.0, min_proc=1, local_threads=1, name='bold_hmc_wf'):
9+
def init_bold_hmc_wf(opts, name='bold_hmc_wf'):
1110
"""
1211
This workflow estimates the motion parameters to perform HMC over the BOLD image.
1312
@@ -28,7 +27,6 @@ def init_bold_hmc_wf(slice_mc=False, rabies_data_type=8, rabies_mem_scale=1.0, m
2827
movpar_file
2928
CSV file with antsMotionCorr motion parameters
3029
"""
31-
import os
3230

3331
workflow = pe.Workflow(name=name)
3432
inputnode = pe.Node(niu.IdentityInterface(fields=['bold_file', 'ref_image']),
@@ -39,23 +37,24 @@ def init_bold_hmc_wf(slice_mc=False, rabies_data_type=8, rabies_mem_scale=1.0, m
3937
name='outputnode')
4038

4139
# Head motion correction (hmc)
42-
motion_estimation = pe.Node(EstimateMotion(rabies_data_type=rabies_data_type), name='ants_MC', mem_gb=1.1*rabies_mem_scale)
40+
motion_estimation = pe.Node(antsMotionCorr(prebuilt_option=opts.HMC_option,transform_type=opts.HMC_transform, second=False, rabies_data_type=opts.data_type),
41+
name='ants_MC', mem_gb=1.1*opts.scale_min_memory)
4342
motion_estimation.plugin_args = {
44-
'qsub_args': '-pe smp %s' % (str(3*min_proc)), 'overwrite': True}
43+
'qsub_args': '-pe smp %s' % (str(3*opts.min_proc)), 'overwrite': True}
4544

4645
workflow.connect([
4746
(inputnode, motion_estimation, [('ref_image', 'ref_file'),
4847
('bold_file', 'in_file')]),
4948
(motion_estimation, outputnode, [
50-
('motcorr_params', 'motcorr_params')]),
49+
('csv_params', 'motcorr_params')]),
5150
])
5251

53-
if slice_mc:
54-
slice_mc_n_procs = int(local_threads/4)+1
52+
if opts.apply_slice_mc:
53+
slice_mc_n_procs = int(opts.local_threads/4)+1
5554
slice_mc_node = pe.Node(SliceMotionCorrection(n_procs=slice_mc_n_procs),
5655
name='slice_mc', mem_gb=1*slice_mc_n_procs, n_procs=slice_mc_n_procs)
5756
slice_mc_node.plugin_args = {
58-
'qsub_args': '-pe smp %s' % (str(3*min_proc)), 'overwrite': True}
57+
'qsub_args': '-pe smp %s' % (str(3*opts.min_proc)), 'overwrite': True}
5958

6059
# conducting a volumetric realignment before slice-specific mc to correct for larger head translations and rotations
6160
workflow.connect([
@@ -68,43 +67,3 @@ def init_bold_hmc_wf(slice_mc=False, rabies_data_type=8, rabies_mem_scale=1.0, m
6867
])
6968

7069
return workflow
71-
72-
73-
class EstimateMotionInputSpec(BaseInterfaceInputSpec):
74-
in_file = File(exists=True, mandatory=True, desc="4D EPI file")
75-
ref_file = File(exists=True, mandatory=True,
76-
desc="Reference image to which timeseries are realigned for motion estimation")
77-
rabies_data_type = traits.Int(mandatory=True,
78-
desc="Integer specifying SimpleITK data type.")
79-
80-
81-
class EstimateMotionOutputSpec(TraitedSpec):
82-
motcorr_params = File(
83-
exists=True, desc="Motion estimation derived from antsMotionCorr")
84-
mc_corrected_bold = File(exists=True, desc="motion corrected time series")
85-
86-
87-
class EstimateMotion(BaseInterface):
88-
"""
89-
Runs ants motion correction interface and returns the motion estimation
90-
"""
91-
92-
input_spec = EstimateMotionInputSpec
93-
output_spec = EstimateMotionOutputSpec
94-
95-
def _run_interface(self, runtime):
96-
import os
97-
from .utils import antsMotionCorr
98-
res = antsMotionCorr(in_file=self.inputs.in_file,
99-
ref_file=self.inputs.ref_file, second=False, rabies_data_type=self.inputs.rabies_data_type).run()
100-
csv_params = os.path.abspath(res.outputs.csv_params)
101-
102-
setattr(self, 'csv_params', csv_params)
103-
setattr(self, 'mc_corrected_bold', os.path.abspath(
104-
res.outputs.mc_corrected_bold))
105-
106-
return runtime
107-
108-
def _list_outputs(self):
109-
return {'mc_corrected_bold': getattr(self, 'mc_corrected_bold'),
110-
'motcorr_params': getattr(self, 'csv_params')}

rabies/preprocess_pkg/registration.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from nipype import Function
44

55

6-
def init_bold_reg_wf(coreg_script='SyN', rabies_data_type=8, rabies_mem_scale=1.0, min_proc=1, name='bold_reg_wf'):
6+
def init_bold_reg_wf(opts, name='bold_reg_wf'):
77
"""
88
This workflow registers the reference BOLD image to anat-space, using
99
antsRegistration, either applying Affine registration only, or the
@@ -55,11 +55,11 @@ def init_bold_reg_wf(coreg_script='SyN', rabies_data_type=8, rabies_mem_scale=1.
5555
"anat_mask", "rabies_data_type"],
5656
output_names=['affine_bold2anat', 'warp_bold2anat',
5757
'inverse_warp_bold2anat', 'output_warped_bold'],
58-
function=run_antsRegistration), name='EPI_Coregistration', mem_gb=3*rabies_mem_scale)
59-
run_reg.inputs.reg_method = coreg_script
60-
run_reg.inputs.rabies_data_type = rabies_data_type
58+
function=run_antsRegistration), name='EPI_Coregistration', mem_gb=3*opts.scale_min_memory)
59+
run_reg.inputs.reg_method = opts.coreg_script
60+
run_reg.inputs.rabies_data_type = opts.data_type
6161
run_reg.plugin_args = {
62-
'qsub_args': '-pe smp %s' % (str(3*min_proc)), 'overwrite': True}
62+
'qsub_args': '-pe smp %s' % (str(3*opts.min_proc)), 'overwrite': True}
6363

6464
workflow.connect([
6565
(inputnode, run_reg, [

0 commit comments

Comments
 (0)