SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sddsrunstats.c File Reference

Detailed Description

Computes running statistics on SDDS data columns.

This program calculates various running statistics (e.g., mean, median, minimum, maximum, etc.) on columns of data from an SDDS (Self-Describing Data Set) file. The program supports multiple options for statistical analysis and allows for processing of sliding window or blocked statistics.

Usage

sddsrunstats [<input>] [<output>]
[-pipe[=input][,output]]
[-points=<integer>]
[-window=column=<column>,width=<value>}]
[-noOverlap]
[-partialOk]
[-mean=[<limitOps>],<columnNameList>]
[-median=[<limitOps>],<columnNameList>]
[-minimum=[<limitOps>],<columnNameList>]
[-maximum=[<limitOps>],<columnNameList>]
[-standardDeviation=[<limitOps>],<columnNameList>]
[-sigma=[<limitOps>],<columnNameList>]
[-sum=[<limitOps>][,power=<integer>],<columnNameList>]
[-sample=[<limitOps>],<columnNameList>]
[-slope=independent=<columnName>,<columnNameList>]
[-majorOrder=row|column]
[-threads=<number>]
<limitOps> is of the form [topLimit=<value>,][bottomLimit=<value>]
double standardDeviation(double *x, long n)
Calculates the standard deviation of an array of doubles.
Definition moments.c:37

Options

Option Description
-pipe Use standard input and/or output streams.
-points Number of points for running statistics. Use 0 for entire page statistics.
-window Defines a sliding window based on a column and window width.
-noOverlap Perform blocked statistics instead of sliding window statistics.
-partialOk Allow computations even if available rows are fewer than specified points.
-mean Compute mean of specified columns with optional limits.
-median Compute median of specified columns with optional limits.
-minimum Compute minimum of specified columns with optional limits.
-maximum Compute maximum of specified columns with optional limits.
-standardDeviation Compute standard deviation with optional limits.
-sigma Compute sigma of specified columns with optional limits.
-sum Compute sum (optionally raised to a power) with optional limits.
-sample Sample values from specified columns with optional limits.
-slope Compute slope of specified columns with a designated independent column.
-majorOrder Specify the major order for data processing.
-threads Number of threads for per-column running-statistic calculations.

Incompatibilities

  • Only one of the following may be specified:
    • -points
    • -window
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
M. Borland, R. Soliday, H. Shang

Definition in file sddsrunstats.c.

#include "mdb.h"
#include "scan.h"
#include "SDDS.h"
#include "SDDSutils.h"
#include <ctype.h>

Go to the source code of this file.

Functions

long addStatRequests (STAT_REQUEST **statRequest, long requests, char **item, long items, long code, unsigned long flag)
 
STAT_DEFINITIONcompileStatDefinitions (SDDS_DATASET *inTable, STAT_REQUEST *request, long requests)
 
long setupOutputFile (SDDS_DATASET *outTable, char *output, SDDS_DATASET *inTable, STAT_DEFINITION *stat, long stats, short columnMajorOrder)
 
static double computeRunningStatistic (STAT_DEFINITION *stat, double *inputDataOffset, double *indepDataOffset, int64_t pointsToStat)
 
int main (int argc, char **argv)
 

Function Documentation

◆ addStatRequests()

long addStatRequests ( STAT_REQUEST ** statRequest,
long requests,
char ** item,
long items,
long code,
unsigned long flag )

Definition at line 639 of file sddsrunstats.c.

639 {
640 long i;
641 if (!(*statRequest = SDDS_Realloc(*statRequest, sizeof(**statRequest) * (requests + 1))) ||
642 !((*statRequest)[requests].sourceColumn = (char **)malloc(sizeof(*(*statRequest)[requests].sourceColumn) * items)))
643 SDDS_Bomb("memory allocation failure");
644 for (i = 0; i < items; i++) {
645 (*statRequest)[requests].sourceColumn[i] = item[i];
646 }
647 (*statRequest)[requests].sourceColumns = items;
648 (*statRequest)[requests].optionCode = code;
649 (*statRequest)[requests].sumPower = 1;
650 (*statRequest)[requests].flags = flags;
651 (*statRequest)[requests].independentColumn = NULL;
652 return requests + 1;
653}
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:380
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:743

◆ compileStatDefinitions()

STAT_DEFINITION * compileStatDefinitions ( SDDS_DATASET * inTable,
STAT_REQUEST * request,
long requests )

Definition at line 655 of file sddsrunstats.c.

655 {
656 STAT_DEFINITION *stat;
657 long iReq, iName;
658 char s[SDDS_MAXLINE];
659
660 if (!(stat = (STAT_DEFINITION *)malloc(sizeof(*stat) * requests)))
661 SDDS_Bomb("memory allocation failure");
662 for (iReq = 0; iReq < requests; iReq++) {
663 if ((stat[iReq].sourceColumns = expandColumnPairNames(inData, &request[iReq].sourceColumn, NULL, request[iReq].sourceColumns, NULL, 0, FIND_NUMERIC_TYPE, 0)) <= 0) {
664 fprintf(stderr, "Error: no match for column names (sddsrunstats):\n");
665 for (iName = 0; iName < request[iReq].sourceColumns; iName++)
666 fprintf(stderr, "%s, ", request[iReq].sourceColumn[iReq]);
667 fputc('\n', stderr);
668 exit(EXIT_FAILURE);
669 }
670 stat[iReq].sourceColumn = request[iReq].sourceColumn;
671 if (!(stat[iReq].resultColumn = malloc(sizeof(*stat[iReq].resultColumn) * stat[iReq].sourceColumns)) ||
672 !(stat[iReq].resultIndex = malloc(sizeof(*stat[iReq].resultIndex) * stat[iReq].sourceColumns))) {
673 SDDS_Bomb("memory allocation failure");
674 }
675 for (iName = 0; iName < stat[iReq].sourceColumns; iName++) {
676 sprintf(s, "%s%s", stat[iReq].sourceColumn[iName], statSuffix[request[iReq].optionCode]);
677 SDDS_CopyString(stat[iReq].resultColumn + iName, s);
678 }
679 stat[iReq].optionCode = request[iReq].optionCode;
680 stat[iReq].sumPower = request[iReq].sumPower;
681 stat[iReq].flags = request[iReq].flags;
682 stat[iReq].topLimit = request[iReq].topLimit;
683 stat[iReq].bottomLimit = request[iReq].bottomLimit;
684 stat[iReq].independentColumn = request[iReq].independentColumn;
685 }
686
687 return stat;
688}
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:922

◆ computeRunningStatistic()

static double computeRunningStatistic ( STAT_DEFINITION * stat,
double * inputDataOffset,
double * indepDataOffset,
int64_t pointsToStat )
static

Definition at line 505 of file sddsrunstats.c.

505 {
506 int64_t rowOffset, count;
507 double result, sum1, sum2, slope, intercept, variance;
508 double *newData;
509
510 switch (stat->optionCode) {
511 case SET_MAXIMUM:
512 result = -DBL_MAX;
513 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
514 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
515 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
516 continue;
517 if (inputDataOffset[rowOffset] > result)
518 result = inputDataOffset[rowOffset];
519 }
520 break;
521 case SET_MINIMUM:
522 result = DBL_MAX;
523 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
524 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
525 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
526 continue;
527 if (inputDataOffset[rowOffset] < result)
528 result = inputDataOffset[rowOffset];
529 }
530 break;
531 case SET_MEAN:
532 result = 0;
533 count = 0;
534 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
535 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
536 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
537 continue;
538 result += inputDataOffset[rowOffset];
539 count++;
540 }
541 if (count)
542 result /= count;
543 else
544 result = DBL_MAX;
545 break;
546 case SET_MEDIAN:
547 result = 0;
548 count = 0;
549 newData = NULL;
550 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
551 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
552 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
553 continue;
554 newData = SDDS_Realloc(newData, sizeof(*newData) * (count + 1));
555 newData[count] = inputDataOffset[rowOffset];
556 count++;
557 }
558 if (count) {
559 if (!compute_median(&result, newData, count))
560 result = DBL_MAX;
561 free(newData);
562 } else
563 result = DBL_MAX;
564 break;
565 case SET_STANDARDDEVIATION:
566 case SET_SIGMA:
567 sum1 = sum2 = count = 0;
568 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
569 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
570 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
571 continue;
572 sum1 += inputDataOffset[rowOffset];
573 sum2 += inputDataOffset[rowOffset] * inputDataOffset[rowOffset];
574 count++;
575 }
576 if (count > 1) {
577 if ((result = sum2 / count - sqr(sum1 / count)) <= 0)
578 result = 0;
579 else
580 result = sqrt(result * count / (count - 1.0));
581 if (stat->optionCode == SET_SIGMA)
582 result /= sqrt(count);
583 } else
584 result = DBL_MAX;
585 break;
586 case SET_RMS:
587 sum2 = count = 0;
588 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
589 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
590 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
591 continue;
592 sum2 += inputDataOffset[rowOffset] * inputDataOffset[rowOffset];
593 count++;
594 }
595 if (count > 0)
596 result = sqrt(sum2 / count);
597 else
598 result = DBL_MAX;
599 break;
600 case SET_SUM:
601 sum1 = count = 0;
602 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
603 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
604 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
605 continue;
606 sum1 += ipow(inputDataOffset[rowOffset], stat->sumPower);
607 count++;
608 }
609 if (count > 0)
610 result = sum1;
611 else
612 result = DBL_MAX;
613 break;
614 case SET_SLOPE:
615 if (!indepDataOffset ||
616 !unweightedLinearFit(indepDataOffset, inputDataOffset, pointsToStat, &slope, &intercept, &variance)) {
617 result = DBL_MAX;
618 } else
619 result = slope;
620 break;
621 case SET_SAMPLE:
622 result = DBL_MAX;
623 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
624 if ((stat->flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat->topLimit) ||
625 (stat->flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat->bottomLimit))
626 continue;
627 result = inputDataOffset[rowOffset];
628 break;
629 }
630 break;
631 default:
632 fprintf(stderr, "Unknown statistics code %ld in sddsrunstats\n", stat->optionCode);
633 exit(EXIT_FAILURE);
634 break;
635 }
636 return result;
637}
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33
long unweightedLinearFit(double *xData, double *yData, long nData, double *slope, double *intercept, double *variance)
Performs an unweighted linear fit on the provided data.
Definition linfit.c:37
long compute_median(double *value, double *x, long n)
Computes the median of an array of doubles.
Definition median.c:29

◆ main()

int main ( int argc,
char ** argv )

Definition at line 198 of file sddsrunstats.c.

198 {
199 STAT_DEFINITION *stat;
200 long stats;
201 STAT_REQUEST *request;
202 long requests;
203 SCANNED_ARG *scanned;
204 SDDS_DATASET inData, outData;
205 char *independent;
206 int32_t power;
207 int64_t pointsToStat;
208 long pointsToStat0, overlap;
209 int64_t rows, outputRowsMax, outputRows, outputRow;
210 long iArg, code, iStat, iColumn;
211 int64_t startRow, rowsToSet;
212 char *input, *output, *windowColumn;
213 double *inputData, *outputData, topLimit, bottomLimit, *inputDataOffset;
214 double windowWidth, *windowData;
215 long windowIndex;
216 unsigned long pipeFlags, scanFlags, majorOrderFlag;
217 char s[100];
218 long lastRegion, region, windowRef, partialOk;
219 short columnMajorOrder = -1;
220 int threads = 1;
221
223 argc = scanargs(&scanned, argc, argv);
224 if (argc < 2) {
225 bomb("too few arguments", USAGE);
226 }
227 input = output = NULL;
228 stat = NULL;
229 request = NULL;
230 stats = requests = pipeFlags = 0;
231 pointsToStat = -1;
232 partialOk = 0;
233 overlap = 1;
234 windowColumn = NULL;
235 windowData = NULL;
236
237 for (iArg = 1; iArg < argc; iArg++) {
238 scanFlags = 0;
239 if (scanned[iArg].arg_type == OPTION) {
240 /* process options here */
241 switch (code = match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
242 case SET_MAJOR_ORDER:
243 majorOrderFlag = 0;
244 scanned[iArg].n_items--;
245 if (scanned[iArg].n_items > 0 &&
246 (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
247 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
248 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
249 SDDS_Bomb("invalid -majorOrder syntax/values");
250 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
251 columnMajorOrder = 1;
252 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
253 columnMajorOrder = 0;
254 break;
255 case SET_THREADS:
256 if (scanned[iArg].n_items != 2 ||
257 sscanf(scanned[iArg].list[1], "%d", &threads) != 1 ||
258 threads < 1)
259 SDDS_Bomb("invalid -threads syntax");
260 break;
261 case SET_POINTS:
262 if (scanned[iArg].n_items != 2 || sscanf(scanned[iArg].list[1], "%" SCNd64, &pointsToStat) != 1 ||
263 (pointsToStat <= 2 && pointsToStat != 0))
264 SDDS_Bomb("invalid -points syntax");
265 break;
266 case SET_NOOVERLAP:
267 overlap = 0;
268 break;
269 case SET_MAXIMUM:
270 case SET_MINIMUM:
271 case SET_MEAN:
272 case SET_STANDARDDEVIATION:
273 case SET_RMS:
274 case SET_SIGMA:
275 case SET_SAMPLE:
276 case SET_MEDIAN:
277 if (scanned[iArg].n_items < 2) {
278 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
279 exit(EXIT_FAILURE);
280 }
281 if (!scanItemList(&scanFlags, scanned[iArg].list, &scanned[iArg].n_items,
282 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS | SCANITEMLIST_IGNORE_VALUELESS,
283 "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
284 "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN, NULL)) {
285 sprintf(s, "invalid -%s syntax", scanned[iArg].list[0]);
286 SDDS_Bomb(s);
287 }
288 requests = addStatRequests(&request, requests, scanned[iArg].list + 1, scanned[iArg].n_items - 1, code, scanFlags);
289 request[requests - 1].topLimit = topLimit;
290 request[requests - 1].bottomLimit = bottomLimit;
291 break;
292 case SET_SUM:
293 if (scanned[iArg].n_items < 2) {
294 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
295 exit(EXIT_FAILURE);
296 }
297 power = 1;
298 if (!scanItemList(&scanFlags, scanned[iArg].list, &scanned[iArg].n_items,
299 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS | SCANITEMLIST_IGNORE_VALUELESS,
300 "power", SDDS_LONG, &power, 1, 0,
301 "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
302 "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN, NULL))
303 SDDS_Bomb("invalid -sum syntax");
304 requests = addStatRequests(&request, requests, scanned[iArg].list + 1, scanned[iArg].n_items - 1, code, scanFlags);
305 request[requests - 1].sumPower = power;
306 request[requests - 1].topLimit = topLimit;
307 request[requests - 1].bottomLimit = bottomLimit;
308 break;
309 case SET_SLOPE:
310 if (scanned[iArg].n_items < 2) {
311 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
312 exit(EXIT_FAILURE);
313 }
314 if (!scanItemList(&scanFlags, scanned[iArg].list, &scanned[iArg].n_items,
315 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS | SCANITEMLIST_IGNORE_VALUELESS,
316 "independent", SDDS_STRING, &independent, 1, INDEPENDENT_GIVEN,
317 NULL) ||
318 !(scanFlags & INDEPENDENT_GIVEN))
319 SDDS_Bomb("invalid -slope syntax");
320 requests = addStatRequests(&request, requests, scanned[iArg].list + 1, scanned[iArg].n_items - 1, code, scanFlags);
321 request[requests - 1].independentColumn = independent;
322 request[requests - 1].topLimit = request[requests - 1].bottomLimit = 0;
323 break;
324 case SET_PIPE:
325 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
326 SDDS_Bomb("invalid -pipe syntax");
327 break;
328 case SET_WINDOW:
329 windowWidth = -1;
330 windowColumn = NULL;
331 scanned[iArg].n_items -= 1;
332 if (!scanItemList(&scanFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
333 "column", SDDS_STRING, &windowColumn, 1, 0,
334 "width", SDDS_DOUBLE, &windowWidth, 1, 0, NULL) ||
335 !windowColumn ||
336 !strlen(windowColumn) ||
337 windowWidth <= 0)
338 SDDS_Bomb("invalid -window syntax/values");
339 break;
340 case SET_PARTIALOK:
341 partialOk = 1;
342 break;
343 default:
344 fprintf(stderr, "error: unknown option '%s' given\n", scanned[iArg].list[0]);
345 exit(EXIT_FAILURE);
346 break;
347 }
348 } else {
349 /* argument is filename */
350 if (!input)
351 input = scanned[iArg].list[0];
352 else if (!output)
353 output = scanned[iArg].list[0];
354 else
355 SDDS_Bomb("too many filenames seen");
356 }
357 }
358
359 if (pointsToStat < 0 && !windowColumn) {
360 pointsToStat = 10;
361 }
362 processFilenames("sddsrunstats", &input, &output, pipeFlags, 0, NULL);
363
364 if (!requests)
365 SDDS_Bomb("no statistics requested");
366
367 if (!SDDS_InitializeInput(&inData, input))
368 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
369
370 if (!(stat = compileStatDefinitions(&inData, request, requests)))
371 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
372 stats = requests;
373#ifdef DEBUG
374 fprintf(stderr, "%ld stats\n", stats);
375 for (iStat = 0; iStat < stats; iStat++) {
376 for (iColumn = 0; iColumn < stat[iStat].sourceColumns; iColumn++) {
377 fprintf(stderr, "iStat=%ld iColumn=%ld source=%s result=%s\n", iStat, iColumn, stat[iStat].sourceColumn[iColumn], stat[iStat].resultColumn[iColumn]);
378 if (stat[iStat].flags & BOTTOMLIMIT_GIVEN)
379 fprintf(stderr, " bottom = %e\n", stat[iStat].bottomLimit);
380 if (stat[iStat].flags & TOPLIMIT_GIVEN)
381 fprintf(stderr, " top = %e\n", stat[iStat].topLimit);
382 }
383 }
384#endif
385
386 if (!setupOutputFile(&outData, output, &inData, stat, stats, columnMajorOrder))
387 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
388
389 if (windowColumn) {
390 if ((windowIndex = SDDS_GetColumnIndex(&inData, windowColumn)) < 0)
391 SDDS_Bomb("Window column not present");
392 if (!SDDS_NUMERIC_TYPE(SDDS_GetColumnType(&inData, windowIndex)))
393 SDDS_Bomb("Window column is not numeric");
394 }
395
396 outputData = NULL;
397 outputRowsMax = 0;
398 pointsToStat0 = pointsToStat;
399 while ((code = SDDS_ReadPage(&inData)) > 0) {
400 rows = SDDS_CountRowsOfInterest(&inData);
401 pointsToStat = pointsToStat0;
402 if (pointsToStat == 0)
403 pointsToStat = rows;
404 if (windowColumn && !(windowData = SDDS_GetColumnInDoubles(&inData, windowColumn))) {
405 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
406 }
407 if (!windowColumn) {
408 if (rows < pointsToStat) {
409 if (partialOk)
410 pointsToStat = rows;
411 else
412 continue;
413 }
414 if (overlap) {
415 outputRows = rows - pointsToStat + 1;
416 } else
417 outputRows = rows / pointsToStat;
418 } else
419 outputRows = rows;
420
421 if (!SDDS_StartPage(&outData, outputRows) ||
422 !SDDS_CopyParameters(&outData, &inData) ||
423 !SDDS_CopyArrays(&outData, &inData))
424 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
425 if (outputRows > outputRowsMax &&
426 !(outputData = SDDS_Realloc(outputData, sizeof(*outputData) * (outputRowsMax = outputRows))))
427 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
428 for (iStat = 0; iStat < stats; iStat++) {
429 for (iColumn = 0; iColumn < stat[iStat].sourceColumns; iColumn++) {
430 double *indepData;
431 lastRegion = 0;
432 windowRef = 0;
433 indepData = NULL;
434 if (!(inputData = SDDS_GetColumnInDoubles(&inData, stat[iStat].sourceColumn[iColumn])))
435 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
436 if (stat[iStat].independentColumn &&
437 !(indepData = SDDS_GetColumnInDoubles(&inData, stat[iStat].independentColumn)))
438 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
439 rowsToSet = outputRows;
440 if (!windowColumn) {
441#pragma omp parallel for private(startRow, inputDataOffset) if (threads > 1 && outputRows > 1) num_threads(threads)
442 for (outputRow = 0; outputRow < outputRows; outputRow++) {
443 startRow = overlap ? outputRow : outputRow * pointsToStat;
444 inputDataOffset = inputData + startRow;
445 outputData[outputRow] = computeRunningStatistic(&stat[iStat], inputDataOffset,
446 indepData ? indepData + startRow : NULL,
447 pointsToStat);
448 }
449 } else {
450 for (outputRow = startRow = 0; outputRow < outputRows; outputRow++, startRow += (overlap ? 1 : pointsToStat)) {
451 short windowFound = 0;
452 if (overlap) {
453 windowRef += 1;
454 lastRegion = 0;
455 }
456 for (pointsToStat = 1; pointsToStat < outputRows - startRow; pointsToStat++) {
457 region = (windowData[startRow + pointsToStat] - windowData[windowRef]) / windowWidth;
458 if (region != lastRegion) {
459 lastRegion = region;
460 windowFound = 1;
461 break;
462 }
463 }
464 if (!windowFound && pointsToStat < 2)
465 break;
466 if (startRow + pointsToStat > rows) {
467 pointsToStat = rows - startRow - 1;
468 if (pointsToStat <= 0)
469 break;
470 }
471#ifdef DEBUG
472 fprintf(stderr, "row=%" PRId64 " pointsToStat=%" PRId64 " delta=%.9lf (%.9lf -> %.9lf)\n", startRow, pointsToStat, windowData[startRow + pointsToStat - 1] - windowData[startRow], windowData[startRow], windowData[startRow + pointsToStat - 1]);
473#endif
474 inputDataOffset = inputData + startRow;
475 outputData[outputRow] = computeRunningStatistic(&stat[iStat], inputDataOffset,
476 indepData ? indepData + startRow : NULL,
477 pointsToStat);
478 }
479 rowsToSet = outputRow;
480 }
481 if (!SDDS_SetColumnFromDoubles(&outData, SDDS_SET_BY_INDEX, outputData, rowsToSet, stat[iStat].resultIndex[iColumn]))
482 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
483 free(inputData);
484 free(indepData);
485 }
486 }
487 if (windowColumn)
488 free(windowData);
489 if (!SDDS_WritePage(&outData))
490 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
491 }
492 if (SDDS_Terminate(&inData) != 1) {
493 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
494 return EXIT_FAILURE;
495 }
496 if (SDDS_Terminate(&outData) != 1) {
497 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
498 return EXIT_FAILURE;
499 }
500 if (outputData)
501 free(outputData);
502 return EXIT_SUCCESS;
503}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_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_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:50
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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:474
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:357
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:391
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.

◆ setupOutputFile()

long setupOutputFile ( SDDS_DATASET * outTable,
char * output,
SDDS_DATASET * inTable,
STAT_DEFINITION * stat,
long stats,
short columnMajorOrder )

Definition at line 690 of file sddsrunstats.c.

690 {
691 long column, iStat;
692 char s[SDDS_MAXLINE];
693
694 if (!SDDS_InitializeOutput(outData, SDDS_BINARY, 1, NULL, NULL, output))
695 return 0;
696 if (columnMajorOrder != -1)
697 outData->layout.data_mode.column_major = columnMajorOrder;
698 else
699 outData->layout.data_mode.column_major = inData->layout.data_mode.column_major;
700 for (iStat = 0; iStat < stats; iStat++) {
701 for (column = 0; column < stat[iStat].sourceColumns; column++) {
702 if (!SDDS_TransferColumnDefinition(outData, inData, stat[iStat].sourceColumn[column], stat[iStat].resultColumn[column])) {
703 sprintf(s, "Problem transferring definition of column %s to %s\n", stat[iStat].sourceColumn[column], stat[iStat].resultColumn[column]);
704 SDDS_SetError(s);
705 return 0;
706 }
707 if ((stat[iStat].resultIndex[column] = SDDS_GetColumnIndex(outData, stat[iStat].resultColumn[column])) < 0) {
708 sprintf(s, "Problem creating column %s", stat[iStat].resultColumn[column]);
709 SDDS_SetError(s);
710 return 0;
711 }
712 if (!SDDS_ChangeColumnInformation(outData, "description", NULL, SDDS_SET_BY_NAME, stat[iStat].resultColumn[column]) ||
713 !SDDS_ChangeColumnInformation(outData, "symbol", NULL, SDDS_SET_BY_NAME, stat[iStat].resultColumn[column]) ||
714 !SDDS_ChangeColumnInformation(outData, "type", "double", SDDS_SET_BY_NAME | SDDS_PASS_BY_STRING, stat[iStat].resultColumn[column])) {
715 sprintf(s, "Problem changing attributes of new column %s", stat[iStat].resultColumn[column]);
716 SDDS_SetError(s);
717 return 0;
718 }
719 }
720 }
721 if (!SDDS_TransferAllParameterDefinitions(outData, inData, SDDS_TRANSFER_KEEPOLD) ||
722 !SDDS_TransferAllArrayDefinitions(outData, inData, 0) ||
723 !SDDS_WriteLayout(outData))
724 return 0;
725 return 1;
726}
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_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_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_TransferAllArrayDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all array definitions from a source dataset to a target dataset.
int32_t SDDS_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions from a source dataset to a target dataset.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421