def N_wet(self, lat, lon): if not self._N_wet: vals = load_data(os.path.join(dataset_dir, 'p453/v12_ESANWET.txt')) lats = load_data(os.path.join(dataset_dir, 'p453/v12_ESALAT.txt')) lons = load_data(os.path.join(dataset_dir, 'p453/v12_ESALON.txt')) self._N_wet = bilinear_2D_interpolator(lats, lons, vals) return self._N_wet(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def Pclw(self, lat, lon): if not self._Pclw: vals = load_data(os.path.join(dataset_dir, 'p840/v7_Pclw.txt')) lats = load_data(os.path.join(dataset_dir, 'p840/v7_Lat.txt')) lons = load_data(os.path.join(dataset_dir, 'p840/v7_Lon.txt')) self._Pclw = bilinear_2D_interpolator(lats, lons, vals) return self._Pclw(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def sigma(self, lat, lon): if not self._sigma: vals = load_data( os.path.join(dataset_dir, 'p840/v4_WRED_LOGNORMAL_STDEV.txt')) lats = load_data(os.path.join(dataset_dir, 'p840/v4_Lat.txt')) lons = load_data(os.path.join(dataset_dir, 'p840/v4_Lon.txt')) self._sigma = bilinear_2D_interpolator(lats, lons, vals) return self._sigma(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def temperature(self, lat, lon): if not self._temperature: vals = load_data(os.path.join(dataset_dir, 'p1510/v0_Temp.txt')) lats = load_data(os.path.join(dataset_dir, 'p1510/v0_Lat.txt')) lons = load_data(os.path.join(dataset_dir, 'p1510/v0_Lon.txt')) self._temperature = bicubic_2D_interpolator(np.flipud(lats), lons, np.flipud(vals)) return self._temperature( np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def isotherm_0(self, lat, lon): if not self._zero_isotherm_data: vals = load_data( os.path.join(dataset_dir, 'p839/v3_ESA0HEIGHT.txt')) lats = load_data(os.path.join(dataset_dir, 'p839/v3_ESALAT.txt')) lons = load_data(os.path.join(dataset_dir, 'p839/v3_ESALON.txt')) self._zero_isotherm_data = bilinear_2D_interpolator( lats, lons, vals) return self._zero_isotherm_data( np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def topo_alt(self, lat, lon): if self._topo_alt is None: d_dir = os.path.join(dataset_dir, 'p836/v6_TOPO_0DOT5.txt') lats = load_data(os.path.join(dataset_dir, 'p836/v6_TOPOLAT.txt')) lons = load_data(os.path.join(dataset_dir, 'p836/v6_TOPOLON.txt')) vals = load_data(d_dir) self._topo_alt = bicubic_2D_interpolator(np.flipud(lats), lons, np.flipud(vals)) return self._topo_alt( np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def temperature(self, lat, lon): if not self._temperature: vals = load_data(os.path.join(dataset_dir, 'p1510/v1_T_Annual.h5')) lats = load_data(os.path.join(dataset_dir, 'p1510/v1_Lat.h5')) lons = load_data(os.path.join(dataset_dir, 'p1510/v1_Lon.h5')) self._temperature = bilinear_2D_interpolator( np.flipud(lats), lons, np.flipud(vals)) lon[lon > 180] = lon[lon > 180] - 360 return self._temperature( np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def altitude(self, lat, lon): if not self._altitude: vals = load_data( os.path.join(dataset_dir, 'p1511/v2_TOPO_0DOT08.h5')) lats = load_data(os.path.join(dataset_dir, 'p1511/v2_Lat.h5')) lons = load_data(os.path.join(dataset_dir, 'p1511/v2_Lon.h5')) self._altitude = bicubic_2D_interpolator(np.flipud(lats), lons, np.flipud(vals)) return self._altitude(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def Beta(self, lat, lon): if not self._Beta: vals = load_data( os.path.join(dataset_dir, 'p837/ESARAIN_BETA_v5.txt')) lats = load_data( os.path.join(dataset_dir, 'p837/ESARAIN_LAT_v5.txt')) lons = load_data( os.path.join(dataset_dir, 'p837/ESARAIN_LON_v5.txt')) self._Beta = bilinear_2D_interpolator(lats, lons, vals) return self._Beta(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def pressure(self, lat, lon): if not self._pressure: vals = load_data(os.path.join(dataset_dir, 'p1853/v2_P_Annual.h5')) lats = load_data(os.path.join(dataset_dir, 'p1853/v2_Lat.h5')) lons = load_data(os.path.join(dataset_dir, 'p1853/v2_Lon.h5')) self._pressure = bilinear_2D_interpolator(np.flipud(lats), lons, np.flipud(vals)) # In this recommendation the longitude is encoded with format -180 to # 180 whereas we always use 0 - 360 encoding lon[lon > 180] = lon[lon > 180] - 360 return self._pressure(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def VSCH(self, lat, lon, p): if not self._VSCH: ps = [0.1, 0.2, 0.3, 0.5, 1, 2, 3, 5, 10, 20, 30, 50, 60, 70, 80, 90, 95, 99] d_dir = os.path.join(dataset_dir, 'p836/v4_VSCH_%s.txt') lats = load_data(os.path.join(dataset_dir, 'p836/v4_Lat.txt')) lons = load_data(os.path.join(dataset_dir, 'p836/v4_Lon.txt')) for p_loads in ps: vals = load_data(d_dir % (str(p_loads).replace('.', ''))) self._VSCH[float(p_loads)] =\ bilinear_2D_interpolator(lats, lons, vals) return self._VSCH[float(p)]( np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def R001(self, lat, lon): if not self._R001: lats = load_data(os.path.join(dataset_dir, 'p837/v7_LAT_R001.h5')) lons = load_data(os.path.join(dataset_dir, 'p837/v7_LON_R001.h5')) vals = load_data(os.path.join(dataset_dir, 'p837/v7_R001.h5')) self._R001 = bilinear_2D_interpolator(np.flipud(lats), lons, np.flipud(vals)) # In this recommendation the longitude is encoded with format -180 to # 180 whereas we always use 0 - 360 encoding lon = np.array(lon) lon[lon > 180] = lon[lon > 180] - 360 return self._R001(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def month_temperature(self, lat, lon, m): if not self._month_temperature: lats = load_data(os.path.join(dataset_dir, 'p1510/v1_Lat.h5')) lons = load_data(os.path.join(dataset_dir, 'p1510/v1_Lon.h5')) for _m in self.__months: vals = load_data( os.path.join(dataset_dir, 'p1510/v1_T_Month{0:02d}.h5').format(_m)) self._month_temperature[_m] = bilinear_2D_interpolator( np.flipud(lats), lons, np.flipud(vals)) lon[lon > 180] = lon[lon > 180] - 360 return self._month_temperature[m](np.array([lat.ravel(), lon.ravel() ]).T).reshape(lat.shape)
class _ITU676_11(): tmp = load_data(os.path.join(dataset_dir, 'p676//v11_lines_water_vapour.txt'), skip_header=1) f_wv = tmp[:, 0] b1 = tmp[:, 1] b2 = tmp[:, 2] b3 = tmp[:, 3] b4 = tmp[:, 4] b5 = tmp[:, 5] b6 = tmp[:, 6] idx_approx = np.zeros_like(b1, dtype=bool).squeeze() asterisk_rows = [0, 3, 4, 5, 7, 12, 20, 24, 34] idx_approx[np.array(asterisk_rows)] = True def __init__(self): self.__version__ = 11 self.year = 2017 self.month = 12 self.link = 'https://www.itu.int/rec/R-REC-P.676-11-201712-S/en' def gammaw_exact(self, f, P, rho, T): return __gammaw_exact__676_9_11__(self, f, P, rho, T)
def s_a(self, lat, lon): """ Standard deviation of terrain heights (m) within a 110 km × 110 km area with a 30 s resolution (e.g. the Globe “gtopo30” data). The value for the mid-path may be obtained from an area roughness with 0.5 × 0.5 degree resolution of geographical coordinates using bi-linear interpolation. """ if not self._s_a: vals = load_data(os.path.join(dataset_dir, 'p530/v16_gtopo_30.txt')) lats = load_data(os.path.join(dataset_dir, 'p530/v16_lat.txt')) lons = load_data(os.path.join(dataset_dir, 'p530/v16_lon.txt')) self._Pr6 = bilinear_2D_interpolator(lats, lons, vals) return self._Pr6(np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def Mt(self, lat, lon, m): if not self._Mt: lats = load_data(os.path.join(dataset_dir, 'p837/v7_LAT_MT.h5')) lons = load_data(os.path.join(dataset_dir, 'p837/v7_LON_MT.h5')) for _m in self.months: vals = load_data( os.path.join(dataset_dir, 'p837/v7_MT_Month{0:02d}.h5').format(_m)) self._Mt[_m] = bilinear_2D_interpolator( np.flipud(lats), lons, np.flipud(vals)) # In this recommendation the longitude is encoded with format -180 to # 180 whereas we always use 0 - 360 encoding lon = np.array(lon) lon[lon > 180] = lon[lon > 180] - 360 return self._Mt[m](np.array([lat.ravel(), lon.ravel()]).T).reshape(lat.shape)
def N_wet(self, lat, lon, p): if not self._N_wet: ps = [ 0.1, 0.2, 0.3, 0.5, 1, 2, 3, 5, 10, 20, 30, 50, 60, 70, 80, 90, 95, 99 ] d_dir = os.path.join(dataset_dir, 'p453/v13_NWET_Annual_%s.txt') lats = load_data(os.path.join(dataset_dir, 'p453/v13_LAT_N.txt')) lons = load_data(os.path.join(dataset_dir, 'p453/v13_LON_N.txt')) for p_loads in ps: vals = load_data(d_dir % (str(p_loads).replace('.', ''))) self._N_wet[float(p_loads)] = bilinear_2D_interpolator( np.flipud(lats), lons, np.flipud(vals)) lon[lon > 180] = lon[lon > 180] - 360 return self._N_wet[float(p)](np.array([lat.ravel(), lon.ravel() ]).T).reshape(lat.shape)
class _ITU676_11(): tmp = load_data(os.path.join(dataset_dir, 'p676//v11_lines_water_vapour.txt'), skip_header=1) f_wv = tmp[:, 0] b1 = tmp[:, 1] b2 = tmp[:, 2] b3 = tmp[:, 3] b4 = tmp[:, 4] b5 = tmp[:, 5] b6 = tmp[:, 6] idx_approx = np.zeros_like(b1, dtype=bool).squeeze() asterisk_rows = [0, 3, 4, 5, 7, 12, 20, 24, 34] idx_approx[np.array(asterisk_rows)] = True def __init__(self): self.__version__ = 11 self.year = 2017 self.month = 12 self.link = 'https://www.itu.int/rec/R-REC-P.676-11-201712-S/en' def gammaw_approx(self, f, P, rho, T): # T in Kelvin # e : water vapour partial pressure in hPa (total barometric pressure # ptot = p + e) theta = 300 / T e = rho * T / 216.7 # water vapour partial pressure p = P - e # Dry air pressure f_wv = self.f_wv[self.idx_approx] b1 = self.b1[self.idx_approx] b2 = self.b2[self.idx_approx] b3 = self.b3[self.idx_approx] b4 = self.b4[self.idx_approx] b5 = self.b5[self.idx_approx] b6 = self.b6[self.idx_approx] N_pp_wv = 0 for ii in np.arange(np.size(f_wv)): D_f_wv = b3[ii] * 1e-4 * (p * theta ** b4[ii] + b5[ii] * e * theta ** b6[ii]) F_i_wv = f / f_wv[ii] * ((D_f_wv) / ((f_wv[ii] - f)**2 + D_f_wv**2) + (D_f_wv) / ((f_wv[ii] + f)**2 + D_f_wv**2)) Si_wv = b1[ii] * 1e-1 * e * theta**3.5 * np.exp(b2[ii] * (1 - theta)) N_pp_wv = N_pp_wv + Si_wv * F_i_wv gamma = 0.1820 * f * N_pp_wv # Eq. 1 [dB/km] return gamma
def DN65(self, lat, lon, p): if not self._DN65: ps = [ 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 98, 99, 99.5, 99.8, 99.9 ] d_dir = os.path.join(dataset_dir, 'p453/v12_DN65m_%02dd%02d_v1.txt') lats = load_data(os.path.join(dataset_dir, 'p453/v12_lat0d75.txt')) lons = load_data(os.path.join(dataset_dir, 'p453/v12_lon0d75.txt')) for p_loads in ps: int_p = p_loads // 1 frac_p = round((p_loads % 1.0) * 100) vals = load_data(d_dir % (int_p, frac_p)) self._DN65[float(p_loads)] = bilinear_2D_interpolator( lats, lons, vals) return self._DN65[float(p)](np.array([lat.ravel(), lon.ravel() ]).T).reshape(lat.shape)
class _ITU676_10(): tmp = load_data(os.path.join(dataset_dir, 'p676/v10_lines_oxygen.txt'), skip_header=1) f_ox = tmp[:, 0] a1 = tmp[:, 1] a2 = tmp[:, 2] a3 = tmp[:, 3] a4 = tmp[:, 4] a5 = tmp[:, 5] a6 = tmp[:, 6] def __init__(self): self.__version__ = 10 self.year = 2013 self.month = 9 self.link = 'https://www.itu.int/rec/R-REC-P.676-10-201309-S/en' def gamma0_exact(self, f, P, rho, T): return __gamma0_exact__676_9_11__(self, f, P, rho, T)
class _ITU676_10(): tmp = load_data(os.path.join(dataset_dir, 'p676//v10_lines_water_vapour.txt'), skip_header=1) f_wv = tmp[:, 0] b1 = tmp[:, 1] b2 = tmp[:, 2] b3 = tmp[:, 3] b4 = tmp[:, 4] b5 = tmp[:, 5] b6 = tmp[:, 6] def __init__(self): self.__version__ = 10 self.year = 2013 self.month = 9 self.link = 'https://www.itu.int/rec/R-REC-P.676-10-201309-S/en' def gammaw_exact(self, f, P, rho, T): return __gammaw_exact__676_9_11__(self, f, P, rho, T)
class _ITU676_9(): tmp = load_data(os.path.join(dataset_dir, 'p676//v9_lines_oxygen.txt'), skip_header=1) f_ox = tmp[:, 0] a1 = tmp[:, 1] a2 = tmp[:, 2] a3 = tmp[:, 3] a4 = tmp[:, 4] a5 = tmp[:, 5] a6 = tmp[:, 6] def __init__(self): self.__version__ = 9 self.year = 2012 self.month = 2 self.link = 'https://www.itu.int/rec/R-REC-P.676-9-201202-S/en' # Recommendation ITU-P R.676-9 has most of the methods similar to those # in Recommendation ITU-P R.676-10. def gamma0_exact(self, f, P, rho, T): return __gamma0_exact__676_9_11__(self, f, P, rho, T)