Coverage for src/CSET/operators/regrid.py: 100%
32 statements
« prev ^ index » next coverage.py v7.5.4, created at 2024-07-01 08:37 +0000
« prev ^ index » next coverage.py v7.5.4, created at 2024-07-01 08:37 +0000
1# Copyright 2024 Met Office and contributors.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15"""Operators to regrid cubes."""
17import iris
18import iris.cube
19import numpy as np
21from CSET.operators._utils import get_cube_yxcoordname
24def regrid_onto_cube(
25 incube: iris.cube.Cube, target: iris.cube.Cube, method: str, **kwargs
26) -> iris.cube.Cube:
27 """Regrid a cube, projecting onto a target cube.
29 Cube must have at least 2 dimensions.
31 Arguments
32 ----------
33 incube: Cube
34 An iris cube of the data to regrid. As a minimum, it needs to be 2D with a latitude,
35 longitude coordinates.
36 target: Cube
37 An iris cube of the data to regrid onto. It needs to be 2D with a latitude,
38 longitude coordinate.
39 method: str
40 Method used to regrid onto, etc. Linear will use iris.analysis.Linear()
42 Returns
43 -------
44 iris.cube.Cube
45 An iris cube of the data that has been regridded.
47 Raises
48 ------
49 ValueError
50 If a unique x/y coordinate cannot be found
51 NotImplementedError
52 If the cubes grid, or the method for regridding, is not yet supported.
54 Notes
55 -----
56 Currently rectlinear grids (uniform) are supported.
57 """
58 # Get y,x coord names
59 y_coord, x_coord = get_cube_yxcoordname(incube)
61 # List of supported grids - check if it is compatible
62 supported_grids = (iris.coord_systems.GeogCS,)
63 if not isinstance(incube.coord(x_coord).coord_system, supported_grids):
64 raise NotImplementedError(
65 f"Does not currently support {incube.coord(x_coord).coord_system} coordinate system"
66 )
67 if not isinstance(incube.coord(y_coord).coord_system, supported_grids):
68 raise NotImplementedError(
69 f"Does not currently support {incube.coord(y_coord).coord_system} coordinate system"
70 )
72 regrid_method = getattr(iris.analysis, method, None)
73 if callable(regrid_method):
74 return incube.regrid(target, regrid_method())
75 else:
76 raise NotImplementedError(f"Does not currently support {method} regrid method")
79def regrid_onto_xyspacing(
80 incube: iris.cube.Cube, xspacing: int, yspacing: int, method: str, **kwargs
81) -> iris.cube.Cube:
82 """Regrid cube onto a set x,y spacing.
84 Regrid cube using specified x,y spacing, which is performed linearly.
86 Parameters
87 ----------
88 incube: Cube
89 An iris cube of the data to regrid. As a minimum, it needs to be 2D with a latitude,
90 longitude coordinates.
91 xspacing: integer
92 Spacing of points in longitude direction (could be degrees, meters etc.)
93 yspacing: integer
94 Spacing of points in latitude direction (could be degrees, meters etc.)
95 method: str
96 Method used to regrid onto, etc. Linear will use iris.analysis.Linear()
98 Returns
99 -------
100 cube_rgd: Cube
101 An iris cube of the data that has been regridded.
103 Raises
104 ------
105 ValueError
106 If a unique x/y coordinate cannot be found
107 NotImplementedError
108 If the cubes grid, or the method for regridding, is not yet supported.
110 Notes
111 -----
112 Currently rectlinear grids (uniform) are supported.
114 """
115 # Get x,y coord names
116 y_coord, x_coord = get_cube_yxcoordname(incube)
118 # List of supported grids - check if it is compatible
119 supported_grids = (iris.coord_systems.GeogCS,)
120 if not isinstance(incube.coord(x_coord).coord_system, supported_grids):
121 raise NotImplementedError(
122 f"Does not currently support {incube.coord(x_coord).coord_system} regrid method"
123 )
124 if not isinstance(incube.coord(y_coord).coord_system, supported_grids):
125 raise NotImplementedError(
126 f"Does not currently support {incube.coord(y_coord).coord_system} regrid method"
127 )
129 # Get axis
130 lat, lon = incube.coord(y_coord), incube.coord(x_coord)
132 # Get bounds
133 lat_min, lon_min = lat.points.min(), lon.points.min()
134 lat_max, lon_max = lat.points.max(), lon.points.max()
136 # Generate new mesh
137 latout = np.arange(lat_min, lat_max, yspacing)
138 lonout = np.arange(lon_min, lon_max, xspacing)
140 regrid_method = getattr(iris.analysis, method, None)
141 if callable(regrid_method):
142 cube_rgd = incube.interpolate(
143 [(y_coord, latout), (x_coord, lonout)], regrid_method()
144 )
145 else:
146 raise NotImplementedError(f"Does not currently support {method} regrid method")
148 return cube_rgd