-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
grdimage shading fails with external matrix #3408
Comments
Hmmm, unless I'm missing something I think it's the user responsibility to pass arrays with order that GMT is expecting. I do that all the time in Julia and never had this problem. Well not counting the countless days working in a way that the memory layout can be set, and changed, to work with this. |
I didn't mean that the first figure is wrong. The flipping Y axis is simply because I didn't spend any time to re-sort the matrix. The first figure shows that the GMT_Read_Data can correctly read the matrix. The main issue here is the second figure. After adding -I+d, the output figure is not what we expect. |
Does it give the same thing if you create the ascii version with grd2xyz? |
Sorry, I forgot to attach the data in my first comment 2d-matrix.txt. |
grd2xyz outputs XYZ triples or Z values, but GMT_Read_Data expects a matrix here (GMT_IS_MATRIX is passed to GMT_Read_Data). |
Sorry but still fail to see that the problem is in GMT. As I said either in Mirone or Julia I pass grids back and forth and when such cases arise it was always my fault. |
@joa-quim It's not about the orders. I've updated the issue description. Hopefully it's more clear to read now. |
grdgradient does recycle the input grid and places gradients there except when we are not allowed:
So since In.file is a @GMTAPI@ memory reference it allocates a separate grid. So not immediately obvious why/where it overwrites the input grid. But clearly it does. @seisman, if you are able to walk through this in Xcode or similar you may be able to verify that it is not allocating a new grid. E.g., new_grid should be true in this case. I can help with debug later but busy day with zoom with all Chairs and Provost. Shit-storm is brewing with Governor planning to take all vacant positions away (we have 5 with active searches all frozen...). |
Line 891 in ddd829b
|
See #3408 for background. Need to add this to the repo to debug in Xcode.
* Add API C code that illustraties failed shading See #3408 for background. Need to add this to the repo to debug in Xcode. * Update gmt_api.c Grid headers read via matrices must still remember they came from a matrix since when GMT_Read_Data is called a second time to get the data they still need to fall into that method. * Update gmt_api.c * Update gmt_api.c * Update gmt_api.c * Update testapi_imageshading.c * Update testapi_imageshading.c * Add test * Update gmt_api.c * Update grdimage.c
The original Python script now crashes. It worked when I tested PR #3510, but I don't why now it crashes after merging #3510 to master.
Here are the verbose messages reported by the above Python script. |
Hm, I do not see any errors in that log. |
It crashes at the end of the log. |
Different from the C example code above, PyGMT calls following C API functions:
|
Re-open the issue because changes between GMT 6.1.0 and 6.1.1 breaks matrix shading again. Here is a Python script to reproduce the issue (adapted from GenericMappingTools/pygmt#364): import pygmt
fig = pygmt.Figure()
# shaded relief using @earth_relief_30m
fig.grdimage('@earth_relief_30m', region='g', frame=True, projection='Cyl_stere/6i', cmap='geo', shading=True)
fig.shift_origin(xshift='7i')
# shaded relief using xarray: DOES NOT WORK.
grid = pygmt.datasets.load_earth_relief('30m')
fig.grdimage(grid, region='g', frame=True, projection='Cyl_stere/6i', cmap='geo', shading=True)
fig.savefig("shading.png") You can see that the right-side map doesn't have shading, although we use |
Ping @PaulWessel to the regression introduced in GMT 6.1.1, which breaks PyGMT's grdimage shading again. |
OK, I will fire up my PyGMT and Xcode tomorrow and have a look. I should remember just enough to at least tell where it goes wrong. |
OK, may need to refine my debug instructions for pygmt to be fool-proof: Got this far:
Do I need to set anything other than GMT_LIBRARY_PATH? |
You're running your GMT debug build, right? For debug build, I believe you also need to define |
Thanks that works. It is a bit odd since the Xcode debug build does not install a share dir so I am pointing it to my regular non-xcode-debug build. So I have
Not a problem, but not sure to have the xcodebuild "install" the stuff under the xbuild tree. |
OK, so on first going-through everything looks fine: Grid is received, values look fine, they are passed to grdgradient which creates a new grid with intensities that are returned back, with values that look good. Then both grids are projected and that looks fine too. THen we build the rgb and I cannot see anything obviously wrong. I only stepped through a few nodes and the only thing I need to go back and do is to look at more values since the few I looked at had very small intensity values (0.0003 etc) which of course would not change the color. The projected intensity grid header has reasonable ranges though. |
Hm, so the diff image does seem to correlate a bit with data gradients, especially the Arctic continental shelf. Yet still a bit odd. And your white washing (I assume it is the same CPT?) would indicate a good amount of constant ambient light (positive intensities). OK, will contrast with the first command to see if values are radically different in the intensity grid. |
Not there yet, but (re-)learning that with the xarray there are no pad, of course, so the grdgradient call makes a new grid for the intensities with a pad of 1. This is returned to grdimage. The grid has no pad. Presumably something funny happens in this context. The left (file case) has pad = 2 throughout and life is good. |
More: Well ,Xcode is acting strange today. I step into a function, then when I step back out I only see assembly, not C. So that is a bit annoying. Anyhow, the new scheme with passing a common H header structure fails since the grid and the intensity grid has different paddings. So I certainly will need to pass HG and HI or something. So will do that first. |
@seisman, if I instead wanted to read in another (very small) grid entirely from netcdf into memory (like grid), is there support for that? |
Yes, you can use I first generate a small grid using grdcut: then plot the grid in two different ways: import pygmt
import xarray as xr
fig = pygmt.Figure()
fig.grdimage('small_grid.nc', frame=True, projection='Cyl_stere/6i', cmap='geo', shading=True)
fig.shift_origin(xshift='7i')
# shaded relief using xarray: DOES NOT WORK.
grid = xr.open_dataarray("small_grid.nc")
fig.grdimage(grid, frame=True, projection='Cyl_stere/6i', cmap='geo', shading=True)
fig.savefig("shading.png") |
The issue was first reported by @liamtoney in GenericMappingTools/pygmt#364. Using the PyGMT script in that issue, he got the following error:
After some debugging, it seems that GMT can correctly read the matrix (i.e., the earth relief data) and can plot it correctly if shading=False (i.e., no -I+d in the command line). However, if shading=True is used (i.e., grdimage -I+d), GMT reports the error above, possibly because the matrix in memory is modified/freed/re-initialized when calling
grdgradient
.The issue can be partially reproduced using the following C codes. The C code below is modified from GMT's own test code
testapi_matrix_plot.c
. It reads a 2d matrix and plots the matrix using grdimage.The data
2d-matrix.txt
is the 60m earth relief data, converted from netCDF to matrix format using following Python code. The data is attached 2d-matrix.txt.The C code is compiled using
The output image looks correct. The coordinates are incorrect, simply because I didn't pass the geographic information.
Changing the grdimage arguments to:
to enable shading, then the output image is:
This is what I expect:
The text was updated successfully, but these errors were encountered: