@@ -558,6 +558,103 @@ def create_reg_workflow(name='registration'):
558
558
return register
559
559
560
560
561
+ def create_unwarp_workflow (name = 'unwarping' ):
562
+ """Creates a workflow for unwarping the EPI data prior to
563
+ coregistration with Siemens fieldmaps.
564
+
565
+ Parameters
566
+ ----------
567
+
568
+ ::
569
+
570
+ name : name of workflow (default: 'unwarping')
571
+
572
+ Inputs::
573
+
574
+ inputspec.realigned_file : realigned time series to unwarp
575
+ inputspec.mean_image : mean or median of time series
576
+ inputspec.fmap_mag : fieldmap magnitude image
577
+ inputspec.fmap_phase : fieldmap phase image
578
+ inputspec.delta_te : echo time difference of the fieldmap sequence [ms]
579
+ inputspec.pedir : phase encoding direction [x/y/z/x-/y-/z-]
580
+ inputspec.echospacing : effective EPI echo spacing (dwell time) [sec]
581
+
582
+ Outputs::
583
+ outputspec.unwarped_mean
584
+ outputspec.unwarped_file : unwarped time series
585
+
586
+ """
587
+ unwarp = Workflow (name = name )
588
+
589
+ inputnode = Node (interface = IdentityInterface (fields = ['realigned_file' ,
590
+ 'mean_image' ,
591
+ 'fmap_mag' ,
592
+ 'fmap_phase' ,
593
+ 'delta_te' ,
594
+ 'pedir' ,
595
+ 'echospacing' ]),
596
+ name = 'inputspec' )
597
+
598
+ outputnode = Node (interface = IdentityInterface (fields = ['unwarped_file' ,
599
+ 'unwarped_mean' ]),
600
+ name = 'outputspec' )
601
+
602
+ # split first magnitude image from mag input file
603
+ split = Node (fsl .ExtractROI (t_min = 0 ,
604
+ t_size = 1 ),
605
+ name = 'split' )
606
+ unwarp .connect (inputnode , 'fmap_mag' , split , 'in_file' )
607
+
608
+ # skullstrip magnitude image and erode further to get rid of noisy edge voxels
609
+ bet = Node (fsl .BET (frac = 0.5 ),
610
+ name = 'bet' )
611
+ unwarp .connect (split ,'roi_file' , bet ,'in_file' )
612
+
613
+ erode = Node (fsl .maths .ErodeImage (kernel_shape = 'sphere' ,
614
+ kernel_size = 5 ),
615
+ name = 'erode' )
616
+ unwarp .connect (bet ,'out_file' , erode , 'in_file' )
617
+
618
+ # prepare fieldmap
619
+ prep_fmap = Node (fsl .epi .PrepareFieldmap (),
620
+ name = 'prepare_fieldmap' )
621
+ unwarp .connect ([(erode , prep_fmap , [('out_file' , 'in_magnitude' )]),
622
+ (inputnode , prep_fmap , [('fmap_phase' , 'in_phase' ),
623
+ ('delta_te' , 'delta_TE' )])
624
+ ])
625
+
626
+ # unmask fieldmap to avoid edge effects
627
+ fmap_mask = Node (fsl .maths .MathsCommand (args = '-abs -bin -fillh' ),
628
+ name = 'fmap_mask' )
629
+
630
+ unmask = Node (fsl .FUGUE (save_unmasked_fmap = True ),
631
+ name = 'unmask' )
632
+
633
+ unwarp .connect ([(prep_fmap , fmap_mask , [('out_fieldmap' , 'in_file' )]),
634
+ (fmap_mask , unmask , [('out_file' , 'mask_file' )]),
635
+ (prep_fmap , unmask ,[('out_fieldmap' ,'fmap_in_file' )]),
636
+ (inputnode , unmask , [('pedir' , 'unwarp_direction' )])
637
+ ])
638
+
639
+ # unwarp epi mean and time series with fieldmap
640
+ unwarp_mean = Node (fsl .FUGUE (save_shift = True ),name = 'unwarp_mean' )
641
+ unwarp_ts = Node (fsl .FUGUE (save_shift = True ),name = 'unwarp_ts' )
642
+
643
+ unwarp .connect ([(inputnode , unwarp_mean , [('mean_image' , 'in_file' ),
644
+ ('echospacing' , 'dwell_time' ),
645
+ ('pedir' , 'unwarp_direction' )]),
646
+ (unmask , unwarp_mean , [('fmap_out_file' , 'fmap_in_file' )]),
647
+ (fmap_mask , unwarp_mean , [('out_file' ,'mask_file' )]),
648
+ (inputnode , unwarp_ts , [('realigned_file' , 'in_file' ),
649
+ ('echospacing' , 'dwell_time' ),
650
+ ('pedir' , 'unwarp_direction' )]),
651
+ (unmask , unwarp_ts , [('fmap_out_file' , 'fmap_in_file' )]),
652
+ (fmap_mask , unwarp_ts , [('out_file' ,'mask_file' )]),
653
+ (unwarp_mean , outputnode , [('unwarped_file' , 'unwarped_mean' )]),
654
+ (unwarp_ts , outputnode , [('unwarped_file' , 'unwarped_file' )])])
655
+
656
+ return unwarp
657
+
561
658
"""
562
659
Creates the main preprocessing workflow
563
660
"""
@@ -577,6 +674,12 @@ def create_workflow(files,
577
674
subjects_dir = None ,
578
675
sink_directory = os .getcwd (),
579
676
target_subject = ['fsaverage3' , 'fsaverage4' ],
677
+ do_unwarp = False ,
678
+ fmap_mag = None ,
679
+ fmap_phase = None ,
680
+ delta_te = None ,
681
+ pedir = None ,
682
+ echospacing = None ,
580
683
name = 'resting' ):
581
684
582
685
wf = Workflow (name = name )
@@ -767,7 +870,33 @@ def merge_files(in1, in2):
767
870
maskts = MapNode (fsl .ApplyMask (), iterfield = ['in_file' ], name = 'ts_masker' )
768
871
wf .connect (warpall , 'output_image' , maskts , 'in_file' )
769
872
wf .connect (mask_target , 'out_file' , maskts , 'mask_file' )
770
-
873
+
874
+
875
+ """
876
+ Rewire for optional fieldmap unwarping
877
+ """
878
+ if do_unwarp :
879
+ unwarping = create_unwarp_workflow (name = 'unwarping' )
880
+ unwarping .inputs .inputspec .fmap_mag = fmap_mag
881
+ unwarping .inputs .inputspec .fmap_phase = fmap_phase
882
+ unwarping .inputs .inputspec .pedir = pedir
883
+ unwarping .inputs .inputspec .delta_te = delta_te
884
+ unwarping .inputs .inputspec .echospacing = echospacing
885
+
886
+ wf .disconnect ([(calc_median , registration , [('median_file' , 'inputspec.mean_image' )]),
887
+ (realign , art , [('out_file' , 'realigned_files' )]),
888
+ (realign , filter1 , [('out_file' , 'in_file' ),
889
+ (('out_file' , rename , '_filtermotart' ),
890
+ 'out_res_name' )])])
891
+ wf .connect ([(realign , unwarping , [('out_file' , 'inputspec.realigned_file' )]),
892
+ (calc_median , unwarping , [('median_file' , 'inputspec.mean_image' )]),
893
+ (unwarping , registration , [('outputspec.unwarped_mean' , 'inputspec.mean_image' )]),
894
+ (unwarping , art , [('outputspec.unwarped_file' , 'realigned_files' )]),
895
+ (unwarping , filter1 , [('outputspec.unwarped_file' , 'in_file' ),
896
+ (('outputspec.unwarped_file' , rename , '_filtermotart' ),
897
+ 'out_res_name' )])])
898
+
899
+
771
900
# map to surface
772
901
# extract aparc+aseg ROIs
773
902
# extract subcortical ROIs
@@ -945,6 +1074,12 @@ def create_resting_workflow(args, name=None):
945
1074
if args .dicom_file :
946
1075
TR , slice_times , slice_thickness = get_info (args .dicom_file )
947
1076
slice_times = (np .array (slice_times )/ 1000. ).tolist ()
1077
+ if args .do_unwarp :
1078
+ fmap_mag = os .path .abspath (args .fmap_mag )
1079
+ fmap_phase = os .path .abspath (args .fmap_phase )
1080
+ else :
1081
+ fmap_mag = None
1082
+ fmap_phase = None
948
1083
949
1084
if name is None :
950
1085
name = 'resting_' + args .subject_id
@@ -961,6 +1096,12 @@ def create_resting_workflow(args, name=None):
961
1096
lowpass_freq = args .lowpass_freq ,
962
1097
highpass_freq = args .highpass_freq ,
963
1098
sink_directory = os .path .abspath (args .sink ),
1099
+ do_unwarp = args .do_unwarp ,
1100
+ fmap_mag = fmap_mag ,
1101
+ fmap_phase = fmap_phase ,
1102
+ delta_te = args .delta_te ,
1103
+ pedir = args .pedir ,
1104
+ echospacing = args .echospacing ,
964
1105
name = name )
965
1106
wf = create_workflow (** kwargs )
966
1107
return wf
@@ -1010,6 +1151,21 @@ def create_resting_workflow(args, name=None):
1010
1151
help = "Plugin to use" )
1011
1152
parser .add_argument ("--plugin_args" , dest = "plugin_args" ,
1012
1153
help = "Plugin arguments" )
1154
+ parser .add_argument ("--do_unwarp" , dest = "do_unwarp" ,
1155
+ default = False ,
1156
+ help = "Whether fieldmap unwarping should be used" )
1157
+ parser .add_argument ("--fmap_mag" , dest = "fmap_mag" , default = None ,
1158
+ help = "fieldmap magnitude image" )
1159
+ parser .add_argument ("--fmap_phase" , dest = "fmap_phase" , default = None ,
1160
+ help = "fieldmap phase image" )
1161
+ parser .add_argument ("--delta_te" , dest = "delta_te" ,
1162
+ default = None , type = float ,
1163
+ help = "echo time difference of the fieldmap sequence [ms]" )
1164
+ parser .add_argument ("--pedir" , dest = "pedir" , default = None ,
1165
+ help = "phase encoding direction [x/y/z/x-/y-/z-]" )
1166
+ parser .add_argument ("--echospacing" , dest = "echospacing" ,
1167
+ default = None , type = float ,
1168
+ help = "echo time difference of the fieldmap sequence [ms]" )
1013
1169
args = parser .parse_args ()
1014
1170
1015
1171
wf = create_resting_workflow (args )
0 commit comments