73char *option[N_OPTIONS] = {
94 "Usage: sddsmultihist [<inputfile>] [<outputfile>] [options]\n"
97 " -pipe=[input][,output] The standard SDDS Toolkit pipe option.\n"
98 " -columns=<name>[,...] Specifies the names of columns from the input to be histogrammed.\n"
99 " Names may contain wildcards.\n"
100 " -abscissa=<name>[,...] Specifies the names of the abscissas in the output file.\n"
101 " When using column names as abscissa names,\n"
102 " the -abscissa option is not required (use -separate).\n"
103 " At least one abscissa name must be supplied if -separate is not used.\n"
104 " -exclude=<name>[,...] (Optional) Specifies column names to exclude from histogramming.\n"
105 " -bins=<integer> Sets the number of bins for the histogram.\n"
106 " -sizeOfBins=<value> Sets the size of each bin for the histogram.\n"
107 " -autobins=target=<number>[,minimum=<integer>][,maximum=<integer>]\n"
108 " Automatically determines the number of bins based on the target number of samples per bin.\n"
109 " Optionally specify minimum and maximum number of bins.\n"
110 " -boundaryData=<filename>,<column> Specifies irregular bin boundaries from a file.\n"
111 " Incompatible with -separate and -abscissa.\n"
112 " -sides[=close|against] Adds zero-height bins at the ends of the histogram.\n"
113 " 'close' centers the first and last bins.\n"
114 " 'against' aligns the first and last bins with the data range.\n"
115 " -expand=<fraction> Expands the range of the histogram by the given fraction.\n"
116 " -lowerLimit=<value>[,...] Sets lower limits for the histograms.\n"
117 " -upperLimit=<value>[,...] Sets upper limits for the histograms.\n"
118 " -separate Creates separate abscissas for each histogram in the output file.\n"
119 " -cdf=[only] Includes the Cumulative Distribution Function (CDF) in the output.\n"
120 " 'only' includes only the CDF, excluding the histogram.\n"
121 " -weightColumn=<name> Specifies a column to weight the histogram.\n"
122 " -majorOrder=row|column Sets the output file's data order to row-major or column-major.\n"
123 " -normalize={sum|peak|no} Normalizes the histogram.\n"
124 " 'sum' normalizes so that the sum of all bins equals 1.\n"
125 " 'peak' normalizes so that the peak bin equals 1.\n"
126 " 'no' applies no normalization.\n"
128 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
131#define DO_CLOSE_SIDES 2
132#define DO_AGAINST_SIDES 3
134#define NORMALIZE_PEAK 0
135#define NORMALIZE_SUM 1
136#define NORMALIZE_NO 2
137#define N_NORMALIZE_OPTIONS 3
138char *normalize_option[N_NORMALIZE_OPTIONS] = {
139 "peak",
"sum",
"no"};
142 long **histogramIndex,
char *output,
char **columnName,
long columnNames,
143 char **abscissaName,
long abscissaNames,
char *boundaryColumn,
char *boundaryColumnUnits,
144 short columnMajorOrder,
short normMode);
145double *ReadBoundaryData(
char *file,
char *column, int64_t *n,
char **units);
146void MakeBoundaryHistogram(
double *histogram,
double *cdf,
double *boundaryValue, int64_t nBoundaryValues,
147 double *data,
double *weight, int64_t nData);
148void NormalizeHistogram(
double *hist, int64_t bins,
short mode);
150static short cdfOnly, freOnly;
152int main(
int argc,
char **argv) {
154 char *boundaryFile, *boundaryColumn, *boundaryColumnUnits;
155 double *boundaryValue;
156 int64_t nBoundaryValues;
157 char **abscissaName, **columnName, **excludeName;
158 long columnNames, excludeNames, abscissaNames, column, offset;
159 long givenLowerLimits, givenUpperLimits;
160 char *input, *output;
161 long readCode, binsGiven;
162 int64_t i, rows, bins, writeBins;
163 long lowerLimitGiven, upperLimitGiven, doSides, doSeparate;
164 double autoBinsTarget;
165 long autoBinsMinimum, autoBinsMaximum;
168 short normMode = NORMALIZE_NO;
169 unsigned long pipeFlags;
170 SCANNED_ARG *scanned;
172 double binSize, *lowerLimit = NULL, *upperLimit = NULL, *givenLowerLimit, *givenUpperLimit, *dx = NULL, range, middle;
173 double **inputData, *abscissa, *histogram, *minValue, *maxValue, transferLimit, *cdf, sum;
174 long *abscissaIndex, *histogramIndex, *cdfIndex;
175 double expandRange, maxRange;
177 unsigned long dummyFlags, majorOrderFlag;
178 short columnMajorOrder = -1;
181 argc =
scanargs(&scanned, argc, argv);
182 if (argc < 3 || argc > (3 + N_OPTIONS)) {
183 fprintf(stderr,
"%s", USAGE);
187 minValue = maxValue = NULL;
188 output = input = NULL;
191 boundaryFile = boundaryColumn = boundaryColumnUnits = NULL;
192 boundaryValue = NULL;
194 columnName = excludeName = NULL;
195 columnNames = excludeNames = abscissaNames = 0;
196 givenLowerLimits = givenUpperLimits = 0;
197 givenLowerLimit = givenUpperLimit = NULL;
198 bins = binsGiven = binSize = doSides = doSeparate = 0;
199 lowerLimitGiven = upperLimitGiven = 0;
204 autoBinsMinimum = autoBinsMaximum = 0;
208 for (iArg = 1; iArg < argc; iArg++) {
209 if (scanned[iArg].arg_type == OPTION) {
211 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
212 case SET_MAJOR_ORDER:
214 scanned[iArg].n_items--;
215 if (scanned[iArg].n_items > 0 && (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
"row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
"column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
216 SDDS_Bomb(
"invalid -majorOrder syntax/values");
217 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
218 columnMajorOrder = 1;
219 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
220 columnMajorOrder = 0;
223 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
228 SDDS_Bomb(
"only one -columns option may be given");
229 if (scanned[iArg].n_items < 2)
231 if (!(columnName =
SDDS_Realloc(columnName,
sizeof(*columnName) * (columnNames + scanned[iArg].n_items - 1))))
233 for (i = 1; i < scanned[iArg].n_items; i++)
234 columnName[columnNames + i - 1] = scanned[iArg].list[i];
235 columnNames += scanned[iArg].n_items - 1;
239 SDDS_Bomb(
"only one -abscissa option may be given");
240 if (scanned[iArg].n_items >= 2) {
241 if (!(abscissaName =
SDDS_Realloc(abscissaName,
sizeof(*abscissaName) * (abscissaNames + scanned[iArg].n_items - 1))))
243 for (i = 1; i < scanned[iArg].n_items; i++)
244 abscissaName[abscissaNames + i - 1] = scanned[iArg].list[i];
245 abscissaNames += scanned[iArg].n_items - 1;
250 SDDS_Bomb(
"-bins specified more than once");
252 if (sscanf(scanned[iArg].list[1],
"%" SCNd64, &bins) != 1 || bins <= 0)
253 SDDS_Bomb(
"invalid value for bins---give a positive value");
256 if (sscanf(scanned[iArg].list[1],
"%le", &binSize) != 1 || binSize <= 0)
257 SDDS_Bomb(
"invalid value for bin size---give a positive value");
260 if (scanned[iArg].n_items < 2)
262 scanned[iArg].n_items -= 1;
263 autoBinsTarget = autoBinsMinimum = autoBinsMaximum = 0;
264 if (!
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
266 "minimum",
SDDS_LONG, &autoBinsMinimum, 1, 0,
267 "maximum",
SDDS_LONG, &autoBinsMaximum, 1, 0, NULL) ||
268 autoBinsTarget <= 0 || autoBinsMinimum < 0 || autoBinsMaximum < 0)
269 SDDS_Bomb(
"incorrect -autoBins syntax or values");
273 SDDS_Bomb(
"only one -exclude option may be given");
274 if (scanned[iArg].n_items < 2)
276 if (!(excludeName =
SDDS_Realloc(excludeName,
sizeof(*excludeName) * (excludeNames + scanned[iArg].n_items - 1))))
278 for (i = 1; i < scanned[iArg].n_items; i++)
279 excludeName[excludeNames + i - 1] = scanned[iArg].list[i];
280 excludeNames += scanned[iArg].n_items - 1;
284 SDDS_Bomb(
"-lowerLimit specified more than once");
286 if (!(givenLowerLimit =
SDDS_Realloc(givenLowerLimit,
sizeof(*givenLowerLimit) * (givenLowerLimits + scanned[iArg].n_items - 1))))
287 SDDS_Bomb(
"SET_LOWERLIMIT: memory allocation failure");
288 for (i = 1; i < scanned[iArg].n_items; i++) {
289 if (sscanf(scanned[iArg].list[i],
"%lf", &transferLimit) != 1)
290 SDDS_Bomb(
"invalid value for -lowerLimit");
291 givenLowerLimit[givenLowerLimits + i - 1] = transferLimit;
293 givenLowerLimits += scanned[iArg].n_items - 1;
297 SDDS_Bomb(
"-upperLimit specified more than once");
299 if (!(givenUpperLimit =
SDDS_Realloc(givenUpperLimit,
sizeof(*givenUpperLimit) * (givenUpperLimits + scanned[iArg].n_items - 1))))
300 SDDS_Bomb(
"SET_UPPERLIMIT: memory allocation failure");
301 for (i = 1; i < scanned[iArg].n_items; i++) {
302 if (sscanf(scanned[iArg].list[i],
"%lf", &transferLimit) != 1)
303 SDDS_Bomb(
"invalid value for -upperLimit");
304 givenUpperLimit[givenUpperLimits + i - 1] = transferLimit;
306 givenUpperLimits += scanned[iArg].n_items - 1;
310 if (scanned[iArg].n_items == 2) {
311 static char *sideOpt[2] = {
"close",
"against"};
312 switch (
match_string(scanned[iArg].list[1], sideOpt, 2, 0)) {
314 doSides = DO_CLOSE_SIDES;
317 doSides = DO_AGAINST_SIDES;
329 if (scanned[iArg].n_items != 2 ||
330 sscanf(scanned[iArg].list[1],
"%lf", &expandRange) != 1 || expandRange <= 0)
334 if (scanned[iArg].n_items == 1)
337 if (scanned[iArg].n_items > 2)
339 CDFONLY = scanned[iArg].list[1];
340 if (strcmp(CDFONLY,
"only") != 0)
341 SDDS_Bomb(
"invalid -cdf value, it should be -cdf or -cdf=only");
346 case SET_BOUNDARYDATA:
347 if (scanned[iArg].n_items != 3 ||
348 !(boundaryFile = scanned[iArg].list[1]) ||
349 !strlen(boundaryFile) ||
350 !(boundaryColumn = scanned[iArg].list[2]) ||
351 !strlen(boundaryColumn))
352 SDDS_Bomb(
"invalid -boundaryData syntax or values");
355 if (scanned[iArg].n_items != 2 ||
356 !(weightColumn = scanned[iArg].list[1]) ||
357 !strlen(weightColumn))
358 SDDS_Bomb(
"invalid -weightColumn syntax or values");
361 if (scanned[iArg].n_items == 1)
362 normMode = NORMALIZE_SUM;
363 else if (scanned[iArg].n_items != 2 ||
364 (normMode =
match_string(scanned[iArg].list[1], normalize_option, N_NORMALIZE_OPTIONS, 0)) < 0)
368 fprintf(stderr,
"Error: unknown or ambiguous option: %s\n", scanned[iArg].list[0]);
369 fprintf(stderr,
"%s", USAGE);
375 input = scanned[iArg].list[0];
377 output = scanned[iArg].list[0];
383 if (boundaryColumn && (abscissaNames > 0 || doSeparate))
384 SDDS_Bomb(
"-boundaryData option is incompatible with -abscissa and -separate options");
386 if (columnNames <= 0)
387 SDDS_Bomb(
"Supply the names of columns to histogram with -columns");
396 if ((columnNames = expandColumnPairNames(&SDDSin, &columnName, NULL, columnNames, excludeName, excludeNames, FIND_NUMERIC_TYPE, 0)) <= 0) {
398 SDDS_Bomb(
"No quantities selected to histogram.");
402 if (abscissaNames <= 0) {
403 if (!(abscissaName =
SDDS_Realloc(abscissaName,
sizeof(*abscissaName) * (abscissaNames + columnNames))))
406 for (i = 0; i < columnNames; i++) {
407 abscissaName[abscissaNames + i] = columnName[i];
409 abscissaNames += columnNames;
411 if (columnNames > 1) {
412 if (abscissaNames > 0) {
413 if (columnNames != abscissaNames)
414 SDDS_Bomb(
"the number of abscissa names must match the number of columns");
416 if (givenLowerLimits)
417 if (columnNames != givenLowerLimits)
418 SDDS_Bomb(
"the number of lower limits must match the number of columns");
419 if (givenUpperLimits)
420 if (columnNames != givenUpperLimits)
421 SDDS_Bomb(
"the number of upper limits must match the number of columns");
424 if (abscissaNames > 0) {
425 if (columnNames != abscissaNames)
428 if (givenLowerLimits)
429 if (columnNames != givenLowerLimits)
430 givenLowerLimits = 1;
431 if (givenUpperLimits)
432 if (columnNames != givenUpperLimits)
433 givenUpperLimits = 1;
435 }
else if (boundaryFile) {
436 if (!(boundaryValue = ReadBoundaryData(boundaryFile, boundaryColumn, &nBoundaryValues, &boundaryColumnUnits))) {
437 SDDS_Bomb(
"Problem reading boundary data");
440 if (abscissaNames <= 0)
441 SDDS_Bomb(
"Supply the name of the abscissa with -abscissaName");
445 SetUpOutput(&SDDSout, &SDDSin, &abscissaIndex, &cdfIndex, &histogramIndex, output, columnName, columnNames, abscissaName, abscissaNames, boundaryColumn, boundaryColumnUnits, columnMajorOrder, normMode);
447 if (!(inputData = (
double **)malloc(columnNames *
sizeof(*inputData))) ||
448 !(minValue = (
double *)malloc(columnNames *
sizeof(*minValue))) ||
449 !(maxValue = (
double *)malloc(columnNames *
sizeof(*maxValue))))
452 if (((binSize ? 1 : 0) + (binsGiven ? 1 : 0) + (autoBinsTarget ? 1 : 0)) > 1)
453 SDDS_Bomb(
"Specify only one of -binSize, -bins, or -autoBins");
454 if (!binSize && !binsGiven && !autoBinsTarget) {
459 abscissa = histogram = cdf = NULL;
469 for (column = 0; column < columnNames; column++) {
474 if (!boundaryColumn) {
475 if (!(lowerLimit = (
double *)malloc(
sizeof(*lowerLimit) * columnNames)))
477 if (!(upperLimit = (
double *)malloc(
sizeof(*upperLimit) * columnNames)))
479 if (!(dx = (
double *)malloc(
sizeof(*dx) * columnNames)))
483 for (column = 0; column < columnNames; column++) {
484 find_min_max(&minValue[column], &maxValue[column], inputData[column], rows);
485 lowerLimit[column] = givenLowerLimits ? givenLowerLimit[column] : minValue[column];
486 upperLimit[column] = givenUpperLimits ? givenUpperLimit[column] : maxValue[column];
489 for (column = 0; column < columnNames; column++)
490 find_min_max(&minValue[column], &maxValue[column], inputData[column], rows);
491 lowerLimit[0] = givenLowerLimits ? givenLowerLimit[0] :
min_in_array(minValue, columnNames);
492 upperLimit[0] = givenUpperLimits ? givenUpperLimit[0] :
max_in_array(maxValue, columnNames);
493 for (column = 1; column < columnNames; column++) {
494 lowerLimit[column] = lowerLimit[0];
495 upperLimit[column] = upperLimit[0];
499 range = (1 + expandRange) * (upperLimit[0] - lowerLimit[0]);
500 if (autoBinsTarget) {
501 bins = (int64_t)(rows / autoBinsTarget);
502 if (autoBinsMinimum) {
503 if (bins < autoBinsMinimum)
504 bins = autoBinsMinimum;
505 }
else if (bins < 5) {
508 if (autoBinsMaximum) {
509 if (bins > autoBinsMaximum)
510 bins = autoBinsMaximum;
511 }
else if (bins > rows)
517 for (column = 0; column < columnNames; column++) {
518 range = (1 + expandRange) * (upperLimit[column] - lowerLimit[column]);
519 range = ((range / binSize) + 1) * binSize;
520 if (range > maxRange)
522 middle = (lowerLimit[column] + upperLimit[column]) / 2;
523 lowerLimit[column] = middle - range / 2;
524 upperLimit[column] = middle + range / 2;
532 bins = maxRange / binSize + 0.5;
533 if (bins < 1 && !doSides)
536 for (column = 0; column < columnNames; column++) {
537 range = upperLimit[column] - lowerLimit[column];
538 upperLimit[column] += (maxRange - range) / 2;
539 lowerLimit[column] -= (maxRange - range) / 2;
540 dx[column] = binSize;
544 for (column = 0; column < columnNames; column++) {
545 range = (1 + expandRange) * (upperLimit[column] - lowerLimit[column]);
546 middle = (upperLimit[column] + lowerLimit[column]) / 2;
547 upperLimit[column] = middle + range / 2;
548 lowerLimit[column] = middle - range / 2;
549 if (upperLimit[column] == lowerLimit[column]) {
550 if (fabs(upperLimit[column]) < sqrt(DBL_MIN)) {
551 upperLimit[column] = sqrt(DBL_MIN);
552 lowerLimit[column] = -sqrt(DBL_MIN);
554 lowerLimit[column] = upperLimit[column] * (1 - 10000 * DBL_EPSILON);
555 upperLimit[column] = upperLimit[column] * (1 + 10000 * DBL_EPSILON);
558 dx[column] = (upperLimit[column] - lowerLimit[column]) / bins;
561 range = (1 + expandRange) * (upperLimit[0] - lowerLimit[0]);
562 middle = (upperLimit[0] + lowerLimit[0]) / 2;
563 upperLimit[0] = middle + range / 2;
564 lowerLimit[0] = middle - range / 2;
565 if (upperLimit[0] == lowerLimit[0]) {
566 if (fabs(upperLimit[0]) < sqrt(DBL_MIN)) {
567 upperLimit[0] = sqrt(DBL_MIN);
568 lowerLimit[0] = -sqrt(DBL_MIN);
570 lowerLimit[0] = upperLimit[0] * (1 - 10000 * DBL_EPSILON);
571 upperLimit[0] = upperLimit[0] * (1 + 10000 * DBL_EPSILON);
574 dx[0] = (upperLimit[0] - lowerLimit[0]) / bins;
577 if (!binsGiven || !abscissa) {
578 if (!(abscissa =
SDDS_Realloc(abscissa,
sizeof(*abscissa) * (bins + 2))) ||
579 !(cdf =
SDDS_Realloc(cdf,
sizeof(*cdf) * (bins + 2))) ||
580 !(histogram =
SDDS_Realloc(histogram,
sizeof(*histogram) * (bins + 2))))
583 writeBins = bins + (doSides ? 2 : 0);
584 offset = doSides ? 0 : 1;
586 bins = writeBins = nBoundaryValues;
589 !(histogram =
SDDS_Realloc(histogram,
sizeof(*histogram) * bins)))
596 if (boundaryColumn) {
597 for (column = 0; column < columnNames; column++) {
598 MakeBoundaryHistogram(histogram, cdf, boundaryValue, nBoundaryValues, inputData[column], weightData, rows);
599 NormalizeHistogram(histogram, nBoundaryValues, normMode);
600 if (!cdfOnly && !
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, histogram, writeBins, histogramIndex[column]))
602 if (!freOnly && !
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, cdf, writeBins, cdfIndex[column]))
604 free(inputData[column]);
606 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, boundaryValue, writeBins, boundaryColumn))
608 }
else if (!doSeparate) {
609 for (i = -1; i < bins + 1; i++)
610 abscissa[i + 1] = (i + 0.5) * dx[0] + lowerLimit[0];
613 abscissa[0] = abscissa[1] - dx[0] / 2;
614 abscissa[bins + 1] = abscissa[bins] + dx[0] / 2;
616 case DO_AGAINST_SIDES:
617 abscissa[0] = abscissa[1];
618 abscissa[bins + 1] = abscissa[bins];
621 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, abscissa + offset, writeBins, abscissaIndex[0]))
623 for (column = 0; column < columnNames; column++) {
624 histogram[0] = histogram[bins + 1] = 0;
626 make_histogram(histogram + 1, bins, lowerLimit[0], upperLimit[0], inputData[column], rows, 1);
628 make_histogram_weighted(histogram + 1, bins, lowerLimit[0], upperLimit[0], inputData[column], rows, 1, weightData);
629 NormalizeHistogram(histogram, bins, normMode);
631 for (i = 0; i <= bins + 1; i++)
633 for (i = 0; i <= bins + 1; i++) {
635 cdf[i] = histogram[i] / sum;
637 cdf[i] = cdf[i - 1] + histogram[i] / sum;
640 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, histogram + offset, writeBins, histogramIndex[column]))
644 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, cdf + offset, writeBins, cdfIndex[column]))
647 free(inputData[column]);
650 for (column = 0; column < columnNames; column++) {
651 for (i = -1; i < bins + 1; i++)
652 abscissa[i + 1] = (i + 0.5) * dx[column] + lowerLimit[column];
655 abscissa[0] = abscissa[1] - dx[column] / 2;
656 abscissa[bins + 1] = abscissa[bins] + dx[column] / 2;
658 case DO_AGAINST_SIDES:
659 abscissa[0] = abscissa[1];
660 abscissa[bins + 1] = abscissa[bins];
663 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, abscissa + offset, writeBins, abscissaIndex[column]))
665 histogram[0] = histogram[bins + 1] = 0;
667 make_histogram(histogram + 1, bins, lowerLimit[column], upperLimit[column], inputData[column], rows, 1);
669 make_histogram_weighted(histogram + 1, bins, lowerLimit[column], upperLimit[column], inputData[column], rows, 1, weightData);
670 NormalizeHistogram(histogram, bins + 2, normMode);
672 for (i = 0; i <= bins + 1; i++)
674 for (i = 0; i <= bins + 1; i++) {
676 cdf[i] = histogram[i] / sum;
678 cdf[i] = cdf[i - 1] + histogram[i] / sum;
681 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, histogram + offset, writeBins, histogramIndex[column]))
685 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, cdf + offset, writeBins, cdfIndex[column]))
688 free(inputData[column]);
730 long **histogramIndex,
char *output,
char **columnName,
long columnNames,
731 char **abscissaName,
long abscissaNames,
char *boundaryColumn,
char *boundaryUnits,
732 short columnMajorOrder,
short normMode) {
734 char s[SDDS_MAXLINE];
736 char *blankString =
"";
741 if (columnMajorOrder != -1)
742 SDDSout->layout.data_mode.column_major = columnMajorOrder;
744 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
746 if (!(*cdfIndex = (
long *)malloc(
sizeof(**cdfIndex) * columnNames)))
749 if (!(*histogramIndex = (
long *)malloc(
sizeof(**histogramIndex) * columnNames)))
752 if (!boundaryColumn) {
753 if (!(*abscissaIndex = (
long *)malloc(
sizeof(**abscissaIndex) * columnNames)))
756 for (column = 0; column < abscissaNames; column++) {
761 if (strcmp(columnName[column], abscissaName[column]) != 0 &&
771 for (column = 0; column < columnNames; column++) {
773 sprintf(s,
"%sCdf", columnName[column]);
780 sprintf(s,
"%sRelativeFrequency", columnName[column]);
783 sprintf(s,
"%sFractionalFrequency", columnName[column]);
786 sprintf(s,
"%sFrequency", columnName[column]);
798double *ReadBoundaryData(
char *file,
char *column, int64_t *n,
char **units) {
815 *n = SDDS_RowCount(&SDDSin);
820 for (j = 1; j < (*n); j++) {
821 if (data[j] <= data[j - 1]) {
822 memmove(data + j, data + j + 1,
sizeof(*data) * ((*n) - 1 - j));
830void MakeBoundaryHistogram(
double *histogram,
double *cdf,
double *boundaryValue, int64_t nBoundaryValues,
831 double *data,
double *weight, int64_t nData) {
833 for (i = 0; i < nBoundaryValues; i++)
834 histogram[i] = cdf[i] = 0;
835 for (i = 0; i < nData; i++) {
837 if (j < nBoundaryValues && j >= 0)
838 histogram[j] += weight ? fabs(weight[i]) : 1;
840 cdf[0] = histogram[0];
841 for (j = 1; j < nBoundaryValues; j++) {
842 cdf[j] = cdf[j - 1] + histogram[j];
844 if (cdf[nBoundaryValues - 1] > 0)
845 for (j = 0; j < nBoundaryValues; j++)
846 cdf[j] /= cdf[nBoundaryValues - 1];
849void NormalizeHistogram(
double *hist, int64_t bins,
short mode) {
854 for (i = 0; i < bins; i++)
858 for (i = 0; i < bins; i++)
867 for (i = 0; i < bins; i++)
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
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_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_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS 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_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.
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.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
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.
#define SDDS_DOUBLE
Identifier for the double data type.
long binaryArraySearch(void *array, size_t elemSize, long members, void *key, int(*compare)(const void *c1, const void *c2), long bracket)
Searches for a key in a sorted array of data values using binary search.
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
double max_in_array(double *array, long n)
Finds the maximum value in an array of doubles.
double min_in_array(double *array, long n)
Finds the minimum value in an array of doubles.
long make_histogram_weighted(double *hist, long n_bins, double lo, double hi, double *data, long n_pts, long new_start, double *weight)
Compiles a weighted histogram from data points.
long make_histogram(double *hist, long n_bins, double lo, double hi, double *data, int64_t n_pts, long new_start)
Compiles a histogram from data points.
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 double_cmpasc(const void *a, const void *b)
Compare two doubles in ascending order.