JiaweiZhuang / xESMF

Universal Regridder for Geospatial Data
http://xesmf.readthedocs.io/
MIT License
269 stars 49 forks source link

conservative methods doesn't work #31

Closed JianghuiDu closed 6 years ago

JianghuiDu commented 6 years ago

I'm regridding CMIP5-CCSM4 ocean output with a dipole grid (in Greenland) onto 1x1 grid. I created the grid as following

sss_out = xe.util.grid_global(1, 1)
sss_out  # contains lat/lon values of cell centers and boundaries. 

which has grid corners

<xarray.Dataset>
Dimensions:  (x: 360, x_b: 361, y: 180, y_b: 181)
Coordinates:
    lon      (y, x) float64 -179.5 -178.5 -177.5 -176.5 -175.5 -174.5 -173.5 ...
    lat      (y, x) float64 -89.5 -89.5 -89.5 -89.5 -89.5 -89.5 -89.5 -89.5 ...
    lon_b    (y_b, x_b) int64 -180 -179 -178 -177 -176 -175 -174 -173 -172 ...
    lat_b    (y_b, x_b) int64 -90 -90 -90 -90 -90 -90 -90 -90 -90 -90 -90 ...
Dimensions without coordinates: x, x_b, y, y_b
Data variables:
    *empty*

However, when I try to use conservative method there seems to be problems with the corner and not recognizing lon_b.

regridder = xe.Regridder(sss, sss_out, 'conservative')
sss_out = regridder(sss)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/miniconda3/lib/python3.6/site-packages/xarray/core/dataarray.py in _getitem_coord(self, key)
    460         try:
--> 461             var = self._coords[key]
    462         except KeyError:

KeyError: 'lon_b'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
<ipython-input-140-83962fdabcdd> in <module>()
----> 1 regridder = xe.Regridder(sss, sss_out, 'conservative')
      2 sss_out = regridder(sss)

~/miniconda3/lib/python3.6/site-packages/xesmf/frontend.py in __init__(self, ds_in, ds_out, method, periodic, filename, reuse_weights)
    128         self._grid_in, shape_in = ds_to_ESMFgrid(ds_in,
    129                                                  need_bounds=self.need_bounds,
--> 130                                                  periodic=periodic
    131                                                  )
    132         self._grid_out, shape_out = ds_to_ESMFgrid(ds_out,

~/miniconda3/lib/python3.6/site-packages/xesmf/frontend.py in ds_to_ESMFgrid(ds, need_bounds, periodic, append)
     59 
     60     if need_bounds:
---> 61         lon_b = np.asarray(ds['lon_b'])
     62         lat_b = np.asarray(ds['lat_b'])
     63         lon_b, lat_b = as_2d_mesh(lon_b, lat_b)

~/miniconda3/lib/python3.6/site-packages/xarray/core/dataarray.py in __getitem__(self, key)
    469     def __getitem__(self, key):
    470         if isinstance(key, basestring):
--> 471             return self._getitem_coord(key)
    472         else:
    473             # xarray-style array indexing

~/miniconda3/lib/python3.6/site-packages/xarray/core/dataarray.py in _getitem_coord(self, key)
    463             dim_sizes = dict(zip(self.dims, self.shape))
    464             _, key, var = _get_virtual_variable(
--> 465                 self._coords, key, self._level_coords, dim_sizes)
    466 
    467         return self._replace_maybe_drop_dims(var, name=key)

~/miniconda3/lib/python3.6/site-packages/xarray/core/dataset.py in _get_virtual_variable(variables, key, level_vars, dim_sizes)
     71         ref_var = dim_var.to_index_variable().get_level_variable(ref_name)
     72     else:
---> 73         ref_var = variables[ref_name]
     74 
     75     if var_name is None:

KeyError: 'lon_b'

The other four methods all work fine, but I'd like to use the conservative method. Any idea why this happens?

JiaweiZhuang commented 6 years ago

Does your source grid ds_in has corner values?

JianghuiDu commented 6 years ago

The original netcdf file does have the corner values lon_bnds and lat_bnds. Maybe it's lost when opened using xarray?

JiaweiZhuang commented 6 years ago

Use ds_in.rename({'lon_bnds: 'lon_b', 'lat_bnds: 'lat_b'}, inplace=True) so xESMF can recognize the name.

JianghuiDu commented 6 years ago

I did this but still not working. The error this time is

ValueError: lon and lat should be both 1D or 2D

The original grid is curve-linear, so lab_b and lon_b are 3D arrays (a vertices dimension, plut the i and j dimensions).

JiaweiZhuang commented 6 years ago

See https://github.com/JiaweiZhuang/xESMF/issues/14#issuecomment-369686779

JianghuiDu commented 6 years ago

Thanks! I followed the suggestion there and manually changed the corners and it worked. One more thing. The regridding returned 0 rather than nan on grid points that have no data. I read some of the older posts and tried the conservative_normalized method but it didn't make a difference. Is it just a matter of removing 0 after regridding or more serious issues?

JiaweiZhuang commented 6 years ago

I followed the suggestion there and manually changed the corners and it worked.

Glad to see that!

The regridding returned 0 rather than nan on grid points that have no data.

This is the same issue as #15. There's a temporary workaround at https://github.com/JiaweiZhuang/xESMF/issues/15#issuecomment-371646763

JianghuiDu commented 6 years ago

That code does work. Thanks.

JiaweiZhuang commented 6 years ago

Great. Let me know if there're further issues.