18
18
>>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data'))
19
19
>>> os.chdir(datadir)
20
20
"""
21
- from __future__ import print_function , division , unicode_literals , absolute_import
21
+ from __future__ import (print_function , division ,
22
+ unicode_literals , absolute_import )
22
23
from builtins import open , range , str , bytes
23
24
24
25
import os
@@ -160,44 +161,61 @@ def _calc_norm_affine(affines, use_differences, brain_pts=None):
160
161
161
162
class ArtifactDetectInputSpec (BaseInterfaceInputSpec ):
162
163
realigned_files = InputMultiPath (File (exists = True ),
163
- desc = "Names of realigned functional data files" ,
164
+ desc = ("Names of realigned functional data "
165
+ "files" ),
164
166
mandatory = True )
165
- realignment_parameters = InputMultiPath (File (exists = True ), mandatory = True ,
166
- desc = ("Names of realignment parameters"
167
- "corresponding to the functional data files" ))
167
+ realignment_parameters = InputMultiPath (File (exists = True ),
168
+ mandatory = True ,
169
+ desc = ("Names of realignment "
170
+ "parameters corresponding to "
171
+ "the functional data files" ))
168
172
parameter_source = traits .Enum ("SPM" , "FSL" , "AFNI" , "NiPy" , "FSFAST" ,
169
173
desc = "Source of movement parameters" ,
170
174
mandatory = True )
171
- use_differences = traits .ListBool ([True , False ], minlen = 2 , maxlen = 2 ,
175
+ use_differences = traits .ListBool ([True , False ],
176
+ minlen = 2 ,
177
+ maxlen = 2 ,
172
178
usedefault = True ,
173
- desc = ("Use differences between successive motion (first element)"
174
- "and intensity paramter (second element) estimates in order"
175
- "to determine outliers. (default is [True, False])" ))
176
- use_norm = traits .Bool (requires = ['norm_threshold' ],
179
+ desc = ("Use differences between successive"
180
+ " motion (first element) and "
181
+ "intensity parameter (second "
182
+ "element) estimates in order to "
183
+ "determine outliers. "
184
+ "(default is [True, False])" ))
185
+ use_norm = traits .Bool (True ,
186
+ usedefault = True ,
187
+ requires = ['norm_threshold' ],
177
188
desc = ("Uses a composite of the motion parameters in "
178
189
"order to determine outliers." ))
179
- norm_threshold = traits .Float (desc = ("Threshold to use to detect motion-rela"
190
+ norm_threshold = traits .Float (xor = ['rotation_threshold' ,
191
+ 'translation_threshold' ],
192
+ mandatory = True ,
193
+ desc = ("Threshold to use to detect motion-rela"
180
194
"ted outliers when composite motion is "
181
- "being used" ), mandatory = True ,
182
- xor = ['rotation_threshold' ,
183
- 'translation_threshold' ])
184
- rotation_threshold = traits .Float (mandatory = True , xor = ['norm_threshold' ],
185
- desc = ("Threshold (in radians) to use to detect rotation-related "
186
- "outliers" ))
187
- translation_threshold = traits .Float (mandatory = True , xor = ['norm_threshold' ],
188
- desc = ("Threshold (in mm) to use to detect translation-related "
195
+ "being used" ))
196
+ rotation_threshold = traits .Float (mandatory = True ,
197
+ xor = ['norm_threshold' ],
198
+ desc = ("Threshold (in radians) to use to "
199
+ "detect rotation-related outliers" ))
200
+ translation_threshold = traits .Float (mandatory = True ,
201
+ xor = ['norm_threshold' ],
202
+ desc = ("Threshold (in mm) to use to "
203
+ "detect translation-related "
189
204
"outliers" ))
190
205
zintensity_threshold = traits .Float (mandatory = True ,
191
- desc = ("Intensity Z-threshold use to detection images that deviate "
206
+ desc = ("Intensity Z-threshold use to "
207
+ "detection images that deviate "
192
208
"from the mean" ))
193
209
mask_type = traits .Enum ('spm_global' , 'file' , 'thresh' ,
194
- desc = ("Type of mask that should be used to mask the functional "
195
- "data. *spm_global* uses an spm_global like calculation to "
196
- "determine the brain mask. *file* specifies a brain mask "
197
- "file (should be an image file consisting of 0s and 1s). "
198
- "*thresh* specifies a threshold to use. By default all voxels"
199
- "are used, unless one of these mask types are defined." ),
200
- mandatory = True )
210
+ mandatory = True ,
211
+ desc = ("Type of mask that should be used to mask the"
212
+ " functional data. *spm_global* uses an "
213
+ "spm_global like calculation to determine the"
214
+ " brain mask. *file* specifies a brain mask "
215
+ "file (should be an image file consisting of "
216
+ "0s and 1s). *thresh* specifies a threshold "
217
+ "to use. By default all voxels are used,"
218
+ "unless one of these mask types are defined" ))
201
219
mask_file = File (exists = True ,
202
220
desc = "Mask file to be used if mask_type is 'file'." )
203
221
mask_threshold = traits .Float (desc = ("Mask threshold to be used if mask_type"
@@ -223,28 +241,36 @@ class ArtifactDetectInputSpec(BaseInterfaceInputSpec):
223
241
224
242
class ArtifactDetectOutputSpec (TraitedSpec ):
225
243
outlier_files = OutputMultiPath (File (exists = True ),
226
- desc = ("One file for each functional run containing a list of "
227
- "0-based indices corresponding to outlier volumes" ))
244
+ desc = ("One file for each functional run "
245
+ "containing a list of 0-based indices"
246
+ " corresponding to outlier volumes" ))
228
247
intensity_files = OutputMultiPath (File (exists = True ),
229
- desc = ("One file for each functional run containing the global "
230
- "intensity values determined from the brainmask" ))
248
+ desc = ("One file for each functional run "
249
+ "containing the global intensity "
250
+ "values determined from the "
251
+ "brainmask" ))
231
252
norm_files = OutputMultiPath (File ,
232
- desc = ("One file for each functional run containing the composite "
233
- "norm" ))
253
+ desc = ("One file for each functional run "
254
+ "containing the composite norm" ))
234
255
statistic_files = OutputMultiPath (File (exists = True ),
235
- desc = ("One file for each functional run containing information "
236
- "about the different types of artifacts and if design info is"
237
- " provided then details of stimulus correlated motion and a "
238
- "listing or artifacts by event type." ))
256
+ desc = ("One file for each functional run "
257
+ "containing information about the "
258
+ "different types of artifacts and "
259
+ "if design info is provided then "
260
+ "details of stimulus correlated "
261
+ "motion and a listing or artifacts "
262
+ "by event type." ))
239
263
plot_files = OutputMultiPath (File ,
240
- desc = ("One image file for each functional run containing the "
241
- "detected outliers" ))
264
+ desc = ("One image file for each functional run "
265
+ "containing the detected outliers" ))
242
266
mask_files = OutputMultiPath (File ,
243
- desc = ("One image file for each functional run containing the mask"
244
- "used for global signal calculation" ))
267
+ desc = ("One image file for each functional run "
268
+ "containing the mask used for global "
269
+ "signal calculation" ))
245
270
displacement_files = OutputMultiPath (File ,
246
- desc = ("One image file for each functional run containing the voxel"
247
- "displacement timeseries" ))
271
+ desc = ("One image file for each "
272
+ "functional run containing the "
273
+ "voxel displacement timeseries" ))
248
274
249
275
250
276
class ArtifactDetect (BaseInterface ):
@@ -314,7 +340,7 @@ def _list_outputs(self):
314
340
outputs ['intensity_files' ] = []
315
341
outputs ['statistic_files' ] = []
316
342
outputs ['mask_files' ] = []
317
- if isdefined (self .inputs .norm_threshold ) :
343
+ if isdefined (self .inputs .use_norm ) and self . inputs . use_norm :
318
344
outputs ['norm_files' ] = []
319
345
if self .inputs .bound_by_brainmask :
320
346
outputs ['displacement_files' ] = []
@@ -328,7 +354,7 @@ def _list_outputs(self):
328
354
outputs ['intensity_files' ].insert (i , intensityfile )
329
355
outputs ['statistic_files' ].insert (i , statsfile )
330
356
outputs ['mask_files' ].insert (i , maskfile )
331
- if isdefined (self .inputs .norm_threshold ) :
357
+ if isdefined (self .inputs .use_norm ) and self . inputs . use_norm :
332
358
outputs ['norm_files' ].insert (i , normfile )
333
359
if self .inputs .bound_by_brainmask :
334
360
outputs ['displacement_files' ].insert (i , displacementfile )
@@ -434,7 +460,7 @@ def _detect_outliers_core(self, imgfile, motionfile, runidx, cwd=None):
434
460
mask_img = Nifti1Image (mask .astype (np .uint8 ), affine )
435
461
mask_img .to_filename (maskfile )
436
462
437
- if isdefined ( self .inputs .norm_threshold ) :
463
+ if self .inputs .use_norm :
438
464
brain_pts = None
439
465
if self .inputs .bound_by_brainmask :
440
466
voxel_coords = np .nonzero (mask )
@@ -477,20 +503,20 @@ def _detect_outliers_core(self, imgfile, motionfile, runidx, cwd=None):
477
503
# write output to outputfile
478
504
np .savetxt (artifactfile , outliers , fmt = b'%d' , delimiter = ' ' )
479
505
np .savetxt (intensityfile , g , fmt = b'%.2f' , delimiter = ' ' )
480
- if isdefined ( self .inputs .norm_threshold ) :
506
+ if self .inputs .use_norm :
481
507
np .savetxt (normfile , normval , fmt = b'%.4f' , delimiter = ' ' )
482
508
483
509
if isdefined (self .inputs .save_plot ) and self .inputs .save_plot :
484
510
import matplotlib
485
511
matplotlib .use (config .get ("execution" , "matplotlib_backend" ))
486
512
import matplotlib .pyplot as plt
487
513
fig = plt .figure ()
488
- if isdefined (self .inputs .norm_threshold ) :
514
+ if isdefined (self .inputs .use_norm ) and self . inputs . use_norm :
489
515
plt .subplot (211 )
490
516
else :
491
517
plt .subplot (311 )
492
518
self ._plot_outliers_with_wave (gz , iidx , 'Intensity' )
493
- if isdefined (self .inputs .norm_threshold ) :
519
+ if isdefined (self .inputs .use_norm ) and self . inputs . use_norm :
494
520
plt .subplot (212 )
495
521
self ._plot_outliers_with_wave (normval , np .union1d (tidx , ridx ),
496
522
'Norm (mm)' )
@@ -515,20 +541,22 @@ def _detect_outliers_core(self, imgfile, motionfile, runidx, cwd=None):
515
541
motion_outliers )),
516
542
'motion_outliers' : len (np .setdiff1d (motion_outliers , iidx )),
517
543
},
518
- {'motion' : [{'using differences' : self .inputs .use_differences [0 ]},
519
- {'mean' : np .mean (mc_in , axis = 0 ).tolist (),
520
- 'min' : np .min (mc_in , axis = 0 ).tolist (),
521
- 'max' : np .max (mc_in , axis = 0 ).tolist (),
522
- 'std' : np .std (mc_in , axis = 0 ).tolist ()},
544
+ {'motion' : [
545
+ {'using differences' : self .inputs .use_differences [0 ]},
546
+ {'mean' : np .mean (mc_in , axis = 0 ).tolist (),
547
+ 'min' : np .min (mc_in , axis = 0 ).tolist (),
548
+ 'max' : np .max (mc_in , axis = 0 ).tolist (),
549
+ 'std' : np .std (mc_in , axis = 0 ).tolist ()},
523
550
]},
524
- {'intensity' : [{'using differences' : self .inputs .use_differences [1 ]},
525
- {'mean' : np .mean (gz , axis = 0 ).tolist (),
526
- 'min' : np .min (gz , axis = 0 ).tolist (),
527
- 'max' : np .max (gz , axis = 0 ).tolist (),
528
- 'std' : np .std (gz , axis = 0 ).tolist ()},
551
+ {'intensity' : [
552
+ {'using differences' : self .inputs .use_differences [1 ]},
553
+ {'mean' : np .mean (gz , axis = 0 ).tolist (),
554
+ 'min' : np .min (gz , axis = 0 ).tolist (),
555
+ 'max' : np .max (gz , axis = 0 ).tolist (),
556
+ 'std' : np .std (gz , axis = 0 ).tolist ()},
529
557
]},
530
558
]
531
- if isdefined ( self .inputs .norm_threshold ) :
559
+ if self .inputs .use_norm :
532
560
stats .insert (3 , {'motion_norm' :
533
561
{'mean' : np .mean (normval , axis = 0 ).tolist (),
534
562
'min' : np .min (normval , axis = 0 ).tolist (),
@@ -549,20 +577,27 @@ def _run_interface(self, runtime):
549
577
550
578
551
579
class StimCorrInputSpec (BaseInterfaceInputSpec ):
552
- realignment_parameters = InputMultiPath (File (exists = True ), mandatory = True ,
553
- desc = ('Names of realignment parameters corresponding to the functional '
554
- 'data files' ))
555
- intensity_values = InputMultiPath (File (exists = True ), mandatory = True ,
556
- desc = 'Name of file containing intensity values' )
557
- spm_mat_file = File (exists = True , mandatory = True ,
558
- desc = 'SPM mat file (use pre-estimate SPM.mat file)' )
580
+ realignment_parameters = InputMultiPath (File (exists = True ),
581
+ mandatory = True ,
582
+ desc = ("Names of realignment "
583
+ "parameters corresponding to "
584
+ "the functional data files" ))
585
+ intensity_values = InputMultiPath (File (exists = True ),
586
+ mandatory = True ,
587
+ desc = ("Name of file containing intensity "
588
+ "values" ))
589
+ spm_mat_file = File (exists = True ,
590
+ mandatory = True ,
591
+ desc = "SPM mat file (use pre-estimate SPM.mat file)" )
559
592
concatenated_design = traits .Bool (mandatory = True ,
560
- desc = 'state if the design matrix contains concatenated sessions' )
593
+ desc = ("state if the design matrix "
594
+ "contains concatenated sessions" )
561
595
562
596
563
597
class StimCorrOutputSpec (TraitedSpec ):
564
598
stimcorr_files = OutputMultiPath (File (exists = True ),
565
- desc = 'List of files containing correlation values' )
599
+ desc = ("List of files containing "
600
+ "correlation values" )
566
601
567
602
568
603
class StimulusCorrelation (BaseInterface ):
@@ -572,8 +607,9 @@ class StimulusCorrelation(BaseInterface):
572
607
Currently this class supports an SPM generated design matrix and requires
573
608
intensity parameters. This implies that one must run
574
609
:ref:`ArtifactDetect <nipype.algorithms.rapidart.ArtifactDetect>`
575
- and :ref:`Level1Design <nipype.interfaces.spm.model.Level1Design>` prior to running this or
576
- provide an SPM.mat file and intensity parameters through some other means.
610
+ and :ref:`Level1Design <nipype.interfaces.spm.model.Level1Design>` prior to
611
+ running this or provide an SPM.mat file and intensity parameters through
612
+ some other means.
577
613
578
614
Examples
579
615
--------
@@ -649,7 +685,8 @@ def _get_spm_submatrix(self, spmmat, sessidx, rows=None):
649
685
U = spmmat ['SPM' ][0 ][0 ].Sess [0 ][sessidx ].U [0 ]
650
686
if rows is None :
651
687
rows = spmmat ['SPM' ][0 ][0 ].Sess [0 ][sessidx ].row [0 ] - 1
652
- cols = spmmat ['SPM' ][0 ][0 ].Sess [0 ][sessidx ].col [0 ][list (range (len (U )))] - 1
688
+ cols = (
689
+ spmmat ['SPM' ][0 ][0 ].Sess [0 ][sessidx ].col [0 ][list (range (len (U )))]- 1 )
653
690
outmatrix = designmatrix .take (rows .tolist (), axis = 0 ).take (cols .tolist (),
654
691
axis = 1 )
655
692
return outmatrix
0 commit comments