Stream: python-questions
Topic: usage interp_hybrid_to_pressure
Brian Medeiros (May 04 2021 at 19:29):
Hi all, but especially @Orhan Eroglu :
I'm getting an error numpy.AxisError: axis 1 is out of bounds for array of dimension 1
when trying to use GeoCAT's interp_hybrid_to_pressure. Here's what I'm trying:
import geocat.comp as gc import xarray as xr loc = "/glade/p/cesm/pcwg/jenkay/COSP/cesm21/f.e21.FHIST_BGC.f09_f09_mg17.CMIP6-AMIP.001_cosp1/atm/proc/tseries/month_1/" ds_ps = xr.open_dataset(loc+"f.e21.FHIST_BGC.f09_f09_mg17.CMIP6-AMIP.001_cosp1.cam.h0.PS.197901-201412.nc") ds_t = xr.open_dataset(loc+"f.e21.FHIST_BGC.f09_f09_mg17.CMIP6-AMIP.001_cosp1.cam.h0.T.197901-201412.nc") temp = ds_t["T"] ps = ds_ps["PS"] temp_plev = gc.interp_hybrid_to_pressure(temp, ps, ds_t['hyam'], ds_t['hybm'], lev_dim='lev')
This is with python 3.9.2 in a brand new geocat environment on casper (with the addition of conda install netcdf4).
Any idea what is happening?
Deepak Cherian (May 04 2021 at 19:33):
This is a bug. interp_axis
should always be -1, since lev_dim
is a core dim, apply_ufunc will transpose so that lev_dim
is the last dimension.
@Brian Medeiros try gc.interp_hybrid_to_pressure(temp.transpose(..., "lev"), ...)
.
Brian Medeiros (May 04 2021 at 21:38):
Thanks, @Deepak Cherian ! That makes sense. Applying transpose appears to be working.
Brian Medeiros (May 04 2021 at 22:22):
I spoke too soon. I can get it to work for a single column, but it seems like as soon as I use an actual multidimensional array it is giving a similar kind of error. I tried to use a subset of the data:
ntime = 2 temp_sample = temp.isel(time=slice(None,ntime)).transpose("time","lat","lon","lev") ps_sample = ps.isel(time=slice(None,ntime)) print(temp_sample.shape) # (2, 192, 288, 32) print(ps_sample.shape) # (2, 192, 288) tmp = gc.interp_hybrid_to_pressure(temp_sample, ps_sample, ds_t['hyam'], ds_t['hybm']) tmp
and it says AxisError: axis 3 is out of bounds for array of dimension 1
Brian Medeiros (May 05 2021 at 02:52):
Well, I don't completely understand what is going on, but I can share a workaround for this issue. I switched from the MetPy interpolation to just plain old numpy interp
:
if method == 'linear': # func_interpolate = metpy.interpolate.interpolate_1d func_interpolate = np.interp
and corresponding adjustment of the vertical remapper:
def _vertical_remap(data, pressure): """Define interpolation function.""" return func_interpolate(new_levels, pressure, data, left=np.nan, right=np.nan)
This appears to behave nicely.
Orhan Eroglu (May 05 2021 at 15:36):
I will be looking into it soon
Ryan May (May 11 2021 at 19:53):
If you find we're doing something wrong, please don't hesitate to open an issue.
Orhan Eroglu (May 18 2021 at 21:35):
Especially @Brian Medeiros and @Ryan May , and also others, sorry for the late report back. I have had some findings now:
1) The pressure
and data
were not of the same shape (after _pressure_from_hybrid
call) though it is required by metpy.interpolate.interpolate_1d
. I first corrected this one:
# Calculate pressure levels at the hybrid levels pressure = _pressure_from_hybrid(ps, hyam, hybm, p0) # Pa pressure = pressure.transpose(*data.dims)
2) After that, the code was still failing within the xarray.apply_ufunc
call. I wanted to first see how metpy.interpolate.interpolate_1d
or metpy.interpolate.log_interpolate_1d
is behaving when data is of type numpy.ndarray or xarray.DataArray. So, I tested the following cases:
a- Numpy Inputs: When I converted Brian's inputs to Numpy and called metpy functions directly (i.e. no xarray.apply_ufunc
), the code ran successfully.
# Calling with Numpy is successful output_np = _vertical_remap(data.values, pressure.values)
b- Xarray Inputs: When I kept Brian's inputs as is ( i.e. Xarray) and called metpy functions directly (i.e. no xarray.apply_ufunc
), the code failed.
# Calling with Xarray is failing!!! output_xr = _vertical_remap(data, pressure)
Here is the failure message, which is clearer than the failure messages that were output while calling via xarray.apply_ufunc
(Though, the original failure Brian found in the original code, i.e. via xarray.apply_ufunc
, was due to this same xarray
thing I think):
File "/Users/oero/miniconda3/envs/geocat_comp_build/lib/python3.9/site-packages/geocat/comp/interp_hybrid_to_pressure.py", line 89, in _vertical_remap return func_interpolate(new_levels, pressure, data, axis=interp_axis) File "/Users/oero/miniconda3/envs/geocat_comp_build/lib/python3.9/site-packages/metpy/xarray.py", line 1206, in wrapper result = func(*bound_args.args, **bound_args.kwargs) File "/Users/oero/miniconda3/envs/geocat_comp_build/lib/python3.9/site-packages/metpy/interpolate/one_dimension.py", line 127, in interpolate_1d minv = np.apply_along_axis(np.searchsorted, axis, xp, x[sort_x]) File "<__array_function__ internals>", line 5, in apply_along_axis TypeError: no implementation found for 'numpy.apply_along_axis' on types that implement __array_function__: [<class 'pint.quantity.build_quantity_class.<locals>.Quantity'>]
I couldn't dig into the actual issue with metpy
& xarray
for the time; I will continue my investigation into it.
@Ryan May : I can create an issue in metpy repo, but I am not sure how to provide them/you with an easily replicable GeoCAT-comp run of this (i.e. it may require you to setup GeoCAT-comp etc.). Maybe I could create a branch/PR from these changes I have made under our code, and metpy folks would like to step in? Let me know what is more convenient for you (if you think it is a metpy issue).
Orhan Eroglu (May 27 2021 at 03:21):
Hi @Brian Medeiros
Please see GeoCAT-comp PR #155 for a workaround to get interp_hybrid_to_pressure
successfully for Xarray inputs of 4D or more dims. With this new version of the code, your original script (i.e. without transposing data) should work successfully. I already tested it. Please let me know if you can test it with the code in the PR; otherwise, you can also give it a try with our newer version via conda around end of May or early June. By the way, I tested both unchunked and chunked versions of your data and got dramatically different performances, which I could share with you.
@Ryan May I think that this is related to metpy.interpolate's xarray interface; thus, I have created an issue with a minimal code that does directly run on metpy functions (i.e. no geocat-comp functionality). Please see the Metpy Issue #1889 here
Last updated: Jan 30 2022 at 12:01 UTC