SDDSlib
Loading...
Searching...
No Matches
sddsinterp.c File Reference

SDDS-format interpolation program. More...

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"
#include "SDDSutils.h"

Go to the source code of this file.

Macros

#define FILEVALUES_PARALLEL_PAGES   0x0001U
 
#define NORMAL_PRINTOUT   1
 
#define BARE_PRINTOUT   2
 
#define STDOUT_PRINTOUT   4
 
#define FORCE_MONOTONIC   0x0001U
 
#define FORCE_INCREASING   0x0002U
 
#define FORCE_DECREASING   0x0004U
 

Enumerations

enum  option_type {
  CLO_ORDER , CLO_ATVALUES , CLO_SEQUENCE , CLO_COLUMNS ,
  CLO_PRINTOUT , CLO_FILEVALUES , CLO_COMBINEDUPLICATES , CLO_BRANCH ,
  CLO_BELOWRANGE , CLO_ABOVERANGE , CLO_PIPE , CLO_EXCLUDE ,
  CLO_FORCEMONOTONIC , CLO_FILLIN , CLO_EQUISPACED , CLO_INTERP_SHORT ,
  CLO_MAJOR_ORDER , N_OPTIONS
}
 

Functions

double * makeSequence (int64_t *points, double start, double end, double spacing, double *data, int64_t dataRows)
 
double * makeFillInSequence (double *x, int64_t dataRows, int64_t *nPointsReturn)
 
long checkMonotonicity (double *indepValue, int64_t rows)
 
int64_t forceMonotonicity (double *indepValue, double **y, long columns, int64_t rows, unsigned long direction)
 
int64_t combineDuplicatePoints (double *x, double **y, long columns, int64_t rows, double tolerance)
 
int main (int argc, char **argv)
 

Variables

char * option [N_OPTIONS]
 
static char * USAGE
 

Detailed Description

SDDS-format interpolation program.

This program performs interpolation on SDDS (Self Describing Data Set) formatted data. It supports various interpolation methods, handles range conditions, and allows customization of output through multiple command-line options.

Usage

The sddsinterp program interpolates data from an input SDDS file and writes the interpolated data to an output SDDS file. It offers several methods for specifying interpolation points and provides options to control the interpolation behavior.

Basic Syntax:

sddsinterp [<inputfile>] [<outputfile>] [options]

Options

The following options are available to customize the interpolation process:

-pipe=[input][,output] -columns=<independent>,<dependent1>[,...] -exclude=<name>[,...] -atValues=<values-list> -sequence=<points>[,<start>,<end>] -equispaced=<spacing>[,<start>,<end>] -fillIn -fileValues=<valuesfile>[,column=<name>][,parallelPages] -interpShort=-1|-2 -order=<number> -printout[=bare][,stdout] -forceMonotonic[={increasing|decreasing}] -belowRange={value=<v>|skip|saturate|extrapolate|wrap}[,{abort|warn}] -aboveRange={value=<v>|skip|saturate|extrapolate|wrap}[,{abort|warn}] -majorOrder=row|column

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddsinterp.c.

Macro Definition Documentation

◆ BARE_PRINTOUT

#define BARE_PRINTOUT   2

Definition at line 134 of file sddsinterp.c.

◆ FILEVALUES_PARALLEL_PAGES

#define FILEVALUES_PARALLEL_PAGES   0x0001U

Definition at line 131 of file sddsinterp.c.

◆ FORCE_DECREASING

#define FORCE_DECREASING   0x0004U

Definition at line 139 of file sddsinterp.c.

◆ FORCE_INCREASING

#define FORCE_INCREASING   0x0002U

Definition at line 138 of file sddsinterp.c.

◆ FORCE_MONOTONIC

#define FORCE_MONOTONIC   0x0001U

Definition at line 137 of file sddsinterp.c.

◆ NORMAL_PRINTOUT

#define NORMAL_PRINTOUT   1

Definition at line 133 of file sddsinterp.c.

◆ STDOUT_PRINTOUT

#define STDOUT_PRINTOUT   4

Definition at line 135 of file sddsinterp.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 57 of file sddsinterp.c.

57 {
58 CLO_ORDER,
59 CLO_ATVALUES,
60 CLO_SEQUENCE,
61 CLO_COLUMNS,
62 CLO_PRINTOUT,
63 CLO_FILEVALUES,
64 CLO_COMBINEDUPLICATES,
65 CLO_BRANCH,
66 CLO_BELOWRANGE,
67 CLO_ABOVERANGE,
68 CLO_PIPE,
69 CLO_EXCLUDE,
70 CLO_FORCEMONOTONIC,
71 CLO_FILLIN,
72 CLO_EQUISPACED,
73 CLO_INTERP_SHORT,
74 CLO_MAJOR_ORDER,
75 N_OPTIONS
76};

Function Documentation

◆ checkMonotonicity()

long checkMonotonicity ( double * indepValue,
int64_t rows )

Definition at line 628 of file sddsinterp.c.

628 {
629 if (rows == 1)
630 return 1;
631 if (indepValue[rows - 1] > indepValue[0]) {
632 while (--rows > 0)
633 if (indepValue[rows] <= indepValue[rows - 1])
634 return 0;
635 return 1;
636 } else {
637 while (--rows > 0)
638 if (indepValue[rows] >= indepValue[rows - 1])
639 return 0;
640 return -1;
641 }
642}

◆ combineDuplicatePoints()

int64_t combineDuplicatePoints ( double * x,
double ** y,
long columns,
int64_t rows,
double tolerance )

Definition at line 644 of file sddsinterp.c.

644 {
645 double xmin, xmax;
646 long column;
647 int64_t i, j;
648
649 find_min_max(&xmin, &xmax, x, rows);
650 if (xmin == xmax)
651 SDDS_Bomb("interpolation data is invalid--no range in independent variable");
652 tolerance *= xmax - xmin;
653 for (i = 1; i < rows; i++) {
654 if (fabs(x[i] - x[i - 1]) <= tolerance) {
655 x[i - 1] = (x[i] + x[i - 1]) / 2;
656 for (column = 0; column < columns; column++)
657 y[column][i - 1] = (y[column][i] + y[column][i - 1]) / 2;
658 for (j = i + 1; j < rows; j++) {
659 x[j - 1] = x[j];
660 for (column = 0; column < columns; column++)
661 y[column][j - 1] = y[column][j];
662 }
663 rows--;
664 i--;
665 }
666 }
667 return rows;
668}
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
Definition findMinMax.c:33

◆ forceMonotonicity()

int64_t forceMonotonicity ( double * indepValue,
double ** y,
long columns,
int64_t rows,
unsigned long direction )

Definition at line 670 of file sddsinterp.c.

670 {
671 int64_t i, j;
672 long column, direction;
673 char *keep;
674 double reference;
675
676 if (rows < 2)
677 return rows;
678
679 if (mode & FORCE_INCREASING)
680 direction = 1;
681 else if (mode & FORCE_DECREASING)
682 direction = -1;
683 else
684 direction = x[1] > x[0] ? 1 : -1;
685
686 keep = tmalloc(sizeof(*keep) * rows);
687 reference = x[0];
688 keep[0] = 1; // Always keep the first point
689 for (i = 1; i < rows; i++) {
690 if (direction * (x[i] - reference) > 0) {
691 reference = x[i];
692 keep[i] = 1;
693 } else {
694 keep[i] = 0;
695 }
696 }
697 for (i = j = 1; i < rows; i++) {
698 if (keep[i]) {
699 if (i != j) {
700 for (column = 0; column < columns; column++)
701 y[column][j] = y[column][i];
702 x[j] = x[i];
703 }
704 j++;
705 }
706 }
707 rows = j;
708 free(keep);
709 return rows;
710}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59

◆ main()

int main ( int argc,
char ** argv )

Definition at line 141 of file sddsinterp.c.

141 {
142 int iArg;
143 char *indepQuantity, **depenQuantity, *fileValuesQuantity, *fileValuesFile, **exclude;
144 long depenQuantities, monotonicity, excludes;
145 char *input, *output;
146 long i, readCode, order, valuesReadCode, fillIn;
147 int64_t rows, row, interpPoints, j;
148 long sequencePoints, combineDuplicates, branch;
149 int32_t *rowFlag;
150 double sequenceStart, sequenceEnd;
151 double sequenceSpacing;
152 unsigned long flags, interpCode, printFlags, forceMonotonic;
153 SCANNED_ARG *scanned;
154 SDDS_DATASET SDDSin, SDDSout, SDDSvalues;
155 OUTRANGE_CONTROL aboveRange, belowRange;
156 double *atValue;
157 long atValues, doNotRead, parallelPages;
158 double *indepValue, **depenValue, *interpPoint, **outputData;
159 unsigned long pipeFlags, majorOrderFlag;
160 FILE *fpPrint;
161 short interpShort = 0, interpShortOrder = -1, *shortValue = NULL, columnMajorOrder = -1;
162 long nextPos;
163
165 argc = scanargs(&scanned, argc, argv);
166 if (argc < 3 || argc > (3 + N_OPTIONS))
167 bomb(NULL, USAGE);
168
169 atValue = NULL;
170 atValues = fillIn = 0;
171 output = input = NULL;
172 combineDuplicates = branch = sequencePoints = parallelPages = 0;
173 indepQuantity = NULL;
174 depenQuantity = exclude = NULL;
175 depenQuantities = excludes = 0;
176 aboveRange.flags = belowRange.flags = OUTRANGE_SATURATE;
177 order = 1;
178 readCode = interpPoints = 0;
179 fileValuesFile = fileValuesQuantity = NULL;
180 sequenceStart = sequenceEnd = sequenceSpacing = 0;
181 printFlags = pipeFlags = 0;
182 forceMonotonic = 0;
183 indepValue = interpPoint = NULL;
184 depenValue = outputData = NULL;
185
186 for (iArg = 1; iArg < argc; iArg++) {
187 if (scanned[iArg].arg_type == OPTION) {
188 /* process options here */
189 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
190 case CLO_MAJOR_ORDER:
191 majorOrderFlag = 0;
192 scanned[iArg].n_items--;
193 if (scanned[iArg].n_items > 0 &&
194 (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
195 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
196 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
197 SDDS_Bomb("invalid -majorOrder syntax/values");
198 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
199 columnMajorOrder = 1;
200 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
201 columnMajorOrder = 0;
202 break;
203 case CLO_ORDER:
204 if (scanned[iArg].n_items != 2 ||
205 sscanf(scanned[iArg].list[1], "%ld", &order) != 1 || order < 0)
206 SDDS_Bomb("invalid -order syntax/value");
207 break;
208 case CLO_ATVALUES:
209 if (scanned[iArg].n_items < 2)
210 SDDS_Bomb("invalid -atValues syntax");
211 if (atValue)
212 SDDS_Bomb("give -atValues only once");
213 atValue = tmalloc(sizeof(*atValue) * (atValues = scanned[iArg].n_items - 1));
214 for (i = 0; i < atValues; i++)
215 if (sscanf(scanned[iArg].list[i + 1], "%lf", &atValue[i]) != 1)
216 SDDS_Bomb("invalid -atValues value");
217 break;
218 case CLO_INTERP_SHORT:
219 if (scanned[iArg].n_items == 2) {
220 if (sscanf(scanned[iArg].list[1], "%hd", &interpShortOrder) != 1 ||
221 (interpShortOrder != -1 && interpShortOrder != -2))
222 SDDS_Bomb("invalid -interpShort value; must be -1 or -2");
223 }
224 interpShort = 1;
225 break;
226 case CLO_SEQUENCE:
227 if ((scanned[iArg].n_items != 2 && scanned[iArg].n_items != 4) ||
228 sscanf(scanned[iArg].list[1], "%ld", &sequencePoints) != 1 ||
229 sequencePoints < 2)
230 SDDS_Bomb("invalid -sequence syntax/value");
231 if (scanned[iArg].n_items == 4 &&
232 (sscanf(scanned[iArg].list[2], "%lf", &sequenceStart) != 1 ||
233 sscanf(scanned[iArg].list[3], "%lf", &sequenceEnd) != 1))
234 SDDS_Bomb("invalid -sequence syntax/value");
235 if (sequenceSpacing)
236 SDDS_Bomb("give only one of -sequence and -equispaced");
237 break;
238 case CLO_EQUISPACED:
239 if ((scanned[iArg].n_items != 2 && scanned[iArg].n_items != 4) ||
240 sscanf(scanned[iArg].list[1], "%lf", &sequenceSpacing) != 1 ||
241 sequenceSpacing <= 0)
242 SDDS_Bomb("invalid -equispaced syntax/value");
243 if (scanned[iArg].n_items == 4 &&
244 (sscanf(scanned[iArg].list[2], "%lf", &sequenceStart) != 1 ||
245 sscanf(scanned[iArg].list[3], "%lf", &sequenceEnd) != 1))
246 SDDS_Bomb("invalid -equispaced syntax/values");
247 if (sequencePoints)
248 SDDS_Bomb("give only one of -sequence and -equispaced");
249 break;
250 case CLO_COLUMNS:
251 if (indepQuantity)
252 SDDS_Bomb("only one -columns option may be given");
253 if (scanned[iArg].n_items < 2)
254 SDDS_Bomb("invalid -columns syntax");
255 indepQuantity = scanned[iArg].list[1];
256 if (scanned[iArg].n_items >= 2) {
257 depenQuantity = tmalloc(sizeof(*depenQuantity) * (depenQuantities = scanned[iArg].n_items - 2));
258 for (i = 0; i < depenQuantities; i++)
259 depenQuantity[i] = scanned[iArg].list[i + 2];
260 }
261 break;
262 case CLO_PRINTOUT:
263 if ((scanned[iArg].n_items -= 1) >= 1) {
264 if (!scanItemList(&printFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
265 "bare", -1, NULL, 0, BARE_PRINTOUT,
266 "stdout", -1, NULL, 0, STDOUT_PRINTOUT, NULL))
267 SDDS_Bomb("invalid -printout syntax");
268 }
269 if (!(printFlags & BARE_PRINTOUT))
270 printFlags |= NORMAL_PRINTOUT;
271 break;
272 case CLO_FILEVALUES:
273 if (scanned[iArg].n_items < 2)
274 SDDS_Bomb("invalid -fileValues syntax");
275 fileValuesFile = scanned[iArg].list[1];
276 scanned[iArg].n_items -= 2;
277 if (!scanItemList(&flags, scanned[iArg].list + 2, &scanned[iArg].n_items, 0,
278 "column", SDDS_STRING, &fileValuesQuantity, 1, 0,
279 "parallelpages", -1, NULL, 0, FILEVALUES_PARALLEL_PAGES, NULL))
280 SDDS_Bomb("invalid -fileValues syntax");
281 if (flags & FILEVALUES_PARALLEL_PAGES)
282 parallelPages = 1;
283 break;
284 case CLO_COMBINEDUPLICATES:
285 SDDS_Bomb("-combineDuplicates option not implemented yet--send email to borland@aps.anl.gov");
286 combineDuplicates = 1;
287 break;
288 case CLO_BRANCH:
289 SDDS_Bomb("-branch option not implemented yet--send email to borland@aps.anl.gov");
290 if (scanned[iArg].n_items != 2 || sscanf(scanned[iArg].list[1], "%ld", &branch) != 1 || branch < 1)
291 SDDS_Bomb("invalid -branch syntax/value");
292 break;
293 case CLO_BELOWRANGE:
294 if ((scanned[iArg].n_items -= 1) < 1 ||
295 !scanItemList(&belowRange.flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
296 "value", SDDS_DOUBLE, &belowRange.value, 1, OUTRANGE_VALUE,
297 "skip", -1, NULL, 0, OUTRANGE_SKIP,
298 "saturate", -1, NULL, 0, OUTRANGE_SATURATE,
299 "extrapolate", -1, NULL, 0, OUTRANGE_EXTRAPOLATE,
300 "wrap", -1, NULL, 0, OUTRANGE_WRAP,
301 "abort", -1, NULL, 0, OUTRANGE_ABORT,
302 "warn", -1, NULL, 0, OUTRANGE_WARN, NULL))
303 SDDS_Bomb("invalid -belowRange syntax/value");
304 if ((i = bitsSet(belowRange.flags & (OUTRANGE_VALUE | OUTRANGE_SKIP | OUTRANGE_SATURATE | OUTRANGE_EXTRAPOLATE | OUTRANGE_WRAP | OUTRANGE_ABORT))) > 1)
305 SDDS_Bomb("incompatible keywords given for -belowRange");
306 if (i != 1)
307 belowRange.flags |= OUTRANGE_SATURATE;
308 break;
309 case CLO_ABOVERANGE:
310 if ((scanned[iArg].n_items -= 1) < 1 ||
311 !scanItemList(&aboveRange.flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
312 "value", SDDS_DOUBLE, &aboveRange.value, 1, OUTRANGE_VALUE,
313 "skip", -1, NULL, 0, OUTRANGE_SKIP,
314 "saturate", -1, NULL, 0, OUTRANGE_SATURATE,
315 "extrapolate", -1, NULL, 0, OUTRANGE_EXTRAPOLATE,
316 "wrap", -1, NULL, 0, OUTRANGE_WRAP,
317 "abort", -1, NULL, 0, OUTRANGE_ABORT,
318 "warn", -1, NULL, 0, OUTRANGE_WARN, NULL))
319 SDDS_Bomb("invalid -aboveRange syntax/value");
320 if ((i = bitsSet(aboveRange.flags & (OUTRANGE_VALUE | OUTRANGE_SKIP | OUTRANGE_SATURATE | OUTRANGE_EXTRAPOLATE | OUTRANGE_WRAP | OUTRANGE_ABORT))) > 1)
321 SDDS_Bomb("incompatible keywords given for -aboveRange");
322 if (i != 1)
323 aboveRange.flags |= OUTRANGE_SATURATE;
324 break;
325 case CLO_PIPE:
326 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
327 SDDS_Bomb("invalid -pipe syntax");
328 break;
329 case CLO_EXCLUDE:
330 if (scanned[iArg].n_items < 2)
331 SDDS_Bomb("invalid -exclude syntax");
332 moveToStringArray(&exclude, &excludes, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
333 break;
334 case CLO_FORCEMONOTONIC:
335 if ((scanned[iArg].n_items -= 1) > 0) {
336 if (!scanItemList(&forceMonotonic, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
337 "increasing", -1, NULL, 0, FORCE_INCREASING,
338 "decreasing", -1, NULL, 0, FORCE_DECREASING, NULL) ||
339 bitsSet(forceMonotonic) != 1)
340 SDDS_Bomb("invalid -forceMonotonic syntax/value");
341 } else
342 forceMonotonic = FORCE_MONOTONIC;
343 break;
344 case CLO_FILLIN:
345 fillIn = 1;
346 break;
347 default:
348 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
349 exit(EXIT_FAILURE);
350 break;
351 }
352 } else {
353 if (!input)
354 input = scanned[iArg].list[0];
355 else if (!output)
356 output = scanned[iArg].list[0];
357 else
358 SDDS_Bomb("too many filenames seen");
359 }
360 }
361
362 processFilenames("sddsinterp", &input, &output, pipeFlags, 0, NULL);
363
364 fpPrint = stderr;
365 if (printFlags & STDOUT_PRINTOUT)
366 fpPrint = stdout;
367
368 if (!indepQuantity)
369 SDDS_Bomb("supply the independent quantity name with the -columns option");
370
371 if ((atValues ? 1 : 0) + (fileValuesFile ? 1 : 0) + (sequencePoints ? 1 : 0) + fillIn + (sequenceSpacing > 0 ? 1 : 0) != 1)
372 SDDS_Bomb("you must give one and only one of -atValues, -fileValues, -sequence, -equispaced, and -fillIn");
373
374 if (!SDDS_InitializeInput(&SDDSin, input))
375 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
376
377 excludes = appendToStringArray(&exclude, excludes, indepQuantity);
378 if (!depenQuantities)
379 depenQuantities = appendToStringArray(&depenQuantity, depenQuantities, "*");
380
381 if ((depenQuantities = expandColumnPairNames(&SDDSin, &depenQuantity, NULL, depenQuantities, exclude, excludes, FIND_NUMERIC_TYPE, 0)) <= 0) {
382 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
383 SDDS_Bomb("no dependent quantities selected for interpolation");
384 }
385
386 if (!SDDS_InitializeOutput(&SDDSout, SDDS_BINARY, 0, NULL, "sddsinterp output", output))
387 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
388 if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, indepQuantity, NULL))
389 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
390 if (columnMajorOrder != -1)
391 SDDSout.layout.data_mode.column_major = columnMajorOrder;
392 else
393 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
394 if (fileValuesFile && !SDDS_InitializeInput(&SDDSvalues, fileValuesFile))
395 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
396
397 if (SDDS_DefineParameter(&SDDSout, "InterpDataPage", NULL, NULL,
398 "Page of interpolation data file used to create this page", NULL, SDDS_LONG, NULL) < 0 ||
399 SDDS_DefineParameter(&SDDSout, "InterpPointsPage", NULL, NULL, "Page of interpolation points file used to create this page", NULL, SDDS_LONG, NULL) < 0)
400 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
401 for (i = 0; i < depenQuantities; i++)
402 if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, depenQuantity[i], NULL)) {
403 fprintf(stderr, "problem creating interpolated-output column %s\n", depenQuantity[i]);
404 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
405 }
406 if (!SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, SDDS_TRANSFER_KEEPOLD) ||
407 !SDDS_WriteLayout(&SDDSout))
408 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
409
410 doNotRead = 0;
411 interpPoint = NULL;
412 outputData = tmalloc(sizeof(*outputData) * (depenQuantities));
413 depenValue = tmalloc(sizeof(*depenValue) * (depenQuantities));
414 rowFlag = NULL;
415 valuesReadCode = 0;
416
417 while (doNotRead || (readCode = SDDS_ReadPage(&SDDSin)) > 0) {
418 rows = SDDS_CountRowsOfInterest(&SDDSin);
419 if (!(indepValue = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
420 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
421 if (atValues) {
422 interpPoint = atValue;
423 interpPoints = atValues;
424 } else if (fileValuesFile) {
425 if (interpPoint)
426 free(interpPoint);
427 if ((valuesReadCode = SDDS_ReadPage(&SDDSvalues)) == 0)
428 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
429 else if (valuesReadCode == -1) {
430 if (parallelPages) {
431 fprintf(stderr, "warning: file %s ends before file %s\n", fileValuesFile, input);
432 break;
433 } else {
434 /* "rewind" the values file */
435 if (!SDDS_Terminate(&SDDSvalues) ||
436 !SDDS_InitializeInput(&SDDSvalues, fileValuesFile))
437 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
438 if ((valuesReadCode = SDDS_ReadPage(&SDDSvalues)) < 1) {
439 fprintf(stderr, "error: unable to (re)read file %s\n", fileValuesFile);
440 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
441 exit(EXIT_FAILURE);
442 }
443 /* read the next page of the interpolation data file */
444 if ((readCode = SDDS_ReadPage(&SDDSin)) < 1) {
445 if (readCode == -1)
446 break;
447 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
448 }
449 rows = SDDS_CountRowsOfInterest(&SDDSin);
450 if (indepValue)
451 free(indepValue);
452 if (!(indepValue = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
453 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
454 }
455 }
456
457 if (!parallelPages)
458 doNotRead = 1;
459 interpPoints = SDDS_CountRowsOfInterest(&SDDSvalues);
460 interpPoint = SDDS_GetColumnInDoubles(&SDDSvalues, fileValuesQuantity);
462 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
463 } else if (sequencePoints || sequenceSpacing) {
464 if (interpPoint)
465 free(interpPoint);
466 interpPoints = sequencePoints;
467 if (!(interpPoint = makeSequence(&interpPoints, sequenceStart, sequenceEnd, sequenceSpacing, indepValue, rows)))
468 exit(EXIT_FAILURE);
469 } else {
470 /* fillIn interpolation */
471 if (interpPoint)
472 free(interpPoint);
473 if (!(interpPoint = makeFillInSequence(indepValue, rows, &interpPoints)))
474 exit(EXIT_FAILURE);
475 }
476
477 for (i = 0; i < depenQuantities; i++)
478 outputData[i] = tmalloc(sizeof(*outputData[i]) * interpPoints);
479 rowFlag = trealloc(rowFlag, sizeof(*rowFlag) * interpPoints);
480 for (j = 0; j < interpPoints; j++)
481 rowFlag[j] = 1;
482 for (i = 0; i < depenQuantities; i++) {
483 if (!(depenValue[i] = SDDS_GetColumnInDoubles(&SDDSin, depenQuantity[i])))
484 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
485 }
486 if (forceMonotonic)
487 rows = forceMonotonicity(indepValue, depenValue, depenQuantities, rows, forceMonotonic);
488 else if (combineDuplicates)
489 rows = combineDuplicatePoints(indepValue, depenValue, depenQuantities, rows, 0.0);
490 if ((monotonicity = checkMonotonicity(indepValue, rows)) == 0)
491 SDDS_Bomb("independent data values do not change monotonically or repeated independent values exist");
492 if (interpShort)
493 shortValue = tmalloc(sizeof(*shortValue) * rows);
494
495 for (i = 0; i < depenQuantities; i++) {
496 if (interpShort) {
497 for (row = 0; row < rows; row++) {
498 shortValue[row] = (short)depenValue[i][row];
499 }
500 }
501 for (j = 0; j < interpPoints; j++) {
502 if (!interpShort) {
503 outputData[i][j] = interpolate(depenValue[i], indepValue, rows, interpPoint[j], &belowRange, &aboveRange, order, &interpCode, monotonicity);
504 } else {
505 outputData[i][j] = (double)interp_short(shortValue, indepValue, rows, interpPoint[j], 0, interpShortOrder, &interpCode, &nextPos);
506 }
507 if (interpCode) {
508 if (interpCode & OUTRANGE_ABORT) {
509 fprintf(stderr, "error: value %e is out of range for column %s\n", interpPoint[j], depenQuantity[i]);
510 exit(EXIT_FAILURE);
511 }
512 if (interpCode & OUTRANGE_WARN)
513 fprintf(stderr, "warning: value %e is out of range for column %s\n", interpPoint[j], depenQuantity[i]);
514 if (interpCode & OUTRANGE_SKIP)
515 rowFlag[j] = 0;
516 }
517 }
518 }
519 if (interpShort)
520 free(shortValue);
521 if (!SDDS_StartPage(&SDDSout, interpPoints) ||
522 !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, interpPoint, interpPoints, indepQuantity))
523 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
524 if (!SDDS_SetParameters(&SDDSout, SDDS_BY_NAME | SDDS_PASS_BY_VALUE, "InterpDataPage", readCode, "InterpPointsPage", valuesReadCode, NULL) ||
525 !SDDS_CopyParameters(&SDDSout, &SDDSin))
526 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
527 for (i = 0; i < depenQuantities; i++)
528 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, outputData[i], interpPoints, depenQuantity[i]))
529 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
530 if (!SDDS_AssertRowFlags(&SDDSout, SDDS_FLAG_ARRAY, rowFlag, rows) || !SDDS_WritePage(&SDDSout))
531 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
532 if (printFlags & BARE_PRINTOUT) {
533 for (j = 0; j < interpPoints; j++)
534 if (rowFlag[j]) {
535 fprintf(fpPrint, "%21.15e ", interpPoint[j]);
536 for (i = 0; i < depenQuantities; i++)
537 fprintf(fpPrint, "%21.15e ", outputData[i][j]);
538 fputc('\n', fpPrint);
539 }
540 } else if (printFlags & NORMAL_PRINTOUT) {
541 for (j = 0; j < interpPoints; j++)
542 if (rowFlag[j]) {
543 fprintf(fpPrint, "%s=%21.15e ", indepQuantity, interpPoint[j]);
544 for (i = 0; i < depenQuantities; i++)
545 fprintf(fpPrint, "%s=%21.15e ", depenQuantity[i], outputData[i][j]);
546 fputc('\n', fpPrint);
547 }
548 }
549 if (indepValue)
550 free(indepValue);
551 indepValue = NULL;
552 for (i = 0; i < depenQuantities; i++) {
553 if (outputData[i])
554 free(outputData[i]);
555 outputData[i] = NULL;
556 if (depenValue[i])
557 free(depenValue[i]);
558 depenValue[i] = NULL;
559 }
560 if (fileValuesFile) {
561 if (interpPoint)
562 free(interpPoint);
563 interpPoint = NULL;
564 }
565 if (rowFlag)
566 free(rowFlag);
567 rowFlag = NULL;
568 }
569
570 if (!SDDS_Terminate(&SDDSin)) {
571 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
572 exit(EXIT_FAILURE);
573 }
574 if (!SDDS_Terminate(&SDDSout)) {
575 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
576 exit(EXIT_FAILURE);
577 }
578 if (fileValuesFile) {
579 if (!SDDS_Terminate(&SDDSvalues)) {
580 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
581 exit(EXIT_FAILURE);
582 }
583 }
584
585 return EXIT_SUCCESS;
586}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
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.
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_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_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
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.
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_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
Definition SDDS_utils.c:304
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
long bitsSet(unsigned long data)
Counts the number of set bits (1s) in the given data.
Definition binary.c:52
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
short interp_short(short *f, double *x, int64_t n, double xo, long warnings, short order, unsigned long *returnCode, long *next_start_pos)
Performs interpolation for short integer data types.
Definition interp.c:281
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
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.

◆ makeFillInSequence()

double * makeFillInSequence ( double * x,
int64_t dataRows,
int64_t * nPointsReturn )

Definition at line 588 of file sddsinterp.c.

588 {
589 int64_t i;
590 double dxMin, dx, xMin, xMax;
591
592 dxMin = DBL_MAX;
593 xMin = xMax = x[0];
594 for (i = 1; i < dataRows; i++) {
595 if ((dx = fabs(x[i] - x[i - 1])) < dxMin && dx > 0)
596 dxMin = dx;
597 if (x[i] < xMin)
598 xMin = x[i];
599 if (x[i] > xMax)
600 xMax = x[i];
601 }
602 *nPointsReturn = (int64_t)((xMax - xMin) / dxMin + 1);
603 return makeSequence(nPointsReturn, xMin, xMax, 0.0, x, dataRows);
604}

◆ makeSequence()

double * makeSequence ( int64_t * points,
double start,
double end,
double spacing,
double * data,
int64_t dataRows )

Definition at line 606 of file sddsinterp.c.

606 {
607 int64_t i;
608 double delta, *sequence;
609 if (start == end) {
610 if (!find_min_max(&start, &end, data, dataRows))
611 return NULL;
612 }
613 if (*points > 1) {
614 delta = (end - start) / (*points - 1);
615 } else if (spacing >= 0) {
616 delta = spacing;
617 *points = (int64_t)((end - start) / delta + 1.5);
618 } else {
619 *points = 1;
620 delta = 0;
621 }
622 sequence = tmalloc(sizeof(*sequence) * (*points));
623 for (i = 0; i < *points; i++)
624 sequence[i] = start + delta * i;
625 return sequence;
626}

Variable Documentation

◆ option

char* option[N_OPTIONS]
Initial value:
= {
"order",
"atvalues",
"sequence",
"columns",
"printout",
"filevalues",
"combineduplicates",
"branch",
"belowrange",
"aboverange",
"pipe",
"exclude",
"forcemonotonic",
"fillin",
"equispaced",
"interpShort",
"majorOrder",
}

Definition at line 78 of file sddsinterp.c.

78 {
79 "order",
80 "atvalues",
81 "sequence",
82 "columns",
83 "printout",
84 "filevalues",
85 "combineduplicates",
86 "branch",
87 "belowrange",
88 "aboverange",
89 "pipe",
90 "exclude",
91 "forcemonotonic",
92 "fillin",
93 "equispaced",
94 "interpShort",
95 "majorOrder",
96};

◆ USAGE

char* USAGE
static
Initial value:
=
"Usage: sddsinterp [<inputfile>] [<outputfile>]\n"
" Options:\n"
" -pipe=[input][,output] Use pipe for input and/or output.\n"
" -columns=<independent>,<dependent1>[,...] Specify the independent and dependent columns.\n"
" -exclude=<name>[,...] Exclude specified columns from processing.\n"
" -atValues=<values-list> Interpolate at the specified list of values.\n"
" -sequence=<points>[,<start>,<end>] Generate a sequence of interpolation points.\n"
" -equispaced=<spacing>[,<start>,<end>] Generate equispaced interpolation points.\n"
" -fillIn Automatically fill in interpolation points based on data.\n"
" -fileValues=<valuesfile>[,column=<name>][,parallelPages]\n"
" Use values from a file for interpolation.\n"
" -interpShort=-1|-2 Interpolate short columns with order -1 or -2.\n"
" Order -1 inherits value from the previous point;\n"
" Order -2 inherits value from the next point.\n"
" -order=<number> Set the interpolation order (default is 1).\n"
" -printout[=bare][,stdout] Output interpolated data in bare format and/or to stdout.\n"
" -forceMonotonic[={increasing|decreasing}] Enforce monotonicity in the data.\n"
" -belowRange={value=<v>|skip|saturate|extrapolate|wrap}[,{abort|warn}]\n"
" Handle values below the interpolation range.\n"
" -aboveRange={value=<v>|skip|saturate|extrapolate|wrap}[,{abort|warn}]\n"
" Handle values above the interpolation range.\n"
" -majorOrder=row|column Set the major order of data storage.\n\n"
" Example:\n"
" sddsinterp input.sdds output.sdds -columns=energy,flux -atValues=1.0,2.0,3.0\n\n"
" Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 98 of file sddsinterp.c.