__init__ (version 0.1)
index
__init__.py

Define/calculate atmospheric constants and quantities.
 
Package of the following classes and methods/functions:
(1) The AtmQty class of all "atmospheric quantities" (defined
    below). All such quantities in a given instantiation of the 
    class share the same latitude, longitude, level locations.
(2) The stand-alone AtmConst class of atmosphere-related con-
    stants.
(3) Stand-alone functions to calculate atmospheric quantities 
    that are directly derivative from standard state variables.
    Most (though not all) of these functions are referenced by 
    methods in AtmQty, but are called "stand-alone" because they 
    can also be used on objects that are not AtmQty attributes.
    Used in a stand-alone fashion, these functions can operate 
    on arrays of any size and dimension and are not confined to
    a spherical or vertical grid.
(4) Stand-alone functions to manipulate objects of the AtmQty
    class (e.g. a regridding function that moves all variables
    from one set of latitude, longitude, level locations to 
    another).
 
"Atmospheric quantities" are defined as quantities that are stan-
dard state variables or are directly derivative (i.e. not requi-
ring time integration or modeling) from standard state variables.  
 
The AtmQty class is defined in __init__.py.  The AtmConst class
and each of the stand-alone functions are defined individually in 
separate modules in this package; AtmConst is defined in module
atmconst.  For the stand-alone functions, the function name is 
the same as the module name (e.g. function "theta" is defined in 
module "theta").
 
The stand-alone functions may not be "truly" stand-alone since they
may require methods in other modules in this package; this package
is designed to be used as a unit.  Some modules, like the atmconst
module, however, are truly stand-alone as they requires no other 
modules besides themselves; see the notes in the beginning of the 
module source code for details.
 
The package is written such that a single command "import atmqty"
to import the package will also import all the submodules in the
package (unless the package initialization module is being run
explicity at the command line as a unit test, in which case this
submodule import is not done).  Thus, one does not need to type 
in individual "import atmqty.M" commands for each M submodule.
 
Some useful online help commands for the package:
* help(atmqty):  Help for the package (including the AtmQty class).  
  A list of all modules in this package is found in the "Package 
  Contents" section of the help output.
* help(atmqty.M):  Details of each module "M", where "M" is the 
  module's name.  
 
 
Example 1:  Atmospheric constants:
 
>>> from atmconst import AtmConst
>>> const = AtmConst()
>>> '%.6f' % const.R_d
'287.050000'
 
 
Example 2:  Stand-alone function:
 
>>> from theta import theta
>>> p = N.array([1000., 850., 500.])
>>> T = N.array([273.1, 257.3, 233.1])
>>> var = theta(p,T)
>>> ['%.6f' % var[i] for i in range(3)]
['273.100000', '269.537605', '284.189919']
 
 
Example 3:  Single-level x-y domain AtmQty object:
 
(a) Initialize the AtmQty object:
 
>>> import atmqty
>>> import Numeric as N
>>> lat = N.arange(13) * 15.0 - 90.0
>>> lon = N.arange(25) * 15.0 - 180.0
>>> lev = N.array(850.)
>>> x = atmqty.AtmQty(lat, lon, lev, missing=1e29)
 
(b) The pattern "base" is two "distorted bulls-eyes" of opposite 
    polarity, centered over the poles (and add extra shallow 
    dimension to represent the single level):
 
>>> base = N.outerproduct(N.sin(lat*N.pi/360.), N.cos(lon*N.pi/360.))
>>> base = N.reshape(base, (base.shape[0], base.shape[1], 1))
 
(c) Create temperature and moisture "data" using the "base"
    pattern and add to AtmQty object (a second, redundant call 
    to add_qty is provided to show the method accepts both types 
    of argument syntax shown):
 
>>> T = (base * 10.) + 257.3
>>> q = N.absolute(base) * 5e-3
>>> x.add_qty( {'q':q,   'T':T} )
>>> x.add_qty( {'q':q}, {'T':T} )
 
(d) Calculate potential temperature and output temperature and
    potential temperature:
 
>>> x.theta()
>>> ['%.6f' % x.qty['T'][i,2,0] for i in range(3)]
['255.469873', '255.724409', '256.005905']
>>> ['%.6f' % x.qty['theta'][i,2,0] for i in range(3)]
['267.620434', '267.887077', '268.181961']
 
(e) Illustrate that the get_qty method is the same as accessing
    the quantities dictionary directly:
 
>>> tmp = x.get_qty('theta')
>>> ['%.6f' % tmp[i,2,0] for i in range(3)]
['267.620434', '267.887077', '268.181961']
 
(f) Set T[1,2,0] to missing and calculate eice (note that the
    other quantities, such as theta, that are dependent on T do 
    not recalculate to take into account the new missing value):
 
>>> x.qty['T'][1,2,0] = 1e29
>>> x.eice()
>>> ['%.7g' % x.qty['eice'][i,2,0] for i in range(3)]
['1.285009', '1e+29', '1.351447']
>>> ['%.6f' % x.qty['theta'][i,2,0] for i in range(3)]
['267.620434', '267.887077', '268.181961']

 
Modules
       
MA
Numeric
atmconst
eice
esat
is_numeric_float
theta
vapor_press
virt_temp

 
Classes
       
AtmQty

 
class AtmQty
    Atmospheric quantities in an latitude, longitude, level domain.
 
All attributes in this class that are "atmospheric quantities" 
are assumed to be on the same latitude, longitude, level slab on 
a spherical grid.  Latitude and longitude are always given in 
decimal degrees.  The level coordinate can be different units 
depending on the instantiation of the object.  Methods operating 
on this object are consistent with each other (i.e. equations 
for all quantities are physically consistent) and thus all 
quantities for a given instantiation of the object, for a given 
set of initial state variables (added to the object by the class 
method add_qty) are consistent with each other (assuming there 
is no recalculation of already calculated values during that
instantiation of the object).
 
Usually latitude and longitude span the entire sphere, but this 
is not required.  Vertically the domain can encompass any number
of levels, with a minimum of one level.  (Of course, certain
methods, such as centered differencing, that require a minimum 
number of points, will not work if the number of points in the
domain is not large enough.  The method will fail appropriately
in such cases.)  However, the domain must be contiguous in all 
three spatial dimensions.
 
This class allows one to define a missing value (self.missing).
All quantities that have this value are considered missing and
calculations done using those values will return a missing
value.  Note that the same location may have missing value in
some quantities and not others; missing values do not have to
be co-located.  This type of tracking of missing values is used
instead of masks to save memory; however, some use of the MA 
module is made to help us temporarily manage missing values.
Note that since missing values are stored as self.missing, all
long-term storage of quantities and argument passing (in and
out) of quantities is through plain Numeric arrays, not MA 
arrays.
 
Object Attributes:
* self.const:  Atmospheric constants.  An instance of class
  AtmConst in module atmconst.
* self.lat:  Latitude [deg] vector for all "quantities".
* self.lon:  Longitude [deg] vector for all "quantities".
* self.lev:  Vertical level for all quantities.  Level "type" 
  is given in self.lev_type.  The units of lev depends on 
  lev_type (see description of self.lev_type for details).
* self.lev_type:  The level "type" given in dimension lev, and
  which can have the following values:
  + "pressure":  Vertical levels are in pressure coordinates 
    and lev is in units hPa (default value of lev_type).
  + "isentropic":  Vertical levels are in isentropic (constant
    potential temperature levels) coordinates and lev is in 
    units K.
* self.missing:  Missing value value.  Floating point scalar.
  If undefined at object instantiation, is set to 1e+20.
* self.p0:  Reference pressure used to calculate potential 
  temperature [hPa].  Floating point scalar.  Set by class
  method theta.
* self.qty:  Dictionary of quantities variables.  All quan-
  tities, whether they are input parameters or are calculated 
  from input parameters, are stored in this dictionary.  Pos-
  sible key values include:
  + 'e':  Vapor pressure (with respect to over water) [hPa].
  + 'eice':  Saturation vapor pressure over ice [hPa].
  + 'esat':  Saturation vapor pressure over water [hPa].
  + 'gpot':  Geopotential height [m].
  + 'p':  Pressure [hPa].
  + 'q':  Specific humidity [kg/kg]
  + 'r':  Mixing ratio [kg/kg].
  + 'RH':  Relative humidity [unitless fraction].
  + 'T':  Temperature [K].
  + 'theta':  Potential temperature [K].
  + 'theta_e':  Equivalent potential temperature [K].
  + 'u':  Zonal velocity [m/s].
  + 'v':  Meridional velocity [m/s].
  Values corresponding to these keys are Numeric floating point
  arrays, with a shape specified by the tuple (self.lat
  self.lon, self.lev).
 
Variables self.lat (lon, lev, lev_type) are initialized upon
instantiation of the class and are held fixed for the entire
lifetime of the object.  The values are passed in as arguments 
to the class __init__ method.  Variables self.qty['p'] or 
self.qty['theta'] are also initialized upon object instantiation 
with the values in self.lev, depending on self.lev_type, and
also will not change for the lifetime of the object.  Note if 
self.qty['theta'] is initialized then, self.p0 is also set to
1000 upon object initialization.
 
The class method add_qty adds variable(s) to the self.qty 
dictionary.  If a quantity is an input parameter state variable, 
you have to use this method first to add the variable to self.qty 
in order for it to be available for calculations.  This is used 
instead of requiring variables be in argument lists in class 
methods, to simplify bookkeeping of what variables are defined 
and what are not.  Quantities are deleted from self.qty by the 
class del_qty method.  One can obtain a quantity from the
quantities dictionary with the get_qty method, or by accessing
the qty attribute directly.
 
Note that depending on what lev_type is the quantities pressure
and potential temperature may be an input state variable or a
calculated derived variables.  Also, because all state and 
derived quantities are in self.qty, when an object method is 
called to calculate a derived quantity, the only inputs that 
are supplied in the method argument list are optional ones.
 
  Methods defined here:
__init__(self, lat, lon, lev, lev_type='pressure', missing=1e+20)
Initialize basic class attributes.
 
Method Arguments:
* lat:  Latitude [deg].  Numeric floating point vector.
* lon:  Longitude [deg].  Numeric floating point vector.
* lev:  Vertical level.  Numeric floating point vector.
* lev_type:  The level "type" given in dimension lev.
  Scalar string.
* missing:  Missing value value.  Numeric floating point
  scalar, if defined.  Default is 1e+20.
 
Additional details regarding arguments are in the docstring 
for the class.
add_qty(self, *quantities)
Add/replace variable(s) to quantities dictionary.
 
Method Arguments:
* *quantities:  Each argument is a dictionary with at least
  one key:value pair where the key is the name of the variable 
  and the value is the variable.  The key is a string scalar 
  and the value is a Numeric floating point array.  See the 
  class docstring for details on possible values of the key 
  and additional conditions the value must meet.  There can
  be as many arguments as desired in the add_qty method call.
 
The method adds all the key:value pairs in all the arguments
to the self.qty quantities dictionary of the object.  If the 
quantities dictionary already contains a term, this method 
replaces that term's entry with the input argument value.
 
Examples of syntax:
  x = atmqty.AtmQty(lat, lon, lev, missing=1e29)
  x.add_qty( {'e':e} )
  x.add_qty( {'q':q}, {'T':T} )
  x.add_qty( {'RH':RH, 'esat':esat, 'r':mix_ratio} )
del_qty(self, *quantities)
Delete variable(s) from quantities dictionary.
 
Method Arguments:
* *quantities:  Each argument is a string scalar of the key
  name of the variable in the quantities dictionary.
 
See the class docstring for details on values of the variable
name.  Note if this method is used to remove all entries in
self.qty, self.qty is not set to None but becomes an empty 
dictionary.
div(self)
Calculate divergence.  (Not done yet.)
 
Method Arguments:  None.
 
How do I calculate the stream function and velocity 
potential of the wind?
 
--- import sphere
Step 1. Get winds u and v and their grid vectors, 
longitude values (lonvals) and latitude values (latvals), 
from somewhere.  This example uses 2D fields for simplicity. 
The fields must be global without missing values.  Hint: 
latvals = u.getLatitude()[:] and lonvals = u.getLongitude()[:]
 
Step 2. Make an instance of the Sphere class, x, as
--- x = sphere.Sphere(lonvals, latvals)
 
Step 3. Compute the streamfunction, sf, and the velocity 
potential, vp, using
--- sf, vp = x.sfvp(u, v)
 
@@@still need to write code
eice(self)
Calculate saturation vapor pressure over ice.
 
Method Arguments:  None.
 
Required Quantities in self.qty:  T.
 
Method adds/recalculates saturation vapor pressure over ice 
to the self.qty quantities dictionary (as self.qty['eice']),
overwriting if the term if it previously exists.
 
This method directly implements the stand-alone method 
eice in module eice.  For additional details, type:  
import atmqty.eice; help(atmqty.eice).
esat(self)
Calculate saturation vapor pressure over liquid water.
 
Method Arguments:  None.
 
Required Quantities in self.qty:  T.
 
Method adds/recalculates saturation vapor pressure over
liquid water to the self.qty quantities dictionary (as 
self.qty['esat']), overwriting if the term if it previously 
exists.
 
This method directly implements the stand-alone method 
esat in module esat.  For additional details, type:  
import atmqty.esat; help(atmqty.esat).
get_qty(self, quantity)
Get variable from quantities dictionary.
 
Method Argument:
* quantity:  String scalar of the key name of the variable 
  in the quantities dictionary to obtain.
 
See the class docstring for details on values of the variable
name.  Note this method does not remove the variable from the
quantities dictionary.
theta(self, p0=1000.0)
Calculate potential temperature.
 
Method Arguments:
* p0:  Reference pressure [hPa].  Floating point scalar.
  Optional (default set to 1000).  Class attribute self.p0
  is set to the value of this argument.
 
Required Quantities in self.qty:  p, T.
 
Method adds/recalculates potential temperature to the
self.qty quantities dictionary (as self.qty['theta']), 
overwriting if the term if it previously exists.  self.p0 
is set to the value of argument p0.  If lev is isentropic 
level(s) and this method is called, an error is produced.
 
This method directly implements the stand-alone method 
theta in module theta.  For additional details, type:  
import atmqty.theta; help(atmqty.theta).
vapor_press(self)
Calculate vapor pressure over liquid water.
 
Method Arguments:  None.
 
Required Quantities in self.qty:  p and r, q and r, or RH
and esat.
 
Method adds/recalculates vapor pressure to the self.qty
quantities dictionary (as self.qty['e']), overwriting if the 
term if it previously exists.
 
This method directly implements the stand-alone method 
vapor_press in module vapor_press.  For additional details, 
type:  import atmqty.vapor_press; help(atmqty.vapor_press).

 
Data
        __all__ = ['atmconst', 'eice', 'esat', 'is_numeric_float', 'theta', 'vapor_press', 'virt_temp']
__test__ = {'Additional Example 1: Constants': '\n >>> from atmconst import AtmConst\n >>> c... >>> const.epsilon\n 0.62195306913960091\n ', 'Additional Example 2: Homogenous x-y domain AtmQty object': "\n >>> import atmqty\n >>> import Numeric as...3)]\n ['8.813646', '4.637070', '1.846433']\n ", 'Additional Example 3: More Example 3 methods, with missing values': "\n >>> import atmqty\n >>> import Numeric as...907822', '1e+29', '1.0002703', '0.67660701']\n "}
__version__ = '0.1'