Interpolation used in pixel-to-node transformations

I’m looking at performing a pixel-aligned to node-aligned transformation in a program of mine, so i thought I’d first look at how GMT does it (since it does so many things well). My test script is

gmt xyz2grd -Gpixel.grd -rp -I1 -R0/2/0/2 <<EOF
0.5, 0.5, 1.0
1.5, 0.5, 2.0
1.5, 1.5, 3.0
gmt grd2xyz pixel.grd
gmt grdsample pixel.grd -Gnode.grd -T
echo '--'
gmt grd2xyz node.grd

so creates a pixel-aligned grid, z = x + y, one missing value, converts it to node-aligned and prints the two out: it produces

0.5	1.5	NaN
1.5	1.5	3
0.5	0.5	1
1.5	0.5	2
0	2	NaN
1	2	3.66891884804
2	2	4.0859375
0	1	0.27702704072
1	1	2
2	1	2.75598096848
0	0	0.4453125
1	0	1.20574164391
2	0	2.11764717102

The results look good, in fact too good – the default interpolation is bicubic right? so I’d expect a lot more NaN propagation than that. Possibly grdsample -T uses a different default? I had a look around the source but couldn’t see anything obvious. Could anyone enlighten me (a reference to the literature and/or location in the source code)? Thanks in advance!

Yes, by default grdsample does a bicubic interpolation (man says so).
When I want to see what a program does I fire the debugger and hit F10 & F11 many times. For present case I think a good entry point is

Thanks Joaquim, that leads here, there is a link in that file (but it 404s), but it all looks pretty standard convolution kernel stuff, still I’m a bit puzzled by the lack of NaN propagation, possibly this is the reason:

Because of the size of the convolution kernels, these routines assume that
the grid is padded with appropriate (periodic or natural) boundary conditions

that assumption seems to be applied non-explicitly, would that be a reasonable summary?

Your case is probably caught up in an ongoing bug situation you can read about here. I can certainly see why you might get a NaN on the right side. I would use another interpolator tha nbicubic here, say bilinear.

Could it be that is working under the hood?

On that issue there is “introduced in 2023”, but I’m using the stock 6.4.0 (compiled locally) who’s tag is June 2022, so predates that.

Pretty sure bug is older