grib2io.utils.rotated_grid
Tools for working with Rotated Lat/Lon Grids.
1""" 2Tools for working with Rotated Lat/Lon Grids. 3""" 4 5import numpy as np 6 7RAD2DEG = 57.29577951308232087684 8DEG2RAD = 0.01745329251994329576 9 10def rotate(latin, lonin, aor, splat, splon): 11 """ 12 Perform grid rotation. This function is adapted from ECMWF's ecCodes library 13 void function, rotate(). 14 15 https://github.com/ecmwf/eccodes/blob/develop/src/grib_geography.cc 16 17 Parameters 18 ---------- 19 20 **`latin : float or array_like`** 21 Latitudes in units of degrees. 22 23 **`lonin : float or array_like`** 24 Longitudes in units of degrees. 25 26 **`aor : float`** 27 Angle of rotation as defined in GRIB2 GDTN 4.1. 28 29 **`splat : float`** 30 Latitude of South Pole as defined in GRIB2 GDTN 4.1. 31 32 **`splon : float`** 33 Longitude of South Pole as defined in GRIB2 GDTN 4.1. 34 35 Returns 36 ------- 37 **`lats, lons : numpy.ndarray`** 38 `numpy.ndarrays` with `dtype=numpy.float32` of grid latitudes and 39 longitudes in units of degrees. 40 """ 41 zsycen = np.sin(DEG2RAD * (splat + 90.)) 42 zcycen = np.cos(DEG2RAD * (splat + 90.)) 43 zxmxc = DEG2RAD * (lonin - splon) 44 zsxmxc = np.sin(zxmxc) 45 zcxmxc = np.cos(zxmxc) 46 zsyreg = np.sin(DEG2RAD * latin) 47 zcyreg = np.cos(DEG2RAD * latin) 48 zsyrot = zcycen * zsyreg - zsycen * zcyreg * zcxmxc 49 50 zsyrot = np.where(zsyrot>1.0,1.0,zsyrot) 51 zsyrot = np.where(zsyrot<-1.0,-1.0,zsyrot) 52 53 pyrot = np.arcsin(zsyrot) * RAD2DEG 54 55 zcyrot = np.cos(pyrot * DEG2RAD) 56 zcxrot = (zcycen * zcyreg * zcxmxc + zsycen * zsyreg) / zcyrot 57 zcxrot = np.where(zcxrot>1.0,1.0,zcxrot) 58 zcxrot = np.where(zcxrot<-1.0,-1.0,zcxrot) 59 zsxrot = zcyreg * zsxmxc / zcyrot 60 61 pxrot = np.arccos(zcxrot) * RAD2DEG 62 63 pxrot = np.where(zsxrot<0.0,-pxrot,pxrot) 64 65 return pyrot, pxrot 66 67 68def unrotate(latin, lonin, aor, splat, splon): 69 """ 70 Perform grid un-rotation. This function is adapted from ECMWF's ecCodes library 71 void function, unrotate(). 72 73 https://github.com/ecmwf/eccodes/blob/develop/src/grib_geography.cc 74 75 Parameters 76 ---------- 77 **`latin : float or array_like`** 78 Latitudes in units of degrees. 79 80 **`lonin : float or array_like`** 81 Longitudes in units of degrees. 82 83 **`aor : float`** 84 Angle of rotation as defined in GRIB2 GDTN 4.1. 85 86 **`splat : float`** 87 Latitude of South Pole as defined in GRIB2 GDTN 4.1. 88 89 **`splon : float`** 90 Longitude of South Pole as defined in GRIB2 GDTN 4.1. 91 92 Returns 93 ------- 94 **`lats, lons : numpy.ndarray`** 95 `numpy.ndarrays` with `dtype=numpy.float32` of grid latitudes and 96 longitudes in units of degrees. 97 """ 98 lon_x = lonin 99 lat_y = latin 100 101 latr = lat_y * DEG2RAD 102 lonr = lon_x * DEG2RAD 103 104 xd = np.cos(lonr) * np.cos(latr) 105 yd = np.sin(lonr) * np.cos(latr) 106 zd = np.sin(latr) 107 108 t = -(90.0 + splat) 109 o = -splon 110 111 sin_t = np.sin(DEG2RAD * t) 112 cos_t = np.cos(DEG2RAD * t) 113 sin_o = np.sin(DEG2RAD * o) 114 cos_o = np.cos(DEG2RAD * o) 115 116 x = cos_t * cos_o * xd + sin_o * yd + sin_t * cos_o * zd 117 y = -cos_t * sin_o * xd + cos_o * yd - sin_t * sin_o * zd 118 z = -sin_t * xd + cos_t * zd 119 120 ret_lat = 0 121 ret_lon = 0 122 123 # Then convert back to 'normal' (lat,lon) 124 # Uses arcsin, to convert back to degrees, put in range -1 to 1 in case of slight rounding error 125 # avoid error on calculating e.g. asin(1.00000001) 126 z = np.where(z>1.0,1.0,z) 127 z = np.where(z<-1.0,-1.0,z) 128 129 ret_lat = np.arcsin(z) * RAD2DEG 130 ret_lon = np.arctan2(y, x) * RAD2DEG 131 132 # Still get a very small rounding error, round to 6 decimal places 133 ret_lat = np.round(ret_lat * 1000000.0) / 1000000.0 134 ret_lon = np.round(ret_lon * 1000000.0) / 1000000.0 135 136 ret_lon -= aor 137 138 return ret_lat, ret_lon
11def rotate(latin, lonin, aor, splat, splon): 12 """ 13 Perform grid rotation. This function is adapted from ECMWF's ecCodes library 14 void function, rotate(). 15 16 https://github.com/ecmwf/eccodes/blob/develop/src/grib_geography.cc 17 18 Parameters 19 ---------- 20 21 **`latin : float or array_like`** 22 Latitudes in units of degrees. 23 24 **`lonin : float or array_like`** 25 Longitudes in units of degrees. 26 27 **`aor : float`** 28 Angle of rotation as defined in GRIB2 GDTN 4.1. 29 30 **`splat : float`** 31 Latitude of South Pole as defined in GRIB2 GDTN 4.1. 32 33 **`splon : float`** 34 Longitude of South Pole as defined in GRIB2 GDTN 4.1. 35 36 Returns 37 ------- 38 **`lats, lons : numpy.ndarray`** 39 `numpy.ndarrays` with `dtype=numpy.float32` of grid latitudes and 40 longitudes in units of degrees. 41 """ 42 zsycen = np.sin(DEG2RAD * (splat + 90.)) 43 zcycen = np.cos(DEG2RAD * (splat + 90.)) 44 zxmxc = DEG2RAD * (lonin - splon) 45 zsxmxc = np.sin(zxmxc) 46 zcxmxc = np.cos(zxmxc) 47 zsyreg = np.sin(DEG2RAD * latin) 48 zcyreg = np.cos(DEG2RAD * latin) 49 zsyrot = zcycen * zsyreg - zsycen * zcyreg * zcxmxc 50 51 zsyrot = np.where(zsyrot>1.0,1.0,zsyrot) 52 zsyrot = np.where(zsyrot<-1.0,-1.0,zsyrot) 53 54 pyrot = np.arcsin(zsyrot) * RAD2DEG 55 56 zcyrot = np.cos(pyrot * DEG2RAD) 57 zcxrot = (zcycen * zcyreg * zcxmxc + zsycen * zsyreg) / zcyrot 58 zcxrot = np.where(zcxrot>1.0,1.0,zcxrot) 59 zcxrot = np.where(zcxrot<-1.0,-1.0,zcxrot) 60 zsxrot = zcyreg * zsxmxc / zcyrot 61 62 pxrot = np.arccos(zcxrot) * RAD2DEG 63 64 pxrot = np.where(zsxrot<0.0,-pxrot,pxrot) 65 66 return pyrot, pxrot
Perform grid rotation. This function is adapted from ECMWF's ecCodes library void function, rotate().
https://github.com/ecmwf/eccodes/blob/develop/src/grib_geography.cc
Parameters
latin : float or array_like
Latitudes in units of degrees.
lonin : float or array_like
Longitudes in units of degrees.
aor : float
Angle of rotation as defined in GRIB2 GDTN 4.1.
splat : float
Latitude of South Pole as defined in GRIB2 GDTN 4.1.
splon : float
Longitude of South Pole as defined in GRIB2 GDTN 4.1.
Returns
lats, lons : numpy.ndarray
numpy.ndarrays
with dtype=numpy.float32
of grid latitudes and
longitudes in units of degrees.
69def unrotate(latin, lonin, aor, splat, splon): 70 """ 71 Perform grid un-rotation. This function is adapted from ECMWF's ecCodes library 72 void function, unrotate(). 73 74 https://github.com/ecmwf/eccodes/blob/develop/src/grib_geography.cc 75 76 Parameters 77 ---------- 78 **`latin : float or array_like`** 79 Latitudes in units of degrees. 80 81 **`lonin : float or array_like`** 82 Longitudes in units of degrees. 83 84 **`aor : float`** 85 Angle of rotation as defined in GRIB2 GDTN 4.1. 86 87 **`splat : float`** 88 Latitude of South Pole as defined in GRIB2 GDTN 4.1. 89 90 **`splon : float`** 91 Longitude of South Pole as defined in GRIB2 GDTN 4.1. 92 93 Returns 94 ------- 95 **`lats, lons : numpy.ndarray`** 96 `numpy.ndarrays` with `dtype=numpy.float32` of grid latitudes and 97 longitudes in units of degrees. 98 """ 99 lon_x = lonin 100 lat_y = latin 101 102 latr = lat_y * DEG2RAD 103 lonr = lon_x * DEG2RAD 104 105 xd = np.cos(lonr) * np.cos(latr) 106 yd = np.sin(lonr) * np.cos(latr) 107 zd = np.sin(latr) 108 109 t = -(90.0 + splat) 110 o = -splon 111 112 sin_t = np.sin(DEG2RAD * t) 113 cos_t = np.cos(DEG2RAD * t) 114 sin_o = np.sin(DEG2RAD * o) 115 cos_o = np.cos(DEG2RAD * o) 116 117 x = cos_t * cos_o * xd + sin_o * yd + sin_t * cos_o * zd 118 y = -cos_t * sin_o * xd + cos_o * yd - sin_t * sin_o * zd 119 z = -sin_t * xd + cos_t * zd 120 121 ret_lat = 0 122 ret_lon = 0 123 124 # Then convert back to 'normal' (lat,lon) 125 # Uses arcsin, to convert back to degrees, put in range -1 to 1 in case of slight rounding error 126 # avoid error on calculating e.g. asin(1.00000001) 127 z = np.where(z>1.0,1.0,z) 128 z = np.where(z<-1.0,-1.0,z) 129 130 ret_lat = np.arcsin(z) * RAD2DEG 131 ret_lon = np.arctan2(y, x) * RAD2DEG 132 133 # Still get a very small rounding error, round to 6 decimal places 134 ret_lat = np.round(ret_lat * 1000000.0) / 1000000.0 135 ret_lon = np.round(ret_lon * 1000000.0) / 1000000.0 136 137 ret_lon -= aor 138 139 return ret_lat, ret_lon
Perform grid un-rotation. This function is adapted from ECMWF's ecCodes library void function, unrotate().
https://github.com/ecmwf/eccodes/blob/develop/src/grib_geography.cc
Parameters
latin : float or array_like
Latitudes in units of degrees.
lonin : float or array_like
Longitudes in units of degrees.
aor : float
Angle of rotation as defined in GRIB2 GDTN 4.1.
splat : float
Latitude of South Pole as defined in GRIB2 GDTN 4.1.
splon : float
Longitude of South Pole as defined in GRIB2 GDTN 4.1.
Returns
lats, lons : numpy.ndarray
numpy.ndarrays
with dtype=numpy.float32
of grid latitudes and
longitudes in units of degrees.