def main(radial_file, save_dir, types=['tabular']):
    """
    Main function to parse and qc radial files
    :param radial_file: Path to radial file
    :param save_path: Path to save quality controlled radial file
    """
    save_dir = Path(save_dir)

    try:
        r = Radial(radial_file)
    except Exception:
        return

    if r.is_valid():
        sname = save_dir / r.file_name
        try:
            for t in types:
                r.export(sname, 'netcdf-{}'.format(t), prepend_ext=True)
        except ValueError:
            pass
Esempio n. 2
0
def plot_ruv(radial_file,
             save_path=None,
             fname=None,
             speed_display='color',
             redblue=True,
             plotflag=None,
             scale=50,
             vlims=(-100, 100)):
    """
    Main function to plot radial files.

    Args:
        radial_file (str or Path): Path to radial file or a Radial object
        save_path (str or Path): Path to save figures
        fname (str): Output file name. If not specified, the radial object filename is used,  Defaults to None
        speed_display (str, optional): 'color' or 'arrowlength' to specify whether current speed is depicted by color or arrow length, Defaults to color
        redblue (bool, optional): If True, colorbar scheme is redblue, Defaults to True
        plotflag (str, optional): QARTOD QC test code, fail and suspect flags for that test will be highlighted, Defaults to None
        scale (int, optional): Scaling factor for drawing the vectors, Default = 50
        vlims (tuple, optional): Velocity limits for the colorbar, Default = (-100,100)
    """
    if not isinstance(radial_file, Radial):
        r = Radial(radial_file)
    else:
        r = radial_file

    if not r.is_valid():
        return
    if r._iscorrupt:
        return

    if fname == None:
        fname = r.file_name[0:-4]

    # Adjust some standard plotting settings to make them the size of a sheet of paper
    fig_size = plt.rcParams["figure.figsize"]
    fig_size[0] = 12
    fig_size[1] = 8
    plt.rcParams["figure.figsize"] = fig_size

    # Set colors of the land.
    edgecolor = 'black'
    landcolor = 'tan'

    LAND = cfeature.NaturalEarthFeature('physical',
                                        'land',
                                        '10m',
                                        edgecolor='face',
                                        facecolor='tan')

    state_lines = cfeature.NaturalEarthFeature(
        category='cultural',
        name='admin_1_states_provinces_lines',
        scale='50m',
        facecolor='none')
    bf = 0.3  #degrees
    extent = [
        r.data.LOND.min() - bf,
        r.data.LOND.max() + bf,
        r.data.LATD.min() - bf,
        r.data.LATD.max() + bf
    ]

    # Split out everything into seperate variables in order to pass them easier to the plotting functions
    time = r.time
    lon = r.data.LOND.to_numpy()
    lat = r.data.LATD.to_numpy()
    u = r.data.VELU.to_numpy()
    v = r.data.VELV.to_numpy()
    velocity = r.data.VELO.to_numpy()
    sitename = r.metadata['Site'][0:4]
    ptype = r.metadata['PatternType']

    # Mask nans just in case there are any
    u = ma.masked_invalid(u)
    v = ma.masked_invalid(v)

    # convert U and V component velocities to angle and speed
    angle, speed = uv2spdir(u, v)

    # convert angle and speed right back back to U and V component velocities,
    # Passing speed as an array of 1's allows for the normalizing of the arrow sizes
    # if we pass the correct
    u, v = spdir2uv(np.ones_like(speed), angle, deg=True)

    # Get the receiver location
    receiver_location = [float(x) for x in r.metadata['Origin'].split('  ')]
    receiver_location.reverse()

    # Intialize an empty subplot using cartopy
    fig, ax = plt.subplots(figsize=(11, 8),
                           subplot_kw=dict(projection=ccrs.Mercator()))
    #plt.quiver(lon, lat, u, v, transform=ccrs.PlateCarree())
    plt.plot(receiver_location[0],
             receiver_location[1],
             'o',
             markersize=10,
             markeredgecolor='black',
             color='red',
             transform=ccrs.PlateCarree())

    map_features(ax, extent, LAND, edgecolor, landcolor, state_lines)

    # The next lines specify the arrow shapes. You can customize this to your preference, usually by trial and error.
    # scale = 50
    headwidth = 2.5
    headlength = 4
    headaxislength = 4
    sub = 1

    # if user requested speed displayed as arrow length
    if speed_display == 'arrowlength':

        scale_units = 'width'
        width = 0.005

        if not plotflag == None:
            fail = r.data[plotflag] == 4
            suspect = r.data[plotflag] == 3
            noteval = r.data[plotflag] == 2
            away = r.data.VELO > 0
            plt.quiver(lon,
                       lat,
                       u,
                       v,
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='lightpink')
            plt.quiver(lon[away],
                       lat[away],
                       u[away],
                       v[away],
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='lightblue')
            #plt.quiver(lon, lat, u, v, transform=ccrs.PlateCarree(), scale=scale, color='white')
            plt.quiver(lon[fail],
                       lat[fail],
                       u[fail],
                       v[fail],
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='red')
            plt.quiver(lon[suspect],
                       lat[suspect],
                       u[suspect],
                       v[suspect],
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='gold')
            plt.quiver(lon[noteval],
                       lat[noteval],
                       u[noteval],
                       v[noteval],
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='gray')
            plt.title(
                f'{sitename} {ptype} {plotflag}\nFail(red) Suspect(yellow) Not Evaluated(grey)\n{time}'
            )
            plt.savefig(save_path + '/' + fname + '_' + plotflag)
            plt.close('all')
        elif redblue:
            away = r.data.VELO > 0
            plt.quiver(lon,
                       lat,
                       u,
                       v,
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='red')
            plt.quiver(lon[away],
                       lat[away],
                       u[away],
                       v[away],
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='blue')
            plt.title(f'{sitename} {ptype}\n{time}')
            plt.savefig(save_path + '/' + fname + '_rb')
            plt.close('all')
        else:
            plt.quiver(lon,
                       lat,
                       u,
                       v,
                       transform=ccrs.PlateCarree(),
                       scale=scale,
                       scale_units=scale_units,
                       width=width,
                       color='wheat')
            plt.title(f'{sitename} {ptype}\n{time}')
            plt.savefig(save_path + '/' + fname)
            plt.close('all')

    # if user requested speed displayed as color
    else:
        if not plotflag == None:

            test = r.data[plotflag]
            velocity[np.where(test >= 0)] = 1
            velocity[np.where(test == 4)] = -1

            color_clipped = np.clip(r.data.VELO[::sub], -1, 1).squeeze()
            offset = TwoSlopeNorm(vmin=-1, vcenter=0, vmax=1)
            cmap = colors.ListedColormap(['red', 'wheat'])

            plt.title(f'{sitename} {ptype} {plotflag} Fail\n{time}')

            qargs = dict(cmap=cmap,
                         scale=scale,
                         headwidth=headwidth,
                         headlength=headlength,
                         headaxislength=headaxislength)
            qargs['transform'] = ccrs.PlateCarree()
            qargs['norm'] = offset

            # plot arrows over pcolor
            h = ax.quiver(lon[::sub], lat[::sub], u[::sub], v[::sub],
                          color_clipped, **qargs)

            plt.savefig(save_path + '/' + fname + '_' + plotflag + '_fail')
            plt.close('all')

        elif redblue:

            cmap = 'bwr'
            # velocity_temp = velocity.where(velocity > 0, other=-1)  # Going away from radar
            velocity[np.where(velocity < 0)] = -1
            velocity[np.where(velocity >= 0)] = 1
            # We will create temporary variable of velocities that sets any velocity less than 0 to 1
            # color_clipped = velocity_temp.where(velocity < 0, other=1)  # Going towards radar
            # Define arrow colors. Limited by velocity_min and velocity_max
            color_clipped = np.clip(r.data.VELO[::sub], -1, 1).squeeze()

            offset = TwoSlopeNorm(vmin=-1, vcenter=0, vmax=1)

            plt.title(f'{sitename} {ptype}\n{time}')

            qargs = dict(cmap=cmap,
                         scale=scale,
                         headwidth=headwidth,
                         headlength=headlength,
                         headaxislength=headaxislength)
            qargs['transform'] = ccrs.PlateCarree()
            qargs['norm'] = offset

            # plot arrows over pcolor
            h = ax.quiver(lon[::sub], lat[::sub], u[::sub], v[::sub],
                          color_clipped, **qargs)
            # map_features(ax, extent, LAND, edgecolor, landcolor, state_lines)
            plt.savefig(save_path + '/' + fname + '_rb')
            plt.close('all')

        else:

            plt.title(f'{sitename} {ptype}\n{time}')

            cmap = cmocean.cm.balance
            # Colorbar options
            velocity_min = vlims[
                0]  # The minimum speed that should be displayed on the colorbar
            velocity_max = vlims[
                1]  # The maximum speed that should be displayed on the colorbar
            cbar_step = 10  # The step between each colorbar tick

            offset = Normalize(vmin=velocity_min, vmax=velocity_max, clip=True)

            # Define arrow colors. Limited by velocity_min and velocity_max
            color_clipped = np.clip(r.data.VELO[::sub], velocity_min,
                                    velocity_max).squeeze()

            ticks = np.append(np.arange(velocity_min, velocity_max, cbar_step),
                              velocity_max)

            qargs = dict(cmap=cmap,
                         scale=scale,
                         headwidth=headwidth,
                         headlength=headlength,
                         headaxislength=headaxislength)
            qargs['transform'] = ccrs.PlateCarree()
            qargs['norm'] = offset

            # plot arrows over pcolor
            h = ax.quiver(lon[::sub], lat[::sub], u[::sub], v[::sub],
                          color_clipped, **qargs)

            # map_features(ax, extent, LAND, edgecolor, landcolor, state_lines)

            # generate colorbar
            divider = make_axes_locatable(ax)
            cax = divider.new_horizontal(size='5%',
                                         pad=0.05,
                                         axes_class=plt.Axes)
            fig.add_axes(cax)

            cb = plt.colorbar(h, cax=cax, ticks=ticks)
            cb.ax.set_yticklabels([f'{s:d}' for s in ticks])
            cb.set_label('cm/s')

            plt.savefig(save_path + '/' + fname)
            plt.close('all')