43
43
)
44
44
from niworkflows .interfaces .freesurfer import PatchedRobustRegister as RobustRegister
45
45
from niworkflows .interfaces .nitransforms import ConcatenateXFMs
46
+ from niworkflows .interfaces .patches import FreeSurferSource
46
47
from niworkflows .interfaces .utility import KeySelect
47
48
from niworkflows .interfaces .workbench import (
48
49
MetricDilate ,
@@ -228,7 +229,7 @@ def init_surface_recon_wf(
228
229
229
230
autorecon_resume_wf = init_autorecon_resume_wf (omp_nthreads = omp_nthreads )
230
231
231
- get_surfaces = pe .Node (nio . FreeSurferSource (), name = 'get_surfaces' )
232
+ get_surfaces = pe .Node (FreeSurferSource (), name = 'get_surfaces' )
232
233
233
234
midthickness = pe .MapNode (
234
235
MakeMidthickness (thickness = True , distance = 0.5 , out_name = 'midthickness' ),
@@ -284,7 +285,7 @@ def init_surface_recon_wf(
284
285
]) # fmt:skip
285
286
else :
286
287
# Pretend to be the autorecon1 node so fsnative2t1w_xfm gets run ASAP
287
- fs_base_inputs = autorecon1 = pe .Node (nio . FreeSurferSource (), name = 'fs_base_inputs' )
288
+ fs_base_inputs = autorecon1 = pe .Node (FreeSurferSource (), name = 'fs_base_inputs' )
288
289
289
290
workflow .connect ([
290
291
(inputnode , fs_base_inputs , [
@@ -328,7 +329,9 @@ def init_surface_recon_wf(
328
329
return workflow
329
330
330
331
331
- def init_refinement_wf (* , name = 'refinement_wf' ):
332
+ def init_refinement_wf (
333
+ * , image_type : ty .Literal ['T1w' , 'T2w' ] = 'T1w' , name : str = 'refinement_wf'
334
+ ) -> Workflow :
332
335
r"""
333
336
Refine ANTs brain extraction with FreeSurfer segmentation
334
337
@@ -346,35 +349,19 @@ def init_refinement_wf(*, name='refinement_wf'):
346
349
FreeSurfer SUBJECTS_DIR
347
350
subject_id
348
351
FreeSurfer subject ID
349
- fsnative2t1w_xfm
350
- LTA-style affine matrix translating from FreeSurfer-conformed subject space to T1w
352
+ fsnative2anat_xfm
353
+ LTA-style affine matrix translating from FreeSurfer-conformed subject space to anatomical
351
354
reference_image
352
355
Input
353
- t2w
354
- List of T2-weighted structural images (only first used)
355
- flair
356
- List of FLAIR images
357
- skullstripped_t1
358
- Skull-stripped T1-weighted image (or mask of image)
359
356
ants_segs
360
357
Brain tissue segmentation from ANTS ``antsBrainExtraction.sh``
361
- corrected_t1
362
- INU-corrected, merged T1-weighted image
363
358
subjects_dir
364
359
FreeSurfer SUBJECTS_DIR
365
360
subject_id
366
361
FreeSurfer subject ID
367
362
368
363
Outputs
369
364
-------
370
- subjects_dir
371
- FreeSurfer SUBJECTS_DIR
372
- subject_id
373
- FreeSurfer subject ID
374
- t1w2fsnative_xfm
375
- LTA-style affine matrix translating from T1w to FreeSurfer-conformed subject space
376
- fsnative2t1w_xfm
377
- LTA-style affine matrix translating from FreeSurfer-conformed subject space to T1w
378
365
out_brainmask
379
366
Refined brainmask, derived from FreeSurfer's ``aseg`` volume
380
367
@@ -397,7 +384,7 @@ def init_refinement_wf(*, name='refinement_wf'):
397
384
fields = [
398
385
'reference_image' ,
399
386
'ants_segs' ,
400
- 'fsnative2t1w_xfm ' ,
387
+ 'fsnative2anat_xfm ' ,
401
388
'subjects_dir' ,
402
389
'subject_id' ,
403
390
]
@@ -413,24 +400,22 @@ def init_refinement_wf(*, name='refinement_wf'):
413
400
name = 'outputnode' ,
414
401
)
415
402
416
- aseg_to_native_wf = init_segs_to_native_wf ()
403
+ aseg_to_native_wf = init_segs_to_native_wf (image_type = image_type )
417
404
refine = pe .Node (RefineBrainMask (), name = 'refine' )
418
405
419
- # fmt:off
420
406
workflow .connect ([
421
407
# Refine ANTs mask, deriving new mask from FS' aseg
422
408
(inputnode , aseg_to_native_wf , [
423
409
('subjects_dir' , 'inputnode.subjects_dir' ),
424
410
('subject_id' , 'inputnode.subject_id' ),
425
411
('reference_image' , 'inputnode.in_file' ),
426
- ('fsnative2t1w_xfm' , 'inputnode.fsnative2t1w_xfm ' ),
412
+ ('fsnative2t1w_xfm' , 'inputnode.fsnative2anat_xfm ' ),
427
413
]),
428
414
(inputnode , refine , [('reference_image' , 'in_anat' ),
429
415
('ants_segs' , 'in_ants' )]),
430
416
(aseg_to_native_wf , refine , [('outputnode.out_file' , 'in_aseg' )]),
431
417
(refine , outputnode , [('out_file' , 'out_brainmask' )]),
432
- ])
433
- # fmt:on
418
+ ]) # fmt:skip
434
419
435
420
return workflow
436
421
@@ -610,8 +595,8 @@ def _dedup(in_list):
610
595
611
596
def init_surface_derivatives_wf (
612
597
* ,
613
- cifti_output : ty .Literal ['91k ' , '170k' , False ] = False ,
614
- name = 'surface_derivatives_wf' ,
598
+ image_type : ty .Literal ['T1w ' , 'T2w' ] = 'T1w' ,
599
+ name : str = 'surface_derivatives_wf' ,
615
600
):
616
601
r"""
617
602
Generate sMRIPrep derivatives from FreeSurfer derivatives
@@ -627,9 +612,9 @@ def init_surface_derivatives_wf(
627
612
Inputs
628
613
------
629
614
reference
630
- Reference image in native T1w space, for defining a resampling grid
631
- fsnative2t1w_xfm
632
- LTA-style affine matrix translating from FreeSurfer-conformed subject space to T1w
615
+ Reference image in native anatomical space, for defining a resampling grid
616
+ fsnative2anat_xfm
617
+ LTA-style affine matrix translating from FreeSurfer-conformed subject space to anatomical
633
618
subjects_dir
634
619
FreeSurfer SUBJECTS_DIR
635
620
subject_id
@@ -643,9 +628,9 @@ def init_surface_derivatives_wf(
643
628
morphometrics
644
629
GIFTIs of cortical thickness, curvature, and sulcal depth
645
630
out_aseg
646
- FreeSurfer's aseg segmentation, in native T1w space
631
+ FreeSurfer's aseg segmentation, in native anatomical space
647
632
out_aparc
648
- FreeSurfer's aparc+aseg segmentation, in native T1w space
633
+ FreeSurfer's aparc+aseg segmentation, in native anatomical space
649
634
650
635
See also
651
636
--------
@@ -659,7 +644,7 @@ def init_surface_derivatives_wf(
659
644
fields = [
660
645
'subjects_dir' ,
661
646
'subject_id' ,
662
- 'fsnative2t1w_xfm ' ,
647
+ 'fsnative2anat_xfm ' ,
663
648
'reference' ,
664
649
]
665
650
),
@@ -679,16 +664,16 @@ def init_surface_derivatives_wf(
679
664
680
665
gifti_surfaces_wf = init_gifti_surfaces_wf (surfaces = ['inflated' ])
681
666
gifti_morph_wf = init_gifti_morphometrics_wf (morphometrics = ['curv' ])
682
- aseg_to_native_wf = init_segs_to_native_wf ()
683
- aparc_to_native_wf = init_segs_to_native_wf (segmentation = 'aparc_aseg' )
667
+ aseg_to_native_wf = init_segs_to_native_wf (image_type = image_type )
668
+ aparc_to_native_wf = init_segs_to_native_wf (image_type = image_type , segmentation = 'aparc_aseg' )
684
669
685
670
# fmt:off
686
671
workflow .connect ([
687
672
# Configuration
688
673
(inputnode , gifti_surfaces_wf , [
689
674
('subjects_dir' , 'inputnode.subjects_dir' ),
690
675
('subject_id' , 'inputnode.subject_id' ),
691
- ('fsnative2t1w_xfm ' , 'inputnode.fsnative2t1w_xfm ' ),
676
+ ('fsnative2anat_xfm ' , 'inputnode.fsnative2anat_xfm ' ),
692
677
]),
693
678
(inputnode , gifti_morph_wf , [
694
679
('subjects_dir' , 'inputnode.subjects_dir' ),
@@ -698,13 +683,13 @@ def init_surface_derivatives_wf(
698
683
('subjects_dir' , 'inputnode.subjects_dir' ),
699
684
('subject_id' , 'inputnode.subject_id' ),
700
685
('reference' , 'inputnode.in_file' ),
701
- ('fsnative2t1w_xfm ' , 'inputnode.fsnative2t1w_xfm ' ),
686
+ ('fsnative2anat_xfm ' , 'inputnode.fsnative2anat_xfm ' ),
702
687
]),
703
688
(inputnode , aparc_to_native_wf , [
704
689
('subjects_dir' , 'inputnode.subjects_dir' ),
705
690
('subject_id' , 'inputnode.subject_id' ),
706
691
('reference' , 'inputnode.in_file' ),
707
- ('fsnative2t1w_xfm ' , 'inputnode.fsnative2t1w_xfm ' ),
692
+ ('fsnative2anat_xfm ' , 'inputnode.fsnative2anat_xfm ' ),
708
693
]),
709
694
710
695
# Output
@@ -1000,7 +985,7 @@ def init_gifti_morphometrics_wf(
1000
985
name = 'outputnode' ,
1001
986
)
1002
987
1003
- get_subject = pe .Node (nio . FreeSurferSource (), name = 'get_surfaces' )
988
+ get_subject = pe .Node (FreeSurferSource (), name = 'get_surfaces' )
1004
989
1005
990
morphometry_list = pe .Node (
1006
991
niu .Merge (len (morphometrics ), ravel_inputs = True ),
@@ -1182,7 +1167,12 @@ def init_hcp_morphometrics_wf(
1182
1167
return workflow
1183
1168
1184
1169
1185
- def init_segs_to_native_wf (* , name = 'segs_to_native' , segmentation = 'aseg' ):
1170
+ def init_segs_to_native_wf (
1171
+ * ,
1172
+ image_type : ty .Literal ['T1w' , 'T2w' ] = 'T1w' ,
1173
+ segmentation : ty .Literal ['aseg' , 'aparc_aseg' , 'wmparc' ] = 'aseg' ,
1174
+ name : str = 'segs_to_native_wf' ,
1175
+ ) -> Workflow :
1186
1176
"""
1187
1177
Get a segmentation from FreeSurfer conformed space into native T1w space.
1188
1178
@@ -1196,19 +1186,21 @@ def init_segs_to_native_wf(*, name='segs_to_native', segmentation='aseg'):
1196
1186
1197
1187
Parameters
1198
1188
----------
1189
+ image_type
1190
+ MR anatomical image type ('T1w' or 'T2w')
1199
1191
segmentation
1200
1192
The name of a segmentation ('aseg' or 'aparc_aseg' or 'wmparc')
1201
1193
1202
1194
Inputs
1203
1195
------
1204
1196
in_file
1205
- Anatomical, merged T1w image after INU correction
1197
+ Anatomical, merged anatomical image after INU correction
1206
1198
subjects_dir
1207
1199
FreeSurfer SUBJECTS_DIR
1208
1200
subject_id
1209
1201
FreeSurfer subject ID
1210
- fsnative2t1w_xfm
1211
- LTA-style affine matrix translating from FreeSurfer-conformed subject space to T1w
1202
+ fsnative2anat_xfm
1203
+ LTA-style affine matrix translating from FreeSurfer-conformed subject space to anatomical
1212
1204
1213
1205
Outputs
1214
1206
-------
@@ -1218,16 +1210,16 @@ def init_segs_to_native_wf(*, name='segs_to_native', segmentation='aseg'):
1218
1210
"""
1219
1211
workflow = Workflow (name = f'{ name } _{ segmentation } ' )
1220
1212
inputnode = pe .Node (
1221
- niu .IdentityInterface (['in_file' , 'subjects_dir' , 'subject_id' , 'fsnative2t1w_xfm ' ]),
1213
+ niu .IdentityInterface (['in_file' , 'subjects_dir' , 'subject_id' , 'fsnative2anat_xfm ' ]),
1222
1214
name = 'inputnode' ,
1223
1215
)
1224
1216
outputnode = pe .Node (niu .IdentityInterface (['out_file' ]), name = 'outputnode' )
1225
1217
# Extract the aseg and aparc+aseg outputs
1226
- fssource = pe .Node (nio . FreeSurferSource (), name = 'fs_datasource' )
1218
+ fssource = pe .Node (FreeSurferSource (), name = 'fs_datasource' )
1227
1219
1228
1220
lta = pe .Node (ConcatenateXFMs (out_fmt = 'fs' ), name = 'lta' , run_without_submitting = True )
1229
1221
1230
- # Resample from T1.mgz to T1w.nii.gz, applying any offset in fsnative2t1w_xfm ,
1222
+ # Resample from T1.mgz to T1w.nii.gz, applying any offset in fsnative2anat_xfm ,
1231
1223
# and convert to NIfTI while we're at it
1232
1224
resample = pe .Node (
1233
1225
fs .ApplyVolTransform (transformed_file = 'seg.nii.gz' , interp = 'nearest' ),
@@ -1252,20 +1244,20 @@ def _sel(x):
1252
1244
1253
1245
segmentation = (segmentation , _sel )
1254
1246
1255
- # fmt:off
1247
+ anat = 'T2' if image_type == 'T2w' else 'T1'
1248
+
1256
1249
workflow .connect ([
1257
1250
(inputnode , fssource , [
1258
1251
('subjects_dir' , 'subjects_dir' ),
1259
1252
('subject_id' , 'subject_id' )]),
1260
1253
(inputnode , lta , [('in_file' , 'reference' ),
1261
- ('fsnative2t1w_xfm ' , 'in_xfms' )]),
1262
- (fssource , lta , [('T1' , 'moving' )]),
1254
+ ('fsnative2anat_xfm ' , 'in_xfms' )]),
1255
+ (fssource , lta , [(anat , 'moving' )]),
1263
1256
(inputnode , resample , [('in_file' , 'target_file' )]),
1264
1257
(fssource , resample , [(segmentation , 'source_file' )]),
1265
1258
(lta , resample , [('out_xfm' , 'lta_file' )]),
1266
1259
(resample , outputnode , [('transformed_file' , 'out_file' )]),
1267
- ])
1268
- # fmt:on
1260
+ ]) # fmt:skip
1269
1261
return workflow
1270
1262
1271
1263
0 commit comments