SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsminterp.c File Reference

Detailed Description

Multiplicative renormalized model interpolation utility for SDDS data sets.

This program performs interpolation of data using another data set as a model function. It utilizes abscissa values from either a values file or the model function file to generate interpolated results. Multiple options allow for customization of interpolation parameters, output formats, and verbosity. The program supports SDDS files for both input and output.

Usage

sddsminterp <input-file> <output-file>
[-pipe=[input],[output]]
-columns=<independent-quantity>,<name>
[-interpOrder=<order>]
-model=<modelFile>,abscissa=<column>,ordinate=<column>[,interp=<order>]
[-fileValues=<valuesFile>[,abscissa=<column>]]
[-majorOrder=row|column]
[-verbose]
[-ascii]
double interp(double *f, double *x, long n, double xo, long warnings, long order, long *returnCode)
Performs simple linear interpolation of data.
Definition interp.c:34

Options

Required Description
-columns Specify the columns for interpolation.
-model Define the model dataset with required abscissa and ordinate columns.
Optional Description
-pipe Use pipes for input and output.
-interpOrder Set the interpolation order (default is 1).
-fileValues Provide abscissa values for interpolation from a file.
-majorOrder Set output data order as row or column.
-verbose Enable detailed output logging.
-ascii Produce ASCII-formatted output.

Incompatibilities

  • -fileValues is not operational yet
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 sddsminterp.c.

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

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 122 of file sddsminterp.c.

122 {
123 SCANNED_ARG *s_arg;
124 SDDS_DATASET modDataSet, valDataSet, dataDataSet, outDataSet;
125 unsigned long modFlags, valFlags, majorOrderFlag;
126 char *modAbscissaName, *modOrdinateName;
127 char *valAbscissaName;
128 char *dataAbscissaName, *dataOrdinateName;
129 char *outAbscissaName, *outOrdinateName;
130 char *modFile, *dataFile, *valFile, *outFile;
131 long dataOrder;
132 int32_t modOrder;
133 double *modAbscissa, *modOrdinate;
134 double *valAbscissa;
135 double *dataAbscissa, *dataOrdinate, *dataScale, *dataOrdinateInterp;
136 double *outScale, *outAbscissa, *outOrdinate;
137 int64_t i, modRows, valRows, dataRows, outRows;
138
139 long i_arg;
140 /*long verbose; */
141 long warning;
142 long ascii;
143 long returnCode;
144 unsigned long pipeFlags;
145 long tmpfile_used, noWarnings;
146 short columnMajorOrder = -1;
147
149 argc = scanargs(&s_arg, argc, argv);
150 if (argc == 1)
151 bomb(NULL, USAGE);
152
153 /* Initialize variables */
154 /*verbose=0; */
155 dataFile = dataAbscissaName = dataOrdinateName = modFile = valFile = NULL;
156 modOrdinate = dataOrdinate = NULL;
157 outFile = NULL;
158 warning = 0;
159 modOrder = DEFAULT_ORDER;
160 dataOrder = DEFAULT_ORDER;
161 ascii = 0;
162 modFlags = 0x0UL;
163 valFlags = 0x0UL;
164 pipeFlags = 0;
165 tmpfile_used = 0;
166 noWarnings = 0;
167
168 for (i_arg = 1; i_arg < argc; i_arg++) {
169 if (s_arg[i_arg].arg_type == OPTION) {
170 switch (match_string(s_arg[i_arg].list[0], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
171 case CLO_MAJOR_ORDER:
172 majorOrderFlag = 0;
173 s_arg[i_arg].n_items--;
174 if (s_arg[i_arg].n_items > 0 &&
175 !scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
176 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
177 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER,
178 NULL))
179 SDDS_Bomb("Invalid -majorOrder syntax or values");
180 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
181 columnMajorOrder = 1;
182 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
183 columnMajorOrder = 0;
184 break;
185 case CLO_VERBOSE:
186 /*verbose=1; */
187 break;
188 case CLO_ASCII:
189 ascii = 1;
190 break;
191 case CLO_PIPE:
192 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
193 SDDS_Bomb("Invalid -pipe syntax");
194 break;
195 case CLO_MODEL:
196 if ((s_arg[i_arg].n_items -= 2) < 0 ||
197 !scanItemList(&modFlags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
198 "abscissa", SDDS_STRING, &modAbscissaName, 1, MOD_ABSCISSA,
199 "ordinate", SDDS_STRING, &modOrdinateName, 1, MOD_ORDINATE,
200 "interp", SDDS_LONG, &modOrder, 1, MOD_ORDER,
201 NULL) ||
202 !(modFlags & MOD_ABSCISSA) || !(modFlags & MOD_ORDINATE))
203 bomb("Invalid -model syntax", modUsage);
204 if (!strlen(modFile = s_arg[i_arg].list[1]))
205 bomb("Invalid -model syntax", modUsage);
206 break;
207 case CLO_VALUES:
208 if ((s_arg[i_arg].n_items -= 2) < 0 ||
209 !scanItemList(&valFlags, s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
210 "abscissa", SDDS_STRING, &valAbscissaName, 1, VAL_ABSCISSA,
211 NULL) ||
212 !(valFlags & VAL_ABSCISSA))
213 bomb("Invalid -fileValues syntax", valUsage);
214 if (!strlen(valFile = s_arg[i_arg].list[1]))
215 bomb("Invalid -fileValues syntax", valUsage);
216 break;
217 case CLO_ORDER:
218 if (!get_long(&dataOrder, s_arg[i_arg].list[1]))
219 bomb("No value provided for option -order", USAGE);
220 break;
221 case CLO_COLUMNS:
222 /* The input file and the -order and -columns options could be combined more
223 compactly to resemble the syntax of the -model option.
224 However, we adopt the command line options of the
225 command sddsinterp since it allows an input pipe */
226 if (s_arg[i_arg].n_items != 3 ||
227 !strlen(dataAbscissaName = s_arg[i_arg].list[1]) ||
228 !strlen(dataOrdinateName = s_arg[i_arg].list[2]))
229 SDDS_Bomb("Invalid -columns syntax");
230 break;
231 default:
232 SDDS_Bomb("Unrecognized option provided");
233 }
234 } else {
235 if (!dataFile)
236 dataFile = s_arg[i_arg].list[0];
237 else if (!outFile)
238 outFile = s_arg[i_arg].list[0];
239 else
240 SDDS_Bomb("Too many filenames provided");
241 }
242 }
243
244 processFilenames("sddsminterp", &dataFile, &outFile, pipeFlags, noWarnings, &tmpfile_used);
245
246 if (valFlags) {
247 fprintf(stderr, "Warning: Option -fileValues is not operational yet. Using model abscissa values.\n");
248 }
249
250 if (!SDDS_InitializeInput(&modDataSet, modFile))
251 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
252 if (SDDS_ReadPage(&modDataSet) < 0)
253 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
254
255 if (valFlags) {
256 if (!SDDS_InitializeInput(&valDataSet, valFile))
257 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
258 if (SDDS_ReadPage(&valDataSet) < 0)
259 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
260 }
261
262 /* Check that the selected columns exist */
263 switch (SDDS_CheckColumn(&modDataSet, modAbscissaName, NULL, SDDS_DOUBLE, NULL)) {
264 case SDDS_CHECK_NONEXISTENT:
265 fprintf(stderr, "Error: Column '%s' does not exist in file '%s'.\n", modAbscissaName, modFile);
266 exit(EXIT_FAILURE);
267 }
268 switch (SDDS_CheckColumn(&modDataSet, modOrdinateName, NULL, SDDS_DOUBLE, NULL)) {
269 case SDDS_CHECK_NONEXISTENT:
270 fprintf(stderr, "Error: Column '%s' does not exist in file '%s'.\n", modOrdinateName, modFile);
271 exit(EXIT_FAILURE);
272 }
273
274 if (valFlags) {
275 switch (SDDS_CheckColumn(&valDataSet, valAbscissaName, NULL, SDDS_DOUBLE, NULL)) {
276 case SDDS_CHECK_NONEXISTENT:
277 fprintf(stderr, "Error: Column '%s' does not exist in file '%s'.\n", valAbscissaName, valFile);
278 exit(EXIT_FAILURE);
279 }
280 }
281
282 modRows = SDDS_CountRowsOfInterest(&modDataSet);
283 modAbscissa = (double *)SDDS_GetColumnInDoubles(&modDataSet, modAbscissaName);
284 modOrdinate = (double *)SDDS_GetColumnInDoubles(&modDataSet, modOrdinateName);
285 if (!modAbscissa || !modOrdinate)
286 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
287
288 if (valFlags) {
289 valRows = SDDS_CountRowsOfInterest(&valDataSet);
290 valAbscissa = (double *)SDDS_GetColumnInDoubles(&valDataSet, valAbscissaName);
291 if (!valAbscissa)
292 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
293 outAbscissa = valAbscissa;
294 outRows = valRows;
295 } else {
296 outAbscissa = modAbscissa;
297 outRows = modRows;
298 }
299
300 if (!SDDS_InitializeInput(&dataDataSet, dataFile))
301 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
302
303 switch (SDDS_CheckColumn(&dataDataSet, dataAbscissaName, NULL, SDDS_DOUBLE, NULL)) {
304 case SDDS_CHECK_NONEXISTENT:
305 fprintf(stderr, "Error: Column '%s' does not exist in file '%s'.\n", dataAbscissaName, dataFile);
306 exit(EXIT_FAILURE);
307 }
308 switch (SDDS_CheckColumn(&dataDataSet, dataOrdinateName, NULL, SDDS_DOUBLE, NULL)) {
309 case SDDS_CHECK_NONEXISTENT:
310 fprintf(stderr, "Error: Column '%s' does not exist in file '%s'.\n", dataOrdinateName, dataFile);
311 exit(EXIT_FAILURE);
312 }
313
314 if (!SDDS_InitializeOutput(&outDataSet, ascii ? SDDS_ASCII : SDDS_BINARY, 1,
315 "Interpolation data from model file", "Interpolated data", outFile) ||
316 !SDDS_InitializeCopy(&outDataSet, &dataDataSet, outFile, "w"))
317 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
318
319 if (columnMajorOrder != -1)
320 outDataSet.layout.data_mode.column_major = columnMajorOrder;
321 else
322 outDataSet.layout.data_mode.column_major = dataDataSet.layout.data_mode.column_major;
323
324 if (!SDDS_WriteLayout(&outDataSet))
325 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
326
327 if (valFlags) {
328 SDDS_CopyString(&outAbscissaName, valAbscissaName);
329 } else {
330 SDDS_CopyString(&outAbscissaName, modAbscissaName);
331 }
332 SDDS_CopyString(&outOrdinateName, dataOrdinateName);
333
334 while (SDDS_ReadPage(&dataDataSet) > 0) {
335 dataAbscissa = (double *)SDDS_GetColumnInDoubles(&dataDataSet, dataAbscissaName);
336 dataOrdinate = (double *)SDDS_GetColumnInDoubles(&dataDataSet, dataOrdinateName);
337 if (!dataAbscissa || !dataOrdinate)
338 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
339
340 dataRows = SDDS_CountRowsOfInterest(&dataDataSet);
341 dataOrdinateInterp = (double *)malloc(sizeof(double) * dataRows);
342 dataScale = (double *)malloc(sizeof(double) * dataRows);
343
344 outScale = (double *)malloc(sizeof(double) * outRows);
345 outOrdinate = (double *)malloc(sizeof(double) * outRows);
346
347 /* There are normally more rows in the model file or value file than in the data file. */
348 for (i = 0; i < dataRows; i++) {
349 dataOrdinateInterp[i] = interp(modOrdinate, modAbscissa, modRows, dataAbscissa[i], warning, modOrder, &returnCode);
350 dataScale[i] = dataOrdinate[i] / dataOrdinateInterp[i]; /* dataScale is a numerator */
351 }
352
353 for (i = 0; i < outRows; i++) {
354 outScale[i] = interp(dataScale, dataAbscissa, dataRows, outAbscissa[i], warning, dataOrder, &returnCode);
355 outOrdinate[i] = modOrdinate[i] * outScale[i];
356 }
357
358 if (SDDS_StartPage(&outDataSet, outRows) < 0)
359 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
360
361 if (!SDDS_CopyParameters(&outDataSet, &dataDataSet) ||
362 !SDDS_CopyArrays(&outDataSet, &dataDataSet) ||
363 !SDDS_SetColumn(&outDataSet, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, modAbscissa, outRows, outAbscissaName) ||
364 !SDDS_SetColumn(&outDataSet, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, outOrdinate, outRows, outOrdinateName) ||
365 SDDS_WritePage(&outDataSet) < 0)
366 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
367
368 free(dataAbscissa);
369 free(dataOrdinate);
370 free(dataOrdinateInterp);
371 free(dataScale);
372 free(outScale);
373 free(outOrdinate);
374 }
375
376 if (!SDDS_Terminate(&modDataSet) ||
377 !SDDS_Terminate(&outDataSet) ||
378 !SDDS_Terminate(&dataDataSet))
379 SDDS_PrintErrors(stdout, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
380
381 if (tmpfile_used && !replaceFileAndBackUp(dataFile, outFile))
382 exit(EXIT_FAILURE);
383
384 return EXIT_SUCCESS;
385}
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_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
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_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
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
#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 bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
int get_long(long *iptr, char *s)
Parses a long integer value from the given string.
Definition data_scan.c:255
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.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
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.