Closed RondeauG closed 8 months ago
I suspect this has to do with how you draw a line from one coordinate to the other. The default ESMF option is to use a great circle, see https://earthsystemmodeling.org/esmpy_doc/release/ESMF_8_2_0/html/LineType.html?highlight=great%20circle
I suspect this would go away using the option for cartesian lines, but this option is not exposed in xesmf for now as far as I know.
I suspect that's a fairly straightforward PR if you're interested to see this work out of the box. Otherwise, you can probably work around this by using a polygon with more segments along the contour you want to follow.
AFAIU, "cartesian" lines are in the cartesian 3D space, not in a 2D latitude-longitude space (that wouldn't be cartesian anyway). It seems like ESMF does not offer an option to work in a purely lat-lon space.
I did test switching the line_type
to the SpatialAverager
regrid call and nothing changed. I'm not sure if this is my switch was ineffective or if the result is the same for both options. The latter seems fishy, it would mean I do not understand what's going on...
My guess is that we need to "densify" the polygons before converting them to meshes. I'm not sure of only increasing the number of nodes in the outer boundary is enough or if we also need to divide large polygons in pieces...
Increasing the density of the polygon contour seems to do the trick. The figure below shows the weights for input grids of 1, 5 and 15 degree resolution and an uniform input field of value one.
The polygon for the top row is defined from the four corners:
p1 = Polygon([(-80, -40), (80, -40), (80, 40), (-80, 40)])
The polygon for the bottom row is an interpolated version.
distance = np.linspace(0, 1, 100)
p2 = Polygon([p1.boundary.interpolate(d, normalized=True) for d in distance])
The white line is the polygon contour and the red line the great circle between polygon vertices.
I must say that I'm baffled by the behavior on the top row, the dependence on the resolution of the input grid is unexpected.
Very interesting find!
v0.8 has a function to densify the polygon segments.
When trying to use
SpatialAverager
to perform a global average, me and @aulemahal found some strange behaviour in the weight given to pixels.These are the weights generated when trying to average over a 40° x 20° rectangle. This seems adequate.![image](https://user-images.githubusercontent.com/38501935/208749534-84f208a0-0c10-4318-894c-c11374299e3d.png)
Something funky happens for a 160° x 80° rectangle however, with curves appearing:![image](https://user-images.githubusercontent.com/38501935/208749727-616fe176-7668-48d2-bb67-3fe8a9f4ec3e.png)
For a 320° x 160° region, the rectangle appears to "flip" and the weights are generated only with a slice of latitudes:![image](https://user-images.githubusercontent.com/38501935/208749872-8a40450f-ed3f-4912-8577-76c932c4062e.png)
For the globe (360° x 180°), the weights are generated along a singular latitude.![image](https://user-images.githubusercontent.com/38501935/208750079-e2d5f530-cb38-4252-827f-0764b20f34d6.png)
Sample code: