127char *option[N_OPTIONS] = {
132 "standarddeviations",
142 "wstandarddeviations",
158char *optionSuffix[N_OPTIONS] = {
194 char *weightColumnName;
195 long optionCode, sumPower;
197 char *percentileString;
206 char *sourceColumn, *weightColumn, *resultColumn, *functionOf;
207 long optionCode, resultIndex, sumPower;
209 char *percentileString;
212 double *value1, *value2, *value3, *value4;
217long addStatRequests(
STAT_REQUEST **statRequest,
long requests,
char **item,
long items,
long code,
double percentile,
long power,
char *functionOf,
long weighted,
char *percentileString);
222int compute_mean_exclude_min_max(
double *value,
double *data,
long n);
224static char *USAGE =
"sddsenvelope [<input>] [<output>] [options]\n"
225 " [-pipe=[input][,output]]\n"
227 " [-maximum=<column-names>]\n"
228 " [-minimum=<column-names>]\n"
229 " [-cmaximum=<indep-column>,<column-names>]\n"
230 " [-cminimum=<indep-column>,<column-names>]\n"
231 " [-pmaximum=<indep-parameter>,<column-names>]\n"
232 " [-pminimum=<indep-parameter>,<column-names>]\n"
233 " [-largest=<column-names>]\n"
234 " [-signedLargest=<column-names>]\n"
235 " [-mean=<column-names>]\n"
236 " [-sum=<power>,<column-names>]\n"
237 " [-median=<column-names>]\n"
238 " [-decilerange=<column-names>]\n"
239 " [-percentile=<percentage>,<column-names>]\n"
240 " [-standarddeviation=<column-names>]\n"
241 " [-rms=<column-names>]\n"
242 " [-sigma=<column-names>]\n"
243 " [-slope=<indep-parameter>,<column-names>]\n"
244 " [-intercept=<indep-parameter>,<column-names>]\n"
245 " [-wmean=<weightColumn>,<columnNames>]\n"
246 " [-wstandarddeviation=<weightColumn>,<columnNames>]\n"
247 " [-wrms=<weightColumn>,<columnNames>]\n"
248 " [-wsigma=<weightColumn>,<columnNames>]\n"
249 " [-majorOrder=row|column]\n"
250 " [-threads=<number>]\n"
252 " -copy=<column-names> Copy specified columns.\n"
253 " -pipe=[input][,output] Use pipe for input/output.\n"
254 " -nowarnings Suppress warnings.\n"
255 " -maximum=<column-names> Compute maximum values.\n"
256 " -minimum=<column-names> Compute minimum values.\n"
257 " -cmaximum=<indep-column>,<column-names> Conditional maximum based on an independent column.\n"
258 " -cminimum=<indep-column>,<column-names> Conditional minimum based on an independent column.\n"
259 " -pmaximum=<indep-parameter>,<column-names> Parameter-based maximum.\n"
260 " -pminimum=<indep-parameter>,<column-names> Parameter-based minimum.\n"
261 " -largest=<column-names> Compute the largest absolute values.\n"
262 " -signedLargest=<column-names> Compute the largest signed values.\n"
263 " -mean=<column-names> Compute mean values.\n"
264 " -sum=<power>,<column-names> Compute sum with power.\n"
265 " -median=<column-names> Compute median values.\n"
266 " -decilerange=<column-names> Compute decile range.\n"
267 " -percentile=<percentage>,<column-names> Compute specified percentile.\n"
268 " -standarddeviation=<column-names> Compute standard deviations.\n"
269 " -rms=<column-names> Compute RMS values.\n"
270 " -sigma=<column-names> Compute sigma values.\n"
271 " -slope=<indep-parameter>,<column-names> Compute slope for linear fit.\n"
272 " -intercept=<indep-parameter>,<column-names> Compute intercept for linear fit.\n"
273 " -wmean=<weightColumn>,<columnNames> Compute weighted mean.\n"
274 " -wstandarddeviation=<weightColumn>,<columnNames> Compute weighted standard deviation.\n"
275 " -wrms=<weightColumn>,<columnNames> Compute weighted RMS.\n"
276 " -wsigma=<weightColumn>,<columnNames> Compute weighted sigma.\n"
277 " -majorOrder=row|column Set major order.\n\n"
278 " -threads=<number> Number of threads for row-wise statistics. The default is 1.\n"
279 "Processes pages from <input> to produce <output> with\n"
280 "one page containing the specified quantities across pages\n"
281 "for each row of the specified columns.\n"
282 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")";
284int main(
int argc,
char **argv) {
289 SCANNED_ARG *scanned;
291 long i_arg, code, power, iStat, pages, nowarnings = 0;
292 int64_t i, rows, firstRows;
293 char *input, *output;
294 double *inputData, *otherData, indepData, *weight;
295 unsigned long pipeFlags, majorOrderFlag;
296 double decilePoint[2] = {10.0, 90.0};
297 double percentilePoint;
299 short columnMajorOrder = -1;
303 argc =
scanargs(&scanned, argc, argv);
305 bomb(
"too few arguments", USAGE);
309 input = output = NULL;
312 stats = requests = pipeFlags = 0;
313 rows = firstRows = i = 0;
315 for (i_arg = 1; i_arg < argc; i_arg++) {
316 if (scanned[i_arg].arg_type == OPTION) {
318 switch (code =
match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
323 case SET_SIGNEDLARGEST:
331 if (scanned[i_arg].n_items < 2) {
332 fprintf(stderr,
"error: invalid -%s syntax\n", option[code]);
335 requests = addStatRequests(&request, requests, scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, code, 0, 0, NULL, 0, NULL);
341 if (scanned[i_arg].n_items < 3) {
342 fprintf(stderr,
"error: invalid -%s syntax\n", option[code]);
346 requests = addStatRequests(&request, requests, scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, code, 0, 0, NULL, 1, NULL);
349 if (scanned[i_arg].n_items < 3) {
350 fprintf(stderr,
"error: invalid -%s syntax\n", option[code]);
353 if (sscanf(scanned[i_arg].list[1],
"%ld", &power) != 1 || power < 1) {
354 fprintf(stderr,
"error: invalid -%s syntax--bad power in field %s\n", option[code], scanned[i_arg].list[2]);
357 requests = addStatRequests(&request, requests, scanned[i_arg].list + 2, scanned[i_arg].n_items - 2, code, 0, power, NULL, 0, NULL);
360 if (scanned[i_arg].n_items < 3) {
361 fprintf(stderr,
"error: invalid -%s syntax\n", option[code]);
364 if (sscanf(scanned[i_arg].list[1],
"%lf", &percentile) != 1 || percentile < 0 || percentile > 100) {
365 fprintf(stderr,
"error: invalid -%s syntax--bad percentage in field %s\n", option[code], scanned[i_arg].list[1]);
368 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]);
376 if (scanned[i_arg].n_items < 3) {
377 fprintf(stderr,
"error: invalid -%s syntax\n", option[code]);
380 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);
383 if (!
processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipeFlags))
389 case SET_MAJOR_ORDER:
391 scanned[i_arg].n_items--;
392 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)))
393 SDDS_Bomb(
"invalid -majorOrder syntax/values");
394 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
395 columnMajorOrder = 1;
396 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
397 columnMajorOrder = 0;
400 if (scanned[i_arg].n_items != 2 ||
401 sscanf(scanned[i_arg].list[1],
"%d", &threads) != 1 ||
406 fprintf(stderr,
"error: unknown option '%s' given\n", scanned[i_arg].list[0]);
413 input = scanned[i_arg].list[0];
415 output = scanned[i_arg].list[0];
433 SDDS_Bomb(
"empty data page in input file");
436 if (!(stat = compileStatDefinitions(&inTable, &stats, request, requests))) {
440 if (!setupOutputFile(&outTable, output, &inTable, stat, stats, rows, columnMajorOrder)) {
444 fprintf(stderr,
"Error setting up output file.\n");
447 }
else if (firstRows != rows)
448 SDDS_Bomb(
"inconsistent number of rows in input file");
449 for (iStat = 0; iStat < stats; iStat++) {
450 if (stat[iStat].optionCode == SET_COPY) {
451 if (code == 1 && !(stat[iStat].copy =
SDDS_GetColumn(&inTable, stat[iStat].sourceColumn)))
455 stat[iStat].copy = NULL;
458 switch (stat[iStat].optionCode) {
461#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
462 for (i = 0; i < rows; i++)
463 stat[iStat].value1[i] = inputData[i];
465#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
466 for (i = 0; i < rows; i++)
467 if (stat[iStat].value1[i] > inputData[i])
468 stat[iStat].value1[i] = inputData[i];
472#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
473 for (i = 0; i < rows; i++)
474 stat[iStat].value1[i] = inputData[i];
476#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
477 for (i = 0; i < rows; i++)
478 if (stat[iStat].value1[i] < inputData[i])
479 stat[iStat].value1[i] = inputData[i];
486#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
487 for (i = 0; i < rows; i++) {
488 stat[iStat].value2[i] = inputData[i];
489 stat[iStat].value1[i] = otherData[i];
492#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
493 for (i = 0; i < rows; i++)
494 if (stat[iStat].value2[i] > inputData[i]) {
495 stat[iStat].value2[i] = inputData[i];
496 stat[iStat].value1[i] = otherData[i];
505#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
506 for (i = 0; i < rows; i++) {
507 stat[iStat].value2[i] = inputData[i];
508 stat[iStat].value1[i] = otherData[i];
511#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
512 for (i = 0; i < rows; i++)
513 if (stat[iStat].value2[i] < inputData[i]) {
514 stat[iStat].value2[i] = inputData[i];
515 stat[iStat].value1[i] = otherData[i];
521#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
522 for (i = 0; i < rows; i++)
523 stat[iStat].value1[i] = fabs(inputData[i]);
525#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
526 for (i = 0; i < rows; i++)
527 if (stat[iStat].value1[i] < fabs(inputData[i]))
528 stat[iStat].value1[i] = fabs(inputData[i]);
530 case SET_SIGNEDLARGEST:
532#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
533 for (i = 0; i < rows; i++)
534 stat[iStat].value1[i] = inputData[i];
536#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
537 for (i = 0; i < rows; i++)
538 if (fabs(stat[iStat].value1[i]) < fabs(inputData[i]))
539 stat[iStat].value1[i] = inputData[i];
543#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
544 for (i = 0; i < rows; i++)
545 stat[iStat].value1[i] = inputData[i];
547#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
548 for (i = 0; i < rows; i++)
549 stat[iStat].value1[i] += inputData[i];
554#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
555 for (i = 0; i < rows; i++) {
556 stat[iStat].sumWeight[i] += weight[i];
557 stat[iStat].value1[i] += inputData[i] * weight[i];
564#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
565 for (i = 0; i < rows; i++) {
566 stat[iStat].value1[i] = inputData[i];
567 stat[iStat].value2[i] = inputData[i] * inputData[i];
570#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
571 for (i = 0; i < rows; i++) {
572 stat[iStat].value1[i] += inputData[i];
573 stat[iStat].value2[i] += inputData[i] * inputData[i];
580#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
581 for (i = 0; i < rows; i++) {
582 stat[iStat].sumWeight[i] += weight[i];
583 stat[iStat].value1[i] += inputData[i] * weight[i];
584 stat[iStat].value2[i] += inputData[i] * inputData[i] * weight[i];
590#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
591 for (i = 0; i < rows; i++)
592 stat[iStat].value1[i] = inputData[i] * inputData[i];
594#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
595 for (i = 0; i < rows; i++)
596 stat[iStat].value1[i] += inputData[i] * inputData[i];
601#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
602 for (i = 0; i < rows; i++) {
603 stat[iStat].sumWeight[i] += weight[i];
604 stat[iStat].value1[i] += inputData[i] * inputData[i] * weight[i];
610#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
611 for (i = 0; i < rows; i++)
612 stat[iStat].value1[i] =
ipow(inputData[i], stat[iStat].sumPower);
614#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
615 for (i = 0; i < rows; i++)
616 stat[iStat].value1[i] +=
ipow(inputData[i], stat[iStat].sumPower);
620 fprintf(stderr,
"error: unable to get value of parameter %s\n", stat[iStat].functionOf);
624#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
625 for (i = 0; i < rows; i++) {
626 stat[iStat].value2[i] = inputData[i];
627 stat[iStat].value1[i] = indepData;
630#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
631 for (i = 0; i < rows; i++) {
632 if (stat[iStat].value2[i] > inputData[i]) {
633 stat[iStat].value2[i] = inputData[i];
634 stat[iStat].value1[i] = indepData;
640 fprintf(stderr,
"error: unable to get value of parameter %s\n", stat[iStat].functionOf);
644#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
645 for (i = 0; i < rows; i++) {
646 stat[iStat].value2[i] = inputData[i];
647 stat[iStat].value1[i] = indepData;
650#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
651 for (i = 0; i < rows; i++) {
652 if (stat[iStat].value2[i] < inputData[i]) {
653 stat[iStat].value2[i] = inputData[i];
654 stat[iStat].value1[i] = indepData;
661 fprintf(stderr,
"error: unable to get value of parameter %s\n", stat[iStat].functionOf);
671#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
672 for (i = 0; i < rows; i++) {
673 stat[iStat].value1[i] = indepData;
674 stat[iStat].value2[i] = indepData * indepData;
675 stat[iStat].value3[i] = inputData[i];
676 stat[iStat].value4[i] = indepData * inputData[i];
679#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
680 for (i = 0; i < rows; i++) {
681 stat[iStat].value1[i] += indepData;
682 stat[iStat].value2[i] += indepData * indepData;
683 stat[iStat].value3[i] += inputData[i];
684 stat[iStat].value4[i] += indepData * inputData[i];
692#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
693 for (i = 0; i < rows; i++) {
694 stat[iStat].array[i] =
tmalloc(
sizeof(*stat[iStat].array[i]));
695 stat[iStat].array[i][pages - 1] = inputData[i];
698#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
699 for (i = 0; i < rows; i++) {
700 stat[iStat].array[i] =
SDDS_Realloc(stat[iStat].array[i],
sizeof(*stat[iStat].array[i]) * pages);
701 stat[iStat].array[i][pages - 1] = inputData[i];
706 SDDS_Bomb(
"invalid statistic code (accumulation loop)");
714 for (iStat = 0; iStat < stats; iStat++) {
715 switch (stat[iStat].optionCode) {
724 case SET_SIGNEDLARGEST:
728#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
729 for (i = 0; i < rows; i++)
730 stat[iStat].value1[i] /= pages;
733 for (i = 0; i < rows; i++)
734 if (stat[iStat].sumWeight[i])
735 stat[iStat].value1[i] /= stat[iStat].sumWeight[i];
738 fprintf(stderr,
"warning: the total weight for the %" PRId64
"th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
739 stat[iStat].value1[i] = DBL_MAX;
744#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
745 for (i = 0; i < rows; i++)
746 stat[iStat].value1[i] = DBL_MAX;
748#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
749 for (i = 0; i < rows; i++) {
751 if ((tmp1 = stat[iStat].value2[i] / pages - sqr(stat[iStat].value1[i] / pages)) <= 0)
752 stat[iStat].value1[i] = 0;
754 stat[iStat].value1[i] = sqrt(tmp1 * pages / (pages - 1.0));
760#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
761 for (i = 0; i < rows; i++)
762 stat[iStat].value1[i] = DBL_MAX;
764 for (i = 0; i < rows; i++) {
766 if (stat[iStat].sumWeight[i]) {
767 if ((tmp1 = stat[iStat].value2[i] / stat[iStat].sumWeight[i] - sqr(stat[iStat].value1[i] / stat[iStat].sumWeight[i])) <= 0)
768 stat[iStat].value1[i] = 0;
770 stat[iStat].value1[i] = sqrt(tmp1 * pages / (pages - 1.0));
773 fprintf(stderr,
"Warning, the total weight for the %" PRId64
"th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
774 stat[iStat].value1[i] = DBL_MAX;
781#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
782 for (i = 0; i < rows; i++)
783 stat[iStat].value1[i] = DBL_MAX;
785#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
786 for (i = 0; i < rows; i++) {
788 if ((tmp1 = stat[iStat].value2[i] / pages - sqr(stat[iStat].value1[i] / pages)) <= 0)
789 stat[iStat].value1[i] = 0;
791 stat[iStat].value1[i] = sqrt(tmp1 / (pages - 1.0));
797#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
798 for (i = 0; i < rows; i++)
799 stat[iStat].value1[i] = DBL_MAX;
801 for (i = 0; i < rows; i++) {
803 if (stat[iStat].sumWeight[i]) {
804 if ((tmp1 = stat[iStat].value2[i] / stat[iStat].sumWeight[i] - sqr(stat[iStat].value1[i] / stat[iStat].sumWeight[i])) <= 0)
805 stat[iStat].value1[i] = 0;
807 stat[iStat].value1[i] = sqrt(tmp1 / (pages - 1.0));
810 fprintf(stderr,
"Warning, the total weight for the %" PRId64
"th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
811 stat[iStat].value1[i] = DBL_MAX;
817#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
818 for (i = 0; i < rows; i++)
819 stat[iStat].value1[i] = sqrt(stat[iStat].value1[i] / pages);
822 for (i = 0; i < rows; i++) {
823 if (stat[iStat].sumWeight[i])
824 stat[iStat].value1[i] = sqrt(stat[iStat].value1[i] / stat[iStat].sumWeight[i]);
827 fprintf(stderr,
"Warning, the total weight for the %" PRId64
"th row of %s is zero.\n", i + 1, stat[iStat].sourceColumn);
828 stat[iStat].value1[i] = DBL_MAX;
833#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
834 for (i = 0; i < rows; i++) {
836 D = pages * stat[iStat].value2[i] - stat[iStat].value1[i] * stat[iStat].value1[i];
837 stat[iStat].value1[i] = (pages * stat[iStat].value4[i] - stat[iStat].value1[i] * stat[iStat].value3[i]) / D;
841#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
842 for (i = 0; i < rows; i++) {
844 D = pages * stat[iStat].value2[i] - stat[iStat].value1[i] * stat[iStat].value1[i];
845 stat[iStat].value1[i] = (stat[iStat].value2[i] * stat[iStat].value3[i] - stat[iStat].value1[i] * stat[iStat].value4[i]) / D;
849#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
850 for (i = 0; i < rows; i++) {
851 compute_median(&stat[iStat].value1[i], stat[iStat].array[i], pages);
855#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
856 for (i = 0; i < rows; i++) {
857 double decileResult[2];
859 stat[iStat].value1[i] = 0;
861 stat[iStat].value1[i] = decileResult[1] - decileResult[0];
865 percentilePoint = stat[iStat].percentile;
866#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
867 for (i = 0; i < rows; i++) {
868 double percentileResult;
869 if (!
compute_percentiles(&percentileResult, &percentilePoint, 1, stat[iStat].array[i], pages))
870 stat[iStat].value1[i] = 0;
872 stat[iStat].value1[i] = percentileResult;
876#pragma omp parallel for if (threads > 1 && rows > 1) num_threads(threads)
877 for (i = 0; i < rows; i++)
878 if (!compute_mean_exclude_min_max(&(stat[iStat].value1[i]), stat[iStat].array[i], pages))
879 stat[iStat].value1[i] = 0;
882 SDDS_Bomb(
"invalid statistic code (final loop)");
885 if (stat[iStat].optionCode == SET_COPY) {
886 if (!
SDDS_SetColumn(&outTable, SDDS_SET_BY_NAME, stat[iStat].copy, rows, stat[iStat].resultColumn)) {
887 fprintf(stderr,
"error setting column values for column %s\n", stat[iStat].resultColumn);
890 }
else if (!
SDDS_SetColumnFromDoubles(&outTable, SDDS_SET_BY_NAME, stat[iStat].value1, rows, stat[iStat].resultColumn)) {
891 fprintf(stderr,
"error setting column values for column %s\n", stat[iStat].resultColumn);
894 if (stat[iStat].value1)
895 free(stat[iStat].value1);
896 if (stat[iStat].value2)
897 free(stat[iStat].value2);
898 if (stat[iStat].value3)
899 free(stat[iStat].value3);
900 if (stat[iStat].value4)
901 free(stat[iStat].value4);
902 if (stat[iStat].copy)
903 free(stat[iStat].copy);
904 if (stat[iStat].array) {
905 for (i = 0; i < rows; i++) {
906 free(stat[iStat].array[i]);
908 free(stat[iStat].array);
910 if (stat[iStat].sumWeight)
911 free(stat[iStat].sumWeight);
912 free(stat[iStat].sourceColumn);
913 free(stat[iStat].resultColumn);
914 stat[iStat].value1 = stat[iStat].value2 = stat[iStat].value3 = stat[iStat].value4 = NULL;
915 stat[iStat].copy = NULL;
916 stat[iStat].array = NULL;
924long addStatRequests(
STAT_REQUEST **statRequest,
long requests,
char **item,
long items,
long code,
double percentile,
long power,
char *functionOf,
long weighted,
char *percentileString) {
927 if (weighted != 0 && weighted != 1)
928 SDDS_Bomb(
"addStatRequests: weighted parameter should be either 0 or 1");
929 if (code == SET_PERCENTILE && (!percentileString || !strlen(percentileString))) {
930 fprintf(stderr,
"Percentile specification is incorrect: percentile=%e, percentileString=%s\n", percentile, percentileString ? percentileString :
"NULL");
933 *statRequest =
SDDS_Realloc(*statRequest,
sizeof(**statRequest) * (requests + items - weighted));
934 for (i = 0; i < items - weighted; i++) {
936 (*statRequest)[requests + i].weightColumnName = item[0];
938 (*statRequest)[requests + i].weightColumnName = NULL;
939 (*statRequest)[i + requests].columnName = item[i + weighted];
940 (*statRequest)[i + requests].optionCode = code;
941 (*statRequest)[i + requests].sumPower = power;
942 (*statRequest)[i + requests].percentile = percentile;
943 (*statRequest)[i + requests].percentileString = percentileString;
944 (*statRequest)[i + requests].functionOf = functionOf;
947 return items + requests - weighted;
952 long iReq, iStat, iName;
954 char s[SDDS_MAXLINE];
958 stat =
tmalloc(
sizeof(*stat) * requests);
959 for (iReq = 0; iReq < requests; iReq++) {
961 stat =
SDDS_Realloc(stat,
sizeof(*stat) * (*stats += 10));
964 sprintf(s,
"error: column %s not found input file", request[iReq].columnName);
968 stat[iStat].weightColumn = request[iReq].weightColumnName;
969 stat[iStat].sourceColumn = request[iReq].columnName;
970 stat[iStat].optionCode = request[iReq].optionCode;
971 stat[iStat].percentile = request[iReq].percentile;
972 stat[iStat].percentileString = request[iReq].percentileString;
973 stat[iStat].sumPower = request[iReq].sumPower;
974 stat[iStat].value1 = stat[iStat].value2 = stat[iStat].value3 = stat[iStat].value4 = NULL;
975 stat[iStat].array = NULL;
976 stat[iStat].copy = NULL;
977 stat[iStat].sumWeight = NULL;
978 if ((stat[iStat].functionOf = request[iReq].functionOf)) {
979 if (stat[iStat].optionCode != SET_CMAXIMA && stat[iStat].optionCode != SET_CMINIMA) {
981 sprintf(s,
"error: parameter %s not found input file (1)", request[iReq].functionOf);
987 sprintf(s,
"error: column %s not found input file (1)", request[iReq].functionOf);
999 sprintf(s,
"no columns selected for wildcard sequence %s", request[iReq].columnName);
1001 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1003 if (iStat + columnNames > *stats)
1004 stat =
SDDS_Realloc(stat,
sizeof(*stat) * (*stats = iStat + columnNames + 10));
1005 for (iName = 0; iName < columnNames; iName++) {
1006 stat[iStat + iName].weightColumn = request[iReq].weightColumnName;
1007 stat[iStat + iName].sourceColumn = columnName[iName];
1008 stat[iStat + iName].optionCode = request[iReq].optionCode;
1009 stat[iStat + iName].sumPower = request[iReq].sumPower;
1010 stat[iStat + iName].percentile = request[iReq].percentile;
1011 stat[iStat + iName].percentileString = request[iReq].percentileString;
1012 stat[iStat + iName].value1 = stat[iStat + iName].value2 = stat[iStat + iName].value3 = stat[iStat + iName].value4 = NULL;
1013 stat[iStat + iName].array = NULL;
1014 stat[iStat + iName].copy = NULL;
1015 stat[iStat + iName].sumWeight = NULL;
1016 if ((stat[iStat + iName].functionOf = request[iReq].functionOf) && iName == 0) {
1017 if (stat[iStat + iName].optionCode != SET_CMAXIMA && stat[iStat + iName].optionCode != SET_CMINIMA) {
1019 sprintf(s,
"error: parameter %s not found input file (2)", request[iReq].functionOf);
1021 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1025 sprintf(s,
"error: column %s not found input file (2)", request[iReq].functionOf);
1027 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1032 iStat += columnNames;
1038 for (iStat = 0; iStat < *stats; iStat++) {
1039 switch (stat[iStat].optionCode) {
1041 strcpy(s, stat[iStat].sourceColumn);
1044 if (stat[iStat].sumPower == 1)
1045 sprintf(s,
"%s%s", stat[iStat].sourceColumn, optionSuffix[stat[iStat].optionCode]);
1047 sprintf(s,
"%s%ld%s", stat[iStat].sourceColumn, stat[iStat].sumPower, optionSuffix[stat[iStat].optionCode]);
1049 case SET_PERCENTILE:
1050 sprintf(s,
"%s%s%s", stat[iStat].sourceColumn, stat[iStat].percentileString, optionSuffix[stat[iStat].optionCode]);
1054 sprintf(s,
"%s%s%s", stat[iStat].functionOf, optionSuffix[stat[iStat].optionCode], stat[iStat].sourceColumn);
1058 sprintf(s,
"%s%s%s", stat[iStat].functionOf, optionSuffix[stat[iStat].optionCode], stat[iStat].sourceColumn);
1061 sprintf(s,
"%s%s", stat[iStat].sourceColumn, optionSuffix[stat[iStat].optionCode]);
1065 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1072 char s[SDDS_MAXLINE], *symbol, *symbol1, *units1;
1076 if (columnMajorOrder != -1)
1077 outTable->layout.data_mode.column_major = columnMajorOrder;
1079 outTable->layout.data_mode.column_major = inTable->layout.data_mode.column_major;
1080 for (column = 0; column < stats; column++) {
1081 stat[column].value1 = calloc(
sizeof(*stat[column].value1), rows);
1082 stat[column].value2 = stat[column].value3 = stat[column].value4 = NULL;
1083 if (stat[column].optionCode == SET_SDS || stat[column].optionCode == SET_SIGMAS ||
1084 stat[column].optionCode == SET_WSDS || stat[column].optionCode == SET_WSIGMAS ||
1085 stat[column].optionCode == SET_PMINIMA || stat[column].optionCode == SET_PMAXIMA ||
1086 stat[column].optionCode == SET_CMINIMA || stat[column].optionCode == SET_CMAXIMA)
1087 stat[column].value2 = calloc(
sizeof(*stat[column].value2), rows);
1088 if (stat[column].optionCode == SET_INTERCEPT || stat[column].optionCode == SET_SLOPE) {
1089 stat[column].value2 = malloc(
sizeof(*stat[column].value2) * rows);
1090 stat[column].value3 = malloc(
sizeof(*stat[column].value3) * rows);
1091 stat[column].value4 = malloc(
sizeof(*stat[column].value4) * rows);
1093 if (stat[column].optionCode == SET_WSDS || stat[column].optionCode == SET_WSIGMAS ||
1094 stat[column].optionCode == SET_WRMSS || stat[column].optionCode == SET_WMEANS)
1095 stat[column].sumWeight = calloc(
sizeof(*stat[column].sumWeight), rows);
1096 if (stat[column].optionCode == SET_MEDIAN || stat[column].optionCode == SET_DRANGE ||
1097 stat[column].optionCode == SET_PERCENTILE || stat[column].optionCode == SET_EXMM_MEAN) {
1098 stat[column].array =
tmalloc(
sizeof(*stat[column].array) * rows);
1101 sprintf(s,
"Problem transferring definition of column %s to %s\n", stat[column].sourceColumn, stat[column].resultColumn);
1107 fprintf(stderr,
"Error: problem setting description for column %s\n", stat[column].resultColumn);
1110 if (stat[column].optionCode > 0) {
1112 fprintf(stderr,
"Error: problem setting type for column %s\n", stat[column].resultColumn);
1118 switch (stat[column].optionCode) {
1123 if (stat[column].sumPower == 1)
1124 sprintf(s,
"%s[%s]", optionSuffix[stat[column].optionCode], symbol);
1126 sprintf(s,
"%s[%s$a%ld$n]", optionSuffix[stat[column].optionCode], symbol, stat[column].sumPower);
1128 case SET_PERCENTILE:
1129 sprintf(s,
"%s[%s,%g]", optionSuffix[stat[column].optionCode], symbol, stat[column].percentile);
1136 symbol1 = stat[column].functionOf;
1137 sprintf(s,
"%s[%s:%s]", optionSuffix[stat[column].optionCode], symbol, symbol1);
1142 fprintf(stderr,
"Error: problem setting units for column %s (1)\n", stat[column].resultColumn);
1146 fprintf(stderr,
"Error: problem setting units for column %s (2)\n", stat[column].resultColumn);
1155 symbol1 = stat[column].functionOf;
1156 sprintf(s,
"%s[%s:%s]", optionSuffix[stat[column].optionCode], symbol, symbol1);
1161 fprintf(stderr,
"Error: problem setting units for column %s\n", stat[column].resultColumn);
1165 fprintf(stderr,
"Error: problem setting units for column %s\n", stat[column].resultColumn);
1174 symbol1 = stat[column].functionOf;
1175 sprintf(s,
"%s[%s:%s]", optionSuffix[stat[column].optionCode], symbol, symbol1);
1178 sprintf(s,
"%s[%s]", optionSuffix[stat[column].optionCode], symbol);
1183 fprintf(stderr,
"Error: problem setting symbol for column %s\n", stat[column].resultColumn);
1192int compute_mean_exclude_min_max(
double *value,
double *data,
long n) {
1196 max = -(min = DBL_MAX);
1197 if (n <= 0 || !data || !value)
1199 for (i = 0; i < n; i++) {
1205 for (i = 0; i < n; i++) {
1206 if (data[i] == min || data[i] == max)
1214 *value = sum / count;
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.
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.
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.
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.
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.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
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)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
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.