Source code for castalign.ndarray_shifted

import numpy as np

[docs] class ndarray_shifted(np.ndarray): """NumPy ndarray with an attached origin offset in 3D space. This is used to carry array data together with a spatial origin so image coordinates can be interpreted in a shared 3D coordinate system without copying data into a separate wrapper object. Notes ----- The ``origin`` attribute stores a coordinate offset (typically ``[z, y, x]``). Array behavior is otherwise the same as ``numpy.ndarray``. See Also -------- castalign.utils.absolute_coords_to_voxel_coords Convert absolute coordinates to voxel indices using ``origin``. castalign.utils.voxel_coords_to_absolute_coords Convert voxel indices back to absolute coordinates. castalign.utils.crop_to_intersection Crop two shifted volumes to a shared overlapping field of view. Examples -------- Create a shifted 3D array:: >>> arr = ndarray_shifted(np.zeros((4, 5, 6)), origin=[10, 20, 30]) >>> isinstance(arr, ndarray_shifted) True >>> isinstance(arr, np.ndarray) True >>> arr.origin.tolist() [10, 20, 30] Keep a plain ndarray when no shift is needed:: >>> out = ndarray_shifted(np.zeros((3, 3, 3)), origin=[0, 0, 0], only_if_necessary=True) >>> isinstance(out, np.ndarray) True >>> isinstance(out, ndarray_shifted) False """ def __new__(cls, a, origin=[0,0,0], only_if_necessary=False): if isinstance(a, cls): origin = a.origin if np.all(origin == np.asarray([0,0,0])) and only_if_necessary: return a arr = np.asarray(a).view(cls) if isinstance(origin, (float, int)): osigin = [origin]*a.ndim arr.origin = np.asarray(origin) # Finally, we must return the newly created object: return arr def __array_finalize__(self, obj): if obj is None: return self.origin = getattr(obj, 'origin', np.asarray([0,0,0])) def __repr__(self): s = super().__repr__() assert s[-1] == ")", "Cannot print" ret = s[:-1] if np.any(self.origin != [0,0,0]): ret += f", origin={list(self.origin)!r}" return ret+")"