137 {
138 long iArg;
140 SCANNED_ARG *scanned;
141 unsigned long pipeFlags = 0;
142 uint64_t gridPoints = 0, atValues = 0, iv = 0, irow = 0;
143 char *input = NULL, *output = NULL, *fileForValues = NULL;
144 char *findLocationOf[2] = {NULL, NULL}, *gridVariable[2] = {NULL, NULL};
145 double *atValue[2] = {NULL, NULL}, value[2] = {0.0, 0.0};
146 short interpolate = 0, restarted = 0, needPage = 0, presorted = 0, inverse = 0, verbose = 0;
147 unsigned long mode = MODE_ALL;
148
150
151 argc =
scanargs(&scanned, argc, argv);
152 if (argc == 1) {
153 fprintf(stderr, "%s", USAGE);
154 exit(EXIT_FAILURE);
155 }
156
157 for (iArg = 1; iArg < argc; iArg++) {
158 if (scanned[iArg].arg_type == OPTION) {
159
160 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
161 case CLO_FINDLOCATIONOF:
162 if (scanned[iArg].n_items != 3 ||
163 !strlen(findLocationOf[0] = scanned[iArg].list[1]) ||
164 !strlen(findLocationOf[1] = scanned[iArg].list[2])) {
165 SDDS_Bomb(
"Invalid -findLocationOf syntax.\n");
166 }
167 if (strcmp(findLocationOf[0], findLocationOf[1]) == 0) {
168 SDDS_Bomb(
"Invalid -findLocationOf values: two variables are the same.\n");
169 }
170 break;
171 case CLO_GRIDVARIABLES:
172 if (scanned[iArg].n_items != 3 ||
173 !strlen(gridVariable[0] = scanned[iArg].list[1]) ||
174 !strlen(gridVariable[1] = scanned[iArg].list[2])) {
175 SDDS_Bomb(
"Invalid -gridVariables syntax.\n");
176 }
177 if (strcmp(gridVariable[0], gridVariable[1]) == 0) {
178 SDDS_Bomb(
"Invalid -gridVariables values: two variables are the same.\n");
179 }
180 break;
181 case CLO_VALUESFILE:
182 if (scanned[iArg].n_items != 2 ||
183 !strlen(fileForValues = scanned[iArg].list[1])) {
184 SDDS_Bomb(
"Invalid -valuesFile syntax.\n");
185 }
186 if (atValues > 0) {
187 SDDS_Bomb(
"Cannot use -valuesFile and -atValues together.\n");
188 }
189 break;
190 case CLO_ATVALUES:
191 atValue[0] =
SDDS_Realloc(atValue[0],
sizeof(
double) * (atValues + 1));
192 atValue[1] =
SDDS_Realloc(atValue[1],
sizeof(
double) * (atValues + 1));
193 if (scanned[iArg].n_items != 3 ||
194 sscanf(scanned[iArg].list[1], "%le", &atValue[0][atValues]) != 1 ||
195 sscanf(scanned[iArg].list[2], "%le", &atValue[1][atValues]) != 1) {
196 SDDS_Bomb(
"Invalid -atValues syntax.\n");
197 }
198 if (fileForValues) {
199 SDDS_Bomb(
"Cannot use -valuesFile and -atValues together.\n");
200 }
201 atValues++;
202 break;
203 case CLO_PIPE:
204 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
206 }
207 break;
208 case CLO_INTERPOLATE:
210 break;
211 case CLO_PRESORTED:
212 presorted = 1;
213 break;
214 case CLO_MODE:
215 mode = 0;
216 if ((scanned[iArg].n_items -= 1) != 1 ||
217 !
scanItemList(&mode, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
218 "onepairperpage", -1, NULL, 0, MODE_ONEPAIRPERPAGE,
219 "reusefirstpage", -1, NULL, 0, MODE_REUSEFIRSTPAGE,
220 "all", -1, NULL, 0, MODE_ALL,
221 NULL) ||
224 }
225 break;
226 case CLO_INVERSE:
227 inverse = 1;
228 break;
229 case CLO_VERBOSE:
230 verbose = 1;
231 break;
232 default:
233 fprintf(stderr, "Invalid option: %s\n", scanned[iArg].list[0]);
234 fprintf(stderr, "%s", USAGE);
235 exit(EXIT_FAILURE);
236 }
237 } else {
238 if (!input) {
239 input = scanned[iArg].list[0];
240 } else if (!output) {
241 output = scanned[iArg].list[0];
242 } else {
243 SDDS_Bomb(
"Too many filenames provided.\n");
244 }
245 }
246 }
247
248 if (!findLocationOf[0] || !findLocationOf[1]) {
249 SDDS_Bomb(
"Must provide -findLocationOf option.\n");
250 }
251 if (!gridVariable[0] || !gridVariable[1]) {
252 SDDS_Bomb(
"Must provide -gridVariables option.\n");
253 }
254 if (!atValues && !fileForValues) {
255 SDDS_Bomb(
"Must provide either -atValues or -valuesFile option.\n");
256 }
257
259
260 if (fileForValues) {
263 }
265 SDDS_Bomb(
"Unable to read values file.\n");
266 }
267 if ((atValues = SDDS_RowCount(&SDDSvalues)) > 0) {
268 if (verbose)
269 fprintf(stderr, "%" PRIu64 " values in values file\n", atValues);
270 if (inverse) {
272 SDDS_Bomb(
"Unable to retrieve values of first grid variable in values file.\n");
273 }
275 SDDS_Bomb(
"Unable to retrieve values of second grid variable in values file.\n");
276 }
277 } else {
279 SDDS_Bomb(
"Unable to retrieve values of first findLocationOf variable in values file.\n");
280 }
282 SDDS_Bomb(
"Unable to retrieve values of second findLocationOf variable in values file.\n");
283 }
284 }
285 }
287 SDDS_Bomb(
"Values file contains multiple pages, which is not supported.\n");
288 }
291 }
292
295 }
296
306 }
308
309 irow = 0;
310 iv = 0;
311 restarted = 0;
312 while (1) {
313 double location[2];
314 needPage = (irow == 0) ? 1 : 0;
315 if (mode == MODE_ONEPAIRPERPAGE) {
316 if (iv == atValues) {
317 break;
318 }
319 needPage = 1;
320 } else if (mode == MODE_REUSEFIRSTPAGE) {
321 if (iv == atValues) {
322 break;
323 }
324 if (iv == 0) {
325 needPage = 1;
326 }
327 } else if (mode == MODE_ALL) {
328 if (iv == atValues) {
329 needPage = 1;
330 iv = 0;
331 restarted = 1;
332 }
333 }
334
335 if (needPage) {
337 if (!restarted) {
338 SDDS_Bomb(
"Too few pages in input file for number of location requests.\n");
339 }
340 break;
341 }
342 if (gridValue[0]) {
343 free(gridValue[0]);
344 free(gridValue[1]);
345 free(valueAtLocation[0]);
346 free(valueAtLocation[1]);
347 gridValue[0] = gridValue[1] = valueAtLocation[0] = valueAtLocation[1] = NULL;
348 }
349 if ((gridPoints = SDDS_RowCount(&SDDSin)) <= 0) {
350 SDDS_Bomb(
"First page of input file is empty.\n");
351 }
354 SDDS_Bomb(
"Grid variables are missing from input file.\n");
355 }
358 SDDS_Bomb(
"Location variables are missing from input file.\n");
359 }
360
361 gridifyData(gridVariable, gridPoints, presorted);
362 }
363
364 if (inverse) {
365
366 double x0, x1, y0, y1, v1, v2, fx, fy;
367 double x, y;
368 uint64_t ix, iy, ig;
369
370 x = atValue[0][iv];
371 y = atValue[1][iv];
372 ix = findGridInterval(x, 0);
373 iy = findGridInterval(y, 1);
374 x0 = gridValue[0][ix * ng[1]];
375 x1 = gridValue[0][(ix + 1) * ng[1]];
376 y0 = gridValue[1][iy];
377 y1 = gridValue[1][iy + 1];
378 fx = (x - x0) / (x1 - x0);
379 fy = (y - y0) / (y1 - y0);
380
381 ig = ix * ng[1] + iy;
382 v1 = valueAtLocation[0][ig] * (1 - fx) + valueAtLocation[0][ig + ng[1]] * fx;
383 ig = ix * ng[1] + iy + 1;
384 v2 = valueAtLocation[0][ig] * (1 - fx) + valueAtLocation[0][ig + ng[1]] * fx;
385 location[0] = v1 * (1 - fy) + v2 * fy;
386 value[0] = x;
387
388 ig = ix * ng[1] + iy;
389 v1 = valueAtLocation[1][ig] * (1 - fx) + valueAtLocation[1][ig + ng[1]] * fx;
390 ig = ix * ng[1] + iy + 1;
391 v2 = valueAtLocation[1][ig] * (1 - fx) + valueAtLocation[1][ig + ng[1]] * fx;
392 location[1] = v1 * (1 - fy) + v2 * fy;
393 value[1] = y;
395 0, value[0], 1, value[1], 2, location[0], 3, location[1],
396 -1)) {
398 }
399 } else {
400 if (verbose)
401 fprintf(stderr, "Finding location for values (%le, %le)\n", atValue[0][iv], atValue[1][iv]);
402 if (!findLocationInGrid(atValue[0][iv], atValue[1][iv], &location[0], &value[0],
interpolate)) {
403 fprintf(stderr, "Couldn't find location for %s=%.6le, %s=%.6le\n",
404 findLocationOf[0], atValue[0][iv],
405 findLocationOf[1], atValue[1][iv]);
406 exit(EXIT_FAILURE);
407 }
408 if (verbose)
409 fprintf(stderr, "Location is (%le, %le) with values (%le, %le)\n", location[0], location[1], value[0], value[1]);
411 0, location[0], 1, location[1], 2, value[0], 3, value[1],
412 -1)) {
414 }
415 }
416 iv++;
417 }
418
422 }
423 if (gridValue[0]) {
424 free(gridValue[0]);
425 free(gridValue[1]);
426 free(valueAtLocation[0]);
427 free(valueAtLocation[1]);
428 gridValue[0] = gridValue[1] = valueAtLocation[0] = valueAtLocation[1] = NULL;
429 }
430 free(atValue[0]);
431 free(atValue[1]);
433 return EXIT_SUCCESS;
434}
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions from a source dataset to a target dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
long bitsSet(unsigned long data)
Counts the number of set bits (1s) in the given data.
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 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)
void free_scanargs(SCANNED_ARG **scanned, int argc)
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.