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

Add option to grdpaste to only report the "pasting" side. #7368

Merged
merged 1 commit into from Apr 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/rst/source/grdpaste.rst
Expand Up @@ -14,6 +14,7 @@ Synopsis

**gmt grdpaste** *file_a.nc file_b.nc*
|-G|\ *outfile.nc*
[ |-S| ]
[ |SYN_OPT-V| ]
[ |SYN_OPT-f| ]
[ |SYN_OPT--| ]
Expand Down Expand Up @@ -48,6 +49,13 @@ Required Arguments
Optional Arguments
------------------

.. _-S:

**-S**
Just prints a code number and a description of the sides at which the grids are pasted.
No pasting actually happens. -G is ignored. This option is useful for externals that want to
reimplement the grdpaste utility since it doesn't work form them (*e.g.* Julia and GMTMEX).

.. |Add_-V| replace:: |Add_-V_links|
.. include:: explain_-V.rst_
:start-after: **Syntax**
Expand Down
45 changes: 42 additions & 3 deletions src/grdpaste.c
Expand Up @@ -30,7 +30,7 @@
#define THIS_MODULE_MODERN_NAME "grdpaste"
#define THIS_MODULE_LIB "core"
#define THIS_MODULE_PURPOSE "Join two grids along their common edge"
#define THIS_MODULE_KEYS "<G{2,GG}"
#define THIS_MODULE_KEYS "<G{2,GG},>DS"
#define THIS_MODULE_NEEDS ""
#define THIS_MODULE_OPTIONS "-Vf"

Expand All @@ -43,6 +43,9 @@ struct GRDPASTE_CTRL {
bool active;
char *file;
} G;
struct GRDPASTE_S { /* -S */
bool active;
} S;
};

static void *New_Ctrl (struct GMT_CTRL *GMT) { /* Allocate and initialize a new control structure */
Expand All @@ -66,7 +69,7 @@ static void Free_Ctrl (struct GMT_CTRL *GMT, struct GRDPASTE_CTRL *C) { /* Deall
static int usage (struct GMTAPI_CTRL *API, int level) {
const char *name = gmt_show_name_and_purpose (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_PURPOSE);
if (level == GMT_MODULE_PURPOSE) return (GMT_NOERROR);
GMT_Usage (API, 0, "usage: %s <grid1> <grid2> -G%s [%s] [%s] [%s]\n", name, GMT_OUTGRID, GMT_V_OPT, GMT_f_OPT, GMT_PAR_OPT);
GMT_Usage (API, 0, "usage: %s <grid1> <grid2> -G%s [-S] [%s] [%s] [%s]\n", name, GMT_OUTGRID, GMT_V_OPT, GMT_f_OPT, GMT_PAR_OPT);

if (level == GMT_SYNOPSIS) return (GMT_MODULE_SYNOPSIS);

Expand All @@ -78,6 +81,9 @@ static int usage (struct GMTAPI_CTRL *API, int level) {
"If grids are geographic and adds to full 360-degree range then <grid1> "
"determines west. Use grdedit -S to rotate grid to another -Rw/e/s/n.");
gmt_outgrid_syntax (API, 'G', "Set name of the output grid file");
GMT_Usage (API, 1, "\n-S");
GMT_Usage (API, -2, "Just prints a code number and a description of the sides at which the grids are pasted. "
"No pasting actually happens. -G is ignored.");
if (gmt_M_showusage (API)) GMT_Message (API, GMT_TIME_NONE, "\n OPTIONAL ARGUMENTS:\n");
GMT_Option (API, "V,f,.");

Expand Down Expand Up @@ -116,14 +122,19 @@ static int parse (struct GMT_CTRL *GMT, struct GRDPASTE_CTRL *Ctrl, struct GMT_O
n_errors += gmt_get_required_file (GMT, opt->arg, opt->option, 0, GMT_IS_GRID, GMT_OUT, GMT_FILE_LOCAL, &(Ctrl->G.file));
break;

case 'S': /* Print the code number that tells on what side grid B glues to A and return. */
n_errors += gmt_M_repeated_module_option (API, Ctrl->S.active);
break;

default: /* Report bad options */
n_errors += gmt_default_option_error (GMT, opt);
break;
}
}

n_errors += gmt_M_check_condition (GMT, !Ctrl->In.file[0] || !Ctrl->In.file[1], "Must specify two input files\n");
n_errors += gmt_M_check_condition (GMT, !Ctrl->G.file, "Option -G: Must specify output file\n");
if (!Ctrl->S.active)
n_errors += gmt_M_check_condition (GMT, !Ctrl->G.file, "Option -G: Must specify output file\n");

return (n_errors ? GMT_PARSE_ERROR : GMT_NOERROR);
}
Expand Down Expand Up @@ -335,6 +346,34 @@ EXTERN_MSC int GMT_grdpaste (void *V_API, int mode, void *args) {
GMT_Report (API, GMT_MSG_INFORMATION, format, Ctrl->G.file, C->header->wesn[XLO], C->header->wesn[XHI], C->header->wesn[YLO], C->header->wesn[YHI], C->header->inc[GMT_X], C->header->inc[GMT_Y], C->header->n_columns, C->header->n_rows);
}

/* This option is mostly for GMT.jl usage because grdpaste doesn't work for externals passing grid objs. */
if (Ctrl->S.active) {
char t[70];
double out[1];
struct GMT_RECORD *Out = NULL;
if (GMT_Init_IO (API, GMT_IS_DATASET, GMT_IS_PLP, GMT_OUT, GMT_ADD_DEFAULT, 0, options) != GMT_NOERROR) { /* Establishes data output */
Return (API->error);
}
if (GMT_Begin_IO (API, GMT_IS_DATASET, GMT_OUT, GMT_HEADER_OFF) != GMT_NOERROR) {
Return (API->error);
}
if ((error = GMT_Set_Columns (API, GMT_OUT, 1, GMT_COL_FIX_NO_TEXT)) != GMT_NOERROR) Return (error);
GMT->current.io.col_type[GMT_OUT][0] = GMT_IS_FLOAT;
(way == 1) ? strcpy(t, "B is on top of A") : (way == 10) ? strcpy(t, "B is on top of A but their grid reg limits underlap by one cell") : (way == 11) ? strcpy(t, "B is on top of A but their pixel reg limits overlap by one cell") :
(way == 2) ? strcpy(t, "A is on top of B") : (way == 20) ? strcpy(t, "A is on top of B but their grid reg limits underlap by one cell") : (way == 21) ? strcpy(t, "A is on top of B but their pixel reg limits overlap by one cell") :
(way == 3) ? strcpy(t, "A is on the right of B") : (way == 30) ? strcpy(t, "A is on right of B but their grid reg limits underlap by one cell") : (way == 31) ? strcpy(t, "A is on right of B but their pixel reg limits overlap by one cell") :
(way == 4) ? strcpy(t, "A is on the left of B") : (way == 40) ? strcpy(t, "A is on left of B but their grid reg limits underlap by one cell") : (way == 41) ? strcpy(t, "A is on left of B but their pixel reg limits overlap by one cell") : "";
Out = gmt_new_record (GMT, out, t);
out[0] = (double)way;
GMT_Put_Record (API, GMT_WRITE_DATA, Out);
if (GMT_End_IO (API, GMT_OUT, 0) != GMT_NOERROR) { /* Disables further data output */
Return (API->error);
}
gmt_set_pad (GMT, API->pad); /* Restore to GMT Defaults */
gmt_M_free (GMT, Out);
Return (GMT_NOERROR);
}

gmt_set_grddim (GMT, C->header);
if (GMT_Create_Data (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_DATA_ONLY, NULL, NULL,
NULL, 0, 0, C) == NULL) Return (API->error); /* Note: 0 for pad since no BC work needed */
Expand Down