Source code for emc2.core.instrument

"""
====================
emc2.core.instrument
====================

This module stores the Instrument class.
"""
import numpy as np

from pint import UnitRegistry
from ..io import load_arm_file

ureg = UnitRegistry()
quantity = ureg.Quantity


[docs] class Instrument(object): """ This is the base class which holds the information needed to contain the instrument parameters for the simulator. Attributes ---------- instrument_str: str The name of the instrument. instrument_class: str The class of the instrument. Currently must be one of 'radar,' or 'lidar'. freq: float The frequency of the instrument. wavelength: float The wavelength of the instrument beta_p_phase_thresh: list of dicts or None If a list, each index contains a dictionaly with class name, class integer value (mask order), LDR value bounds, and the corresponding beta_p threshold (thresholds are linearly interpolated between LDR values). In order for the method to operate properly, the list should be arranged from the lowest to highest beta_p threshold values for a given LDR, that is, beta_p[i+1 | LDR=x] >= beta_p[i | LDR=x]. ext_OD: float The optical depth where we have full extinction of the lidar signal. OD_from_sfc: Bool If True (default), optical depth will be calculated from the surface. If False, optical depth will be calculated from the top of the atmosphere. eta: float Multiple scattering coefficient. K_w: float The index of refraction of water used for Ze calculation. See the ARM KAZR handbook (Widener et al. 2012) eps_liq: float The complex dielectric constant for liquid water. pt: float Transmitting power in Watts. theta: float 3 dB beam width in degrees gain: float The antenna gain in linear units. Z_min_1km: float The minimum detectable signal at 1 km in dBZ lr: float Attenuation based on the the general attributes in the spectra files. pr_noise_ge: float Minimum detectable signal in mW. tau_ge: float Pulse width in mus. tau_md: float Pulse width in mus. """
[docs] def __init__(self, frequency=None, wavelength=None): self.instrument_str = "" self.instrument_class = "" self.freq = np.nan self.wavelength = np.nan self.beta_p_phase_thresh = [] self.ext_OD = np.nan self.OD_from_sfc = True self.eta = np.nan self.K_w = np.nan self.eps_liq = np.nan self.location_code = "" self.pt = np.nan self.theta = np.nan self.gain = np.nan self.Z_min_1km = np.nan self.lr = np.nan self.pr_noise_ge = np.nan self.pr_noise_md = np.nan self.tau_ge = np.nan self.tau_md = np.nan self.c = 299792458.0 # m/s self.R_d = 287.058 # J K^-1 Kg^-1 self.g = 9.80665 # m/s^2 self.rho_i = 917 * ureg.kg / (ureg.m**3) # kg/m^3 (0 C 1013.25 hPa, typical model accuracy) self.rho_l = 1000 * ureg.kg / (ureg.m**3) # kg/m^3 (typical model accuracy) self.scatterer = None if frequency is None and wavelength is None: raise ValueError("Your instrument must have a frequency or wavelength!") if frequency is None: self.freq = self.c / wavelength.to('meter').magnitude self.wavelength = wavelength.to('micrometer').magnitude elif wavelength is None: self.freq = frequency.to('Hz').magnitude self.wavelength = self.c / self.freq * 1e6 else: self.freq = frequency.to('Hz').magnitude self.wavelength = wavelength.to('micrometer').magnitude self.mie_table = {} self.scat_table = {} # scattering calculation LUTs (e.g., C6 or m-D, A-D relationships). self.bulk_table = {} self.scatterer = {} self.ds = None
[docs] def read_arm_netcdf_file(self, filename, **kwargs): """ Loads a netCDF file that corresponds to ARM standards. Parameters ---------- filename: str Additional keyword arguments are passed into :py:func:`act.io.arm.read_arm_netcdf` """ self.ds = load_arm_file(filename, **kwargs)