Source code for pyrad.prod.process_grid_products

"""
pyrad.prod.process_grid_products
================================

Functions for obtaining Pyrad products from gridded datasets

.. autosummary::
    :toctree: generated/

    generate_grid_time_avg_products
    generate_sparse_grid_products
    generate_grid_products

"""

from ..util import warn
from copy import deepcopy

import numpy as np

import pyart

from ..io.io_aux import get_fieldname_pyart
from ..io.io_aux import get_save_dir, make_filename
from ..io.write_data import write_histogram, write_ts_stats

from ..graph.plots_grid import plot_surface, plot_surface_raw
from ..graph.plots_grid import plot_longitude_slice, plot_latitude_slice
from ..graph.plots_grid import plot_cross_section, plot_surface_contour
from ..graph.plots_grid import plot_dda_map, plot_dda_slice

from ..graph.plots_aux import get_colobar_label, get_field_name
from ..graph.plots_aux import generate_dda_map_title
from ..graph.plots_aux import generate_dda_latitude_slice_title
from ..graph.plots_aux import generate_dda_longitude_slice_title
from ..graph.plots import plot_histogram, plot_pos

from ..util.radar_utils import compute_histogram


[docs] def generate_grid_time_avg_products(dataset, prdcfg): """ generates time average products. Accepted product types: All the products of the 'VOL' dataset group Parameters ---------- dataset : tuple radar objects and colocated gates dictionary prdcfg : dictionary of dictionaries product configuration dictionary of dictionaries Returns ------- filename : str the name of the file created. None otherwise """ prdcfg["timeinfo"] = dataset["timeinfo"] return generate_grid_products(dataset, prdcfg)
def generate_sparse_grid_products(dataset, prdcfg): """ generates products defined by sparse points. Accepted product types: 'SURFACE_IMAGE': Generates a surface image User defined parameters: 'field_limits': list of floats The limits of the surface to plot [deg] lon0, lon1, lat0, lat1 Parameters ---------- dataset : dictionary containing the points and their values prdcfg : dictionary of dictionaries product configuration dictionary of dictionaries Returns ------- no return """ dssavedir = prdcfg["dsname"] if "dssavename" in prdcfg: dssavedir = prdcfg["dssavename"] if prdcfg["type"] == "SURFACE_IMAGE": field_name = get_fieldname_pyart(prdcfg["voltype"]) if field_name not in dataset["radar_out"]["fields"]: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "surface", prdcfg["dstype"], prdcfg["voltype"], prdcfg["imgformat"], timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname cb_label = get_colobar_label( dataset["radar_out"]["fields"][field_name], field_name ) titl = ( prdcfg["timeinfo"].strftime("%Y-%m-%dT%H:%M%SZ") + "\n" + get_field_name(dataset["radar_out"]["fields"][field_name], field_name) ) if "field_limits" in prdcfg: field_limits = prdcfg["field_limits"] else: field_limits = dataset["radar_out"]["field_limits"] # get colobar limits vmin, vmax = pyart.config.get_field_limits(field_name) plot_pos( dataset["radar_out"]["lat"], dataset["radar_out"]["lon"], dataset["radar_out"]["fields"][field_name]["data"], fname_list, cb_label=cb_label, titl=titl, limits=field_limits, vmin=vmin, vmax=vmax, ) print("----- save to " + " ".join(fname_list)) return fname_list warn(" Unsupported product type: " + prdcfg["type"]) return None
[docs] def generate_grid_products(dataset, prdcfg): """ generates grid products. Accepted product types: 'CROSS_SECTION': Plots a cross-section of gridded data User defined parameters: voltype: str Name of the pyrad variable to use, it must be either a voltype available in the dataset or "RGB", which will make a RGB plot of Zh, Zdr and RhoHV (if they are available) coord1: dict Lat, lon coordinates of the start point. It must be a dict with the keywords 'lat' and 'lon' [degree]. The altitude limits are defined by the parameters ymin, ymax in 'xsecImageConfig' in the 'loc' configuration file coord2: dict Lat, lon coordinates of the end point. It must be a dict with the keywords 'lat' and 'lon' [degree]. The altitude limits are defined by the parameters ymin, ymax in 'xsecImageConfig' in the 'loc' configuration file 'HISTOGRAM': Computes a histogram of the radar volum data User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset step: float or None the data quantization step. If none it will be obtained from the Py-ART configuration file vmin, vmax: float or None The minimum and maximum values. If None they will be obtained from the Py-ART configuration file mask_val: float or None A value to mask. write_data: Bool If true the histogram data is written in a csv file 'LATITUDE_SLICE': Plots a cross-section of gridded data over a constant latitude. User defined parameters: voltype: str Name of the pyrad variable to use, it must be either a voltype available in the dataset or "RGB", which will make a RGB plot of Zh, Zdr and RhoHV (if they are available) lon: float Start longitude of the cross-section. Default is to use the radar longitude. The end coordinates are obtained from the parameter xmax in 'xsecImageConfig' in the loc config file lat: float Latitude of the cross-section. Default is to use the radar latitude. 'LONGITUDE_SLICE': Plots a cross-ection of gridded data over a constant longitude. User defined parameters: voltype: str Name of the pyrad variable to use, it must be either a voltype available in the dataset or "RGB", which will make a RGB plot of Zh, Zdr and RhoHV (if they are available) lon: float Longitude of the cross-section. Default is to use the radar longitude. lat: float Start latitude of the cross-section. Default is to use the radar latitude. The end coordinates are obtained from the parameter xmax in 'xsecImageConfig' in the loc config file 'SAVEALL': Saves a gridded data object including all or a list of user-defined fields in a netcdf file User defined parameters: datatypes: list of str or None The list of data types to save. If it is None, all fields in the radar object will be saved 'SAVEALL_GRID' : Same as before but can be used in a mixed GRID/VOL dataset, as there is no ambiguity with SAVEALL for VOL datasets 'SAVEVOL': Saves on field of a gridded data object in a netcdf file. User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset file_type: str The type of file used to save the data. Can be 'nc' or 'h5'. Default 'nc' physical: Bool If True the data will be saved in physical units (floats). Otherwise it will be quantized and saved as binary. Default True compression: str For ODIM file formats, the type of compression. Can be any of the allowed compression types for hdf5 files. Default gzip compression_opts: any The compression options allowed by the hdf5. Depends on the type of compression. Default 6 (The gzip compression level). 'SAVEVOL_GRID' : Same as before but can be used in a mixed GRID/VOL dataset, as there is no ambiguity with SAVEVOL for VOL datasets 'STATS': Computes statistics over the whole images and stores them in a file. User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset stat: str The statistic used. Can be mean, median, min, max 'SURFACE_RAW': Plots a surface image of gridded data without projecting it into a map User defined parameters: voltype: str Name of the pyrad variable to use, it must be either a voltype available in the dataset or "RGB", which will make a RGB plot of Zh, Zdr and RhoHV (if they are available) level: int The altitude level to plot. The rest of the parameters are defined by the parameters in 'ppiImageConfig' and 'ppiMapImageConfig' in the 'loc' configuration file 'SURFACE_IMAGE': Plots a surface image of gridded data. User defined parameters: voltype: str Name of the pyrad variable to use, it must be either a voltype available in the dataset or "RGB", which will make a RGB plot of Zh, Zdr and RhoHV (if they are available) level: int The altitude level to plot. The rest of the parameters are defined by the parameters in 'ppiImageConfig' and 'ppiMapImageConfig' in the 'loc' configuration file 'SURFACE_CONTOUR': Plots a surface image of contour gridded data. User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset level: int The altitude level to plot. The rest of the parameters are defined by the parameters in 'ppiImageConfig' and 'ppiMapImageConfig' in the 'loc' configuration file contour_values : float array or None The contour values. If None the values are taken from the 'boundaries' keyword in the field description in the Py-ART config file. If 'boundaries' is not set the countours are 10 values linearly distributed from vmin to vmax linewidths : float width of the contour lines colors : color string or sequence of colors The contour colours 'SURFACE_CONTOUR_OVERPLOT': Plots a surface image of gridded data with a contour overplotted. User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset level: int The altitude level to plot. The rest of the parameters are defined by the parameters in 'ppiImageConfig' and 'ppiMapImageConfig' in the 'loc' configuration file contour_values : float array or None The contour values. If None the values are taken from the 'boundaries' keyword in the field description in the Py-ART config file. If 'boundaries' is not set the countours are 10 values linearly distributed from vmin to vmax linewidths : float width of the contour lines colors : color string or sequence of colors The contour colours 'SURFACE_OVERPLOT': Plots on the same surface two images, one on top of the other. User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset level: int The altitude level to plot. The rest of the parameters are defined by the parameters in 'ppiImageConfig' and 'ppiMapImageConfig' in the 'loc' configuration file contour_values : float array or None The contour values. If None the values are taken from the 'boundaries' keyword in the field description in the Py-ART config file. If 'boundaries' is not set the countours are 10 values linearly distributed from vmin to vmax 'DDA_MAP': Plots horizontal wind vectors obtained from a DDA analysis on a 2D map. The pyDDA package is required User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset level: int The altitude level to plot. The rest of the parameters are defined by the parameters in 'ppiImageConfig' and 'ppiMapImageConfig' in the 'loc' configuration file display_type: str Display method for the wind vectors, can be either 'streamline', 'quiver' or 'barbs' bg_ref_rad: int Which radar to use as reference to display the background voltype. u_vel_contours: list of int The contours to use for plotting contours of u. Set to None to not display such contours. v_vel_contours: list of int The contours to use for plotting contours of v. Set to None to not display such contours. w_vel_contours: list of int The contours to use for plotting contours of w. Set to None to not display such contours. vector_spacing_km: float Spacing in km between wind vectors in x and y axis (only used for barbs and quiver plots) quiver_len: float Length to use for the quiver key in m/s. (only used for quiver plots) streamline_arrowsize: float Factor scale arrow size for streamlines. (only used for streamline plots) linewidth: float Linewidths for streamlines. (only used for streamline plots) 'DDA_LONGITUDE_SLICE': Plots horizontal wind vectors obtained from a DDA analysis on a vertical transect along a given longitude The pyDDA package is required User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset level: int The longitude level to plot. The rest of the parameters are defined by the parameters in 'xsecImageConfig' in the 'loc' configuration file display_type: str Display method for the wind vectors, can be either 'streamline', 'quiver' or 'barbs' bg_ref_rad: int Which radar to use as reference to display the background voltype. u_vel_contours: list of int The contours to use for plotting contours of u. Set to None to not display such contours. v_vel_contours: list of int The contours to use for plotting contours of v. Set to None to not display such contours. w_vel_contours: list of int The contours to use for plotting contours of w. Set to None to not display such contours. vector_spacing_km: float Spacing in km between wind vectors in x and y axis (only used for barbs and quiver plots) quiver_len: float Length to use for the quiver key in m/s. (only used for quiver plots) streamline_arrowsize: float Factor scale arrow size for streamlines. (only used for streamline plots) linewidth: float Linewidths for streamlines. (only used for streamline plots) 'DDA_LATITUDE_SLICE': Plots horizontal wind vectors obtained from a DDA analysis on a vertical transect along a given latitude The pyDDA package is required User defined parameters: voltype: str name of the pyrad variable to use, it must be available in the dataset level: int The latitude level to plot. The rest of the parameters are defined by the parameters in 'xsecImageConfig' in the 'loc' configuration file display_type: str Display method for the wind vectors, can be either 'streamline', 'quiver' or 'barbs' bg_ref_rad: int Which radar to use as reference to display the background voltype. u_vel_contours: list of int The contours to use for plotting contours of u. Set to None to not display such contours. v_vel_contours: list of int The contours to use for plotting contours of v. Set to None to not display such contours. w_vel_contours: list of int The contours to use for plotting contours of w. Set to None to not display such contours. vector_spacing_km: float Spacing in km between wind vectors in x and y axis (only used for barbs and quiver plots) quiver_len: float Length to use for the quiver key in m/s. (only used for quiver plots) streamline_arrowsize: float Factor scale arrow size for streamlines. (only used for streamline plots) linewidth: float Linewidths for streamlines. (only used for streamline plots) Parameters ---------- dataset : grid grid object prdcfg : dictionary of dictionaries product configuration dictionary of dictionaries Returns ------- None or name of generated files """ dssavedir = prdcfg["dsname"] if "dssavename" in prdcfg: dssavedir = prdcfg["dssavename"] if prdcfg["type"] == "STATS": field_name = get_fieldname_pyart(prdcfg["voltype"]) if field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values stat = prdcfg.get("stat", "mean") savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=None, ) fname = make_filename( "stats", prdcfg["dstype"], prdcfg["voltype"], ["csv"], prdcfginfo=stat, timeinfo=None, runinfo=prdcfg["runinfo"], )[0] fname = savedir + fname if stat == "mean": value = np.ma.masked_all(1) value[0] = np.ma.mean(dataset["radar_out"].fields[field_name]["data"]) elif stat == "median": value = np.ma.masked_all(1) value[0] = np.ma.median(dataset["radar_out"].fields[field_name]["data"]) elif stat == "min": value = np.ma.masked_all(1) value[0] = np.ma.min(dataset["radar_out"].fields[field_name]["data"]) elif stat == "max": value = np.ma.masked_all(1) value[0] = np.ma.max(dataset["radar_out"].fields[field_name]["data"]) else: warn("Unsupported statistic " + stat) return None write_ts_stats(prdcfg["timeinfo"], value, fname, stat=stat) print("----- save to " + fname) return fname if prdcfg["type"] == "SURFACE_RAW": fields = dataset["radar_out"].fields field_name = get_fieldname_pyart(prdcfg["voltype"]) names = field_name if isinstance(field_name, (list, tuple)) else [field_name] if not all(f in fields for f in names): warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values level = prdcfg.get("level", 0) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "surface", prdcfg["dstype"], ( "RGB" if isinstance(prdcfg["voltype"], (tuple, list)) else prdcfg["voltype"] ), prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname plot_surface_raw(dataset["radar_out"], field_name, level, prdcfg, fname_list) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "SURFACE_IMAGE": field_name = get_fieldname_pyart(prdcfg["voltype"]) fields = dataset["radar_out"].fields names = field_name if isinstance(field_name, (list, tuple)) else [field_name] if not all(f in fields for f in names): warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values level = prdcfg.get("level", 0) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "surface", prdcfg["dstype"], ( "RGB" if isinstance(prdcfg["voltype"], (tuple, list)) else prdcfg["voltype"] ), prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname plot_surface(dataset["radar_out"], field_name, level, prdcfg, fname_list) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "SURFACE_CONTOUR": field_name = get_fieldname_pyart(prdcfg["voltype"]) if field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values contour_values = prdcfg.get("contour_values", None) linewidths = prdcfg.get("linewidths", 1.5) colors = prdcfg.get("colors", "k") level = prdcfg.get("level", 0) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "surface", prdcfg["dstype"], prdcfg["voltype"], prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname plot_surface_contour( dataset["radar_out"], field_name, level, prdcfg, fname_list, contour_values=contour_values, linewidths=linewidths, colors=colors, ) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "SURFACE_CONTOUR_OVERPLOT": field_name = get_fieldname_pyart(prdcfg["voltype"]) if field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None contour_name = get_fieldname_pyart(prdcfg["contourtype"]) if contour_name not in dataset["radar_out"].fields: warn( "Contour type " + contour_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None contour_values = prdcfg.get("contour_values", None) linewidths = prdcfg.get("linewidths", 1.5) colors = prdcfg.get("colors", "k") level = prdcfg.get("level", 0) contour_level = prdcfg.get("contour_level", level) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "surface-contour", prdcfg["dstype"], prdcfg["voltype"] + "-" + prdcfg["contourtype"], prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname titl = ( pyart.graph.common.generate_grid_title( dataset["radar_out"], field_name, level ) + " - " + pyart.graph.common.generate_field_name(dataset["radar_out"], contour_name) ) fig, ax, display = plot_surface( dataset["radar_out"], field_name, level, prdcfg, fname_list, titl=titl, save_fig=False, ) fname_list = plot_surface_contour( dataset["radar_out"], contour_name, contour_level, prdcfg, fname_list, contour_values=contour_values, linewidths=linewidths, colors=colors, ax=ax, fig=fig, display=display, save_fig=True, ) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "SURFACE_OVERPLOT": field_name_btm = get_fieldname_pyart(prdcfg["voltype_btm"]) if field_name_btm not in dataset["radar_out"].fields: warn( " Field type " + field_name_btm + " not available in data set. Skipping product " + prdcfg["type"] ) return None field_name_top = get_fieldname_pyart(prdcfg["voltype_top"]) if field_name_top not in dataset["radar_out"].fields: warn( "Contour type " + field_name_top + " not available in data set. Skipping product " + prdcfg["type"] ) return None level_btm = prdcfg.get("level_btm", 0) level_top = prdcfg.get("level_top", 0) alpha = prdcfg.get("alpha", None) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "surface_overplot", prdcfg["dstype"], prdcfg["voltype_btm"] + "-" + prdcfg["voltype_top"], prdcfg["imgformat"], prdcfginfo="l" + str(level_btm), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname titl = ( pyart.graph.common.generate_grid_title( dataset["radar_out"], field_name_btm, level_btm ) + " - " + pyart.graph.common.generate_field_name( dataset["radar_out"], field_name_top ) ) fig, ax, display = plot_surface( dataset["radar_out"], field_name_btm, level_btm, prdcfg, fname_list, titl=titl, save_fig=False, ) fname_list = plot_surface( dataset["radar_out"], field_name_top, level_top, prdcfg, fname_list, titl=titl, alpha=alpha, ax=ax, fig=fig, display=display, save_fig=True, ) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "LATITUDE_SLICE": fields = dataset["radar_out"].fields field_name = get_fieldname_pyart(prdcfg["voltype"]) names = field_name if isinstance(field_name, (list, tuple)) else [field_name] if not all(f in fields for f in names): warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values lon = prdcfg.get("lon", dataset["radar_out"].origin_longitude["data"][0]) lat = prdcfg.get("lat", dataset["radar_out"].origin_latitude["data"][0]) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "lat_slice", prdcfg["dstype"], ( "RGB" if isinstance(prdcfg["voltype"], (tuple, list)) else prdcfg["voltype"] ), prdcfg["imgformat"], prdcfginfo="lat" + "{:.2f}".format(lat), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname plot_latitude_slice( dataset["radar_out"], field_name, lon, lat, prdcfg, fname_list ) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "LONGITUDE_SLICE": fields = dataset["radar_out"].fields field_name = get_fieldname_pyart(prdcfg["voltype"]) names = field_name if isinstance(field_name, (list, tuple)) else [field_name] if not all(f in fields for f in names): warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values lon = prdcfg.get("lon", dataset["radar_out"].origin_longitude["data"][0]) lat = prdcfg.get("lat", dataset["radar_out"].origin_latitude["data"][0]) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "lon_slice", prdcfg["dstype"], ( "RGB" if isinstance(prdcfg["voltype"], (tuple, list)) else prdcfg["voltype"] ), prdcfg["imgformat"], prdcfginfo="lon" + "{:.2f}".format(lon), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname plot_longitude_slice( dataset["radar_out"], field_name, lon, lat, prdcfg, fname_list ) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "CROSS_SECTION": fields = dataset["radar_out"].fields field_name = get_fieldname_pyart(prdcfg["voltype"]) names = field_name if isinstance(field_name, (list, tuple)) else [field_name] if not all(f in fields for f in names): warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values lon1 = dataset["radar_out"].point_longitude["data"][0, 0, 0] lat1 = dataset["radar_out"].point_latitude["data"][0, 0, 0] lon2 = dataset["radar_out"].point_longitude["data"][0, -1, -1] lat2 = dataset["radar_out"].point_latitude["data"][0, -1, -1] if "coord1" in prdcfg: if "lon" in prdcfg["coord1"]: lon1 = prdcfg["coord1"]["lon"] if "lat" in prdcfg["coord1"]: lat1 = prdcfg["coord1"]["lat"] if "coord2" in prdcfg: if "lon" in prdcfg["coord2"]: lon2 = prdcfg["coord2"]["lon"] if "lat" in prdcfg["coord2"]: lat2 = prdcfg["coord2"]["lat"] coord1 = (lat1, lon1) coord2 = (lat2, lon2) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "lonlat", prdcfg["dstype"], ( "RGB" if isinstance(prdcfg["voltype"], (tuple, list)) else prdcfg["voltype"] ), prdcfg["imgformat"], prdcfginfo="lon-lat1_" + "{:.2f}".format(lon1) + "-" + "{:.2f}".format(lat1) + "_lon-lat2_" + "{:.2f}".format(lon2) + "-" + "{:.2f}".format(lat2), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname plot_cross_section( dataset["radar_out"], field_name, coord1, coord2, prdcfg, fname_list ) print("----- save to " + " ".join(fname_list)) return fname_list if prdcfg["type"] == "HISTOGRAM": field_name = get_fieldname_pyart(prdcfg["voltype"]) if field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None step = prdcfg.get("step", None) vmin = prdcfg.get("vmin", None) vmax = prdcfg.get("vmax", None) mask_val = prdcfg.get("mask_val", None) write_data = prdcfg.get("write_data", 0) binwidth_equal = prdcfg.get("binwidth_equal", 0) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "histogram", prdcfg["dstype"], prdcfg["voltype"], prdcfg["imgformat"], timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname values = dataset["radar_out"].fields[field_name]["data"] if mask_val is not None: values = np.ma.masked_values(values, mask_val) bin_edges, values = compute_histogram( values, field_name, step=step, vmin=vmin, vmax=vmax ) titl = ( pyart.graph.common.generate_grid_time_begin( dataset["radar_out"] ).isoformat() + "Z" + "\n" + get_field_name(dataset["radar_out"].fields[field_name], field_name) ) labelx = get_colobar_label(dataset["radar_out"].fields[field_name], field_name) plot_histogram( bin_edges, values, fname_list, labelx=labelx, labely="Number of Samples", titl=titl, binwidth_equal=binwidth_equal, ) print("----- save to " + " ".join(fname_list)) if write_data: fname = ( savedir + make_filename( "histogram", prdcfg["dstype"], prdcfg["voltype"], ["csv"], timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], )[0] ) hist, _ = np.histogram(values, bins=bin_edges) write_histogram( bin_edges, hist, fname, datatype=prdcfg["voltype"], step=step ) print("----- save to " + fname) return fname return fname_list if prdcfg["type"] == "SAVEVOL" or prdcfg["type"] == "SAVEVOL_GRID": field_name = get_fieldname_pyart(prdcfg["voltype"]) if field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None file_type = prdcfg.get("file_type", "nc") prdcfg.get("physical", True) compression = prdcfg.get("compression", "gzip") compression_opts = prdcfg.get("compression_opts", 6) new_dataset = deepcopy(dataset["radar_out"]) new_dataset.fields = dict() new_dataset.add_field(field_name, dataset["radar_out"].fields[field_name]) # This key is required for pyDDA processing but poses # problem when saving to CFRadial if "additional_radars" in new_dataset.metadata: new_dataset.metadata.pop("additional_radars") savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname = make_filename( "savevol", prdcfg["dstype"], prdcfg["voltype"], [file_type], timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], )[0] fname = savedir + fname if file_type == "nc": pyart.io.write_grid( fname, new_dataset, write_point_x_y_z=True, write_point_lon_lat_alt=True ) elif file_type == "h5": pyart.aux_io.write_odim_grid_h5( fname, new_dataset, compression=compression, compression_opts=compression_opts, ) else: warn("Data could not be saved. " + "Unknown saving file type " + file_type) return None print("saved file: " + fname) return fname if prdcfg["type"] == "SAVEALL" or prdcfg["type"] == "SAVEALL_GRID": datatypes = prdcfg.get("datatypes", None) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname = make_filename( "savevol", prdcfg["dstype"], "all_fields", ["nc"], timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], )[0] fname = savedir + fname field_names = None if datatypes is not None: field_names = [] for datatype in datatypes: field_names.append(get_fieldname_pyart(datatype)) if field_names is not None: new_dataset = deepcopy(dataset["radar_out"]) new_dataset.fields = dict() for field_name in field_names: if field_name not in dataset["radar_out"].fields: warn(field_name + " not in grid object") else: new_dataset.add_field( field_name, dataset["radar_out"].fields[field_name] ) else: new_dataset = dataset["radar_out"] pyart.io.write_grid( fname, new_dataset, write_point_x_y_z=True, write_point_lon_lat_alt=True ) print("saved file: " + fname) return fname if prdcfg["type"] == "DDA_MAP": display_type = prdcfg.get("display_type", "quiver") if display_type not in ["quiver", "barbs", "streamline"]: warn("Invalid display_type, must be " + '"streamline", "quiver" or "barbs"') return None bg_field_name = get_fieldname_pyart(prdcfg["voltype"]) bg_ref_rad = prdcfg.get("bg_ref_rad", 0) # get bg field name given which radar serves as reference if bg_ref_rad != 0: bg_field_name += "_radar{:d}".format(bg_ref_rad) if bg_field_name not in dataset["radar_out"].fields: warn( " Field type " + bg_field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values level = prdcfg.get("level", 0) alpha = prdcfg.get("alpha", 1) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "dda_map", prdcfg["dstype"], prdcfg["voltype"], prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname titl = generate_dda_map_title(dataset["radar_out"], bg_field_name, level) plot_dda_map( dataset["radar_out"], bg_field_name, level, prdcfg, fname_list, alpha=alpha, display_type=display_type, titl=titl, ) print("----- save to " + " ".join(fname_list)) if prdcfg["type"] == "DDA_LONGITUDE_SLICE": display_type = prdcfg.get("display_type", "quiver") if display_type not in ["quiver", "barbs", "streamline"]: warn("Invalid display_type, must be " + '"streamline", "quiver" or "barbs"') return None bg_field_name = get_fieldname_pyart(prdcfg["voltype"]) bg_ref_rad = prdcfg.get("bg_ref_rad", 0) # get bg field name given which radar serves as reference if bg_ref_rad != 0: bg_field_name += "_radar{:d}".format(bg_ref_rad) if bg_field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values lon = prdcfg.get("lon", dataset["radar_out"].origin_longitude["data"][0]) lat = prdcfg.get("lat", dataset["radar_out"].origin_latitude["data"][0]) alpha = prdcfg.get("alpha", 1) wind_vectors = prdcfg.get("wind_vectors", "hor") # Find indexes where to slice with a pyart display object # this is a bit clumsy display = pyart.graph.GridMapDisplay(dataset["radar_out"]) level, _ = display._find_nearest_grid_indices(lon, lat) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "dda_lon_slice", prdcfg["dstype"], prdcfg["voltype"], prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname titl = generate_dda_longitude_slice_title( dataset["radar_out"], bg_field_name, level ) plot_dda_slice( dataset["radar_out"], bg_field_name, "longitude", level, prdcfg, fname_list, alpha=alpha, display_type=display_type, titl=titl, wind_vectors=wind_vectors, ) print("----- save to " + " ".join(fname_list)) if prdcfg["type"] == "DDA_LATITUDE_SLICE": display_type = prdcfg.get("display_type", "quiver") if display_type not in ["quiver", "barbs", "streamline"]: warn("Invalid display_type, must be " + '"streamline", "quiver" or "barbs"') return None bg_field_name = get_fieldname_pyart(prdcfg["voltype"]) bg_ref_rad = prdcfg.get("bg_ref_rad", 0) # get bg field name given which radar serves as reference if bg_ref_rad != 0: bg_field_name += "_radar{:d}".format(bg_ref_rad) if bg_field_name not in dataset["radar_out"].fields: warn( " Field type " + field_name + " not available in data set. Skipping product " + prdcfg["type"] ) return None # user defined values lon = prdcfg.get("lon", dataset["radar_out"].origin_longitude["data"][0]) lat = prdcfg.get("lat", dataset["radar_out"].origin_latitude["data"][0]) alpha = prdcfg.get("alpha", 1) wind_vectors = prdcfg.get("wind_vectors", "hor") # Find indexes where to slice with a pyart display object # this is a bit clumsy display = pyart.graph.GridMapDisplay(dataset["radar_out"]) _, level = display._find_nearest_grid_indices(lon, lat) savedir = get_save_dir( prdcfg["basepath"], prdcfg["procname"], dssavedir, prdcfg["prdname"], timeinfo=prdcfg["timeinfo"], ) fname_list = make_filename( "dda_lat_slice", prdcfg["dstype"], prdcfg["voltype"], prdcfg["imgformat"], prdcfginfo="l" + str(level), timeinfo=prdcfg["timeinfo"], runinfo=prdcfg["runinfo"], ) for i, fname in enumerate(fname_list): fname_list[i] = savedir + fname titl = generate_dda_latitude_slice_title( dataset["radar_out"], bg_field_name, level ) plot_dda_slice( dataset["radar_out"], bg_field_name, "latitude", level, prdcfg, fname_list, alpha=alpha, display_type=display_type, titl=titl, wind_vectors=wind_vectors, ) print("----- save to " + " ".join(fname_list)) else: return None