def rain_attenuation_probability(self, lat, lon, el, hs=None, Ls=None, P0=None): Re = 8500 if hs is None: hs = topographic_altitude(lat, lon).to(u.km).value # Step 1: Estimate the probability of rain, at the earth station either # from Recommendation ITU-R P.837 or from local measured rainfall # rate data if P0 is None: P0 = rainfall_probability(lat, lon).\ to(u.dimensionless_unscaled).value # Step 2: Calculate the parameter alpha using the inverse of the # Q-function alpha = Q^{-1}(P0) -> Q(alpha) = P0 alpha = stats.norm.ppf(1 - P0) # Step 3: Calculate the spatial correlation function, rho: hr = rain_height(lat, lon).value if Ls is None: Ls = np.where( el >= 5, (hr - hs) / (np.sin(np.deg2rad(el))), # Eq. 1 2 * (hr - hs) / (((np.sin(np.deg2rad(el)))**2 + 2 * (hr - hs) / Re)**0.5 + (np.sin(np.deg2rad(el))))) # Eq. 2 d = Ls * np.cos(np.deg2rad(el)) rho = 0.59 * np.exp(-abs(d) / 31) + 0.41 * np.exp(-abs(d) / 800) # Step 4: Calculate the complementary bivariate normal distribution biva_fcn = np.vectorize(__CDF_bivariate_normal__) c_B = biva_fcn(alpha, alpha, rho) # Step 5: Calculate the probability of rain attenuation on the slant # path: P = 1 - (1 - P0) * ((c_B - P0**2) / (P0 * (1 - P0)))**P0 return P
def rain_attenuation(self, lat, lon, f, el, hs=None, p=0.01, R001=None, tau=45, Ls=None): if p < 0.001 or p > 5: warnings.warn( RuntimeWarning('The method to compute the rain attenuation in ' 'recommendation ITU-P 618-12 is only valid for ' 'unavailability values between 0.001 and 5')) Re = 8500 # Efective radius of the Earth (8500 km) if hs is None: hs = topographic_altitude(lat, lon).to(u.km).value # Step 1: Compute the rain height (hr) based on ITU - R P.839 hr = rain_height(lat, lon).value # Step 2: Compute the slant path length if Ls is None: Ls = np.where( el >= 5, (hr - hs) / (np.sin(np.deg2rad(el))), # Eq. 1 2 * (hr - hs) / (((np.sin(np.deg2rad(el)))**2 + 2 * (hr - hs) / Re)**0.5 + (np.sin(np.deg2rad(el))))) # Eq. 2 # Step 3: Calculate the horizontal projection, LG, of the # slant-path length Lg = np.abs(Ls * np.cos(np.deg2rad(el))) # Obtain the raingall rate, exceeded for 0.01% of an average year, # if not provided, as described in ITU-R P.837. if R001 is None: R001 = rainfall_rate(lat, lon, 0.01).to(u.mm / u.hr).value # Step 5: Obtain the specific attenuation gammar using the frequency # dependent coefficients as given in ITU-R P.838 gammar = rain_specific_attenuation(R001, f, el, tau).to(u.dB / u.km).value # Step 6: Calculate the horizontal reduction factor, r0.01, # for 0.01% of the time: r001 = 1. / (1 + 0.78 * np.sqrt(Lg * gammar / f) - 0.38 * (1 - np.exp(-2 * Lg))) # Step 7: Calculate the vertical adjustment factor, v0.01, # for 0.01% of the time: eta = np.rad2deg(np.arctan2(hr - hs, Lg * r001)) Lr = np.where(eta > el, Lg * r001 / np.cos(np.deg2rad(el)), (hr - hs) / np.sin(np.deg2rad(el))) xi = np.where(np.abs(lat) < 36, 36 - np.abs(lat), 0) v001 = 1. / ( 1 + np.sqrt(np.sin(np.deg2rad(el))) * (31 * (1 - np.exp(-(el / (1 + xi)))) * np.sqrt(Lr * gammar) / f**2 - 0.45)) # Step 8: calculate the effective path length: Le = Lr * v001 # (km) # Step 9: The predicted attenuation exceeded for 0.01% of an average # year A001 = gammar * Le # (dB) # Step 10: The estimated attenuation to be exceeded for other # percentages of an average year if p >= 1: beta = np.zeros_like(A001) else: beta = np.where( np.abs(lat) > 36, np.zeros_like(A001), np.where((np.abs(lat) < 36) & (el > 25), -0.005 * (np.abs(lat) - 36), -0.005 * (np.abs(lat) - 36) + 1.8 - 4.25 * np.sin(np.deg2rad(el)))) A = A001 * (p / 0.01)**( -(0.655 + 0.033 * np.log(p) - 0.045 * np.log(A001) - beta * (1 - p) * np.sin(np.deg2rad(el)))) return A