SDDSlib
Loading...
Searching...
No Matches
sddsenvelope.c
Go to the documentation of this file.
1/**
2 * @file sddsenvelope.c
3 * @brief Combine data from SDDS pages to create a new file with computed statistics.
4 *
5 * This program processes SDDS (Self Describing Data Set) input files, computing various statistics such as
6 * minimum, maximum, mean, standard deviations, and more for specified columns. The resulting statistics
7 * are written to an output SDDS file.
8 *
9 * ## Usage
10 * ```
11 * sddsenvelope [<input>] [<output>] [options]
12 * ```
13 *
14 * ## Options
15 * -copy=<column-names>
16 * -pipe=[input][,output]
17 * -nowarnings
18 * -maximum=<column-names>
19 * -minimum=<column-names>
20 * -cmaximum=<indep-column>,<column-names>
21 * -cminimum=<indep-column>,<column-names>
22 * -pmaximum=<indep-parameter>,<column-names>
23 * -pminimum=<indep-parameter>,<column-names>
24 * -largest=<column-names>
25 * -signedLargest=<column-names>
26 * -mean=<column-names>
27 * -sum=<power>,<column-names>
28 * -median=<column-names>
29 * -decilerange=<column-names>
30 * -percentile=<percentage>,<column-names>
31 * -standarddeviation=<column-names>
32 * -rms=<column-names>
33 * -sigma=<column-names>
34 * -slope=<indep-parameter>,<column-names>
35 * -intercept=<indep-parameter>,<column-names>
36 * -wmean=<weightColumn>,<columnNames>
37 * -wstandarddeviation=<weightColumn>,<columnNames>
38 * -wrms=<weightColumn>,<columnNames>
39 * -wsigma=<weightColumn>,<columnNames>
40 * -majorOrder=row|column
41 *
42 * @copyright
43 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
44 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
45 *
46 * @license
47 * This file is distributed under the terms of the Software License Agreement
48 * found in the file LICENSE included with this distribution.
49 *
50 * @author M. Borland, C. Saunders, R. Soliday, L. Emery, H. Shang
51 */
52
53#include "mdb.h"
54#include "scan.h"
55#include "SDDS.h"
56#include <ctype.h>
57
58/* Enumeration for option types */
59enum option_type {
60 SET_COPY,
61 SET_MAXIMA,
62 SET_MINIMA,
63 SET_MEANS,
64 SET_SDS,
65 SET_RMSS,
66 SET_SUMS,
67 SET_SLOPE,
68 SET_INTERCEPT,
69 SET_PIPE,
70 SET_SIGMAS,
71 SET_MEDIAN,
72 SET_DRANGE,
73 SET_WMEANS,
74 SET_WSDS,
75 SET_WRMSS,
76 SET_WSIGMAS,
77 SET_NOWARNINGS,
78 SET_LARGEST,
79 SET_PERCENTILE,
80 SET_SIGNEDLARGEST,
81 SET_PMAXIMA,
82 SET_PMINIMA,
83 SET_MAJOR_ORDER,
84 SET_EXMM_MEAN,
85 SET_CMAXIMA,
86 SET_CMINIMA,
87 N_OPTIONS
88};
89
90char *option[N_OPTIONS] = {
91 "copy",
92 "maximum",
93 "minimum",
94 "mean",
95 "standarddeviations",
96 "rms",
97 "sum",
98 "slope",
99 "intercept",
100 "pipe",
101 "sigmas",
102 "median",
103 "decilerange",
104 "wmean",
105 "wstandarddeviations",
106 "wrms",
107 "wsigma",
108 "nowarnings",
109 "largest",
110 "percentile",
111 "signedlargest",
112 "pmaximum",
113 "pminimum",
114 "majorOrder",
115 "exmmMean",
116 "cmaximum",
117 "cminimum",
118};
119
120char *optionSuffix[N_OPTIONS] = {
121 "",
122 "Max",
123 "Min",
124 "Mean",
125 "StDev",
126 "Rms",
127 "Sum",
128 "Slope",
129 "Intercept",
130 "",
131 "Sigma",
132 "Median",
133 "DRange",
134 "WMean",
135 "WStDev",
136 "WRms",
137 "WSigma",
138 "",
139 "Largest",
140 "Percentile",
141 "SignedLargest",
142 "PMaximum",
143 "PMinimum",
144 "",
145 "ExmmMean",
146 "CMaximum",
147 "CMinimum",
148};
149
150/* this structure stores a command-line request for statistics computation */
151/* columnName may contain wildcards */
152typedef struct
153{
154 char *columnName;
155 char *weightColumnName;
156 long optionCode, sumPower;
157 double percentile;
158 char *percentileString;
159 char *functionOf;
161
162/* this structure stores data necessary for accessing/creating SDDS columns and
163 * for computing a statistic
164 */
165typedef struct
166{
167 char *sourceColumn, *weightColumn, *resultColumn, *functionOf;
168 long optionCode, resultIndex, sumPower;
169 double percentile;
170 char *percentileString;
171 /* these store intermediate values during processing */
172 void *copy;
173 double *value1, *value2, *value3, *value4;
174 double **array;
175 double *sumWeight;
177
178long addStatRequests(STAT_REQUEST **statRequest, long requests, char **item, long items, long code, double percentile, long power, char *functionOf, long weighted, char *percentileString);
179/*weighted=0, no weighted column; else, weighted statistic, the weight factor is given by
180 weightedColumn*/
181STAT_DEFINITION *compileStatDefinitions(SDDS_DATASET *inTable, long *stats, STAT_REQUEST *request, long requests);
182long setupOutputFile(SDDS_DATASET *outTable, char *output, SDDS_DATASET *inTable, STAT_DEFINITION *stat, long stats, int64_t rows, short columnMajorOrder);
183int compute_mean_exclude_min_max(double *value, double *data, long n);
184
185static char *USAGE = "sddsenvelope [<input>] [<output>] [options]\n"
186 "Options:\n"
187 " -copy=<column-names> Copy specified columns.\n"
188 " -pipe=[input][,output] Use pipe for input/output.\n"
189 " -nowarnings Suppress warnings.\n"
190 " -maximum=<column-names> Compute maximum values.\n"
191 " -minimum=<column-names> Compute minimum values.\n"
192 " -cmaximum=<indep-column>,<column-names> Conditional maximum based on an independent column.\n"
193 " -cminimum=<indep-column>,<column-names> Conditional minimum based on an independent column.\n"
194 " -pmaximum=<indep-parameter>,<column-names> Parameter-based maximum.\n"
195 " -pminimum=<indep-parameter>,<column-names> Parameter-based minimum.\n"
196 " -largest=<column-names> Compute the largest absolute values.\n"
197 " -signedLargest=<column-names> Compute the largest signed values.\n"
198 " -mean=<column-names> Compute mean values.\n"
199 " -sum=<power>,<column-names> Compute sum with power.\n"
200 " -median=<column-names> Compute median values.\n"
201 " -decilerange=<column-names> Compute decile range.\n"
202 " -percentile=<percentage>,<column-names> Compute specified percentile.\n"
203 " -standarddeviation=<column-names> Compute standard deviations.\n"
204 " -rms=<column-names> Compute RMS values.\n"
205 " -sigma=<column-names> Compute sigma values.\n"
206 " -slope=<indep-parameter>,<column-names> Compute slope for linear fit.\n"
207 " -intercept=<indep-parameter>,<column-names> Compute intercept for linear fit.\n"
208 " -wmean=<weightColumn>,<columnNames> Compute weighted mean.\n"
209 " -wstandarddeviation=<weightColumn>,<columnNames> Compute weighted standard deviation.\n"
210 " -wrms=<weightColumn>,<columnNames> Compute weighted RMS.\n"
211 " -wsigma=<weightColumn>,<columnNames> Compute weighted sigma.\n"
212 " -majorOrder=row|column Set major order.\n\n"
213 "Processes pages from <input> to produce <output> with\n"
214 "one page containing the specified quantities across pages\n"
215 "for each row of the specified columns.\n"
216 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")";
217
218int main(int argc, char **argv) {
219 STAT_DEFINITION *stat;
220 long stats;
221 STAT_REQUEST *request;
222 long requests;
223 SCANNED_ARG *scanned; /* structure for scanned arguments */
224 SDDS_DATASET inTable, outTable;
225 long i_arg, code, power, iStat, pages, nowarnings = 0;
226 int64_t i, rows, firstRows;
227 char *input, *output;
228 double *inputData, *otherData, indepData, *weight;
229 unsigned long pipeFlags, majorOrderFlag;
230 double decilePoint[2] = {10.0, 90.0}, decileResult[2];
231 double percentilePoint, percentileResult;
232 double percentile;
233 short columnMajorOrder = -1;
234
236 argc = scanargs(&scanned, argc, argv);
237 if (argc < 2) {
238 bomb("too few arguments", USAGE);
239 exit(EXIT_FAILURE);
240 }
241 weight = NULL;
242 input = output = NULL;
243 stat = NULL;
244 request = NULL;
245 stats = requests = pipeFlags = 0;
246 rows = firstRows = i = 0;
247
248 for (i_arg = 1; i_arg < argc; i_arg++) {
249 if (scanned[i_arg].arg_type == OPTION) {
250 /* process options here */
251 switch (code = match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
252 case SET_COPY:
253 case SET_MINIMA:
254 case SET_MAXIMA:
255 case SET_LARGEST:
256 case SET_SIGNEDLARGEST:
257 case SET_MEANS:
258 case SET_SDS:
259 case SET_SIGMAS:
260 case SET_RMSS:
261 case SET_MEDIAN:
262 case SET_DRANGE:
263 case SET_EXMM_MEAN:
264 if (scanned[i_arg].n_items < 2) {
265 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
266 exit(EXIT_FAILURE);
267 }
268 requests = addStatRequests(&request, requests, scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, code, 0, 0, NULL, 0, NULL);
269 break;
270 case SET_WMEANS:
271 case SET_WSDS:
272 case SET_WRMSS:
273 case SET_WSIGMAS:
274 if (scanned[i_arg].n_items < 3) {
275 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
276 exit(EXIT_FAILURE);
277 }
278 /*note here, items=scanned[i_arg].n_items-2, because the weightedColumn should be excluded */
279 requests = addStatRequests(&request, requests, scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, code, 0, 0, NULL, 1, NULL);
280 break;
281 case SET_SUMS:
282 if (scanned[i_arg].n_items < 3) {
283 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
284 exit(EXIT_FAILURE);
285 }
286 if (sscanf(scanned[i_arg].list[1], "%ld", &power) != 1 || power < 1) {
287 fprintf(stderr, "error: invalid -%s syntax--bad power in field %s\n", option[code], scanned[i_arg].list[2]);
288 exit(EXIT_FAILURE);
289 }
290 requests = addStatRequests(&request, requests, scanned[i_arg].list + 2, scanned[i_arg].n_items - 2, code, 0, power, NULL, 0, NULL);
291 break;
292 case SET_PERCENTILE:
293 if (scanned[i_arg].n_items < 3) {
294 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
295 exit(EXIT_FAILURE);
296 }
297 if (sscanf(scanned[i_arg].list[1], "%lf", &percentile) != 1 || percentile < 0 || percentile > 100) {
298 fprintf(stderr, "error: invalid -%s syntax--bad percentage in field %s\n", option[code], scanned[i_arg].list[1]);
299 exit(EXIT_FAILURE);
300 }
301 requests = addStatRequests(&request, requests, scanned[i_arg].list + 2, scanned[i_arg].n_items - 2, code, percentile, 0, NULL, 0, scanned[i_arg].list[1]);
302 break;
303 case SET_SLOPE:
304 case SET_INTERCEPT:
305 case SET_PMINIMA:
306 case SET_PMAXIMA:
307 case SET_CMINIMA:
308 case SET_CMAXIMA:
309 if (scanned[i_arg].n_items < 3) {
310 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
311 exit(EXIT_FAILURE);
312 }
313 requests = addStatRequests(&request, requests, scanned[i_arg].list + 2, scanned[i_arg].n_items - 2, code, 0, 0, scanned[i_arg].list[1], 0, NULL);
314 break;
315 case SET_PIPE:
316 if (!processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipeFlags))
317 SDDS_Bomb("invalid -pipe syntax");
318 break;
319 case SET_NOWARNINGS:
320 nowarnings = 1;
321 break;
322 case SET_MAJOR_ORDER:
323 majorOrderFlag = 0;
324 scanned[i_arg].n_items--;
325 if (scanned[i_arg].n_items > 0 && (!scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
326 SDDS_Bomb("invalid -majorOrder syntax/values");
327 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
328 columnMajorOrder = 1;
329 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
330 columnMajorOrder = 0;
331 break;
332 default:
333 fprintf(stderr, "error: unknown option '%s' given\n", scanned[i_arg].list[0]);
334 exit(EXIT_FAILURE);
335 break;
336 }
337 } else {
338 /* argument is filename */
339 if (!input)
340 input = scanned[i_arg].list[0];
341 else if (!output)
342 output = scanned[i_arg].list[0];
343 else
344 SDDS_Bomb("too many filenames seen");
345 }
346 }
347
348 processFilenames("sddsenvelope", &input, &output, pipeFlags, 0, NULL);
349
350 if (!requests)
351 SDDS_Bomb("no statistics requested");
352
353 if (!SDDS_InitializeInput(&inTable, input))
354 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
355
356 pages = 0;
357 while ((code = SDDS_ReadPage(&inTable)) > 0) {
358 pages++;
359 if (!(rows = SDDS_CountRowsOfInterest(&inTable)))
360 SDDS_Bomb("empty data page in input file");
361 if (code == 1) {
362 firstRows = rows;
363 if (!(stat = compileStatDefinitions(&inTable, &stats, request, requests))) {
364 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
365 exit(EXIT_FAILURE);
366 }
367 if (!setupOutputFile(&outTable, output, &inTable, stat, stats, rows, columnMajorOrder)) {
369 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
370 else
371 fprintf(stderr, "Error setting up output file.\n");
372 exit(EXIT_FAILURE);
373 }
374 } else if (firstRows != rows)
375 SDDS_Bomb("inconsistent number of rows in input file");
376 for (iStat = 0; iStat < stats; iStat++) {
377 if (stat[iStat].optionCode == SET_COPY) {
378 if (code == 1 && !(stat[iStat].copy = SDDS_GetColumn(&inTable, stat[iStat].sourceColumn)))
379 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
380 continue;
381 }
382 stat[iStat].copy = NULL;
383 if (!(inputData = SDDS_GetColumnInDoubles(&inTable, stat[iStat].sourceColumn)))
384 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
385 switch (stat[iStat].optionCode) {
386 case SET_MINIMA:
387 if (code == 1)
388 for (i = 0; i < rows; i++)
389 stat[iStat].value1[i] = inputData[i];
390 else
391 for (i = 0; i < rows; i++)
392 if (stat[iStat].value1[i] > inputData[i])
393 stat[iStat].value1[i] = inputData[i];
394 break;
395 case SET_MAXIMA:
396 if (code == 1)
397 for (i = 0; i < rows; i++)
398 stat[iStat].value1[i] = inputData[i];
399 else
400 for (i = 0; i < rows; i++)
401 if (stat[iStat].value1[i] < inputData[i])
402 stat[iStat].value1[i] = inputData[i];
403 break;
404 case SET_CMINIMA:
405 /* Value from another column corresponding to minimum value in main column */
406 if (!(otherData = SDDS_GetColumnInDoubles(&inTable, stat[iStat].functionOf)))
407 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
408 if (code == 1)
409 for (i = 0; i < rows; i++) {
410 stat[iStat].value2[i] = inputData[i];
411 stat[iStat].value1[i] = otherData[i];
412 }
413 else
414 for (i = 0; i < rows; i++)
415 if (stat[iStat].value2[i] > inputData[i]) {
416 stat[iStat].value2[i] = inputData[i];
417 stat[iStat].value1[i] = otherData[i];
418 }
419 free(otherData);
420 break;
421 case SET_CMAXIMA:
422 /* Value from another column corresponding to maximum value in main column */
423 if (!(otherData = SDDS_GetColumnInDoubles(&inTable, stat[iStat].functionOf)))
424 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
425 if (code == 1)
426 for (i = 0; i < rows; i++) {
427 stat[iStat].value2[i] = inputData[i];
428 stat[iStat].value1[i] = otherData[i];
429 }
430 else
431 for (i = 0; i < rows; i++)
432 if (stat[iStat].value2[i] < inputData[i]) {
433 stat[iStat].value2[i] = inputData[i];
434 stat[iStat].value1[i] = otherData[i];
435 }
436 free(otherData);
437 break;
438 case SET_LARGEST:
439 if (code == 1)
440 for (i = 0; i < rows; i++)
441 stat[iStat].value1[i] = fabs(inputData[i]);
442 else
443 for (i = 0; i < rows; i++)
444 if (stat[iStat].value1[i] < fabs(inputData[i]))
445 stat[iStat].value1[i] = fabs(inputData[i]);
446 break;
447 case SET_SIGNEDLARGEST:
448 if (code == 1)
449 for (i = 0; i < rows; i++)
450 stat[iStat].value1[i] = inputData[i];
451 else
452 for (i = 0; i < rows; i++)
453 if (fabs(stat[iStat].value1[i]) < fabs(inputData[i]))
454 stat[iStat].value1[i] = inputData[i];
455 break;
456 case SET_MEANS:
457 if (code == 1)
458 for (i = 0; i < rows; i++)
459 stat[iStat].value1[i] = inputData[i];
460 else
461 for (i = 0; i < rows; i++)
462 stat[iStat].value1[i] += inputData[i];
463 break;
464 case SET_WMEANS:
465 if (!(weight = SDDS_GetColumnInDoubles(&inTable, stat[iStat].weightColumn)))
466 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
467 for (i = 0; i < rows; i++) {
468 stat[iStat].sumWeight[i] += weight[i];
469 stat[iStat].value1[i] += inputData[i] * weight[i];
470 }
471 free(weight);
472 break;
473 case SET_SDS:
474 case SET_SIGMAS:
475 if (code == 1)
476 for (i = 0; i < rows; i++) {
477 stat[iStat].value1[i] = inputData[i];
478 stat[iStat].value2[i] = inputData[i] * inputData[i];
479 }
480 else
481 for (i = 0; i < rows; i++) {
482 stat[iStat].value1[i] += inputData[i];
483 stat[iStat].value2[i] += inputData[i] * inputData[i];
484 }
485 break;
486 case SET_WSDS:
487 case SET_WSIGMAS:
488 if (!(weight = SDDS_GetColumnInDoubles(&inTable, stat[iStat].weightColumn)))
489 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
490 for (i = 0; i < rows; i++) {
491 stat[iStat].sumWeight[i] += weight[i];
492 stat[iStat].value1[i] += inputData[i] * weight[i];
493 stat[iStat].value2[i] += inputData[i] * inputData[i] * weight[i];
494 }
495 free(weight);
496 break;
497 case SET_RMSS:
498 if (code == 1)
499 for (i = 0; i < rows; i++)
500 stat[iStat].value1[i] = inputData[i] * inputData[i];
501 else
502 for (i = 0; i < rows; i++)
503 stat[iStat].value1[i] += inputData[i] * inputData[i];
504 break;
505 case SET_WRMSS:
506 if (!(weight = SDDS_GetColumnInDoubles(&inTable, stat[iStat].weightColumn)))
507 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
508 for (i = 0; i < rows; i++) {
509 stat[iStat].sumWeight[i] += weight[i];
510 stat[iStat].value1[i] += inputData[i] * inputData[i] * weight[i];
511 }
512 free(weight);
513 break;
514 case SET_SUMS:
515 if (code == 1)
516 for (i = 0; i < rows; i++)
517 stat[iStat].value1[i] = ipow(inputData[i], stat[iStat].sumPower);
518 else
519 for (i = 0; i < rows; i++)
520 stat[iStat].value1[i] += ipow(inputData[i], stat[iStat].sumPower);
521 break;
522 case SET_PMINIMA:
523 if (!SDDS_GetParameterAsDouble(&inTable, stat[iStat].functionOf, &indepData)) {
524 fprintf(stderr, "error: unable to get value of parameter %s\n", stat[iStat].functionOf);
525 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
526 }
527 if (code == 1)
528 for (i = 0; i < rows; i++) {
529 stat[iStat].value2[i] = inputData[i];
530 stat[iStat].value1[i] = indepData;
531 }
532 else
533 for (i = 0; i < rows; i++) {
534 if (stat[iStat].value2[i] > inputData[i]) {
535 stat[iStat].value2[i] = inputData[i];
536 stat[iStat].value1[i] = indepData;
537 }
538 }
539 break;
540 case SET_PMAXIMA:
541 if (!SDDS_GetParameterAsDouble(&inTable, stat[iStat].functionOf, &indepData)) {
542 fprintf(stderr, "error: unable to get value of parameter %s\n", stat[iStat].functionOf);
543 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
544 }
545 if (code == 1)
546 for (i = 0; i < rows; i++) {
547 stat[iStat].value2[i] = inputData[i];
548 stat[iStat].value1[i] = indepData;
549 }
550 else
551 for (i = 0; i < rows; i++) {
552 if (stat[iStat].value2[i] < inputData[i]) {
553 stat[iStat].value2[i] = inputData[i];
554 stat[iStat].value1[i] = indepData;
555 }
556 }
557 break;
558 case SET_SLOPE:
559 case SET_INTERCEPT:
560 if (!SDDS_GetParameterAsDouble(&inTable, stat[iStat].functionOf, &indepData)) {
561 fprintf(stderr, "error: unable to get value of parameter %s\n", stat[iStat].functionOf);
562 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
563 }
564 /* linear fit:
565 y = a + bx
566 a = (S x^2 Sy - S x S xy)/D
567 b = (N S xy - Sx Sy)/D
568 D = N S x^2 - (S x)^2
569 */
570 if (code == 1)
571 for (i = 0; i < rows; i++) {
572 stat[iStat].value1[i] = indepData; /* Sum x */
573 stat[iStat].value2[i] = indepData * indepData; /* Sum x^2 */
574 stat[iStat].value3[i] = inputData[i]; /* Sum y */
575 stat[iStat].value4[i] = indepData * inputData[i]; /* Sum xy */
576 }
577 else
578 for (i = 0; i < rows; i++) {
579 stat[iStat].value1[i] += indepData;
580 stat[iStat].value2[i] += indepData * indepData;
581 stat[iStat].value3[i] += inputData[i];
582 stat[iStat].value4[i] += indepData * inputData[i];
583 }
584 break;
585 case SET_MEDIAN:
586 case SET_DRANGE:
587 case SET_PERCENTILE:
588 case SET_EXMM_MEAN:
589 if (code == 1)
590 for (i = 0; i < rows; i++) {
591 stat[iStat].array[i] = tmalloc(sizeof(*stat[iStat].array[i]));
592 stat[iStat].array[i][pages - 1] = inputData[i];
593 }
594 else {
595 for (i = 0; i < rows; i++) {
596 stat[iStat].array[i] = SDDS_Realloc(stat[iStat].array[i], sizeof(*stat[iStat].array[i]) * pages);
597 stat[iStat].array[i][pages - 1] = inputData[i];
598 }
599 }
600 break;
601 default:
602 SDDS_Bomb("invalid statistic code (accumulation loop)");
603 break;
604 }
605 free(inputData);
606 }
607 }
608 if (pages == 0)
609 SDDS_Bomb("no pages in input");
610 for (iStat = 0; iStat < stats; iStat++) {
611 switch (stat[iStat].optionCode) {
612 case SET_COPY:
613 case SET_MINIMA:
614 case SET_MAXIMA:
615 case SET_PMINIMA:
616 case SET_PMAXIMA:
617 case SET_CMINIMA:
618 case SET_CMAXIMA:
619 case SET_LARGEST:
620 case SET_SIGNEDLARGEST:
621 case SET_SUMS:
622 break;
623 case SET_MEANS:
624 for (i = 0; i < rows; i++)
625 stat[iStat].value1[i] /= pages;
626 break;
627 case SET_WMEANS:
628 for (i = 0; i < rows; i++)
629 if (stat[iStat].sumWeight[i])
630 stat[iStat].value1[i] /= stat[iStat].sumWeight[i];
631 else {
632 if (!nowarnings)
633 fprintf(stderr, "warning: the total weight for the %" PRId64 "th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
634 stat[iStat].value1[i] = DBL_MAX;
635 }
636 break;
637 case SET_SDS:
638 if (pages < 2)
639 stat[iStat].value1[i] = DBL_MAX;
640 else
641 for (i = 0; i < rows; i++) {
642 double tmp1;
643 if ((tmp1 = stat[iStat].value2[i] / pages - sqr(stat[iStat].value1[i] / pages)) <= 0)
644 stat[iStat].value1[i] = 0;
645 else
646 stat[iStat].value1[i] = sqrt(tmp1 * pages / (pages - 1.0));
647 }
648 break;
649 case SET_WSDS:
650 if (pages < 2)
651 stat[iStat].value1[i] = DBL_MAX;
652 else
653 for (i = 0; i < rows; i++) {
654 double tmp1;
655 if (stat[iStat].sumWeight[i]) {
656 if ((tmp1 = stat[iStat].value2[i] / stat[iStat].sumWeight[i] - sqr(stat[iStat].value1[i] / stat[iStat].sumWeight[i])) <= 0)
657 stat[iStat].value1[i] = 0;
658 else
659 stat[iStat].value1[i] = sqrt(tmp1 * pages / (pages - 1.0));
660 } else {
661 if (!nowarnings)
662 fprintf(stderr, "Warning, the total weight for the %" PRId64 "th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
663 stat[iStat].value1[i] = DBL_MAX;
664 }
665 }
666 break;
667 case SET_SIGMAS:
668 if (pages < 2)
669 stat[iStat].value1[i] = DBL_MAX;
670 else
671 for (i = 0; i < rows; i++) {
672 double tmp1;
673 if ((tmp1 = stat[iStat].value2[i] / pages - sqr(stat[iStat].value1[i] / pages)) <= 0)
674 stat[iStat].value1[i] = 0;
675 else
676 stat[iStat].value1[i] = sqrt(tmp1 / (pages - 1.0));
677 }
678 break;
679 case SET_WSIGMAS:
680 if (pages < 2)
681 stat[iStat].value1[i] = DBL_MAX;
682 else
683 for (i = 0; i < rows; i++) {
684 double tmp1;
685 if (stat[iStat].sumWeight[i]) {
686 if ((tmp1 = stat[iStat].value2[i] / stat[iStat].sumWeight[i] - sqr(stat[iStat].value1[i] / stat[iStat].sumWeight[i])) <= 0)
687 stat[iStat].value1[i] = 0;
688 else
689 stat[iStat].value1[i] = sqrt(tmp1 / (pages - 1.0));
690 } else {
691 if (!nowarnings)
692 fprintf(stderr, "Warning, the total weight for the %" PRId64 "th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
693 stat[iStat].value1[i] = DBL_MAX;
694 }
695 }
696 break;
697 case SET_RMSS:
698 for (i = 0; i < rows; i++)
699 stat[iStat].value1[i] = sqrt(stat[iStat].value1[i] / pages);
700 break;
701 case SET_WRMSS:
702 for (i = 0; i < rows; i++) {
703 if (stat[iStat].sumWeight[i])
704 stat[iStat].value1[i] = sqrt(stat[iStat].value1[i] / stat[iStat].sumWeight[i]);
705 else {
706 if (!nowarnings)
707 fprintf(stderr, "Warning, the total weight for the %" PRId64 "th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
708 stat[iStat].value1[i] = DBL_MAX;
709 }
710 }
711 break;
712 case SET_SLOPE:
713 for (i = 0; i < rows; i++) {
714 double D;
715 D = pages * stat[iStat].value2[i] - stat[iStat].value1[i] * stat[iStat].value1[i];
716 stat[iStat].value1[i] = (pages * stat[iStat].value4[i] - stat[iStat].value1[i] * stat[iStat].value3[i]) / D;
717 }
718 break;
719 case SET_INTERCEPT:
720 for (i = 0; i < rows; i++) {
721 double D;
722 D = pages * stat[iStat].value2[i] - stat[iStat].value1[i] * stat[iStat].value1[i];
723 stat[iStat].value1[i] = (stat[iStat].value2[i] * stat[iStat].value3[i] - stat[iStat].value1[i] * stat[iStat].value4[i]) / D;
724 }
725 break;
726 case SET_MEDIAN:
727 for (i = 0; i < rows; i++) {
728 compute_median(&stat[iStat].value1[i], stat[iStat].array[i], pages);
729 }
730 break;
731 case SET_DRANGE:
732 for (i = 0; i < rows; i++) {
733 if (!compute_percentiles(decileResult, decilePoint, 2, stat[iStat].array[i], pages))
734 stat[iStat].value1[i] = 0;
735 else
736 stat[iStat].value1[i] = decileResult[1] - decileResult[0];
737 }
738 break;
739 case SET_PERCENTILE:
740 percentilePoint = stat[iStat].percentile;
741 for (i = 0; i < rows; i++) {
742 if (!compute_percentiles(&percentileResult, &percentilePoint, 1, stat[iStat].array[i], pages))
743 stat[iStat].value1[i] = 0;
744 else
745 stat[iStat].value1[i] = percentileResult;
746 }
747 break;
748 case SET_EXMM_MEAN:
749 for (i = 0; i < rows; i++)
750 if (!compute_mean_exclude_min_max(&(stat[iStat].value1[i]), stat[iStat].array[i], pages))
751 stat[iStat].value1[i] = 0;
752 break;
753 default:
754 SDDS_Bomb("invalid statistic code (final loop)");
755 break;
756 }
757 if (stat[iStat].optionCode == SET_COPY) {
758 if (!SDDS_SetColumn(&outTable, SDDS_SET_BY_NAME, stat[iStat].copy, rows, stat[iStat].resultColumn)) {
759 fprintf(stderr, "error setting column values for column %s\n", stat[iStat].resultColumn);
760 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
761 }
762 } else if (!SDDS_SetColumnFromDoubles(&outTable, SDDS_SET_BY_NAME, stat[iStat].value1, rows, stat[iStat].resultColumn)) {
763 fprintf(stderr, "error setting column values for column %s\n", stat[iStat].resultColumn);
764 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
765 }
766 if (stat[iStat].value1)
767 free(stat[iStat].value1);
768 if (stat[iStat].value2)
769 free(stat[iStat].value2);
770 if (stat[iStat].value3)
771 free(stat[iStat].value3);
772 if (stat[iStat].value4)
773 free(stat[iStat].value4);
774 if (stat[iStat].copy)
775 free(stat[iStat].copy);
776 if (stat[iStat].array) {
777 for (i = 0; i < rows; i++) {
778 free(stat[iStat].array[i]);
779 }
780 free(stat[iStat].array);
781 }
782 if (stat[iStat].sumWeight)
783 free(stat[iStat].sumWeight);
784 free(stat[iStat].sourceColumn);
785 free(stat[iStat].resultColumn);
786 stat[iStat].value1 = stat[iStat].value2 = stat[iStat].value3 = stat[iStat].value4 = NULL;
787 stat[iStat].copy = NULL;
788 stat[iStat].array = NULL;
789 }
790 free(stat);
791 if (!SDDS_WritePage(&outTable) || !SDDS_Terminate(&inTable) || !SDDS_Terminate(&outTable))
792 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
793 return EXIT_SUCCESS;
794}
795
796long addStatRequests(STAT_REQUEST **statRequest, long requests, char **item, long items, long code, double percentile, long power, char *functionOf, long weighted, char *percentileString) {
797 long i;
798 /*weighted factor should be either 0 or 1 */
799 if (weighted != 0 && weighted != 1)
800 SDDS_Bomb("addStatRequests: weighted parameter should be either 0 or 1");
801 if (code == SET_PERCENTILE && (!percentileString || !strlen(percentileString))) {
802 fprintf(stderr, "Percentile specification is incorrect: percentile=%e, percentileString=%s\n", percentile, percentileString ? percentileString : "NULL");
803 exit(EXIT_FAILURE);
804 }
805 *statRequest = SDDS_Realloc(*statRequest, sizeof(**statRequest) * (requests + items - weighted));
806 for (i = 0; i < items - weighted; i++) {
807 if (weighted)
808 (*statRequest)[requests + i].weightColumnName = item[0];
809 else
810 (*statRequest)[requests + i].weightColumnName = NULL;
811 (*statRequest)[i + requests].columnName = item[i + weighted];
812 (*statRequest)[i + requests].optionCode = code;
813 (*statRequest)[i + requests].sumPower = power;
814 (*statRequest)[i + requests].percentile = percentile;
815 (*statRequest)[i + requests].percentileString = percentileString;
816 (*statRequest)[i + requests].functionOf = functionOf;
817 }
818
819 return items + requests - weighted;
820}
821
822STAT_DEFINITION *compileStatDefinitions(SDDS_DATASET *inTable, long *stats, STAT_REQUEST *request, long requests) {
823 STAT_DEFINITION *stat;
824 long iReq, iStat, iName;
825 int32_t columnNames;
826 char s[SDDS_MAXLINE];
827 char **columnName;
828
829 *stats = iStat = 0;
830 stat = tmalloc(sizeof(*stat) * requests);
831 for (iReq = 0; iReq < requests; iReq++) {
832 if (iStat >= *stats)
833 stat = SDDS_Realloc(stat, sizeof(*stat) * (*stats += 10));
834 if (!has_wildcards(request[iReq].columnName)) {
835 if (SDDS_GetColumnIndex(inTable, request[iReq].columnName) < 0) {
836 sprintf(s, "error: column %s not found input file", request[iReq].columnName);
837 SDDS_SetError(s);
838 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
839 }
840 stat[iStat].weightColumn = request[iReq].weightColumnName;
841 stat[iStat].sourceColumn = request[iReq].columnName;
842 stat[iStat].optionCode = request[iReq].optionCode;
843 stat[iStat].percentile = request[iReq].percentile;
844 stat[iStat].percentileString = request[iReq].percentileString;
845 stat[iStat].sumPower = request[iReq].sumPower;
846 stat[iStat].value1 = stat[iStat].value2 = stat[iStat].value3 = stat[iStat].value4 = NULL;
847 stat[iStat].array = NULL;
848 stat[iStat].copy = NULL;
849 stat[iStat].sumWeight = NULL;
850 if ((stat[iStat].functionOf = request[iReq].functionOf)) {
851 if (stat[iStat].optionCode != SET_CMAXIMA && stat[iStat].optionCode != SET_CMINIMA) {
852 if (SDDS_GetParameterIndex(inTable, request[iReq].functionOf) < 0) {
853 sprintf(s, "error: parameter %s not found input file (1)", request[iReq].functionOf);
854 SDDS_SetError(s);
855 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
856 }
857 } else {
858 if (SDDS_GetColumnIndex(inTable, request[iReq].functionOf) < 0) {
859 sprintf(s, "error: column %s not found input file (1)", request[iReq].functionOf);
860 SDDS_SetError(s);
861 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
862 }
863 }
864 }
865 iStat++;
866 } else {
867 SDDS_SetColumnFlags(inTable, 0);
868 if (!SDDS_SetColumnsOfInterest(inTable, SDDS_MATCH_STRING, request[iReq].columnName, SDDS_OR))
869 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
870 if (!(columnName = SDDS_GetColumnNames(inTable, &columnNames))) {
871 sprintf(s, "no columns selected for wildcard sequence %s", request[iReq].columnName);
872 SDDS_SetError(s);
873 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
874 }
875 if (iStat + columnNames > *stats)
876 stat = SDDS_Realloc(stat, sizeof(*stat) * (*stats = iStat + columnNames + 10));
877 for (iName = 0; iName < columnNames; iName++) {
878 stat[iStat + iName].weightColumn = request[iReq].weightColumnName;
879 stat[iStat + iName].sourceColumn = columnName[iName];
880 stat[iStat + iName].optionCode = request[iReq].optionCode;
881 stat[iStat + iName].sumPower = request[iReq].sumPower;
882 stat[iStat + iName].percentile = request[iReq].percentile;
883 stat[iStat + iName].percentileString = request[iReq].percentileString;
884 stat[iStat + iName].value1 = stat[iStat + iName].value2 = stat[iStat + iName].value3 = stat[iStat + iName].value4 = NULL;
885 stat[iStat + iName].array = NULL;
886 stat[iStat + iName].copy = NULL;
887 stat[iStat + iName].sumWeight = NULL;
888 if ((stat[iStat + iName].functionOf = request[iReq].functionOf) && iName == 0) {
889 if (stat[iStat + iName].optionCode != SET_CMAXIMA && stat[iStat + iName].optionCode != SET_CMINIMA) {
890 if (SDDS_GetParameterIndex(inTable, request[iReq].functionOf) < 0) {
891 sprintf(s, "error: parameter %s not found input file (2)", request[iReq].functionOf);
892 SDDS_SetError(s);
893 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
894 }
895 } else {
896 if (SDDS_GetColumnIndex(inTable, request[iReq].functionOf) < 0) {
897 sprintf(s, "error: column %s not found input file (2)", request[iReq].functionOf);
898 SDDS_SetError(s);
899 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
900 }
901 }
902 }
903 }
904 iStat += columnNames;
905 free(columnName);
906 }
907 }
908
909 *stats = iStat;
910 for (iStat = 0; iStat < *stats; iStat++) {
911 switch (stat[iStat].optionCode) {
912 case SET_COPY:
913 strcpy(s, stat[iStat].sourceColumn);
914 break;
915 case SET_SUMS:
916 if (stat[iStat].sumPower == 1)
917 sprintf(s, "%s%s", stat[iStat].sourceColumn, optionSuffix[stat[iStat].optionCode]);
918 else
919 sprintf(s, "%s%ld%s", stat[iStat].sourceColumn, stat[iStat].sumPower, optionSuffix[stat[iStat].optionCode]);
920 break;
921 case SET_PERCENTILE:
922 sprintf(s, "%s%s%s", stat[iStat].sourceColumn, stat[iStat].percentileString, optionSuffix[stat[iStat].optionCode]);
923 break;
924 case SET_PMAXIMA:
925 case SET_PMINIMA:
926 sprintf(s, "%s%s%s", stat[iStat].functionOf, optionSuffix[stat[iStat].optionCode], stat[iStat].sourceColumn);
927 break;
928 case SET_CMAXIMA:
929 case SET_CMINIMA:
930 sprintf(s, "%s%s%s", stat[iStat].functionOf, optionSuffix[stat[iStat].optionCode], stat[iStat].sourceColumn);
931 break;
932 default:
933 sprintf(s, "%s%s", stat[iStat].sourceColumn, optionSuffix[stat[iStat].optionCode]);
934 break;
935 }
936 if (!SDDS_CopyString(&stat[iStat].resultColumn, s))
937 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
938 }
939 return stat;
940}
941
942long setupOutputFile(SDDS_DATASET *outTable, char *output, SDDS_DATASET *inTable, STAT_DEFINITION *stat, long stats, int64_t rows, short columnMajorOrder) {
943 long column;
944 char s[SDDS_MAXLINE], *symbol, *symbol1, *units1;
945
946 if (!SDDS_InitializeOutput(outTable, SDDS_BINARY, 0, NULL, "sddsenvelope output", output))
947 return 0;
948 if (columnMajorOrder != -1)
949 outTable->layout.data_mode.column_major = columnMajorOrder;
950 else
951 outTable->layout.data_mode.column_major = inTable->layout.data_mode.column_major;
952 for (column = 0; column < stats; column++) {
953 stat[column].value1 = calloc(sizeof(*stat[column].value1), rows);
954 stat[column].value2 = stat[column].value3 = stat[column].value4 = NULL;
955 if (stat[column].optionCode == SET_SDS || stat[column].optionCode == SET_SIGMAS ||
956 stat[column].optionCode == SET_WSDS || stat[column].optionCode == SET_WSIGMAS ||
957 stat[column].optionCode == SET_PMINIMA || stat[column].optionCode == SET_PMAXIMA ||
958 stat[column].optionCode == SET_CMINIMA || stat[column].optionCode == SET_CMAXIMA)
959 stat[column].value2 = calloc(sizeof(*stat[column].value2), rows);
960 if (stat[column].optionCode == SET_INTERCEPT || stat[column].optionCode == SET_SLOPE) {
961 stat[column].value2 = malloc(sizeof(*stat[column].value2) * rows);
962 stat[column].value3 = malloc(sizeof(*stat[column].value3) * rows);
963 stat[column].value4 = malloc(sizeof(*stat[column].value4) * rows);
964 }
965 if (stat[column].optionCode == SET_WSDS || stat[column].optionCode == SET_WSIGMAS ||
966 stat[column].optionCode == SET_WRMSS || stat[column].optionCode == SET_WMEANS)
967 stat[column].sumWeight = calloc(sizeof(*stat[column].sumWeight), rows);
968 if (stat[column].optionCode == SET_MEDIAN || stat[column].optionCode == SET_DRANGE ||
969 stat[column].optionCode == SET_PERCENTILE || stat[column].optionCode == SET_EXMM_MEAN) {
970 stat[column].array = tmalloc(sizeof(*stat[column].array) * rows);
971 }
972 if (!SDDS_TransferColumnDefinition(outTable, inTable, stat[column].sourceColumn, stat[column].resultColumn)) {
973 sprintf(s, "Problem transferring definition of column %s to %s\n", stat[column].sourceColumn, stat[column].resultColumn);
974 SDDS_SetError(s);
975 return 0;
976 }
977 if (SDDS_ChangeColumnInformation(outTable, "description", NULL, SDDS_SET_BY_NAME, stat[column].resultColumn) != SDDS_STRING ||
978 SDDS_GetColumnInformation(outTable, "symbol", &symbol, SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING) {
979 fprintf(stderr, "Error: problem setting description for column %s\n", stat[column].resultColumn);
980 return 0;
981 }
982 if (stat[column].optionCode > 0) {
983 if (SDDS_ChangeColumnInformation(outTable, "type", "double", SDDS_PASS_BY_STRING | SDDS_SET_BY_NAME, stat[column].resultColumn) != SDDS_LONG) {
984 fprintf(stderr, "Error: problem setting type for column %s\n", stat[column].resultColumn);
985 return 0;
986 }
987 }
988 if (!symbol)
989 SDDS_CopyString(&symbol, stat[column].sourceColumn);
990 switch (stat[column].optionCode) {
991 case SET_COPY:
992 strcpy(s, symbol);
993 break;
994 case SET_SUMS:
995 if (stat[column].sumPower == 1)
996 sprintf(s, "%s[%s]", optionSuffix[stat[column].optionCode], symbol);
997 else
998 sprintf(s, "%s[%s$a%ld$n]", optionSuffix[stat[column].optionCode], symbol, stat[column].sumPower);
999 break;
1000 case SET_PERCENTILE:
1001 sprintf(s, "%s[%s,%g]", optionSuffix[stat[column].optionCode], symbol, stat[column].percentile);
1002 break;
1003 case SET_PMINIMA:
1004 case SET_PMAXIMA:
1005 if (SDDS_GetParameterInformation(inTable, "symbol", &symbol1, SDDS_BY_NAME, stat[column].functionOf) != SDDS_STRING ||
1006 !symbol1 ||
1007 !strlen(symbol1))
1008 symbol1 = stat[column].functionOf;
1009 sprintf(s, "%s[%s:%s]", optionSuffix[stat[column].optionCode], symbol, symbol1);
1010 if (SDDS_GetParameterInformation(inTable, "units", &units1, SDDS_BY_NAME, stat[column].functionOf) != SDDS_STRING)
1011 return 0;
1012 if (units1) {
1013 if (SDDS_ChangeColumnInformation(outTable, "units", units1, SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING) {
1014 fprintf(stderr, "Error: problem setting units for column %s (1)\n", stat[column].resultColumn);
1015 return 0;
1016 }
1017 } else if (SDDS_ChangeColumnInformation(outTable, "units", "", SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING) {
1018 fprintf(stderr, "Error: problem setting units for column %s (2)\n", stat[column].resultColumn);
1019 return 0;
1020 }
1021 break;
1022 case SET_CMINIMA:
1023 case SET_CMAXIMA:
1024 if (SDDS_GetColumnInformation(inTable, "symbol", &symbol1, SDDS_BY_NAME, stat[column].functionOf) != SDDS_STRING ||
1025 !symbol1 ||
1026 !strlen(symbol1))
1027 symbol1 = stat[column].functionOf;
1028 sprintf(s, "%s[%s:%s]", optionSuffix[stat[column].optionCode], symbol, symbol1);
1029 if (SDDS_GetColumnInformation(inTable, "units", &units1, SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING)
1030 return 0;
1031 if (units1) {
1032 if (SDDS_ChangeColumnInformation(outTable, "units", units1, SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING) {
1033 fprintf(stderr, "Error: problem setting units for column %s\n", stat[column].resultColumn);
1034 return 0;
1035 }
1036 } else if (SDDS_ChangeColumnInformation(outTable, "units", "", SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING) {
1037 fprintf(stderr, "Error: problem setting units for column %s\n", stat[column].resultColumn);
1038 return 0;
1039 }
1040 break;
1041 case SET_INTERCEPT:
1042 case SET_SLOPE:
1043 if (SDDS_GetParameterInformation(inTable, "symbol", &symbol1, SDDS_BY_NAME, stat[column].functionOf) != SDDS_STRING ||
1044 !symbol1 ||
1045 !strlen(symbol1))
1046 symbol1 = stat[column].functionOf;
1047 sprintf(s, "%s[%s:%s]", optionSuffix[stat[column].optionCode], symbol, symbol1);
1048 break;
1049 default:
1050 sprintf(s, "%s[%s]", optionSuffix[stat[column].optionCode], symbol);
1051 break;
1052 }
1053 free(symbol);
1054 if (SDDS_ChangeColumnInformation(outTable, "symbol", s, SDDS_BY_NAME, stat[column].resultColumn) != SDDS_STRING) {
1055 fprintf(stderr, "Error: problem setting symbol for column %s\n", stat[column].resultColumn);
1056 return 0;
1057 }
1058 }
1059 if (!SDDS_WriteLayout(outTable) || !SDDS_StartPage(outTable, rows))
1060 return 0;
1061 return 1;
1062}
1063
1064int compute_mean_exclude_min_max(double *value, double *data, long n) {
1065 double sum = 0;
1066 long i, count = 0;
1067 double min, max;
1068 max = -(min = DBL_MAX);
1069 if (n <= 0 || !data || !value)
1070 return 0;
1071 for (i = 0; i < n; i++) {
1072 if (min > data[i])
1073 min = data[i];
1074 if (max < data[i])
1075 max = data[i];
1076 }
1077 for (i = 0; i < n; i++) {
1078 if (data[i] == min || data[i] == max)
1079 continue;
1080 count++;
1081 sum += data[i];
1082 }
1083 if (count == 0)
1084 *value = min;
1085 else
1086 *value = sum / count;
1087 return 1;
1088}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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.
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.
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".
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_SetColumnsOfInterest(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Sets the acceptance flags for columns based on specified naming criteria.
int32_t SDDS_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns in the current data table of a data set.
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_GetParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified parameter in the SDDS dataset.
Definition SDDS_info.c:117
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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns 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_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
Definition SDDS_utils.c:304
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
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33
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 compute_percentiles(double *position, double *percent, long positions, double *x, long n)
Computes multiple percentiles of an array of doubles.
Definition median.c:84
long compute_median(double *value, double *x, long n)
Computes the median of an array of doubles.
Definition median.c:29
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.
int has_wildcards(char *template)
Check if a template string contains any wildcard characters.
Definition wild_match.c:498