def quick_vil(r_list: Volume_T) -> Radial: r''' Calculate vertically integrated liquid Paramters --------- r_list: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid vertically integrated liquid ''' r_data, d, a, elev = _extract(r_list) i = r_list[0] vil = vert_integrated_liquid(r_data.astype(np.double), d.astype(np.double), elev.astype(np.double)) l2_obj = Radial(np.ma.array(vil, mask=(vil <= 0)), i.drange, 0, i.reso, i.code, i.name, i.scantime, 'VIL', i.stp['lon'], i.stp['lat'], **i.scan_info) lon, lat = get_coordinate(d[0], a[:, 0], 0, i.stp['lon'], i.stp['lat']) l2_obj.add_geoc(lon, lat, np.zeros(lon.shape)) return l2_obj
def quick_et(r_list: Volume_T) -> Radial: r''' Calculate echo tops Paramters --------- r_list: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid echo tops ''' r_data, d, a, elev = _extract(r_list) i = r_list[0] et = echo_top(r_data.astype(np.double), d.astype(np.double), elev.astype(np.double), 0.) l2_obj = Radial(np.ma.array(et, mask=(et < 2)), i.drange, 0, i.reso, i.code, i.name, i.scantime, 'ET', i.stp['lon'], i.stp['lat'], **i.scan_info) lon, lat = get_coordinate(d[0], a[:, 0], 0, i.stp['lon'], i.stp['lat']) l2_obj.add_geoc(lon, lat, np.zeros(lon.shape)) return l2_obj
def get_data(self): dist = np.arange(self.start_range, self.end_range, self.reso) lon, lat = get_coordinate( dist, self.azi, self.el, self.stationlon, self.stationlat ) hgt = height(dist, self.el, self.radarheight) radial = Radial( self.data, self.end_range, self.el, self.reso, self.code, self.name, self.scantime, self.dtype, self.stationlon, self.stationlat, lon, lat, height, task=self.task_name, ) return radial
def plot_range_rings( self, _range: Union[int, float, list], color: str = "white", linewidth: Number_T = 0.5, **kwargs ): r"""Plot range rings on PPI plot.""" slon, slat = self.data.site_longitude, self.data.site_latitude if isinstance(_range, (int, float)): _range = [_range] theta = np.linspace(0, 2 * np.pi, 800) for d in _range: x, y = get_coordinate(d, theta, 0, slon, slat, h_offset=False) # self.ax.plot(x, y, color=color, linewidth=linewidth, **kwargs) self.geoax.plot( x, y, color=color, linewidth=linewidth, transform=self.data_crs, **kwargs )
from metpy.io.nexrad import Level3File from tkinter import filedialog from metpy.plots import colortables from cinrad.datastruct import Radial from cinrad.projection import get_coordinate from cinrad.visualize import ppi name = filedialog.askopenfilename() f = Level3File(name) # Pull the data out of the file object datadict = f.sym_block[0][0] # Turn into an array, then mask data = np.array(datadict['data']).astype(float) data[data == 0] = np.nan rf = np.ma.array(data, mask=(data != 1)) # Grab azimuths and calculate a range based on number of gates az = np.deg2rad(datadict['start_az'] + [datadict['end_az'][-1]]) rng = np.linspace(0, f.max_range, data.shape[-1] + 1) elev = f.metadata['el_angle'] slon, slat = f.lon, f.lat scantime = f.metadata['msg_time'] lon, lat = get_coordinate(rng, az, elev, slon, slat) threshold = f.thresholds data = data * threshold[1] / 10 + threshold[0] / 10 v_obj = Radial([data, rf], int(f.max_range), elev, f.ij_to_km, f.siteID, f.siteID, scantime.strftime('%Y%m%d%H%M%S'), 'VEL', slon, slat) v_obj.add_geoc(lon, lat, np.zeros(lon.shape)) norm2, v_cmap = colortables.get_with_range('NWS8bitVel', -64, 64) fig = ppi.PPI(v_obj, coastline=True, norm=norm2, cmap=v_cmap, nlabel=17) fig()
def current(self, storm_id:str) -> tuple: curpos = self.info[storm_id]['current storm position'] dist, az = self.xy2polar(*curpos) lonlat = get_coordinate(dist, az * deg2rad, 0, self.handler.lon, self.handler.lat, h_offset=False) return lonlat
def get_data(self, tilt: int, drange: Number_T, dtype: str) -> xr.Dataset: r""" Get radar data with extra information Args: tilt (int): Index of elevation angle starting from zero. drange (float): Radius of data. dtype (str): Type of product (REF, VEL, etc.) Returns: xarray.Dataset: Data. """ reso = self.scan_config[tilt].dop_reso / 1000 ret = self.get_raw(tilt, drange, dtype) shape = ret[0].shape[1] if isinstance(ret, tuple) else ret.shape[1] if self.scan_type == "PPI": x, y, z, d, a = self.projection(reso) if dtype in ["VEL", "SW"]: da = xr.DataArray(ret[0], coords=[a, d], dims=["azimuth", "distance"]) else: da = xr.DataArray(ret, coords=[a, d], dims=["azimuth", "distance"]) ds = xr.Dataset( {dtype: da}, attrs={ "elevation": self.elev, "range": int(np.round(shape * reso)), "scan_time": self.scantime.strftime("%Y-%m-%d %H:%M:%S"), "site_code": self.code, "site_name": self.name, "site_longitude": self.stationlon, "site_latitude": self.stationlat, "tangential_reso": reso, "nyquist_vel": self.scan_config[tilt].nyquist_spd, "task": self.task_name, }, ) ds["longitude"] = (["azimuth", "distance"], x) ds["latitude"] = (["azimuth", "distance"], y) ds["height"] = (["azimuth", "distance"], z) if dtype in ["VEL", "SW"]: ds["RF"] = (["azimuth", "distance"], ret[1]) else: # Manual projection dist = np.linspace(reso, self.drange, ret.shape[1]) azimuth = self.aux[tilt]["azimuth"][0] elev = self.aux[tilt]["elevation"] d, e = np.meshgrid(dist, elev) h = height(d, e, self.radarheight) if dtype in ["VEL", "SW"]: da = xr.DataArray( ret[0], coords=[elev, dist], dims=["tilt", "distance"] ) else: da = xr.DataArray(ret, coords=[elev, dist], dims=["tilt", "distance"]) # Calculate the "start" and "end" of RHI scan # to facilitate tick labeling start_lon = self.stationlon start_lat = self.stationlat end_lon, end_lat = get_coordinate( drange, azimuth * deg2rad, 0, self.stationlon, self.stationlat ) ds = xr.Dataset( {dtype: da}, attrs={ "range": drange, "scan_time": self.scantime.strftime("%Y-%m-%d %H:%M:%S"), "site_code": self.code, "site_name": self.name, "site_longitude": self.stationlon, "site_latitude": self.stationlat, "tangential_reso": reso, "azimuth": azimuth, "start_lon": start_lon, "start_lat": start_lat, "end_lon": end_lon, "end_lat": end_lat, }, ) ds["x_cor"] = (["tilt", "distance"], d) ds["y_cor"] = (["tilt", "distance"], h) return ds
from cinrad.visualize import ppi from cinrad.constants import deg2rad name = filedialog.askopenfilename() radar = pyart.io.read_nexrad_archive(name) sweep = 1 drange = 300 irange = radar.get_start_end(sweep) cali = pyart.correct.dealias_region_based(radar) v = cali['data'][irange[0]:irange[1] + 1] az = radar.get_azimuth(sweep) * deg2rad az = np.append(az, az[0]) v_range = radar.range['data'] / 1000 reso = radar.range['meters_between_gates'] / 1000 v_ori = radar.get_field(sweep, 'velocity').T[:int(drange / reso)].T slon, slat = radar.longitude['data'][0], radar.latitude['data'][0] scantime = datetime.datetime.strptime(radar.time['units'], 'seconds since %Y-%m-%dT%H:%M:%SZ') el = radar.get_elevation(sweep)[0] lon, lat = get_coordinate(v_range[:int(drange / reso)], az, el, slon, slat) timestr = scantime.strftime('%Y%m%d%H%M%S') data = v.T[:int(drange / reso)].T data_f = np.ma.array(data, mask=v_ori.mask) data_f = np.concatenate((data_f, data_f[0, None])) data_f[data_f == -64.5] = np.ma.masked rf = np.ma.array(data_f, mask=(data_f != -64)) v_obj = Radial([data_f, rf], drange, el, reso, 'PGUA', 'PGUA', timestr, 'VEL', slon, slat) v_obj.add_geoc(lon, lat, np.zeros(lon.shape)) norm2, v_cmap = colortables.get_with_range('NWS8bitVel', -64, 64) fig = ppi.PPI(v_obj, coastline=True, norm=norm2, cmap=v_cmap, nlabel=17) fig()
def projection(self) -> tuple: return get_coordinate(self.rng, self.az, self.el, self.stationlon, self.stationlat, h_offset=False)
def projection(self, reso:float) -> tuple: r = np.arange(reso, self.drange + reso, reso) theta = np.array(self.aux[self.tilt]['azimuth']) * deg2rad lonx, latx = get_coordinate(r, theta, self.elev, self.stationlon, self.stationlat) hght = height(r, self.elev, self.radarheight) * np.ones(theta.shape[0])[:, np.newaxis] return lonx, latx, hght, r, theta
def get_data(self): lon, lat = get_coordinate(self.rng, self.az, self.el, self.stationlon, self.stationlat, h_offset=False) return Radial(self.data, int(self.rng[-1]), self.el, 1, self.code, self.name, self.scantime.strftime('%Y%m%d%H%M%S'), self.dtype, self.stationlon, self.stationlat, lon, lat)