Source code for radtraq.proc.noise

"""
radtraq.noise
-------------

Module for calculating noise floor and applying a
mask to the data

"""

import dask
import numpy as np
import xarray as xr

from ..utils.corrections import range_correction


[docs] def calc_noise_floor(obj, variable, height_variable=None): """ Main function for getting the noise floor Parameters ---------- obj : Xarray.dataset ACT object with data variable : string Variable name to calculate. Should be a reflectivity. height_variable : string Height variable name to use for calculations. If not provided will attempt to use coordinates of data variable. Returns ------- result : Numpy float array Returns the noise floor value for each time sample. References ---------- Kollias, P., I. Jo, P. Borque, A. Tatarevic, K. Lamer, N. Bharadwaj, K. Widener, K. Johnson, and E.E. Clothiaux, 2014: Scanning ARM Cloud Radars. Part II: Data Quality Control and Processing. J. Atmos. Oceanic Technol., 31, 583–598, https://doi.org/10.1175/JTECH-D-13-00045.1 """ if not isinstance(obj, xr.core.dataset.Dataset): raise ValueError('Please use a valid Xarray.Dataset') if not isinstance(variable, str): raise ValueError('Please Specify a Variable Name') # Range correct data and return the DataArray from Dataset data = range_correction(obj, variable, height_variable=height_variable) # Pass each timestep into task list to calculate cloud threshhold # with a delayed dask process task = [dask.delayed(cloud_threshold)(row) for row in data] # Perform dask computation result = dask.compute(*task) # Convert returned dask tuple into numpy array result = np.array(result, dtype=float) return result
def cloud_threshold(data, n_avg=1.0, nffts=None): """ Calculates the noise floor Parameters ---------- data : Xarray.DataArray Xarray DataArray n_avg : float Number of points to average over nffts : int Number of heights to iterate over. If None will use the size of data. Returns ------- result : numpy scalar float Returns the noise floor value for each time sample References ---------- Kollias, P., I. Jo, P. Borque, A. Tatarevic, K. Lamer, N. Bharadwaj, K. Widener, K. Johnson, and E.E. Clothiaux, 2014: Scanning ARM Cloud Radars. Part II: Data Quality Control and Processing. J. Atmos. Oceanic Technol., 31, 583–598, https://doi.org/10.1175/JTECH-D-13-00045.1 """ if nffts is None: nffts = data.size data = 10.0 ** (data.values / 10.0) data = np.sort(data) nthld = 10.0**-10.0 dsum = 0.0 sumSq = 0.0 n = 0.0 numNs = [] sqrt_n_avg = np.sqrt(n_avg) for i in range(nffts): if data[i] > nthld: dsum += data[i] sumSq += data[i] ** 2.0 n += 1.0 a3 = dsum * dsum a1 = sqrt_n_avg * (n * sumSq - a3) if n > nffts / 4.0: if a1 <= a3: sumNs = dsum numNs = [n] else: sumNs = dsum numNs = [n] if len(numNs) > 0: n_mean = sumNs / numNs[0] else: n_mean = np.nan if n_mean == 0.0: value = np.nan else: value = 10.0 * np.log10(n_mean) return value