Skip to content
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

Increase information encoded in virtual file names #2861

Merged
merged 9 commits into from
Mar 8, 2020
6 changes: 3 additions & 3 deletions doc/rst/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,8 @@ this program:
void *API; /* The API control structure */
struct GMT_DATASET *D = NULL; /* Structure to hold input dataset */
struct GMT_GRID *G = NULL; /* Structure to hold output grid */
char input[GMT_STR16] = {""}; /* String to hold virtual input filename */
char output[GMT_STR16] = {""}; /* String to hold virtual output filename */
char input[GMT_VF_LEN] = {""}; /* String to hold virtual input filename */
char output[GMT_VF_LEN] = {""}; /* String to hold virtual output filename */
char args[128] = {""}; /* String to hold module command arguments */

/* Initialize the GMT session */
Expand Down Expand Up @@ -1644,7 +1644,7 @@ The full syntax is
unsigned int direction, void *data, char *filename);

Here, ``data`` is the pointer to your memory object. The function returns the
desired filename via ``filename``. This string must be at least ``GMT_STR16`` bytes (16).
desired filename via ``filename``. This string must be at least ``GMT_VF_LEN`` bytes (16).
The other arguments have been discussed earlier. Specifically for direction, use
GMT_IN for reading and GMT_OUT for writing. Simply pass this filename in
the calling sequence to the module you want to use to indicate which file should
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ endif (DO_EXAMPLES OR DO_TESTS AND NOT DCW_FOUND)

if (DO_API_TESTS)
# These lines are temporarily here for the beta release - comment to avoid in the build
set (GMT_DEMOS_SRCS testapi.c testpsl.c testgmt.c testgmtshell.c testgmtio.c testgrdio.c testio.c
set (GMT_DEMOS_SRCS testpsl.c testgmtshell.c testgmtio.c testgrdio.c
testapiconv.c example1.c testapi_matrix.c testapi_matrix_plot.c testapi_vector.c test_JL.c testapi_mixmatrix.c
test_walter.c testapi_usergrid.c testapi_userdataset.c testapi_uservectors.c)
endif (DO_API_TESTS)
Expand Down
36 changes: 27 additions & 9 deletions src/blockmean.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,12 @@ GMT_LOCAL int parse (struct GMT_CTRL *GMT, struct BLOCKMEAN_CTRL *Ctrl, struct G

int GMT_blockmean (void *V_API, int mode, void *args) {
uint64_t node, n_cells_filled, n_read, n_lost, n_pitched, w_col, *np = NULL;
unsigned int row, col, n_input, k, NF = 0, fcol[BLK_N_FIELDS] = {2,3,4,5,6,0,0,0}, field[BLK_N_FIELDS];
unsigned int row, col, n_input, k, kk, NF = 0, fcol[BLK_N_FIELDS] = {2,3,4,5,6,0,0,0}, field[BLK_N_FIELDS];
int error;
bool use_xy, use_weight, duplicate_col;
bool use_xy, use_weight, duplicate_col, bail = false;
double weight, weight_s2 = 0, weight_pos, weighted_z, iw, half_dx, wesn[4], out[7], *in = NULL;
char format[GMT_LEN512] = {""}, *fcode[BLK_N_FIELDS] = {"z", "s", "l", "h", "w", "", "", ""}, *code[BLK_N_FIELDS];
char file[PATH_MAX] = {""};

struct GMT_OPTION *options = NULL;
struct GMT_GRID *Grid = NULL, *G = NULL, *GridOut[BLK_N_FIELDS];
Expand Down Expand Up @@ -451,22 +452,27 @@ int GMT_blockmean (void *V_API, int mode, void *args) {

if (n_read == 0) { /* Blank/empty input files */
GMT_Report (API, GMT_MSG_WARNING, "No data records found; no output produced\n");
Return (GMT_NOERROR);
if (!(API->external && Ctrl->G.active))
bail = true;
}
if (n_pitched == 0) { /* No points inside region */
else if (n_pitched == 0) { /* No points inside region */
GMT_Report (API, GMT_MSG_WARNING, "No data points found inside the region; no output produced\n");
if (!(API->external && Ctrl->G.active))
bail = true;
}

if (bail) { /* Time to quit */
Return (GMT_NOERROR);
}

w_col = gmt_get_cols (GMT, GMT_OUT) - 1; /* Index of weight column (the last output column) */
n_cells_filled = 0; /* Number of blocks with values */
fcol[4] = (unsigned int)w_col; /* Since we don't know what it is until parsed */
GMT_Report (API, GMT_MSG_INFORMATION, "Calculating block means\n");

if (Ctrl->G.active) { /* Create the grid(s) */
char *remarks[BLK_N_FIELDS] = {"Mean value per bin", "Standard deviation per bin", "Lowest value per bin",
"Highest value per bin", "Weight per bin"};
for (k = 0; k < BLK_N_FIELDS; k++) {
for (k = kk = 0; k < BLK_N_FIELDS; k++) {
if (!Ctrl->A.selected[k]) continue;
field[NF] = fcol[k]; /* Just keep record of which fields we are actually using */
code[NF] = fcode[k];
Expand All @@ -477,9 +483,22 @@ int GMT_blockmean (void *V_API, int mode, void *args) {
if (GMT_Set_Comment (API, GMT_IS_GRID, GMT_COMMENT_IS_REMARK, remarks[k], GridOut[NF])) Return (API->error);
if (G == NULL) G = GridOut[NF]; /* First grid header used to get node later */
for (node = 0; node < G->header->size; node++)
GridOut[NF]->data[node] = GMT->session.f_NaN;
GridOut[NF]->data[node] = GMT->session.f_NaN; /* Initialize with NaNs */
if (API->external && n_read == 0) { /* Write the empty grids back to the external caller */
if (strstr (Ctrl->G.file[kk], "%s"))
sprintf (file, Ctrl->G.file[kk], code[k]);
else
strncpy (file, Ctrl->G.file[kk], PATH_MAX-1);
if (GMT_Write_Data (API, GMT_IS_GRID, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_AND_DATA, NULL, file, GridOut[k]) != GMT_NOERROR) {
Return (API->error);
}
}
if (Ctrl->G.n > 1) kk++; /* Only true for APIs */
NF++; /* Number of actual field grids */
}
if (API->external && n_read == 0) { /* Delayed return */
Return (GMT_NOERROR);
}
}
else { /* Get ready for rec-by-rec output */
if (GMT->common.h.add_colnames) { /* Create meaningful column header */
Expand All @@ -503,6 +522,7 @@ int GMT_blockmean (void *V_API, int mode, void *args) {
}
}

GMT_Report (API, GMT_MSG_INFORMATION, "Calculating block means\n");
Out = gmt_new_record (GMT, out, NULL); /* Since we only need to worry about numerics in this module */

for (node = 0; node < Grid->header->size; node++) { /* Visit all possible blocks to see if they were visited */
Expand Down Expand Up @@ -558,8 +578,6 @@ int GMT_blockmean (void *V_API, int mode, void *args) {
GMT_Put_Record (API, GMT_WRITE_DATA, Out); /* Write this to output */
}
if (Ctrl->G.active) { /* Writes the grid(s) */
unsigned int kk;
char file[PATH_MAX] = {""};
for (k = kk = 0; k < NF; k++) {
if (strstr (Ctrl->G.file[kk], "%s"))
sprintf (file, Ctrl->G.file[kk], code[k]);
Expand Down
33 changes: 26 additions & 7 deletions src/blockmedian.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,15 @@ GMT_LOCAL void median_output (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *h, u

int GMT_blockmedian (void *V_API, int mode, void *args) {
int error = 0;
bool do_extra = false, duplicate_col;
bool do_extra = false, duplicate_col, bail = false;
uint64_t n_lost, node, first_in_cell, first_in_new_cell;
uint64_t n_read, nz, n_pitched, n_cells_filled, w_col, i_col = 0, sid_col;
size_t n_alloc = 0, nz_alloc = 0;
unsigned int row, col, emode = 0, n_input, n_output, n_quantiles = 1, go_quickly = 0;
unsigned int k, NF = 0, fcol[BLK_N_FIELDS] = {2,3,4,5,6,7,0,0}, field[BLK_N_FIELDS];
unsigned int k, kk, NF = 0, fcol[BLK_N_FIELDS] = {2,3,4,5,6,7,0,0}, field[BLK_N_FIELDS];
double out[8], wesn[4], quantile[3] = {0.25, 0.5, 0.75}, extra[8], weight, half_dx, *in = NULL, *z_tmp = NULL;
char format[GMT_LEN512] = {""}, *old_format = NULL, *fcode[BLK_N_FIELDS] = {"z", "s", "l", "q25", "q75", "h", "w", ""}, *code[BLK_N_FIELDS];
char file[PATH_MAX] = {""};

struct GMT_OPTION *options = NULL;
struct GMT_GRID *Grid = NULL, *G = NULL, *GridOut[BLK_N_FIELDS];
Expand Down Expand Up @@ -527,10 +528,15 @@ int GMT_blockmedian (void *V_API, int mode, void *args) {

if (n_read == 0) { /* Blank/empty input files */
GMT_Report (API, GMT_MSG_WARNING, "No data records found; no output produced\n");
Return (GMT_NOERROR);
if (!(API->external && Ctrl->G.active))
bail = true;
}
if (n_pitched == 0) { /* No points inside region */
else if (n_pitched == 0) { /* No points inside region */
GMT_Report (API, GMT_MSG_WARNING, "No data points found inside the region; no output produced\n");
if (!(API->external && Ctrl->G.active))
bail = true;
}
if (bail) { /* Time to quit */
Return (GMT_NOERROR);
}

Expand All @@ -545,7 +551,7 @@ int GMT_blockmedian (void *V_API, int mode, void *args) {

if (Ctrl->G.active) { /* Create the grid(s) */
char *remarks[BLK_N_FIELDS] = {"Median value per bin", "L1 scale per bin", "Lowest value per bin", "25% quartile", "75% quartile", "Highest value per bin", "Weight per bin"};
for (k = NF = 0; k < BLK_N_FIELDS; k++) {
for (k = kk = 0; k < BLK_N_FIELDS; k++) {
if (!Ctrl->A.selected[k]) continue;
field[NF] = fcol[k]; /* Just keep record of which fields we are actually using */
code[NF] = fcode[k];
Expand All @@ -557,8 +563,21 @@ int GMT_blockmedian (void *V_API, int mode, void *args) {
if (G == NULL) G = GridOut[NF]; /* First grid header used to get node later */
for (node = 0; node < G->header->size; node++)
GridOut[NF]->data[node] = GMT->session.f_NaN;
if (API->external && n_read == 0) { /* Write the empty grids back to the external caller */
if (strstr (Ctrl->G.file[kk], "%s"))
sprintf (file, Ctrl->G.file[kk], code[k]);
else
strncpy (file, Ctrl->G.file[kk], PATH_MAX-1);
if (GMT_Write_Data (API, GMT_IS_GRID, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_AND_DATA, NULL, file, GridOut[k]) != GMT_NOERROR) {
Return (API->error);
}
}
if (Ctrl->G.n > 1) kk++; /* Only true for APIs */
NF++; /* Number of actual field grids */
}
if (API->external && n_read == 0) { /* Delayed return */
Return (GMT_NOERROR);
}
}
else { /* Get ready for rec-by-rec output */
if (GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_ON) != GMT_NOERROR) { /* Enables data output and sets access mode */
Expand All @@ -571,6 +590,8 @@ int GMT_blockmedian (void *V_API, int mode, void *args) {
}
}

GMT_Report (API, GMT_MSG_INFORMATION, "Calculating block medians\n");

if (emode) { /* Index column last, with weight col just before */
i_col = w_col--;
old_format = GMT->current.io.o_format[i_col]; /* Need to restore this at end */
Expand Down Expand Up @@ -648,8 +669,6 @@ int GMT_blockmedian (void *V_API, int mode, void *args) {
if (do_extra) gmt_M_free (GMT, z_tmp);

if (Ctrl->G.active) { /* Writes the grid(s) */
unsigned int kk;
char file[PATH_MAX] = {""};
for (k = kk = 0; k < NF; k++) {
if (strstr (Ctrl->G.file[kk], "%s"))
sprintf (file, Ctrl->G.file[kk], code[k]);
Expand Down
40 changes: 31 additions & 9 deletions src/blockmode.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,12 +483,12 @@ GMT_LOCAL double weighted_mode (struct BLK_DATA *d, double wsum, unsigned int em
#define Return(code) {GMT_Destroy_Data (API, &Grid); gmt_M_free (GMT, Out); gmt_M_free (GMT, data); Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); bailout (code);}

int GMT_blockmode (void *V_API, int mode, void *args) {
bool mode_xy, do_extra = false, is_integer, duplicate_col;
bool mode_xy, do_extra = false, is_integer, duplicate_col, bail = false;

int way, error = 0;

unsigned int row, col, emode = 0, n_input, n_output;
unsigned int k, NF = 0, fcol[BLK_N_FIELDS] = {2,3,4,5,6,7,0,0}, field[BLK_N_FIELDS];
unsigned int k, kk, NF = 0, fcol[BLK_N_FIELDS] = {2,3,4,5,6,7,0,0}, field[BLK_N_FIELDS];

uint64_t node, first_in_cell, first_in_new_cell, n_lost, n_read;
uint64_t n_cells_filled, n_in_cell, nz, n_pitched, src_id = 0;
Expand All @@ -500,6 +500,7 @@ int GMT_blockmode (void *V_API, int mode, void *args) {
double z_min = DBL_MAX, z_max = -DBL_MAX;

char format[GMT_LEN512] = {""}, *old_format = NULL, *fcode[BLK_N_FIELDS] = {"z", "s", "l", "h", "w", "", "", ""}, *code[BLK_N_FIELDS];
char file[PATH_MAX] = {""};

struct GMT_OPTION *options = NULL;
struct GMT_GRID *Grid = NULL, *G = NULL, *GridOut[BLK_N_FIELDS];
Expand Down Expand Up @@ -650,17 +651,23 @@ int GMT_blockmode (void *V_API, int mode, void *args) {
Return (API->error);
}

if (Ctrl->D.active && Ctrl->D.width == 0.0 && !is_integer) {
GMT_Report (API, GMT_MSG_ERROR, "Option -D: No bin width specified and data are not integers\n");
Return (GMT_PARSE_ERROR);
}

if (n_read == 0) { /* Blank/empty input files */
GMT_Report (API, GMT_MSG_WARNING, "No data records found; no output produced\n");
Return (GMT_NOERROR);
if (!(API->external && Ctrl->G.active))
bail = true;
}
if (n_pitched == 0) { /* No points inside region */
else if (n_pitched == 0) { /* No points inside region */
GMT_Report (API, GMT_MSG_WARNING, "No data points found inside the region; no output produced\n");
Return (GMT_NOERROR);
if (!(API->external && Ctrl->G.active))
bail = true;
}
if (Ctrl->D.active && Ctrl->D.width == 0.0 && !is_integer) {
GMT_Report (API, GMT_MSG_ERROR, "Option -D: No bin width specified and data are not integers\n");
Return (GMT_PARSE_ERROR);
if (bail) { /* Time to quit */
Return (GMT_NOERROR);
}
if (n_pitched < n_alloc) {
n_alloc = n_pitched;
Expand All @@ -673,7 +680,7 @@ int GMT_blockmode (void *V_API, int mode, void *args) {

if (Ctrl->G.active) { /* Create the grid(s) */
char *remarks[BLK_N_FIELDS] = {"Median value per bin", "L1 scale per bin", "Lowest value per bin", "Highest value per bin", "Weight per bin"};
for (k = 0; k < BLK_N_FIELDS; k++) {
for (k = kk = 0; k < BLK_N_FIELDS; k++) {
if (!Ctrl->A.selected[k]) continue;
field[NF] = fcol[k]; /* Just keep record of which fields we are actually using */
code[NF] = fcode[k];
Expand All @@ -685,8 +692,21 @@ int GMT_blockmode (void *V_API, int mode, void *args) {
if (G == NULL) G = GridOut[NF]; /* First grid header used to get node later */
for (node = 0; node < G->header->size; node++)
GridOut[NF]->data[node] = GMT->session.f_NaN;
if (API->external && n_read == 0) { /* Write the empty grids back to the external caller */
if (strstr (Ctrl->G.file[kk], "%s"))
sprintf (file, Ctrl->G.file[kk], code[k]);
else
strncpy (file, Ctrl->G.file[kk], PATH_MAX-1);
if (GMT_Write_Data (API, GMT_IS_GRID, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_AND_DATA, NULL, file, GridOut[k]) != GMT_NOERROR) {
Return (API->error);
}
}
if (Ctrl->G.n > 1) kk++; /* Only true for APIs */
NF++; /* Number of actual field grids */
}
if (API->external && n_read == 0) { /* Delayed return */
Return (GMT_NOERROR);
}
}
else { /* Get ready for rec-by-rec output */
if (GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_ON) != GMT_NOERROR) { /* Enables data output and sets access mode */
Expand All @@ -697,6 +717,8 @@ int GMT_blockmode (void *V_API, int mode, void *args) {
}
}

GMT_Report (API, GMT_MSG_INFORMATION, "Calculating block modes\n");

if (emode) { /* Index column last, with weight col just before */
i_col = w_col--;
old_format = GMT->current.io.o_format[i_col]; /* Need to restore this at end */
Expand Down
4 changes: 2 additions & 2 deletions src/example1.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ int main () {
void *API; /* The API control structure */
struct GMT_DATASET *D = NULL; /* Structure to hold input dataset */
struct GMT_GRID *G = NULL; /* Structure to hold output grid */
char input[GMT_STR16] = {""}; /* String to hold virtual input filename */
char output[GMT_STR16] = {""}; /* String to hold virtual output filename */
char input[GMT_VF_LEN] = {""}; /* String to hold virtual input filename */
char output[GMT_VF_LEN] = {""}; /* String to hold virtual output filename */
char args[128] = {""}; /* String to hold module command arguments */

/* Initialize the GMT session */
Expand Down
10 changes: 0 additions & 10 deletions src/gmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,6 @@ EXTERN_MSC int GMT_Extract_Region (void *API, char *file, double wesn[]);
EXTERN_MSC float GMT_Get_Version (void *API, unsigned int *major, unsigned int *minor, unsigned int *patch);
EXTERN_MSC void *GMT_Get_Ctrl (void *API);

/* These 8 functions are provided for backwards compatibility but are considered obsolete as of 6 */
EXTERN_MSC void *GMT_Get_Data (void *API, int object_ID, unsigned int mode, void *data);
EXTERN_MSC int GMT_Put_Data (void *API, int object_ID, unsigned int mode, void *data);
EXTERN_MSC void *GMT_Retrieve_Data (void *API, int object_ID);
EXTERN_MSC int GMT_Encode_ID (void *API, char *string, int object_ID);
EXTERN_MSC int GMT_Get_ID (void *API, unsigned int family, unsigned int direction, void *resource);
EXTERN_MSC int GMT_Get_Value (void *API, const char *arg, double *par);
EXTERN_MSC int GMT_Get_Family (void *API, unsigned int direction, struct GMT_OPTION *head);
EXTERN_MSC int GMT_Status_IO (void *API, unsigned int mode);

#ifdef __cplusplus
}
#endif
Expand Down
Loading