Source code for pyart.correct.dealias

"""
Front end to the University of Washington 4DD code for Doppler dealiasing.

"""

import numpy as np

from ..config import get_field_name, get_fillvalue, get_metadata
try:
    from ..io import _rsl_interface
    from . import _fourdd_interface
    _FOURDD_AVAILABLE = True
except ImportError:
    _FOURDD_AVAILABLE = False
from ._common_dealias import _parse_gatefilter, _set_limits
from ..exceptions import MissingOptionalDependency


[docs]def dealias_fourdd( radar, last_radar=None, sonde_profile=None, gatefilter=False, filt=1, rsl_badval=131072.0, keep_original=False, set_limits=True, vel_field=None, corr_vel_field=None, last_vel_field=None, debug=False, max_shear=0.05, sign=1, **kwargs): """ Dealias Doppler velocities using the 4DD algorithm. Dealias the Doppler velocities field using the University of Washington 4DD algorithm utilizing information from a previous volume scan and/or sounding data. Either last_radar or sonde_profile must be provided. For best results provide both a previous volume scan and sounding data. Radar and last_radar must contain the same number of rays per sweep. Additional arguments are passed to :py:func:`_fourdd_interface.fourdd_dealias`. These can be used to fine tune the behavior of the FourDD algorithm. See the documentation of Other Parameters for details. For the default values of these parameters see the documentation of :py:func:`_fourdd_interface.fourdd_dealias`. Parameters ---------- radar : Radar Radar object to use for dealiasing. Must have a Nyquist defined in the instrument_parameters attribute and have a reflectivity_horizontal and mean_doppler_velocity fields. last_radar : Radar, optional The previous radar volume, which has been successfully dealiased. Using a previous volume as an initial condition can greatly improve the dealiasing, and represents the final dimension in the 4DD algorithm. sonde_profile : HorizontalWindProfile, optional Profile of horizontal winds from a sonding used for the initial condition of the dealiasing. Other Parameters ---------------- gatefilter : GateFilter, optional. A GateFilter instance which specifies which gates should be ignored when performing velocity dealiasing. A value of None will create this filter from the radar moments using any additional arguments by passing them to :py:func:`moment_based_gate_filter`. The default value assumes all gates are valid. filt : int, optional Flag controlling Bergen and Albers filter, 1 = yes, 0 = no. rsl_badval : float, optional Value which represents a bad value in RSL. keep_original : bool, optional True to keep original doppler velocity values when the dealiasing procedure fails, otherwise these gates will be masked. NaN values are still masked. set_limits : bool, optional True to set valid_min and valid_max elements in the returned dictionary. False will not set these dictionary elements. vel_field : str, optional Field in radar to use as the Doppler velocities during dealiasing. None will use the default field name from the Py-ART configuration file. corr_vel_field : str, optional Name to use for the dealiased Doppler velocity field metadata. None will use the default field name from the Py-ART configuration file. last_vel_field : str, optional Name to use for the dealiased Doppler velocity field metadata in last_radar. None will use the corr_vel_field name. maxshear : float, optional Maximum vertical shear which will be incorporated into the created volume from the sounding data. Parameter not used when no sounding data is provided. sign : int, optional Sign convention which the radial velocities in the volume created from the sounding data will will. This should match the convention used in the radar data. A value of 1 represents when positive values velocities are towards the radar, -1 represents when negative velocities are towards the radar. compthresh : float, optional Fraction of the Nyquist velocity to use as a threshold when performing continuity (initial) dealiasing. Velocities differences above this threshold will not be marked as gate from which to begin unfolding during spatial dealiasing. compthresh2 : float, optional The same as compthresh but the value used during the second pass of dealiasing. This second pass is only performed in both a sounding and last volume are provided. thresh : float, optional Fraction of the Nyquist velocity to use as a threshold when performing spatial dealiasing. Horizontally adjacent gates with velocities above this threshold will count against assigning the gate in question the velocity value being tested. ckval : float, optional When the absolute value of the velocities are below this value they will not be marked as gates from which to begin unfolding during spatial dealiasing. stdthresh : float, optional Fraction of the Nyquist velocity to use as a standard deviation threshold in the window dealiasing portion of the algorithm. epsilon : float, optional Difference used when comparing a value to missing value, changing this from the default is not recommended. maxcount : int, optional Maximum allowed number of fold allowed when unfolding velocities. pass2 : int, optional Controls weather unfolded gates should be removed (a value of 0) or retained for unfolding during the second pass (a value of 1) when both a sounding volume and last volume are provided. rm : int, optional Determines what should be done with gates that are left unfolded after the first pass of dealiasing. A value of 1 will remove these gates, a value of 0 sets these gates to their initial velocity. If both a sounding volume and last volume are provided this parameter is ignored. proximity : int, optional Number of gates and rays to include of either side of the current gate during window dealiasing. This value may be doubled in cases where a standard sized window does not capture a sufficient number of good valued gates. mingood : int, optional Number of good valued gates required within the window before the current gate will be unfolded. ba_mincount : int, optional Number of neighbors required during Bergen and Albers filter for a given gate to be included, must be between 1 and 8, 5 recommended. ba_edgecount : int, optional Same as ba_mincount but used at ray edges, must be between 1 and 5, 3 recommended. debug : bool, optional Set True to return RSL Volume objects for debugging: usuccess, radialVelVolume, lastVelVolume, unfoldedVolume, sondVolume Returns ------- vr_corr : dict Field dictionary containing dealiased Doppler velocities. Dealiased array is stored under the 'data' key. Notes ----- Due to limitations in the C code do not call with sounding arrays over 999 elements long. References ---------- C. N. James and R. A Houze Jr, A Real-Time Four-Dimensional Doppler Dealising Scheme, Journal of Atmospheric and Oceanic Technology, 2001, 18, 1674. """ # check that FourDD is available (requires TRMM RSL) if not _FOURDD_AVAILABLE: raise MissingOptionalDependency( "Py-ART must be build with support for TRMM RSL to use" + " the dealias_fourdd function.") # verify that sounding data or last_volume is provided if (sonde_profile is None) and (last_radar is None): raise ValueError('sonde_profile or last_radar must be provided.') # parse the field parameters if vel_field is None: vel_field = get_field_name('velocity') if corr_vel_field is None: corr_vel_field = get_field_name('corrected_velocity') if last_vel_field is None: last_vel_field = get_field_name('corrected_velocity') # get fill value fill_value = get_fillvalue() # parse radar gate filter gatefilter = _parse_gatefilter(gatefilter, radar, **kwargs) excluded = gatefilter.gate_excluded # create RSL volumes containing the doppler velocity and # doppler velocity in the last radar (if provided) vel_volume = _create_rsl_volume(radar, vel_field, 1, rsl_badval, excluded) if last_radar is not None: last_vel_volume = _create_rsl_volume( last_radar, last_vel_field, 1, rsl_badval) else: last_vel_volume = None # create an RslVolume containing the sounding data if it available if sonde_profile is not None: # convert the sounding data to 1D float32 arrays height = np.ascontiguousarray(sonde_profile.height, dtype=np.float32) speed = np.ascontiguousarray(sonde_profile.speed, dtype=np.float32) wdir = np.ascontiguousarray(sonde_profile.direction, dtype=np.float32) if len(height) > 999: raise ValueError("Too many sounding heights, maximum is 999") success, sound_volume = _fourdd_interface.create_soundvolume( vel_volume, height, speed, wdir, sign, max_shear) if success == 0: raise ValueError('Error when loading sounding data.') else: sound_volume = None # perform dealiasing if debug: return _fourdd_interface.fourdd_dealias( vel_volume, last_vel_volume, sound_volume, filt, debug=True, **kwargs) _, data = _fourdd_interface.fourdd_dealias( vel_volume, last_vel_volume, sound_volume, filt, debug=False, **kwargs) # prepare data for output, set bad values and mask data is_bad_data = np.logical_or(np.isnan(data), data == rsl_badval) if keep_original: vel_array = radar.fields[vel_field]['data'] data = np.where(is_bad_data, vel_array, data) else: data[is_bad_data] = fill_value data = np.ma.masked_equal(data, fill_value) # return field dictionary containing dealiased Doppler velocities vr_corr = get_metadata(corr_vel_field) vr_corr['data'] = data vr_corr['_FillValue'] = data.fill_value if set_limits: nyquist_vel = radar.instrument_parameters['nyquist_velocity']['data'] _set_limits(data, nyquist_vel, vr_corr) return vr_corr
def _create_rsl_volume(radar, field_name, vol_num, rsl_badval, excluded=None): """ Create a RSLVolume containing data from a field in radar. """ fill_value = get_fillvalue() fdata = np.copy(radar.fields[field_name]['data']).astype(np.float32) fdata = np.ma.filled(fdata, fill_value) is_bad = np.logical_or(fdata == fill_value, np.isnan(fdata)) fdata[is_bad] = rsl_badval if excluded is not None: fdata[excluded] = rsl_badval rays_per_sweep = (radar.sweep_end_ray_index['data'] - radar.sweep_start_ray_index['data'] + 1) rays_per_sweep = rays_per_sweep.astype(np.int32) rsl_volume = _rsl_interface.create_volume(fdata, rays_per_sweep, vol_num) _rsl_interface._label_volume(rsl_volume, radar) return rsl_volume