def get_data(self, tilt:int, drange:Number_T, dtype:str) -> Radial: if isinstance(dtype, str): self.dtype = dtype.upper().encode() elif isinstance(dtype, bytes): self.dtype = dtype.upper() if self.dtype in [b'REF', b'VEL', b'ZDR', b'PHI', b'RHO']: if self.dtype in [b'ZDR', b'PHI', b'RHO'] and tilt in [1, 3]: tilt -= 1 warnings.warn('Elevation angle {} does not contain {} data, automatically switch to tilt {}'.format( tilt + 1, self.dtype.decode(), tilt)) elif self.dtype in [b'VEL', b'SW'] and tilt in [0, 2]: tilt += 1 warnings.warn('Elevation angle {} does not contain {} data, automatically switch to tilt {}'.format( tilt - 1, self.dtype.decode(), tilt)) hdr = self.f.sweeps[tilt][0][4][self.dtype][0] self.reso = hdr.gate_width raw = np.array([ray[4][self.dtype][1] for ray in self.f.sweeps[tilt]]) else: raise RadarDecodeError('Unsupported data type {}'.format(self.dtype.decode())) cut = raw[:, :int(drange / self.reso)] masked = np.ma.array(cut, mask=np.isnan(cut)) self.tilt = tilt self.drange = drange self.elev = self.el[tilt] x, y, z, d, a = self.projection(self.reso) radial = Radial(masked, drange, self.elev, self.reso, self.name, self.name, self.scantime, self.dtype.decode(), self.stationlon, self.stationlat, x, y, a_reso=720) radial.add_polarc(d, a) return radial
def max_potential_gust(r_list: Volume_T) -> Radial: r""" Estimate maximum potential descending gust by Stewart's formula Paramters --------- r_list: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid Wind gust """ r_data, d, a, elev = _extract(r_list) i = r_list[0] g = potential_maximum_gust_from_reflectivity(r_data, d, elev) l2_obj = Radial( np.ma.array(g, mask=(g <= 0)), i.drange, 0, i.reso, i.code, i.name, i.scantime, "GUST", i.stp["lon"], i.stp["lat"], **i.scan_info ) lon, lat = get_coordinate(d[0], a.T[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.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 quick_vild(r_list: RList) -> Radial: r''' Calculate vertically integrated liquid density Paramters --------- r_list: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid vertically integrated liquid density ''' 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), density=True) vild = np.ma.masked_invalid(vil) l2_obj = Radial(np.ma.array(vild, mask=(vild <= 0.1)), i.drange, 0, i.reso, i.code, i.name, i.scantime, 'VILD', 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_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 get_data(self) -> Union[Grid, Radial]: if self.radial_flag: lon, lat = self.projection() return Radial( self.data, self.max_range, self.el, self.reso, self.code, self.name, self.scantime, self.dtype, self.stationlon, self.stationlat, lon, lat, ) else: return Grid( self.data, self.max_range, self.reso, self.code, self.name, self.scantime, self.dtype, self.stationlon, self.stationlat, self.lon, self.lat, )
def get_data(self, tilt:int, drange:Number_T, dtype:str) -> Radial: r''' Get radar data Parameters ---------- tilt: int index of elevation angle drange: float radius of data dtype: str type of product (REF, VEL, etc.) Returns ------- r_obj: cinrad.datastruct.Radial ''' task = getattr(self, 'task_name', None) reso = self.Rreso if dtype == 'REF' else self.Vreso ret = self.get_raw(tilt, drange, dtype) shape = ret[0].shape[1] if isinstance(ret, tuple) else ret.shape[1] r_obj = Radial(ret, int(np.round(shape * reso)), self.elev, reso, self.code, self.name, self.scantime, dtype, self.stationlon, self.stationlat, nyquist_velocity=self.nyquist_v[tilt], task=task) x, y, z, d, a = self.projection(reso) r_obj.add_geoc(x, y, z) r_obj.add_polarc(d, a) if self.radartype == 'CC': r_obj.a_reso = 512 return r_obj
def get_data(self, tilt, drange, dtype): r''' Get radar raw data Parameters ---------- tilt: int index of elevation angle drange: float radius of data dtype: str type of product (REF, VEL, etc.) Returns ------- r_obj: cinrad.datastruct.Radial ''' rf_flag = False self.tilt = tilt reso = self.Rreso if dtype == 'REF' else self.Vreso dmax = np.round(self.data[tilt][dtype][0].shape[0] * reso) if dmax < drange: warnings.warn('Requested data range exceed max range in this tilt') self.drange = drange self.elev = self.el[tilt] try: data = np.ma.array(self.data[tilt][dtype]) except KeyError: raise RadarDecodeError('Invalid product name') length = data.shape[1] * reso cut = data.T[:int(np.round(drange / reso))] shape_diff = np.round(drange / reso) - cut.shape[0] append = np.zeros( (int(np.round(shape_diff)), cut.shape[1])) * np.ma.masked if dtype == 'VEL': try: rf = self.data[tilt]['RF'] except KeyError: pass else: rf_flag = True rf = rf.T[:int(np.round(drange / reso))] rf = np.ma.vstack([rf, append]) #r = np.ma.array(cut, mask=np.isnan(cut)) r = np.ma.vstack([cut, append]) if rf_flag: r.mask = np.logical_or(r.mask, ~rf.mask) ret = (r.T, rf.T) else: ret = r.T r_obj = Radial(ret, int(np.round(r.shape[0] * reso)), self.elev, reso, self.code, self.name, self.scantime, dtype, self.stationlon, self.stationlat) x, y, z, d, a = self.projection(reso) r_obj.add_geoc(x, y, z) r_obj.add_polarc(d, a) if self.radartype == 'CC': r_obj.a_reso = 512 return r_obj
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)
def max_potential_gust(r_list: RList) -> Radial: r''' Estimate maximum potential descending gust by Stewart's formula Paramters --------- r_list: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid Wind gust ''' r_data, d, a, elev = _extract(r_list) i = r_list[0] g = potential_maximum_gust_from_reflectivity(r_data, d, elev) l2_obj = Radial(np.ma.array(g, mask=(g <= 0)), i.drange, 0, 1, i.code, i.name, i.scantime, 'GUST', i.stp['lon'], i.stp['lat']) lon, lat = get_coordinate(d[0], a.T[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:RList) -> 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, 1, i.code, i.name, i.scantime, 'ET', i.stp['lon'], i.stp['lat']) 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_vil(Rlist): r''' Calculate vertically integrated liquid Paramters --------- Rlist: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid vertically integrated liquid ''' r_data, d, a, elev = _extract(Rlist) i = Rlist[0] vil = vert_integrated_liquid(r_data, d, elev) l2_obj = Radial(np.ma.array(vil, mask=(vil <= 0)), i.drange, 0, 1, i.code, i.name, i.scantime, 'VIL', i.stp['lon'], i.stp['lat']) lon, lat = get_coordinate(d[0], a.T[0], 0, i.stp['lon'], i.stp['lat']) l2_obj.add_geoc(lon, lat, np.zeros(lon.shape)) return l2_obj
def quick_et(Rlist): r''' Calculate echo tops Paramters --------- Rlist: list of cinrad.datastruct.Radial Returns ------- l2_obj: cinrad.datastruct.Grid echo tops ''' r_data, d, a, elev = _extract(Rlist) i = Rlist[0] et = echo_top(r_data, d, elev, 0) l2_obj = Radial(et, i.drange, 0, 1, i.code, i.name, i.scantime, 'ET', i.stp['lon'], i.stp['lat']) lon, lat = get_coordinate(d[0], a.T[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, tilt: int, drange: Number_T, dtype: str ) -> Union[Radial, Slice_]: r""" Get radar data Parameters ---------- tilt: int index of elevation angle drange: float radius of data dtype: str type of product (REF, VEL, etc.) Returns ------- r_obj: cinrad.datastruct.Radial """ reso = self.scan_config[tilt].dop_reso / 1000 ret = self.get_raw(tilt, drange, dtype) if self.scan_type == "PPI": shape = ret[0].shape[1] if isinstance(ret, tuple) else ret.shape[1] r_obj = Radial( ret, int(shape * reso), self.elev, reso, self.code, self.name, self.scantime, dtype, self.stationlon, self.stationlat, nyquist_velocity=self.scan_config[tilt].nyquist_spd, task=self.task_name, ) x, y, z, d, a = self.projection(reso) r_obj.add_geoc(x, y, z) r_obj.add_polarc(d, a) return r_obj else: # Manual projection shape = ret[0].shape[1] if isinstance(ret, tuple) else ret.shape[1] dist = np.linspace(reso, self.drange, ret.shape[1]) d, e = np.meshgrid(dist, self.aux[tilt]["elevation"]) h = height(d, e, 0) rhi = Slice_( ret, d, h, self.scantime, self.code, self.name, dtype, azimuth=self.aux[tilt]["azimuth"][0], ) return rhi
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 get_data(self, tilt, drange, dtype): r''' Get radar raw data Parameters ---------- tilt: int index of elevation angle drange: float radius of data dtype: str type of product (REF, VEL, etc.) Returns ------- r_obj: cinrad.datastruct.Radial ''' self.tilt = tilt self.drange = drange self.elev = self.el[tilt] try: raw = np.array(self.data[tilt][dtype]) except KeyError: raise RadarDecodeError('Invalid product name') if raw.size == 0: warnings.warn('Empty data', RuntimeWarning) data = np.ma.array(raw, mask=(raw <= 5)) reso = self.scan_config[tilt].dop_reso / 1000 cut = data[:, :int(drange / reso)] shape_diff = np.round(drange / reso) - cut.shape[1] append = np.zeros((cut.shape[0], int(shape_diff))) * np.ma.masked if dtype == 'VEL': rf = np.ma.array(cut.data, mask=(cut.data != 1)) rf = np.ma.hstack([rf, append]) cut = np.ma.hstack([cut, append]) scale, offset = self.aux[tilt][dtype] r = (cut - offset) / scale if dtype == 'VEL': ret = (r, rf) else: ret = r r_obj = Radial(ret, int(r.shape[1] * reso), self.elev, reso, self.code, self.name, self.scantime, dtype, self.stationlon, self.stationlat) x, y, z, d, a = self.projection(reso) r_obj.add_geoc(x, y, z) r_obj.add_polarc(d, a) return r_obj
def get_data(self, tilt, drange, dtype): r''' Get radar raw data Parameters ---------- tilt: int index of elevation angle drange: float radius of data dtype: str type of product (REF, VEL, etc.) Returns ------- r_obj: cinrad.datastruct.Radial ''' self.tilt = tilt self.drange = drange self.elev = self.el[tilt] try: data = np.array(self.data[tilt][dtype]) except KeyError: raise RadarDecodeError('Invalid product name') if data.size == 0: raise RadarDecodeError( 'Current elevation does not contain this data.') reso = self.scanconfig[tilt]['radial_reso'] length = data.shape[1] * reso cut = data[:, :int(drange / reso)] r = np.ma.array(cut, mask=np.isnan(cut)) r_obj = Radial(r, int(r.shape[0] * reso), self.elev, reso, self.code, self.name, self.scantime, dtype, self.stationlon, self.stationlat) x, y, z, d, a = self.projection(reso) r_obj.add_geoc(x, y, z) r_obj.add_polarc(d, a) return r_obj
def get_data(self, tilt: int, drange: number_type, dtype: str) -> Radial: r''' Get radar raw data Parameters ---------- tilt: int index of elevation angle drange: float radius of data dtype: str type of product (REF, VEL, etc.) Returns ------- r_obj: cinrad.datastruct.Radial ''' self.tilt = tilt if self.scan_type == 'PPI' else 0 self.drange = drange if self.scan_type == 'RHI': max_range = self.scan_config[0].max_range1 / 1000 if drange > max_range: drange = max_range self.elev = self.el[tilt] try: raw = np.array(self.data[tilt][dtype]) except KeyError: raise RadarDecodeError('Invalid product name') if raw.size == 0: warnings.warn('Empty data', RuntimeWarning) data = np.ma.array(raw, mask=(raw <= 5)) reso = self.scan_config[tilt].dop_reso / 1000 cut = data[:, :int(drange / reso)] shape_diff = np.round(drange / reso) - cut.shape[1] append = np.zeros((cut.shape[0], int(shape_diff))) * np.ma.masked if dtype == 'VEL': rf = np.ma.array(cut.data, mask=(cut.data != 1)) rf = np.ma.hstack([rf, append]) cut = np.ma.hstack([cut, append]) scale, offset = self.aux[tilt][dtype] r = (cut - offset) / scale if dtype in ['VEL', 'SW']: ret = (r, rf) else: ret = r if self.scan_type == 'PPI': r_obj = Radial(ret, int(r.shape[1] * reso), self.elev, reso, self.code, self.name, self.scantime, dtype, self.stationlon, self.stationlat, nyquist_velocity=self.scan_config[tilt].nyquist_spd) x, y, z, d, a = self.projection(reso) r_obj.add_geoc(x, y, z) r_obj.add_polarc(d, a) return r_obj else: # Manual projection dist = np.linspace(reso, self.drange, cut.shape[1]) d, e = np.meshgrid(dist, self.aux[tilt]['elevation']) h = height(d, e, 0) rhi = Slice_(ret, d, h, self.scantime, self.code, self.name, dtype, azimuth=self.aux[tilt]['azimuth'][0]) return rhi
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()
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 get_data(self): lon, lat = self.projection() 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)