Source code for pyart.retrieve.cfad

"""
Create CFAD from a radar or grid field

"""

import numpy as np


[docs]def create_cfad( radar, field_bins, altitude_bins, field="reflectivity", field_mask=None, min_frac_thres=0.1, ): """ This function returns a Contoured Frequency by Altitude Diagram (CFAD; Yuter et al. 1995), a 2-dimensional histogram that is normalized by the number of points at each altitude. Altitude bins are masked where the counts are less than a minimum fraction of the largest number of counts for any altitude row. radar : Radar Radar object used. Can be Radar or Grid object. field_bins : list List of bin edges for field values to use for CFAD creation. altitude_bins : list List of bin edges for height values to use for CFAD creation. field : str Field name to use to look up reflectivity data. In the radar object. Default field name is 'reflectivity'. field_mask : array An array the same size as the field array used to mask values. min_frac_thres : float, optional Fraction of values to remove in CFAD normalization (default 0.1). If an altitude row has a total count that is less than min_frac_thres of the largest number of total counts for any altitude row, the bins in that altitude row are masked. Returns ------- freq_norm : array Array of normalized frequency. height_edges : array Array of bin edges for height data. field_edges : array of x coordinates Array of bin edges for field data. References ---------- Yuter, S. E., and R. A. Houze, 1995: Three-Dimensional Kinematic and Microphysical Evolution of Florida Cumulonimbus. Part II: Frequency Distributions of Vertical Velocity, Reflectivity, and Differential Reflectivity. Mon. Wea. Rev. 123, 1941-1963. https://doi.org/10.1175/1520-0493(1995)123%3C1941:TDKAME%3E2.0.CO;2 """ # get field data field_data = radar.fields[field]["data"][:] # get altitude data # first try to get altitude data from a radar object try: altitude_data = radar.gate_z["data"] # if it fails, try to get altitude data from a grid object except: try: altitude_data = radar.point_z["data"] except: print("No altitude data found") raise # option to mask data if a mask is given if field_mask is not None: field_data = np.ma.masked_where(field_mask, field_data) altitude_data = np.ma.masked_where(field_data.mask, altitude_data) # get raw bin counts freq, height_edges, field_edges = np.histogram2d( altitude_data.compressed(), field_data.compressed(), bins=[altitude_bins, field_bins], ) # sum counts over y axis (height) freq_sum = np.sum(freq, axis=1) # get threshold for normalizing point_thres = min_frac_thres * np.max(freq_sum) # repeat to create array same size as freq freq_sum_rep = np.repeat(freq_sum[..., np.newaxis], freq.shape[1], axis=1) # normalize freq_norm = freq / freq_sum_rep # mask data where there is not enough points freq_norm = np.ma.masked_where(freq_sum_rep < point_thres, freq_norm) return freq_norm, height_edges, field_edges