Skip to content

Commit 2178db0

Browse files
committed
Refac 51PW
1 parent f8742ca commit 2178db0

File tree

1 file changed

+42
-34
lines changed

1 file changed

+42
-34
lines changed

narps_open/pipelines/team_51PW.py

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@
88

99
from nipype import Node, Workflow, MapNode
1010
from nipype.interfaces.utility import IdentityInterface, Function, Split
11-
from nipype.interfaces.io import SelectFiles, DataSink
11+
from nipype.interfaces.io import SelectFiles, DataSink, DataGrabber
1212
from nipype.interfaces.fsl import (
1313
# General usage
14-
FSLCommand, ImageStats,
14+
FSLCommand, ImageStats, ImageMaths
1515
# Preprocessing
1616
SUSAN,
1717
# Analyses
1818
Level1Design, FEATModel, L2Model, FILMGLS,
1919
FLAMEO, Randomise, MultipleRegressDesign
2020
)
21-
from nipype.interfaces.fsl.utils import ExtractROI, Merge as MergeImages
21+
from nipype.interfaces.fsl.utils import ExtractROI, Merge as FSLMerge
2222
from nipype.interfaces.fsl.maths import MathsCommand, MultiImageMaths
2323
from nipype.algorithms.modelgen import SpecifyModel
2424

@@ -53,6 +53,10 @@ def get_preprocessing(self):
5353
Returns:
5454
- preprocessing : nipype.WorkFlow
5555
"""
56+
# Define workflow
57+
preprocessing = Workflow(base_dir = self.directories.working_dir, name = 'preprocessing')
58+
preprocessing.config['execution']['stop_on_first_crash'] = 'true'
59+
5660
# IdentityInterface node - allows to iterate over subjects and runs
5761
information_source = Node(IdentityInterface(
5862
fields = ['subject_id', 'run_id']),
@@ -75,10 +79,22 @@ def get_preprocessing(self):
7579
}
7680
select_files = Node(SelectFiles(templates), name = 'select_files')
7781
select_files.inputs.base_directory = self.directories.dataset_dir
78-
79-
# DataSink Node - store the wanted results in the wanted directory
80-
data_sink = Node(DataSink(), name = 'data_sink')
81-
data_sink.inputs.base_directory = self.directories.output_dir
82+
preprocessing.connect(information_source, 'subject_id', select_files, 'subject_id')
83+
preprocessing.connect(information_source, 'run_id', select_files, 'run_id')
84+
85+
# ImageMaths - Convert func to float representation
86+
func_to_float = Node(ImageMaths(), name = 'func_to_float')
87+
func_to_float.inputs.out_data_type = 'float'
88+
func_to_float.inputs.op_string = ''
89+
func_to_float.inputs.suffix = '_dtype'
90+
preprocessing.connect(select_files, 'func', func_to_float, 'in_file')
91+
92+
# ImageMaths - Mask the functional image
93+
mask_func = Node(ImageMaths(), name = 'mask_func')
94+
mask_func.inputs.suffix = '_thresh'
95+
mask_func.inputs.op_string = '-mas'
96+
preprocessing.connect(func_to_float, 'out_file', mask_func, 'in_file')
97+
preprocessing.connect(select_files, 'mask', mask_func, 'in_file2')
8298

8399
# ImageStats Node - Compute mean value of the 4D data
84100
# -k option adds a mask
@@ -88,10 +104,14 @@ def get_preprocessing(self):
88104
# (i.e.: apply mask then compute stat)
89105
compute_mean = Node(ImageStats(), name = 'compute_mean')
90106
compute_mean.inputs.op_string = '-k %s -m'
107+
preprocessing.connect(mask_func, 'out_file', compute_mean, 'in_file')
91108

92109
# MathsCommand Node - Perform grand-mean intensity normalisation of the entire 4D data
93-
intensity_normalization = Node(MathsCommand(), name = 'intensity_normalization')
94-
build_ing_args = lambda x : f'-ing {x}'
110+
intensity_normalization = Node(ImageMaths(), name = 'intensity_normalization')
111+
build_ing_args = lambda val : '-mul %.10f' % (10000. / val)
112+
preprocessing.connect(mask_func, 'out_file', intensity_normalization, 'in_file')
113+
preprocessing.connect(
114+
compute_mean, ('out_stat', build_ing_args), intensity_normalization, 'args')
95115

96116
# ImageStats Node - Compute median of voxel values to derive SUSAN's brightness_threshold
97117
# -k option adds a mask
@@ -101,34 +121,22 @@ def get_preprocessing(self):
101121
# (i.e.: apply mask then compute stat)
102122
compute_median = Node(ImageStats(), name = 'compute_median')
103123
compute_median.inputs.op_string = '-k %s -p 50'
124+
preprocessing.connect(mask_func, 'out_file', compute_median, 'in_file')
104125

105126
# SUSAN Node - smoothing of functional images
106127
# we set brightness_threshold to .75x median of the input file, as performed by fMRIprep
107128
smoothing = Node(SUSAN(), name = 'smoothing')
108129
smoothing.inputs.fwhm = self.fwhm
109130
compute_brightness_threshold = lambda x : .75 * x
131+
preprocessing.connect(
132+
compute_median, ('out_stat', compute_brightness_threshold),
133+
smoothing, 'brightness_threshold')
134+
preprocessing.connect(intensity_normalization, 'out_file', smoothing, 'in_file')
110135

111-
# Define workflow
112-
preprocessing = Workflow(base_dir = self.directories.working_dir, name = 'preprocessing')
113-
preprocessing.config['execution']['stop_on_first_crash'] = 'true'
114-
preprocessing.connect([
115-
(information_source, select_files, [
116-
('subject_id', 'subject_id'), ('run_id', 'run_id')
117-
]),
118-
(select_files, compute_mean, [('func', 'in_file')]),
119-
(select_files, compute_mean, [('mask', 'mask_file')]),
120-
(select_files, intensity_normalization, [('func', 'in_file')]),
121-
(select_files, compute_median, [('func', 'in_file')]),
122-
(select_files, compute_median, [('mask', 'mask_file')]),
123-
(compute_mean, intensity_normalization, [
124-
(('out_stat', build_ing_args), 'args')
125-
]),
126-
(compute_median, smoothing, [
127-
(('out_stat', compute_brightness_threshold), 'brightness_threshold')
128-
]),
129-
(intensity_normalization, smoothing, [('out_file', 'in_file')]),
130-
(smoothing, data_sink, [('smoothed_file', 'preprocessing.@output_image')])
131-
])
136+
# DataSink Node - store the wanted results in the wanted directory
137+
data_sink = Node(DataSink(), name = 'data_sink')
138+
data_sink.inputs.base_directory = self.directories.output_dir
139+
preprocessing.connect(smoothing, 'smoothed_file', data_sink, 'preprocessing.@output_image')
132140

133141
# Remove large files, if requested
134142
if Configuration()['pipelines']['remove_unused_data']:
@@ -467,11 +475,11 @@ def get_subject_level_analysis(self):
467475
generate_model.inputs.num_copes = len(self.run_list)
468476

469477
# Merge Node - Merge copes files for each subject
470-
merge_copes = Node(MergeImages(), name = 'merge_copes')
478+
merge_copes = Node(FSLMerge(), name = 'merge_copes')
471479
merge_copes.inputs.dimension = 't'
472480

473481
# Merge Node - Merge varcopes files for each subject
474-
merge_varcopes = Node(MergeImages(), name = 'merge_varcopes')
482+
merge_varcopes = Node(FSLMerge(), name = 'merge_varcopes')
475483
merge_varcopes.inputs.dimension = 't'
476484

477485
# Split Node - Split mask list to serve them as inputs of the MultiImageMaths node.
@@ -665,11 +673,11 @@ def get_group_level_analysis_sub_workflow(self, method):
665673
)
666674

667675
# Merge Node - Merge cope files
668-
merge_copes = Node(MergeImages(), name = 'merge_copes')
676+
merge_copes = Node(FSLMerge(), name = 'merge_copes')
669677
merge_copes.inputs.dimension = 't'
670678

671679
# Merge Node - Merge cope files
672-
merge_varcopes = Node(MergeImages(), name = 'merge_varcopes')
680+
merge_varcopes = Node(FSLMerge(), name = 'merge_varcopes')
673681
merge_varcopes.inputs.dimension = 't'
674682

675683
# Split Node - Split mask list to serve them as inputs of the MultiImageMaths node.

0 commit comments

Comments
 (0)