JiaweiZhuang / xESMF

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

reuse weights only checked by shape #48

Closed mathause closed 5 years ago

mathause commented 5 years ago

When reusing weight it seems to only check whether the on-disk weights have the same size as the new ones. This can lead to wrong results. Example:


import numpy as np
import xarray as xr
import xesmf

def sample_dataset(nlon, dlon, lon_start):

    nlat = 2

    data = np.random.randn(nlat, nlon)

    lon = np.arange(lon_start, lon_start + nlon * dlon, dlon)
    lat = np.arange(nlat)

    coords = dict(lon=lon, lat=lat)

    return xr.Dataset(dict(data=(('lat', 'lon'), data)), coords=coords)

# create a dataset to regrid
in_data = sample_dataset(nlon=50, dlon=1, lon_start=1)

# create 2 sample destination grids with same shape but different coords
grid1 = sample_dataset(nlon=10, dlon=2, lon_start=1)
grid2 = sample_dataset(nlon=10, dlon=2, lon_start=10)

If I now regrid with reuse_weights=True the result for grid2 is wrong:

regridder = xesmf.Regridder(in_data, grid1, 'bilinear', reuse_weights=True)
print('-- grid1, reuse=True', regridder.regrid_dataarray(in_data['data']).values[0, 0])

regridder = xesmf.Regridder(in_data, grid2, 'bilinear', reuse_weights=True)
print('-- grid2, reuse=True', regridder.regrid_dataarray(in_data['data']).values[0, 0])

regridder = xesmf.Regridder(in_data, grid1, 'bilinear', reuse_weights=False)
print('-- grid1, reuse=False', regridder.regrid_dataarray(in_data['data']).values[0, 0])

regridder = xesmf.Regridder(in_data, grid2, 'bilinear', reuse_weights=False)
print('-- grid2, reuse=False', regridder.regrid_dataarray(in_data['data']).values[0, 0])

Notice how results 1 and 2 are the same while 3 and 4 are different. I think it is important that this is checked.

JiaweiZhuang commented 5 years ago

You are right -- the current design is very suboptimal and I am going to overhaul this (#11). As a temporary fix you can explicitly specify the filename (either during creation or reusing) byRegridder(..., filename='custom_name.nc')

mathause commented 5 years ago

Thanks!