|
|
@ -8,13 +8,17 @@ from itertools import product |
|
|
|
from types import GeneratorType |
|
|
|
from types import GeneratorType |
|
|
|
import datetime as dt |
|
|
|
import datetime as dt |
|
|
|
from math import floor, copysign |
|
|
|
from math import floor, copysign |
|
|
|
|
|
|
|
|
|
|
|
from inspect import getmodule |
|
|
|
from inspect import getmodule |
|
|
|
try: |
|
|
|
try: |
|
|
|
from inspect import signature |
|
|
|
from inspect import signature |
|
|
|
except ImportError: |
|
|
|
except ImportError: |
|
|
|
from inspect import getargspec, getargvalues |
|
|
|
from inspect import getargspec |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
from inspect import getargvalues |
|
|
|
|
|
|
|
except ImportError: |
|
|
|
|
|
|
|
from inspect import getgeneratorlocals |
|
|
|
|
|
|
|
|
|
|
|
import numpy as np |
|
|
|
import numpy as np |
|
|
|
import numpy.ma as ma |
|
|
|
import numpy.ma as ma |
|
|
@ -81,7 +85,10 @@ def _is_mapping(wrfnc): |
|
|
|
|
|
|
|
|
|
|
|
def _generator_copy(gen): |
|
|
|
def _generator_copy(gen): |
|
|
|
funcname = gen.__name__ |
|
|
|
funcname = gen.__name__ |
|
|
|
argvals = getargvalues(gen.gi_frame) |
|
|
|
try: |
|
|
|
|
|
|
|
argvals = getargvalues(gen.gi_frame) |
|
|
|
|
|
|
|
except NameError: |
|
|
|
|
|
|
|
argvals = getgeneratorlocals(gen) |
|
|
|
module = getmodule(gen.gi_frame) |
|
|
|
module = getmodule(gen.gi_frame) |
|
|
|
|
|
|
|
|
|
|
|
if module is not None: |
|
|
|
if module is not None: |
|
|
@ -177,11 +184,13 @@ def isstr(s): |
|
|
|
except NameError: |
|
|
|
except NameError: |
|
|
|
return isinstance(s, str) |
|
|
|
return isinstance(s, str) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Python 2 rounding behavior |
|
|
|
# Python 2 rounding behavior |
|
|
|
def _round2(x, d=0): |
|
|
|
def _round2(x, d=0): |
|
|
|
p = 10 ** d |
|
|
|
p = 10 ** d |
|
|
|
return float(floor((x * p) + copysign(0.5, x)))/p |
|
|
|
return float(floor((x * p) + copysign(0.5, x)))/p |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def py2round(x, d=0): |
|
|
|
def py2round(x, d=0): |
|
|
|
if version_info >= (3,): |
|
|
|
if version_info >= (3,): |
|
|
|
return _round2(x, d) |
|
|
|
return _round2(x, d) |
|
|
@ -189,6 +198,20 @@ def py2round(x, d=0): |
|
|
|
return round(x, d) |
|
|
|
return round(x, d) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def range2(*args): |
|
|
|
|
|
|
|
if version_info >= (3,): |
|
|
|
|
|
|
|
return range(*args) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return xrange(*args) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ucode(*args, **kwargs): |
|
|
|
|
|
|
|
if version_info >= (3, ): |
|
|
|
|
|
|
|
return str(*args, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return unicode(*args, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Helper to extract masked arrays from DataArrays that convert to NaN |
|
|
|
# Helper to extract masked arrays from DataArrays that convert to NaN |
|
|
|
def npvalues(da): |
|
|
|
def npvalues(da): |
|
|
|
if not isinstance(da, DataArray): |
|
|
|
if not isinstance(da, DataArray): |
|
|
@ -262,7 +285,7 @@ def _corners_moved(wrfnc, first_ll_corner, first_ur_corner, latvar, lonvar): |
|
|
|
lons = wrfnc.variables[lonvar] |
|
|
|
lons = wrfnc.variables[lonvar] |
|
|
|
|
|
|
|
|
|
|
|
# Need to check all times |
|
|
|
# Need to check all times |
|
|
|
for i in xrange(lats.shape[-3]): |
|
|
|
for i in range2(lats.shape[-3]): |
|
|
|
start_idxs = [0]*len(lats.shape) # PyNIO does not support ndim |
|
|
|
start_idxs = [0]*len(lats.shape) # PyNIO does not support ndim |
|
|
|
start_idxs[-3] = i |
|
|
|
start_idxs[-3] = i |
|
|
|
start_idxs = tuple(start_idxs) |
|
|
|
start_idxs = tuple(start_idxs) |
|
|
@ -459,7 +482,7 @@ def _combine_dict(wrfdict, varname, timeidx, method, meta): |
|
|
|
idx += 1 |
|
|
|
idx += 1 |
|
|
|
|
|
|
|
|
|
|
|
if xarray_enabled() and meta: |
|
|
|
if xarray_enabled() and meta: |
|
|
|
outname = unicode(first_array.name) |
|
|
|
outname = str(first_array.name) |
|
|
|
# Note: assumes that all entries in dict have same coords |
|
|
|
# Note: assumes that all entries in dict have same coords |
|
|
|
outcoords = OrderedDict(first_array.coords) |
|
|
|
outcoords = OrderedDict(first_array.coords) |
|
|
|
outdims = ["key"] + list(first_array.dims) |
|
|
|
outdims = ["key"] + list(first_array.dims) |
|
|
@ -580,7 +603,7 @@ def _build_data_array(wrfnc, varname, timeidx, is_moving_domain): |
|
|
|
varname) |
|
|
|
varname) |
|
|
|
proj = [getproj(lats=lats[i,:], |
|
|
|
proj = [getproj(lats=lats[i,:], |
|
|
|
lons=lons[i,:], |
|
|
|
lons=lons[i,:], |
|
|
|
**proj_params) for i in xrange(lats.shape[0])] |
|
|
|
**proj_params) for i in range2(lats.shape[0])] |
|
|
|
|
|
|
|
|
|
|
|
if time_coord is not None: |
|
|
|
if time_coord is not None: |
|
|
|
coords[time_coord] = (lon_coord_var.dimensions[0], |
|
|
|
coords[time_coord] = (lon_coord_var.dimensions[0], |
|
|
@ -778,14 +801,14 @@ def _cat_files(wrfseq, varname, timeidx, is_moving, squeeze, meta): |
|
|
|
varname) |
|
|
|
varname) |
|
|
|
projs = [getproj(lats=lats[i,:], |
|
|
|
projs = [getproj(lats=lats[i,:], |
|
|
|
lons=lons[i,:], |
|
|
|
lons=lons[i,:], |
|
|
|
**proj_params) for i in xrange(lats.shape[0])] |
|
|
|
**proj_params) for i in range2(lats.shape[0])] |
|
|
|
|
|
|
|
|
|
|
|
outprojs[startidx:endidx] = np.asarray(projs, np.object)[:] |
|
|
|
outprojs[startidx:endidx] = np.asarray(projs, np.object)[:] |
|
|
|
|
|
|
|
|
|
|
|
startidx = endidx |
|
|
|
startidx = endidx |
|
|
|
|
|
|
|
|
|
|
|
if xarray_enabled() and meta: |
|
|
|
if xarray_enabled() and meta: |
|
|
|
outname = unicode(first_var.name) |
|
|
|
outname = ucode(first_var.name) |
|
|
|
outattrs = OrderedDict(first_var.attrs) |
|
|
|
outattrs = OrderedDict(first_var.attrs) |
|
|
|
outcoords = OrderedDict(first_var.coords) |
|
|
|
outcoords = OrderedDict(first_var.coords) |
|
|
|
outdimnames = list(first_var.dims) |
|
|
|
outdimnames = list(first_var.dims) |
|
|
@ -939,7 +962,7 @@ def _join_files(wrfseq, varname, timeidx, is_moving, meta): |
|
|
|
varname) |
|
|
|
varname) |
|
|
|
projs = [getproj(lats=lats[i,:], |
|
|
|
projs = [getproj(lats=lats[i,:], |
|
|
|
lons=lons[i,:], |
|
|
|
lons=lons[i,:], |
|
|
|
**proj_params) for i in xrange(lats.shape[0])] |
|
|
|
**proj_params) for i in range2(lats.shape[0])] |
|
|
|
|
|
|
|
|
|
|
|
outprojs[file_idx, 0:numtimes] = ( |
|
|
|
outprojs[file_idx, 0:numtimes] = ( |
|
|
|
np.asarray(projs, np.object)[:]) |
|
|
|
np.asarray(projs, np.object)[:]) |
|
|
@ -954,12 +977,12 @@ def _join_files(wrfseq, varname, timeidx, is_moving, meta): |
|
|
|
outdata = np.ma.masked_values(outdata, Constants.DEFAULT_FILL) |
|
|
|
outdata = np.ma.masked_values(outdata, Constants.DEFAULT_FILL) |
|
|
|
|
|
|
|
|
|
|
|
if xarray_enabled() and meta: |
|
|
|
if xarray_enabled() and meta: |
|
|
|
outname = unicode(first_var.name) |
|
|
|
outname = ucode(first_var.name) |
|
|
|
outcoords = OrderedDict(first_var.coords) |
|
|
|
outcoords = OrderedDict(first_var.coords) |
|
|
|
outattrs = OrderedDict(first_var.attrs) |
|
|
|
outattrs = OrderedDict(first_var.attrs) |
|
|
|
# New dimensions |
|
|
|
# New dimensions |
|
|
|
outdimnames = ["file"] + list(first_var.dims) |
|
|
|
outdimnames = ["file"] + list(first_var.dims) |
|
|
|
outcoords["file"] = [i for i in xrange(numfiles)] |
|
|
|
outcoords["file"] = [i for i in range2(numfiles)] |
|
|
|
|
|
|
|
|
|
|
|
# Time needs to be multi dimensional, so use the default dimension |
|
|
|
# Time needs to be multi dimensional, so use the default dimension |
|
|
|
del outcoords["Time"] |
|
|
|
del outcoords["Time"] |
|
|
@ -1085,14 +1108,20 @@ def extract_vars(wrfnc, timeidx, varnames, method="cat", squeeze=True, |
|
|
|
method, squeeze, cache, meta) |
|
|
|
method, squeeze, cache, meta) |
|
|
|
for var in varlist} |
|
|
|
for var in varlist} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Python 3 compatability |
|
|
|
|
|
|
|
def _npbytes_to_str(var): |
|
|
|
|
|
|
|
return (bytes(c).decode("utf-8") for c in var[:]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _make_time(timearr): |
|
|
|
def _make_time(timearr): |
|
|
|
return dt.datetime.strptime("".join(timearr[:]), "%Y-%m-%d_%H:%M:%S") |
|
|
|
return dt.datetime.strptime("".join(_npbytes_to_str(timearr)), |
|
|
|
|
|
|
|
"%Y-%m-%d_%H:%M:%S") |
|
|
|
|
|
|
|
|
|
|
|
def _file_times(wrfnc, timeidx): |
|
|
|
def _file_times(wrfnc, timeidx): |
|
|
|
multitime = _is_multi_time_req(timeidx) |
|
|
|
multitime = _is_multi_time_req(timeidx) |
|
|
|
if multitime: |
|
|
|
if multitime: |
|
|
|
times = wrfnc.variables["Times"][:,:] |
|
|
|
times = wrfnc.variables["Times"][:,:] |
|
|
|
for i in xrange(times.shape[0]): |
|
|
|
for i in range2(times.shape[0]): |
|
|
|
yield _make_time(times[i,:]) |
|
|
|
yield _make_time(times[i,:]) |
|
|
|
else: |
|
|
|
else: |
|
|
|
times = wrfnc.variables["Times"][timeidx,:] |
|
|
|
times = wrfnc.variables["Times"][timeidx,:] |
|
|
@ -1148,7 +1177,7 @@ def get_left_indexes(ref_var, expected_dims): |
|
|
|
if (extra_dim_num == 0): |
|
|
|
if (extra_dim_num == 0): |
|
|
|
return [] |
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
return tuple([ref_var.shape[x] for x in xrange(extra_dim_num)]) |
|
|
|
return tuple([ref_var.shape[x] for x in range2(extra_dim_num)]) |
|
|
|
|
|
|
|
|
|
|
|
def iter_left_indexes(dims): |
|
|
|
def iter_left_indexes(dims): |
|
|
|
"""A generator which yields the iteration tuples for a sequence of |
|
|
|
"""A generator which yields the iteration tuples for a sequence of |
|
|
@ -1163,7 +1192,7 @@ def iter_left_indexes(dims): |
|
|
|
- dims - a sequence of dimensions sizes (e.g. ndarry.shape) |
|
|
|
- dims - a sequence of dimensions sizes (e.g. ndarry.shape) |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
|
""" |
|
|
|
arg = [xrange(dim) for dim in dims] |
|
|
|
arg = [range2(dim) for dim in dims] |
|
|
|
for idxs in product(*arg): |
|
|
|
for idxs in product(*arg): |
|
|
|
yield idxs |
|
|
|
yield idxs |
|
|
|
|
|
|
|
|
|
|
@ -1236,26 +1265,26 @@ class CoordPair(object): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def from_args(func, argnames, *args, **kwargs): |
|
|
|
def from_args(func, argnames, *args, **kwargs): |
|
|
|
"""Parses the function args and kargs looking for the desired argument |
|
|
|
"""Parses the function args and kargs looking for the desired argument |
|
|
|
value. Otherwise, the value is taken from the default keyword argument |
|
|
|
value. Otherwise, the value is taken from the default keyword argument |
|
|
|
using the arg spec. |
|
|
|
using the arg spec. |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
|
""" |
|
|
|
if isstr(argnames): |
|
|
|
if isstr(argnames): |
|
|
|
arglist = [argnames] |
|
|
|
arglist = [argnames] |
|
|
|
else: |
|
|
|
else: |
|
|
|
arglist = argnames |
|
|
|
arglist = argnames |
|
|
|
|
|
|
|
|
|
|
|
result = {} |
|
|
|
result = {} |
|
|
|
for argname in arglist: |
|
|
|
for argname in arglist: |
|
|
|
arg_loc = arg_location(func, argname, args, kwargs) |
|
|
|
arg_loc = arg_location(func, argname, args, kwargs) |
|
|
|
|
|
|
|
|
|
|
|
if arg_loc is not None: |
|
|
|
if arg_loc is not None: |
|
|
|
result[argname] = arg_loc[0][arg_loc[1]] |
|
|
|
result[argname] = arg_loc[0][arg_loc[1]] |
|
|
|
else: |
|
|
|
else: |
|
|
|
result[argname] = None |
|
|
|
result[argname] = None |
|
|
|
|
|
|
|
|
|
|
|
return result |
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
def _args_to_list2(func, args, kwargs): |
|
|
|
def _args_to_list2(func, args, kwargs): |
|
|
|
argspec = getargspec(func) |
|
|
|
argspec = getargspec(func) |
|
|
@ -1281,7 +1310,7 @@ def _args_to_list3(func, args, kwargs): |
|
|
|
bound = sig.bind(*args, **kwargs) |
|
|
|
bound = sig.bind(*args, **kwargs) |
|
|
|
bound.apply_defaults() |
|
|
|
bound.apply_defaults() |
|
|
|
|
|
|
|
|
|
|
|
return [x for x in bound.arguments.values] |
|
|
|
return [x for x in bound.arguments.values()] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def args_to_list(func, args, kwargs): |
|
|
|
def args_to_list(func, args, kwargs): |
|
|
@ -1309,9 +1338,14 @@ def _arg_location2(func, argname, args, kwargs): |
|
|
|
|
|
|
|
|
|
|
|
def _arg_location3(func, argname, args, kwargs): |
|
|
|
def _arg_location3(func, argname, args, kwargs): |
|
|
|
sig = signature(func) |
|
|
|
sig = signature(func) |
|
|
|
params = list(sig.params.keys()) |
|
|
|
params = list(sig.parameters.keys()) |
|
|
|
|
|
|
|
|
|
|
|
list_args = _args_to_list3(func, args, kwargs) |
|
|
|
list_args = _args_to_list3(func, args, kwargs) |
|
|
|
result_idx = params.index(argname) |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
result_idx = params.index(argname) |
|
|
|
|
|
|
|
except ValueError: |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
return list_args, result_idx |
|
|
|
return list_args, result_idx |
|
|
|
|
|
|
|
|
|
|
|