@@ -329,3 +329,78 @@ def _list_outputs(self):
329
329
outputs ['output_image' ] = os .path .abspath (
330
330
self ._gen_filename ('output_image' ))
331
331
return outputs
332
+
333
+
334
+ class ApplyTransformsToPointsInputSpec (ANTSCommandInputSpec ):
335
+ dimension = traits .Enum (2 , 3 , 4 , argstr = '--dimensionality %d' ,
336
+ desc = ('This option forces the image to be treated '
337
+ 'as a specified-dimensional image. If not '
338
+ 'specified, antsWarp tries to infer the '
339
+ 'dimensionality from the input image.' ))
340
+ input_file = File (argstr = '--input %s' , mandatory = True ,
341
+ desc = ("Currently, the only input supported is a csv file with "
342
+ "columns including x,y (2D), x,y,z (3D) or x,y,z,t,label (4D) column headers."
343
+ "The points should be defined in physical space."
344
+ "If in doubt how to convert coordinates from your files to the space"
345
+ "required by antsApplyTransformsToPoints try creating/drawing a simple"
346
+ "label volume with only one voxel set to 1 and all others set to 0."
347
+ "Write down the voxel coordinates. Then use ImageMaths LabelStats to find"
348
+ "out what coordinates for this voxel antsApplyTransformsToPoints is"
349
+ "expecting." ),
350
+ exists = True )
351
+ output_file = traits .Str (argstr = '--output %s' ,
352
+ desc = ('Name of the output CSV file' ), name_source = ['input_file' ],
353
+ hash_files = False , name_template = '%s_transformed.csv' )
354
+ transforms = traits .List (File (exists = True ), argstr = '%s' , mandatory = True ,
355
+ desc = ('transforms that will be applied to the points' ))
356
+ invert_transform_flags = traits .List (traits .Bool (),
357
+ desc = ('list indicating if a transform should be reversed' ))
358
+
359
+
360
+ class ApplyTransformsToPointsOutputSpec (TraitedSpec ):
361
+ output_file = File (exists = True , desc = 'csv file with transformed coordinates' )
362
+
363
+
364
+ class ApplyTransformsToPoints (ANTSCommand ):
365
+ """ApplyTransformsToPoints, applied to an CSV file, transforms coordinates
366
+ using provided transform (or a set of transforms).
367
+
368
+ Examples
369
+ --------
370
+
371
+ >>> from nipype.interfaces.ants import ApplyTransforms
372
+ >>> at = ApplyTransformsToPoints()
373
+ >>> at.inputs.dimension = 3
374
+ >>> at.inputs.input_file = 'moving.csv'
375
+ >>> at.inputs.transforms = ['trans.mat', 'ants_Warp.nii.gz']
376
+ >>> at.inputs.invert_transform_flags = [False, False]
377
+ >>> at.cmdline
378
+ 'antsApplyTransformsToPoints --dimensionality 3 --input moving.csv --output moving_transformed.csv --transform [trans.mat,0] --transform [ants_Warp.nii.gz,0]'
379
+
380
+
381
+ """
382
+ _cmd = 'antsApplyTransformsToPoints'
383
+ input_spec = ApplyTransformsToPointsInputSpec
384
+ output_spec = ApplyTransformsToPointsOutputSpec
385
+
386
+
387
+ def _getTransformFileNames (self ):
388
+ retval = []
389
+ for ii in range (len (self .inputs .transforms )):
390
+ if isdefined (self .inputs .invert_transform_flags ):
391
+ if len (self .inputs .transforms ) == len (self .inputs .invert_transform_flags ):
392
+ invert_code = 1 if self .inputs .invert_transform_flags [
393
+ ii ] else 0
394
+ retval .append ("--transform [%s,%d]" %
395
+ (self .inputs .transforms [ii ], invert_code ))
396
+ else :
397
+ raise Exception ("ERROR: The useInverse list must have the same number of entries as the transformsFileName list." )
398
+ else :
399
+ retval .append ("--transform %s" % self .inputs .transforms [ii ])
400
+ return " " .join (retval )
401
+
402
+ def _format_arg (self , opt , spec , val ):
403
+ if opt == "transforms" :
404
+ return self ._getTransformFileNames ()
405
+ return super (ApplyTransformsToPoints , self )._format_arg (opt , spec , val )
406
+
0 commit comments