135 {
136 long iArg;
138 SCANNED_ARG *scanned;
139 unsigned long pipeFlags;
140 uint64_t gridPoints = 0, atValues = 0, iv = 0, irow = 0;
141 char *input = NULL, *output = NULL, *fileForValues = NULL;
142 char *findLocationOf[2] = {NULL, NULL}, *gridVariable[2] = {NULL, NULL};
143 double *atValue[2] = {NULL, NULL}, value[2] = {0.0, 0.0};
144 short interpolate = 0, restarted = 0, needPage = 0, presorted = 0, inverse = 0;
145 unsigned long mode = MODE_ALL;
146
148
149 argc =
scanargs(&scanned, argc, argv);
150 if (argc == 1) {
151 fprintf(stderr, "%s", USAGE);
152 exit(EXIT_FAILURE);
153 }
154
155 for (iArg = 1; iArg < argc; iArg++) {
156 if (scanned[iArg].arg_type == OPTION) {
157
158 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
159 case CLO_FINDLOCATIONOF:
160 if (scanned[iArg].n_items != 3 ||
161 !strlen(findLocationOf[0] = scanned[iArg].list[1]) ||
162 !strlen(findLocationOf[1] = scanned[iArg].list[2])) {
163 SDDS_Bomb(
"Invalid -findLocationOf syntax.\n");
164 }
165 if (strcmp(findLocationOf[0], findLocationOf[1]) == 0) {
166 SDDS_Bomb(
"Invalid -findLocationOf values: two variables are the same.\n");
167 }
168 break;
169 case CLO_GRIDVARIABLES:
170 if (scanned[iArg].n_items != 3 ||
171 !strlen(gridVariable[0] = scanned[iArg].list[1]) ||
172 !strlen(gridVariable[1] = scanned[iArg].list[2])) {
173 SDDS_Bomb(
"Invalid -gridVariables syntax.\n");
174 }
175 if (strcmp(gridVariable[0], gridVariable[1]) == 0) {
176 SDDS_Bomb(
"Invalid -gridVariables values: two variables are the same.\n");
177 }
178 break;
179 case CLO_VALUESFILE:
180 if (scanned[iArg].n_items != 2 ||
181 !strlen(fileForValues = scanned[iArg].list[1])) {
182 SDDS_Bomb(
"Invalid -valuesFile syntax.\n");
183 }
184 if (atValues > 0) {
185 SDDS_Bomb(
"Cannot use -valuesFile and -atValues together.\n");
186 }
187 break;
188 case CLO_ATVALUES:
189 atValue[0] =
SDDS_Realloc(atValue[0],
sizeof(
double) * (atValues + 1));
190 atValue[1] =
SDDS_Realloc(atValue[1],
sizeof(
double) * (atValues + 1));
191 if (scanned[iArg].n_items != 3 ||
192 sscanf(scanned[iArg].list[1], "%le", &atValue[0][atValues]) != 1 ||
193 sscanf(scanned[iArg].list[2], "%le", &atValue[1][atValues]) != 1) {
194 SDDS_Bomb(
"Invalid -atValues syntax.\n");
195 }
196 if (fileForValues) {
197 SDDS_Bomb(
"Cannot use -valuesFile and -atValues together.\n");
198 }
199 atValues++;
200 break;
201 case CLO_PIPE:
202 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
204 }
205 break;
206 case CLO_INTERPOLATE:
208 break;
209 case CLO_PRESORTED:
210 presorted = 1;
211 break;
212 case CLO_MODE:
213 mode = 0;
214 if ((scanned[iArg].n_items -= 1) != 1 ||
215 !
scanItemList(&mode, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
216 "onepairperpage", -1, NULL, 0, MODE_ONEPAIRPERPAGE,
217 "reusefirstpage", -1, NULL, 0, MODE_REUSEFIRSTPAGE,
218 "all", -1, NULL, 0, MODE_ALL,
219 NULL) ||
222 }
223 break;
224 case CLO_INVERSE:
225 inverse = 1;
226 break;
227 default:
228 fprintf(stderr, "Invalid option: %s\n", scanned[iArg].list[0]);
229 fprintf(stderr, "%s", USAGE);
230 exit(EXIT_FAILURE);
231 }
232 } else {
233 if (!input) {
234 input = scanned[iArg].list[0];
235 } else if (!output) {
236 output = scanned[iArg].list[0];
237 } else {
238 SDDS_Bomb(
"Too many filenames provided.\n");
239 }
240 }
241 }
242
243 if (!findLocationOf[0] || !findLocationOf[1]) {
244 SDDS_Bomb(
"Must provide -findLocationOf option.\n");
245 }
246 if (!gridVariable[0] || !gridVariable[1]) {
247 SDDS_Bomb(
"Must provide -gridVariables option.\n");
248 }
249 if (!atValues && !fileForValues) {
250 SDDS_Bomb(
"Must provide either -atValues or -valuesFile option.\n");
251 }
252
254
255 if (fileForValues) {
258 }
260 SDDS_Bomb(
"Unable to read values file.\n");
261 }
262 if ((atValues = SDDS_RowCount(&SDDSvalues)) > 0) {
263 if (inverse) {
265 SDDS_Bomb(
"Unable to retrieve values of first grid variable in values file.\n");
266 }
268 SDDS_Bomb(
"Unable to retrieve values of second grid variable in values file.\n");
269 }
270 } else {
272 SDDS_Bomb(
"Unable to retrieve values of first findLocationOf variable in values file.\n");
273 }
275 SDDS_Bomb(
"Unable to retrieve values of second findLocationOf variable in values file.\n");
276 }
277 }
278 }
280 SDDS_Bomb(
"Values file contains multiple pages, which is not supported.\n");
281 }
284 }
285
288 }
289
299 }
301
302 irow = 0;
303 iv = 0;
304 restarted = 0;
305 while (1) {
306 double location[2];
307 needPage = (irow == 0) ? 1 : 0;
308 if (mode == MODE_ONEPAIRPERPAGE) {
309 if (iv == atValues) {
310 break;
311 }
312 needPage = 1;
313 } else if (mode == MODE_REUSEFIRSTPAGE) {
314 if (iv == atValues) {
315 break;
316 }
317 if (iv == 0) {
318 needPage = 1;
319 }
320 } else if (mode == MODE_ALL) {
321 if (iv == atValues) {
322 needPage = 1;
323 iv = 0;
324 restarted = 1;
325 }
326 }
327
328 if (needPage) {
330 if (!restarted) {
331 SDDS_Bomb(
"Too few pages in input file for number of location requests.\n");
332 }
333 break;
334 }
335 if (gridValue[0]) {
336 free(gridValue[0]);
337 free(gridValue[1]);
338 free(valueAtLocation[0]);
339 free(valueAtLocation[1]);
340 gridValue[0] = gridValue[1] = valueAtLocation[0] = valueAtLocation[1] = NULL;
341 }
342 if ((gridPoints = SDDS_RowCount(&SDDSin)) <= 0) {
343 SDDS_Bomb(
"First page of input file is empty.\n");
344 }
347 SDDS_Bomb(
"Grid variables are missing from input file.\n");
348 }
351 SDDS_Bomb(
"Location variables are missing from input file.\n");
352 }
353
354 gridifyData(gridVariable, gridPoints, presorted);
355 }
356
357 if (inverse) {
358
359 double xmin, ymin, xmax, ymax, dx, dy, v1, v2, fx, fy;
360 double x, y;
361 int64_t ix, iy, ig;
362
363 xmin = gridValue[0][0];
364 ymin = gridValue[1][0];
365 xmax = gridValue[0][gridPoints - 1];
366 ymax = gridValue[1][gridPoints - 1];
367 dx = (xmax - xmin) / (ng[0] - 1);
368 dy = (ymax - ymin) / (ng[1] - 1);
369 x = atValue[0][iv];
370 y = atValue[1][iv];
371 ix = (x - xmin) / dx;
372 if (ix < 0) {
373 ix = 0;
374 }
375 if (ix >= (int64_t)(ng[0] - 1)) {
376 ix = ng[0] - 2;
377 }
378 iy = (y - ymin) / dy;
379 if (iy < 0) {
380 iy = 0;
381 }
382 if (iy >= (int64_t)(ng[1] - 1)) {
383 iy = ng[1] - 2;
384 }
385 fx = (x - (ix * dx + xmin)) / dx;
386 fy = (y - (iy * dy + ymin)) / dy;
387
388 ig = ix * ng[1] + iy;
389 v1 = valueAtLocation[0][ig] * (1 - fx) + valueAtLocation[0][ig + ng[1]] * fx;
390 ig = ix * ng[1] + iy + 1;
391 v2 = valueAtLocation[0][ig] * (1 - fx) + valueAtLocation[0][ig + ng[1]] * fx;
392 location[0] = v1 * (1 - fy) + v2 * fy;
393 value[0] = x;
394
395 ig = ix * ng[1] + iy;
396 v1 = valueAtLocation[1][ig] * (1 - fx) + valueAtLocation[1][ig + ng[1]] * fx;
397 ig = ix * ng[1] + iy + 1;
398 v2 = valueAtLocation[1][ig] * (1 - fx) + valueAtLocation[1][ig + ng[1]] * fx;
399 location[1] = v1 * (1 - fy) + v2 * fy;
400 value[1] = y;
402 0, value[0], 1, value[1], 2, location[0], 3, location[1],
403 -1)) {
405 }
406 } else {
407 if (!findLocationInGrid(atValue[0][iv], atValue[1][iv], &location[0], &value[0],
interpolate)) {
408 fprintf(stderr, "Couldn't find location for %s=%.6le, %s=%.6le\n",
409 findLocationOf[0], atValue[0][iv],
410 findLocationOf[1], atValue[1][iv]);
411 exit(EXIT_FAILURE);
412 }
414 0, location[0], 1, location[1], 2, value[0], 3, value[1],
415 -1)) {
417 }
418 }
419 iv++;
420 }
421
425 }
426 if (gridValue[0]) {
427 free(gridValue[0]);
428 free(gridValue[1]);
429 free(valueAtLocation[0]);
430 free(valueAtLocation[1]);
431 gridValue[0] = gridValue[1] = valueAtLocation[0] = valueAtLocation[1] = NULL;
432 }
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)
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.