forked from 3rdparty/wrf-python
92 changed files with 14000 additions and 12804 deletions
@ -0,0 +1,63 @@
@@ -0,0 +1,63 @@
|
||||
.. _contrib_guide: |
||||
|
||||
Contributor Guide |
||||
================================= |
||||
|
||||
.. note:: |
||||
|
||||
This contributor guide is written for wrf-python v1.3.x. In the |
||||
not-too-distant future, wrf-python will undergo a significant refactoring |
||||
to remove the wrapt decorators (which don't serialize for dask), but the |
||||
concepts will remain the same as described below. |
||||
|
||||
|
||||
Ways to Contribute |
||||
----------------------------- |
||||
|
||||
Users are encouraged to contribute various ways. This includes: |
||||
|
||||
- Submitting a bug report |
||||
- Submitting bug fixes |
||||
- Submitting new Fortran computational routines |
||||
- Submitting new Python computational routines |
||||
- Submitting fully wrapped computational routines |
||||
|
||||
|
||||
Getting the source code |
||||
------------------------------ |
||||
|
||||
The source code is available on GitHub: |
||||
|
||||
https://github.com/NCAR/wrf-python |
||||
|
||||
To checkout the code:: |
||||
|
||||
git clone https://github.com/NCAR/wrf-python |
||||
|
||||
|
||||
Git Flow |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
This project follows the GitFlow Workflow, which you can read about here if it |
||||
is new to you: |
||||
|
||||
https://leanpub.com/git-flow/read |
||||
|
||||
When you first clone the repository, by default you will be on the 'develop' |
||||
branch, which is what you should use for your development. |
||||
|
||||
|
||||
Pull Requests |
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
In order to submit changes, you must use GitHub to issue a pull request. |
||||
|
||||
|
||||
Overview of WRF-Python Internals |
||||
---------------------------------- |
||||
|
||||
WRF-Python is a collection of diagnostic and interpolation routines for WRF-ARW |
||||
data. The API consists of a handful of functions |
||||
|
||||
|
||||
|
@ -1,265 +1,254 @@
@@ -1,265 +1,254 @@
|
||||
from __future__ import (absolute_import, division, print_function) |
||||
|
||||
from .py3compat import py2round |
||||
|
||||
|
||||
|
||||
|
||||
def _binary_operator(operator): |
||||
"""Function wrapper for binary operators. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
operator (method): The operator to wrap. |
||||
|
||||
|
||||
Returns: |
||||
|
||||
|
||||
method: An implementation for the *operator* type. |
||||
|
||||
|
||||
""" |
||||
def func(self, other): |
||||
"""Operator implementation. |
||||
|
||||
Operator action is performed across the same class attributes when |
||||
|
||||
Operator action is performed across the same class attributes when |
||||
the *other* object is a :class:`CoordPair`. If the *other* object is |
||||
a scalar value, the operator action is performed across all |
||||
a scalar value, the operator action is performed across all |
||||
attributes with the scalar value. |
||||
|
||||
|
||||
Args: |
||||
|
||||
other (:class:`CoordPair` or scalar): A separate :class:`CoordPair` |
||||
|
||||
other (:class:`CoordPair` or scalar): A separate :class:`CoordPair` |
||||
object or scalar value. |
||||
|
||||
|
||||
Returns: |
||||
|
||||
:class:`CoordPair`: A new :class:`CoordPair` object that is the |
||||
|
||||
:class:`CoordPair`: A new :class:`CoordPair` object that is the |
||||
result of the operator action. |
||||
|
||||
|
||||
""" |
||||
if isinstance(other, CoordPair): |
||||
args = [ |
||||
None if getattr(self, attr) is None or getattr(other, attr) is None |
||||
else getattr(getattr(self, attr), operator)(getattr(other, attr)) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
args = [None if getattr(self, attr) is None or |
||||
getattr(other, attr) is None else |
||||
getattr(getattr(self, attr), operator)(getattr(other, |
||||
attr)) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
else: |
||||
args = [ |
||||
None if getattr(self, attr) is None |
||||
else getattr(getattr(self, attr), operator)(other) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
|
||||
args = [None if getattr(self, attr) is None |
||||
else getattr(getattr(self, attr), operator)(other) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
|
||||
return CoordPair(*args) |
||||
|
||||
|
||||
return func |
||||
|
||||
|
||||
def _unary_operator(operator): |
||||
"""Function wrapper for unary operators. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
operator (method): The operator to wrap. |
||||
|
||||
|
||||
Returns: |
||||
|
||||
|
||||
method: An implementation for the *operator* type. |
||||
|
||||
|
||||
""" |
||||
def func(self): |
||||
"""Operator implementation. |
||||
|
||||
|
||||
Operator action is performed across all class attributes. |
||||
|
||||
|
||||
Returns: |
||||
|
||||
:class:`CoordPair`: A new :class:`CoordPair` object that is the |
||||
|
||||
:class:`CoordPair`: A new :class:`CoordPair` object that is the |
||||
result of the operator action. |
||||
|
||||
|
||||
""" |
||||
args = [None if getattr(self, attr) is None |
||||
else getattr(getattr(self, attr), operator)() |
||||
else getattr(getattr(self, attr), operator)() |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
|
||||
|
||||
return CoordPair(*args) |
||||
|
||||
|
||||
return func |
||||
|
||||
|
||||
def _cmp_operator(operator): |
||||
"""Function wrapper for comparison operators. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
operator (method): The operator to wrap. |
||||
|
||||
|
||||
Returns: |
||||
|
||||
|
||||
method: An implementation for the *operator* type. |
||||
|
||||
|
||||
""" |
||||
|
||||
|
||||
def func(self, other): |
||||
"""Operator implementation. |
||||
|
||||
Performs a comparison operation across all of the same class |
||||
attributes, and returns True if all these operations are True. |
||||
|
||||
|
||||
Performs a comparison operation across all of the same class |
||||
attributes, and returns True if all these operations are True. |
||||
|
||||
Returns: |
||||
|
||||
:obj:`boot`: Returns True if all comparisons across class |
||||
|
||||
:obj:`boot`: Returns True if all comparisons across class |
||||
attributes returns True, otherwise False. |
||||
|
||||
|
||||
""" |
||||
vals = [getattr(getattr(self, attr), operator)(getattr(other, attr)) |
||||
for attr in ("x", "y", "lat", "lon") |
||||
for attr in ("x", "y", "lat", "lon") |
||||
if getattr(self, attr) is not None] |
||||
|
||||
|
||||
return all(vals) |
||||
|
||||
|
||||
return func |
||||
|
||||
|
||||
|
||||
|
||||
class CoordPair(object): |
||||
"""A class that stores (x, y) and/or (latitude, longitude) |
||||
"""A class that stores (x, y) and/or (latitude, longitude) |
||||
coordinate pairs. |
||||
|
||||
Most math operators are supplied. When the other operand is a |
||||
:class:`CoordPair`, the operation is performed with the same attribute. |
||||
When a math operation uses a scalar as the other operand, the |
||||
operation is applied across all attributes. |
||||
|
||||
|
||||
Most math operators are supplied. When the other operand is a |
||||
:class:`CoordPair`, the operation is performed with the same attribute. |
||||
When a math operation uses a scalar as the other operand, the |
||||
operation is applied across all attributes. |
||||
|
||||
Attributes: |
||||
|
||||
|
||||
x (:obj:`float`): The x-coordinate. |
||||
y (:obj:`float`): The y-coordinate. |
||||
lat (:obj:`float`): The latitude coordinate. |
||||
lon (:obj:`float`): The longitude coordinate. |
||||
|
||||
|
||||
|
||||
|
||||
""" |
||||
def __init__(self, x=None, y=None, lat=None, lon=None): |
||||
"""Initialize a :class:`CoordPair` object. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
x (:obj:`float`, optional): The x-coordinate. |
||||
y (:obj:`float`, optional): The y-coordinate. |
||||
lat (:obj:`float`, optional): The latitude coordinate. |
||||
lon (:obj:`float`, optional): The longitude coordinate. |
||||
|
||||
|
||||
|
||||
|
||||
""" |
||||
self.x = x |
||||
self.y = y |
||||
self.lat = lat |
||||
self.lon = lon |
||||
|
||||
|
||||
|
||||
def __repr__(self): |
||||
args = [] |
||||
if self.x is not None: |
||||
args.append("x={}".format(self.x)) |
||||
args.append("y={}".format(self.y)) |
||||
|
||||
|
||||
if self.lat is not None: |
||||
args.append("lat={}".format(self.lat)) |
||||
args.append("lon={}".format(self.lon)) |
||||
|
||||
|
||||
argstr = ", ".join(args) |
||||
|
||||
|
||||
return "{}({})".format(self.__class__.__name__, argstr) |
||||
|
||||
|
||||
|
||||
def __str__(self): |
||||
return self.__repr__() |
||||
|
||||
|
||||
|
||||
def xy_str(self, fmt="{:.4f}, {:.4f}"): |
||||
"""Return a :obj:`str` for the (x,y) coordinate pair. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
fmt (:obj:`str`): The format string. Default is '{:.4f}, {:.4f}' |
||||
|
||||
|
||||
Returns: |
||||
|
||||
|
||||
:obj:`str`: A string for the (x,y) coordinate pair |
||||
|
||||
|
||||
""" |
||||
if self.x is None or self.y is None: |
||||
return None |
||||
|
||||
|
||||
return fmt.format(self.x, self.y) |
||||
|
||||
|
||||
|
||||
def latlon_str(self, fmt="{:.4f}, {:.4f}"): |
||||
"""Return a :obj:`str` for the (latitude, longitude) coordinate pair. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
fmt (:obj:`str`): The format string. Default is '{:.4f}, {:.4f}' |
||||
|
||||
|
||||
Returns: |
||||
|
||||
|
||||
:obj:`str`: A string for the (latitude, longitude) coordinate pair |
||||
|
||||
|
||||
""" |
||||
if self.lat is None or self.lon is None: |
||||
return None |
||||
|
||||
|
||||
return fmt.format(self.lat, self.lon) |
||||
|
||||
|
||||
|
||||
def __round__(self, ndigits=None): |
||||
"""Return a new :class:`CoordPair` object with all coordinate values |
||||
rounded to the nearest integer. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
ndigits (:obj:`int`): The number of digits. |
||||
|
||||
|
||||
Returns: |
||||
|
||||
|
||||
:class:`CoordPair`: A CoordPair object. |
||||
|
||||
|
||||
""" |
||||
args = [None if getattr(self, attr) is None |
||||
else py2round(getattr(self, attr), ndigits) |
||||
else py2round(getattr(self, attr), ndigits) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
|
||||
|
||||
return CoordPair(*args) |
||||
|
||||
|
||||
|
||||
def __pow__(self, other, modulo=None): |
||||
if isinstance(other, CoordPair): |
||||
args = [ |
||||
None if getattr(self, attr) is None or getattr(other, attr) is None |
||||
else getattr(getattr(self, attr), "__pow__")(getattr(other, attr), |
||||
modulo) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
args = [None if getattr(self, attr) is None or |
||||
getattr(other, attr) is None |
||||
else getattr(getattr(self, attr), "__pow__")( |
||||
getattr(other, attr), modulo) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
else: |
||||
args = [ |
||||
None if getattr(self, attr) is None |
||||
else getattr(getattr(self, attr), "__pow__")(other, modulo) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
|
||||
args = [None if getattr(self, attr) is None |
||||
else getattr(getattr(self, attr), "__pow__")(other, modulo) |
||||
for attr in ("x", "y", "lat", "lon")] |
||||
|
||||
return CoordPair(*args) |
||||
|
||||
|
||||
|
||||
def __rpow__(self, other): |
||||
return self.__pow__(other) |
||||
|
||||
|
||||
for operator in ("__add__", "__divmod__", "__floordiv__", "__mod__", |
||||
"__mul__", "__sub__", "__truediv__", "__radd__", |
||||
"__rdivmod__", "__rsub__", "__rmul__", "__rtruediv__", |
||||
|
||||
for operator in ("__add__", "__divmod__", "__floordiv__", "__mod__", |
||||
"__mul__", "__sub__", "__truediv__", "__radd__", |
||||
"__rdivmod__", "__rsub__", "__rmul__", "__rtruediv__", |
||||
"__rfloordiv__", "__rmod__"): |
||||
setattr(CoordPair, operator, _binary_operator(operator)) |
||||
|
||||
|
||||
|
||||
for operator in ("__neg__", "__pos__", "__abs__", "__invert__"): |
||||
setattr(CoordPair, operator, _unary_operator(operator)) |
||||
|
||||
|
||||
|
||||
for operator in ("__lt__", "__le__", "__eq__", "__ne__", "__gt__", "__ge__"): |
||||
setattr(CoordPair, operator, _cmp_operator(operator)) |
||||
|
||||
|
||||
|
@ -1,164 +1,163 @@
@@ -1,164 +1,163 @@
|
||||
from __future__ import (absolute_import, division, print_function) |
||||
|
||||
#from .extension import computetd |
||||
from .extension import _td |
||||
from .decorators import convert_units |
||||
from .metadecorators import copy_and_set_metadata |
||||
from .util import extract_vars |
||||
|
||||
|
||||
@copy_and_set_metadata(copy_varname="QVAPOR", name="td", |
||||
@copy_and_set_metadata(copy_varname="QVAPOR", name="td", |
||||
description="dew point temperature") |
||||
@convert_units("temp", "c") |
||||
def get_dp(wrfin, timeidx=0, method="cat", squeeze=True, |
||||
def get_dp(wrfin, timeidx=0, method="cat", squeeze=True, |
||||
cache=None, meta=True, _key=None, units="degC"): |
||||
"""Return the dewpoint temperature. |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
object in order to perform the calculation. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
or an iterable sequence of the aforementioned types. |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
all times in the file or sequence. The default is 0. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
The default is 'cat'. |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
of the output. Default is True. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
Default is None. |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
:class:`xarray.DataArray`. Default is True. |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
purposes only. Default is None. |
||||
|
||||
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` |
||||
product table for a list of available units for 'td'. Default |
||||
|
||||
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` |
||||
product table for a list of available units for 'td'. Default |
||||
is 'degC'. |
||||
|
||||
|
||||
Returns: |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The |
||||
dewpoint temperature. |
||||
If xarray is enabled and the *meta* parameter is True, then the result |
||||
will be a :class:`xarray.DataArray` object. Otherwise, the result will |
||||
If xarray is enabled and the *meta* parameter is True, then the result |
||||
will be a :class:`xarray.DataArray` object. Otherwise, the result will |
||||
be a :class:`numpy.ndarray` object with no metadata. |
||||
|
||||
|
||||
""" |
||||
|
||||
varnames=("P", "PB", "QVAPOR") |
||||
|
||||
varnames = ("P", "PB", "QVAPOR") |
||||
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, |
||||
meta=False, _key=_key) |
||||
|
||||
|
||||
p = ncvars["P"] |
||||
pb = ncvars["PB"] |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# break with every release |
||||
qvapor = ncvars["QVAPOR"].copy() |
||||
|
||||
|
||||
# Algorithm requires hPa |
||||
full_p = .01*(p + pb) |
||||
qvapor[qvapor < 0] = 0 |
||||
|
||||
|
||||
td = _td(full_p, qvapor) |
||||
return td |
||||
|
||||
@copy_and_set_metadata(copy_varname="Q2", name="td2", |
||||
|
||||
@copy_and_set_metadata(copy_varname="Q2", name="td2", |
||||
description="2m dew point temperature") |
||||
@convert_units("temp", "c") |
||||
def get_dp_2m(wrfin, timeidx=0, method="cat", squeeze=True, |
||||
def get_dp_2m(wrfin, timeidx=0, method="cat", squeeze=True, |
||||
cache=None, meta=True, _key=None, units="degC"): |
||||
"""Return the 2m dewpoint temperature. |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
object in order to perform the calculation. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
or an iterable sequence of the aforementioned types. |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
all times in the file or sequence. The default is 0. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
The default is 'cat'. |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
of the output. Default is True. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
Default is None. |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
:class:`xarray.DataArray`. Default is True. |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
purposes only. Default is None. |
||||
|
||||
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` |
||||
product table for a list of available units for 'td2'. Default |
||||
|
||||
units (:obj:`str`): The desired units. Refer to the :meth:`getvar` |
||||
product table for a list of available units for 'td2'. Default |
||||
is 'degC'. |
||||
|
||||
|
||||
Returns: |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The |
||||
2m dewpoint temperature. |
||||
If xarray is enabled and the *meta* parameter is True, then the result |
||||
will be a :class:`xarray.DataArray` object. Otherwise, the result will |
||||
If xarray is enabled and the *meta* parameter is True, then the result |
||||
will be a :class:`xarray.DataArray` object. Otherwise, the result will |
||||
be a :class:`numpy.ndarray` object with no metadata. |
||||
|
||||
|
||||
""" |
||||
varnames=("PSFC", "Q2") |
||||
varnames = ("PSFC", "Q2") |
||||
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, |
||||
meta=False, _key=_key) |
||||
|
||||
# Algorithm requires hPa |
||||
psfc = .01*(ncvars["PSFC"]) |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# break with every release |
||||
q2 = ncvars["Q2"].copy() |
||||
q2[q2 < 0] = 0 |
||||
|
||||
|
||||
td = _td(psfc, q2) |
||||
|
||||
return td |
||||
|
||||
return td |
||||
|
@ -1,91 +1,86 @@
@@ -1,91 +1,86 @@
|
||||
from __future__ import (absolute_import, division, print_function) |
||||
|
||||
#from .extension import computepw,computetv,computetk |
||||
from .extension import _pw, _tv, _tk |
||||
from .constants import Constants |
||||
from .util import extract_vars |
||||
from .metadecorators import copy_and_set_metadata |
||||
|
||||
|
||||
@copy_and_set_metadata(copy_varname="T", name="pw", |
||||
@copy_and_set_metadata(copy_varname="T", name="pw", |
||||
remove_dims=("bottom_top",), |
||||
description="precipitable water", |
||||
MemoryOrder="XY", |
||||
units="kg m-2") |
||||
def get_pw(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, |
||||
def get_pw(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, |
||||
meta=True, _key=None): |
||||
"""Return the preciptiable water. |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
object in order to perform the calculation. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
or an iterable sequence of the aforementioned types. |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
all times in the file or sequence. The default is 0. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
The default is 'cat'. |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
of the output. Default is True. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
Default is None. |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
:class:`xarray.DataArray`. Default is True. |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
purposes only. Default is None. |
||||
|
||||
|
||||
Returns: |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The preciptable |
||||
water. If xarray is |
||||
enabled and the *meta* parameter is True, then the result will be a |
||||
:class:`xarray.DataArray` object. Otherwise, the result will be a |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The preciptable |
||||
water. If xarray is |
||||
enabled and the *meta* parameter is True, then the result will be a |
||||
:class:`xarray.DataArray` object. Otherwise, the result will be a |
||||
:class:`numpy.ndarray` object with no metadata. |
||||
|
||||
|
||||
""" |
||||
varnames=("T", "P", "PB", "PH", "PHB", "QVAPOR") |
||||
varnames = ("T", "P", "PB", "PH", "PHB", "QVAPOR") |
||||
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, |
||||
meta=False, _key=_key) |
||||
|
||||
|
||||
t = ncvars["T"] |
||||
p = ncvars["P"] |
||||
pb = ncvars["PB"] |
||||
ph = ncvars["PH"] |
||||
phb = ncvars["PHB"] |
||||
qv = ncvars["QVAPOR"] |
||||
|
||||
|
||||
full_p = p + pb |
||||
ht = (ph + phb)/Constants.G |
||||
full_t = t + Constants.T_BASE |
||||
|
||||
|
||||
tk = _tk(full_p, full_t) |
||||
tv = _tv(tk, qv) |
||||
|
||||
|
||||
return _pw(full_p, tv, qv, ht) |
||||
|
||||
|
||||
|
||||
|
@ -1,156 +1,154 @@
@@ -1,156 +1,154 @@
|
||||
from __future__ import (absolute_import, division, print_function) |
||||
|
||||
from .constants import Constants |
||||
#from .extension import computerh, computetk |
||||
from .constants import Constants |
||||
from .extension import _rh, _tk |
||||
from .util import extract_vars |
||||
from .metadecorators import copy_and_set_metadata |
||||
|
||||
|
||||
@copy_and_set_metadata(copy_varname="T", name="rh", |
||||
@copy_and_set_metadata(copy_varname="T", name="rh", |
||||
description="relative humidity", |
||||
units="%") |
||||
def get_rh(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, |
||||
def get_rh(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, |
||||
meta=True, _key=None): |
||||
"""Return the relative humidity. |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
object in order to perform the calculation. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
or an iterable sequence of the aforementioned types. |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
all times in the file or sequence. The default is 0. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
The default is 'cat'. |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
of the output. Default is True. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
Default is None. |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
:class:`xarray.DataArray`. Default is True. |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
purposes only. Default is None. |
||||
|
||||
|
||||
Returns: |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The relative |
||||
humidity. If xarray is |
||||
enabled and the *meta* parameter is True, then the result will be a |
||||
:class:`xarray.DataArray` object. Otherwise, the result will be a |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The relative |
||||
humidity. If xarray is |
||||
enabled and the *meta* parameter is True, then the result will be a |
||||
:class:`xarray.DataArray` object. Otherwise, the result will be a |
||||
:class:`numpy.ndarray` object with no metadata. |
||||
|
||||
|
||||
""" |
||||
varnames=("T", "P", "PB", "QVAPOR") |
||||
varnames = ("T", "P", "PB", "QVAPOR") |
||||
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, |
||||
meta=False, _key=_key) |
||||
t = ncvars["T"] |
||||
p = ncvars["P"] |
||||
pb = ncvars["PB"] |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# break with every release |
||||
qvapor = ncvars["QVAPOR"].copy() |
||||
|
||||
|
||||
full_t = t + Constants.T_BASE |
||||
full_p = p + pb |
||||
qvapor[qvapor < 0] = 0 |
||||
tk = _tk(full_p, full_t) |
||||
rh = _rh(qvapor, full_p, tk) |
||||
|
||||
|
||||
return rh |
||||
|
||||
|
||||
@copy_and_set_metadata(copy_varname="T2", name="rh2", |
||||
@copy_and_set_metadata(copy_varname="T2", name="rh2", |
||||
description="2m relative humidity", |
||||
units="%") |
||||
def get_rh_2m(wrfin, timeidx=0, method="cat", squeeze=True, cache=None, |
||||
meta=True, _key=None): |
||||
"""Return the 2m relative humidity. |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
|
||||
This functions extracts the necessary variables from the NetCDF file |
||||
object in order to perform the calculation. |
||||
|
||||
|
||||
Args: |
||||
|
||||
|
||||
wrfin (:class:`netCDF4.Dataset`, :class:`Nio.NioFile`, or an \ |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
iterable): WRF-ARW NetCDF |
||||
data as a :class:`netCDF4.Dataset`, :class:`Nio.NioFile` |
||||
or an iterable sequence of the aforementioned types. |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
|
||||
timeidx (:obj:`int` or :data:`wrf.ALL_TIMES`, optional): The |
||||
desired time index. This value can be a positive integer, |
||||
negative integer, or |
||||
:data:`wrf.ALL_TIMES` (an alias for None) to return |
||||
all times in the file or sequence. The default is 0. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
|
||||
method (:obj:`str`, optional): The aggregation method to use for |
||||
sequences. Must be either 'cat' or 'join'. |
||||
'cat' combines the data along the Time dimension. |
||||
'join' creates a new dimension for the file index. |
||||
The default is 'cat'. |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
|
||||
squeeze (:obj:`bool`, optional): Set to False to prevent dimensions |
||||
with a size of 1 from being automatically removed from the shape |
||||
of the output. Default is True. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
|
||||
cache (:obj:`dict`, optional): A dictionary of (varname, ndarray) |
||||
that can be used to supply pre-extracted NetCDF variables to the |
||||
computational routines. It is primarily used for internal |
||||
purposes, but can also be used to improve performance by |
||||
eliminating the need to repeatedly extract the same variables |
||||
used in multiple diagnostics calculations, particularly when using |
||||
large sequences of files. |
||||
Default is None. |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
|
||||
meta (:obj:`bool`, optional): Set to False to disable metadata and |
||||
return :class:`numpy.ndarray` instead of |
||||
:class:`xarray.DataArray`. Default is True. |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
|
||||
_key (:obj:`int`, optional): A caching key. This is used for internal |
||||
purposes only. Default is None. |
||||
|
||||
|
||||
Returns: |
||||
:class:`xarray.DataArray` or :class:`numpy.ndarray`: The 2m relative |
||||
humidity. If xarray is |
||||
enabled and the *meta* parameter is True, then the result will be a |
||||
:class:`xarray.DataArray` object. Otherwise, the result will be a |
||||
humidity. If xarray is |
||||
enabled and the *meta* parameter is True, then the result will be a |
||||
:class:`xarray.DataArray` object. Otherwise, the result will be a |
||||
:class:`numpy.ndarray` object with no metadata. |
||||
|
||||
|
||||
""" |
||||
varnames=("T2", "PSFC", "Q2") |
||||
varnames = ("T2", "PSFC", "Q2") |
||||
ncvars = extract_vars(wrfin, timeidx, varnames, method, squeeze, cache, |
||||
meta=False, _key=_key) |
||||
t2 = ncvars["T2"] |
||||
psfc = ncvars["PSFC"] |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# Copy needed for the mmap nonsense of scipy.io.netcdf, which seems to |
||||
# break with every release |
||||
q2 = ncvars["Q2"].copy() |
||||
|
||||
|
||||
q2[q2 < 0] = 0 |
||||
rh = _rh(q2, psfc, t2) |
||||
|
||||
return rh |
||||
|
||||
return rh |
||||
|
@ -1,2 +1 @@
@@ -1,2 +1 @@
|
||||
__version__ = "1.3.1" |
||||
|
||||
__version__ = "1.3.2" |
||||
|
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
|
||||
from netCDF4 import Dataset |
||||
|
||||
VARS_TO_KEEP = ("Times", "XLAT", "XLONG", "XLAT_U", "XLAT_V", "XLONG_U", |
||||
"XLONG_V", "U", "V", "W", "PH", "PHB", "T", "P", "PB", "Q2", |
||||
"T2", "PSFC", "U10", "V10", "XTIME", "QVAPOR", "QCLOUD", |
||||
"QGRAUP", "QRAIN", "QSNOW", "QICE", "MAPFAC_M", "MAPFAC_U", |
||||
"MAPFAC_V", "F", "HGT", "RAINC", "RAINSH", "RAINNC", |
||||
"I_RAINC", "I_RAINNC") |
||||
|
||||
INPUT_FILE = "wrfout_d02_2005-08-28_00:00:00" |
||||
OUTPUT_FILE = "wrfout_problem_file" |
||||
DESIRED_TIME_INDEX = 0 |
||||
|
||||
with Dataset(INPUT_FILE) as infile, Dataset(OUTPUT_FILE, mode="w") as outfile: |
||||
# Copy the global attributes |
||||
outfile.setncatts(infile.__dict__) |
||||
|
||||
# Copy Dimensions |
||||
for name, dimension in infile.dimensions.items(): |
||||
if name != "Time": |
||||
dimsize = len(dimension) |
||||
outfile.createDimension(name, dimsize) |
||||
else: |
||||
outfile.createDimension(name, 1) |
||||
|
||||
# Copy Variables |
||||
for name, variable in infile.variables.iteritems(): |
||||
if name not in VARS_TO_KEEP: |
||||
continue |
||||
|
||||
outvar = outfile.createVariable(name, variable.datatype, |
||||
variable.dimensions, zlib=True) |
||||
|
||||
if len(variable.dimensions) > 1: |
||||
outvar[:] = variable[DESIRED_TIME_INDEX, :] |
||||
else: |
||||
outvar[:] = variable[DESIRED_TIME_INDEX] |
||||
|
||||
outvar.setncatts(variable.__dict__) |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
from __future__ import print_function, division |
||||
|
||||
import os |
||||
import numpy as np |
||||
from netCDF4 import Dataset |
||||
from wrf import getvar, ALL_TIMES, to_np |
||||
import xarray |
||||
|
||||
filename_list = ["/Users/ladwig/Documents/wrf_files/" |
||||
"wrf_vortex_single/wrfout_d02_2005-08-28_00:00:00", |
||||
"/Users/ladwig/Documents/wrf_files/wrf_vortex_single/" |
||||
"wrfout_d02_2005-08-28_03:00:00", |
||||
"/Users/ladwig/Documents/wrf_files/wrf_vortex_single/" |
||||
"wrfout_d02_2005-08-28_06:00:00", |
||||
"/Users/ladwig/Documents/wrf_files/wrf_vortex_single/" |
||||
"wrfout_d02_2005-08-28_09:00:00"] |
||||
|
||||
result_shape = (4, 1, 96, 96) |
||||
|
||||
# Let's get the first time so we can copy the metadata later |
||||
f = Dataset(filename_list[0]) |
||||
# By setting squeeze to False, you'll get all the dimension names. |
||||
z1 = getvar(f, "T2", 0, squeeze=False) |
||||
xlat = getvar(f, "XLAT", 0) |
||||
xlong = getvar(f, "XLONG", 0) |
||||
|
||||
|
||||
z_final = np.empty(result_shape, np.float32) |
||||
|
||||
# Modify this number if using more than 1 time per file |
||||
times_per_file = 1 |
||||
|
||||
data_times = [] |
||||
xtimes = [] |
||||
for timeidx in range(result_shape[0]): |
||||
# Compute the file index and the time index inside the file |
||||
fileidx = timeidx // times_per_file |
||||
file_timeidx = timeidx % times_per_file |
||||
|
||||
f = Dataset(filename_list[fileidx]) |
||||
z = getvar(f, "T2", file_timeidx) |
||||
t = getvar(f, "Times", file_timeidx) |
||||
xt = getvar(f, "xtimes", file_timeidx) |
||||
data_times.append(to_np(t)) |
||||
xtimes.append(to_np(xt)) |
||||
z_final[timeidx, :] = z[:] |
||||
f.close() |
||||
|
||||
# Let's make the metadata. Dimension names should copy easily if you set |
||||
# sqeeze to False, otherwise you can just set them yourself is a tuple of |
||||
# dimension names. Since you wanted |
||||
# to keep the bottom_top dimension for this 2D variable (which is normally |
||||
# removed), I'm doing this manually. |
||||
z_dims = ["Time", "bottom_top", "south_north", "west_east"] |
||||
|
||||
# Xarray doesn't copy coordinates easily (it always complains about shape |
||||
# mismatches), so do this manually |
||||
z_coords = {} |
||||
z_coords["Time"] = data_times |
||||
z_coords["XTIME"] = ("Time",), xtimes |
||||
z_coords["XLAT"] = ("south_north", "west_east"), xlat |
||||
z_coords["XLONG"] = ("south_north", "west_east"), xlong |
||||
z_name = "T2" |
||||
|
||||
# Attributes copy nicely |
||||
z_attrs = {} |
||||
z_attrs.update(z1.attrs) |
||||
|
||||
z_with_meta = xarray.DataArray(z_final, coords=z_coords, dims=z_dims, |
||||
attrs=z_attrs, name=z_name) |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
from netCDF4 import Dataset |
||||
import numpy as np |
||||
import matplotlib.pyplot as plt |
||||
from matplotlib.cm import get_cmap |
||||
import cartopy.crs as crs |
||||
from cartopy.feature import NaturalEarthFeature |
||||
|
||||
from wrf import (getvar, interplevel, to_np, latlon_coords, get_cartopy, |
||||
cartopy_xlim, cartopy_ylim) |
||||
|
||||
# Open the NetCDF file |
||||
ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") |
||||
|
||||
# Extract the pressure and wind variables |
||||
|
||||
p = getvar(ncfile, "pressure") |
||||
# Note: This is m/s. |
||||
ua = getvar(ncfile, "ua") |
||||
va = getvar(ncfile, "va") |
||||
|
||||
# Interpolate u, and v winds to 950 hPa |
||||
u_950 = interplevel(ua, p, 950) |
||||
v_950 = interplevel(va, p, 950) |
||||
|
||||
# Get the lat/lon coordinates |
||||
lats, lons = latlon_coords(u_950) |
||||
|
||||
# Get the map projection information |
||||
cart_proj = get_cartopy(u_950) |
||||
|
||||
# Create the figure |
||||
fig = plt.figure(figsize=(12, 9)) |
||||
ax = plt.axes(projection=cart_proj) |
||||
|
||||
# Download and add the states and coastlines |
||||
states = NaturalEarthFeature(category='cultural', scale='50m', |
||||
facecolor='none', |
||||
name='admin_1_states_provinces_shp') |
||||
ax.add_feature(states, linewidth=0.5) |
||||
ax.coastlines('50m', linewidth=0.8) |
||||
|
||||
# Add the 950 hPa wind barbs, only plotting every 'thin'ed barb. Adjust thin |
||||
# as needed. Also, no scaling is done for the arrows, so you might need to |
||||
# mess with the scale argument. |
||||
thin = 50 |
||||
plt.quiver(to_np(lons[::thin, ::thin]), to_np(lats[::thin, ::thin]), |
||||
to_np(u_950[::thin, ::thin]), to_np(v_950[::thin, ::thin]), |
||||
transform=crs.PlateCarree()) |
||||
|
||||
# Set the map bounds |
||||
ax.set_xlim(cartopy_xlim(u_950)) |
||||
ax.set_ylim(cartopy_ylim(v_950)) |
||||
|
||||
ax.gridlines() |
||||
|
||||
plt.title("Arrows") |
||||
|
||||
plt.show() |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
import matplotlib.pyplot as plt |
||||
from mpl_toolkits.basemap import Basemap |
||||
|
||||
|
||||
def main(): |
||||
bm = Basemap(projection="rotpole", |
||||
o_lat_p=36.0, |
||||
o_lon_p=180.0, |
||||
llcrnrlat=-10.590603, |
||||
urcrnrlat=46.591976, |
||||
llcrnrlon=-139.08585, |
||||
urcrnrlon=22.661009, |
||||
lon_0=-106.0, |
||||
rsphere=6370000, |
||||
resolution='l') |
||||
|
||||
fig = plt.figure(figsize=(8, 8)) |
||||
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) |
||||
|
||||
bm.drawcoastlines(linewidth=.5) |
||||
|
||||
print(bm.proj4string) |
||||
|
||||
plt.savefig("basemap_map.png") |
||||
plt.close(fig) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
main() |
@ -1,26 +1,25 @@
@@ -1,26 +1,25 @@
|
||||
# Test snippet for f2py |
||||
import numpy as np |
||||
|
||||
import wrf._wrffortran |
||||
errlen = int(wrf._wrffortran.constants.errlen) |
||||
|
||||
|
||||
a = np.ones((3,3,3)) |
||||
b = np.zeros((3,3,3,3)) |
||||
a = np.ones((3, 3, 3)) |
||||
b = np.zeros((3, 3, 3, 3)) |
||||
c = np.zeros(errlen, "c") |
||||
errstat = np.array(0) |
||||
errmsg = np.zeros(errlen, "c") |
||||
|
||||
c[:] = "Test String" |
||||
|
||||
|
||||
for i in xrange(2): |
||||
outview = b[i,:] |
||||
outview = b[i, :] |
||||
outview = outview.T |
||||
q = wrf._wrffortran.testfunc(a,outview,c,errstat=errstat,errmsg=errmsg) |
||||
print errstat |
||||
|
||||
q = wrf._wrffortran.testfunc(a, outview, c, errstat=errstat, |
||||
errmsg=errmsg) |
||||
print(errstat) |
||||
|
||||
|
||||
str_bytes = (bytes(char).decode("utf-8") for char in errmsg[:]) |
||||
print repr(errmsg) |
||||
print "".join(str_bytes).strip() |
||||
print(repr(errmsg)) |
||||
print("".join(str_bytes).strip()) |
@ -0,0 +1,230 @@
@@ -0,0 +1,230 @@
|
||||
# Hastily made script to read WPS intermediate files |
||||
from __future__ import print_function |
||||
import struct |
||||
|
||||
import numpy as np |
||||
|
||||
# Number of bytes used at the start and end of a fortran record to |
||||
# indicate the record size |
||||
SIZE_BYTES = 4 |
||||
|
||||
|
||||
class WPSData(object): |
||||
def __init__(self, ifv=None, hdate=None, xfcst=None, map_source=None, |
||||
field=None, units=None, desc=None, xlvl=None, nx=None, |
||||
ny=None, iproj=None, startloc=None, startlat=None, |
||||
startlon=None, deltalat=None, deltalon=None, nlats=None, |
||||
dx=None, dy=None, xlonc=None, truelat1=None, truelat2=None, |
||||
earth_radius=None, is_wind_earth_rel=None, slab=None): |
||||
|
||||
self.ifv = ifv |
||||
self.hdate = hdate |
||||
self.xfcst = xfcst |
||||
self.map_source = map_source |
||||
self.field = field |
||||
self.units = units |
||||
self.desc = desc |
||||
self.xlvl = xlvl |
||||
self.nx = nx |
||||
self.ny = ny |
||||
self.iproj = iproj |
||||
self.startloc = startloc |
||||
self.startlat = startlat |
||||
self.startlon = startlon |
||||
self.deltalat = deltalat |
||||
self.deltalon = deltalon |
||||
self.nlats = nlats |
||||
self.dx = dx |
||||
self.dy = dy |
||||
self.xlonc = xlonc |
||||
self.truelat1 = truelat1 |
||||
self.truelat2 = truelat2 |
||||
self.earth_radius = earth_radius |
||||
self.is_wind_earth_rel = is_wind_earth_rel |
||||
self.slab = slab |
||||
|
||||
|
||||
def _parse_record1(data): |
||||
result = {} |
||||
result["ifv"] = struct.unpack(">i", data) |
||||
|
||||
return result |
||||
|
||||
|
||||
def _parse_record2(data): |
||||
result = {} |
||||
parsed = struct.unpack(">24sf32s9s25s46sfiii", data) |
||||
result["hdate"] = parsed[0] |
||||
result["xfcst"] = parsed[1] |
||||
result["map_source"] = parsed[2] |
||||
result["field"] = parsed[3] |
||||
result["units"] = parsed[4] |
||||
result["desc"] = parsed[5] |
||||
result["xlvl"] = parsed[6] |
||||
result["nx"] = parsed[7] |
||||
result["ny"] = parsed[8] |
||||
result["iproj"] = parsed[9] |
||||
|
||||
return result |
||||
|
||||
|
||||
def _parse_record3(data, iproj): |
||||
result = {} |
||||
if iproj == 0: |
||||
fmt = ">8sfffff" |
||||
parsed = struct.unpack(fmt, data) |
||||
result["startloc"] = parsed[0] |
||||
result["startlat"] = parsed[1] |
||||
result["startlon"] = parsed[2] |
||||
result["deltalat"] = parsed[3] |
||||
result["deltalon"] = parsed[4] |
||||
result["earth_radius"] = parsed[5] |
||||
elif iproj == 1: |
||||
fmt = ">8sffffff" |
||||
parsed = struct.unpack(fmt, data) |
||||
result["startloc"] = parsed[0] |
||||
result["startlat"] = parsed[1] |
||||
result["startlon"] = parsed[2] |
||||
result["dx"] = parsed[3] |
||||
result["dy"] = parsed[4] |
||||
result["truelat1"] = parsed[5] |
||||
result["earth_radius"] = parsed[6] |
||||
elif iproj == 3: |
||||
fmt = ">8sffffffff" |
||||
parsed = struct.unpack(fmt, data) |
||||
result["startloc"] = parsed[0] |
||||
result["startlat"] = parsed[1] |
||||
result["startlon"] = parsed[2] |
||||
result["dx"] = parsed[3] |
||||
result["dy"] = parsed[4] |
||||
result["xlonc"] = parsed[5] |
||||
result["truelat1"] = parsed[6] |
||||
result["truelat2"] = parsed[7] |
||||
result["earth_radius"] = parsed[8] |
||||
elif iproj == 4: |
||||
fmt = ">8sfffff" |
||||
parsed = struct.unpack(fmt, data) |
||||
result["startloc"] = parsed[0] |
||||
result["startlat"] = parsed[1] |
||||
result["startlon"] = parsed[2] |
||||
result["nlats"] = parsed[3] |
||||
result["deltalon"] = parsed[4] |
||||
result["earth_radius"] = parsed[5] |
||||
elif iproj == 5: |
||||
fmt = ">8sfffffff" |
||||
parsed = struct.unpack(fmt, data) |
||||
result["startloc"] = parsed[0] |
||||
result["startlat"] = parsed[1] |
||||
result["startlon"] = parsed[2] |
||||
result["dx"] = parsed[3] |
||||
result["dy"] = parsed[4] |
||||
result["xlonc"] = parsed[5] |
||||
result["truelat1"] = parsed[6] |
||||
result["earth_radius"] = parsed[7] |
||||
|
||||
return result |
||||
|
||||
|
||||
def _parse_record4(data): |
||||
result = {} |
||||
result["is_wind_earth_rel"] = struct.unpack(">i", data) |
||||
|
||||
return result |
||||
|
||||
|
||||
def _parse_record5(data, nx, ny): |
||||
result = {} |
||||
|
||||
size = nx * ny |
||||
fmt = ">{}f".format(size) |
||||
parsed = struct.unpack(fmt, data) |
||||
|
||||
arr = np.array(parsed, dtype=np.float32) |
||||
result["slab"] = arr.reshape((nx, ny), order="F") |
||||
|
||||
return result |
||||
|
||||
|
||||
_PARSE_MAP = {0: _parse_record1, |
||||
1: _parse_record2, |
||||
2: _parse_record3, |
||||
3: _parse_record4, |
||||
4: _parse_record5} |
||||
|
||||
|
||||
def parse_record(record_idx, data, iproj=None, nx=None, ny=None): |
||||
|
||||
if record_idx == 0 or record_idx == 1 or record_idx == 3: |
||||
return _PARSE_MAP[record_idx](data) |
||||
elif record_idx == 2: |
||||
return _PARSE_MAP[record_idx](data, iproj) |
||||
elif record_idx == 4: |
||||
return _PARSE_MAP[record_idx](data, nx, ny) |
||||
|
||||
|
||||
def read_wps(wps_file, field=None): |
||||
with open(wps_file, "rb") as f: |
||||
wps_params = {} |
||||
record_list = [] |
||||
raw_data = f.read() |
||||
|
||||
record_size_idx = 0 |
||||
end_of_file_idx = len(raw_data) - 1 |
||||
|
||||
while True: |
||||
iproj = None |
||||
nx = None |
||||
ny = None |
||||
keep_record = True |
||||
for record_idx in range(5): |
||||
# Each record has the size (in SIZE_BYTES bytes) at the |
||||
# start and end of each record. This might be compiler |
||||
# dependent though, so this might need to be modified. |
||||
# Also, the WPS files are stored big endian. |
||||
|
||||
record_size = struct.unpack( |
||||
">i", |
||||
raw_data[record_size_idx: record_size_idx + SIZE_BYTES]) |
||||
record_start = record_size_idx + SIZE_BYTES |
||||
record_end = record_start + record_size[0] |
||||
record_data = raw_data[record_start:record_end] |
||||
|
||||
parsed_record = parse_record(record_idx, record_data, iproj, |
||||
nx, ny) |
||||
|
||||
try: |
||||
field_name = parsed_record["field"].strip() |
||||
except KeyError: |
||||
pass |
||||
else: |
||||
if field is not None: |
||||
if field_name != field: |
||||
keep_record = False |
||||
|
||||
try: |
||||
iproj = parsed_record["iproj"] |
||||
except KeyError: |
||||
pass |
||||
|
||||
try: |
||||
nx = parsed_record["nx"] |
||||
except KeyError: |
||||
pass |
||||
|
||||
try: |
||||
ny = parsed_record["ny"] |
||||
except KeyError: |
||||
pass |
||||
|
||||
wps_params.update(parsed_record) |
||||
|
||||
record_size_idx = record_end + SIZE_BYTES |
||||
|
||||
if keep_record: |
||||
record_list.append(WPSData(**wps_params)) |
||||
|
||||
# Repeat for all record slabs |
||||
if record_end + SIZE_BYTES > end_of_file_idx: |
||||
break |
||||
|
||||
return record_list |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
input_file = addfile("/Users/ladwig/Documents/wrf_files/wrfout_d02_2010-06-13_21:00:00.nc", "r") |
||||
|
||||
z = wrf_user_getvar(input_file, "z", 0) ; grid point height |
||||
p = wrf_user_getvar(input_file, "pressure", 0) ; total pressure |
||||
|
||||
dimsz = dimsizes(z) |
||||
pivot = (/ (dimsz(2)-1)/2, (dimsz(1)-1)/2 /) ; pivot point is center of domain |
||||
|
||||
; For the new cross section routine |
||||
xopt = True |
||||
xopt@use_pivot = True |
||||
xopt@angle = 45.0 |
||||
;xopt@levels = |
||||
;xopt@latlon = |
||||
xopt@file_handle = input_file |
||||
;xopt@timeidx = |
||||
xopt@linecoords = True |
||||
|
||||
ht_vertcross = wrf_user_vertcross(z, p, pivot, xopt) |
||||
|
||||
printVarSummary(ht_vertcross) |
||||
print(min(ht_vertcross@lats)) |
||||
print(min(ht_vertcross@lons)) |
||||
print(max(ht_vertcross@lats)) |
||||
print(max(ht_vertcross@lons)) |
||||
|
||||
|
||||
xopt@use_pivot = False |
||||
xopt@angle = 0.0 |
||||
;xopt@levels = |
||||
xopt@latlon = True |
||||
xopt@file_handle = input_file |
||||
xopt@timeidx = 0 |
||||
xopt@linecoords = True |
||||
|
||||
loc_param = (/-104.3632, 32.8562, -95.15308, 40.06575 /) ; pivot point is center of domain |
||||
ht_vertcross2 = wrf_user_vertcross(z, p, loc_param, xopt) |
||||
|
||||
printVarSummary(ht_vertcross2) |
||||
print(min(ht_vertcross2@lats)) |
||||
print(min(ht_vertcross2@lons)) |
||||
print(max(ht_vertcross2@lats)) |
||||
print(max(ht_vertcross2@lons)) |
||||
|
||||
print(ht_vertcross2@lats(190)) |
||||
print(ht_vertcross2@lons(190)) |
||||
|
||||
xopt@use_pivot = True |
||||
xopt@angle = 45.0 |
||||
;xopt@levels = |
||||
xopt@latlon = True |
||||
xopt@file_handle = input_file |
||||
xopt@timeidx = 0 |
||||
xopt@linecoords = True |
||||
|
||||
loc_param := (/-99.98572, 36.54949 /) ; pivot point is center of domain |
||||
ht_vertcross3 = wrf_user_vertcross(z, p, loc_param, xopt) |
||||
|
||||
printVarSummary(ht_vertcross3) |
||||
print(min(ht_vertcross3@lats)) |
||||
print(min(ht_vertcross3@lons)) |
||||
print(max(ht_vertcross3@lats)) |
||||
print(max(ht_vertcross3@lons)) |
||||
|
||||
|
||||
xopt@use_pivot = True |
||||
xopt@angle = 45.0 |
||||
xopt@levels = (/1000., 850., 700., 500., 250. /) |
||||
xopt@latlon = True |
||||
xopt@file_handle = input_file |
||||
xopt@timeidx = 0 |
||||
xopt@linecoords = True |
||||
|
||||
loc_param := (/-99.98572, 36.54949 /) ; pivot point is center of domain |
||||
ht_vertcross4 = wrf_user_vertcross(z, p, loc_param, xopt) |
||||
|
||||
printVarSummary(ht_vertcross4) |
||||
print(min(ht_vertcross4@lats)) |
||||
print(min(ht_vertcross4@lons)) |
||||
print(max(ht_vertcross4@lats)) |
||||
print(max(ht_vertcross4@lons)) |
||||
|
||||
o = True |
||||
o@returnInt = False |
||||
o@useTime = 0 |
||||
l = wrf_user_ll_to_xy(input_file, -99.98572, 36.54949, o) |
||||
print(l) |
||||
|
||||
|
||||
l1 = wrf_user_xy_to_ll(input_file, l(1), l(0), o) |
||||
print(l1) |
||||
|
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
a = addfile("wrfout_d03_2017-04-03_06:00:00_ctrl","r") |
||||
|
||||
time = 0 |
||||
refl_10cm = wrf_user_getvar(a,"REFL_10CM",time) |
||||
z = wrf_user_getvar(a, "z", time) |
||||
lat = wrf_user_getvar(a, "lat", time) |
||||
lon = wrf_user_getvar(a, "lon", time) |
||||
|
||||
; convert the lat/lon to x,y |
||||
start_lat = 20.9 |
||||
start_lon = 92.5 |
||||
end_lat = 29.2 |
||||
end_lon = 92.5 |
||||
|
||||
opt = True |
||||
|
||||
start_ij = wrf_user_ll_to_ij(a, start_lon, start_lat, opt) |
||||
start_ij = start_ij - 1 |
||||
|
||||
end_ij = wrf_user_ll_to_ij(a, end_lon, end_lat, opt) |
||||
end_ij = end_ij - 1 |
||||
|
||||
start_end = (/start_ij(0), start_ij(1), end_ij(0), end_ij(1)/) |
||||
|
||||
lat_line = wrf_user_intrp2d(lat,start_end,0.0,True) |
||||
nlat = dimsizes(lat_line) |
||||
|
||||
lon_line = wrf_user_intrp2d(lon,start_end,0.0,True) |
||||
|
||||
refl_cross = wrf_user_intrp3d(refl_10cm,z,"v",start_end,0.,True) |
||||
|
||||
; Need to make a vertical coordinate by using the same code as the |
||||
; cross section |
||||
|
||||
; Currently, the vertical coordinate is not set, so let's do it |
||||
; manually. This will be fixed in the next version of NCL. |
||||
; If you want to set these levels yourself, you'll need to copy the |
||||
; code I sent before and manually set the levels in the cross section |
||||
; routine, then do it again here. |
||||
|
||||
z_max = max(z) |
||||
z_min = 0. |
||||
dz = 0.01 * z_max |
||||
nlevels = tointeger( z_max/dz ) |
||||
z_var2d = new( (/nlevels/), typeof(z)) |
||||
z_var2d(0) = z_min |
||||
|
||||
do i=1, nlevels-1 |
||||
z_var2d(i) = z_var2d(0)+i*dz |
||||
end do |
||||
|
||||
refl_cross&Vertical = z_var2d |
||||
|
||||
wks = gsn_open_wks("png","cross") |
||||
cmap := read_colormap_file("BlAqGrYeOrReVi200") |
||||
cmap(0,:) = (/0,0,0,0/) ; make first color fully transparent |
||||
|
||||
resx = True |
||||
resx@gsnMaximize = True |
||||
resx@lbLabelAutoStride = True ; default v6.1.0 |
||||
|
||||
resx@cnFillOn = True ; turn on color fill |
||||
resx@cnLinesOn = False ; turn lines on/off ; True is default |
||||
resx@cnLineLabelsOn = False ; turn line labels on/off ; True is default |
||||
resx@cnFillPalette = cmap |
||||
nLabels = 8 ; arbitrary |
||||
resx@tmXBLabels = new(nLabels,"string") |
||||
resx@tmXBMode = "Explicit" |
||||
|
||||
resx@tmXBValues := toint(fspan(0,nlat-1,nLabels)) |
||||
do i=0,nLabels-1 |
||||
x = lon_line(i) |
||||
y = lat_line(i) |
||||
resx@tmXBLabels(i) = sprintf("%5.1f", y)+"~C~"+sprintf("%5.1f", x) |
||||
end do |
||||
|
||||
resx@tiMainString = "Full South-North Grid Line X-Section" |
||||
|
||||
|
||||
plot1 = gsn_csm_contour(wks, refl_cross, resx ) |
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
|
||||
;---Open file and calculate slp. |
||||
a = addfile("/Users/ladwig/Documents/wrf_files/rotated_pole_test.nc","r") |
||||
|
||||
t2 = wrf_user_getvar(a,"T2",0) |
||||
|
||||
;---Start the graphics |
||||
wks = gsn_open_wks("x11","wrf") |
||||
|
||||
;---Set some graphical resources |
||||
res = True |
||||
res@gsnMaximize = True |
||||
res@cnFillOn = True |
||||
res@tfDoNDCOverlay = True ; This is necessary if you don't |
||||
; set sfXArray/sfYArray |
||||
|
||||
;---Add additional map resources |
||||
res = wrf_map_resources(a,res) |
||||
|
||||
;---Change some of the resources that were set (these were set to "gray") |
||||
res@mpGeophysicalLineColor = "black" |
||||
res@mpNationalLineColor = "black" |
||||
res@mpUSStateLineColor = "black" |
||||
|
||||
plot = gsn_csm_contour_map(wks,t2,res) |
||||
|
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
ifils = systemfunc ("ls /Users/ladwig/Documents/wrf_files/wrf_vortex_single/wrfout_d02_*") |
||||
print(ifils) |
||||
a = addfiles(ifils, "r") |
||||
;a = addfile("/Users/ladwig/Documents/wrf_files/wrfout_d01_2010-06-13_21:00:00.nc", "r") |
||||
|
||||
lats := (/22.0, 25.0, 27.0 /) |
||||
lons := (/-90.0, -87.5, -83.75 /) |
||||
|
||||
opt = True |
||||
opt@useTime = -1 |
||||
opt@returnI = False |
||||
xy = wrf_user_ll_to_xy(a, lons, lats, opt) |
||||
|
||||
print(xy) |
||||
|
||||
x_s = (/10, 50, 90 /) |
||||
y_s = (/10, 50, 90 /) |
||||
|
||||
ll = wrf_user_xy_to_ll(a, x_s, y_s, opt) |
||||
print(ll) |
||||
|
@ -0,0 +1,416 @@
@@ -0,0 +1,416 @@
|
||||
;-------------------------------------------------------------------------------- |
||||
|
||||
undef("wrf_user_ll_to_xy") |
||||
function wrf_user_ll_to_xy( file_handle, longitude:numeric, latitude:numeric, \ |
||||
opts_args:logical ) |
||||
|
||||
; This is the same as wrf_user_ll_to_ij, but returns 0-based indexes |
||||
|
||||
begin |
||||
; |
||||
; As of NCL V6.0.0, wrf_user_ll_to_ij can now handle a file |
||||
; or a list of files. |
||||
; |
||||
if(typeof(file_handle).eq."file") then |
||||
ISFILE = True |
||||
nc_file = file_handle |
||||
elseif(typeof(file_handle).eq."list") then |
||||
ISFILE = False |
||||
nc_file = file_handle[0] |
||||
else |
||||
print("wrf_user_ll_to_xy: Error: the first argument must be a file or a list of files opened with addfile or addfiles") |
||||
return |
||||
end if |
||||
|
||||
opts = opts_args |
||||
useT = get_res_value(opts,"useTime",0) |
||||
returnI= get_res_value(opts,"returnInt",True) |
||||
|
||||
res = True |
||||
res@MAP_PROJ = nc_file@MAP_PROJ |
||||
res@TRUELAT1 = nc_file@TRUELAT1 |
||||
res@TRUELAT2 = nc_file@TRUELAT2 |
||||
res@STAND_LON = nc_file@STAND_LON |
||||
res@DX = nc_file@DX |
||||
res@DY = nc_file@DY |
||||
|
||||
if (res@MAP_PROJ .eq. 6) then |
||||
res@POLE_LAT = nc_file@POLE_LAT |
||||
res@POLE_LON = nc_file@POLE_LON |
||||
res@LATINC = (res@DY*360.)/2.0/3.141592653589793/6370000. |
||||
res@LONINC = (res@DX*360.)/2.0/3.141592653589793/6370000. |
||||
else |
||||
res@POLE_LAT = 90.0 |
||||
res@POLE_LON = 0.0 |
||||
res@LATINC = 0.0 |
||||
res@LONINC = 0.0 |
||||
end if |
||||
|
||||
if(isfilevar(nc_file,"XLAT")) |
||||
if(ISFILE) then |
||||
XLAT = nc_file->XLAT(useT,:,:) |
||||
XLONG = nc_file->XLONG(useT,:,:) |
||||
else |
||||
XLAT = file_handle[:]->XLAT |
||||
XLONG = file_handle[:]->XLONG |
||||
end if |
||||
else |
||||
if(ISFILE) then |
||||
XLAT = nc_file->XLAT_M(useT,:,:) |
||||
XLONG = nc_file->XLONG_M(useT,:,:) |
||||
else |
||||
XLAT = file_handle[:]->XLAT_M |
||||
XLONG = file_handle[:]->XLONG_M |
||||
end if |
||||
end if |
||||
|
||||
|
||||
if(dimsizes(dimsizes(XLAT)).eq.2) then |
||||
; Rank 2 |
||||
res@REF_LAT = XLAT(0,0) |
||||
res@REF_LON = XLONG(0,0) |
||||
else |
||||
; Rank 3 |
||||
res@REF_LAT = XLAT(useT,0,0) |
||||
res@REF_LON = XLONG(useT,0,0) |
||||
end if |
||||
res@KNOWNI = 1.0 |
||||
res@KNOWNJ = 1.0 |
||||
|
||||
loc = wrf_ll_to_ij (longitude, latitude, res) |
||||
loc = loc - 1 |
||||
|
||||
if (dimsizes(dimsizes(loc)) .eq. 1) then |
||||
loc!0 = "x_y" |
||||
elseif (dimsizes(dimsizes(loc)) .eq. 2) then |
||||
loc!0 = "x_y" |
||||
loc!1 = "idx" |
||||
else ; Not currently supported |
||||
loc!0 = "x_y" |
||||
loc!1 = "domain_idx" |
||||
loc!2 = "idx" |
||||
end if |
||||
|
||||
if ( returnI ) then |
||||
loci = new(dimsizes(loc),integer) |
||||
;loci@_FillValue = default_fillvalue("integer") ; was -999 |
||||
loci = tointeger(loc + .5) |
||||
loci!0 = loc!0 |
||||
return(loci) |
||||
else |
||||
return(loc) |
||||
end if |
||||
|
||||
|
||||
end |
||||
|
||||
;-------------------------------------------------------------------------------- |
||||
|
||||
undef("wrf_user_xy_to_ll") |
||||
function wrf_user_xy_to_ll( file_handle, x:numeric, y:numeric, \ |
||||
opts_args:logical ) |
||||
|
||||
begin |
||||
; |
||||
; As of NCL V6.0.0, wrf_user_ll_to_ij can now handle a file |
||||
; or a list of files. |
||||
; |
||||
if(typeof(file_handle).eq."file") then |
||||
ISFILE = True |
||||
nc_file = file_handle |
||||
elseif(typeof(file_handle).eq."list") then |
||||
ISFILE = False |
||||
nc_file = file_handle[0] |
||||
else |
||||
print("wrf_user_xy_to_ll: Error: the first argument must be a file or a list of files opened with addfile or addfiles") |
||||
return |
||||
end if |
||||
|
||||
opts = opts_args |
||||
useT = get_res_value(opts,"useTime",0) |
||||
|
||||
res = True |
||||
res@MAP_PROJ = nc_file@MAP_PROJ |
||||
res@TRUELAT1 = nc_file@TRUELAT1 |
||||
res@TRUELAT2 = nc_file@TRUELAT2 |
||||
res@STAND_LON = nc_file@STAND_LON |
||||
res@DX = nc_file@DX |
||||
res@DY = nc_file@DY |
||||
|
||||
if (res@MAP_PROJ .eq. 6) then |
||||
res@POLE_LAT = nc_file@POLE_LAT |
||||
res@POLE_LON = nc_file@POLE_LON |
||||
res@LATINC = (res@DY*360.)/2.0/3.141592653589793/6370000. |
||||
res@LONINC = (res@DX*360.)/2.0/3.141592653589793/6370000. |
||||
else |
||||
res@POLE_LAT = 90.0 |
||||
res@POLE_LON = 0.0 |
||||
res@LATINC = 0.0 |
||||
res@LONINC = 0.0 |
||||
end if |
||||
|
||||
|
||||
if(isfilevar(nc_file,"XLAT")) then |
||||
if(ISFILE) then |
||||
XLAT = nc_file->XLAT(useT,:,:) |
||||
XLONG = nc_file->XLONG(useT,:,:) |
||||
else |
||||
XLAT = file_handle[:]->XLAT |
||||
XLONG = file_handle[:]->XLONG |
||||
end if |
||||
else |
||||
if(ISFILE) then |
||||
XLAT = nc_file->XLAT_M(useT,:,:) |
||||
XLONG = nc_file->XLONG_M(useT,:,:) |
||||
else |
||||
XLAT = file_handle[:]->XLAT_M |
||||
XLONG = file_handle[:]->XLONG_M |
||||
end if |
||||
end if |
||||
|
||||
if(dimsizes(dimsizes(XLAT)).eq.2) then |
||||
; Rank 2 |
||||
res@REF_LAT = XLAT(0,0) |
||||
res@REF_LON = XLONG(0,0) |
||||
else |
||||
; Rank 3 |
||||
res@REF_LAT = XLAT(useT,0,0) |
||||
res@REF_LON = XLONG(useT,0,0) |
||||
end if |
||||
res@KNOWNI = 1.0 |
||||
res@KNOWNJ = 1.0 |
||||
|
||||
; Convert to 1-based indexes for Fortran |
||||
new_x = x + 1 |
||||
new_y = y + 1 |
||||
|
||||
loc = wrf_ij_to_ll (new_x,new_y,res) |
||||
|
||||
if (dimsizes(dimsizes(loc)) .eq. 1) then |
||||
loc!0 = "lon_lat" |
||||
elseif (dimsizes(dimsizes(loc)) .eq. 2) then |
||||
loc!0 = "lon_lat" |
||||
loc!1 = "idx" |
||||
else ; Not currently supported |
||||
loc!0 = "lon_lat" |
||||
loc!1 = "domain_idx" |
||||
loc!2 = "idx" |
||||
end if |
||||
|
||||
return(loc) |
||||
|
||||
|
||||
end |
||||
|
||||
;-------------------------------------------------------------------------------- |
||||
|
||||
undef("wrf_user_vertcross") |
||||
function wrf_user_vertcross(var3d:numeric, z_in:numeric, \ |
||||
loc_param:numeric, opts:logical ) |
||||
|
||||
; var3d - 3d field to interpolate (all input fields must be unstaggered) |
||||
; z_in - interpolate to this field (either p/z) |
||||
; loc_param - an array of 4 values representing the start point and end point |
||||
; for the cross section (start_x, start_y, end_x, end_y) OR a single |
||||
; point when opt@use_pivot is True representing the pivot point. |
||||
; The values can be in grid coordinates or lat/lon coordinates |
||||
; (start_x = start_lon, start_y = start_lat, ...). If using |
||||
; lat/lon coordinates, then opt@latlon must be True. |
||||
; opts - optional arguments |
||||
; use_pivot - set to True to indicate that loc_param and angle are used, |
||||
; otherwise loc_param is set to 4 values to indicate a start and |
||||
; end point |
||||
; angle - an angle for vertical plots - 90 represent a WE cross section, |
||||
; ignored if use_pivot is False. |
||||
; levels - the vertical levels to use in the same units as z_in. Set to |
||||
; False to automatically generate the number of levels specified |
||||
; by autolevels. |
||||
; latlon - set to True if the values in loc_param are latitude and longitude |
||||
; values rather than grid values |
||||
; file_handle - must be set to a file handle when latlon is True or |
||||
; linecoords is True, otherwise this is ignored. |
||||
; timeidx - the time index to use for moving nests when latlon is True. Set |
||||
; to 0 if the nest is not moving. |
||||
; linecoords - set to True to include the latitude and longitude coordinates |
||||
; for the cross section line in the output attributes. |
||||
; autolevels - set to the desired number of levels when levels are |
||||
; selected automatically (default 100). |
||||
|
||||
begin |
||||
|
||||
use_pivot = get_res_value(opts, "use_pivot", False) |
||||
angle = get_res_value(opts, "angle", 0.0) |
||||
levels = get_res_value(opts, "levels", new(1,integer)) |
||||
latlon = get_res_value(opts, "latlon", False) |
||||
file_handle = get_res_value(opts, "file_handle", 0) |
||||
timeidx = get_res_value(opts, "timeidx", 0) |
||||
linecoords = get_res_value(opts, "linecoords", False) |
||||
nlevels = get_res_value(opts, "autolevels", 100) |
||||
|
||||
dims = dimsizes(var3d) |
||||
nd = dimsizes(dims) |
||||
|
||||
dimX = dims(nd-1) |
||||
dimY = dims(nd-2) |
||||
dimZ = dims(nd-3) |
||||
|
||||
if ( nd .eq. 4 ) then |
||||
z = z_in(0,:,:,:) |
||||
else |
||||
z = z_in |
||||
end if |
||||
|
||||
; Convert latlon to xy coordinates |
||||
|
||||
if (use_pivot) then |
||||
if (latlon) then |
||||
opt = True |
||||
opt@returnInt = True |
||||
opt@useTime = timeidx |
||||
ij := wrf_user_ll_to_xy(file_handle, loc_param(0), loc_param(1), opt) |
||||
start_x = ij(0) |
||||
start_y = ij(1) |
||||
else |
||||
start_x = loc_param(0) |
||||
start_y = loc_param(1) |
||||
end if |
||||
else |
||||
if (latlon) then |
||||
opt = True |
||||
opt@returnInt = True |
||||
opt@useTime = timeidx |
||||
ij := wrf_user_ll_to_xy(file_handle, (/ loc_param(0), loc_param(2) /), (/ loc_param(1), loc_param(3) /), opt) |
||||
start_x = ij(0,0) |
||||
start_y = ij(1,0) |
||||
end_x = ij(0,1) |
||||
end_y = ij(1,1) |
||||
else |
||||
start_x = loc_param(0) |
||||
start_y = loc_param(1) |
||||
end_x = loc_param(2) |
||||
end_y = loc_param(3) |
||||
end if |
||||
end if |
||||
|
||||
; get the lat/lons along the cross section line if requested |
||||
|
||||
; set the cross section line coordinates if requested |
||||
if (linecoords) then |
||||
|
||||
latname = "XLAT" |
||||
lonname = "XLONG" |
||||
if(.not. isfilevar(file_handle,"XLAT")) then |
||||
if(isfilevar(file_handle,"XLAT_M")) then |
||||
latname = "XLAT_M" |
||||
lonname = "XLONG_M" |
||||
end if |
||||
end if |
||||
|
||||
latvar = _get_wrf_var(file_handle, latname, timeidx) |
||||
lonvar = _get_wrf_var(file_handle, lonname, timeidx) |
||||
|
||||
if (use_pivot) then |
||||
loc := (/start_x, start_y/) |
||||
linelats = wrf_user_intrp2d(latvar, loc, angle, False) |
||||
linelons = wrf_user_intrp2d(lonvar, loc, angle, False) |
||||
else |
||||
loc := (/start_x, start_y, end_x, end_y /) |
||||
linelats = wrf_user_intrp2d(latvar, loc, angle, True) |
||||
linelons = wrf_user_intrp2d(lonvar, loc, angle, True) |
||||
end if |
||||
|
||||
end if |
||||
|
||||
; set vertical cross section |
||||
; Note for wrf_user_set_xy, opt is False when pivot and angle used. |
||||
if (use_pivot) then |
||||
xy = wrf_user_set_xy( z, start_x, start_y, \ ; assumes 0-based indexing in v6.5.0 |
||||
0.0, 0.0, angle, False ) |
||||
|
||||
else |
||||
xy = wrf_user_set_xy( z, start_x, start_y, \ ; assumes 0-based indexing in v6.5.0 |
||||
end_x, end_y, \ |
||||
angle, True) |
||||
|
||||
end if |
||||
xp = dimsizes(xy) |
||||
|
||||
|
||||
; first we interp z |
||||
var2dz = wrf_interp_2d_xy( z, xy) |
||||
|
||||
; interp to constant z grid |
||||
if (all(ismissing(levels))) then |
||||
if(var2dz(0,0) .gt. var2dz(1,0) ) then ; monotonically decreasing coordinate |
||||
z_max = floor(max(z)/10)*10 ; bottom value |
||||
z_min = ceil(min(z)/10)*10 ; top value |
||||
dz = (1.0/nlevels) * (z_max - z_min) |
||||
;nlevels = tointeger( (z_max-z_min)/dz) |
||||
z_var2d = new( (/nlevels/), typeof(z)) |
||||
z_var2d(0) = z_max |
||||
dz = -dz |
||||
else |
||||
z_max = max(z) |
||||
z_min = 0. |
||||
dz = (1.0/nlevels) * z_max |
||||
;nlevels = tointeger( z_max/dz ) |
||||
z_var2d = new( (/nlevels/), typeof(z)) |
||||
z_var2d(0) = z_min |
||||
end if |
||||
|
||||
do i=1, nlevels-1 |
||||
z_var2d(i) = z_var2d(0)+i*dz |
||||
end do |
||||
else |
||||
z_var2d = levels |
||||
nlevels = dimsizes(z_var2d) |
||||
end if |
||||
|
||||
; interp the variable |
||||
if ( dimsizes(dims) .eq. 4 ) then |
||||
var2d = new( (/dims(0), nlevels, xp(0)/), typeof(var2dz)) |
||||
do it = 0,dims(0)-1 |
||||
var2dtmp = wrf_interp_2d_xy( var3d(it,:,:,:), xy) |
||||
do i=0,xp(0)-1 |
||||
var2d(it,:,i) = wrf_interp_1d( var2dtmp(:,i), var2dz(:,i), z_var2d) |
||||
end do |
||||
end do |
||||
var2d!0 = var3d!0 |
||||
var2d!1 = "vertical" |
||||
var2d!2 = "cross_line_idx" |
||||
else |
||||
var2d = new( (/nlevels, xp(0)/), typeof(var2dz)) |
||||
var2dtmp = wrf_interp_2d_xy( var3d, xy) |
||||
do i=0,xp(0)-1 |
||||
var2d(:,i) = wrf_interp_1d( var2dtmp(:,i), var2dz(:,i), z_var2d) |
||||
end do |
||||
var2d!0 = "vertical" |
||||
var2d!1 = "cross_line_idx" |
||||
end if |
||||
|
||||
st_x = tointeger(xy(0,0)) ; + 1 (removed 1-based indexing in 6.5.0) |
||||
st_y = tointeger(xy(0,1)) ; + 1 |
||||
ed_x = tointeger(xy(xp(0)-1,0)) ; + 1 |
||||
ed_y = tointeger(xy(xp(0)-1,1)) ; + 1 |
||||
if (.not. use_pivot) then |
||||
var2d@Orientation = "Cross-Section: (" + \ |
||||
st_x + "," + st_y + ") to (" + \ |
||||
ed_x + "," + ed_y + ")" |
||||
else |
||||
var2d@Orientation = "Cross-Section: (" + \ |
||||
st_x + "," + st_y + ") to (" + \ |
||||
ed_x + "," + ed_y + ") ; center=(" + \ |
||||
start_x + "," + start_y + \ |
||||
") ; angle=" + angle |
||||
end if |
||||
|
||||
if (linecoords) then |
||||
var2d@lats = linelats |
||||
var2d@lons = linelons |
||||
end if |
||||
|
||||
var2d&vertical = z_var2d |
||||
|
||||
return(var2d) |
||||
|
||||
end |
@ -1,30 +0,0 @@
@@ -1,30 +0,0 @@
|
||||
|
||||
import matplotlib.pyplot as plt |
||||
from mpl_toolkits.basemap import Basemap |
||||
|
||||
def main(): |
||||
bm = Basemap(projection = "rotpole", |
||||
o_lat_p = 36.0, |
||||
o_lon_p = 180.0, |
||||
llcrnrlat = -10.590603, |
||||
urcrnrlat = 46.591976, |
||||
llcrnrlon = -139.08585, |
||||
urcrnrlon = 22.661009, |
||||
lon_0 = -106.0, |
||||
rsphere = 6370000, |
||||
resolution = 'l') |
||||
|
||||
fig = plt.figure(figsize=(8,8)) |
||||
ax = fig.add_axes([0.1,0.1,0.8,0.8]) |
||||
|
||||
bm.drawcoastlines(linewidth=.5) |
||||
|
||||
print bm.proj4string |
||||
|
||||
plt.savefig("basemap_map.png") |
||||
plt.close(fig) |
||||
|
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
main() |
@ -1,77 +1,79 @@
@@ -1,77 +1,79 @@
|
||||
import unittest as ut |
||||
import numpy.testing as nt |
||||
import numpy.testing as nt |
||||
import numpy as np |
||||
import numpy.ma as ma |
||||
import os, sys |
||||
import os |
||||
import sys |
||||
import subprocess |
||||
|
||||
from wrf import getvar, ALL_TIMES |
||||
|
||||
TEST_DIR = "/Users/ladwig/Documents/wrf_files/wrf_vortex_multi/moving_nest" |
||||
TEST_FILENAMES = ["wrfout_d02_2005-08-28_00:00:00", |
||||
"wrfout_d02_2005-08-28_12:00:00", |
||||
"wrfout_d02_2005-08-29_00:00:00"] |
||||
"wrfout_d02_2005-08-28_12:00:00", |
||||
"wrfout_d02_2005-08-29_00:00:00"] |
||||
TEST_FILES = [os.path.join(TEST_DIR, x) for x in TEST_FILENAMES] |
||||
|
||||
# Python 3 |
||||
if sys.version_info > (3,): |
||||
xrange = range |
||||
|
||||
|
||||
|
||||
class WRFFileVarsTest(ut.TestCase): |
||||
longMessage = True |
||||
|
||||
|
||||
def make_test(ncfiles, varname): |
||||
def test(self): |
||||
#import time |
||||
#very_start = time.time() |
||||
#start = time.time() |
||||
# import time |
||||
# very_start = time.time() |
||||
# start = time.time() |
||||
t1 = getvar(ncfiles, varname, 0) |
||||
|
||||
#end = time.time() |
||||
#print ("t1: ", start-end) |
||||
#start = time.time() |
||||
|
||||
# end = time.time() |
||||
# print("t1: ", start-end) |
||||
# start = time.time() |
||||
t2 = getvar(ncfiles, varname, 0, meta=False) |
||||
#end = time.time() |
||||
#print ("t2: ", start-end) |
||||
#start = time.time() |
||||
# end = time.time() |
||||
# print("t2: ", start-end) |
||||
# start = time.time() |
||||
t3 = getvar(ncfiles, varname, ALL_TIMES) |
||||
#end = time.time() |
||||
#print ("t3: ", start-end) |
||||
#start = time.time() |
||||
# end = time.time() |
||||
# print("t3: ", start-end) |
||||
# start = time.time() |
||||
t4 = getvar(ncfiles, varname, ALL_TIMES, meta=False) |
||||
#end = time.time() |
||||
#print ("t4: ", start-end) |
||||
#start = time.time() |
||||
# end = time.time() |
||||
# print("t4: ", start-end) |
||||
# start = time.time() |
||||
t5 = getvar(ncfiles, varname, ALL_TIMES, method="join") |
||||
#end = time.time() |
||||
#print ("t5: ", start-end) |
||||
#start = time.time() |
||||
# end = time.time() |
||||
# print("t5: ", start-end) |
||||
# start = time.time() |
||||
t6 = getvar(ncfiles, varname, ALL_TIMES, method="join", meta=False) |
||||
#end = time.time() |
||||
#print ("t6: ", start-end) |
||||
#start = time.time() |
||||
|
||||
#print ("Total Time: ", (end-start)) |
||||
# end = time.time() |
||||
# print("t6: ", start-end) |
||||
# start = time.time() |
||||
|
||||
# print("Total Time: ", (end-start)) |
||||
return test |
||||
|
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
from netCDF4 import Dataset |
||||
ncfiles = [Dataset(x) for x in TEST_FILES] |
||||
|
||||
#import scipy.io |
||||
#ncfiles = [scipy.io.netcdf.netcdf_file(x) for x in TEST_FILES] |
||||
|
||||
|
||||
# import scipy.io |
||||
# ncfiles = [scipy.io.netcdf.netcdf_file(x) for x in TEST_FILES] |
||||
|
||||
file_vars = ncfiles[0].variables.keys() |
||||
|
||||
|
||||
ignore_vars = [] |
||||
|
||||
|
||||
for var in file_vars: |
||||
if var in ignore_vars: |
||||
continue |
||||
|
||||
|
||||
test_func1 = make_test(ncfiles, var) |
||||
setattr(WRFFileVarsTest, 'test_{0}'.format(var), test_func1) |
||||
|
||||
ut.main() |
||||
|
||||
ut.main() |
||||
|
@ -1,314 +1,302 @@
@@ -1,314 +1,302 @@
|
||||
import unittest as ut |
||||
import numpy.testing as nt |
||||
import numpy.testing as nt |
||||
import numpy as np |
||||
import numpy.ma as ma |
||||
import os, sys |
||||
import os |
||||
import sys |
||||
import subprocess |
||||
|
||||
from wrf import xy_to_ll_proj, ll_to_xy_proj, to_np |
||||
|
||||
|
||||
|
||||
class WRFLatLonProjTest(ut.TestCase): |
||||
longMessage = True |
||||
|
||||
|
||||
def make_test(xy_or_ll_out): |
||||
def test(self): |
||||
|
||||
|
||||
# Python 3 |
||||
if sys.version_info > (3,): |
||||
if sys.version_info > (3, ): |
||||
assert_raises_regex = self.assertRaisesRegex |
||||
xrange = range |
||||
else: |
||||
assert_raises_regex = self.assertRaisesRegexp |
||||
|
||||
|
||||
if xy_or_ll_out == "xy": |
||||
# Test the required failures |
||||
with assert_raises_regex(ValueError, ".*map_proj.*" ): |
||||
ll_to_xy_proj(30,-110) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lat.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lon.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1, ref_lat=45) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_x.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_y.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1, ref_lat=45.0, |
||||
with assert_raises_regex(ValueError, ".*map_proj.*"): |
||||
ll_to_xy_proj(30, -110) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lat.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lon.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1, ref_lat=45) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_x.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_y.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=1) |
||||
|
||||
with assert_raises_regex(ValueError, ".*dx.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0) |
||||
|
||||
####### Now test the projections |
||||
|
||||
|
||||
with assert_raises_regex(ValueError, ".*dx.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0) |
||||
|
||||
# Now test the projections |
||||
|
||||
# Lambert Conformal - truelat1, stand_lon required |
||||
with assert_raises_regex(ValueError, ".*truelat1.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1, ref_lat=45.0, |
||||
with assert_raises_regex(ValueError, ".*truelat1.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=1, ref_lat=45.0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000., |
||||
truelat1=60.) |
||||
|
||||
truelat1=60.) |
||||
|
||||
# Make sure it runs with all params set vs not |
||||
p_all = ll_to_xy_proj(28., -89., map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., |
||||
stand_lon=-89.) |
||||
|
||||
p_all = ll_to_xy_proj(28., -89., map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., stand_lon=-89.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
# Polar Stereographic - truelat1, stand_lon |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=2, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=2, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=2, ref_lat=45.0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=2, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000., |
||||
truelat1=60.) |
||||
|
||||
p_all = ll_to_xy_proj(28., -89., map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., |
||||
stand_lon=-89.) |
||||
|
||||
truelat1=60.) |
||||
|
||||
p_all = ll_to_xy_proj(28., -89., map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., stand_lon=-89.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
|
||||
# Mercator - truelat1 |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=2, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=2, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000.) |
||||
|
||||
p_all = ll_to_xy_proj(28., -89., map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30.) |
||||
|
||||
dx=3000.) |
||||
|
||||
p_all = ll_to_xy_proj(28., -89., map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
# Lat/lon - stand_lon, dy, pole_lat, pole_lon |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=6, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*dy.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=6, ref_lat=45.0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*dy.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
stand_lon=89.0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lat.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=6, ref_lat=45.0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lat.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
stand_lon=89.0, |
||||
dx=.2698388, dy=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lon.*" ): |
||||
ll_to_xy_proj(30,-110, map_proj=6, ref_lat=45.0, |
||||
dx=.2698388, dy=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lon.*"): |
||||
ll_to_xy_proj(30, -110, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
stand_lon=89.0, |
||||
dx=.2698388, dy=.2698388, |
||||
pole_lat=62.0) |
||||
|
||||
p_all = ll_to_xy_proj(28.,-89., map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
dx=30000, dy=30000, |
||||
truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
stand_lon=-89., |
||||
dx=30000, dy=30000, pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
pole_lat=62.0) |
||||
|
||||
p_all = ll_to_xy_proj(28., -89., map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
dx=30000, dy=30000, |
||||
truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
p_def = ll_to_xy_proj(28., -89., map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
stand_lon=-89., |
||||
dx=30000, dy=30000, pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
|
||||
if xy_or_ll_out == "ll": |
||||
|
||||
|
||||
# Test the required failures |
||||
with assert_raises_regex(ValueError, ".*map_proj.*" ): |
||||
with assert_raises_regex(ValueError, ".*map_proj.*"): |
||||
xy_to_ll_proj(45, 50) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lat.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=1) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lon.*" ): |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lat.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1) |
||||
|
||||
with assert_raises_regex(ValueError, ".*ref_lon.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_x.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_y.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_x.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*known_y.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=1) |
||||
|
||||
with assert_raises_regex(ValueError, ".*dx.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*dx.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0) |
||||
|
||||
####### Now test the projections |
||||
|
||||
|
||||
# Now test the projections |
||||
|
||||
# Lambert Conformal - truelat1, stand_lon required |
||||
with assert_raises_regex(ValueError, ".*truelat1.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
with assert_raises_regex(ValueError, ".*truelat1.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=1, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000., |
||||
truelat1=60.) |
||||
|
||||
truelat1=60.) |
||||
|
||||
# Make sure it runs with all params set vs not |
||||
p_all = xy_to_ll_proj(45, 50, map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
|
||||
p_def = xy_to_ll_proj(45, 50, map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., |
||||
stand_lon=-89.) |
||||
|
||||
p_all = xy_to_ll_proj(45, 50, map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
p_def = xy_to_ll_proj(45, 50, map_proj=1, ref_lat=17.803, |
||||
ref_lon=-100.7747, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., |
||||
stand_lon=-89.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
# Polar Stereographic - truelat1, stand_lon |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=2, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=2, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=2, ref_lat=45.0, |
||||
dx=3000.) |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=2, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000., |
||||
truelat1=60.) |
||||
|
||||
p_all = xy_to_ll_proj(45, 50, map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
|
||||
p_def = xy_to_ll_proj(45, 50, map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., |
||||
stand_lon=-89.) |
||||
|
||||
truelat1=60.) |
||||
|
||||
p_all = xy_to_ll_proj(45, 50, map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
p_def = xy_to_ll_proj(45, 50, map_proj=2, ref_lat=17.933, |
||||
ref_lon=-100.0735, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., |
||||
stand_lon=-89.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
|
||||
# Mercator - truelat1 |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=2, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*truelat1.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=2, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=3000.) |
||||
|
||||
p_all = xy_to_ll_proj(45, 50, map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
|
||||
p_def = xy_to_ll_proj(45, 50, map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30.) |
||||
|
||||
dx=3000.) |
||||
|
||||
p_all = xy_to_ll_proj(45, 50, map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=90., pole_lon=0.) |
||||
|
||||
p_def = xy_to_ll_proj(45, 50, map_proj=3, ref_lat=19.1075, |
||||
ref_lon=-101.008, known_x=0, known_y=0, |
||||
dx=30000., truelat1=30.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
# Lat/lon - stand_lon, dy, pole_lat, pole_lon |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
|
||||
with assert_raises_regex(ValueError, ".*stand_lon.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*dy.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*dy.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
stand_lon=89.0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lat.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
dx=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lat.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
stand_lon=89.0, |
||||
dx=.2698388, dy=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lon.*" ): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
dx=.2698388, dy=.2698388) |
||||
|
||||
with assert_raises_regex(ValueError, ".*pole_lon.*"): |
||||
xy_to_ll_proj(45, 50, map_proj=6, ref_lat=45.0, |
||||
ref_lon=-120., known_x=0, known_y=0, |
||||
stand_lon=89.0, |
||||
dx=.2698388, dy=.2698388, |
||||
pole_lat=62.0) |
||||
|
||||
p_all = xy_to_ll_proj(64, 40, map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
dx=30000, dy=30000, |
||||
truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
|
||||
p_def = xy_to_ll_proj(64, 40, map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
stand_lon=-89., |
||||
dx=30000, dy=30000, pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
pole_lat=62.0) |
||||
|
||||
p_all = xy_to_ll_proj(64, 40, map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
dx=30000, dy=30000, |
||||
truelat1=30., truelat2=30., |
||||
stand_lon=-89., pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
p_def = xy_to_ll_proj(64, 40, map_proj=6, ref_lat=17.6759, |
||||
ref_lon=-101.4286, known_x=0, known_y=0, |
||||
stand_lon=-89., |
||||
dx=30000, dy=30000, pole_lat=62.0, |
||||
pole_lon=180.) |
||||
|
||||
nt.assert_allclose(to_np(p_all), to_np(p_def)) |
||||
|
||||
|
||||
return test |
||||
|
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
|
||||
|
||||
for v in ("xy", "ll"): |
||||
test_func = make_test(v) |
||||
setattr(WRFLatLonProjTest, 'test_{0}'.format(v), test_func) |
||||
|
||||
|
||||
ut.main() |
||||
|
Loading…
Reference in new issue