SDDSlib
Loading...
Searching...
No Matches
sddsinteg.c
Go to the documentation of this file.
1/**
2 * @file sddsinteg.c
3 * @brief Integrates a dataset using specified columns and methods.
4 *
5 * This program performs numerical integration on specified columns of an SDDS
6 * dataset. It supports various integration methods, error propagation, and
7 * customizable output templates. Users can specify input and output files,
8 * integrate multiple columns, exclude certain columns, and format the output
9 * as needed.
10 *
11 * Usage:
12 * sddsinteg [<input>] [<output>] [-pipe=[input][,output]]
13 * -integrate=<column-name>[,<sigma-name>] ...
14 * [-exclude=<column-name>[,...]] -versus=<column-name>[,<sigma-name>]
15 * [-mainTemplates=<item>=<string>[,...]]
16 * [-errorTemplates=<item>=<string>[,...]]
17 * [-copycolumns=<list of column names>]
18 * [-method={trapazoid|GillMiller}]
19 * [-printFinal[=bare][,stdout][,format=<string>]]
20 *
21 * Options:
22 * -pipe Standard SDDS pipe option.
23 * -integrate Name of column to integrate, plus optional RMS error.
24 * Column name may include wildcards, in which case the error
25 * name should include the field %s for substitution of the main name.
26 * -exclude List of column names to exclude from integration.
27 * -versus Name of column to integrate against, plus optional RMS error.
28 * -mainTemplates=<item>=<string>
29 * Customize the main templates for name, symbol, or description.
30 * Example items: "name", "symbol", "description".
31 * -errorTemplates=<item>=<string>
32 * Customize the error templates for name, symbol, or description.
33 * Example items: "name", "symbol", "description".
34 * -copycolumns Provide a comma-separated list of columns to copy from the input
35 * file to the output file.
36 * -method Integration method to use. Options are:
37 * trapazoid (default) - Trapezoidal rule.
38 * GillMiller - Gill-Miller method (more accurate but no error propagation).
39 * -printFinal Print the final value of the integral. Options:
40 * bare - Print only the integral value.
41 * stdout - Print to standard output.
42 * format=<string> - Specify the format for printing.
43 *
44 * @copyright
45 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
46 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
47 *
48 * @license
49 * This file is distributed under the terms of the Software License Agreement
50 * found in the file LICENSE included with this distribution.
51 *
52 * @author M. Borland, C. Saunders, R. Soliday, H. Shang
53 */
54
55#include "mdb.h"
56#include "SDDS.h"
57#include "SDDSutils.h"
58#include "scan.h"
59#include <ctype.h>
60
61static char *USAGE =
62 "Usage: sddsinteg [<input>] [<output>] [-pipe=[input][,output]]\n"
63 " -integrate=<column-name>[,<sigma-name>] ...\n"
64 " [-exclude=<column-name>[,...]]\n"
65 " -versus=<column-name>[,<sigma-name>]\n"
66 " [-mainTemplates=<item>=<string>[,...]]\n"
67 " [-errorTemplates=<item>=<string>[,...]]\n"
68 " [-copycolumns=<list of column names>]\n"
69 " [-method={trapazoid|GillMiller}]\n"
70 " [-printFinal[=bare][,stdout][,format=<string>]]\n\n"
71 "Options:\n"
72 " -pipe Standard SDDS pipe option.\n"
73 " -integrate Name of column to integrate, plus optional RMS error.\n"
74 " Column name may include wildcards, with error name using %%s.\n"
75 " -exclude List of column names to exclude from integration.\n"
76 " -versus Name of column to integrate against, plus optional RMS error.\n"
77 " -mainTemplates Customize main templates for name, symbol, or description.\n"
78 " -errorTemplates Customize error templates for name, symbol, or description.\n"
79 " -copycolumns Comma-separated list of columns to copy to the output.\n"
80 " -method Integration method: trapazoid (default) or GillMiller.\n"
81 " -printFinal Print the final integral value. Options:\n"
82 " bare - Print only the integral value.\n"
83 " stdout - Print to standard output.\n"
84 " format=<s> - Specify printf format string.\n\n"
85 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")";
86
87/* Enumeration for option types */
88enum option_type {
89 CLO_INTEGRATE,
90 CLO_VERSUS,
91 CLO_METHOD,
92 CLO_PRINTFINAL,
93 CLO_MAINTEMPLATE,
94 CLO_ERRORTEMPLATE,
95 CLO_PIPE,
96 CLO_EXCLUDE,
97 CLO_MAJOR_ORDER,
98 CLO_COPY,
99 N_OPTIONS
100};
101
102static char *option[N_OPTIONS] = {
103 "integrate",
104 "versus",
105 "method",
106 "printfinal",
107 "maintemplate",
108 "errortemplate",
109 "pipe",
110 "exclude",
111 "majorOrder",
112 "copycolumns",
113};
114
115void trapizoid(double *x, double *y, double *sx, double *sy, int64_t n, double *integ, double *error);
116long checkErrorNames(char **yErrorName, long nIntegrals);
117void makeSubstitutions(char *buffer1, char *buffer2, char *template, char *nameRoot, char *symbolRoot, char *xName, char *xSymbol);
118char *changeInformation(SDDS_DATASET *SDDSout, char *name, char *nameRoot, char *symbolRoot,
119 char *xName, char *xSymbol, char **template, char *newUnits);
120long setupOutputFile(SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, char *output,
121 char ***yOutputName, char ***yOutputErrorName, char ***yOutputUnits,
122 char *xName, char *xErrorName, char **yName, char **yErrorName,
123 long yNames, char **mainTemplate, char **errorTemplate, long methodCode,
124 short columnMajorOrder, char **colMatch, int32_t colMatches);
125
126#define NORMAL_PRINTOUT 1
127#define BARE_PRINTOUT 2
128#define STDOUT_PRINTOUT 4
129
130#define TRAPAZOID_METHOD 0
131#define GILLMILLER_METHOD 1
132#define N_METHODS 2
133
134static char *methodOption[N_METHODS] = {
135 "trapazoid",
136 "gillmiller"
137};
138
139int main(int argc, char **argv) {
140 double *xData = NULL, *yData = NULL, *xError = NULL, *yError = NULL, *integral = NULL, *integralError = NULL;
141 char *input = NULL, *output = NULL, *xName = NULL, *xErrorName = NULL;
142 char **yName = NULL, **yErrorName = NULL, **yOutputName = NULL, **yOutputErrorName = NULL, *ptr = NULL, **colMatch = NULL;
143 char **yOutputUnits = NULL, **yExcludeName = NULL;
144 char *mainTemplate[3] = {"%yNameInteg", "Integral w.r.t. %xSymbol of %ySymbol", "$sI$e %ySymbol d%xSymbol"};
145 char *errorTemplate[3] = {"%yNameIntegSigma", "Sigma of integral w.r.t. %xSymbol of %ySymbol",
146 "Sigma[$sI$e %ySymbol d%xSymbol]"};
147 char *GMErrorTemplate[3] = {"%yNameIntegError", "Error estimate for integral w.r.t. %xSymbol of %ySymbol",
148 "Error[$sI$e %ySymbol d%xSymbol]"};
149 long i, iArg, yNames = 0, yExcludeNames = 0;
150 int32_t colMatches = 0;
151 int64_t rows;
152 SDDS_DATASET SDDSin, SDDSout;
153 SCANNED_ARG *scanned = NULL;
154 unsigned long flags = 0, pipeFlags = 0, printFlags = 0, majorOrderFlag = 0;
155 FILE *fpPrint = stderr;
156 char *printFormat = "%21.15e";
157 int methodCode = TRAPAZOID_METHOD;
158 short columnMajorOrder = -1;
159
161
162 argc = scanargs(&scanned, argc, argv);
163 if (argc == 1) {
164 fprintf(stderr, "%s\n", USAGE);
165 return EXIT_FAILURE;
166 }
167
168 colMatch = NULL;
169 colMatches = 0;
170 input = output = xName = xErrorName = NULL;
171 yName = yErrorName = yExcludeName = NULL;
172 integral = integralError = yError = yData = xData = xError = NULL;
173 yNames = yExcludeNames = 0;
174 pipeFlags = printFlags = 0;
175 fpPrint = stderr;
176 printFormat = "%21.15e";
177 methodCode = TRAPAZOID_METHOD;
178
179 for (iArg = 1; iArg < argc; iArg++) {
180 if (scanned[iArg].arg_type == OPTION) {
181 /* process options here */
182 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
183 case CLO_MAJOR_ORDER:
184 majorOrderFlag = 0;
185 scanned[iArg].n_items--;
186 if (scanned[iArg].n_items > 0 &&
187 !scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
188 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
189 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)) {
190 SDDS_Bomb("invalid -majorOrder syntax/values");
191 }
192 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
193 columnMajorOrder = 1;
194 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
195 columnMajorOrder = 0;
196 break;
197 case CLO_INTEGRATE:
198 if (scanned[iArg].n_items != 2 && scanned[iArg].n_items != 3)
199 SDDS_Bomb("invalid -integrate syntax");
200 yName = SDDS_Realloc(yName, sizeof(*yName) * (yNames + 1));
201 yErrorName = SDDS_Realloc(yErrorName, sizeof(*yErrorName) * (yNames + 1));
202 yName[yNames] = scanned[iArg].list[1];
203 if (scanned[iArg].n_items == 3)
204 yErrorName[yNames] = scanned[iArg].list[2];
205 else
206 yErrorName[yNames] = NULL;
207 yNames++;
208 break;
209 case CLO_EXCLUDE:
210 if (scanned[iArg].n_items < 2)
211 SDDS_Bomb("invalid -exclude syntax");
212 moveToStringArray(&yExcludeName, &yExcludeNames, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
213 break;
214 case CLO_VERSUS:
215 if (xName)
216 SDDS_Bomb("give -versus only once");
217 if (scanned[iArg].n_items != 2 && scanned[iArg].n_items != 3)
218 SDDS_Bomb("invalid -versus syntax");
219 xName = scanned[iArg].list[1];
220 if (scanned[iArg].n_items == 3)
221 xErrorName = scanned[iArg].list[2];
222 else
223 xErrorName = NULL;
224 break;
225 case CLO_METHOD:
226 if (scanned[iArg].n_items != 2 ||
227 (methodCode = match_string(scanned[iArg].list[1], methodOption, N_METHODS, 0)) < 0)
228 SDDS_Bomb("invalid -method syntax");
229 break;
230 case CLO_PRINTFINAL:
231 if ((scanned[iArg].n_items -= 1) >= 1) {
232 if (!scanItemList(&printFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
233 "bare", -1, NULL, 0, BARE_PRINTOUT,
234 "stdout", -1, NULL, 0, STDOUT_PRINTOUT,
235 "format", SDDS_STRING, &printFormat, 1, 0, NULL)) {
236 SDDS_Bomb("invalid -printFinal syntax");
237 }
238 }
239 if (!(printFlags & BARE_PRINTOUT))
240 printFlags |= NORMAL_PRINTOUT;
241 break;
242 case CLO_MAINTEMPLATE:
243 if (scanned[iArg].n_items < 2)
244 SDDS_Bomb("invalid -mainTemplate syntax");
245 scanned[iArg].n_items--;
246 if (!scanItemList(&flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
247 "name", SDDS_STRING, mainTemplate + 0, 1, 0,
248 "description", SDDS_STRING, mainTemplate + 1, 1, 0,
249 "symbol", SDDS_STRING, mainTemplate + 2, 1, 0, NULL)) {
250 SDDS_Bomb("invalid -mainTemplate syntax");
251 }
252 break;
253 case CLO_ERRORTEMPLATE:
254 if (scanned[iArg].n_items < 2)
255 SDDS_Bomb("invalid -errorTemplate syntax");
256 scanned[iArg].n_items--;
257 if (!scanItemList(&flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
258 "name", SDDS_STRING, errorTemplate + 0, 1, 0,
259 "description", SDDS_STRING, errorTemplate + 1, 1, 0,
260 "symbol", SDDS_STRING, errorTemplate + 2, 1, 0, NULL)) {
261 SDDS_Bomb("invalid -errorTemplate syntax");
262 }
263 break;
264 case CLO_PIPE:
265 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
266 SDDS_Bomb("invalid -pipe syntax");
267 break;
268 case CLO_COPY:
269 if (scanned[iArg].n_items < 2)
270 SDDS_Bomb("Invalid copycolumns syntax provided.");
271 colMatch = tmalloc(sizeof(*colMatch) * (colMatches = scanned[iArg].n_items - 1));
272 for (i = 0; i < colMatches; i++)
273 colMatch[i] = scanned[iArg].list[i + 1];
274 break;
275 default:
276 fprintf(stderr, "invalid option seen: %s\n", scanned[iArg].list[0]);
277 return EXIT_FAILURE;
278 }
279 } else {
280 if (!input)
281 input = scanned[iArg].list[0];
282 else if (!output)
283 output = scanned[iArg].list[0];
284 else
285 SDDS_Bomb("too many filenames");
286 }
287 }
288
289 processFilenames("sddsinteg", &input, &output, pipeFlags, 0, NULL);
290
291 if (methodCode != TRAPAZOID_METHOD) {
292 xErrorName = NULL;
293 for (i = 0; i < yNames; i++)
294 yErrorName[i] = NULL;
295 }
296
297 if (printFlags & STDOUT_PRINTOUT)
298 fpPrint = stdout;
299
300 if (yNames == 0)
301 SDDS_Bomb("-integrate option must be given at least once");
302 if (!checkErrorNames(yErrorName, yNames))
303 SDDS_Bomb("either all -integrate quantities must have errors, or none");
304
305 if (!SDDS_InitializeInput(&SDDSin, input))
306 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
307
308 if (!(ptr = SDDS_FindColumn(&SDDSin, FIND_NUMERIC_TYPE, xName, NULL))) {
309 fprintf(stderr, "error: column %s doesn't exist\n", xName);
310 return EXIT_FAILURE;
311 }
312 free(xName);
313 xName = ptr;
314
315 if (xErrorName) {
316 if (!(ptr = SDDS_FindColumn(&SDDSin, FIND_NUMERIC_TYPE, xErrorName, NULL))) {
317 fprintf(stderr, "error: column %s doesn't exist\n", xErrorName);
318 return EXIT_FAILURE;
319 } else {
320 free(xErrorName);
321 xErrorName = ptr;
322 }
323 }
324
325 if (!(yNames = expandColumnPairNames(&SDDSin, &yName, &yErrorName, yNames, yExcludeName, yExcludeNames, FIND_NUMERIC_TYPE, 0))) {
326 fprintf(stderr, "error: no quantities to integrate found in file\n");
327 return EXIT_FAILURE;
328 }
329
330 if (!setupOutputFile(&SDDSout, &SDDSin, output, &yOutputName, &yOutputErrorName, &yOutputUnits,
331 xName, xErrorName, yName, yErrorName, yNames,
332 mainTemplate, (methodCode == GILLMILLER_METHOD) ? (char **)GMErrorTemplate : (char **)errorTemplate,
333 methodCode, columnMajorOrder, colMatch, colMatches)) {
334 SDDS_Bomb("Failed to set up output file.");
335 }
336
337 while (SDDS_ReadPage(&SDDSin) > 0) {
338 rows = SDDS_CountRowsOfInterest(&SDDSin);
339 integral = SDDS_Realloc(integral, sizeof(*integral) * rows);
340 integralError = SDDS_Realloc(integralError, sizeof(*integralError) * rows);
341 if (!SDDS_StartPage(&SDDSout, rows) ||
342 !SDDS_CopyPage(&SDDSout, &SDDSin))
343 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
344
345 xError = NULL;
346 if (!(xData = SDDS_GetColumnInDoubles(&SDDSin, xName)) ||
347 (xErrorName && !(xError = SDDS_GetColumnInDoubles(&SDDSin, xErrorName))))
348 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
349
350 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, xData, rows, xName) ||
351 (xErrorName && !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, xError, rows, xErrorName)))
352 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
353
354 for (i = 0; i < yNames; i++) {
355 yError = NULL;
356 if (!(yData = SDDS_GetColumnInDoubles(&SDDSin, yName[i])) ||
357 (yErrorName && yErrorName[i] &&
358 !(yError = SDDS_GetColumnInDoubles(&SDDSin, yErrorName[i]))))
359 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
360
361 switch (methodCode) {
362 case TRAPAZOID_METHOD:
363 trapizoid(xData, yData, xError, yError, rows, integral, integralError);
364 break;
365 case GILLMILLER_METHOD:
366 if (GillMillerIntegration(integral, integralError, yData, xData, rows) != 0)
367 SDDS_Bomb("Problem with integration: check for monotonically changing independent variable values");
368 break;
369 }
370
371 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, integral, rows, yOutputName[i]) ||
372 (yOutputErrorName && yOutputErrorName[i] &&
373 !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, integralError, rows, yOutputErrorName[i])))
374 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
375
376 if (printFlags & BARE_PRINTOUT) {
377 fprintf(fpPrint, printFormat, integral[rows - 1]);
378 if (xError || yError || (yOutputErrorName && yOutputErrorName[i])) {
379 fputc(' ', fpPrint);
380 fprintf(fpPrint, printFormat, integralError[rows - 1]);
381 }
382 fputc('\n', fpPrint);
383 } else if (printFlags & NORMAL_PRINTOUT) {
384 fprintf(fpPrint, "%s: ", yName[i]);
385 fprintf(fpPrint, printFormat, integral[rows - 1]);
386 if (xError || yError || (yOutputErrorName && yOutputErrorName[i])) {
387 fputs(" +/- ", fpPrint);
388 fprintf(fpPrint, printFormat, integralError[rows - 1]);
389 fputs(yOutputUnits[i], fpPrint);
390 }
391 fputc('\n', fpPrint);
392 }
393
394 if (yData)
395 free(yData);
396 if (yError)
397 free(yError);
398 yData = yError = NULL;
399 }
400
401 if (!SDDS_WritePage(&SDDSout))
402 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
403
404 if (xData)
405 free(xData);
406 if (xError)
407 free(xError);
408 xData = xError = NULL;
409 }
410
411 if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
412 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
413 return EXIT_FAILURE;
414 }
415
416 if (integral)
417 free(integral);
418 if (integralError)
419 free(integralError);
420 if (colMatch)
421 free(colMatch);
422
423 return EXIT_SUCCESS;
424}
425
426long setupOutputFile(SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, char *output,
427 char ***yOutputName, char ***yOutputErrorName, char ***yOutputUnits,
428 char *xName, char *xErrorName, char **yName, char **yErrorName,
429 long yNames, char **mainTemplate, char **errorTemplate, long methodCode,
430 short columnMajorOrder, char **colMatch, int32_t colMatches) {
431 long i;
432 char *xSymbol = NULL, *ySymbol = NULL, **col = NULL;
433 int32_t cols = 0;
434
435 *yOutputName = tmalloc(sizeof(**yOutputName) * yNames);
436 *yOutputErrorName = tmalloc(sizeof(**yOutputErrorName) * yNames);
437 *yOutputUnits = tmalloc(sizeof(**yOutputUnits) * yNames);
438
439 if (!SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL, "sddsinteg output", output))
440 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
441
442 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, xName, NULL) ||
443 (xErrorName && !SDDS_TransferColumnDefinition(SDDSout, SDDSin, xErrorName, NULL)))
444 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
445
446 if (SDDS_GetColumnInformation(SDDSout, "symbol", &xSymbol, SDDS_GET_BY_NAME, xName) != SDDS_STRING) {
447 fprintf(stderr, "error: problem getting symbol for column %s\n", xName);
448 return EXIT_FAILURE;
449 }
450
451 if (columnMajorOrder != -1)
452 SDDSout->layout.data_mode.column_major = columnMajorOrder;
453 else
454 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
455
456 if (!xSymbol)
457 SDDS_CopyString(&xSymbol, xName);
458
459 for (i = 0; i < yNames; i++) {
460 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, yName[i], NULL)) {
461 fprintf(stderr, "error: problem transferring definition for column %s\n", yName[i]);
462 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
463 }
464
465 if (SDDS_GetColumnInformation(SDDSout, "symbol", &ySymbol, SDDS_GET_BY_NAME, yName[i]) != SDDS_STRING) {
466 fprintf(stderr, "error: problem getting symbol for column %s\n", yName[i]);
467 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
468 }
469
470 if (!ySymbol || SDDS_StringIsBlank(ySymbol))
471 SDDS_CopyString(&ySymbol, yName[i]);
472
473 (*yOutputUnits)[i] = multiplyColumnUnits(SDDSout, yName[i], xName);
474 (*yOutputName)[i] = changeInformation(SDDSout, yName[i], yName[i], ySymbol, xName, xSymbol, mainTemplate, (*yOutputUnits)[i]);
475
476 if (yErrorName || xErrorName || methodCode == GILLMILLER_METHOD) {
477 if (yErrorName && yErrorName[i]) {
478 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, yErrorName[i], NULL)) {
479 fprintf(stderr, "error: problem transferring definition for column %s\n", yErrorName[i]);
480 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
481 }
482 (*yOutputErrorName)[i] = changeInformation(SDDSout, yErrorName[i], yName[i], ySymbol, xName, xSymbol, errorTemplate, (*yOutputUnits)[i]);
483 } else {
484 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, yName[i], NULL)) {
485 fprintf(stderr, "error: problem transferring error definition for column %s\n", yName[i]);
486 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
487 }
488 (*yOutputErrorName)[i] = changeInformation(SDDSout, yName[i], yName[i], ySymbol, xName, xSymbol, errorTemplate, (*yOutputUnits)[i]);
489 }
490 } else {
491 (*yOutputErrorName)[i] = NULL;
492 }
493 }
494
495 if (colMatches) {
496 col = getMatchingSDDSNames(SDDSin, colMatch, colMatches, &cols, SDDS_MATCH_COLUMN);
497 for (i = 0; i < cols; i++) {
498 if (SDDS_GetColumnIndex(SDDSout, col[i]) < 0 && !SDDS_TransferColumnDefinition(SDDSout, SDDSin, col[i], NULL))
499 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
500 }
501 SDDS_FreeStringArray(col, cols);
502 free(col);
503 }
504
505 if (!SDDS_TransferAllParameterDefinitions(SDDSout, SDDSin, SDDS_TRANSFER_KEEPOLD) ||
506 !SDDS_WriteLayout(SDDSout))
507 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
508
509 return 1;
510}
511
512char *changeInformation(SDDS_DATASET *SDDSout, char *name, char *nameRoot, char *symbolRoot,
513 char *xName, char *xSymbol, char **template, char *newUnits) {
514 char buffer1[SDDS_MAXLINE], buffer2[SDDS_MAXLINE], *ptr = NULL;
515
516 if (!SDDS_ChangeColumnInformation(SDDSout, "units", newUnits, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
517 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
518
519 makeSubstitutions(buffer1, buffer2, template[2], nameRoot, symbolRoot, xName, xSymbol);
520 if (!SDDS_ChangeColumnInformation(SDDSout, "symbol", buffer2, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
521 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
522
523 makeSubstitutions(buffer1, buffer2, template[1], nameRoot, symbolRoot, xName, xSymbol);
524 if (!SDDS_ChangeColumnInformation(SDDSout, "description", buffer2, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
525 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
526
527 makeSubstitutions(buffer1, buffer2, template[0], nameRoot, symbolRoot, xName, xSymbol);
528 if (!SDDS_ChangeColumnInformation(SDDSout, "name", buffer2, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
529 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
530
531 SDDS_CopyString(&ptr, buffer2);
532 return ptr;
533}
534
535void makeSubstitutions(char *buffer1, char *buffer2, char *template, char *nameRoot, char *symbolRoot,
536 char *xName, char *xSymbol) {
537 strcpy(buffer2, template);
538 replace_string(buffer1, buffer2, "%ySymbol", symbolRoot);
539 replace_string(buffer2, buffer1, "%xSymbol", xSymbol);
540 replace_string(buffer1, buffer2, "%yName", nameRoot);
541 replace_string(buffer2, buffer1, "%xName", xName);
542 strcpy(buffer1, buffer2);
543}
544
545void trapizoid(double *x, double *y, double *sx, double *sy, int64_t n, double *integ, double *error) {
546 double dx, dy;
547 int64_t i;
548
549 integ[0] = error[0] = 0;
550 for (i = 1; i < n; i++) {
551 dy = y[i] + y[i - 1];
552 dx = x[i] - x[i - 1];
553 integ[i] = integ[i - 1] + dy * dx;
554 if (sx && sy)
555 error[i] = error[i - 1] + sqr(dy) * (sqr(sx[i - 1]) + sqr(sx[i])) + sqr(dx) * (sqr(sy[i - 1]) + sqr(sy[i]));
556 else if (sx)
557 error[i] = error[i - 1] + sqr(dy) * (sqr(sx[i - 1]) + sqr(sx[i]));
558 else if (sy)
559 error[i] = error[i - 1] + sqr(dx) * (sqr(sy[i - 1]) + sqr(sy[i]));
560 else
561 error[i] = 0;
562 }
563 for (i = 0; i < n; i++) {
564 error[i] = sqrt(error[i]) / 2;
565 integ[i] /= 2;
566 }
567}
568
569long checkErrorNames(char **yErrorName, long yNames) {
570 long i;
571 if (yErrorName[0]) {
572 for (i = 1; i < yNames; i++)
573 if (!yErrorName[i])
574 return 0;
575 } else {
576 for (i = 1; i < yNames; i++)
577 if (yErrorName[i])
578 return 0;
579 }
580 return 1;
581}
int GillMillerIntegration(double *integral, double *error, double *f, double *x, long n)
Performs numerical integration using the Gill-Miller method.
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
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.
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_ChangeColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Modifies a specific field in a column definition within the SDDS dataset.
Definition SDDS_info.c:364
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
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_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.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
char ** getMatchingSDDSNames(SDDS_DATASET *dataset, char **matchName, int32_t matches, int32_t *names, short type)
Retrieves an array of matching SDDS entity names based on specified criteria.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS 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_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
char * SDDS_FindColumn(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Finds the first column in the SDDS dataset that matches the specified criteria.
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
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
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
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 replace_string(char *t, char *s, char *orig, char *repl)
Replace all occurrences of one string with another string.
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.