Skip to content

Commit

Permalink
Handle matrix via reference for grid input (#3829) (#3838)
Browse files Browse the repository at this point in the history
* Handle matrix vai reference for grid input

Testing is done via testapi_matrix_360_ref.c  Seems to work but raises an issue related to memory freeing.  Since the matrix data is only pointed to by the grid, I set the grid alloc_mode to external.  However, that also means that the x and y arrays that are created when creating the grid is left unfreed at the end.  We could just ignore this rare memory leak or do something about it.  One way is to add info to the struct HIDDEN so that we free those arrays even those the matrix is left untouched.

* Add PS orig

* Update gmt_api.c

* Update gmt_grdio.c

* Fix output ij

* Handle a switch from reference to duplicate

* make sure we set min/max when needed and not reset it

* use lessons learned from MATRIX/DUPLICATE to GRID/DUPLICATE

Lots of errors there as well and probalby never accessed.

* Use duplcate for 360 adn ref for 360_ref

Also fix the region assignment

* Apply same logic for finding min/max as for duplicate

* handle non-projection in grdimage when a referenced global grid

Co-authored-by: Paul Wessel <[email protected]>
  • Loading branch information
github-actions[bot] and PaulWessel authored Aug 4, 2020
1 parent 262f739 commit a4fca92
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 59 deletions.
134 changes: 83 additions & 51 deletions src/gmt_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -5193,6 +5193,15 @@ GMT_LOCAL int gmtapi_export_image (struct GMTAPI_CTRL *API, int object_ID, unsig
return (GMT_NOERROR);
}

unsigned int gmt_whole_earth (struct GMT_CTRL *GMT, double we_in[], double we_out[]) {
/* Determines if this is a global geographic grid and we want the whole world, regardless of central longitude */
if (!gmt_M_is_geographic (GMT, GMT_IN)) return 0;
if (!gmt_M_360_range (we_in[XLO], we_in[XHI])) return 0;
if (!gmt_M_360_range (we_out[XLO], we_out[XHI])) return 0;
if (doubleAlmostEqualZero (we_in[XLO], we_out[XLO])) return 2; /* Both regions are the same */
return 1; /* Different central meridians */
}

/*! . */
GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int object_ID, unsigned int mode, struct GMT_GRID *grid) {
/* Handles the reading of a 2-D grid given in one of several ways.
Expand All @@ -5207,10 +5216,10 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj

int item, new_item, new_ID;
bool done = true, new = false, row_by_row;
uint64_t row, col, kol, i0, i1, j0, j1, ij, ij_orig;
uint64_t row, col, kol, row_out, i0, i1, j0, j1, ij, ij_orig;
size_t size;
unsigned int both_set = (GMT_CONTAINER_ONLY | GMT_DATA_ONLY);
unsigned int method;
unsigned int method, start_over_method = 0;
double dx, dy, d;
p_func_uint64_t GMT_2D_to_index = NULL;
struct GMT_GRID *G_obj = NULL, *G_orig = NULL;
Expand Down Expand Up @@ -5243,6 +5252,9 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
if (grid->header->wesn[XLO] == S_obj->wesn[XLO] && grid->header->wesn[XHI] == S_obj->wesn[XHI] && grid->header->wesn[YLO] == S_obj->wesn[YLO] && grid->header->wesn[YHI] == S_obj->wesn[YHI]) S_obj->region = false;
}
method = gmtapi_set_method (S_obj); /* Get the actual method to use since may be MATRIX or VECTOR masquerading as GRID */

start_over_import_grid: /* We may get here if we cannot honor a GMT_IS_REFERENCE from below */

switch (method) {
/* Status: This case is fully tested and operational */
case GMT_IS_FILE: /* Name of a grid file on disk */
Expand Down Expand Up @@ -5332,26 +5344,32 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
GH->alloc_mode = GMT_ALLOC_INTERNALLY;
if (!S_obj->region && gmt_grd_pad_status (GMT, G_obj->header, GMT->current.io.pad)) { /* Want an exact copy with no subset and same padding */
gmt_M_memcpy (G_obj->data, G_orig->data, G_orig->header->size, gmt_grdfloat);
gmt_BC_init (GMT, G_obj->header); /* Initialize grid interpolation and boundary condition parameters */
if (gmt_M_err_pass (GMT, gmt_grd_BC_set (GMT, G_obj, GMT_IN), "Grid memory"))
return_null (API, GMT_GRID_BC_ERROR); /* Set boundary conditions */
break; /* Done with this grid */
}
/* Here we need to do more work: Either extract subset or add/change padding, or both. */
/* Get start/stop row/cols for subset (or the entire domain) */
/* dx,dy are needed when the grid is pixel-registered as the w/e/s/n bounds are off by 0.5 {dx,dy} relative to node coordinates */
dx = G_obj->header->inc[GMT_X] * G_obj->header->xy_off; dy = G_obj->header->inc[GMT_Y] * G_obj->header->xy_off;
j1 = (unsigned int)gmt_M_grd_y_to_row (GMT, G_obj->header->wesn[YLO]+dy, G_orig->header);
j0 = (unsigned int)gmt_M_grd_y_to_row (GMT, G_obj->header->wesn[YHI]-dy, G_orig->header);
i0 = (unsigned int)gmt_M_grd_x_to_col (GMT, G_obj->header->wesn[XLO]+dx, G_orig->header);
i1 = (unsigned int)gmt_M_grd_x_to_col (GMT, G_obj->header->wesn[XHI]-dx, G_orig->header);
j1 = (unsigned int)gmt_M_grd_y_to_row (GMT, S_obj->wesn[YLO]+dy, G_orig->header);
j0 = (unsigned int)gmt_M_grd_y_to_row (GMT, S_obj->wesn[YHI]-dy, G_orig->header);
i0 = (unsigned int)gmt_M_grd_x_to_col (GMT, S_obj->wesn[XLO]+dx, G_orig->header);
i1 = (unsigned int)gmt_M_grd_x_to_col (GMT, S_obj->wesn[XHI]-dx, G_orig->header);
gmt_M_memcpy (G_obj->header->pad, GMT->current.io.pad, 4, int); /* Set desired padding */
gmt_M_memcpy (G_obj->header->wesn, S_obj->wesn, 4U, double); /* Update the grid header region to match subset request */
gmt_set_grddim (GMT, G_obj->header); /* Adjust all dimensions accordingly before accessing the grid for output */
/* get stats */
HH = gmt_get_H_hidden (G_obj->header);
G_obj->header->z_min = DBL_MAX;
G_obj->header->z_max = -DBL_MAX;
HH->has_NaNs = GMT_GRID_NO_NANS; /* We are about to check for NaNs and if none are found we retain 1, else 2 */
for (row = j0; row <= j1; row++) {
for (row = j0, row_out = 0; row <= j1; row++, row_out++) {
ij = gmt_M_ijp (G_obj->header, row_out, 0); /* Position in output grid at start of current row */
for (col = i0; col <= i1; col++, ij++) {
ij_orig = gmt_M_ijp (G_orig->header, row, col); /* Position of this (row,col) in original grid organization */
ij = gmt_M_ijp (G_obj->header, row, col); /* Position of this (row,col) in output grid organization */
kol = col % G_orig->header->n_columns;
ij_orig = gmt_M_ijp (G_orig->header, row, kol); /* Position of this (row,col) in original grid organization */
G_obj->data[ij] = G_orig->data[ij_orig];
if (gmt_M_is_fnan (G_obj->data[ij]))
HH->has_NaNs = GMT_GRID_HAS_NANS;
Expand Down Expand Up @@ -5419,34 +5437,38 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
GMT_2D_to_index = gmtapi_get_2d_to_index (API, M_obj->shape, GMT_GRID_IS_REAL);
if ((api_get_val = gmtapi_select_get_function (API, M_obj->type)) == NULL)
return_null (API, GMT_NOT_A_VALID_TYPE);
G_obj->header->z_min = +DBL_MAX;
G_obj->header->z_max = -DBL_MAX;
HH = gmt_get_H_hidden (G_obj->header);
HH->has_NaNs = GMT_GRID_NO_NANS; /* We are about to check for NaNs and if none are found we retain 1, else 2 */

if (! (mode & GMT_DATA_ONLY)) { /* Must first init header and copy the header information from the matrix header */
gmtapi_matrixinfo_to_grdheader (GMT, G_obj->header, M_obj); /* Populate a GRD header structure */
if (mode & GMT_CONTAINER_ONLY) { /* Just needed the header */
/* Must get the full zmin/max range since not provided by the matrix header */
/* Must get the full zmin/max range since not provided by the matrix header */
G_obj->header->z_min = +DBL_MAX;
G_obj->header->z_max = -DBL_MAX;
HH->has_NaNs = GMT_GRID_NO_NANS; /* We are about to check for NaNs and if none are found we retain 1, else 2 */
gmt_M_grd_loop (GMT, G_obj, row, col, ij) {
ij_orig = GMT_2D_to_index (row, col, M_obj->dim);
api_get_val (&(M_obj->data), ij_orig, &d);
if (gmt_M_is_dnan (d))
HH->has_NaNs = GMT_GRID_HAS_NANS;
else {
G_obj->header->z_min = MIN (G_obj->header->z_min, (gmt_grdfloat)d);
G_obj->header->z_max = MAX (G_obj->header->z_max, (gmt_grdfloat)d);
}
ij_orig = GMT_2D_to_index (row, col, M_obj->dim);
api_get_val (&(M_obj->data), ij_orig, &d);
if (gmt_M_is_dnan (d))
HH->has_NaNs = GMT_GRID_HAS_NANS;
else {
G_obj->header->z_min = MIN (G_obj->header->z_min, (gmt_grdfloat)d);
G_obj->header->z_max = MAX (G_obj->header->z_max, (gmt_grdfloat)d);
}
break; /* Done for now */
}
if (mode & GMT_CONTAINER_ONLY) /* Just needed the header */
break; /* Done for now */
}

GMT_Report (API, GMT_MSG_INFORMATION, "Importing grid data from user matrix memory location\n");

/* Get start/stop row/cols for subset (or the entire domain) */
/* dx,dy are needed when the grid is pixel-registered as the w/e/s/n bounds are off by 0.5 {dx,dy} relative to node coordinates */
if (S_obj->region) { /* Want a subset */
if (!S_obj->region || gmt_whole_earth (GMT, M_obj->range, S_obj->wesn)) { /* Easy, get the whole enchilada */
j0 = i0 = 0;
j1 = G_obj->header->n_rows - 1; /* Minus 1 since we loop up to and including below */
i1 = G_obj->header->n_columns - 1;
}
else { /* Want a subset */
dx = G_obj->header->inc[GMT_X] * G_obj->header->xy_off; dy = G_obj->header->inc[GMT_Y] * G_obj->header->xy_off;
j1 = (unsigned int)gmt_M_grd_y_to_row (GMT, S_obj->wesn[YLO]+dy, G_obj->header);
j0 = (unsigned int)gmt_M_grd_y_to_row (GMT, S_obj->wesn[YHI]-dy, G_obj->header);
Expand All @@ -5455,23 +5477,18 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
gmt_M_memcpy (G_obj->header->wesn, S_obj->wesn, 4U, double); /* Update the grid header region to match subset request */
gmt_set_grddim (GMT, G_obj->header); /* Adjust all dimensions accordingly before allocating space */
}
else { /* Easy, get the whole enchilada */
j0 = i0 = 0;
j1 = G_obj->header->n_rows - 1; /* Minus 1 since we loop up to and including below */
i1 = G_obj->header->n_columns - 1;
}
if (G_obj->data) { /* This is an error - there cannot be a data pointer yet */
GMT_Report (API, GMT_MSG_ERROR, "G->data is not NULL when memory allocation is about to happen\n");
return_null (API, GMT_PTR_IS_NULL);
}
else
G_obj->data = gmt_M_memory_aligned (GMT, NULL, G_obj->header->size, gmt_grdfloat);

for (row = j0; row <= j1; row++) {
for (row = j0, row_out = 0; row <= j1; row++, row_out++) {
ij = gmt_M_ijp (G_obj->header, row_out, 0); /* Position in output grid at start of current row */
for (col = i0; col <= i1; col++, ij++) {
kol = col % M_obj->n_columns;
ij_orig = GMT_2D_to_index (row, kol, M_obj->dim); /* Position of this (row,col) in input matrix organization */
ij = gmt_M_ijp (G_obj->header, row, kol); /* Position of this (row,col) in output grid organization */
api_get_val (&(M_obj->data), ij_orig, &d); /* Get the next item from the matrix */
G_obj->data[ij] = (gmt_grdfloat)d;
if (gmt_M_is_dnan (d))
Expand All @@ -5482,7 +5499,7 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
}
}
}
if (gmt_M_is_geographic (GMT, GMT_IN) && gmt_M_360_range (M_obj->range[XLO], M_obj->range[XHI]) && gmt_M_360_range (G_obj->header->wesn[XLO], G_obj->header->wesn[XHI])) {
if (gmt_whole_earth (GMT, M_obj->range, S_obj->wesn)) {
/* Global grids passed via matrix are not rotated to fit the desired global region, so we need to correct the wesn for this grid to match the matrix */
gmt_M_memcpy (G_obj->header->wesn, M_obj->range, 4U, double);
}
Expand All @@ -5491,13 +5508,25 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
return_null (API, GMT_GRID_BC_ERROR); /* Set boundary conditions */
API->object[new_item]->status = GMT_IS_USED; /* Mark as read */
API->object[new_item]->actual_family = GMT_IS_GRID; /* Done reading from matrix */
if (start_over_method) API->object[new_item]->method = start_over_method; /* We changed our mind from reference to duplicate due to region */
GH->alloc_level = API->object[new_item]->alloc_level; /* Since allocated here */
break;

case GMT_IS_REFERENCE|GMT_VIA_MATRIX: /* The user's 2-D grid array of some sort, + info in the args [NOT YET FULLY TESTED] */
/* Getting a matrix info S_obj->resource. Create grid header and then pass the grid pointer via the matrix pointer */
if ((M_obj = S_obj->resource) == NULL) return_null (API, GMT_PTR_IS_NULL);
//if (S_obj->region) return_null (API, GMT_SUBSET_NOT_ALLOWED);
/* Determine if it is possible to use the matrix given the region selected and the fact we chose GMT_IS_REFERENCE. This test will
* only kick in after we allocate the G_obj and come back the second time (after getting header) since otherwise S_obj->wesn is not set yet */
if (!(!S_obj->region ||
(S_obj->wesn[XLO] >= M_obj->range[XLO] && S_obj->wesn[XHI] <= M_obj->range[XHI] && S_obj->wesn[YLO] >= M_obj->range[YLO] && S_obj->wesn[YHI] <= M_obj->range[YHI]) ||
gmt_whole_earth (GMT, M_obj->range, S_obj->wesn))) { /* Cannot do this by reference, switch to duplication */
method -= GMT_IS_REFERENCE;
method += GMT_IS_DUPLICATE;
start_over_method = GMT_IS_DUPLICATE;
GMT_Report (API, GMT_MSG_DEBUG, "Subset selection requires GMT_IS_DUPLICATION instead of GMT_IS_REFERENCE - method has been switched\n");
goto start_over_import_grid;
}

/* This method requires the input data to be a GMT_GRD_FORMAT matrix - otherwise we should be DUPLICATING */
MH = gmt_get_M_hidden (M_obj);
if (!(M_obj->shape == GMT_IS_ROW_FORMAT && M_obj->type == GMT_GRDFLOAT && (mode & GMT_GRID_IS_COMPLEX_MASK) == 0))
Expand All @@ -5514,27 +5543,26 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
done = (mode & GMT_CONTAINER_ONLY) ? false : true; /* Not done until we read grid */
if (! (mode & GMT_DATA_ONLY)) {
gmtapi_matrixinfo_to_grdheader (GMT, G_obj->header, M_obj); /* Populate a GRD header structure */
if (mode & GMT_CONTAINER_ONLY) { /* Just needed the header but need to set zmin/zmax first */
/* Temporarily set data pointer for convenience; removed later */
/* Temporarily set data pointer for convenience; removed later */
#ifdef DOUBLE_PRECISION_GRID
G_obj->data = M_obj->data.f8;
G_obj->data = M_obj->data.f8;
#else
G_obj->data = M_obj->data.f4;
G_obj->data = M_obj->data.f4;
#endif
G_obj->header->z_min = +DBL_MAX;
G_obj->header->z_max = -DBL_MAX;
HH->has_NaNs = GMT_GRID_NO_NANS; /* We are about to check for NaNs and if none are found we retain 1, else 2 */
gmt_M_grd_loop (GMT, G_obj, row, col, ij) {
if (gmt_M_is_fnan (G_obj->data[ij]))
HH->has_NaNs = GMT_GRID_HAS_NANS;
else {
G_obj->header->z_min = MIN (G_obj->header->z_min, G_obj->data[ij]);
G_obj->header->z_max = MAX (G_obj->header->z_max, G_obj->data[ij]);
}
G_obj->header->z_min = +DBL_MAX;
G_obj->header->z_max = -DBL_MAX;
HH->has_NaNs = GMT_GRID_NO_NANS; /* We are about to check for NaNs and if none are found we retain 1, else 2 */
gmt_M_grd_loop (GMT, G_obj, row, col, ij) {
if (gmt_M_is_fnan (G_obj->data[ij]))
HH->has_NaNs = GMT_GRID_HAS_NANS;
else {
G_obj->header->z_min = MIN (G_obj->header->z_min, G_obj->data[ij]);
G_obj->header->z_max = MAX (G_obj->header->z_max, G_obj->data[ij]);
}
G_obj->data = NULL; /* Since data are not requested yet */
break;
}
G_obj->data = NULL; /* Since data are not requested yet */
if (mode & GMT_CONTAINER_ONLY) /* Just needed the header but had to set zmin/zmax first */
break;
}
if ((new_ID = gmtapi_get_object (API, GMT_IS_GRID, G_obj)) == GMT_NOTSET)
return_null (API, GMT_OBJECT_NOT_FOUND);
Expand All @@ -5548,11 +5576,15 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj
#endif
GH = gmt_get_G_hidden (G_obj);
S_obj->alloc_mode = MH->alloc_mode; /* Pass on alloc_mode of matrix */
GH->alloc_mode = MH->alloc_mode;
GH->alloc_mode = GMT_ALLOC_EXTERNALLY; /* Since we cannot have both M and G try to free */
API->object[new_item]->resource = G_obj;
API->object[new_item]->status = GMT_IS_USED; /* Mark as read */
GH->alloc_level = API->object[new_item]->alloc_level; /* Since allocated here */
if (S_obj->region) { /* Possibly adjust the pad so inner region matches wesn */
if (gmt_whole_earth (GMT, M_obj->range, S_obj->wesn)) {
/* Global grids passed via matrix are not rotated to fit the desired global region, so we need to correct the wesn for this grid to match the matrix */
gmt_M_memcpy (G_obj->header->wesn, M_obj->range, 4U, double);
}
else if (S_obj->region) { /* Possibly adjust the pad so inner region matches wesn */
if (S_obj->reset_pad) { /* First undo a prior sub-region used with this memory grid */
gmtlib_contract_headerpad (GMT, G_obj->header, S_obj->orig_pad, S_obj->orig_wesn);
S_obj->reset_pad = 0;
Expand Down
14 changes: 7 additions & 7 deletions src/gmt_grdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2660,6 +2660,7 @@ struct GMT_GRID *gmt_duplicate_grid (struct GMT_CTRL *GMT, struct GMT_GRID *G, u
gmt_copy_gridheader (GMT, Gnew->header, G->header);

if ((mode & GMT_DUPLICATE_DATA) || (mode & GMT_DUPLICATE_ALLOC)) { /* Also allocate and possibly duplicate data array */
struct GMT_GRID_HIDDEN *GH = gmt_get_G_hidden (Gnew);
if ((mode & GMT_DUPLICATE_RESET) && !gmt_grd_pad_status (GMT, G->header, GMT->current.io.pad)) {
/* Pads differ and we requested resetting the pad */
gmt_M_grd_setpad (GMT, Gnew->header, GMT->current.io.pad); /* Set default pad size */
Expand All @@ -2682,6 +2683,7 @@ struct GMT_GRID *gmt_duplicate_grid (struct GMT_CTRL *GMT, struct GMT_GRID *G, u

Gnew->x = gmt_grd_coord (GMT, Gnew->header, GMT_X); /* Get array of x coordinates */
Gnew->y = gmt_grd_coord (GMT, Gnew->header, GMT_Y); /* Get array of y coordinates */
GH->xy_alloc_mode[GMT_X] = GH->xy_alloc_mode[GMT_Y] = GMT_ALLOC_INTERNALLY;
}
return (Gnew);
}
Expand Down Expand Up @@ -2712,13 +2714,11 @@ unsigned int gmtlib_free_grid_ptr (struct GMT_CTRL *GMT, struct GMT_GRID *G, boo
if (GH->alloc_mode == GMT_ALLOC_INTERNALLY) gmt_M_free_aligned (GMT, G->data);
G->data = NULL; /* This will remove reference to external memory since gmt_M_free_aligned would not have been called */
}
if (G->x && G->y && free_grid) {
if (GH->xy_alloc_mode[GMT_X] == GMT_ALLOC_INTERNALLY)
gmt_M_free (GMT, G->x);
if (GH->xy_alloc_mode[GMT_Y] == GMT_ALLOC_INTERNALLY)
gmt_M_free (GMT, G->y);
G->x = G->y = NULL; /* This will remove reference to external memory since gmt_M_free would not have been called */
}
if (G->x && GH->xy_alloc_mode[GMT_X] == GMT_ALLOC_INTERNALLY)
gmt_M_free (GMT, G->x);
if (G->y && GH->xy_alloc_mode[GMT_Y] == GMT_ALLOC_INTERNALLY)
gmt_M_free (GMT, G->y);
G->x = G->y = NULL; /* This will remove reference to external memory since gmt_M_free would not have been called */
if (GH->extra) gmtlib_close_grd (GMT, G); /* Close input file used for row-by-row i/o */
alloc_mode = GH->alloc_mode;
gmt_M_free (GMT, G->hidden);
Expand Down
1 change: 1 addition & 0 deletions src/gmt_prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ EXTERN_MSC void gmt_polar_to_cart (struct GMT_CTRL *GMT, double r, double theta,
EXTERN_MSC void gmt_cart_to_polar (struct GMT_CTRL *GMT, double *r, double *theta, double *a, bool degrees);

/* From gmt_api.c */
EXTERN_MSC unsigned int gmt_whole_earth (struct GMT_CTRL *GMT, double we_in[], double we_out[]);
EXTERN_MSC int gmt_copy (struct GMTAPI_CTRL *API, enum GMT_enum_family family, unsigned int direction, char *ifile, char *ofile);
EXTERN_MSC struct GMTAPI_CTRL * gmt_get_api_ptr (struct GMTAPI_CTRL *ptr);
EXTERN_MSC const char * gmt_show_name_and_purpose (void *API, const char *name, const char *component, const char *purpose);
Expand Down
3 changes: 3 additions & 0 deletions src/grdimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,9 @@ EXTERN_MSC int GMT_grdimage (void *V_API, int mode, void *args) {

}

if (n_grids && (gmt_whole_earth (GMT, Grid_orig[0]->header->wesn, wesn) == 1))
need_to_project = true; /* This can only happen if reading a global geographic memory grid */

if (need_to_project) { /* Need to resample the grd file using the specified map projection */
int nx_proj = 0, ny_proj = 0;
double inc[2] = {0.0, 0.0};
Expand Down
2 changes: 1 addition & 1 deletion src/testapi_matrix_360.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ int main () {
M->inc[0] = M->inc[1] = 1.0;
M->registration = 1;
/* Create a virtual file to pass as a grid */
GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, M, input);
GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN, M, input);
/* Call grdimage with central longitude 0, which is the center of the grid */
sprintf (args, "%s -Rg -JH0/6i -Bg30 -K -Cgeo -P", input);
GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args);
Expand Down
Binary file added test/api/apimat_360_ref.ps
Binary file not shown.

0 comments on commit a4fca92

Please sign in to comment.