Source code for pycaps.io.modelobs


from binfile import BinFile

from collections import OrderedDict


[docs]class ARPSModelObsFile(BinFile): """ Read an ARPS EnKF model observation file (such as that created by arpsenkf or postinnov). Args: file_name (str): The name of the file to open. vars (list): A list containing the names and order of the variables in the file. Defaults to ['vr', 'Z'] (radial velocity, then reflectivity). mpi_config (tuple): A tuple containing the MPI configuration of the run that generated this file. Defaults to (1, 1), signifying no MPI. mode (str): Read/write mode for this file. The default is 'r' for reading, currently the only supported option. Attributes: timestamp (datetime): The valid time for the data in the file. n_tilts (int): Number of elevation angles in the file. n_gridx (int): Number of grid points in the x direction. n_gridy (int): Number of grid points in the y direction. radar_id (str): 4-character ID for the radar. radar_lat (float): Latitude of the radar. radar_lon (float): Longitude of the radar. radar_x (float): x coordinate of the radar on the domain. radar_y (float): y coordinate of the radar on the domain. d_azim (float): Azimuthal spacing of the raw data. range_min (float): Minimum range of the raw data. range_max (float): Maximum range of the raw data. elevations (np.array): List of elevation angles in the file. """ # Header block definitions (ordered dictionaries of field names and data types) _amof_time = OrderedDict( [('timestamp', 'i'), ('year', 'i'), ('month', 'i'), ('day', 'i'), ('hour', 'i'), ('minute', 'i'), ('second', 'i')] ) _amof_dimensions = OrderedDict([('n_tilts', 'i'), ('n_gridx', 'i'), ('n_gridy', 'i')]) _amof_radar_name = OrderedDict([('radar_id', '4s')]) _amof_location = OrderedDict( [('radar_lat', 'f'), ('radar_lon', 'f'), ('radar_x', 'f'), ('radar_y', 'f'), ('radar_alt', 'f')] ) _amof_radar_meta = OrderedDict([('d_azim', 'f'), ('range_min', 'f'), ('range_max', 'f')]) def __init__(self, file_name, vars=('vr', 'Z'), mpi_config=(1, 1), mode='r'): """ Constructor for the ARPSModelObsFile class """ super(ARPSModelObsFile, self).__init__(file_name, mode, byteorder='>') self._mpi = mpi_config self._var_names = vars if 'r' in mode: self._read_headers() self._read_data() return def _read_headers(self): # Read all header blocks for block in [_AMOF._amof_time, _AMOF._amof_dimensions, _AMOF._amof_radar_name, _AMOF._amof_location, _AMOF._amof_radar_meta]: self._read_block(block, self.__dict__, fortran=True) return def _read_data(self): self.elevations = self._read_grid('f', (self.n_tilts,), fortran=True) block_size = self._peek('i') if block_size != self.n_tilts * self.n_gridx * self.n_gridy * 4: self.sd_nx = self.n_gridx self.sd_ny = self.n_gridy self.n_gridx, self.n_gridy = self._subdomain_to_full(self._mpi) self.height = self._read_grid('f', (self.n_gridx, self.n_gridy, self.n_tilts), fortran=True).T self.range = self._read_grid('f', (self.n_gridx, self.n_gridy, self.n_tilts), fortran=True).T vars = self._read_grid('f', (self.n_gridx, self.n_gridy, self.n_tilts, len(self._var_names)), fortran=True).T self._variables = dict(zip(self._var_names, vars)) return def _subdomain_to_full(self, mpi_config): nproc_x, nproc_y = mpi_config nx = nproc_x * (self.sd_nx - 3) + 3 ny = nproc_y * (self.sd_ny - 3) + 3 return nx, ny
[docs] def __getitem__(self, var_name): """ Retrieve data from the file. Args: var_name (str): Name of the variable to retrieve. Acceptable values are 'z' (height), 'r' (slant range), or any of the names passed to the `vars` keyword argument in :py:meth:`ARPSModelObsFile.__init__()`. Returns: A three-dimensional numpy array (NTILT :math:`\\times` NY :math:`\\times` NX) """ if var_name == 'z': var = self.height elif var_name == 'r': var = self.range elif var_name in self._variables: var = self._variables[var_name] else: raise ValueError("Variable name %s was not given" % var_name) return var
# Alias to _AMOF to make accessing the format dictionaries easier. _AMOF = ARPSModelObsFile if __name__ == "__main__": ad = ARPSModelObsFile("/caps2/tsupinie/05June2009/1km-sfc-diff/KCYSan014400", mpi_config=(2, 12)) print ad['Z'].max(), ad['Z'].min()