def __getitem__(self, index): """ Create an AffineTransform coordinate map with into self.coords with slices created as in np.mgrid/np.ogrid. """ dtype = self.coordmap.function_domain.coord_dtype results = [a.ravel().astype(dtype) for a in np.ogrid[index]] if len(results) != len(self.coordmap.function_domain.coord_names): raise ValueError('the number of slice objects must match ' 'the number of input dimensions') cmaps = [] for i, result in enumerate(results): if result.shape[0] > 1: step = result[1] - result[0] else: step = 0 start = result[0] cmaps.append(AffineTransform( CoordinateSystem(['i%d' % i], coord_dtype=dtype), CoordinateSystem([self.coordmap.function_domain.coord_names[i]], coord_dtype=dtype), np.array([[step, start],[0,1]], dtype=dtype))) shape = [result.shape[0] for result in results] cmap = cmap_product(*cmaps) # Identify the origin in the range of cmap # with the origin in the domain of self.coordmap cmap = shifted_range_origin(cmap, np.zeros(cmap.ndims[1]), self.coordmap.function_domain.name) return ArrayCoordMap(compose(self.coordmap, cmap), tuple(shape))
def _slice(coordmap, shape, *slices): """ Slice a 'voxel' CoordinateMap's function_domain with slices. A 'voxel' CoordinateMap is interpreted as a coordmap having a shape. """ if len(slices) < coordmap.ndims[0]: slices = (list(slices) + [slice(None,None,None)] * (coordmap.ndims[0] - len(slices))) ranges = [np.arange(s) for s in shape] cmaps = [] keep_in_output = [] dtype = coordmap.function_domain.coord_dtype newshape = [] for i, __slice in enumerate(slices): ranges[i] = ranges[i][__slice] try: start = ranges[i][0] except IndexError: try: start = int(ranges[i]) except TypeError: raise ValueError('empty slice for dimension %d, ' 'coordinate %s' % (i, coordmap.function_domain.coord_names[i])) if ranges[i].shape == (): step = 0 start = int(ranges[i]) l = 1 elif ranges[i].shape[0] > 1: start = ranges[i][0] step = ranges[i][1] - ranges[i][0] l = ranges[i].shape[0] keep_in_output.append(i) else: start = ranges[i][0] step = 0. l = 1 keep_in_output.append(i) if step > 1: name = coordmap.function_domain.coord_names[i] + '-slice' else: name = coordmap.function_domain.coord_names[i] cmaps.append(AffineTransform( CoordinateSystem([name], coord_dtype=dtype), CoordinateSystem([coordmap.function_domain.coord_names[i]]), np.array([[step, start],[0,1]], dtype=dtype))) if i in keep_in_output: newshape.append(l) slice_cmap = cmap_product(*cmaps) # Identify the origin in the range of cmap # with the origin in the domain of coordmap slice_cmap = shifted_range_origin(slice_cmap, np.zeros(slice_cmap.ndims[1]), coordmap.function_domain.name) # Reduce the size of the matrix innames = slice_cmap.function_domain.coord_names inmat = [] function_domain = CoordinateSystem( [innames[i] for i in keep_in_output], 'input-slice', coordmap.function_domain.coord_dtype) A = np.zeros((coordmap.ndims[0]+1, len(keep_in_output)+1)) for j, i in enumerate(keep_in_output): A[:,j] = slice_cmap.affine[:,i] A[:,-1] = slice_cmap.affine[:,-1] A = A.astype(function_domain.coord_dtype) slice_cmap = AffineTransform(function_domain, coordmap.function_domain, A) return ArrayCoordMap(compose(coordmap, slice_cmap), tuple(newshape))