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