1313 >>> os.chdir(datadir)
1414"""
1515from __future__ import print_function , division , unicode_literals , absolute_import
16- from builtins import str , bytes
1716
1817import os
19- import os .path as op
20- import re
21- import numpy as np
2218
23- from ...utils .filemanip import (load_json , save_json , split_filename )
2419from ..base import (
2520 CommandLineInputSpec , CommandLine , Directory , TraitedSpec ,
2621 traits , isdefined , File , InputMultiPath , Undefined , Str )
@@ -33,133 +28,161 @@ class DeconvolveInputSpec(AFNICommandInputSpec):
3328 in_files = InputMultiPath (
3429 File (
3530 exists = True ),
36- desc = 'fname = filename of 3D+time input dataset '
37- ' [more than one filename can be given] '
38- ' here, and these datasets will be] '
39- ' [auto-catenated in time; if you do this,] '
40- ' [\' -concat\' is not needed and is ignored.] '
41- '** You can input a 1D time series file here, '
42- ' but the time axis should run along the '
43- ' ROW direction, not the COLUMN direction as '
44- ' in the -input1D option. You can automatically '
45- ' transpose a 1D file on input using the \\ \' '
46- ' operator at the end of the filename, as in '
47- ' -input fred.1D\\ \' '
48- ' * This is the only way to use 3dDeconvolve '
49- ' with a multi-column 1D time series file.' ,
31+ desc = 'Filenames of 3D+time input datasets. More than one filename can '
32+ 'be given and the datasets will be auto-catenated in time. '
33+ 'You can input a 1D time series file here, but the time axis '
34+ 'should run along the ROW direction, not the COLUMN direction as '
35+ 'in the \' input1D\' option.' ,
5036 argstr = '-input %s' ,
5137 mandatory = True ,
52- copyfile = False )
38+ copyfile = False ,
39+ sep = " " )
40+ sat = traits .Bool (
41+ desc = 'Check the dataset time series for initial saturation transients,'
42+ ' which should normally have been excised before data analysis.' ,
43+ argstr = '-sat' ,
44+ xor = ['trans' ])
45+ trans = traits .Bool (
46+ desc = 'Check the dataset time series for initial saturation transients,'
47+ ' which should normally have been excised before data analysis.' ,
48+ argstr = '-trans' ,
49+ xor = ['sat' ])
50+ noblock = traits .Bool (
51+ desc = 'Normally, if you input multiple datasets with \' input\' , then '
52+ 'the separate datasets are taken to be separate image runs that '
53+ 'get separate baseline models. Use this options if you want to '
54+ 'have the program consider these to be all one big run.'
55+ '* If any of the input dataset has only 1 sub-brick, then this '
56+ 'option is automatically invoked!'
57+ '* If the auto-catenation feature isn\' t used, then this option '
58+ 'has no effect, no how, no way.' ,
59+ argstr = '-noblock' )
60+ force_TR = traits .Int (
61+ desc = 'Use this value of TR instead of the one in the \' input\' '
62+ 'dataset. (It\' s better to fix the input using 3drefit.)' ,
63+ argstr = '-force_TR %d' )
64+ input1D = File (
65+ desc = 'Filename of single (fMRI) .1D time series where time runs down '
66+ 'the column.' ,
67+ argstr = '-input1D %s' ,
68+ exists = True )
69+ TR_1D = traits .Float (
70+ desc = 'TR to use with \' input1D\' . This option has no effect if you do '
71+ 'not also use \' input1D\' .' ,
72+ argstr = '-TR_1D %f' )
73+ legendre = traits .Bool (
74+ desc = 'Use Legendre polynomials for null hypothesis (baseline model)' ,
75+ argstr = '-legendre' )
76+ nolegendre = traits .Bool (
77+ desc = 'Use power polynomials for null hypotheses. Don\' t do this '
78+ 'unless you are crazy!' ,
79+ argstr = '-nolegendre' )
5380 mask = File (
54- desc = 'filename of 3D mask dataset; '
55- 'Only data time series from within the mask '
56- 'will be analyzed; results for voxels outside '
57- 'the mask will be set to zero.' ,
81+ desc = 'Filename of 3D mask dataset; only data time series from within '
82+ 'the mask will be analyzed; results for voxels outside the mask '
83+ 'will be set to zero.' ,
5884 argstr = '-mask %s' ,
5985 exists = True )
6086 automask = traits .Bool (
61- usedefault = True ,
62- argstr = '-automask' ,
63- desc = 'Build a mask automatically from input data '
64- '(will be slow for long time series datasets)' )
87+ desc = 'Build a mask automatically from input data (will be slow for '
88+ 'long time series datasets)' ,
89+ argstr = '-automask' )
6590 censor = File (
66- desc = ' cname = filename of censor .1D time series '
67- '* This is a file of 1s and 0s, indicating which '
68- ' time points are to be included (1) and which are '
69- ' to be excluded (0). '
70- '* Option \' -censor\' can only be used once!' ,
91+ desc = 'Filename of censor .1D time series. This is a file of 1s and 0s, '
92+ 'indicating which time points are to be included (1) and which '
93+ 'are to be excluded (0).' ,
7194 argstr = '-censor %s' ,
7295 exists = True )
7396 polort = traits .Int (
74- desc = 'pnum = degree of polynomial corresponding to the '
75- ' null hypothesis [default: pnum = 1]' ,
97+ desc = 'Degree of polynomial corresponding to the null hypothesis '
98+ '[default: 1]' ,
7699 argstr = '-polort %d' )
77100 ortvec = traits .Tuple (
78101 File (
79102 desc = 'filename' ,
80103 exists = True ),
81104 Str (
82105 desc = 'label' ),
83- desc = 'This option lets you input a rectangular array '
84- 'of 1 or more baseline vectors from file \' fff\' , '
85- 'which will get the label \' lll\' . Functionally, '
86- 'it is the same as using \' -stim_file\' on each '
87- 'column of \' fff\' separately (plus \' -stim_base\' ). '
88- 'This method is just a faster and simpler way to '
106+ desc = 'This option lets you input a rectangular array of 1 or more '
107+ 'baseline vectors from a file. This method is a fast way to '
89108 'include a lot of baseline regressors in one step. ' ,
90109 argstr = 'ortvec %s' )
91- x1d = File (
92- desc = 'save out X matrix' ,
110+ x1D = File (
111+ desc = 'Save out X matrix' ,
93112 argstr = '-x1D %s' )
94- x1d_stop = traits .Bool (
95- desc = 'stop running after writing .xmat.1D file' ,
113+ x1D_stop = traits .Bool (
114+ desc = 'Stop running after writing .xmat.1D file' ,
96115 argstr = '-x1D_stop' )
97- bucket = File (
98- desc = 'output statistics file' ,
116+ out_file = File (
117+ 'bucket.nii' ,
118+ desc = 'Output statistics file' ,
99119 argstr = '-bucket %s' )
100120 jobs = traits .Int (
101- desc = 'run the program with given number of sub-processes' ,
121+ desc = 'Run the program with provided number of sub-processes' ,
102122 argstr = '-jobs %d' )
103- stim_times_subtract = traits .Float (
104- desc = 'This option means to subtract \' SS\' seconds from each time '
105- 'encountered in any \' -stim_times*\' option. The purpose of this '
106- 'option is to make it simple to adjust timing files for the '
107- 'removal of images from the start of each imaging run.' ,
108- argstr = '-stim_times_subtract %f' )
109- num_stimts = traits .Int (
110- desc = 'number of stimulus timing files' ,
111- argstr = '-num_stimts %d' )
112- num_glt = traits .Int (
113- desc = 'number of general linear tests (i.e., contrasts)' ,
114- argstr = '-num_glt %d' )
115- global_times = traits .Bool (
116- desc = 'use global timing for stimulus timing files' ,
117- argstr = '-global_times' ,
118- xor = ['local_times' ])
119- local_times = traits .Bool (
120- desc = 'use local timing for stimulus timing files' ,
121- argstr = '-local_times' ,
122- xor = ['global_times' ])
123123 fout = traits .Bool (
124- desc = 'output F-statistic for each stimulus' ,
124+ desc = 'Output F-statistic for each stimulus' ,
125125 argstr = '-fout' )
126126 rout = traits .Bool (
127- desc = 'output the R^2 statistic for each stimulus' ,
127+ desc = 'Output the R^2 statistic for each stimulus' ,
128128 argstr = '-rout' )
129129 tout = traits .Bool (
130- desc = 'output the T-statistic for each stimulus' ,
130+ desc = 'Output the T-statistic for each stimulus' ,
131131 argstr = '-tout' )
132132 vout = traits .Bool (
133- desc = 'output the sample variance (MSE) for each stimulus' ,
133+ desc = 'Output the sample variance (MSE) for each stimulus' ,
134134 argstr = '-vout' )
135+ global_times = traits .Bool (
136+ desc = 'Use global timing for stimulus timing files' ,
137+ argstr = '-global_times' ,
138+ xor = ['local_times' ])
139+ local_times = traits .Bool (
140+ desc = 'Use local timing for stimulus timing files' ,
141+ argstr = '-local_times' ,
142+ xor = ['global_times' ])
143+ num_stimts = traits .Int (
144+ desc = 'Number of stimulus timing files' ,
145+ argstr = '-num_stimts %d' ,
146+ position = 0 )
135147 stim_times = traits .List (
136148 traits .Tuple (traits .Int (desc = 'k-th response model' ),
137149 File (desc = 'stimulus timing file' ,exists = True ),
138150 Str (desc = 'model' )),
139- desc = 'Generate the k-th response model from a set of stimulus times'
140- ' given in file \' tname \' .' ,
141- argstr = '-stim_times %d %s %s' )
151+ desc = 'Generate a response model from a set of stimulus times'
152+ ' given in file.' ,
153+ argstr = '-stim_times %d %s %s... ' )
142154 stim_label = traits .List (
143155 traits .Tuple (traits .Int (desc = 'k-th input stimulus' ),
144156 Str (desc = 'stimulus label' )),
145- desc = 'label for kth input stimulus' ,
146- argstr = '-stim_label %d %s' ,
157+ desc = 'Label for kth input stimulus' ,
158+ argstr = '-stim_label %d %s... ' ,
147159 requires = ['stim_times' ])
160+ stim_times_subtract = traits .Float (
161+ desc = 'This option means to subtract specified seconds from each time '
162+ 'encountered in any \' stim_times\' option. The purpose of this '
163+ 'option is to make it simple to adjust timing files for the '
164+ 'removal of images from the start of each imaging run.' ,
165+ argstr = '-stim_times_subtract %f' )
166+ num_glt = traits .Int (
167+ desc = 'Number of general linear tests (i.e., contrasts)' ,
168+ argstr = '-num_glt %d' ,
169+ position = 1 )
148170 gltsym = traits .List (
149171 Str (desc = 'symbolic general linear test' ),
150- desc = 'general linear tests (i.e., contrasts) using symbolic '
151- 'conventions' ,
152- argstr = '-gltsym %s ' )
153- glt_labels = traits .List (
172+ desc = 'General linear tests (i.e., contrasts) using symbolic '
173+ 'conventions (e.g., \' +Label1 -Label2 \' ) ' ,
174+ argstr = '-gltsym SYM: %s... ' )
175+ glt_label = traits .List (
154176 traits .Tuple (traits .Int (desc = 'k-th general linear test' ),
155177 Str (desc = 'GLT label' )),
156- desc = 'general linear test (i.e., contrast) labels' ,
157- argstr = '-glt_label %d %s' ,
158- requires = ['glt_sym ' ])
178+ desc = 'General linear test (i.e., contrast) labels' ,
179+ argstr = '-glt_label %d %s... ' ,
180+ requires = ['gltsym ' ])
159181
160182
161- class DeconvolveOutputSpec (TraitedSpec ):
162- pass
183+ class DeconvolveOutputSpec (AFNICommandOutputSpec ):
184+ out_file = File (desc = 'output statistics file' ,
185+ exists = True )
163186
164187
165188class Deconvolve (AFNICommand ):
@@ -173,20 +196,32 @@ class Deconvolve(AFNICommand):
173196
174197 >>> from nipype.interfaces import afni
175198 >>> deconvolve = afni.Deconvolve()
176- >>> deconvolve.inputs.in_file = 'functional.nii'
177- >>> deconvolve.inputs.bucket = 'output.nii'
199+ >>> deconvolve.inputs.in_files = [ 'functional.nii', 'functional2.nii']
200+ >>> deconvolve.inputs.out_file = 'output.nii'
178201 >>> deconvolve.inputs.x1D = 'output.1D'
179- >>> stim_times = [(1, 'stims1 .txt', 'SPMG1(4)'), (2, 'stims2 .txt', 'SPMG2(4)')]
202+ >>> stim_times = [(1, 'timeseries .txt', 'SPMG1(4)'), (2, 'timeseries .txt', 'SPMG2(4)')]
180203 >>> deconvolve.inputs.stim_times = stim_times
204+ >>> deconvolve.inputs.stim_label = [(1, 'Houses'), (2, 'Apartments')]
205+ >>> deconvolve.inputs.gltsym = [('SYM: +Houses -Apartments')]
206+ >>> deconvolve.inputs.glt_label = [(1, 'Houses-Apartments')]
181207 >>> deconvolve.cmdline # doctest: +ALLOW_UNICODE
182- '3dDeconvolve -input functional.nii -bucket output.nii -x1D output - stim_times 1 stims1 .txt SPMG1(4) 2 stims2 .txt SPMG2(4)'
208+ '3dDeconvolve -num_stimts 2 -num_glt 1 -glt_label 1 Houses_Apartments -gltsym SYM: +Houses -Apartments - input functional.nii functional2.nii -bucket output.nii -stim_label 1 Houses -stim_label 2 Apartments - stim_times 1 timeseries .txt SPMG1(4) -stim_times 2 timeseries .txt SPMG2(4) -x1D output.1D '
183209 >>> res = deconvolve.run() # doctest: +SKIP
184210 """
185211
186212 _cmd = '3dDeconvolve'
187213 input_spec = DeconvolveInputSpec
188214 output_spec = AFNICommandOutputSpec
189215
216+ def _parse_inputs (self , skip = None ):
217+ if skip is None :
218+ skip = []
219+ if len (self .inputs .stim_times ) and not isdefined (self .inputs .num_stimts ):
220+ self .inputs .num_stimts = len (self .inputs .stim_times )
221+ if len (self .inputs .gltsym ) and not isdefined (self .inputs .num_glt ):
222+ self .inputs .num_glt = len (self .inputs .gltsym )
223+ return super (Deconvolve , self )._parse_inputs (skip )
224+
190225 def _list_outputs (self ):
191226 outputs = self .output_spec ().get ()
192227 if isdefined (self .inputs .x1D ):
@@ -195,23 +230,5 @@ def _list_outputs(self):
195230 else :
196231 outputs ['x1D' ] = self .inputs .x1D
197232
198- outputs ['bucket ' ] = self .inputs .bucket
233+ outputs ['out_file ' ] = self .inputs .out_file
199234 return outputs
200-
201- def _format_arg (self , name , trait_spec , value ):
202- """
203- Argument num_glt is defined automatically from the number of contrasts
204- desired (defined by the length of glt_sym). No effort has been made to
205- make this compatible with glt.
206- """
207- if name in ['stim_times' , 'stim_labels' ]:
208- arg = ''
209- for st in value :
210- arg += trait_spec .argstr % value
211- arg = arg .rstrip ()
212- return arg
213-
214- if name == 'stim_times' :
215- self .inputs .num_stimts = len (value )
216- elif name == 'glt_sym' :
217- self .inputs .num_glt = len (value )
0 commit comments