def dz( self, vector_input: vectors.Vector3D, ): return vectors.Vector2D( x=self.x.dz(vector_input=vector_input), y=self.y.dz(vector_input=vector_input), )
def __call__( self, vector_input: vectors.Vector3D, ): return vectors.Vector2D( x=self.x(vector_input=vector_input), y=self.y(vector_input=vector_input), )
def plate_scale(self) -> vectors.Vector2D: model = self.model() # output_max = self.spatial_mesh_input.max() # output_min = self.spatial_mesh_input.min() # dy = model(output_max.to_3d(self.wavelength)) - model(output_min.to_3d(self.wavelength)) # dx = output_max - output_min # return dx / dy center_fov = vectors.Vector3D(x=0 * u.arcsec, y=0 * u.arcsec, z=self.wavelength) # return 1 / model.dx(center_fov) return vectors.Vector2D( x=1 / model.dx(center_fov).length, y=1 / model.dy(center_fov).length, )
def __call__( self, cube: u.Quantity, wavelength: u.Quantity, spatial_input_min: vectors.Vector2D, spatial_input_max: vectors.Vector2D, spatial_output_min: vectors.Vector2D, spatial_output_max: vectors.Vector2D, spatial_samples_output: typ.Union[int, vectors.Vector2D], inverse: bool = False, # channel_index: typ.Optional[int] = None, interp_order: int = 1, interp_prefilter: bool = False, fill_value: float = np.nan, ) -> np.ndarray: # if isinstance(spatial_samples_output, int): # spatial_samples_output = vector.Vector2D(spatial_samples_output, spatial_samples_output) output_grid = vectors.Vector3D() output_grid.x = np.linspace(spatial_output_min.x, spatial_output_max.x, spatial_samples_output.x) output_grid.y = np.linspace(spatial_output_min.y, spatial_output_max.y, spatial_samples_output.y) output_grid.x = output_grid.x[..., :, np.newaxis, np.newaxis] output_grid.y = output_grid.y[..., np.newaxis, :, np.newaxis] wavelength = wavelength[..., np.newaxis, np.newaxis, :] output_grid.z = wavelength # output_grid_x = np.linspace(output_min[x], output_max[x], spatial_samples_output[x]) # output_grid_y = np.linspace(output_min[y], output_max[y], spatial_samples_output[y]) # wavelength, output_grid_x, output_grid_y = np.broadcast_arrays( # wavelength[..., None, None], output_grid_x[..., None], output_grid_y, subok=True) model = self.model(inverse=not inverse) # coordinates = model(wavelength, output_grid_x, output_grid_y) coordinates = model(output_grid) coordinates = (coordinates - spatial_input_min) / (spatial_input_max - spatial_input_min) # coordinates *= cube.shape[~1:] * u.pix coordinates = coordinates * vectors.Vector2D(x=cube.shape[~2] * u.pix, y=cube.shape[~1] * u.pix) coordinates = coordinates.to_3d(wavelength) sh = cube.shape[:~2] coordinates = np.broadcast_to(coordinates, sh + coordinates.shape[~2:]) coordinates_flat = coordinates.reshape((-1, ) + coordinates.shape[~2:]) # coordinates_flat = np.moveaxis(coordinates_flat, ~0, 2) cube_flat = cube.reshape((-1, ) + cube.shape[~2:]) new_cube_flat_shape = list(cube_flat.shape) new_cube_flat_shape[~2] = spatial_samples_output.x new_cube_flat_shape[~1] = spatial_samples_output.y new_cube_flat = np.empty(new_cube_flat_shape) for i in range(cube_flat.shape[0]): # for j in range(cube_flat.shape[~0]): coords = coordinates_flat[i] new_cube_flat[i] = scipy.ndimage.map_coordinates( input=cube_flat[i], coordinates=np.stack([coords.x, coords.y, coords.z]), order=interp_order, prefilter=interp_prefilter, cval=fill_value, ) return new_cube_flat.reshape(cube.shape[:~2] + new_cube_flat.shape[~2:]) << cube.unit