Source code for pyuff_ustb.readers.lazy_arrays.lazy_operations

from dataclasses import dataclass
from typing import Optional, Sequence, Tuple

import numpy as np


[docs]@dataclass class LazyOperation: transform_data: callable transform_index: Optional[callable] = None transform_shape: Optional[callable] = None
[docs]class LazyTranspose(LazyOperation):
[docs] def __init__(self): def transform_index(k, shape: Tuple[int, ...]): if not isinstance(k, Sequence): k = [k] # Add enough new slices to match the number of dimensions k = [*k, *[slice(None) for _ in range(len(shape) - len(k))]] k = reversed(k) # Reverse the order of the slices because of the transpose return tuple(k) def transform_shape(shape: Tuple[int, ...]): return tuple(reversed(shape)) super().__init__(lambda x: x.T, transform_index, transform_shape)
[docs]def apply_lazy_operations_on_data( data: np.ndarray, operations: Sequence[LazyOperation], ) -> np.ndarray: for op in operations: data = op.transform_data(data) return data
[docs]def apply_lazy_operations_on_index( index, shape: Tuple[int, ...], operations: Sequence[LazyOperation], ) -> np.ndarray: for op in operations: if op.transform_index is not None: index = op.transform_index(index, shape) if op.transform_shape is not None: shape = op.transform_shape(shape) return index
[docs]def apply_lazy_operations_on_shape( shape: Tuple[int, ...], operations: Sequence[LazyOperation], ) -> np.ndarray: for op in operations: if op.transform_shape is not None: shape = op.transform_shape(shape) return shape
if __name__ == "__main__": T = LazyTranspose() Ts = [T, T, T] a = np.ones((2, 3, 4, 5)) index = (slice(0, 1), 1) b = a.__getitem__(apply_lazy_operations_on_index(index, a.shape, Ts)) b = apply_lazy_operations_on_data(b, Ts) print(b.shape) assert b.shape == (1, 3, 2)