JiaweiZhuang / xESMF

Universal Regridder for Geospatial Data

Home Page:http://xesmf.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem with dateline (longitude=0) for higher resolution global grids

trondkr opened this issue · comments

When I use the grid_global method for generating a 1x1 degree grid where I interpolate CMIP6 global climate models I keep experiencing a problem with data at longitude=0. This is very visible in the resulting maps.
Skjermbilde 2020-06-02 kl  11 50 08
If I use a global grid with resolution 4x4 the problem goes away. I have tried a multitude of approaches to deal with the problem and I thought adding cartopy add_cyclic_point would surely fix it but no. So I am thinking that I do something wrong using the regridder which produces erroneous data at longitude=0.

I have a rather long notebook where I use CMIP6 data for calculating various properties and I plot the global results. The notebook is found here.

I define my global grid using : ds_out = xe.util.grid_global(1, 1)

And my regridder as:

def regrid_variable(varname, ds_in, ds_out, transpose=True):
    regridder = xe.Regridder(ds_in, ds_out, 'bilinear', reuse_weights=False, ignore_degenerate=True)
    regridder._grid_in = None
    regridder._grid_out = None
    if transpose:
        return regridder(ds_in[varname].T)
    else:
        return regridder(ds_in[varname])

To see the problem it is probably best to look at the notebook that has the images, but I am hoping you would see an obvious error in my definition of the global grid or the regridder. 
Thanks for your help. Cheers, Trond

@ahuang11 Thanks for your response. I already do use the add_cyclic_point to my code and problem is still there. I think I do something wrong with the interpolation.

indata_cyclic, lon_cyclic = add_cyclic_point(indata, coord=lon)

@ahuang11 I tried that too without success:
regridder = xe.Regridder(ds_in, ds_out, 'bilinear', reuse_weights=True, periodic=True, ignore_degenerate=False)

However, I did not try to add cyclic point to a dataset prior to interpolation. Is there an easy way to do that, which takes care of coordinates and variables in the dataset simultaneously?

@ahuang11 So it seems my problem is caused by my input grid having larger steps between each grid point than I thought.

(y) float64 45.0 46.25 47.5 48.75 ... 86.25 87.5 88.75 90.0 (x) float64 0.0 1.875 3.75 5.625 ... 352.5 354.4 356.2 358.1

The longitude ends at 358.1. If I use a global grid with 2x2 degrees resolution I do not experience the line at longitude 359/0, but with a step size of 1 longitude, I do. Is there a good way to fix this without having to increase my grid to 2x2 instead of 1x1?

I solved my problem by doing the interpolation twice (not the most elegant solution), first using a coarser resolution regridder to get global coverage and then downscaling the solution. Suggestions for improvements are very welcome. But it works...

ds_out_amon = xe.util.grid_2d(-180,180,2,southern_limit_latitude,90,2) 
ds_out = xe.util.grid_2d(-180,180,1,southern_limit_latitude,90,1) #grid_global(1, 1)
                           

dr_out_uas_amon=regrid_variable("uas",ds_uas,ds_out_amon,transpose=True).to_dataset()
dr_out_uas=regrid_variable("uas",dr_out_uas_amon,ds_out,transpose=False)`

For what it's worth, I have a simple example of using cartopy.util.add_cyclic_point to add a wrap-around or cyclic pixel to xarray.Dataset here: https://gist.github.com/brews/95e167fb7df997864304f07ee321f4fd.

This removes the longitude band artifact if you add the wrap-around pixels before passing the data fields to instantiate xesmf.Regridder.