Source code for towerpy.io.empty

"""Towerpy: an open-source toolbox for processing polarimetric radar data."""

import datetime as dt
from zoneinfo import ZoneInfo
import numpy as np
from ..georad import georef_rdata as geo


[docs] class Rad_scan: """ A Towerpy class to store radar scan data. Attributes ---------- elev_angle : float Elevation angle at which the scan was taken, in deg. file_name : str Name of the file containing radar data. scandatetime : datetime Date and time of scan. site_name : str Name of the radar site. georef : dict Georeferenced data containing descriptors of the azimuth, gates and beam height, amongst others. params : dict Radar technical details. vars : dict Radar variables. """ def __init__(self, filename, site_name=None):
[docs] self.file_name = filename
[docs] self.site_name = site_name
[docs] def ppi_emptylike(self, nrays=360, ngates=425, elev=0.5, rad_vars='default', scandt=None, tz='Europe/London'): r""" Create an empty object listing different radar parameters. Parameters ---------- nrays : int Number of rays on the radar sweep. The default is 360. ngates : int, optional Number of bins comprising the radar rays. The default is 425. elev : float, optional Elevation angle of the radar scan. The default is 0.5. rad_vars : list, optional Polarimetric variables to add to the object. The default are: :math:`Z_{H} [dBZ]`, :math:`Z_{DR} [dB]`, :math:`\rho_{HV} [-]`, :math:`\Phi_{DP} [deg]`, :math:`V [m/s]` The default is 'default'. scandt : datetime, optional Date and time of the scan. If not provided, datetime.now is used. The default is None. tz : str Key/name of the radar data timezone. The given tz string is then retrieved from the ZoneInfo module. Default is 'Europe/London' """ # add aditional pol vars defined by the user if rad_vars == 'default': radvars = ['ZH [dBZ]', 'ZDR [dB]', 'PhiDP [deg]', 'rhoHV [-]', 'V [m/s]'] else: radvars = rad_vars # create dicts to store the empty arrays # poldata = {i: np.empty([nrays, ngates],dtype=float) for i in radvars} poldata = {i: np.nan for i in radvars} parameters = {'nvars': len(radvars), 'ngates': int(ngates), 'nrays': int(nrays), 'gateres [m]': np.nan, 'rpm': np.nan, 'prf [Hz]': np.nan, 'pulselength [ns]': np.nan, 'avsamples': np.nan, 'wavelength [cm]': np.nan, 'latitude [dd]': np.nan, 'longitude [dd]': np.nan, 'altitude [m]': 0, 'easting [km]': np.nan, 'northing [km]': np.nan, 'radar constant [dB]': 0, 'elev_ang [deg]': elev, 'beamwidth [deg]': 1.} if scandt is None: parameters['datetime'] = dt.datetime.now(tz=ZoneInfo(tz)) nowdt = [dt.datetime.now(tz=ZoneInfo(tz)).year, dt.datetime.now(tz=ZoneInfo(tz)).month, dt.datetime.now(tz=ZoneInfo(tz)).day, dt.datetime.now(tz=ZoneInfo(tz)).hour, dt.datetime.now(tz=ZoneInfo(tz)).minute, dt.datetime.now(tz=ZoneInfo(tz)).second] parameters['datetimearray'] = nowdt else: parameters['datetime'] = scandt.replace(tzinfo=ZoneInfo(tz)) udt = list(parameters['datetime'].timetuple())[: -3] parameters['datetimearray'] = udt self.vars = poldata self.params = parameters self.elev_angle = parameters['elev_ang [deg]'] self.scandatetime = parameters['datetime']
[docs] def ppi_create_georef(self, polarc_exist=True, elev=0.5, gate0=0, gateres=250): """ Create a georeferenced grid for the empty object. Parameters ---------- polarc_exist : bool If True, polar coordinates (range, azimuth, elevation) are read directly from the georef attribute. If False, synthesise elevation, azimuth, and range. The default is True elev : float Elevation angle in degrees (used if `polarc_exist=False`). The default is 0.5 gate0 : float Starting range gate in metres (used if `polarc_exist=False`). The default is 0 gateres : float Gate resolution in metres (used if `polarc_exist=False`). The default is 250 Notes ----- 1. Polar coordinates (azimuth, elevation) are expected to be in radians, and range values are expected to be in metres. 2. Some radar technical details are read from Rad_scan.params 3. This method wraps :func:`geo.ppi_georef` and updates the object's `georef` attribute with computed Cartesian grids and beam heights. """ if polarc_exist: geogrid, _ = geo.ppi_georef(self.params, georef=self.georef) else: geogrid, geopolc = geo.ppi_georef( self.params, polarc_exist=False, elev=elev, gate0=gate0, gateres=gateres) # Update resolution in params self.params['gateres [m]'] = gateres if hasattr(self, 'georef'): self.georef.update(geogrid) else: self.georef = {'azim [rad]': geopolc['azim [rad]'], 'elev [rad]': geopolc['elev [rad]'], 'range [m]': geopolc['range [m]']} self.georef.update(geogrid)