106char *option[N_OPTIONS] = {
127 "Usage: sddsmultihist [<inputfile>] [<outputfile>]\n"
128 " [-pipe=[input][,output]]\n"
129 " -columns=<name>[,...]\n"
130 " -abscissa=<name>[,...]\n"
131 " [-exclude=<name>[,...]]\n"
132 " [-bins=<integer>]\n"
133 " [-sizeOfBins=<value>]\n"
134 " [-autobins=target=<number>[,minimum=<integer>][,maximum=<integer>]]\n"
135 " [-boundaryData=<filename>,<column>]\n"
136 " [-sides[=close|against]]\n"
137 " [-expand=<fraction>]\n"
138 " [-lowerLimit=<value>[,...]]\n"
139 " [-upperLimit=<value>[,...]]\n"
142 " [-weightColumn=<name>]\n"
143 " [-majorOrder=row|column]\n"
144 " [-normalize={sum|peak|no}]\n"
146 " -pipe=[input][,output] The standard SDDS Toolkit pipe option.\n"
147 " -columns=<name>[,...] Specifies the names of columns from the input to be histogrammed.\n"
148 " Names may contain wildcards.\n"
149 " -abscissa=<name>[,...] Specifies the names of the abscissas in the output file.\n"
150 " When using column names as abscissa names,\n"
151 " the -abscissa option is not required (use -separate).\n"
152 " At least one abscissa name must be supplied if -separate is not used.\n"
153 " -exclude=<name>[,...] (Optional) Specifies column names to exclude from histogramming.\n"
154 " -bins=<integer> Sets the number of bins for the histogram.\n"
155 " -sizeOfBins=<value> Sets the size of each bin for the histogram.\n"
156 " -autobins=target=<number>[,minimum=<integer>][,maximum=<integer>]\n"
157 " Automatically determines the number of bins based on the target number of samples per bin.\n"
158 " Optionally specify minimum and maximum number of bins.\n"
159 " -boundaryData=<filename>,<column> Specifies irregular bin boundaries from a file.\n"
160 " Incompatible with -separate and -abscissa.\n"
161 " -sides[=close|against] Adds zero-height bins at the ends of the histogram.\n"
162 " 'close' centers the first and last bins.\n"
163 " 'against' aligns the first and last bins with the data range.\n"
164 " -expand=<fraction> Expands the range of the histogram by the given fraction.\n"
165 " -lowerLimit=<value>[,...] Sets lower limits for the histograms.\n"
166 " -upperLimit=<value>[,...] Sets upper limits for the histograms.\n"
167 " -separate Creates separate abscissas for each histogram in the output file.\n"
168 " -cdf=[only] Includes the Cumulative Distribution Function (CDF) in the output.\n"
169 " 'only' includes only the CDF, excluding the histogram.\n"
170 " -weightColumn=<name> Specifies a column to weight the histogram.\n"
171 " -majorOrder=row|column Sets the output file's data order to row-major or column-major.\n"
172 " -normalize={sum|peak|no} Normalizes the histogram.\n"
173 " 'sum' normalizes so that the sum of all bins equals 1.\n"
174 " 'peak' normalizes so that the peak bin equals 1.\n"
175 " 'no' applies no normalization.\n"
177 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
180#define DO_CLOSE_SIDES 2
181#define DO_AGAINST_SIDES 3
183#define NORMALIZE_PEAK 0
184#define NORMALIZE_SUM 1
185#define NORMALIZE_NO 2
186#define N_NORMALIZE_OPTIONS 3
187char *normalize_option[N_NORMALIZE_OPTIONS] = {
188 "peak",
"sum",
"no"};
191 long **histogramIndex,
char *output,
char **columnName,
long columnNames,
192 char **abscissaName,
long abscissaNames,
char *boundaryColumn,
char *boundaryColumnUnits,
193 short columnMajorOrder,
short normMode);
194double *ReadBoundaryData(
char *file,
char *column, int64_t *n,
char **units);
195void MakeBoundaryHistogram(
double *histogram,
double *cdf,
double *boundaryValue, int64_t nBoundaryValues,
196 double *data,
double *weight, int64_t nData);
197void NormalizeHistogram(
double *hist, int64_t bins,
short mode);
199static short cdfOnly, freOnly;
201int main(
int argc,
char **argv) {
203 char *boundaryFile, *boundaryColumn, *boundaryColumnUnits;
204 double *boundaryValue;
205 int64_t nBoundaryValues;
206 char **abscissaName, **columnName, **excludeName;
207 long columnNames, excludeNames, abscissaNames, column, offset;
208 long givenLowerLimits, givenUpperLimits;
209 char *input, *output;
210 long readCode, binsGiven;
211 int64_t i, rows, bins, writeBins;
212 long lowerLimitGiven, upperLimitGiven, doSides, doSeparate;
213 double autoBinsTarget;
214 long autoBinsMinimum, autoBinsMaximum;
217 short normMode = NORMALIZE_NO;
218 unsigned long pipeFlags;
219 SCANNED_ARG *scanned;
221 double binSize, *lowerLimit = NULL, *upperLimit = NULL, *givenLowerLimit, *givenUpperLimit, *dx = NULL, range, middle;
222 double **inputData, *abscissa, *histogram, *minValue, *maxValue, transferLimit, *cdf, sum;
223 long *abscissaIndex, *histogramIndex, *cdfIndex;
224 double expandRange, maxRange;
226 unsigned long dummyFlags, majorOrderFlag;
227 short columnMajorOrder = -1;
230 argc =
scanargs(&scanned, argc, argv);
231 if (argc < 3 || argc > (3 + N_OPTIONS)) {
232 fprintf(stderr,
"%s", USAGE);
236 minValue = maxValue = NULL;
237 output = input = NULL;
240 boundaryFile = boundaryColumn = boundaryColumnUnits = NULL;
241 boundaryValue = NULL;
243 columnName = excludeName = NULL;
244 columnNames = excludeNames = abscissaNames = 0;
245 givenLowerLimits = givenUpperLimits = 0;
246 givenLowerLimit = givenUpperLimit = NULL;
247 bins = binsGiven = binSize = doSides = doSeparate = 0;
248 lowerLimitGiven = upperLimitGiven = 0;
253 autoBinsMinimum = autoBinsMaximum = 0;
257 for (iArg = 1; iArg < argc; iArg++) {
258 if (scanned[iArg].arg_type == OPTION) {
260 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
261 case SET_MAJOR_ORDER:
263 scanned[iArg].n_items--;
264 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)))
265 SDDS_Bomb(
"invalid -majorOrder syntax/values");
266 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
267 columnMajorOrder = 1;
268 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
269 columnMajorOrder = 0;
272 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
277 SDDS_Bomb(
"only one -columns option may be given");
278 if (scanned[iArg].n_items < 2)
280 if (!(columnName =
SDDS_Realloc(columnName,
sizeof(*columnName) * (columnNames + scanned[iArg].n_items - 1))))
282 for (i = 1; i < scanned[iArg].n_items; i++)
283 columnName[columnNames + i - 1] = scanned[iArg].list[i];
284 columnNames += scanned[iArg].n_items - 1;
288 SDDS_Bomb(
"only one -abscissa option may be given");
289 if (scanned[iArg].n_items >= 2) {
290 if (!(abscissaName =
SDDS_Realloc(abscissaName,
sizeof(*abscissaName) * (abscissaNames + scanned[iArg].n_items - 1))))
292 for (i = 1; i < scanned[iArg].n_items; i++)
293 abscissaName[abscissaNames + i - 1] = scanned[iArg].list[i];
294 abscissaNames += scanned[iArg].n_items - 1;
299 SDDS_Bomb(
"-bins specified more than once");
301 if (sscanf(scanned[iArg].list[1],
"%" SCNd64, &bins) != 1 || bins <= 0)
302 SDDS_Bomb(
"invalid value for bins---give a positive value");
305 if (sscanf(scanned[iArg].list[1],
"%le", &binSize) != 1 || binSize <= 0)
306 SDDS_Bomb(
"invalid value for bin size---give a positive value");
309 if (scanned[iArg].n_items < 2)
311 scanned[iArg].n_items -= 1;
312 autoBinsTarget = autoBinsMinimum = autoBinsMaximum = 0;
313 if (!
scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
315 "minimum",
SDDS_LONG, &autoBinsMinimum, 1, 0,
316 "maximum",
SDDS_LONG, &autoBinsMaximum, 1, 0, NULL) ||
317 autoBinsTarget <= 0 || autoBinsMinimum < 0 || autoBinsMaximum < 0)
318 SDDS_Bomb(
"incorrect -autoBins syntax or values");
322 SDDS_Bomb(
"only one -exclude option may be given");
323 if (scanned[iArg].n_items < 2)
325 if (!(excludeName =
SDDS_Realloc(excludeName,
sizeof(*excludeName) * (excludeNames + scanned[iArg].n_items - 1))))
327 for (i = 1; i < scanned[iArg].n_items; i++)
328 excludeName[excludeNames + i - 1] = scanned[iArg].list[i];
329 excludeNames += scanned[iArg].n_items - 1;
333 SDDS_Bomb(
"-lowerLimit specified more than once");
335 if (!(givenLowerLimit =
SDDS_Realloc(givenLowerLimit,
sizeof(*givenLowerLimit) * (givenLowerLimits + scanned[iArg].n_items - 1))))
336 SDDS_Bomb(
"SET_LOWERLIMIT: memory allocation failure");
337 for (i = 1; i < scanned[iArg].n_items; i++) {
338 if (sscanf(scanned[iArg].list[i],
"%lf", &transferLimit) != 1)
339 SDDS_Bomb(
"invalid value for -lowerLimit");
340 givenLowerLimit[givenLowerLimits + i - 1] = transferLimit;
342 givenLowerLimits += scanned[iArg].n_items - 1;
346 SDDS_Bomb(
"-upperLimit specified more than once");
348 if (!(givenUpperLimit =
SDDS_Realloc(givenUpperLimit,
sizeof(*givenUpperLimit) * (givenUpperLimits + scanned[iArg].n_items - 1))))
349 SDDS_Bomb(
"SET_UPPERLIMIT: memory allocation failure");
350 for (i = 1; i < scanned[iArg].n_items; i++) {
351 if (sscanf(scanned[iArg].list[i],
"%lf", &transferLimit) != 1)
352 SDDS_Bomb(
"invalid value for -upperLimit");
353 givenUpperLimit[givenUpperLimits + i - 1] = transferLimit;
355 givenUpperLimits += scanned[iArg].n_items - 1;
359 if (scanned[iArg].n_items == 2) {
360 static char *sideOpt[2] = {
"close",
"against"};
361 switch (
match_string(scanned[iArg].list[1], sideOpt, 2, 0)) {
363 doSides = DO_CLOSE_SIDES;
366 doSides = DO_AGAINST_SIDES;
378 if (scanned[iArg].n_items != 2 ||
379 sscanf(scanned[iArg].list[1],
"%lf", &expandRange) != 1 || expandRange <= 0)
383 if (scanned[iArg].n_items == 1)
386 if (scanned[iArg].n_items > 2)
388 CDFONLY = scanned[iArg].list[1];
389 if (strcmp(CDFONLY,
"only") != 0)
390 SDDS_Bomb(
"invalid -cdf value, it should be -cdf or -cdf=only");
395 case SET_BOUNDARYDATA:
396 if (scanned[iArg].n_items != 3 ||
397 !(boundaryFile = scanned[iArg].list[1]) ||
398 !strlen(boundaryFile) ||
399 !(boundaryColumn = scanned[iArg].list[2]) ||
400 !strlen(boundaryColumn))
401 SDDS_Bomb(
"invalid -boundaryData syntax or values");
404 if (scanned[iArg].n_items != 2 ||
405 !(weightColumn = scanned[iArg].list[1]) ||
406 !strlen(weightColumn))
407 SDDS_Bomb(
"invalid -weightColumn syntax or values");
410 if (scanned[iArg].n_items == 1)
411 normMode = NORMALIZE_SUM;
412 else if (scanned[iArg].n_items != 2 ||
413 (normMode =
match_string(scanned[iArg].list[1], normalize_option, N_NORMALIZE_OPTIONS, 0)) < 0)
417 fprintf(stderr,
"Error: unknown or ambiguous option: %s\n", scanned[iArg].list[0]);
418 fprintf(stderr,
"%s", USAGE);
424 input = scanned[iArg].list[0];
426 output = scanned[iArg].list[0];
432 if (boundaryColumn && (abscissaNames > 0 || doSeparate))
433 SDDS_Bomb(
"-boundaryData option is incompatible with -abscissa and -separate options");
435 if (columnNames <= 0)
436 SDDS_Bomb(
"Supply the names of columns to histogram with -columns");
445 if ((columnNames = expandColumnPairNames(&SDDSin, &columnName, NULL, columnNames, excludeName, excludeNames, FIND_NUMERIC_TYPE, 0)) <= 0) {
447 SDDS_Bomb(
"No quantities selected to histogram.");
451 if (abscissaNames <= 0) {
452 if (!(abscissaName =
SDDS_Realloc(abscissaName,
sizeof(*abscissaName) * (abscissaNames + columnNames))))
455 for (i = 0; i < columnNames; i++) {
456 abscissaName[abscissaNames + i] = columnName[i];
458 abscissaNames += columnNames;
460 if (columnNames > 1) {
461 if (abscissaNames > 0) {
462 if (columnNames != abscissaNames)
463 SDDS_Bomb(
"the number of abscissa names must match the number of columns");
465 if (givenLowerLimits)
466 if (columnNames != givenLowerLimits)
467 SDDS_Bomb(
"the number of lower limits must match the number of columns");
468 if (givenUpperLimits)
469 if (columnNames != givenUpperLimits)
470 SDDS_Bomb(
"the number of upper limits must match the number of columns");
473 if (abscissaNames > 0) {
474 if (columnNames != abscissaNames)
477 if (givenLowerLimits)
478 if (columnNames != givenLowerLimits)
479 givenLowerLimits = 1;
480 if (givenUpperLimits)
481 if (columnNames != givenUpperLimits)
482 givenUpperLimits = 1;
484 }
else if (boundaryFile) {
485 if (!(boundaryValue = ReadBoundaryData(boundaryFile, boundaryColumn, &nBoundaryValues, &boundaryColumnUnits))) {
486 SDDS_Bomb(
"Problem reading boundary data");
489 if (abscissaNames <= 0)
490 SDDS_Bomb(
"Supply the name of the abscissa with -abscissaName");
494 SetUpOutput(&SDDSout, &SDDSin, &abscissaIndex, &cdfIndex, &histogramIndex, output, columnName, columnNames, abscissaName, abscissaNames, boundaryColumn, boundaryColumnUnits, columnMajorOrder, normMode);
496 if (!(inputData = (
double **)malloc(columnNames *
sizeof(*inputData))) ||
497 !(minValue = (
double *)malloc(columnNames *
sizeof(*minValue))) ||
498 !(maxValue = (
double *)malloc(columnNames *
sizeof(*maxValue))))
501 if (((binSize ? 1 : 0) + (binsGiven ? 1 : 0) + (autoBinsTarget ? 1 : 0)) > 1)
502 SDDS_Bomb(
"Specify only one of -binSize, -bins, or -autoBins");
503 if (!binSize && !binsGiven && !autoBinsTarget) {
508 abscissa = histogram = cdf = NULL;
518 for (column = 0; column < columnNames; column++) {
523 if (!boundaryColumn) {
524 if (!(lowerLimit = (
double *)malloc(
sizeof(*lowerLimit) * columnNames)))
526 if (!(upperLimit = (
double *)malloc(
sizeof(*upperLimit) * columnNames)))
528 if (!(dx = (
double *)malloc(
sizeof(*dx) * columnNames)))
532 for (column = 0; column < columnNames; column++) {
533 find_min_max(&minValue[column], &maxValue[column], inputData[column], rows);
534 lowerLimit[column] = givenLowerLimits ? givenLowerLimit[column] : minValue[column];
535 upperLimit[column] = givenUpperLimits ? givenUpperLimit[column] : maxValue[column];
538 for (column = 0; column < columnNames; column++)
539 find_min_max(&minValue[column], &maxValue[column], inputData[column], rows);
540 lowerLimit[0] = givenLowerLimits ? givenLowerLimit[0] :
min_in_array(minValue, columnNames);
541 upperLimit[0] = givenUpperLimits ? givenUpperLimit[0] :
max_in_array(maxValue, columnNames);
542 for (column = 1; column < columnNames; column++) {
543 lowerLimit[column] = lowerLimit[0];
544 upperLimit[column] = upperLimit[0];
548 range = (1 + expandRange) * (upperLimit[0] - lowerLimit[0]);
549 if (autoBinsTarget) {
550 bins = (int64_t)(rows / autoBinsTarget);
551 if (autoBinsMinimum) {
552 if (bins < autoBinsMinimum)
553 bins = autoBinsMinimum;
554 }
else if (bins < 5) {
557 if (autoBinsMaximum) {
558 if (bins > autoBinsMaximum)
559 bins = autoBinsMaximum;
560 }
else if (bins > rows)
566 for (column = 0; column < columnNames; column++) {
567 range = (1 + expandRange) * (upperLimit[column] - lowerLimit[column]);
568 range = ((range / binSize) + 1) * binSize;
569 if (range > maxRange)
571 middle = (lowerLimit[column] + upperLimit[column]) / 2;
572 lowerLimit[column] = middle - range / 2;
573 upperLimit[column] = middle + range / 2;
581 bins = maxRange / binSize + 0.5;
582 if (bins < 1 && !doSides)
585 for (column = 0; column < columnNames; column++) {
586 range = upperLimit[column] - lowerLimit[column];
587 upperLimit[column] += (maxRange - range) / 2;
588 lowerLimit[column] -= (maxRange - range) / 2;
589 dx[column] = binSize;
593 for (column = 0; column < columnNames; column++) {
594 range = (1 + expandRange) * (upperLimit[column] - lowerLimit[column]);
595 middle = (upperLimit[column] + lowerLimit[column]) / 2;
596 upperLimit[column] = middle + range / 2;
597 lowerLimit[column] = middle - range / 2;
598 if (upperLimit[column] == lowerLimit[column]) {
599 if (fabs(upperLimit[column]) < sqrt(DBL_MIN)) {
600 upperLimit[column] = sqrt(DBL_MIN);
601 lowerLimit[column] = -sqrt(DBL_MIN);
603 lowerLimit[column] = upperLimit[column] * (1 - 10000 * DBL_EPSILON);
604 upperLimit[column] = upperLimit[column] * (1 + 10000 * DBL_EPSILON);
607 dx[column] = (upperLimit[column] - lowerLimit[column]) / bins;
610 range = (1 + expandRange) * (upperLimit[0] - lowerLimit[0]);
611 middle = (upperLimit[0] + lowerLimit[0]) / 2;
612 upperLimit[0] = middle + range / 2;
613 lowerLimit[0] = middle - range / 2;
614 if (upperLimit[0] == lowerLimit[0]) {
615 if (fabs(upperLimit[0]) < sqrt(DBL_MIN)) {
616 upperLimit[0] = sqrt(DBL_MIN);
617 lowerLimit[0] = -sqrt(DBL_MIN);
619 lowerLimit[0] = upperLimit[0] * (1 - 10000 * DBL_EPSILON);
620 upperLimit[0] = upperLimit[0] * (1 + 10000 * DBL_EPSILON);
623 dx[0] = (upperLimit[0] - lowerLimit[0]) / bins;
626 if (!binsGiven || !abscissa) {
627 if (!(abscissa =
SDDS_Realloc(abscissa,
sizeof(*abscissa) * (bins + 2))) ||
628 !(cdf =
SDDS_Realloc(cdf,
sizeof(*cdf) * (bins + 2))) ||
629 !(histogram =
SDDS_Realloc(histogram,
sizeof(*histogram) * (bins + 2))))
632 writeBins = bins + (doSides ? 2 : 0);
633 offset = doSides ? 0 : 1;
635 bins = writeBins = nBoundaryValues;
638 !(histogram =
SDDS_Realloc(histogram,
sizeof(*histogram) * bins)))
645 if (boundaryColumn) {
646 for (column = 0; column < columnNames; column++) {
647 MakeBoundaryHistogram(histogram, cdf, boundaryValue, nBoundaryValues, inputData[column], weightData, rows);
648 NormalizeHistogram(histogram, nBoundaryValues, normMode);
649 if (!cdfOnly && !
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, histogram, writeBins, histogramIndex[column]))
651 if (!freOnly && !
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, cdf, writeBins, cdfIndex[column]))
653 free(inputData[column]);
655 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_NAME, boundaryValue, writeBins, boundaryColumn))
657 }
else if (!doSeparate) {
658 for (i = -1; i < bins + 1; i++)
659 abscissa[i + 1] = (i + 0.5) * dx[0] + lowerLimit[0];
662 abscissa[0] = abscissa[1] - dx[0] / 2;
663 abscissa[bins + 1] = abscissa[bins] + dx[0] / 2;
665 case DO_AGAINST_SIDES:
666 abscissa[0] = abscissa[1];
667 abscissa[bins + 1] = abscissa[bins];
670 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, abscissa + offset, writeBins, abscissaIndex[0]))
672 for (column = 0; column < columnNames; column++) {
673 histogram[0] = histogram[bins + 1] = 0;
675 make_histogram(histogram + 1, bins, lowerLimit[0], upperLimit[0], inputData[column], rows, 1);
677 make_histogram_weighted(histogram + 1, bins, lowerLimit[0], upperLimit[0], inputData[column], rows, 1, weightData);
678 NormalizeHistogram(histogram, bins, normMode);
680 for (i = 0; i <= bins + 1; i++)
682 for (i = 0; i <= bins + 1; i++) {
684 cdf[i] = histogram[i] / sum;
686 cdf[i] = cdf[i - 1] + histogram[i] / sum;
689 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, histogram + offset, writeBins, histogramIndex[column]))
693 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, cdf + offset, writeBins, cdfIndex[column]))
696 free(inputData[column]);
699 for (column = 0; column < columnNames; column++) {
700 for (i = -1; i < bins + 1; i++)
701 abscissa[i + 1] = (i + 0.5) * dx[column] + lowerLimit[column];
704 abscissa[0] = abscissa[1] - dx[column] / 2;
705 abscissa[bins + 1] = abscissa[bins] + dx[column] / 2;
707 case DO_AGAINST_SIDES:
708 abscissa[0] = abscissa[1];
709 abscissa[bins + 1] = abscissa[bins];
712 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, abscissa + offset, writeBins, abscissaIndex[column]))
714 histogram[0] = histogram[bins + 1] = 0;
716 make_histogram(histogram + 1, bins, lowerLimit[column], upperLimit[column], inputData[column], rows, 1);
718 make_histogram_weighted(histogram + 1, bins, lowerLimit[column], upperLimit[column], inputData[column], rows, 1, weightData);
719 NormalizeHistogram(histogram, bins + 2, normMode);
721 for (i = 0; i <= bins + 1; i++)
723 for (i = 0; i <= bins + 1; i++) {
725 cdf[i] = histogram[i] / sum;
727 cdf[i] = cdf[i - 1] + histogram[i] / sum;
730 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, histogram + offset, writeBins, histogramIndex[column]))
734 if (!
SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, cdf + offset, writeBins, cdfIndex[column]))
737 free(inputData[column]);
779 long **histogramIndex,
char *output,
char **columnName,
long columnNames,
780 char **abscissaName,
long abscissaNames,
char *boundaryColumn,
char *boundaryUnits,
781 short columnMajorOrder,
short normMode) {
783 char s[SDDS_MAXLINE];
785 char *blankString =
"";
790 if (columnMajorOrder != -1)
791 SDDSout->layout.data_mode.column_major = columnMajorOrder;
793 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
795 if (!(*cdfIndex = (
long *)malloc(
sizeof(**cdfIndex) * columnNames)))
798 if (!(*histogramIndex = (
long *)malloc(
sizeof(**histogramIndex) * columnNames)))
801 if (!boundaryColumn) {
802 if (!(*abscissaIndex = (
long *)malloc(
sizeof(**abscissaIndex) * columnNames)))
805 for (column = 0; column < abscissaNames; column++) {
810 if (strcmp(columnName[column], abscissaName[column]) != 0 &&
820 for (column = 0; column < columnNames; column++) {
822 sprintf(s,
"%sCdf", columnName[column]);
829 sprintf(s,
"%sRelativeFrequency", columnName[column]);
832 sprintf(s,
"%sFractionalFrequency", columnName[column]);
835 sprintf(s,
"%sFrequency", columnName[column]);
847double *ReadBoundaryData(
char *file,
char *column, int64_t *n,
char **units) {
864 *n = SDDS_RowCount(&SDDSin);
869 for (j = 1; j < (*n); j++) {
870 if (data[j] <= data[j - 1]) {
871 memmove(data + j, data + j + 1,
sizeof(*data) * ((*n) - 1 - j));
879void MakeBoundaryHistogram(
double *histogram,
double *cdf,
double *boundaryValue, int64_t nBoundaryValues,
880 double *data,
double *weight, int64_t nData) {
882 for (i = 0; i < nBoundaryValues; i++)
883 histogram[i] = cdf[i] = 0;
884 for (i = 0; i < nData; i++) {
886 if (j < nBoundaryValues && j >= 0)
887 histogram[j] += weight ? fabs(weight[i]) : 1;
889 cdf[0] = histogram[0];
890 for (j = 1; j < nBoundaryValues; j++) {
891 cdf[j] = cdf[j - 1] + histogram[j];
893 if (cdf[nBoundaryValues - 1] > 0)
894 for (j = 0; j < nBoundaryValues; j++)
895 cdf[j] /= cdf[nBoundaryValues - 1];
898void NormalizeHistogram(
double *hist, int64_t bins,
short mode) {
903 for (i = 0; i < bins; i++)
907 for (i = 0; i < bins; i++)
916 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.
Utility functions for SDDS dataset manipulation and string array operations.
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.