18
18
from ..interfaces import DerivativesDataSink , BIDSDataGrabber
19
19
from ..interfaces .reports import SubjectSummary , AboutSummary
20
20
from ..utils .bids import collect_data
21
- from .dwi import init_dwi_preproc_wf
21
+ from .dwi . base import init_early_b0ref_wf
22
22
23
23
24
24
def init_dmriprep_wf ():
@@ -40,42 +40,42 @@ def init_dmriprep_wf():
40
40
wf = init_dmriprep_wf()
41
41
42
42
"""
43
- dmriprep_wf = Workflow (name = ' dmriprep_wf' )
43
+ dmriprep_wf = Workflow (name = " dmriprep_wf" )
44
44
dmriprep_wf .base_dir = config .execution .work_dir
45
45
46
46
freesurfer = config .workflow .run_reconall
47
47
if freesurfer :
48
48
fsdir = pe .Node (
49
49
BIDSFreeSurferDir (
50
50
derivatives = config .execution .output_dir ,
51
- freesurfer_home = os .getenv (' FREESURFER_HOME' ),
51
+ freesurfer_home = os .getenv (" FREESURFER_HOME" ),
52
52
spaces = config .workflow .spaces .get_fs_spaces ()),
53
- name = ' fsdir_run_%s' % config .execution .run_uuid .replace ('-' , '_' ),
53
+ name = f" fsdir_run_{ config .execution .run_uuid .replace ('-' , '_' )} " ,
54
54
run_without_submitting = True )
55
55
if config .execution .fs_subjects_dir is not None :
56
56
fsdir .inputs .subjects_dir = str (config .execution .fs_subjects_dir .absolute ())
57
57
58
58
for subject_id in config .execution .participant_label :
59
59
single_subject_wf = init_single_subject_wf (subject_id )
60
60
61
- single_subject_wf .config [' execution' ][ ' crashdump_dir' ] = str (
62
- config .execution .output_dir / "dmriprep" / "-" . join (( " sub" , subject_id ))
61
+ single_subject_wf .config [" execution" ][ " crashdump_dir" ] = str (
62
+ config .execution .output_dir / "dmriprep" / f" sub- { subject_id } "
63
63
/ "log" / config .execution .run_uuid
64
64
)
65
65
66
66
for node in single_subject_wf ._get_all_nodes ():
67
67
node .config = deepcopy (single_subject_wf .config )
68
68
if freesurfer :
69
- dmriprep_wf .connect (fsdir , ' subjects_dir' ,
70
- single_subject_wf , 'inputnode .subjects_dir' )
69
+ dmriprep_wf .connect (fsdir , " subjects_dir" ,
70
+ single_subject_wf , "fsinputnode .subjects_dir" )
71
71
else :
72
72
dmriprep_wf .add_nodes ([single_subject_wf ])
73
73
74
74
# Dump a copy of the config file into the log directory
75
- log_dir = config .execution .output_dir / ' dmriprep' / ' sub-{}' . format ( subject_id ) \
76
- / ' log' / config .execution .run_uuid
75
+ log_dir = config .execution .output_dir / " dmriprep" / f" sub-{ subject_id } " \
76
+ / " log" / config .execution .run_uuid
77
77
log_dir .mkdir (exist_ok = True , parents = True )
78
- config .to_filename (log_dir / ' dmriprep.toml' )
78
+ config .to_filename (log_dir / " dmriprep.toml" )
79
79
80
80
return dmriprep_wf
81
81
@@ -102,7 +102,7 @@ def init_single_subject_wf(subject_id):
102
102
from dmriprep.config.testing import mock_config
103
103
from dmriprep.workflows.base import init_single_subject_wf
104
104
with mock_config():
105
- wf = init_single_subject_wf(' THP0005' )
105
+ wf = init_single_subject_wf(" THP0005" )
106
106
107
107
Parameters
108
108
----------
@@ -115,24 +115,24 @@ def init_single_subject_wf(subject_id):
115
115
FreeSurfer's ``$SUBJECTS_DIR``
116
116
117
117
"""
118
- name = "single_subject_%s_wf" % subject_id
118
+ name = f "single_subject_{ subject_id } _wf"
119
119
subject_data = collect_data (
120
120
config .execution .layout ,
121
121
subject_id )[0 ]
122
122
123
- if ' flair' in config .workflow .ignore :
124
- subject_data [' flair' ] = []
125
- if ' t2w' in config .workflow .ignore :
126
- subject_data [' t2w' ] = []
123
+ if " flair" in config .workflow .ignore :
124
+ subject_data [" flair" ] = []
125
+ if " t2w" in config .workflow .ignore :
126
+ subject_data [" t2w" ] = []
127
127
128
128
anat_only = config .workflow .anat_only
129
129
130
130
# Make sure we always go through these two checks
131
- if not anat_only and not subject_data [' dwi' ]:
131
+ if not anat_only and not subject_data [" dwi" ]:
132
132
raise Exception (f"No DWI data found for participant { subject_id } . "
133
133
"All workflows require DWI images." )
134
134
135
- if not subject_data [' t1w' ]:
135
+ if not subject_data [" t1w" ]:
136
136
raise Exception (f"No T1w images found for participant { subject_id } . "
137
137
"All workflows require T1w images." )
138
138
@@ -165,34 +165,34 @@ def init_single_subject_wf(subject_id):
165
165
166
166
"""
167
167
spaces = config .workflow .spaces
168
- reportlets_dir = str (config .execution .work_dir / ' reportlets' )
168
+ reportlets_dir = str (config .execution .work_dir / " reportlets" )
169
169
170
- inputnode = pe .Node (niu .IdentityInterface (fields = [' subjects_dir' ]),
171
- name = 'inputnode' )
170
+ fsinputnode = pe .Node (niu .IdentityInterface (fields = [" subjects_dir" ]),
171
+ name = "fsinputnode" )
172
172
173
173
bidssrc = pe .Node (BIDSDataGrabber (subject_data = subject_data , anat_only = anat_only ),
174
- name = ' bidssrc' )
174
+ name = " bidssrc" )
175
175
176
176
bids_info = pe .Node (BIDSInfo (
177
- bids_dir = config .execution .bids_dir , bids_validate = False ), name = ' bids_info' )
177
+ bids_dir = config .execution .bids_dir , bids_validate = False ), name = " bids_info" )
178
178
179
179
summary = pe .Node (SubjectSummary (std_spaces = spaces .get_spaces (nonstandard = False ),
180
180
nstd_spaces = spaces .get_spaces (standard = False )),
181
- name = ' summary' , run_without_submitting = True )
181
+ name = " summary" , run_without_submitting = True )
182
182
183
183
about = pe .Node (AboutSummary (version = config .environment .version ,
184
- command = ' ' .join (sys .argv )),
185
- name = ' about' , run_without_submitting = True )
184
+ command = " " .join (sys .argv )),
185
+ name = " about" , run_without_submitting = True )
186
186
187
187
ds_report_summary = pe .Node (
188
188
DerivativesDataSink (base_directory = reportlets_dir ,
189
- desc = ' summary' , keep_dtype = True ),
190
- name = ' ds_report_summary' , run_without_submitting = True )
189
+ desc = " summary" , keep_dtype = True ),
190
+ name = " ds_report_summary" , run_without_submitting = True )
191
191
192
192
ds_report_about = pe .Node (
193
193
DerivativesDataSink (base_directory = reportlets_dir ,
194
- desc = ' about' , keep_dtype = True ),
195
- name = ' ds_report_about' , run_without_submitting = True )
194
+ desc = " about" , keep_dtype = True ),
195
+ name = " ds_report_about" , run_without_submitting = True )
196
196
197
197
# Preprocessing of T1w (includes registration to MNI)
198
198
anat_preproc_wf = init_anat_preproc_wf (
@@ -205,77 +205,76 @@ def init_single_subject_wf(subject_id):
205
205
output_dir = str (config .execution .output_dir ),
206
206
reportlets_dir = reportlets_dir ,
207
207
skull_strip_fixed_seed = config .workflow .skull_strip_fixed_seed ,
208
- skull_strip_mode = ' force' ,
208
+ skull_strip_mode = " force" ,
209
209
skull_strip_template = Reference .from_string (
210
210
config .workflow .skull_strip_template )[0 ],
211
211
spaces = spaces ,
212
- t1w = subject_data [' t1w' ],
212
+ t1w = subject_data [" t1w" ],
213
213
)
214
214
215
215
workflow .connect ([
216
- (inputnode , anat_preproc_wf , [(' subjects_dir' , ' inputnode.subjects_dir' )]),
217
- (bidssrc , bids_info , [((' t1w' , fix_multi_T1w_source_name ), ' in_file' )]),
218
- (inputnode , summary , [(' subjects_dir' , ' subjects_dir' )]),
219
- (bidssrc , summary , [(' t1w' , ' t1w' ),
220
- (' t2w' , ' t2w' ),
221
- (' dwi' , ' dwi' )]),
222
- (bids_info , summary , [(' subject' , ' subject_id' )]),
223
- (bids_info , anat_preproc_wf , [((' subject' , _prefix ), ' inputnode.subject_id' )]),
224
- (bidssrc , anat_preproc_wf , [(' t1w' , ' inputnode.t1w' ),
225
- (' t2w' , ' inputnode.t2w' ),
226
- (' roi' , ' inputnode.roi' ),
227
- (' flair' , ' inputnode.flair' )]),
228
- (bidssrc , ds_report_summary , [((' t1w' , fix_multi_T1w_source_name ), ' source_file' )]),
229
- (summary , ds_report_summary , [(' out_report' , ' in_file' )]),
230
- (bidssrc , ds_report_about , [((' t1w' , fix_multi_T1w_source_name ), ' source_file' )]),
231
- (about , ds_report_about , [(' out_report' , ' in_file' )]),
216
+ (fsinputnode , anat_preproc_wf , [(" subjects_dir" , " inputnode.subjects_dir" )]),
217
+ (bidssrc , bids_info , [((" t1w" , fix_multi_T1w_source_name ), " in_file" )]),
218
+ (fsinputnode , summary , [(" subjects_dir" , " subjects_dir" )]),
219
+ (bidssrc , summary , [(" t1w" , " t1w" ),
220
+ (" t2w" , " t2w" ),
221
+ (" dwi" , " dwi" )]),
222
+ (bids_info , summary , [(" subject" , " subject_id" )]),
223
+ (bids_info , anat_preproc_wf , [((" subject" , _prefix ), " inputnode.subject_id" )]),
224
+ (bidssrc , anat_preproc_wf , [(" t1w" , " inputnode.t1w" ),
225
+ (" t2w" , " inputnode.t2w" ),
226
+ (" roi" , " inputnode.roi" ),
227
+ (" flair" , " inputnode.flair" )]),
228
+ (bidssrc , ds_report_summary , [((" t1w" , fix_multi_T1w_source_name ), " source_file" )]),
229
+ (summary , ds_report_summary , [(" out_report" , " in_file" )]),
230
+ (bidssrc , ds_report_about , [((" t1w" , fix_multi_T1w_source_name ), " source_file" )]),
231
+ (about , ds_report_about , [(" out_report" , " in_file" )]),
232
232
])
233
233
234
234
# Overwrite ``out_path_base`` of smriprep's DataSinks
235
235
for node in workflow .list_node_names ():
236
- if node .split ('.' )[- 1 ].startswith (' ds_' ):
237
- workflow .get_node (node ).interface .out_path_base = ' dmriprep'
236
+ if node .split ("." )[- 1 ].startswith (" ds_" ):
237
+ workflow .get_node (node ).interface .out_path_base = " dmriprep"
238
238
239
239
if anat_only :
240
240
return workflow
241
241
242
242
# Append the dMRI section to the existing anatomical excerpt
243
243
# That way we do not need to stream down the number of bold datasets
244
- anat_preproc_wf .__postdesc__ = (anat_preproc_wf .__postdesc__ or '' ) + f"""
244
+ anat_preproc_wf .__postdesc__ = (anat_preproc_wf .__postdesc__ or "" ) + f"""
245
245
Diffusion data preprocessing
246
246
247
247
: For each of the { len (subject_data ["dwi" ])} dwi scans found per subject
248
248
(across all sessions), the following preprocessing was performed."""
249
249
250
- for dwi_file in subject_data ['dwi' ]:
251
- dwi_preproc_wf = init_dwi_preproc_wf (dwi_file )
252
-
253
- workflow .connect ([
254
- (anat_preproc_wf , dwi_preproc_wf ,
255
- [(('outputnode.t1w_preproc' , _pop ), 'inputnode.t1w_preproc' ),
256
- ('outputnode.t1w_mask' , 'inputnode.t1w_mask' ),
257
- ('outputnode.t1w_dseg' , 'inputnode.t1w_dseg' ),
258
- ('outputnode.t1w_aseg' , 'inputnode.t1w_aseg' ),
259
- ('outputnode.t1w_aparc' , 'inputnode.t1w_aparc' ),
260
- ('outputnode.t1w_tpms' , 'inputnode.t1w_tpms' ),
261
- ('outputnode.template' , 'inputnode.template' ),
262
- ('outputnode.anat2std_xfm' , 'inputnode.anat2std_xfm' ),
263
- ('outputnode.std2anat_xfm' , 'inputnode.std2anat_xfm' ),
264
- # Undefined if --fs-no-reconall, but this is safe
265
- ('outputnode.subjects_dir' , 'inputnode.subjects_dir' ),
266
- ('outputnode.subject_id' , 'inputnode.subject_id' ),
267
- ('outputnode.t1w2fsnative_xfm' , 'inputnode.t1w2fsnative_xfm' ),
268
- ('outputnode.fsnative2t1w_xfm' , 'inputnode.fsnative2t1w_xfm' )]),
250
+ layout = config .execution .layout
251
+ inputnode = pe .Node (niu .IdentityInterface (fields = ["dwi_data" ]),
252
+ name = "inputnode" )
253
+ inputnode .iterables = [(
254
+ "dwi_data" , tuple ([
255
+ (dwi , layout .get_bvec (dwi ), layout .get_bval (dwi ),
256
+ layout .get_metadata (dwi )["PhaseEncodingDirection" ])
257
+ for dwi in subject_data ["dwi" ]
269
258
])
259
+ )]
260
+ split_info = pe .Node (niu .Function (
261
+ function = _unpack , output_names = ["dwi_file" , "bvec" , "bval" , "pedir" ]),
262
+ name = "split_info" , run_without_submitting = True )
263
+
264
+ early_b0ref_wf = init_early_b0ref_wf ()
265
+ workflow .connect ([
266
+ (inputnode , split_info , [("dwi_data" , "in_tuple" )]),
267
+ (split_info , early_b0ref_wf , [("dwi_file" , "inputnode.dwi_file" ),
268
+ ("bvec" , "inputnode.in_bvec" ),
269
+ ("bval" , "inputnode.in_bval" )]),
270
+ ])
270
271
271
272
return workflow
272
273
273
274
274
275
def _prefix (subid ):
275
- return '-' .join ((' sub' , subid .lstrip (' sub-' )))
276
+ return "-" .join ((" sub" , subid .lstrip (" sub-" )))
276
277
277
278
278
- def _pop (inlist ):
279
- if isinstance (inlist , (list , tuple )):
280
- return inlist [0 ]
281
- return inlist
279
+ def _unpack (in_tuple ):
280
+ return in_tuple
0 commit comments