def lon_lat_to_cartesian(lon, lat, radius=1): """ calculates lon, lat coordinates of a point on a sphere with radius radius """ # Unpack xarray object into plane arrays if hasattr(lon, 'data'): lon = lon.data if hasattr(lat, 'data'): lat = lat.data if lon.ndim != lat.ndim: raise ValueError('coordinate must share the same number of dimensions') if lon.ndim == 1: lon, lat = np.meshgrid(lon, lat) lon_r = xu.radians(lon) lat_r = xu.radians(lat) x = radius * xu.cos(lat_r) * xu.cos(lon_r) y = radius * xu.cos(lat_r) * xu.sin(lon_r) z = radius * xu.sin(lat_r) return x.flatten(), y.flatten(), z.flatten()
def distance_to_point(self, lat, lon): """ Use Haversine formula to estimate distances from all gridpoints to a given location (lat, lon) """ R = 6371. # Radius of earth in km lat = np.radians(lat) lon = np.radians(lon) dlat = lat - xu.radians(self['lat'].values) dlon = lon - xu.radians(self['lon'].values) a = xu.sin(dlat/2)**2 + xu.cos(lat) * xu.cos(xu.radians(self['lat'].values)) * \ xu.sin(dlon/2)**2 c = 2 * xu.arctan2(xu.sqrt(a), xu.sqrt(1.0-a)) return R*c
def distance_to_point(self, lat, lon): """ Use Haversine formula to estimate distances from all gridpoints to a given location (lat, lon) """ R = 6371. # Radius of earth in km lat = np.radians(lat) lon = np.radians(lon) dlat = lat - xu.radians(self['lat'].values) dlon = lon - xu.radians(self['lon'].values) a = xu.sin(dlat/2)**2 + xu.cos(lat) * xu.cos(xu.radians(self['lat'].values)) * \ xu.sin(dlon/2)**2 c = 2 * xu.arctan2(xu.sqrt(a), xu.sqrt(1.0 - a)) return R * c
def nearest_points(self, lat, lon, npt=1): """ Use the lat-lon arrays to return a list of indices of the nearest npt points to the given lat-lon """ # Use sin of lat lon to handle periodic # and not worry about if we are in negative # degrees dist = xu.hypot(xu.sin(xu.radians(self['lat'].values)) - xu.sin(xu.radians(lat)),\ xu.cos(xu.radians(self['lon'].values)) - xu.cos(xu.radians(lon))) # Get indices of the flattened array nearest_raw = dist.argsort(axis=None)[:npt] # Convert back to 2-d coords nearest = np.unravel_index(nearest_raw, self['lat'].shape) return nearest
def atmospheric_path_length_correction(data, cos_zen, limit=88.): """Perform Sun zenith angle correction. This function uses the correction method proposed by Li and Shibata (2006): https://doi.org/10.1175/JAS3682.1 The correction is limited to *limit* degrees (default: 88.0 degrees). For larger zenith angles, the correction is the same as at the *limit*. Both *data* and *cos_zen* are given as 2-dimensional Numpy arrays or Numpy MaskedArrays, and they should have equal shapes. """ # Convert the zenith angle limit to cosine of zenith angle limit = xu.cos(xu.radians(limit)) # Cosine correction corr = _get_sunz_corr_li_and_shibata(cos_zen) # Use constant value (the limit) for larger zenith # angles corr_lim = _get_sunz_corr_li_and_shibata(limit) corr = corr.where(cos_zen > limit).fillna(corr_lim) return data * corr