SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
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]
<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.

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)
 
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 604 of file sddsrunstats.c.

604 {
605 long i;
606 if (!(*statRequest = SDDS_Realloc(*statRequest, sizeof(**statRequest) * (requests + 1))) ||
607 !((*statRequest)[requests].sourceColumn = (char **)malloc(sizeof(*(*statRequest)[requests].sourceColumn) * items)))
608 SDDS_Bomb("memory allocation failure");
609 for (i = 0; i < items; i++) {
610 (*statRequest)[requests].sourceColumn[i] = item[i];
611 }
612 (*statRequest)[requests].sourceColumns = items;
613 (*statRequest)[requests].optionCode = code;
614 (*statRequest)[requests].sumPower = 1;
615 (*statRequest)[requests].flags = flags;
616 (*statRequest)[requests].independentColumn = NULL;
617 return requests + 1;
618}
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677

◆ compileStatDefinitions()

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

Definition at line 620 of file sddsrunstats.c.

620 {
621 STAT_DEFINITION *stat;
622 long iReq, iName;
623 char s[SDDS_MAXLINE];
624
625 if (!(stat = (STAT_DEFINITION *)malloc(sizeof(*stat) * requests)))
626 SDDS_Bomb("memory allocation failure");
627 for (iReq = 0; iReq < requests; iReq++) {
628 if ((stat[iReq].sourceColumns = expandColumnPairNames(inData, &request[iReq].sourceColumn, NULL, request[iReq].sourceColumns, NULL, 0, FIND_NUMERIC_TYPE, 0)) <= 0) {
629 fprintf(stderr, "Error: no match for column names (sddsrunstats):\n");
630 for (iName = 0; iName < request[iReq].sourceColumns; iName++)
631 fprintf(stderr, "%s, ", request[iReq].sourceColumn[iReq]);
632 fputc('\n', stderr);
633 exit(EXIT_FAILURE);
634 }
635 stat[iReq].sourceColumn = request[iReq].sourceColumn;
636 if (!(stat[iReq].resultColumn = malloc(sizeof(*stat[iReq].resultColumn) * stat[iReq].sourceColumns)) ||
637 !(stat[iReq].resultIndex = malloc(sizeof(*stat[iReq].resultIndex) * stat[iReq].sourceColumns))) {
638 SDDS_Bomb("memory allocation failure");
639 }
640 for (iName = 0; iName < stat[iReq].sourceColumns; iName++) {
641 sprintf(s, "%s%s", stat[iReq].sourceColumn[iName], statSuffix[request[iReq].optionCode]);
642 SDDS_CopyString(stat[iReq].resultColumn + iName, s);
643 }
644 stat[iReq].optionCode = request[iReq].optionCode;
645 stat[iReq].sumPower = request[iReq].sumPower;
646 stat[iReq].flags = request[iReq].flags;
647 stat[iReq].topLimit = request[iReq].topLimit;
648 stat[iReq].bottomLimit = request[iReq].bottomLimit;
649 stat[iReq].independentColumn = request[iReq].independentColumn;
650 }
651
652 return stat;
653}
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

◆ main()

int main ( int argc,
char ** argv )

Definition at line 190 of file sddsrunstats.c.

190 {
191 STAT_DEFINITION *stat;
192 long stats;
193 STAT_REQUEST *request;
194 long requests;
195 int64_t count;
196 SCANNED_ARG *scanned;
197 SDDS_DATASET inData, outData;
198 char *independent;
199 int32_t power;
200 int64_t pointsToStat;
201 long pointsToStat0, overlap;
202 int64_t rows, outputRowsMax, outputRows, outputRow;
203 long iArg, code, iStat, iColumn;
204 int64_t startRow, rowOffset;
205 char *input, *output, *windowColumn;
206 double *inputData, *outputData, topLimit, bottomLimit, *inputDataOffset, result, sum1, sum2, *newData;
207 double windowWidth, *windowData, slope, intercept, variance;
208 long windowIndex;
209 unsigned long pipeFlags, scanFlags, majorOrderFlag;
210 char s[100];
211 long lastRegion, region, windowRef, partialOk;
212 short columnMajorOrder = -1;
213
215 argc = scanargs(&scanned, argc, argv);
216 if (argc < 2) {
217 bomb("too few arguments", USAGE);
218 }
219 newData = NULL;
220 result = 0;
221 input = output = NULL;
222 stat = NULL;
223 request = NULL;
224 stats = requests = pipeFlags = 0;
225 pointsToStat = -1;
226 partialOk = 0;
227 overlap = 1;
228 windowColumn = NULL;
229 windowData = NULL;
230
231 for (iArg = 1; iArg < argc; iArg++) {
232 scanFlags = 0;
233 if (scanned[iArg].arg_type == OPTION) {
234 /* process options here */
235 switch (code = match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
236 case SET_MAJOR_ORDER:
237 majorOrderFlag = 0;
238 scanned[iArg].n_items--;
239 if (scanned[iArg].n_items > 0 &&
240 (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
241 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
242 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
243 SDDS_Bomb("invalid -majorOrder syntax/values");
244 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
245 columnMajorOrder = 1;
246 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
247 columnMajorOrder = 0;
248 break;
249 case SET_POINTS:
250 if (scanned[iArg].n_items != 2 || sscanf(scanned[iArg].list[1], "%" SCNd64, &pointsToStat) != 1 ||
251 (pointsToStat <= 2 && pointsToStat != 0))
252 SDDS_Bomb("invalid -points syntax");
253 break;
254 case SET_NOOVERLAP:
255 overlap = 0;
256 break;
257 case SET_MAXIMUM:
258 case SET_MINIMUM:
259 case SET_MEAN:
260 case SET_STANDARDDEVIATION:
261 case SET_RMS:
262 case SET_SIGMA:
263 case SET_SAMPLE:
264 case SET_MEDIAN:
265 if (scanned[iArg].n_items < 2) {
266 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
267 exit(EXIT_FAILURE);
268 }
269 if (!scanItemList(&scanFlags, scanned[iArg].list, &scanned[iArg].n_items,
270 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS | SCANITEMLIST_IGNORE_VALUELESS,
271 "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
272 "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN, NULL)) {
273 sprintf(s, "invalid -%s syntax", scanned[iArg].list[0]);
274 SDDS_Bomb(s);
275 }
276 requests = addStatRequests(&request, requests, scanned[iArg].list + 1, scanned[iArg].n_items - 1, code, scanFlags);
277 request[requests - 1].topLimit = topLimit;
278 request[requests - 1].bottomLimit = bottomLimit;
279 break;
280 case SET_SUM:
281 if (scanned[iArg].n_items < 2) {
282 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
283 exit(EXIT_FAILURE);
284 }
285 power = 1;
286 if (!scanItemList(&scanFlags, scanned[iArg].list, &scanned[iArg].n_items,
287 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS | SCANITEMLIST_IGNORE_VALUELESS,
288 "power", SDDS_LONG, &power, 1, 0,
289 "toplimit", SDDS_DOUBLE, &topLimit, 1, TOPLIMIT_GIVEN,
290 "bottomlimit", SDDS_DOUBLE, &bottomLimit, 1, BOTTOMLIMIT_GIVEN, NULL))
291 SDDS_Bomb("invalid -sum syntax");
292 requests = addStatRequests(&request, requests, scanned[iArg].list + 1, scanned[iArg].n_items - 1, code, scanFlags);
293 request[requests - 1].sumPower = power;
294 request[requests - 1].topLimit = topLimit;
295 request[requests - 1].bottomLimit = bottomLimit;
296 break;
297 case SET_SLOPE:
298 if (scanned[iArg].n_items < 2) {
299 fprintf(stderr, "error: invalid -%s syntax\n", option[code]);
300 exit(EXIT_FAILURE);
301 }
302 if (!scanItemList(&scanFlags, scanned[iArg].list, &scanned[iArg].n_items,
303 SCANITEMLIST_UNKNOWN_VALUE_OK | SCANITEMLIST_REMOVE_USED_ITEMS | SCANITEMLIST_IGNORE_VALUELESS,
304 "independent", SDDS_STRING, &independent, 1, INDEPENDENT_GIVEN,
305 NULL) ||
306 !(scanFlags & INDEPENDENT_GIVEN))
307 SDDS_Bomb("invalid -slope syntax");
308 requests = addStatRequests(&request, requests, scanned[iArg].list + 1, scanned[iArg].n_items - 1, code, scanFlags);
309 request[requests - 1].independentColumn = independent;
310 request[requests - 1].topLimit = request[requests - 1].bottomLimit = 0;
311 break;
312 case SET_PIPE:
313 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
314 SDDS_Bomb("invalid -pipe syntax");
315 break;
316 case SET_WINDOW:
317 windowWidth = -1;
318 windowColumn = NULL;
319 scanned[iArg].n_items -= 1;
320 if (!scanItemList(&scanFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
321 "column", SDDS_STRING, &windowColumn, 1, 0,
322 "width", SDDS_DOUBLE, &windowWidth, 1, 0, NULL) ||
323 !windowColumn ||
324 !strlen(windowColumn) ||
325 windowWidth <= 0)
326 SDDS_Bomb("invalid -window syntax/values");
327 break;
328 case SET_PARTIALOK:
329 partialOk = 1;
330 break;
331 default:
332 fprintf(stderr, "error: unknown option '%s' given\n", scanned[iArg].list[0]);
333 exit(EXIT_FAILURE);
334 break;
335 }
336 } else {
337 /* argument is filename */
338 if (!input)
339 input = scanned[iArg].list[0];
340 else if (!output)
341 output = scanned[iArg].list[0];
342 else
343 SDDS_Bomb("too many filenames seen");
344 }
345 }
346
347 if (pointsToStat < 0 && !windowColumn) {
348 pointsToStat = 10;
349 }
350 processFilenames("sddsrunstats", &input, &output, pipeFlags, 0, NULL);
351
352 if (!requests)
353 SDDS_Bomb("no statistics requested");
354
355 if (!SDDS_InitializeInput(&inData, input))
356 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
357
358 if (!(stat = compileStatDefinitions(&inData, request, requests)))
359 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
360 stats = requests;
361#ifdef DEBUG
362 fprintf(stderr, "%ld stats\n", stats);
363 for (iStat = 0; iStat < stats; iStat++) {
364 for (iColumn = 0; iColumn < stat[iStat].sourceColumns; iColumn++) {
365 fprintf(stderr, "iStat=%ld iColumn=%ld source=%s result=%s\n", iStat, iColumn, stat[iStat].sourceColumn[iColumn], stat[iStat].resultColumn[iColumn]);
366 if (stat[iStat].flags & BOTTOMLIMIT_GIVEN)
367 fprintf(stderr, " bottom = %e\n", stat[iStat].bottomLimit);
368 if (stat[iStat].flags & TOPLIMIT_GIVEN)
369 fprintf(stderr, " top = %e\n", stat[iStat].topLimit);
370 }
371 }
372#endif
373
374 if (!setupOutputFile(&outData, output, &inData, stat, stats, columnMajorOrder))
375 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
376
377 if (windowColumn) {
378 if ((windowIndex = SDDS_GetColumnIndex(&inData, windowColumn)) < 0)
379 SDDS_Bomb("Window column not present");
380 if (!SDDS_NUMERIC_TYPE(SDDS_GetColumnType(&inData, windowIndex)))
381 SDDS_Bomb("Window column is not numeric");
382 }
383
384 outputData = NULL;
385 outputRowsMax = 0;
386 pointsToStat0 = pointsToStat;
387 while ((code = SDDS_ReadPage(&inData)) > 0) {
388 rows = SDDS_CountRowsOfInterest(&inData);
389 pointsToStat = pointsToStat0;
390 if (pointsToStat == 0)
391 pointsToStat = rows;
392 if (windowColumn && !(windowData = SDDS_GetColumnInDoubles(&inData, windowColumn))) {
393 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
394 }
395 if (!windowColumn) {
396 if (rows < pointsToStat) {
397 if (partialOk)
398 pointsToStat = rows;
399 else
400 continue;
401 }
402 if (overlap) {
403 outputRows = rows - pointsToStat + 1;
404 } else
405 outputRows = rows / pointsToStat;
406 } else
407 outputRows = rows;
408
409 if (!SDDS_StartPage(&outData, outputRows) ||
410 !SDDS_CopyParameters(&outData, &inData) ||
411 !SDDS_CopyArrays(&outData, &inData))
412 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
413 if (outputRows > outputRowsMax &&
414 !(outputData = SDDS_Realloc(outputData, sizeof(*outputData) * (outputRowsMax = outputRows))))
415 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
416 for (iStat = 0; iStat < stats; iStat++) {
417 for (iColumn = 0; iColumn < stat[iStat].sourceColumns; iColumn++) {
418 double *indepData;
419 lastRegion = 0;
420 windowRef = 0;
421 indepData = NULL;
422 if (!(inputData = SDDS_GetColumnInDoubles(&inData, stat[iStat].sourceColumn[iColumn])))
423 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
424 if (stat[iStat].independentColumn &&
425 !(indepData = SDDS_GetColumnInDoubles(&inData, stat[iStat].independentColumn)))
426 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
427 for (outputRow = startRow = 0; outputRow < outputRows; outputRow++, startRow += (overlap ? 1 : pointsToStat)) {
428 if (windowColumn) {
429 short windowFound = 0;
430 if (overlap) {
431 windowRef += 1;
432 lastRegion = 0;
433 }
434 for (pointsToStat = 1; pointsToStat < outputRows - startRow; pointsToStat++) {
435 region = (windowData[startRow + pointsToStat] - windowData[windowRef]) / windowWidth;
436 if (region != lastRegion) {
437 lastRegion = region;
438 windowFound = 1;
439 break;
440 }
441 }
442 if (!windowFound && pointsToStat < 2)
443 break;
444 if (startRow + pointsToStat > rows) {
445 pointsToStat = rows - startRow - 1;
446 if (pointsToStat <= 0)
447 break;
448 }
449#ifdef DEBUG
450 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]);
451#endif
452 }
453 inputDataOffset = inputData + startRow;
454 switch (stat[iStat].optionCode) {
455 case SET_MAXIMUM:
456 result = -DBL_MAX;
457 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
458 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
459 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
460 continue;
461 if (inputDataOffset[rowOffset] > result)
462 result = inputDataOffset[rowOffset];
463 }
464 break;
465 case SET_MINIMUM:
466 result = DBL_MAX;
467 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
468 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
469 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
470 continue;
471 if (inputDataOffset[rowOffset] < result)
472 result = inputDataOffset[rowOffset];
473 }
474 break;
475 case SET_MEAN:
476 result = 0;
477 count = 0;
478 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
479 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
480 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
481 continue;
482 result += inputDataOffset[rowOffset];
483 count++;
484 }
485 if (count)
486 result /= count;
487 else
488 result = DBL_MAX;
489 break;
490 case SET_MEDIAN:
491 result = 0;
492 count = 0;
493 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
494 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
495 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
496 continue;
497 newData = SDDS_Realloc(newData, sizeof(*newData) * (count + 1));
498 newData[count] = inputDataOffset[rowOffset];
499 count++;
500 }
501 if (count) {
502 if (!compute_median(&result, newData, count))
503 result = DBL_MAX;
504 free(newData);
505 newData = NULL;
506 } else
507 result = DBL_MAX;
508 break;
509 case SET_STANDARDDEVIATION:
510 case SET_SIGMA:
511 sum1 = sum2 = count = 0;
512 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
513 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
514 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
515 continue;
516 sum1 += inputDataOffset[rowOffset];
517 sum2 += inputDataOffset[rowOffset] * inputDataOffset[rowOffset];
518 count++;
519 }
520 if (count > 1) {
521 if ((result = sum2 / count - sqr(sum1 / count)) <= 0)
522 result = 0;
523 else
524 result = sqrt(result * count / (count - 1.0));
525 if (stat[iStat].optionCode == SET_SIGMA)
526 result /= sqrt(count);
527 }
528 break;
529 case SET_RMS:
530 sum2 = count = 0;
531 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
532 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
533 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
534 continue;
535 sum2 += inputDataOffset[rowOffset] * inputDataOffset[rowOffset];
536 count++;
537 }
538 if (count > 0)
539 result = sqrt(sum2 / count);
540 else
541 result = DBL_MAX;
542 break;
543 case SET_SUM:
544 sum1 = count = 0;
545 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
546 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
547 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
548 continue;
549 sum1 += ipow(inputDataOffset[rowOffset], stat[iStat].sumPower);
550 count++;
551 }
552 if (count > 0)
553 result = sum1;
554 else
555 result = DBL_MAX;
556 break;
557 case SET_SLOPE:
558 if (!unweightedLinearFit(indepData + startRow, inputDataOffset, pointsToStat, &slope, &intercept,
559 &variance)) {
560 result = DBL_MAX;
561 } else
562 result = slope;
563 break;
564 case SET_SAMPLE:
565 result = DBL_MAX;
566 for (rowOffset = 0; rowOffset < pointsToStat; rowOffset++) {
567 if ((stat[iStat].flags & TOPLIMIT_GIVEN && inputDataOffset[rowOffset] > stat[iStat].topLimit) ||
568 (stat[iStat].flags & BOTTOMLIMIT_GIVEN && inputDataOffset[rowOffset] < stat[iStat].bottomLimit))
569 continue;
570 result = inputDataOffset[rowOffset];
571 break;
572 }
573 break;
574 default:
575 fprintf(stderr, "Unknown statistics code %ld in sddsrunave\n", stat[iStat].optionCode);
576 exit(EXIT_FAILURE);
577 break;
578 }
579 outputData[outputRow] = result;
580 }
581 if (!SDDS_SetColumnFromDoubles(&outData, SDDS_SET_BY_INDEX, outputData, outputRow, stat[iStat].resultIndex[iColumn]))
582 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
583 free(inputData);
584 }
585 }
586 if (windowColumn)
587 free(windowData);
588 if (!SDDS_WritePage(&outData))
589 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
590 }
591 if (SDDS_Terminate(&inData) != 1) {
592 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
593 return EXIT_FAILURE;
594 }
595 if (SDDS_Terminate(&outData) != 1) {
596 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
597 return EXIT_FAILURE;
598 }
599 if (outputData)
600 free(outputData);
601 return EXIT_SUCCESS;
602}
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:49
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: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_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
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 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_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.

◆ setupOutputFile()

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

Definition at line 655 of file sddsrunstats.c.

655 {
656 long column, iStat;
657 char s[SDDS_MAXLINE];
658
659 if (!SDDS_InitializeOutput(outData, SDDS_BINARY, 1, NULL, NULL, output))
660 return 0;
661 if (columnMajorOrder != -1)
662 outData->layout.data_mode.column_major = columnMajorOrder;
663 else
664 outData->layout.data_mode.column_major = inData->layout.data_mode.column_major;
665 for (iStat = 0; iStat < stats; iStat++) {
666 for (column = 0; column < stat[iStat].sourceColumns; column++) {
667 if (!SDDS_TransferColumnDefinition(outData, inData, stat[iStat].sourceColumn[column], stat[iStat].resultColumn[column])) {
668 sprintf(s, "Problem transferring definition of column %s to %s\n", stat[iStat].sourceColumn[column], stat[iStat].resultColumn[column]);
669 SDDS_SetError(s);
670 return 0;
671 }
672 if ((stat[iStat].resultIndex[column] = SDDS_GetColumnIndex(outData, stat[iStat].resultColumn[column])) < 0) {
673 sprintf(s, "Problem creating column %s", stat[iStat].resultColumn[column]);
674 SDDS_SetError(s);
675 return 0;
676 }
677 if (!SDDS_ChangeColumnInformation(outData, "description", NULL, SDDS_SET_BY_NAME, stat[iStat].resultColumn[column]) ||
678 !SDDS_ChangeColumnInformation(outData, "symbol", NULL, SDDS_SET_BY_NAME, stat[iStat].resultColumn[column]) ||
679 !SDDS_ChangeColumnInformation(outData, "type", "double", SDDS_SET_BY_NAME | SDDS_PASS_BY_STRING, stat[iStat].resultColumn[column])) {
680 sprintf(s, "Problem changing attributes of new column %s", stat[iStat].resultColumn[column]);
681 SDDS_SetError(s);
682 return 0;
683 }
684 }
685 }
686 if (!SDDS_TransferAllParameterDefinitions(outData, inData, SDDS_TRANSFER_KEEPOLD) ||
687 !SDDS_TransferAllArrayDefinitions(outData, inData, 0) ||
688 !SDDS_WriteLayout(outData))
689 return 0;
690 return 1;
691}
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:379