SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsinterpset.c
Go to the documentation of this file.
1/**
2 * @file sddsinterpset.c
3 * @brief Perform multiple interpolations on SDDS data sets.
4 *
5 * @details
6 * This program reads an input SDDS file containing references to multiple data files.
7 * For each referenced data file, it performs interpolation based on specified parameters
8 * and writes the results to an output SDDS file. The interpolation behavior can be customized
9 * using various command-line options.
10 *
11 * @section Usage
12 * ```
13 * sddsinterpset [<input>] [<output>]
14 * [-pipe=[input][,output]]
15 * [-order=<number>]
16 * [-verbose]
17 * [-data=fileColumn=<colName>,interpolate=<colName>,functionof=<colName>,column=<colName> | atValue=<value>]
18 * [-majorOrder=row|column]
19 * [-belowRange={value=<value>|skip|saturate|extrapolate|wrap}[,{abort|warn}]]
20 * [-aboveRange={value=<value>|skip|saturate|extrapolate|wrap}[,{abort|warn}]]
21 * ```
22 *
23 * @section Options
24 * | Option | Description |
25 * |---------------------|-----------------------------------------------------------------------------|
26 * | `-pipe` | Use standard SDDS Toolkit pipe options for input and output. |
27 * | `-order` | Specify the order of the polynomials used for interpolation. |
28 * | `-verbose` | Print detailed processing messages. |
29 * | `-data` | Define data interpolation parameters. |
30 * | `-majorOrder` | Specify data ordering for output: `row` or `column`. |
31 * | `-belowRange` | Define behavior for out-of-range points below data range. |
32 * | `-aboveRange` | Define behavior for out-of-range points above data range. |
33 *
34 * @subsection Incompatibilities
35 * - The `column` and `atValue` options within `-data` are mutually exclusive; only one can be specified per invocation.
36 *
37 * @copyright
38 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
39 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
40 *
41 * @license
42 * This file is distributed under the terms of the Software License Agreement
43 * found in the file LICENSE included with this distribution.
44 *
45 * @authors
46 * H. Shang, R. Soliday, Xuesong Jiao, M. Borland
47 */
48
49#include "mdb.h"
50#include "SDDS.h"
51#include "scan.h"
52#include "SDDSutils.h"
53#include <ctype.h>
54
55/* Enumeration for option types */
56enum option_type {
57 CLO_ORDER,
58 CLO_PIPE,
59 CLO_BELOWRANGE,
60 CLO_ABOVERANGE,
61 CLO_DATA,
62 CLO_VERBOSE,
63 CLO_MAJOR_ORDER,
64 N_OPTIONS
65};
66
67char *option[N_OPTIONS] = {
68 "order",
69 "pipe",
70 "belowrange",
71 "aboverange",
72 "data",
73 "verbose",
74 "majorOrder",
75};
76
77static const char *USAGE =
78 "Usage: sddsinterpset [<input>] [<output>] \n"
79 " [-pipe=[input][,output]] \n"
80 " [-order=<number>] \n"
81 " [-verbose] \n"
82 " [-data=fileColumn=<colName>,interpolate=<colName>,functionof=<colName>,\n"
83 " column=<colName> | atValue=<value>] \n"
84 " [-majorOrder=row|column] \n"
85 " [-belowRange={value=<value>|skip|saturate|extrapolate|wrap}[,{abort|warn}]] \n"
86 " [-aboveRange={value=<value>|skip|saturate|extrapolate|wrap}[,{abort|warn}]]\n\n"
87 "Options:\n"
88 " -verbose Print detailed processing messages.\n"
89 " -pipe Use standard SDDS Toolkit pipe options for input and output.\n"
90 " -order Specify the order of the polynomials used for interpolation.\n"
91 " Default is 1 (linear interpolation).\n"
92 " -data Define data interpolation parameters:\n"
93 " - fileColumn=<colName> : Column with data file names.\n"
94 " - interpolate=<colName> : Column to interpolate.\n"
95 " - functionof=<colName> : Independent variable column name.\n"
96 " - column=<colName> : Specify interpolation point as a column.\n"
97 " or\n"
98 " - atValue=<value> : Specify a fixed interpolation value.\n"
99 " -majorOrder Specify data ordering for output: 'row' or 'column'.\n"
100 " Default inherits from input file.\n"
101 " -belowRange Define behavior for interpolation points below data range:\n"
102 " Options: value=<value>, skip, saturate, extrapolate, wrap, abort, warn.\n"
103 " -aboveRange Define behavior for interpolation points above data range:\n"
104 " Options: value=<value>, skip, saturate, extrapolate, wrap, abort, warn.\n\n"
105 "Program by Hairong Shang. ("__DATE__
106 " "__TIME__
107 ", SVN revision: " SVN_VERSION ")\n";
108
109#define AT_COLUMN 0x00000001
110#define AT_VALUE 0x00000002
111
112typedef struct {
113 char *fileColumn;
114 char *interpCol;
115 char *funcOfCol;
116 char *atCol;
117 char **file;
118 int64_t files;
119 double atValue;
120 double *colValue;
121 unsigned long hasdata;
122 unsigned long flags;
124
125long checkMonotonicity(double *indepValue, int64_t rows);
126void freedatacontrol(DATA_CONTROL *data_control, long dataControls);
127
128int main(int argc, char **argv) {
129 int i_arg;
130 char *input = NULL, *output = NULL, **interpCol = NULL, **funcOf = NULL;
131 long order = 1, dataControls = 0, valid_option = 1, monotonicity;
132 //long verbose = 0;
133 SCANNED_ARG *s_arg;
134 OUTRANGE_CONTROL aboveRange, belowRange;
135 DATA_CONTROL *data_control = NULL;
136 unsigned long pipeFlags = 0, interpCode = 0, majorOrderFlag;
137 SDDS_DATASET SDDSdata, SDDSout, SDDSin;
138 double *indepValue = NULL, *depenValue = NULL, **out_depenValue = NULL, atValue = 0;
139 int32_t **rowFlag = NULL;
140 long valid_data = 0, index, pages = 0;
141 int64_t *rows = NULL;
142 int64_t i, j, datarows, row;
143 short columnMajorOrder = -1;
144
146 argc = scanargs(&s_arg, argc, argv);
147 if (argc < 3) {
148 fprintf(stderr, "%s", USAGE);
149 exit(EXIT_FAILURE);
150 }
151
152 aboveRange.flags = belowRange.flags = OUTRANGE_SATURATE;
153
154 for (i_arg = 1; i_arg < argc; i_arg++) {
155 if (s_arg[i_arg].arg_type == OPTION) {
156 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
157 case CLO_MAJOR_ORDER:
158 majorOrderFlag = 0;
159 s_arg[i_arg].n_items--;
160 if (s_arg[i_arg].n_items > 0 &&
161 !scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
162 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
163 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)) {
164 SDDS_Bomb("invalid -majorOrder syntax/values");
165 }
166 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
167 columnMajorOrder = 1;
168 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
169 columnMajorOrder = 0;
170 break;
171
172 case CLO_ORDER:
173 if (s_arg[i_arg].n_items != 2 ||
174 sscanf(s_arg[i_arg].list[1], "%ld", &order) != 1 ||
175 order < 1) {
176 SDDS_Bomb("invalid -order syntax/value");
177 }
178 break;
179
180 case CLO_PIPE:
181 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
182 SDDS_Bomb("invalid -pipe syntax");
183 }
184 break;
185
186 case CLO_ABOVERANGE:
187 s_arg[i_arg].n_items -= 1;
188 if (s_arg[i_arg].n_items < 1 ||
189 !scanItemList(&aboveRange.flags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
190 "value", SDDS_DOUBLE, &aboveRange.value, 1, OUTRANGE_VALUE,
191 "skip", -1, NULL, 0, OUTRANGE_SKIP,
192 "saturate", -1, NULL, 0, OUTRANGE_SATURATE,
193 "extrapolate", -1, NULL, 0, OUTRANGE_EXTRAPOLATE,
194 "wrap", -1, NULL, 0, OUTRANGE_WRAP,
195 "abort", -1, NULL, 0, OUTRANGE_ABORT,
196 "warn", -1, NULL, 0, OUTRANGE_WARN, NULL)) {
197 SDDS_Bomb("invalid -aboveRange syntax/value");
198 }
199 if ((i = bitsSet(aboveRange.flags & (OUTRANGE_VALUE | OUTRANGE_SKIP | OUTRANGE_SATURATE |
200 OUTRANGE_EXTRAPOLATE | OUTRANGE_WRAP | OUTRANGE_ABORT))) > 1) {
201 SDDS_Bomb("incompatible keywords given for -aboveRange");
202 }
203 if (i != 1)
204 aboveRange.flags |= OUTRANGE_SATURATE;
205 break;
206
207 case CLO_VERBOSE:
208 //verbose = 1;
209 break;
210
211 case CLO_BELOWRANGE:
212 s_arg[i_arg].n_items -= 1;
213 if (s_arg[i_arg].n_items < 1 ||
214 !scanItemList(&belowRange.flags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
215 "value", SDDS_DOUBLE, &belowRange.value, 1, OUTRANGE_VALUE,
216 "skip", -1, NULL, 0, OUTRANGE_SKIP,
217 "saturate", -1, NULL, 0, OUTRANGE_SATURATE,
218 "extrapolate", -1, NULL, 0, OUTRANGE_EXTRAPOLATE,
219 "wrap", -1, NULL, 0, OUTRANGE_WRAP,
220 "abort", -1, NULL, 0, OUTRANGE_ABORT,
221 "warn", -1, NULL, 0, OUTRANGE_WARN, NULL)) {
222 SDDS_Bomb("invalid -belowRange syntax/value");
223 }
224 if ((i = bitsSet(belowRange.flags & (OUTRANGE_VALUE | OUTRANGE_SKIP | OUTRANGE_SATURATE |
225 OUTRANGE_EXTRAPOLATE | OUTRANGE_WRAP | OUTRANGE_ABORT))) > 1) {
226 SDDS_Bomb("incompatible keywords given for -belowRange");
227 }
228 if (i != 1)
229 belowRange.flags |= OUTRANGE_SATURATE;
230 break;
231
232 case CLO_DATA:
233 s_arg[i_arg].n_items -= 1;
234 if (s_arg[i_arg].n_items < 4) {
235 SDDS_Bomb("invalid -data syntax");
236 }
237 data_control = SDDS_Realloc(data_control, sizeof(*data_control) * (dataControls + 1));
238 data_control[dataControls].fileColumn = data_control[dataControls].interpCol =
239 data_control[dataControls].funcOfCol = data_control[dataControls].atCol = NULL;
240 data_control[dataControls].file = NULL;
241 data_control[dataControls].files = 0;
242 data_control[dataControls].hasdata = 0;
243 data_control[dataControls].colValue = NULL;
244 data_control[dataControls].flags = 0;
245
246 if (!scanItemList(&data_control[dataControls].flags, s_arg[i_arg].list + 1,
247 &s_arg[i_arg].n_items, 0,
248 "fileColumn", SDDS_STRING, &(data_control[dataControls].fileColumn), 1, 0,
249 "interpolate", SDDS_STRING, &(data_control[dataControls].interpCol), 1, 0,
250 "functionof", SDDS_STRING, &(data_control[dataControls].funcOfCol), 1, 0,
251 "column", SDDS_STRING, &(data_control[dataControls].atCol), 1, AT_COLUMN,
252 "atValue", SDDS_DOUBLE, &(data_control[dataControls].atValue), 1, AT_VALUE, NULL) ||
253 !data_control[dataControls].fileColumn ||
254 !data_control[dataControls].interpCol ||
255 !data_control[dataControls].funcOfCol) {
256 SDDS_Bomb("Invalid -data syntax");
257 }
258
259 if (!(data_control[dataControls].flags & AT_COLUMN) &&
260 !(data_control[dataControls].flags & AT_VALUE)) {
261 SDDS_Bomb("Invalid -data syntax: either column or atValue option should be given.");
262 }
263
264 if ((data_control[dataControls].flags & AT_COLUMN) &&
265 (data_control[dataControls].flags & AT_VALUE)) {
266 SDDS_Bomb("Invalid -data syntax: column and atValue options are not compatible.");
267 }
268
269 valid_option = 1;
270 if (dataControls) {
271 if (match_string(data_control[dataControls].funcOfCol, funcOf, dataControls, EXACT_MATCH) > 0) {
272 fprintf(stderr, "Multiple independent columns provided!\n");
273 exit(EXIT_FAILURE);
274 }
275 if (match_string(data_control[dataControls].interpCol, interpCol, dataControls, EXACT_MATCH) > 0) {
276 fprintf(stderr, "Warning: Interpolate column '%s' has been used.\n", data_control[dataControls].interpCol);
277 valid_option = 0;
278 }
279 }
280
281 if (valid_option) {
282 interpCol = SDDS_Realloc(interpCol, sizeof(*interpCol) * (dataControls + 1));
283 funcOf = SDDS_Realloc(funcOf, sizeof(*funcOf) * (dataControls + 1));
284 interpCol[dataControls] = data_control[dataControls].interpCol;
285 funcOf[dataControls] = data_control[dataControls].funcOfCol;
286 dataControls++;
287 }
288 break;
289
290 default:
291 fprintf(stderr, "Error: Unknown or ambiguous option '%s'\n", s_arg[i_arg].list[0]);
292 exit(EXIT_FAILURE);
293 break;
294 }
295 } else {
296 if (!input)
297 input = s_arg[i_arg].list[0];
298 else if (!output)
299 output = s_arg[i_arg].list[0];
300 else
301 SDDS_Bomb("Too many filenames provided.");
302 }
303 }
304
305 processFilenames("sddsinterpset", &input, &output, pipeFlags, 0, NULL);
306
307 if (!SDDS_InitializeInput(&SDDSin, input))
308 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
309
310 for (i = 0; i < dataControls; i++) {
311 if ((index = SDDS_GetColumnIndex(&SDDSin, data_control[i].fileColumn)) < 0) {
312 fprintf(stderr, "Warning: Column '%s' does not exist in input file '%s'.\n",
313 data_control[i].fileColumn, input);
314 continue;
315 }
316 if (SDDS_GetColumnType(&SDDSin, index) != SDDS_STRING) {
317 fprintf(stderr, "Error: Column '%s' in input file '%s' is not a string column.\n",
318 data_control[i].fileColumn, input);
319 continue;
320 }
321 if (data_control[i].atCol) {
322 if ((index = SDDS_GetColumnIndex(&SDDSin, data_control[i].atCol)) < 0) {
323 fprintf(stderr, "Warning: Column '%s' does not exist in input file '%s'.\n",
324 data_control[i].atCol, input);
325 continue;
326 }
327 if (!SDDS_NUMERIC_TYPE(SDDS_GetColumnType(&SDDSin, index))) {
328 fprintf(stderr, "Error: Column '%s' in input file '%s' is not a numeric column.\n",
329 data_control[i].atCol, input);
330 continue;
331 }
332 }
333 data_control[i].hasdata = 1;
334 valid_data++;
335 }
336
337 if (!valid_data) {
338 fprintf(stderr, "Error: No valid -data options provided for processing.\n");
339 exit(EXIT_FAILURE);
340 }
341
342 if (!SDDS_InitializeCopy(&SDDSout, &SDDSin, output, "w"))
343 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
344
345 if (columnMajorOrder != -1)
346 SDDSout.layout.data_mode.column_major = columnMajorOrder;
347 else
348 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
349
350 while (SDDS_ReadPage(&SDDSin) > 0) {
351 rows = SDDS_Realloc(rows, sizeof(*rows) * (pages + 1));
352 out_depenValue = SDDS_Realloc(out_depenValue, sizeof(*out_depenValue) * (pages + 1));
353 rowFlag = SDDS_Realloc(rowFlag, sizeof(*rowFlag) * (pages + 1));
354
355 if (!(rows[pages] = SDDS_CountRowsOfInterest(&SDDSin))) {
356 fprintf(stderr, "Error: No data found in input file '%s'.\n", input);
357 exit(EXIT_FAILURE);
358 }
359
360 rowFlag[pages] = (int32_t *)malloc(sizeof(**rowFlag) * rows[pages]);
361 out_depenValue[pages] = (double *)malloc(sizeof(**out_depenValue) * rows[pages]);
362
363 for (i = 0; i < rows[pages]; i++)
364 rowFlag[pages][i] = 1;
365
366 for (i = 0; i < dataControls; i++) {
367 if (data_control[i].hasdata) {
368 data_control[i].files = rows[pages];
369 if (!(data_control[i].file = (char **)SDDS_GetColumn(&SDDSin, data_control[i].fileColumn))) {
370 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
371 }
372
373 if (data_control[i].atCol) {
374 if (!(data_control[i].colValue = SDDS_GetColumnInDoubles(&SDDSin, data_control[i].atCol))) {
375 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
376 }
377 }
378
379 if (!data_control[i].atCol)
380 atValue = data_control[i].atValue;
381
382 for (j = 0; j < rows[pages]; j++) {
383 if (!SDDS_InitializeInput(&SDDSdata, data_control[i].file[j]))
384 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
385
386 switch (SDDS_CheckColumn(&SDDSdata, data_control[i].interpCol, NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) {
387 case SDDS_CHECK_OKAY:
388 if (j == (rows[pages] - 1)) {
389 if (!pages) {
390 if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSdata, data_control[i].interpCol, data_control[i].interpCol))
391 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
392 }
393 }
394 break;
395 default:
396 fprintf(stderr, "Error: Column '%s' missing or invalid in file '%s'.\n",
397 data_control[i].interpCol, data_control[i].file[j]);
398 exit(EXIT_FAILURE);
399 break;
400 }
401
402 switch (SDDS_CheckColumn(&SDDSdata, data_control[i].funcOfCol, NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) {
403 case SDDS_CHECK_OKAY:
404 if (j == (rows[pages] - 1)) {
405 if ((!pages) && !(data_control[i].atCol)) {
406 if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSdata, data_control[i].funcOfCol, data_control[i].funcOfCol))
407 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
408 }
409 }
410 break;
411 default:
412 fprintf(stderr, "Error: Column '%s' missing or invalid in file '%s'.\n",
413 data_control[i].funcOfCol, data_control[i].file[j]);
414 exit(EXIT_FAILURE);
415 break;
416 }
417
418 if (SDDS_ReadPage(&SDDSdata) <= 0)
419 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
420
421 datarows = SDDS_CountRowsOfInterest(&SDDSdata);
422
423 if (!(indepValue = SDDS_GetColumnInDoubles(&SDDSdata, data_control[i].funcOfCol))) {
424 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
425 }
426 if (!(depenValue = SDDS_GetColumnInDoubles(&SDDSdata, data_control[i].interpCol))) {
427 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
428 }
429
430 if (!SDDS_Terminate(&SDDSdata))
431 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
432
433 if (!(monotonicity = checkMonotonicity(indepValue, datarows))) {
434 fprintf(stderr, "Error: Independent (%s) data in file '%s' is not monotonic.\n",
435 data_control[i].funcOfCol, data_control[i].file[j]);
436 exit(EXIT_FAILURE);
437 }
438
439 if (data_control[i].atCol)
440 atValue = data_control[i].colValue[j];
441
442 out_depenValue[pages][j] = interpolate(depenValue, indepValue, datarows, atValue,
443 &belowRange, &aboveRange, order, &interpCode, monotonicity);
444
445 if (interpCode) {
446 if (interpCode & OUTRANGE_ABORT) {
447 fprintf(stderr, "Error: Value %e out of range for column '%s'.\n",
448 atValue, data_control[i].interpCol);
449 exit(EXIT_FAILURE);
450 }
451 if (interpCode & OUTRANGE_WARN)
452 fprintf(stderr, "Warning: Value %e out of range for column '%s'.\n",
453 atValue, data_control[i].interpCol);
454 if (interpCode & OUTRANGE_SKIP)
455 rowFlag[pages][j] = 0;
456 }
457
458 free(depenValue);
459 free(indepValue);
460 }
461 }
462
463 for (j = 0; j < data_control[i].files; j++)
464 free(data_control[i].file[j]);
465 free(data_control[i].file);
466 data_control[i].file = NULL;
467
468 if (data_control[i].colValue) {
469 free(data_control[i].colValue);
470 data_control[i].colValue = NULL;
471 }
472 }
473
474 if (!pages) {
475 if (!SDDS_WriteLayout(&SDDSout))
476 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
477 }
478
479 if (!SDDS_StartTable(&SDDSout, rows[pages]))
480 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
481
482 if (!SDDS_CopyColumns(&SDDSout, &SDDSin))
483 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
484
485 if (!SDDS_CopyParameters(&SDDSout, &SDDSin))
486 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
487
488 for (i = 0; i < dataControls; i++) {
489 if (data_control[i].hasdata) {
490 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, out_depenValue[pages],
491 rows[pages], data_control[i].interpCol)) {
492 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
493 }
494 if (!(data_control[i].atCol)) {
495 for (row = 0; row < rows[pages]; row++) {
496 if (!SDDS_SetRowValues(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, row,
497 data_control[i].funcOfCol, data_control[i].atValue, NULL)) {
498 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
499 }
500 }
501 }
502 }
503 }
504
505 if (!SDDS_AssertRowFlags(&SDDSout, SDDS_FLAG_ARRAY, rowFlag[pages], rows[pages]))
506 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
507
508 if (!SDDS_WritePage(&SDDSout))
509 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
510
511 pages++;
512 }
513
514 if (!SDDS_Terminate(&SDDSin))
515 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
516
517 if (!SDDS_Terminate(&SDDSout)) {
518 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
519 exit(EXIT_FAILURE);
520 }
521
522 freedatacontrol(data_control, dataControls);
523
524 if (out_depenValue) {
525 for (i = 0; i < pages; i++) {
526 free(out_depenValue[i]);
527 free(rowFlag[i]);
528 }
529 free(out_depenValue);
530 free(rowFlag);
531 }
532
533 if (interpCol)
534 free(interpCol);
535 if (funcOf)
536 free(funcOf);
537 if (rows)
538 free(rows);
539
540 free_scanargs(&s_arg, argc);
541 return EXIT_SUCCESS;
542}
543
544long checkMonotonicity(double *indepValue, int64_t rows) {
545 if (rows == 1)
546 return 1;
547
548 if (indepValue[rows - 1] > indepValue[0]) {
549 while (--rows > 0)
550 if (indepValue[rows] < indepValue[rows - 1])
551 return 0;
552 return 1;
553 } else {
554 while (--rows > 0)
555 if (indepValue[rows] > indepValue[rows - 1])
556 return 0;
557 return -1;
558 }
559}
560
561void freedatacontrol(DATA_CONTROL *data_control, long dataControls) {
562 long i;
563 for (i = 0; i < dataControls; i++) {
564 free(data_control[i].interpCol);
565 free(data_control[i].funcOfCol);
566 free(data_control[i].fileColumn);
567 if (data_control[i].atCol)
568 free(data_control[i].atCol);
569 }
570 free(data_control);
571}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyColumns(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:387
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
int32_t SDDS_AssertRowFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for rows based on specified criteria.
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_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_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
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.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
Utility functions for SDDS dataset manipulation and string array operations.
long bitsSet(unsigned long data)
Counts the number of set bits (1s) in the given data.
Definition binary.c:52
double interpolate(double *f, double *x, int64_t n, double xo, OUTRANGE_CONTROL *belowRange, OUTRANGE_CONTROL *aboveRange, long order, unsigned long *returnCode, long M)
Performs interpolation with range control options.
Definition interp.c:160
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)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.