@@ -23,21 +23,35 @@ class Dcm2niiInputSpec(CommandLineInputSpec):
23
23
copyfile = False , mandatory = True , xor = ['source_dir' ])
24
24
source_dir = Directory (exists = True , argstr = "%s" , position = - 1 , mandatory = True ,
25
25
xor = ['source_names' ])
26
- anonymize = traits .Bool (True , argstr = '-a' , usedefault = True )
27
- config_file = File (exists = True , argstr = "-b %s" , genfile = True )
28
- collapse_folders = traits .Bool (True , argstr = '-c' , usedefault = True )
29
- date_in_filename = traits .Bool (True , argstr = '-d' , usedefault = True )
30
- events_in_filename = traits .Bool (True , argstr = '-e' , usedefault = True )
31
- source_in_filename = traits .Bool (False , argstr = '-f' , usedefault = True )
32
- gzip_output = traits .Bool (False , argstr = '-g' , usedefault = True )
33
- id_in_filename = traits .Bool (False , argstr = '-i' , usedefault = True )
34
- nii_output = traits .Bool (True , argstr = '-n' , usedefault = True )
35
- output_dir = Directory (exists = True , argstr = '-o %s' , genfile = True )
36
- protocol_in_filename = traits .Bool (True , argstr = '-p' , usedefault = True )
37
- reorient = traits .Bool (argstr = '-r' )
38
- spm_analyze = traits .Bool (argstr = '-s' , xor = ['nii_output' ])
39
- convert_all_pars = traits .Bool (True , argstr = '-v' , usedefault = True )
40
- reorient_and_crop = traits .Bool (False , argstr = '-x' , usedefault = True )
26
+ anonymize = traits .Bool (True , argstr = '-a' , usedefault = True ,
27
+ desc = "Remove identifying information" )
28
+ config_file = File (exists = True , argstr = "-b %s" , genfile = True ,
29
+ desc = "Load settings from specified inifile" )
30
+ collapse_folders = traits .Bool (True , argstr = '-c' , usedefault = True ,
31
+ desc = "Collapse input folders" )
32
+ date_in_filename = traits .Bool (True , argstr = '-d' , usedefault = True ,
33
+ desc = "Date in filename" )
34
+ events_in_filename = traits .Bool (True , argstr = '-e' , usedefault = True ,
35
+ desc = "Events (series/acq) in filename" )
36
+ source_in_filename = traits .Bool (False , argstr = '-f' , usedefault = True ,
37
+ desc = "Source filename" )
38
+ gzip_output = traits .Bool (False , argstr = '-g' , usedefault = True ,
39
+ desc = "Gzip output (.gz)" )
40
+ id_in_filename = traits .Bool (False , argstr = '-i' , usedefault = True ,
41
+ desc = "ID in filename" )
42
+ nii_output = traits .Bool (True , argstr = '-n' , usedefault = True ,
43
+ desc = "Save as .nii - if no, create .hdr/.img pair" )
44
+ output_dir = Directory (exists = True , argstr = '-o %s' , genfile = True ,
45
+ desc = "Output dir - if unspecified, source directory is used" )
46
+ protocol_in_filename = traits .Bool (True , argstr = '-p' , usedefault = True ,
47
+ desc = "Protocol in filename" )
48
+ reorient = traits .Bool (argstr = '-r' , desc = "Reorient image to nearest orthogonal" )
49
+ spm_analyze = traits .Bool (argstr = '-s' , xor = ['nii_output' ],
50
+ desc = "SPM2/Analyze not SPM5/NIfTI" )
51
+ convert_all_pars = traits .Bool (True , argstr = '-v' , usedefault = True ,
52
+ desc = "Convert every image in directory" )
53
+ reorient_and_crop = traits .Bool (False , argstr = '-x' , usedefault = True ,
54
+ desc = "Reorient and crop 3D images" )
41
55
42
56
43
57
class Dcm2niiOutputSpec (TraitedSpec ):
@@ -185,3 +199,125 @@ def _gen_filename(self, name):
185
199
f .close ()
186
200
return config_file
187
201
return None
202
+
203
+
204
+ class Dcm2niixInputSpec (CommandLineInputSpec ):
205
+ source_names = InputMultiPath (File (exists = True ), argstr = "%s" , position = - 1 ,
206
+ copyfile = False , mandatory = True , xor = ['source_dir' ])
207
+ source_dir = Directory (exists = True , argstr = "%s" , position = - 1 , mandatory = True ,
208
+ xor = ['source_names' ])
209
+ out_filename = traits .Str ('%t%p' , argstr = "-f %s" , usedefault = True ,
210
+ desc = "Output filename" )
211
+ output_dir = Directory (exists = True , argstr = '-o %s' , genfile = True ,
212
+ desc = "Output directory" )
213
+ bids_format = traits .Bool (True , argstr = '-b' , usedefault = True ,
214
+ desc = "Create a BIDS sidecar file" )
215
+ compress = traits .Enum ('i' , ['y' ,'i' ,'n' ], argstr = '-z %s' , usedefault = True ,
216
+ desc = "Gzip compress images - [y=pigz, i=internal, n=no]" )
217
+ merge_imgs = traits .Bool (False , argstr = '-m' , usedefault = True ,
218
+ desc = "merge 2D slices from same series" )
219
+ single_file = traits .Bool (False , argstr = '-s' , usedefault = True ,
220
+ desc = "Convert only one image (filename as last input" )
221
+ verbose = traits .Bool (False , argstr = '-v' , usedefault = True ,
222
+ desc = "Verbose output" )
223
+
224
+
225
+ class Dcm2niixOutputSpec (TraitedSpec ):
226
+ converted_files = OutputMultiPath (File (exists = True ))
227
+ bvecs = OutputMultiPath (File (exists = True ))
228
+ bvals = OutputMultiPath (File (exists = True ))
229
+ bids = OutputMultiPath (File (exists = True ))
230
+
231
+
232
+ class Dcm2niix (CommandLine ):
233
+ """Uses Chris Rorden's dcm2niix to convert dicom files
234
+ Examples
235
+ ========
236
+ >>> from nipype.interfaces.dcm2nii import Dcm2niix
237
+ >>> converter = Dcm2niix()
238
+ >>> converter.inputs.source_names = ['functional_1.dcm', 'functional_2.dcm']
239
+ >>> converter.inputs.compress = 'i'
240
+ >>> converter.inputs.single_file = True
241
+ >>> converter.inputs.output_dir = '.'
242
+ >>> converter.cmdline
243
+ 'dcm2niix -b y -z i -m n -f %t%p -o . -s y -v n functional_1.dcm'
244
+ """
245
+
246
+ input_spec = Dcm2niixInputSpec
247
+ output_spec = Dcm2niixOutputSpec
248
+ _cmd = 'dcm2niix'
249
+
250
+ def _format_arg (self , opt , spec , val ):
251
+ if opt in ['bids_format' , 'merge_imgs' , 'single_file' , 'verbose' ]:
252
+ spec = deepcopy (spec )
253
+ if val :
254
+ spec .argstr += ' y'
255
+ else :
256
+ spec .argstr += ' n'
257
+ val = True
258
+ if opt == 'source_names' :
259
+ return spec .argstr % val [0 ]
260
+ return super (Dcm2niix , self )._format_arg (opt , spec , val )
261
+
262
+ def _run_interface (self , runtime ):
263
+ new_runtime = super (Dcm2niix , self )._run_interface (runtime )
264
+ if self .inputs .bids_format :
265
+ (self .output_files , self .bvecs ,
266
+ self .bvals , self .bids ) = self ._parse_stdout (new_runtime .stdout )
267
+ else :
268
+ (self .output_files , self .bvecs ,
269
+ self .bvals ) = self ._parse_stdout (new_runtime .stdout )
270
+ return new_runtime
271
+
272
+ def _parse_stdout (self , stdout ):
273
+ files = []
274
+ bvecs = []
275
+ bvals = []
276
+ bids = []
277
+ skip = False
278
+ find_b = False
279
+ for line in stdout .split ("\n " ):
280
+ if not skip :
281
+ out_file = None
282
+ if line .startswith ("Convert " ): # output
283
+ fname = str (re .search ('\S+/\S+' , line ).group (0 ))
284
+ if isdefined (self .inputs .output_dir ):
285
+ output_dir = self .inputs .output_dir
286
+ else :
287
+ output_dir = self ._gen_filename ('output_dir' )
288
+ out_file = os .path .abspath (os .path .join (output_dir , fname ))
289
+ # extract bvals
290
+ if find_b :
291
+ bvecs .append (out_file + ".bvec" )
292
+ bvals .append (out_file + ".bval" )
293
+ find_b = False
294
+ # next scan will have bvals/bvecs
295
+ elif 'DTI gradient directions' in line :
296
+ find_b = True
297
+ else :
298
+ pass
299
+ if out_file :
300
+ files .append (out_file + ".nii.gz" )
301
+ if self .inputs .bids_format :
302
+ bids .append (out_file + ".bids" )
303
+ continue
304
+ skip = False
305
+ # just return what was done
306
+ if not bids :
307
+ return files , bvecs , bvals
308
+ else :
309
+ return files , bvecs , bvals , bids
310
+
311
+ def _list_outputs (self ):
312
+ outputs = self .output_spec ().get ()
313
+ outputs ['converted_files' ] = self .output_files
314
+ outputs ['bvecs' ] = self .bvecs
315
+ outputs ['bvals' ] = self .bvals
316
+ if self .inputs .bids_format :
317
+ outputs ['bids' ] = self .bids
318
+ return outputs
319
+
320
+ def _gen_filename (self , name ):
321
+ if name == 'output_dir' :
322
+ return os .getcwd ()
323
+ return None
0 commit comments