def test_lin2db(fake_nc_file):
    nc = netCDF4.Dataset(fake_nc_file)
    test_var = nc.variables['time']
    name, units = 'test_name', 'm s-1'
    obj = CloudnetArray(test_var, name, units)
    obj.lin2db()
    assert obj.units == 'dB'
    assert_array_equal(obj.data, utils.lin2db(test_var[:]))
Ejemplo n.º 2
0
    def calc_errors(self, attenuations: dict, classification: ClassificationResult) -> None:
        """Calculates uncertainties of radar echo.

        Calculates and adds `Z_error`, `Z_sensitivity` and `Z_bias` :class:`CloudnetArray`
        instances to `data` attribute.

        Args:
            attenuations: 2-D attenuations due to atmospheric gases.
            classification: The :class:`ClassificationResult` instance.

        References:
            The method is based on Hogan R. and O'Connor E., 2004, https://bit.ly/2Yjz9DZ
            and the original Cloudnet Matlab implementation.

        """
        def _calc_sensitivity() -> np.ndarray:
            """Returns sensitivity of radar as function of altitude."""
            mean_gas_atten = ma.mean(attenuations['radar_gas_atten'], axis=0)
            z_sensitivity = z_power_min + log_range + mean_gas_atten
            zc = ma.median(ma.array(z, mask=~classification.is_clutter), axis=0)
            z_sensitivity[~zc.mask] = zc[~zc.mask]
            return z_sensitivity

        def _calc_error() -> np.ndarray:
            if 'width' not in self.data:
                return 0.3
            z_precision = 4.343 * (1 / np.sqrt(_number_of_independent_pulses())
                                   + utils.db2lin(z_power_min - z_power) / 3)
            gas_error = attenuations['radar_gas_atten'] * 0.1
            liq_error = attenuations['liquid_atten_err'].filled(0)
            z_error = utils.l2norm(gas_error, liq_error, z_precision)
            z_error[attenuations['liquid_uncorrected']] = ma.masked
            return z_error

        def _number_of_independent_pulses() -> float:
            seconds_in_hour = 3600
            dwell_time = utils.mdiff(self.time) * seconds_in_hour
            return (dwell_time * self.radar_frequency * 1e9 * 4
                    * np.sqrt(math.pi) * self.data['width'][:] / 3e8)

        def _calc_z_power_min() -> float:
            if ma.all(z_power.mask):
                return 0
            return np.percentile(z_power.compressed(), 0.1)

        z = self.data['Z'][:]
        radar_range = self.km2m(self.dataset.variables['range'])
        log_range = utils.lin2db(radar_range, scale=20)
        z_power = z - log_range
        z_power_min = _calc_z_power_min()
        self.append_data(_calc_error(), 'Z_error')
        self.append_data(_calc_sensitivity(), 'Z_sensitivity')
        self.append_data(1, 'Z_bias')
Ejemplo n.º 3
0
def test_lin2db(input, result):
    assert utils.lin2db(*input) == result
Ejemplo n.º 4
0
 def _get_z_factor(self) -> float:
     """Returns empirical scaling factor for radar echo."""
     return float(utils.lin2db(self.coeffs.K2liquid0 / 0.93))
Ejemplo n.º 5
0
 def lin2db(self) -> None:
     """Converts linear units to log."""
     if "db" not in self.units.lower():
         self.data = utils.lin2db(self.data)
         self.units = "dB"
Ejemplo n.º 6
0
 def test_lin2db(self):
     name, units = "test_name", "m s-1"
     obj = CloudnetArray(self.time, name, units)
     obj.lin2db()
     assert obj.units == "dB"
     assert_array_equal(obj.data, utils.lin2db(self.time[:]))
Ejemplo n.º 7
0
def test_lin2db_arrays(input, expected):
    converted = utils.lin2db(input)
    assert_array_equal(converted, expected)
    if ma.isMaskedArray(input):
        assert_array_equal(converted.mask, expected.mask)
Ejemplo n.º 8
0
 def test_lin2db(self):
     name, units = 'test_name', 'm s-1'
     obj = CloudnetArray(self.time, name, units)
     obj.lin2db()
     assert obj.units == 'dB'
     assert_array_equal(obj.data, utils.lin2db(self.time[:]))