Source code for aospy.var

"""Funcionality for representing a physical variable in aospy."""
import numpy as np


[docs]class Var(object): """An object representing a physical quantity to be computed. Attributes ---------- name : str The variable's name alt_names : tuple of strings All other names that the variable may be referred to in the input data names : tuple of strings The combination of `name` and `alt_names` description : str A description of the variable func : function The function with which to compute the variable variables : sequence of aospy.Var objects The variables passed to `func` to compute it units : str The variable's physical units domain : str The physical domain of the variable, e.g. 'atmos', 'ocean', or 'land' def_time, def_vert, def_lat, def_lon : bool Whether the variable is defined, respectively, in time, vertically, in latitude, and in longitude math_str : str The mathematical representation of the variable colormap : str The name of the default colormap to be used in plots of this variable valid_range : length-2 tuple The range of values outside which to flag as unphysical/erroneous """
[docs] def __init__(self, name, alt_names=None, func=None, variables=None, units='', plot_units='', plot_units_conv=1, domain='atmos', description='', def_time=False, def_vert=False, def_lat=False, def_lon=False, math_str=False, colormap='RdBu_r', valid_range=None): """Instantiate a Var object. Parameters ---------- name : str The variable's name alt_names : tuple of strings All other names that the variable might be referred to in any input data. Each of these should be unique to this variable in order to avoid loading the wrong quantity. description : str A description of the variable func : function The function with which to compute the variable variables : sequence of aospy.Var objects The variables passed to `func` to compute it. Order matters: whenever calculations are performed to generate data corresponding to this Var, the data corresponding to the elements of `variables` will be passed to `self.function` in the same order. units : str The variable's physical units domain : str The physical domain of the variable, e.g. 'atmos', 'ocean', or 'land'. This is only used by aospy by some types of `DataLoader`, including `GFDLDataLoader`. def_time, def_vert, def_lat, def_lon : bool Whether the variable is defined, respectively, in time, vertically, in latitude, and in longitude math_str : str The mathematical representation of the variable. This is typically a raw string of LaTeX math-mode, e.g. r'$T_\mathrm{sfc}$' for surface temperature. colormap : str (Currently not used by aospy) The name of the default colormap to be used in plots of this variable. valid_range : length-2 tuple The range of values outside which to flag as unphysical/erroneous """ # noqa: W605 self.name = name if alt_names is None: self.names = tuple([name]) else: self.alt_names = alt_names self.names = tuple([name] + list(alt_names)) if func is None: self.func = lambda x: x self.variables = None else: self.func = func self.variables = variables self.units = units if not description: if self.func.__doc__ is None: self.description = '' else: self.description = self.func.__doc__ else: self.description = description self.domain = domain self.def_time = def_time self.def_vert = def_vert self.def_lat = def_lat self.def_lon = def_lon self.math_str = math_str self.colormap = colormap self.valid_range = valid_range
def __str__(self): return 'Var instance "' + self.name + '"' __repr__ = __str__
[docs] def to_plot_units(self, data, dtype_vert=False): """Convert the given data to plotting units.""" if dtype_vert == 'vert_av' or not dtype_vert: conv_factor = self.units.plot_units_conv elif dtype_vert == ('vert_int'): conv_factor = self.units.vert_int_plot_units_conv else: raise ValueError("dtype_vert value `{0}` not recognized. Only " "bool(dtype_vert) = False, 'vert_av', and " "'vert_int' supported.".format(dtype_vert)) if isinstance(data, dict): return {key: val*conv_factor for key, val in data.items()} return data*conv_factor
[docs] def mask_unphysical(self, data): """Mask data array where values are outside physically valid range.""" if not self.valid_range: return data else: return np.ma.masked_outside(data, np.min(self.valid_range), np.max(self.valid_range))