diff --git a/doc/examples/ex34/ex34.ps b/doc/examples/ex34/ex34.ps index a520c7e5088..51d18e91aec 100644 Binary files a/doc/examples/ex34/ex34.ps and b/doc/examples/ex34/ex34.ps differ diff --git a/doc/rst/source/api.rst b/doc/rst/source/api.rst index d95e781352b..bba6131464b 100644 --- a/doc/rst/source/api.rst +++ b/doc/rst/source/api.rst @@ -1571,7 +1571,7 @@ different data types. Here, ``mode`` determines how we read the grid: To read the entire grid and its header, pass ``GMT_CONTAINER_AND_DATA``. However, if you may need to extract a sub-region you must first read the header by passing - ``GMT_CONTAINER_ONLY``, then examine the header structure range + ``GMT_CONTAINER_ONLY`` with ``wesn`` = NULL, then examine the header structure range attributes, specify a subset via the array ``wesn``, and finally call GMT_Read_Data_ a second time, now with ``mode`` = ``GMT_DATA_ONLY``, passing your ``wesn`` array and the grid @@ -1684,11 +1684,11 @@ to ``family`` so that the module knows what to do. Finally, in the case of pass ``data`` as NULL you may also control what type of matrix or vector will be created in GMT for the output by adding in the modifiers GMT_VIA_type, as listed in :ref:`types `. **Note**: GMT tries to minimize data duplication if possible, so if your input arrays are -compatible with the data type used by the modules then we may use your array directly. -This *may* have the side-effect that your input array is modified by the module. -If you want to prevent this from happening then add GMT_IS_DUPLICATE to the ``direction`` -argument and we will duplicate the array internally to make sure your input is truly -read-only. +compatible with the data type used by the modules then we could use your array directly. +This *may* have the side-effect that your input array is modified by the module, especially +if the module writes the results to a netCDF grid file. +If that is a price you are willing to pay then you can add GMT_IS_REFERENCE to the ``direction`` +argument and we will pass the array internally to avoid duplicating memory. Import from a virtual file ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/gmt_api.c b/src/gmt_api.c index cf015795903..14e582d31d9 100644 --- a/src/gmt_api.c +++ b/src/gmt_api.c @@ -1907,7 +1907,7 @@ GMT_LOCAL int gmtapi_init_grdheader (struct GMT_CTRL *GMT, unsigned int directio if (registration & GMT_GRID_DEFAULT_REG) registration |= GMT->common.R.registration; /* Set the default registration */ registration = (registration & 1); /* Knock off any GMT_GRID_DEFAULT_REG bit */ - if (dim && wesn == NULL && inc == NULL) { /* Gave dimension instead, set range and inc (1/1) while considering registration */ + if (dim && (wesn == NULL || (gmt_M_is_zero (wesn[XLO]) && gmt_M_is_zero (wesn[XHI]) && gmt_M_is_zero (wesn[YLO]) && gmt_M_is_zero (wesn[YHI]))) && (inc == NULL || (gmt_M_is_zero (inc[GMT_X]) && gmt_M_is_zero (inc[GMT_Y])))) { /* Gave dimension instead, set range and inc (1/1) while considering registration */ gmt_M_memset (wesn_dup, 4, double); wesn_dup[XHI] = (double)(dim[GMT_X]); wesn_dup[YHI] = (double)(dim[GMT_Y]); @@ -5112,6 +5112,7 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj } method = gmtapi_set_method (S_obj); /* Get the actual method to use since may be MATRIX or VECTOR masquerading as GRID */ switch (method) { + /* Status: This case is fully tested and operational */ case GMT_IS_FILE: /* Name of a grid file on disk */ if (gmt_file_is_tiled_list (API, S_obj->filename, NULL, NULL, NULL)) { /* Special list file */ if (grid == NULL) { /* Only allocate grid struct when not already allocated */ @@ -5180,16 +5181,13 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj if ((G_orig = S_obj->resource) == NULL) return_null (API, GMT_PTR_IS_NULL); if (grid == NULL) { /* Only allocate when not already allocated */ if (mode & GMT_DATA_ONLY) return_null (API, GMT_NO_GRDHEADER); /* For mode & GMT_DATA_ONLY grid must already be allocated */ - if ((G_obj = GMT_Duplicate_Data (API, GMT_IS_GRID, mode, G_orig)) == NULL) + if ((G_obj = GMT_Duplicate_Data (API, GMT_IS_GRID, GMT_DUPLICATE_NONE, G_orig)) == NULL) return_null (API, GMT_MEMORY_ERROR); } else G_obj = grid; /* We are passing in a grid already */ done = (mode & GMT_CONTAINER_ONLY) ? false : true; /* Not done until we read grid */ - if (! (mode & GMT_DATA_ONLY)) { /* Must init header and copy the header information from the existing grid */ - gmt_copy_gridheader (GMT, G_obj->header, G_orig->header); - if (mode & GMT_CONTAINER_ONLY) break; /* Just needed the header, get out of here */ - } + if (mode & GMT_CONTAINER_ONLY) break; /* Just needed the header, get out of here */ /* Here we will read grid data. */ /* To get a subset we use wesn that is not NULL or contain 0/0/0/0. * Otherwise we use everything passed in */ @@ -5236,7 +5234,7 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj return_null (API, GMT_GRID_BC_ERROR); /* Set boundary conditions */ break; - case GMT_IS_REFERENCE: /* GMT grid and header in a GMT_GRID container object by reference [NOT SURE ABOUT THIS]*/ + case GMT_IS_REFERENCE: /* GMT grid and header in a GMT_GRID container object by reference [NOT SURE ABOUT THIS] */ if (S_obj->region) return_null (API, GMT_SUBSET_NOT_ALLOWED); GMT_Report (API, GMT_MSG_INFORMATION, "Referencing grid data from GMT_GRID memory location\n"); if ((G_obj = S_obj->resource) == NULL) return_null (API, GMT_PTR_IS_NULL); @@ -5265,10 +5263,10 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj GMT_Report (API, GMT_MSG_DEBUG, "gmtapi_import_grid: Return from GMT_IS_REFERENCE\n"); break; - case GMT_IS_DUPLICATE|GMT_VIA_MATRIX: /* The user's 2-D grid array of some sort, + info in the args */ + /* Status: This case is fully tested and operational */ + case GMT_IS_DUPLICATE|GMT_VIA_MATRIX: /* The user's 2-D grid array of some sort, + info in the matrix header */ /* Must create a grid container from matrix info S_obj->resource and hence a new object is required */ 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); if (grid == NULL) { /* Only allocate when not already allocated */ uint64_t dim[3] = {M_obj->n_columns, M_obj->n_rows, 1}; if ((G_obj = GMT_Create_Data (API, GMT_IS_GRID, GMT_IS_SURFACE, mode, dim, M_obj->range, M_obj->inc, M_obj->registration, GMT_NOTSET, NULL)) == NULL) @@ -5286,17 +5284,18 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj G_obj->header->complex_mode = mode; /* Set the complex mode */ GH->alloc_mode = GMT_ALLOC_INTERNALLY; done = (mode & GMT_CONTAINER_ONLY) ? false : true; /* Not done until we read grid */ - if (! (mode & GMT_DATA_ONLY)) { + 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 set the zmin/max range since unknown per header */ - HH = gmt_get_H_hidden (G_obj->header); - GMT_2D_to_index = gmtapi_get_2d_to_index (API, M_obj->shape, GMT_GRID_IS_REAL); - 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 */ - if ((api_get_val = gmtapi_select_get_function (API, M_obj->type)) == NULL) - return_null (API, GMT_NOT_A_VALID_TYPE); + /* Must get the full zmin/max range since not provided by the matrix header */ 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); @@ -5307,19 +5306,48 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj G_obj->header->z_max = MAX (G_obj->header->z_max, (gmt_grdfloat)d); } } - break; + break; /* Done for now */ } } - /* Must convert to new array. Here the header is fully filled */ - GMT_Report (API, GMT_MSG_INFORMATION, "Importing grid data from user memory location\n"); - G_obj->data = gmt_M_memory_aligned (GMT, NULL, G_obj->header->size, gmt_grdfloat); - 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); - 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); - G_obj->data[ij] = (gmt_grdfloat)d; + + 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 */ + 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); + i0 = (unsigned int)gmt_M_grd_x_to_col (GMT, S_obj->wesn[XLO]+dx, G_obj->header); + i1 = (unsigned int)gmt_M_grd_x_to_col (GMT, S_obj->wesn[XHI]-dx, G_obj->header); + 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 (col = i0; col <= i1; col++, ij++) { + ij_orig = GMT_2D_to_index (row, col, M_obj->dim); /* Position of this (row,col) in input matrix organization */ + ij = gmt_M_ijp (G_obj->header, row, col); /* 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)) + 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); + } + } } 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")) @@ -5332,14 +5360,14 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj 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); + //if (S_obj->region) return_null (API, GMT_SUBSET_NOT_ALLOWED); /* 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 && MH->alloc_mode == GMT_ALLOC_EXTERNALLY && (mode & GMT_GRID_IS_COMPLEX_MASK) == 0)) return_null (API, GMT_NOT_A_VALID_IO_ACCESS); - if (grid == NULL) { /* Only allocate when not already allocated */ + if (grid == NULL) { /* Only allocate when not already allocated. Note cannot have pad since input matrix wont have one */ uint64_t dim[3] = {M_obj->n_rows, M_obj->n_columns, 1}; - if ((G_obj = GMT_Create_Data (API, GMT_IS_GRID, GMT_IS_SURFACE, mode, dim, M_obj->range, M_obj->inc, M_obj->registration, GMT_NOTSET, NULL)) == NULL) + if ((G_obj = GMT_Create_Data (API, GMT_IS_GRID, GMT_IS_SURFACE, mode, dim, M_obj->range, M_obj->inc, M_obj->registration, 0, NULL)) == NULL) return_null (API, GMT_MEMORY_ERROR); } else @@ -5387,16 +5415,14 @@ GMT_LOCAL struct GMT_GRID * gmtapi_import_grid (struct GMTAPI_CTRL *API, int obj 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 0 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 = G_obj->header->reset_pad = 0; + S_obj->reset_pad = 0; } if (gmtlib_expand_headerpad (GMT, G_obj->header, S_obj->wesn, S_obj->orig_pad, S_obj->orig_wesn)) - S_obj->reset_pad = G_obj->header->reset_pad = 1; + S_obj->reset_pad = 1; } -#endif break; default: @@ -6252,7 +6278,7 @@ void gmtlib_garbage_collection (struct GMTAPI_CTRL *API, int level) { if (!(level == GMT_NOTSET || S_obj->alloc_level == u_level)) { /* Not the right module level (or not end of session yet) */ if (S_obj->reset_pad && S_obj->no_longer_owner == false) { /* Temporarily changed pad to access a sub-region of a memory grid - now reset this if still the owner */ address = S_obj->resource; /* Try to get the data object */ - gmtlib_contract_pad (API->GMT, address, S_obj->family, S_obj->orig_pad, S_obj->orig_wesn); + gmtlib_contract_pad (API->GMT, address, S_obj->actual_family, S_obj->orig_pad, S_obj->orig_wesn); S_obj->reset_pad = 0; } i++; continue; @@ -7321,15 +7347,11 @@ GMT_LOCAL unsigned int gmtapi_separate_families (unsigned int *family) { return actual_family; } -GMT_LOCAL void gmtapi_maybe_change_method_to_duplicate (struct GMTAPI_CTRL *API, struct GMTAPI_DATA_OBJECT *S_obj, bool readonly) { - /* We want to pass a matrix from the outside as a grid. If it is a float matrix then should be possible to pass - * as is but the test below changes REF to DUPLICATE. Without this we crash. Need to either explain why it cannot - * work that way or make changes. As it stands, it seems all REF methods are converted to DUPLICATE. PW 6/6/2018 */ - if (readonly) { /* We must duplicate this resource */ - S_obj->method = GMT_IS_DUPLICATE; - GMT_Report (API, GMT_MSG_INFORMATION, "GMT_Open_VirtualFile: Switch method to GMT_IS_DUPLICATE per input flag\n"); - } - else if (S_obj->actual_family == GMT_IS_MATRIX && S_obj->family == GMT_IS_GRID && !gmtapi_matrix_data_conforms_to_grid (S_obj->resource)) { +GMT_LOCAL void gmtapi_maybe_change_method_to_duplicate (struct GMTAPI_CTRL *API, struct GMTAPI_DATA_OBJECT *S_obj) { + /* We want to pass a matrix or set of vectors from the outside as a grid or as a dataset. + * grid: If it is a float matrix in row-order layout then we can, else we must duplicate + * dataset: If matrix or vector are in columns and they are all doubles then we can, else we must duplicate */ + if (S_obj->actual_family == GMT_IS_MATRIX && S_obj->family == GMT_IS_GRID && !gmtapi_matrix_data_conforms_to_grid (S_obj->resource)) { S_obj->method = GMT_IS_DUPLICATE; /* Must duplicate this resource */ GMT_Report (API, GMT_MSG_INFORMATION, "GMT_Open_VirtualFile: Switch method to GMT_IS_DUPLICATE as input matrix is not compatible with a GMT gmt_grdfloat grid\n"); } @@ -7357,7 +7379,7 @@ int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometr * beforehand or it is NULL and we create an expanding output resource. * name is the name given to the virtual file and is returned. */ int object_ID = GMT_NOTSET, item_s = 0; - unsigned int item, orig_family, actual_family = 0, via_type = 0, messenger = 0, module_input; + unsigned int item, orig_family, actual_family = 0, via_type = 0, messenger = 0, module_input, the_mode = GMT_IS_DUPLICATE; bool readonly = false; struct GMTAPI_DATA_OBJECT *S_obj = NULL; struct GMTAPI_CTRL *API = NULL; @@ -7367,6 +7389,7 @@ int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometr if (direction & GMT_IS_REFERENCE) { /* Treat this memory as read-only */ readonly = true; direction -= GMT_IS_REFERENCE; + the_mode = GMT_IS_REFERENCE; if (direction == GMT_OUT) { GMT_Report (API, GMT_MSG_ERROR, "GMT_Open_VirtualFile: GMT_IS_REFERENCE can only be added for inputs, not output files\n"); return_error (V_API, GMT_NOT_A_VALID_DIRECTION); @@ -7402,7 +7425,7 @@ int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometr if (direction == GMT_IN) { /* Set things up for reading */ /* See if this one is known to us already */ if (object_ID == GMT_NOTSET) { /* Register data as a new object for reading [GMT_IN] and reset its status to unread */ - if ((object_ID = GMT_Register_IO (API, family, GMT_IS_REFERENCE|GMT_IO_RESET, geometry, GMT_IN, NULL, data)) == GMT_NOTSET) + if ((object_ID = GMT_Register_IO (API, family, the_mode|GMT_IO_RESET, geometry, GMT_IN, NULL, data)) == GMT_NOTSET) return (API->error); if ((item_s = gmtapi_get_item (API, family, data)) == GMT_NOTSET) { /* Not found in list */ return_error (API, GMT_OBJECT_NOT_FOUND); /* Could not find that item in the array despite finding its ID? */ @@ -7413,16 +7436,16 @@ int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometr if (S_obj->family != family || S_obj->actual_family != actual_family) return_error (API, GMT_WRONG_FAMILY); /* Mixup between what was created and what was passed in */ S_obj->status = 0; /* Open for business */ - S_obj->method = GMT_IS_REFERENCE; /* Now a memory resource */ + S_obj->method = the_mode; /* Now a memory resource */ S_obj->direction = GMT_IN; /* Make sure it now is flagged for reading */ } - /* If the input a container masquerading as another then we may have to replace method GMT_IS_REFERENCE by GMT_IS_DUPLICATE */ - gmtapi_maybe_change_method_to_duplicate (API, S_obj, readonly); + /* If the input a container masquerading as another then we may have to replace method GMT_IS_REFERENCE by GMT_IS_DUPLICATE if REFERENCE was specified */ + if (S_obj->method == GMT_IS_REFERENCE) gmtapi_maybe_change_method_to_duplicate (API, S_obj); } else { /* Set things up for writing */ if (data) { /* Was provided an object to use */ if (object_ID == GMT_NOTSET) { /* Register a new object for writing [GMT_OUT] and reset its status to unread */ - if ((object_ID = GMT_Register_IO (API, orig_family, GMT_IS_REFERENCE|GMT_IO_RESET, geometry, GMT_OUT, NULL, data)) == GMT_NOTSET) + if ((object_ID = GMT_Register_IO (API, orig_family, the_mode|GMT_IO_RESET, geometry, GMT_OUT, NULL, data)) == GMT_NOTSET) return (API->error); if ((item_s = gmtapi_get_item (API, family, data)) == GMT_NOTSET) { /* Not found in list */ return_error (API, GMT_OBJECT_NOT_FOUND); /* Could not find that item in the array despite finding its ID? */ @@ -7430,9 +7453,9 @@ int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometr S_obj = API->object[item_s]; /* Short-hand for later */ } else { /* Here we have the item and can recycle the address */ - S_obj->status = 0; /* Open for business */ - S_obj->method = GMT_IS_REFERENCE; /* Now a memory resource */ - S_obj->direction = GMT_OUT; /* Make sure it now is flagged for writing */ + S_obj->status = 0; /* Open for business */ + S_obj->method = the_mode; /* Now a memory resource */ + S_obj->direction = GMT_OUT; /* Make sure it now is flagged for writing */ } } else { /* New expanding output resource */ @@ -7449,12 +7472,14 @@ int GMT_Open_VirtualFile (void *V_API, unsigned int family, unsigned int geometr } S_obj = API->object[item_s]; /* Short-hand for later */ S_obj->type = (via_type) ? via_type - 1 : API->GMT->current.setting.export_type; /* Remember what output type we want */ - S_obj->method = GMT_IS_REFERENCE; /* Now a memory resource */ + S_obj->method = the_mode; /* Now a memory resource */ messenger = 1; } - /* If the output is a matrix masquerading as grid then it must be GMT_FLOAT, otherwise change to DUPLICATE */ - gmtapi_maybe_change_method_to_duplicate (API, S_obj, readonly); + /* If the output is a matrix masquerading as grid then it must be GMT_FLOAT, otherwise change to DUPLICATE if REFERENCE was specified */ + if (S_obj->method == GMT_IS_REFERENCE) gmtapi_maybe_change_method_to_duplicate (API, S_obj); } + S_obj->region = false; /* No subset of anything is being considered here */ + gmt_M_memset (S_obj->wesn, 4, double); /* Obtain the unique VirtualFile name */ if (gmtapi_encode_id (API, module_input, direction, family, actual_family, geometry, messenger, object_ID, name) != GMT_NOERROR) return (API->error); @@ -7568,7 +7593,8 @@ int GMT_Init_VirtualFile_ (unsigned int mode, char *string, int len) { GMT_LOCAL bool gmtapi_is_passable (struct GMTAPI_DATA_OBJECT *S_obj, unsigned int family) { if (family != (unsigned int)S_obj->actual_family) return false; /* Cannot deal with masquerading containers */ - if (S_obj->resource == NULL) return false; /* Certaintly cannot pass this guy */ + if (S_obj->resource == NULL) return false; /* Certainly cannot pass this guy */ + if (S_obj->method != GMT_IS_REFERENCE) return false; /* Only references can be passed */ if (S_obj->family == GMT_IS_GRID) { struct GMT_GRID *G = gmtapi_get_grid_data (S_obj->resource); return (G->data == NULL) ? false : true; @@ -7665,6 +7691,7 @@ void * GMT_Read_Data (void *V_API, unsigned int family, unsigned int method, uns return_null (API, API->error); } gmt_M_memcpy (API->object[item]->wesn, wesn, 4, double); + API->object[item]->region = true; } } else if (input) { /* Case 1: Load from a single input, given source. Register it first. */ @@ -8350,6 +8377,7 @@ GMT_LOCAL void gmtapi_get_record_init (struct GMTAPI_CTRL *API) { if (API->current_get_V->text == NULL) GMT->current.io.record.text = NULL; break; + case GMT_IS_DUPLICATE: /* Only for datasets */ case GMT_IS_REFERENCE: /* Only for datasets */ API->current_get_D_set = gmtapi_get_dataset_data (S->resource); /* Get the right dataset */ API->current_get_n_columns = (GMT->common.i.select) ? GMT->common.i.n_cols : API->current_get_D_set->n_columns; diff --git a/src/gmt_init.c b/src/gmt_init.c index ba7dce7ff0b..657610b18a3 100644 --- a/src/gmt_init.c +++ b/src/gmt_init.c @@ -876,7 +876,7 @@ GMT_LOCAL int gmtinit_rectR_to_geoR (struct GMT_CTRL *GMT, char unit, double rec /* Set up machinery to call mapproject */ /* Register In as input virtual file and define an output virtual file */ - if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, In, in_string) == GMT_NOTSET) + if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, In, in_string) == GMT_NOTSET) return (GMT->parent->error); if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_OUT, NULL, out_string) == GMT_NOTSET) return (GMT->parent->error); diff --git a/src/gmt_io.c b/src/gmt_io.c index 659daed3f75..3f8e306fa17 100644 --- a/src/gmt_io.c +++ b/src/gmt_io.c @@ -2835,7 +2835,7 @@ GMT_LOCAL int gmtio_prep_ogr_output (struct GMT_CTRL *GMT, struct GMT_DATASET *D /* Determine w/e/s/n via GMT_gmtinfo */ - if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, D, in_string) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, D, in_string) == GMT_NOTSET) { return (GMT->parent->error); } if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_OUT, NULL, out_string) == GMT_NOTSET) { diff --git a/src/gmtlogo.c b/src/gmtlogo.c index 8b2ee1c2922..e2d746871f5 100644 --- a/src/gmtlogo.c +++ b/src/gmtlogo.c @@ -423,7 +423,7 @@ EXTERN_MSC int GMT_gmtlogo (void *V_API, int mode, void *args) { if ((M = GMT_Create_Data (API, GMT_IS_DATASET|GMT_VIA_MATRIX, GMT_IS_POLY, GMT_CONTAINER_ONLY, par, NULL, NULL, 0, GMT_IS_ROW_FORMAT, NULL)) == NULL) exit (EXIT_FAILURE); GMT_Put_Matrix (API, M, GMT_FLOAT, 0, gmt_letters); /* Hook in our static float matrix */ - GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_MATRIX, GMT_IS_POLY, GMT_IN, M, file); /* Open matrix for reading */ + GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_MATRIX, GMT_IS_POLY, GMT_IN|GMT_IS_REFERENCE, M, file); /* Open matrix for reading */ sprintf (cmd, "-<%s -R167/527/-90/90 -JI-13/%gi -O -K -G%s@40 --GMT_HISTORY=false", file, scale * 1.55, c_gmt_shadow); GMT_Report (API, GMT_MSG_INFORMATION, "Calling psxy with args %s\n", cmd); diff --git a/src/grd2kml.c b/src/grd2kml.c index 5a235053422..1151111260a 100644 --- a/src/grd2kml.c +++ b/src/grd2kml.c @@ -739,7 +739,7 @@ EXTERN_MSC int GMT_grd2kml (void *V_API, int mode, void *args) { gmt_M_str_free (S->text[c]); /* Free previous string */ S->text[c] = strdup (line); /* Update string */ } - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_NONE, GMT_IN, C, contour_file) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_NONE, GMT_IN|GMT_IS_REFERENCE, C, contour_file) != GMT_NOERROR) { GMT_Report (API, GMT_MSG_ERROR, "Unable to create virtual file for contours\n"); gmt_M_free (GMT, Q); GMT_Destroy_Data (API, &C); @@ -848,7 +848,7 @@ EXTERN_MSC int GMT_grd2kml (void *V_API, int mode, void *args) { if (use_tile) { /* Found data inside this tile, make plot and rasterize (if PostScript) */ char z_data[GMT_VF_LEN] = {""}, psfile[PATH_MAX] = {""}; /* Open the grid subset as a virtual file we can pass to grdimage */ - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, T, z_data) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, T, z_data) == GMT_NOTSET) { GMT_Report (API, GMT_MSG_ERROR, "Unable to open grid tile as virtual file!\n"); gmt_M_free (GMT, Q); if (Ctrl->W.active) GMT_Destroy_Data (API, &C); diff --git a/src/grdfill.c b/src/grdfill.c index 3af51f60e86..9addeb2fa11 100644 --- a/src/grdfill.c +++ b/src/grdfill.c @@ -248,7 +248,7 @@ GMT_LOCAL int grdfill_do_splinefill (struct GMTAPI_CTRL *API, struct GMT_GRID *G GMT_Put_Vector (API, V, GMT_Y, GMT_DOUBLE, y); GMT_Put_Vector (API, V, GMT_Z, GMT_FLOAT, z); /* Associate our input data vectors with a virtual input file */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN, V, input) == GMT_NOTSET) + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, V, input) == GMT_NOTSET) return (API->error); /* Prepare the greenspline command-line arguments */ mode = (gmt_M_is_geographic (GMT, GMT_IN)) ? 2 : 1; diff --git a/src/grdfilter.c b/src/grdfilter.c index 19aaf6aa1f0..5bd5621567e 100644 --- a/src/grdfilter.c +++ b/src/grdfilter.c @@ -1339,7 +1339,7 @@ EXTERN_MSC int GMT_grdfilter (void *V_API, int mode, void *args) { /* Here we low-passed filtered onto a coarse grid but to get high-pass we must sample the low-pass result at the original resolution */ /* Create a virtual file for the low-pass filtered grid */ - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Gout, in_string) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Gout, in_string) == GMT_NOTSET) { Return (API->error); } /* Create a virtual file to hold the resampled grid */ diff --git a/src/grdfilter_mt.c b/src/grdfilter_mt.c index 48eda37909c..75be181111f 100644 --- a/src/grdfilter_mt.c +++ b/src/grdfilter_mt.c @@ -1010,7 +1010,7 @@ int GMT_grdfilter_mt (void *V_API, int mode, void *args) char in_string[GMT_VF_LEN], out_string[GMT_VF_LEN], cmd[GMT_LEN256]; /* Here we low-passed filtered onto a coarse grid but to get high-pass we must sample the low-pass result at the original resolution */ /* Create a virtual file for the low-pass filtered grid */ - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Gout, in_string) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Gout, in_string) == GMT_NOTSET) { Return (API->error); } /* Create a virtual file to hold the resampled grid */ diff --git a/src/grdimage.c b/src/grdimage.c index 5ad4855c6ad..0d754974b4a 100644 --- a/src/grdimage.c +++ b/src/grdimage.c @@ -672,7 +672,7 @@ EXTERN_MSC int GMT_grdimage (void *V_API, int mode, void *args) { //if ((Grid_orig[0] = GMT_Read_Data (API, GMT_IS_GRID, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_AND_DATA, GMT->common.R.wesn, Ctrl->In.file[0], NULL)) == NULL) /* Get srtm grid data */ if ((Grid_orig[0] = GMT_Read_Data (API, GMT_IS_GRID, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_AND_DATA, API->tile_wesn, Ctrl->In.file[0], NULL)) == NULL) /* Get srtm grid data */ Return (API->error); - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Grid_orig[0], data_grd)) + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Grid_orig[0], data_grd)) Return (API->error); got_data_grid = true; } @@ -917,7 +917,7 @@ EXTERN_MSC int GMT_grdimage (void *V_API, int mode, void *args) { char in_string[GMT_VF_LEN] = {""}, out_string[GMT_VF_LEN] = {""}; /* Associate the intensity grid with an open virtual file - in_string will then hold the name of this input "file" */ - GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Intens_orig, in_string); + GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Intens_orig, in_string); /* Create a virtual file to hold the resampled grid - out_string then holds the name of this output "file" */ GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_OUT, NULL, out_string); /* Create the command to do the resampling via the grdsample module */ diff --git a/src/grdinterpolate.c b/src/grdinterpolate.c index 1a63af862e8..909590c8aae 100644 --- a/src/grdinterpolate.c +++ b/src/grdinterpolate.c @@ -527,7 +527,7 @@ EXTERN_MSC int GMT_grdinterpolate (void *V_API, int mode, void *args) { GMT_Report (API, GMT_MSG_ERROR, "Unable to create output dataset for time-series\n"); Return (API->error); } - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, In, i_file) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, In, i_file) != GMT_NOERROR) { GMT_Report (API, GMT_MSG_ERROR, "Unable to create virtual dataset for time-series\n"); Return (API->error); } @@ -597,7 +597,7 @@ EXTERN_MSC int GMT_grdinterpolate (void *V_API, int mode, void *args) { gmt_set_column (GMT, GMT_OUT, col, level_type); /* This is the grid-level data type which on output is in this column */ if (Ctrl->T.active) { /* Want to interpolate through the sampled points using the specified spline */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN, Out, i_file) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN|GMT_IS_REFERENCE, Out, i_file) != GMT_NOERROR) { GMT_Report (API, GMT_MSG_ERROR, "Unable to create virtual dataset for sampled time-series\n"); Return (API->error); } diff --git a/src/grdview.c b/src/grdview.c index 5f7d3ba9feb..9b81b15dcbf 100644 --- a/src/grdview.c +++ b/src/grdview.c @@ -870,7 +870,7 @@ EXTERN_MSC int GMT_grdview (void *V_API, int mode, void *args) { if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_OUT, NULL, int_grd)) Return (API->error); if (Topo->data) { /* If not NULL it means we have a tiled and blended grid, use as is */ - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Topo, data_file)) + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Topo, data_file)) Return (API->error); } else diff --git a/src/img/img2grd.c b/src/img/img2grd.c index 26b7e31f9e7..05d2bd0a32b 100644 --- a/src/img/img2grd.c +++ b/src/img/img2grd.c @@ -773,7 +773,7 @@ EXTERN_MSC int GMT_img2grd (void *V_API, int mode, void *args) { /* Preparing source and destination for GMT_grdproject */ /* a. Register the Mercator grid to be the source read by GMT_grdproject by passing a pointer */ GMT_Report (API, GMT_MSG_DEBUG, "Open Mercator Grid as grdproject virtual input\n"); - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Merc, input) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Merc, input) != GMT_NOERROR) { Return (API->error); } /* b. If -E: Register a grid struct Geo to be the destination allocated and written to by GMT_grdproject, else write to -G */ @@ -815,7 +815,7 @@ EXTERN_MSC int GMT_img2grd (void *V_API, int mode, void *args) { sprintf (Geo->header->x_units, "longitude [degrees_east]"); sprintf (Geo->header->y_units, "latitude [degrees_north]"); GMT_Report (API, GMT_MSG_DEBUG, "Open Geo Grid container as grdsample virtual input\n"); - if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, Geo, input) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, Geo, input) != GMT_NOERROR) { Return (API->error); } sprintf (cmd, "-R%g/%g/%g/%g -I%gm %s -G%s -fg --GMT_HISTORY=false", west, east, south, north, Ctrl->I.value, input, Ctrl->G.file); diff --git a/src/pslegend.c b/src/pslegend.c index a192089e6d7..deb82ce7073 100644 --- a/src/pslegend.c +++ b/src/pslegend.c @@ -1730,7 +1730,7 @@ EXTERN_MSC int GMT_pslegend (void *V_API, int mode, void *args) { if (D[FRONT]) { /* Create option list, register D[FRONT] as input source */ D[FRONT]->table[0]->n_segments = n_fronts; /* Set correct number of fronts */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN, D[FRONT], string) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN|GMT_IS_REFERENCE, D[FRONT], string) != GMT_NOERROR) { Return (API->error); } sprintf (buffer, "-R0/%g/0/%g -Jx1i -O -K -N -Sf0.1i %s --GMT_HISTORY=false", GMT->current.proj.rect[XHI], GMT->current.proj.rect[YHI], string); @@ -1753,7 +1753,7 @@ EXTERN_MSC int GMT_pslegend (void *V_API, int mode, void *args) { if (D[QLINE]) { /* Create option list, register D[QLINE] as input source */ D[QLINE]->table[0]->n_segments = n_quoted_lines; /* Set correct number of lines */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN, D[QLINE], string) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN|GMT_IS_REFERENCE, D[QLINE], string) != GMT_NOERROR) { Return (API->error); } sprintf (buffer, "-R0/%g/0/%g -Jx1i -O -K -N -Sqn1 %s --GMT_HISTORY=false", GMT->current.proj.rect[XHI], GMT->current.proj.rect[YHI], string); @@ -1776,7 +1776,7 @@ EXTERN_MSC int GMT_pslegend (void *V_API, int mode, void *args) { if (D[SYM]) { D[SYM]->table[0]->n_segments = n_symbols; /* Set correct number of segments */ /* Create option list, register D[SYM] as input source */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, D[SYM], string) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, D[SYM], string) != GMT_NOERROR) { Return (API->error); } /* Because the sizes internally are in inches we must tell plot that inch is the current length unit */ @@ -1800,7 +1800,7 @@ EXTERN_MSC int GMT_pslegend (void *V_API, int mode, void *args) { if (D[TXT]) { D[TXT]->table[0]->segment[0]->n_rows = D[TXT]->n_records = krow[TXT]; /* Create option list, register D[TXT] as input source */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_NONE, GMT_IN, D[TXT], string) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_NONE, GMT_IN|GMT_IS_REFERENCE, D[TXT], string) != GMT_NOERROR) { Return (API->error); } sprintf (buffer, "-R0/%g/0/%g -Jx1i -O -K -N -F+f+j %s --GMT_HISTORY=false", GMT->current.proj.rect[XHI], GMT->current.proj.rect[YHI], string); @@ -1829,7 +1829,7 @@ EXTERN_MSC int GMT_pslegend (void *V_API, int mode, void *args) { } /* Create option list, register D[PAR] as input source */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_TEXT, GMT_IN, D[PAR], string) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_TEXT, GMT_IN|GMT_IS_REFERENCE, D[PAR], string) != GMT_NOERROR) { Return (API->error); } sprintf (buffer, "-R0/%g/0/%g -Jx1i -O -K -N -M -F+a+f+j %s --GMT_HISTORY=false", GMT->current.proj.rect[XHI], GMT->current.proj.rect[YHI], string); diff --git a/src/psternary.c b/src/psternary.c index 30775f9e8c9..34a9fc715d2 100644 --- a/src/psternary.c +++ b/src/psternary.c @@ -524,7 +524,7 @@ EXTERN_MSC int GMT_psternary (void *V_API, int mode, void *args) { } if (Ctrl->S.active) { /* Plot symbols */ char vfile[GMT_VF_LEN] = {""}; - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, D, vfile) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, D, vfile) == GMT_NOTSET) { GMT_Report (API, GMT_MSG_ERROR, "Unable to create a virtual data set\n"); Return (API->error); } diff --git a/src/psxy.c b/src/psxy.c index 8968758bb06..54741fa73f8 100644 --- a/src/psxy.c +++ b/src/psxy.c @@ -296,7 +296,7 @@ GMT_LOCAL int psxy_plot_decorations (struct GMT_CTRL *GMT, struct GMT_DATASET *D return GMT_NOERROR; /* Here we have symbols. Open up virtual file for the call to psxy */ - if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN, D, string) != GMT_NOERROR) + if (GMT_Open_VirtualFile (GMT->parent, GMT_IS_DATASET, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, D, string) != GMT_NOERROR) return (GMT->parent->error); if (decorate_custom) { /* Must find the custom symbol */ if ((type = gmt_locate_custom_symbol (GMT, &symbol_code[1], name, path, &pos)) == 0) return (GMT_RUNTIME_ERROR); diff --git a/src/subplot.c b/src/subplot.c index 8edad90283f..7d3a5277b74 100644 --- a/src/subplot.c +++ b/src/subplot.c @@ -1204,7 +1204,7 @@ EXTERN_MSC int GMT_subplot (void *V_API, int mode, void *args) { T->table[0]->segment[0]->text[0] = strdup (Ctrl->T.title); T->table[0]->segment[0]->n_rows = 1; T->n_records = T->table[0]->n_records = T->table[0]->segment[0]->n_rows = 1; - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_NONE, GMT_IN, T, vfile) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_NONE, GMT_IN|GMT_IS_REFERENCE, T, vfile) != GMT_NOERROR) { Return (API->error); } sprintf (command, "-R0/%g/0/%g -Jx1i -N -F+jBC+f%s %s -X%c%gi -Y%c%gi --GMT_HISTORY=false", @@ -1232,7 +1232,7 @@ EXTERN_MSC int GMT_subplot (void *V_API, int mode, void *args) { Return (API->error); } if (Ctrl->F.Lpen[0]) { /* Draw lines between interior tiles */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN, L, vfile) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_LINE, GMT_IN|GMT_IS_REFERENCE, L, vfile) != GMT_NOERROR) { Return (API->error); } sprintf (command, "-R0/%g/0/%g -Jx1i -W%s %s --GMT_HISTORY=false", Ctrl->F.dim[GMT_X] + GMT->current.setting.map_origin[GMT_X], Ctrl->F.dim[GMT_Y] + GMT->current.setting.map_origin[GMT_Y], Ctrl->F.Lpen, vfile); @@ -1357,7 +1357,7 @@ EXTERN_MSC int GMT_subplot (void *V_API, int mode, void *args) { if ((D = GMT_Read_Data (API, GMT_IS_DATASET, GMT_IS_FILE, GMT_IS_POLY, 0, NULL, file, NULL)) == NULL) { Return (API->error); } - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POLY, GMT_IN, D, vfile) != GMT_NOERROR) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET, GMT_IS_POLY, GMT_IN|GMT_IS_REFERENCE, D, vfile) != GMT_NOERROR) { Return (API->error); } sprintf (command, "-R%s -Jx1i %s -L -Wfaint,red -Xa0i -Ya0i --GMT_HISTORY=false", D->table[0]->header[0], vfile); diff --git a/src/surface.c b/src/surface.c index c89b1c04fdc..46fd066306b 100644 --- a/src/surface.c +++ b/src/surface.c @@ -2100,7 +2100,7 @@ EXTERN_MSC int GMT_surface (void *V_API, int mode, void *args) { GMT_Put_Vector (API, V, GMT_X, GMT_DOUBLE, data[GMT_X]); GMT_Put_Vector (API, V, GMT_Y, GMT_DOUBLE, data[GMT_Y]); /* Create a virtual file for reading the input data grid */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN, V, input) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, V, input) == GMT_NOTSET) { Return (API->error); } /* Create a virtual file to hold the mask grid */ diff --git a/src/surface_experimental.c b/src/surface_experimental.c index 5d2415e02c8..5c3915198e4 100644 --- a/src/surface_experimental.c +++ b/src/surface_experimental.c @@ -2450,7 +2450,7 @@ int GMT_surface_mt (void *V_API, int mode, void *args) { GMT_Put_Vector (API, V, GMT_X, GMT_DOUBLE, data[GMT_X]); GMT_Put_Vector (API, V, GMT_Y, GMT_DOUBLE, data[GMT_Y]); /* Create a virtual file for reading the input data grid */ - if (GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN, V, input) == GMT_NOTSET) { + if (GMT_Open_VirtualFile (API, GMT_IS_DATASET|GMT_VIA_VECTOR, GMT_IS_POINT, GMT_IN|GMT_IS_REFERENCE, V, input) == GMT_NOTSET) { Return (API->error); } /* Create a virtual file to hold the mask grid */ diff --git a/src/testapi_matrix_as_grid.c b/src/testapi_matrix_as_grid.c index 28201a06083..8194734e3a6 100644 --- a/src/testapi_matrix_as_grid.c +++ b/src/testapi_matrix_as_grid.c @@ -14,14 +14,14 @@ int main () { struct GMTAPI_CTRL *API = NULL; double inc[2] = {1.0, 1.0}; - double coord[9] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; + float coord[9] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; /* Use floats to match what grids are */ API = GMT_Create_Session ("test", 2U, mode, NULL); /* pass matrix as gridline-registered grid */ double range_g[4] = {0.0, 2.0, 0.0, 2.0}; if ((M_g = GMT_Create_Data (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_CONTAINER_ONLY, NULL, range_g, inc, GMT_GRID_NODE_REG, 0, NULL)) == NULL) return (EXIT_FAILURE); - GMT_Put_Matrix (API, M_g, GMT_DOUBLE, 0, coord); + GMT_Put_Matrix (API, M_g, GMT_FLOAT, 0, coord); GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, M_g, input_g); /* call grdinfo to make sure it doesn't crash * See https://github.com/GenericMappingTools/gmt/pull/3514 */ @@ -30,12 +30,11 @@ int main () { /* call grdimage */ sprintf (args_g, "%s -R-1/3/-1/3 -JX6c -Baf -BWSen+tGridline -K -P > api_matrix_as_grid.ps", input_g); GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args_g); - GMT_Close_VirtualFile (API, input_g); /* pass matrix as pixel-registered grid */ double range_p[4] = {-0.5, 2.5, -0.5, 2.5}; if ((M_p = GMT_Create_Data (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_CONTAINER_ONLY, NULL, range_p, inc, GMT_GRID_PIXEL_REG, 0, NULL)) == NULL) return (EXIT_FAILURE); - GMT_Put_Matrix (API, M_p, GMT_DOUBLE, 0, coord); + GMT_Put_Matrix (API, M_p, GMT_FLOAT, 0, coord); GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, M_p, input_p); /* call grdinfo to make sure it doesn't crash * See https://github.com/GenericMappingTools/gmt/pull/3514 */ @@ -46,6 +45,10 @@ int main () { GMT_Call_Module (API, "grdimage", GMT_MODULE_CMD, args_p); GMT_Close_VirtualFile (API, input_p); + sprintf (args_g, "%s -R0/1/0/1 -Goutput.nc", input_g); + GMT_Call_Module (API, "grdcut", GMT_MODULE_CMD, args_g); + GMT_Close_VirtualFile (API, input_g); + if (GMT_Destroy_Session (API)) return EXIT_FAILURE; exit (0); } diff --git a/src/testapi_usergrid.c b/src/testapi_usergrid.c index 4bcac41ad08..4b4aed1647e 100644 --- a/src/testapi_usergrid.c +++ b/src/testapi_usergrid.c @@ -199,6 +199,8 @@ int deploy_test (unsigned int intype, unsigned int outtype, int alloc_in_GMT, in if (V) mode += (6 << 16); /* Activate -Vd */ in_data = get_array (intype, 1); /* Create dummy user grid in_data[] = k */ + if (intype == GMT_FLOAT) + bad = 0; /* Initialize a GMT session */ API = GMT_Create_Session ("test", 2U, mode, NULL); @@ -211,8 +213,8 @@ int deploy_test (unsigned int intype, unsigned int outtype, int alloc_in_GMT, in } /* Hook the user input array up to this container */ GMT_Put_Matrix (API, M[GMT_IN], intype, 0, in_data); - /* Associate our matrix container with a virtual grid file to "read" from */ - GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN|GMT_IS_REFERENCE, M[GMT_IN], input); + /* Associate our matrix container with a virtual grid file to "read" from via duplication */ + GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, GMT_IS_SURFACE, GMT_IN, M[GMT_IN], input); if (alloc_in_GMT) /* Request matrix container for output data to be allocated by GMT */ GMT_Open_VirtualFile (API, GMT_IS_GRID|GMT_VIA_MATRIX, out_via, GMT_OUT, NULL, output); else { /* Preallocate array space here in the app */ diff --git a/test/grdfilter/highpass.ps b/test/grdfilter/highpass.ps index d53e47b083e..8ea0de93c96 100644 Binary files a/test/grdfilter/highpass.ps and b/test/grdfilter/highpass.ps differ diff --git a/test/img/imgmap.ps b/test/img/imgmap.ps index e2ff3821290..ad5cc9c88e3 100644 Binary files a/test/img/imgmap.ps and b/test/img/imgmap.ps differ