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