@@ -112,6 +112,10 @@ def __invert__(self):
112
112
113
113
"""
114
114
return self .__class__ (self ._inverse )
115
+
116
+ def __len__ (self ):
117
+ """Enable using len()."""
118
+ return 1 if self ._matrix .ndim == 2 else len (self ._matrix )
115
119
116
120
def __matmul__ (self , b ):
117
121
"""
@@ -330,10 +334,6 @@ def __getitem__(self, i):
330
334
"""Enable indexed access to the series of matrices."""
331
335
return Affine (self .matrix [i , ...], reference = self ._reference )
332
336
333
- def __len__ (self ):
334
- """Enable using len()."""
335
- return len (self ._matrix )
336
-
337
337
def map (self , x , inverse = False ):
338
338
r"""
339
339
Apply :math:`y = f(x)`.
@@ -402,119 +402,6 @@ def to_filename(self, filename, fmt="X5", moving=None):
402
402
).to_filename (filename )
403
403
return filename
404
404
405
- def apply (
406
- self ,
407
- spatialimage ,
408
- reference = None ,
409
- order = 3 ,
410
- mode = "constant" ,
411
- cval = 0.0 ,
412
- prefilter = True ,
413
- output_dtype = None ,
414
- ):
415
- """
416
- Apply a transformation to an image, resampling on the reference spatial object.
417
-
418
- Parameters
419
- ----------
420
- spatialimage : `spatialimage`
421
- The image object containing the data to be resampled in reference
422
- space
423
- reference : spatial object, optional
424
- The image, surface, or combination thereof containing the coordinates
425
- of samples that will be sampled.
426
- order : int, optional
427
- The order of the spline interpolation, default is 3.
428
- The order has to be in the range 0-5.
429
- mode : {"constant", "reflect", "nearest", "mirror", "wrap"}, optional
430
- Determines how the input image is extended when the resamplings overflows
431
- a border. Default is "constant".
432
- cval : float, optional
433
- Constant value for ``mode="constant"``. Default is 0.0.
434
- prefilter: bool, optional
435
- Determines if the image's data array is prefiltered with
436
- a spline filter before interpolation. The default is ``True``,
437
- which will create a temporary *float64* array of filtered values
438
- if *order > 1*. If setting this to ``False``, the output will be
439
- slightly blurred if *order > 1*, unless the input is prefiltered,
440
- i.e. it is the result of calling the spline filter on the original
441
- input.
442
-
443
- Returns
444
- -------
445
- resampled : `spatialimage` or ndarray
446
- The data imaged after resampling to reference space.
447
-
448
- """
449
-
450
- if reference is not None and isinstance (reference , (str , Path )):
451
- reference = _nbload (str (reference ))
452
-
453
- _ref = (
454
- self .reference if reference is None else SpatialReference .factory (reference )
455
- )
456
-
457
- if isinstance (spatialimage , (str , Path )):
458
- spatialimage = _nbload (str (spatialimage ))
459
-
460
- # Avoid opening the data array just yet
461
- input_dtype = get_obj_dtype (spatialimage .dataobj )
462
- output_dtype = output_dtype or input_dtype
463
-
464
- # Prepare physical coordinates of input (grid, points)
465
- xcoords = _ref .ndcoords .astype ("f4" ).T
466
-
467
- # Invert target's (moving) affine once
468
- ras2vox = ~ Affine (spatialimage .affine )
469
-
470
- if spatialimage .ndim == 4 and (len (self ) != spatialimage .shape [- 1 ]):
471
- raise ValueError (
472
- "Attempting to apply %d transforms on a file with "
473
- "%d timepoints" % (len (self ), spatialimage .shape [- 1 ])
474
- )
475
-
476
- # Order F ensures individual volumes are contiguous in memory
477
- # Also matches NIfTI, making final save more efficient
478
- resampled = np .zeros (
479
- (xcoords .shape [0 ], len (self )), dtype = output_dtype , order = "F"
480
- )
481
-
482
- dataobj = (
483
- np .asanyarray (spatialimage .dataobj , dtype = input_dtype )
484
- if spatialimage .ndim in (2 , 3 )
485
- else None
486
- )
487
-
488
- for t , xfm_t in enumerate (self ):
489
- # Map the input coordinates on to timepoint t of the target (moving)
490
- ycoords = xfm_t .map (xcoords )[..., : _ref .ndim ]
491
-
492
- # Calculate corresponding voxel coordinates
493
- yvoxels = ras2vox .map (ycoords )[..., : _ref .ndim ]
494
-
495
- # Interpolate
496
- resampled [..., t ] = ndi .map_coordinates (
497
- (
498
- dataobj
499
- if dataobj is not None
500
- else spatialimage .dataobj [..., t ].astype (input_dtype , copy = False )
501
- ),
502
- yvoxels .T ,
503
- output = output_dtype ,
504
- order = order ,
505
- mode = mode ,
506
- cval = cval ,
507
- prefilter = prefilter ,
508
- )
509
-
510
- if isinstance (_ref , ImageGrid ): # If reference is grid, reshape
511
- newdata = resampled .reshape (_ref .shape + (len (self ),))
512
- moved = spatialimage .__class__ (newdata , _ref .affine , spatialimage .header )
513
- moved .header .set_data_dtype (output_dtype )
514
- return moved
515
-
516
- return resampled
517
-
518
405
519
406
def load (filename , fmt = None , reference = None , moving = None ):
520
407
"""
0 commit comments