49#if defined(linux) || (defined(_WIN32) && !defined(_MINGW))
52void omp_set_num_threads(
int a) {}
65char *option[N_OPTIONS] = {
74static char *USAGE =
"\nUsage:\n" \
75 " sddsinsideboundaries [<inputfile>] [<outputfile>] [-pipe=[input][,output]]\n" \
76 " -columns=<x-name>,<y-name>\n" \
77 " Specify the names of the (x, y) columns in the input file.\n" \
78 " -boundary=<filename>,<x-name>,<y-name>\n" \
79 " Provide a file with boundary data, including x and y columns.\n" \
80 " The file can have multiple pages.\n" \
81 " -insideColumn=<column_name>\n" \
82 " Specify the name of the output column for the count of boundaries\n" \
83 " containing each point (default: InsideSum).\n" \
84 " -keep={inside|outside}\n" \
86 " inside - Keep only points inside any boundary.\n" \
87 " outside - Keep only points outside all boundaries.\n" \
88 " By default, all points are kept.\n" \
89 " -threads=<number>\n" \
90 " Set the number of threads for computation (default: 1).\n\n" \
91 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
100char *keepOption[N_KEEP_OPTIONS] = {
106long compute_inside_sum(
double x,
double y,
double **xBoundary,
double **yBoundary, int64_t *nValues,
long nBoundaries);
107long read_boundary_data(
char *boundaryInput,
char *bxColumn,
char *byColumn,
double ***xBoundary,
double ***yBoundary, int64_t **nValues);
109double *xData, *yData;
110double **xBoundary = NULL, **yBoundary = NULL;
111int64_t *nValues = NULL, rows;
114int32_t *insideSumData;
116int main(
int argc,
char **argv) {
118 SCANNED_ARG *scanned = NULL;
119 char *input = NULL, *output = NULL, *boundaryInput = NULL;
120 char *xColumn = NULL, *yColumn = NULL, *bxColumn = NULL, *byColumn = NULL;
121 char *insideColumn =
"InsideSum";
124 long keepCode = KEEP_ALL;
125 long readCode, keepSeen = 0;
127 unsigned long pipeFlags = 0;
130 argc =
scanargs(&scanned, argc, argv);
134 for (iArg = 1; iArg < argc; iArg++) {
135 if (scanned[iArg].arg_type == OPTION) {
137 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
139 if (xColumn || yColumn)
140 SDDS_Bomb(
"only one -columns option may be given");
141 if (scanned[iArg].n_items != 3)
143 xColumn = scanned[iArg].list[1];
144 yColumn = scanned[iArg].list[2];
148 SDDS_Bomb(
"only one -boundary option may be given");
149 if (scanned[iArg].n_items != 4)
151 boundaryInput = scanned[iArg].list[1];
152 bxColumn = scanned[iArg].list[2];
153 byColumn = scanned[iArg].list[3];
155 case SET_INSIDE_COLUMN:
156 if (scanned[iArg].n_items != 2)
157 SDDS_Bomb(
"invalid -insideColumn syntax");
158 insideColumn = scanned[iArg].list[1];
162 SDDS_Bomb(
"only one -keep option may be given");
163 if (scanned[iArg].n_items != 2)
165 if ((keepCode =
match_string(scanned[iArg].list[1], keepOption, N_KEEP_OPTIONS, 0)) < 0)
166 SDDS_Bomb(
"invalid -keep value. Supply 'all', 'inside', or 'outside' or a unique abbreviation");
169 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
173 if (scanned[iArg].n_items != 2 ||
174 sscanf(scanned[iArg].list[1],
"%d", &threads) != 1 || threads < 1)
178 fprintf(stderr,
"error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
184 input = scanned[iArg].list[0];
186 output = scanned[iArg].list[0];
192 processFilenames(
"sddsinsideboundaries", &input, &output, pipeFlags, 0, NULL);
193 if (!pipeFlags && strcmp(input, output) == 0)
194 SDDS_Bomb(
"can't use same file for input and output");
196 if (!boundaryInput || !bxColumn || !byColumn)
197 SDDS_Bomb(
"-boundaries option must be given");
198 if ((nBoundaries = read_boundary_data(boundaryInput, bxColumn, byColumn, &xBoundary, &yBoundary, &nValues)) <= 0)
199 SDDS_Bomb(
"No valid data in boundary data file");
206 SDDS_Bomb(
"-xColumn is not present or not numeric");
208 SDDS_Bomb(
"-yColumn is not present or not numeric");
216 insideSumData = NULL;
218 xData = yData = NULL;
219 omp_set_num_threads(threads);
230 insideSumData = calloc(rows,
sizeof(*insideSumData));
231 keep = calloc(rows,
sizeof(*keep));
233#pragma omp parallel for
234 for (i = 0; i < rows; i++) {
235 insideSumData[i] = compute_inside_sum(xData[i], yData[i], xBoundary, yBoundary, nValues, nBoundaries);
238 keep[i] = insideSumData[i];
241 keep[i] = insideSumData[i] == 0;
248 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, insideSumData, rows, insideColumn) ||
262long read_boundary_data(
char *boundaryInput,
char *bxColumn,
char *byColumn,
double ***xBoundary,
double ***yBoundary, int64_t **nValues) {
272 if (SDDS_RowCount(&SDDSin) == 0)
274 *xBoundary =
SDDS_Realloc(*xBoundary,
sizeof(**xBoundary) * (nSets + 1));
275 *yBoundary =
SDDS_Realloc(*yBoundary,
sizeof(**yBoundary) * (nSets + 1));
276 *nValues =
SDDS_Realloc(*nValues,
sizeof(**nValues) * (nSets + 1));
277 (*nValues)[nSets] = SDDS_RowCount(&SDDSin);
286long compute_inside_sum(
double x,
double y,
double **xBoundary,
double **yBoundary, int64_t *nValues,
long nBoundaries) {
289 for (ib = 0; ib < nBoundaries; ib++)
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int pointIsInsideContour(double x0, double y0, double *x, double *y, int64_t n, double *center, double theta)
Determine if a given point (x0, y0) is inside a specified polygonal contour.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)