52
52
from nipype .interfaces .base import CommandLine
53
53
CommandLine .set_default_terminal_output ('allatonce' )
54
54
55
+ # https://github.com/moloney/dcmstack
55
56
from dcmstack .extract import default_extractor
57
+ # pip install pydicom
56
58
from dicom import read_file
57
59
58
60
from nipype .interfaces import (fsl , Function , ants , freesurfer , nipy )
64
66
65
67
from nipype .algorithms .rapidart import ArtifactDetect
66
68
from nipype .algorithms .misc import TSNR
69
+ from nipype .algorithms .compcor import ACompCor
67
70
from nipype .interfaces .utility import Rename , Merge , IdentityInterface
68
71
from nipype .utils .filemanip import filename_to_list
69
72
from nipype .interfaces .io import DataSink , FreeSurferSource
@@ -228,51 +231,6 @@ def build_filter1(motion_params, comp_norm, outliers, detrend_poly=None):
228
231
out_files .append (filename )
229
232
return out_files
230
233
231
-
232
- def extract_noise_components (realigned_file , mask_file , num_components = 5 ,
233
- extra_regressors = None ):
234
- """Derive components most reflective of physiological noise
235
-
236
- Parameters
237
- ----------
238
- realigned_file: a 4D Nifti file containing realigned volumes
239
- mask_file: a 3D Nifti file containing white matter + ventricular masks
240
- num_components: number of components to use for noise decomposition
241
- extra_regressors: additional regressors to add
242
-
243
- Returns
244
- -------
245
- components_file: a text file containing the noise components
246
- """
247
- imgseries = nb .load (realigned_file )
248
- components = None
249
- for filename in filename_to_list (mask_file ):
250
- mask = nb .load (filename ).get_data ()
251
- if len (np .nonzero (mask > 0 )[0 ]) == 0 :
252
- continue
253
- voxel_timecourses = imgseries .get_data ()[mask > 0 ]
254
- voxel_timecourses [np .isnan (np .sum (voxel_timecourses , axis = 1 )), :] = 0
255
- # remove mean and normalize by variance
256
- # voxel_timecourses.shape == [nvoxels, time]
257
- X = voxel_timecourses .T
258
- stdX = np .std (X , axis = 0 )
259
- stdX [stdX == 0 ] = 1.
260
- stdX [np .isnan (stdX )] = 1.
261
- stdX [np .isinf (stdX )] = 1.
262
- X = (X - np .mean (X , axis = 0 )) / stdX
263
- u , _ , _ = sp .linalg .svd (X , full_matrices = False )
264
- if components is None :
265
- components = u [:, :num_components ]
266
- else :
267
- components = np .hstack ((components , u [:, :num_components ]))
268
- if extra_regressors :
269
- regressors = np .genfromtxt (extra_regressors )
270
- components = np .hstack ((components , regressors ))
271
- components_file = os .path .join (os .getcwd (), 'noise_components.txt' )
272
- np .savetxt (components_file , components , fmt = b"%.10f" )
273
- return components_file
274
-
275
-
276
234
def rename (in_files , suffix = None ):
277
235
from nipype .utils .filemanip import (filename_to_list , split_filename ,
278
236
list_to_filename )
@@ -592,7 +550,7 @@ def create_workflow(files,
592
550
realign .inputs .slice_info = 2
593
551
realign .plugin_args = {'sbatch_args' : '-c%d' % 4 }
594
552
595
- # Comute TSNR on realigned data regressing polynomials upto order 2
553
+ # Compute TSNR on realigned data regressing polynomials up to order 2
596
554
tsnr = MapNode (TSNR (regress_poly = 2 ), iterfield = ['in_file' ], name = 'tsnr' )
597
555
wf .connect (realign , "out_file" , tsnr , "in_file" )
598
556
@@ -694,14 +652,10 @@ def merge_files(in1, in2):
694
652
filter1 , 'out_res_name' )
695
653
wf .connect (createfilter1 , 'out_files' , filter1 , 'design' )
696
654
697
- createfilter2 = MapNode (Function (input_names = ['realigned_file' , 'mask_file' ,
698
- 'num_components' ,
699
- 'extra_regressors' ],
700
- output_names = ['out_files' ],
701
- function = extract_noise_components ,
702
- imports = imports ),
655
+ createfilter2 = MapNode (ACompCor (),
703
656
iterfield = ['realigned_file' , 'extra_regressors' ],
704
657
name = 'makecompcorrfilter' )
658
+ createfilter2 .inputs .components_file = 'noise_components.txt'
705
659
createfilter2 .inputs .num_components = num_components
706
660
707
661
wf .connect (createfilter1 , 'out_files' , createfilter2 , 'extra_regressors' )
@@ -717,7 +671,7 @@ def merge_files(in1, in2):
717
671
wf .connect (filter1 , 'out_res' , filter2 , 'in_file' )
718
672
wf .connect (filter1 , ('out_res' , rename , '_cleaned' ),
719
673
filter2 , 'out_res_name' )
720
- wf .connect (createfilter2 , 'out_files ' , filter2 , 'design' )
674
+ wf .connect (createfilter2 , 'components_file ' , filter2 , 'design' )
721
675
wf .connect (mask , 'mask_file' , filter2 , 'mask' )
722
676
723
677
bandpass = Node (Function (input_names = ['files' , 'lowpass_freq' ,
@@ -923,7 +877,7 @@ def get_names(files, suffix):
923
877
wf .connect (smooth , 'out_file' , datasink , 'resting.timeseries.@smoothed' )
924
878
wf .connect (createfilter1 , 'out_files' ,
925
879
datasink , 'resting.regress.@regressors' )
926
- wf .connect (createfilter2 , 'out_files ' ,
880
+ wf .connect (createfilter2 , 'components_file ' ,
927
881
datasink , 'resting.regress.@compcorr' )
928
882
wf .connect (maskts , 'out_file' , datasink , 'resting.timeseries.target' )
929
883
wf .connect (sampleaparc , 'summary_file' ,
0 commit comments