# Path: atmos/constants.py

# 
# Path: atmos/data.py
# def get_coord(data, coord_name, return_type='values'):
#     """Return values, name or dimension of coordinate in DataArray.
# 
#     Parameters
#     ----------
#     data : xray.DataArray
#         Data array to search for latitude coords.
#     coord_name : str
#         Coordinate to extract.  Can be the exact ID of the variable or
#         a generic ID ('lat', 'lon', 'plev', 'time', 'day', 'year').
#         If a generic ID is provided then lists of common names for that ID
#         will be searched for a match.
#     return_type : {'values', 'name', 'dim'}, optional
#         'values' : Return an array of coordinate values.
#         'name' : Return the name of the coordinate.
#         'dim' : Return the dimension of the coordinate.
# 
#     Returns
#     -------
#     output : ndarray, string or int
# 
#     The generic coordinate names searched through are:
#     'lat' : ['lats', 'latitude', 'YDim','Y', 'y']
#     'lon' : ['long', 'lons', 'longitude', 'XDim', 'X', 'x']
#     'plev' : ['plevel', 'plevels', 'lev', 'level',
#               'levels', 'Height']
#     as well as capitalization options for coord_name (.upper(),
#     .lower(), .capitalize())
#     """
# 
#     def name_options(nm):
#         opts = {'lat' : ['lats', 'latitude', 'YDim','Y', 'y'],
#                 'lon' : ['long', 'lons', 'longitude', 'XDim', 'X', 'x'],
#                 'plev' : ['plevel', 'plevels', 'lev', 'level', 'levels',
#                           'Height']}
# 
#         nms = list(set([nm, nm.lower(), nm.upper(), nm.capitalize()]))
#         if opts.get(nm) is not None:
#             nms = list(nms) + opts[nm]
#         return nms
# 
#     names = name_options(coord_name)
# 
#     # Look in list of common coordinate names
#     if coord_name not in data.coords:
#         found = [i for i, s in enumerate(names) if s in data.coords]
# 
#         if len(found) == 0:
#             raise ValueError("Can't find coordinate name in data coords %s" %
#                              data.coords.keys())
#         if len(found) > 1:
#             raise ValueError('Conflicting possible coord names in coords %s'
#                 % data.coords.keys())
#         else:
#             coord_name = names[found[0]]
# 
#     if return_type == 'values':
#         output = data[coord_name].values.copy()
#     elif return_type == 'name':
#         output = coord_name
#     elif return_type == 'dim':
#         output = data.dims.index(coord_name)
#     else:
#         raise ValueError('Invalid return_type ' + return_type)
# 
#     return output
# 
# def int_pres(data, plev=None, pdim=-3, pmin=0, pmax=1e6):
#     """Return the mass-weighted vertical integral of the data.
# 
#     Parameters
#     ----------
#     data : xray.DataArray or ndarray
#         Data to be integrated, on pressure levels.
#     plev : ndarray, optional
#         Vertical pressure levels in Pascals.  Only used if data
#         is an ndarray.  If data is a DataArray, plev is extracted
#         from data and converted to Pa if necessary.
#     pdim : int, optional
#         Dimension of vertical pressure levels in data.
#     pmin, pmax : float, optional
#         Lower and upper bounds (inclusive) of pressure levels (Pa)
#         to include in integration.
# 
#     Returns
#     -------
#     data_int : xray.DataArray or ndarray
#         Mass-weighted vertical integral of data from pmin to pmax.
#     """
# 
#     if isinstance(data, xray.DataArray):
#         i_DataArray = True
#         data = data.copy()
#         name, _, coords, _ = xr.meta(data)
#         attrs = collections.OrderedDict()
#         title = 'Vertically integrated by dp/g'
#         attrs['title'] = title
#         if 'long_name' in data.attrs.keys():
#             attrs['long_name'] = data.attrs['long_name']
#         if 'units' in data.attrs.keys():
#             attrs['units'] = '(' + data.attrs['units'] + ') * kg'
#         pname = get_coord(data, 'plev', 'name')
#         del(coords[pname])
#         if plev is None:
#             # -- Make sure pressure levels are in Pa
#             plev = get_coord(data, 'plev')
#             plev = pres_convert(plev, data[pname].units, 'Pa')
#         data[pname].values = plev
#     else:
#         i_DataArray = False
#         # Pack into DataArray to easily extract pressure level subset
#         pname = 'plev'
#         coords = xr.coords_init(data)
#         coords = xr.coords_assign(coords, pdim, pname, plev)
#         data = xray.DataArray(data, coords=coords)
# 
#     # Extract subset and integrate
#     data = subset(data, {pname : (pmin, pmax)})
#     vals_int = nantrapz(data.values, data[pname].values, axis=pdim)
#     vals_int /= constants.g.values
# 
#     if utils.strictly_decreasing(plev):
#         vals_int = -vals_int
# 
#     if i_DataArray:
#         data_int = xray.DataArray(vals_int, name=name, coords=coords,
#                                   attrs=attrs)
#     else:
#         data_int = vals_int
# 
#     return data_int


import numpy as np
import matplotlib.pyplot as plt
import xray
import atmos.utils as utils
import atmos.plots as ap
import atmos.data as dat
from atmos.constants import const as constants
from atmos.data import get_coord, int_pres


# ----------------------------------------------------------------------
# Read monthly mean climatologies and do some test calcs
# ----------------------------------------------------------------------

filename = 'data/more/ncep2_climatology_monthly.nc'
ds = dat.ncload(filename)
u = ds['u']
v = ds['v']
T = ds['T']
ps = ds['ps']
lat = get_coord(u, 'lat')
lon = get_coord(u, 'lon')

# Path: atmos/constants.py

# 
# Path: atmos/data.py
# def get_coord(data, coord_name, return_type='values'):
#     """Return values, name or dimension of coordinate in DataArray.
# 
#     Parameters
#     ----------
#     data : xray.DataArray
#         Data array to search for latitude coords.
#     coord_name : str
#         Coordinate to extract.  Can be the exact ID of the variable or
#         a generic ID ('lat', 'lon', 'plev', 'time', 'day', 'year').
#         If a generic ID is provided then lists of common names for that ID
#         will be searched for a match.
#     return_type : {'values', 'name', 'dim'}, optional
#         'values' : Return an array of coordinate values.
#         'name' : Return the name of the coordinate.
#         'dim' : Return the dimension of the coordinate.
# 
#     Returns
#     -------
#     output : ndarray, string or int
# 
#     The generic coordinate names searched through are:
#     'lat' : ['lats', 'latitude', 'YDim','Y', 'y']
#     'lon' : ['long', 'lons', 'longitude', 'XDim', 'X', 'x']
#     'plev' : ['plevel', 'plevels', 'lev', 'level',
#               'levels', 'Height']
#     as well as capitalization options for coord_name (.upper(),
#     .lower(), .capitalize())
#     """
# 
#     def name_options(nm):
#         opts = {'lat' : ['lats', 'latitude', 'YDim','Y', 'y'],
#                 'lon' : ['long', 'lons', 'longitude', 'XDim', 'X', 'x'],
#                 'plev' : ['plevel', 'plevels', 'lev', 'level', 'levels',
#                           'Height']}
# 
#         nms = list(set([nm, nm.lower(), nm.upper(), nm.capitalize()]))
#         if opts.get(nm) is not None:
#             nms = list(nms) + opts[nm]
#         return nms
# 
#     names = name_options(coord_name)
# 
#     # Look in list of common coordinate names
#     if coord_name not in data.coords:
#         found = [i for i, s in enumerate(names) if s in data.coords]
# 
#         if len(found) == 0:
#             raise ValueError("Can't find coordinate name in data coords %s" %
#                              data.coords.keys())
#         if len(found) > 1:
#             raise ValueError('Conflicting possible coord names in coords %s'
#                 % data.coords.keys())
#         else:
#             coord_name = names[found[0]]
# 
#     if return_type == 'values':
#         output = data[coord_name].values.copy()
#     elif return_type == 'name':
#         output = coord_name
#     elif return_type == 'dim':
#         output = data.dims.index(coord_name)
#     else:
#         raise ValueError('Invalid return_type ' + return_type)
# 
#     return output
# 
# def int_pres(data, plev=None, pdim=-3, pmin=0, pmax=1e6):
#     """Return the mass-weighted vertical integral of the data.
# 
#     Parameters
#     ----------
#     data : xray.DataArray or ndarray
#         Data to be integrated, on pressure levels.
#     plev : ndarray, optional
#         Vertical pressure levels in Pascals.  Only used if data
#         is an ndarray.  If data is a DataArray, plev is extracted
#         from data and converted to Pa if necessary.
#     pdim : int, optional
#         Dimension of vertical pressure levels in data.
#     pmin, pmax : float, optional
#         Lower and upper bounds (inclusive) of pressure levels (Pa)
#         to include in integration.
# 
#     Returns
#     -------
#     data_int : xray.DataArray or ndarray
#         Mass-weighted vertical integral of data from pmin to pmax.
#     """
# 
#     if isinstance(data, xray.DataArray):
#         i_DataArray = True
#         data = data.copy()
#         name, _, coords, _ = xr.meta(data)
#         attrs = collections.OrderedDict()
#         title = 'Vertically integrated by dp/g'
#         attrs['title'] = title
#         if 'long_name' in data.attrs.keys():
#             attrs['long_name'] = data.attrs['long_name']
#         if 'units' in data.attrs.keys():
#             attrs['units'] = '(' + data.attrs['units'] + ') * kg'
#         pname = get_coord(data, 'plev', 'name')
#         del(coords[pname])
#         if plev is None:
#             # -- Make sure pressure levels are in Pa
#             plev = get_coord(data, 'plev')
#             plev = pres_convert(plev, data[pname].units, 'Pa')
#         data[pname].values = plev
#     else:
#         i_DataArray = False
#         # Pack into DataArray to easily extract pressure level subset
#         pname = 'plev'
#         coords = xr.coords_init(data)
#         coords = xr.coords_assign(coords, pdim, pname, plev)
#         data = xray.DataArray(data, coords=coords)
# 
#     # Extract subset and integrate
#     data = subset(data, {pname : (pmin, pmax)})
#     vals_int = nantrapz(data.values, data[pname].values, axis=pdim)
#     vals_int /= constants.g.values
# 
#     if utils.strictly_decreasing(plev):
#         vals_int = -vals_int
# 
#     if i_DataArray:
#         data_int = xray.DataArray(vals_int, name=name, coords=coords,
#                                   attrs=attrs)
#     else:
#         data_int = vals_int
# 
#     return data_int


# Path: testing/testing-data-int_pres.py
import numpy as np
import matplotlib.pyplot as plt
import xray
import atmos.utils as utils
import atmos.plots as ap
import atmos.data as dat
from atmos.constants import const as constants
from atmos.data import get_coord, int_pres



# ----------------------------------------------------------------------
# Read monthly mean climatologies and do some test calcs
# ----------------------------------------------------------------------

filename = 'data/more/ncep2_climatology_monthly.nc'
ds = dat.ncload(filename)
u = ds['u']
v = ds['v']
T = ds['T']
ps = ds['ps']
lat = get_coord(u, 'lat')
lon = get_coord(u, 'lon')

plev = get_coord(u, 'plev')