SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddsgfit.c File Reference

Detailed Description

A program for performing Gaussian fitting on input data.

This program fits input data to a Gaussian function using customizable options. It reads data from SDDS (Self Describing Data Set) files, processes input columns, and generates fitted results. Users can specify fit ranges, initial parameter guesses, verbosity levels, and output formats.

Usage

sddsgfit [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
-columns=<x-name>,<y-name>[,ySigma=<sy-name>]
[-fitRange=<lower>|@<parameter-name>,<upper>|@<parameter-name>]
[-fullOutput]
[-verbosity=<integer>]
[-stepSize=<factor>]
[-tolerance=<value>]
[-guesses=[baseline=<value>|@<parameter-name>][,mean=<value>|@<parameter-name>][,height=<value>|@<parameter-name>][,sigma=<value>|@<parameter-name>]]
[-fixValue=[baseline=<value>|@<parameter-name>][,mean=<value>|@<parameter-name>][,height=<value>|@<parameter-name>][,sigma=<value>|@<parameter-name>]]
[-limits=[evaluations=<number>][,passes=<number>]]
[-majorOrder=row|column]

Options

Required Description
-columns Specifies the column names for x and y data.
Optional Description
-pipe Specifies input/output via pipes.
-fitRange Sets the range for fitting.
-fullOutput Enables full output, including residuals.
-verbosity Controls verbosity level (higher values give more detailed logs).
-stepSize Sets the optimization step size.
-tolerance Specifies the convergence tolerance.
-guesses Provides initial parameter guesses (baseline, mean, height, sigma).
-fixValue Fixes specific parameter values during fitting.
-limits Sets limits for evaluations and passes.
-majorOrder Defines the data order for output (row or column major).

Incompatibilities

  • -fixValue is incompatible with -guesses for the same parameter.

The program fits data to the Gaussian function:

y(n) = baseline + height * exp(-0.5 * (x(n) - mean)^2 / sigma^2)
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddsgfit.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Functions

void report (double res, double *a, long pass, long n_eval, long n_dimen)
 
void setupOutputFile (SDDS_DATASET *OutputTable, long *xIndex, long *yIndex, long *syIndex, long *fitIndex, long *residualIndex, long fullOutput, char *output, SDDS_DATASET *InputTable, char *xName, char *yName, char *syName, short columnMajorOrder)
 
long computeStartingPoint (double *a, double *da, double *x, double *y, int64_t n, unsigned long guessFlags, double sigmaGuess, double meanGuess, double baselineGuess, double heightGuess, double stepSize)
 
double fitFunction (double *a, long *invalid)
 
int64_t makeFilteredCopy (double **xFit, double **yFit, double **syFit, double *x, double *y, double *sy, int64_t n, double lower, double upper)
 
int main (int argc, char **argv)
 

Function Documentation

◆ computeStartingPoint()

long computeStartingPoint ( double * a,
double * da,
double * x,
double * y,
int64_t n,
unsigned long guessFlags,
double sigmaGuess,
double meanGuess,
double baselineGuess,
double heightGuess,
double stepSize )

Definition at line 711 of file sddsgfit.c.

713 {
714 double xhalf, dhalf, ymin, ymax, xcenter, tmp, xmax, xmin;
715 int64_t i;
716
717 if (n < 5) {
718 return 0;
719 }
720
721 /* first find maximum y value and corresponding x value, plus max x */
722 xcenter = 0;
723 ymax = xmax = -DBL_MAX;
724 ymin = xmin = DBL_MAX;
725 for (i = 0; i < n; i++) {
726 if (xmax < fabs(x[i])) {
727 xmax = fabs(x[i]);
728 }
729 if (xmin > fabs(x[i])) { /* Corrected comparison from < to > */
730 xmin = fabs(x[i]);
731 }
732 if (ymax < y[i]) {
733 ymax = y[i];
734 xcenter = x[i];
735 }
736 if (ymin > y[i]) {
737 ymin = y[i];
738 }
739 }
740
741 /* now find approximate half-max point */
742 xhalf = 0;
743 dhalf = DBL_MAX;
744 for (i = 0; i < n; i++) {
745 tmp = fabs((fabs(y[i] - ymax) / (ymax - ymin)) - 0.5);
746 if (tmp < dhalf) {
747 xhalf = x[i];
748 dhalf = tmp;
749 }
750 }
751 if (dhalf != DBL_MAX) {
752 a[SIGMA_INDEX] = fabs(xhalf - xcenter) / 1.177; /* starting sigma */
753 } else {
754 a[SIGMA_INDEX] = xmax - xmin;
755 }
756 a[MEAN_INDEX] = xcenter; /* starting mean */
757 a[BASELINE_INDEX] = ymin; /* starting baseline */
758 a[HEIGHT_INDEX] = ymax - ymin; /* starting height */
759
760 if (guessFlags & (GUESS_SIGMA_GIVEN + FIX_SIGMA_GIVEN)) {
761 a[SIGMA_INDEX] = sigmaGuess;
762 }
763 if (guessFlags & (GUESS_MEAN_GIVEN + FIX_MEAN_GIVEN)) {
764 a[MEAN_INDEX] = meanGuess;
765 }
766 if (guessFlags & (GUESS_BASELINE_GIVEN + FIX_BASELINE_GIVEN)) {
767 a[BASELINE_INDEX] = baselineGuess;
768 }
769 if (guessFlags & (GUESS_HEIGHT_GIVEN + FIX_HEIGHT_GIVEN)) {
770 a[HEIGHT_INDEX] = heightGuess;
771 }
772
773 /* step sizes */
774 for (i = 0; i < 4; i++) {
775 if (!(da[i] = a[i] * stepSize))
776 da[i] = stepSize;
777 }
778
779 return 1;
780}

◆ fitFunction()

double fitFunction ( double * a,
long * invalid )

Definition at line 674 of file sddsgfit.c.

674 {
675 double sum, tmp, mean, sigma, base, norm;
676 int64_t i;
677
678 *invalid = 0;
679 sigma = a[SIGMA_INDEX];
680 mean = a[MEAN_INDEX];
681 base = a[BASELINE_INDEX];
682 norm = a[HEIGHT_INDEX];
683
684 if (!syDataFit) {
685 for (i = sum = 0; i < nDataFit; i++) {
686 tmp = (xDataFit[i] - mean) / sigma;
687 tmp = yDataFit[i] - base - norm * exp(-sqr(tmp) / 2);
688 sum += sqr(tmp);
689 }
690 return (sum / nDataFit);
691 } else {
692 for (i = sum = 0; i < nDataFit; i++) {
693 tmp = (xDataFit[i] - mean) / sigma;
694 tmp = (yDataFit[i] - base - norm * exp(-sqr(tmp) / 2)) / syDataFit[i];
695 sum += sqr(tmp);
696 }
697 return (sum / nDataFit);
698 }
699}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 143 of file sddsgfit.c.

143 {
144 double *xData = NULL, *yData = NULL, *syData = NULL;
145 int64_t nData = 0;
146 SDDS_DATASET InputTable, OutputTable;
147 SCANNED_ARG *s_arg;
148 long i_arg;
149 char *input, *output, *xName, *yName, *syName;
150 long xIndex, yIndex, fitIndex, residualIndex, syIndex_out, retval;
151 double *fitData, *residualData, rmsResidual, chiSqr, sigLevel;
152 unsigned long guessFlags, dummyFlags, pipeFlags, majorOrderFlag;
153 double sigmaGuess, meanGuess, baselineGuess, heightGuess;
154 double tolerance, stepSize;
155 double a[4], da[4], lower, upper, result;
156 double aLow[4], aHigh[4];
157 short disable[4] = {0, 0, 0, 0};
158 int32_t nEvalMax = 5000, nPassMax = 100;
159 long nEval, verbosity, fullOutput = 0;
160 int64_t i;
161 short columnMajorOrder = -1;
162 char *lowerPar, *upperPar, *baselineGuessPar, *sigmaGuessPar, *meanGuessPar, *heightGuessPar;
163
165 argc = scanargs(&s_arg, argc, argv);
166 if (argc < 2 || argc > (2 + N_OPTIONS)) {
167 bomb(NULL, USAGE);
168 }
169
170 for (i = 0; i < 4; i++) {
171 aLow[i] = -(aHigh[i] = DBL_MAX);
172 }
173 aLow[SIGMA_INDEX] = 0;
174 input = output = NULL;
175 stepSize = 1e-2;
176 tolerance = 1e-8;
177 verbosity = 0;
178 guessFlags = sigmaGuess = heightGuess = baselineGuess = meanGuess = pipeFlags = 0;
179 xName = yName = syName = NULL;
180 lower = upper = 0;
181 lowerPar = upperPar = sigmaGuessPar = heightGuessPar = baselineGuessPar = meanGuessPar = NULL;
182
183 for (i_arg = 1; i_arg < argc; i_arg++) {
184 if (s_arg[i_arg].arg_type == OPTION) {
185 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
186 case SET_MAJOR_ORDER:
187 majorOrderFlag = 0;
188 s_arg[i_arg].n_items--;
189 if (s_arg[i_arg].n_items > 0 && (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1,
190 &s_arg[i_arg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
191 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
192 SDDS_Bomb("invalid -majorOrder syntax/values");
193 }
194 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER) {
195 columnMajorOrder = 1;
196 } else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER) {
197 columnMajorOrder = 0;
198 }
199 break;
200
201 case SET_FITRANGE:
202 if (s_arg[i_arg].n_items != 3) {
203 SDDS_Bomb("incorrect -fitRange syntax");
204 }
205 if (s_arg[i_arg].list[1][0] == '@') {
206 cp_str(&lowerPar, s_arg[i_arg].list[1] + 1);
207 } else if (sscanf(s_arg[i_arg].list[1], "%lf", &lower) != 1) {
208 SDDS_Bomb("invalid fitRange lower value provided");
209 }
210 if (s_arg[i_arg].list[2][0] == '@') {
211 cp_str(&upperPar, s_arg[i_arg].list[2] + 1);
212 } else if (sscanf(s_arg[i_arg].list[2], "%lf", &upper) != 1) {
213 SDDS_Bomb("invalid fitRange upper value provided");
214 }
215 break;
216
217 case SET_TOLERANCE:
218 if (s_arg[i_arg].n_items != 2 ||
219 sscanf(s_arg[i_arg].list[1], "%lf", &tolerance) != 1 ||
220 tolerance <= 0) {
221 SDDS_Bomb("incorrect -tolerance syntax");
222 }
223 break;
224
225 case SET_STEPSIZE:
226 if (s_arg[i_arg].n_items != 2 ||
227 sscanf(s_arg[i_arg].list[1], "%lf", &stepSize) != 1 ||
228 stepSize <= 0) {
229 SDDS_Bomb("incorrect -stepSize syntax");
230 }
231 break;
232
233 case SET_VERBOSITY:
234 if (s_arg[i_arg].n_items != 2 ||
235 sscanf(s_arg[i_arg].list[1], "%ld", &verbosity) != 1) {
236 SDDS_Bomb("incorrect -verbosity syntax");
237 }
238 break;
239
240 case SET_GUESSES:
241 if (s_arg[i_arg].n_items < 2) {
242 SDDS_Bomb("incorrect -guesses syntax");
243 }
244 s_arg[i_arg].n_items -= 1;
245 dummyFlags = guessFlags;
246 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
247 "baseline", SDDS_STRING, &baselineGuessPar, 1, GUESS_BASELINE_GIVEN,
248 "height", SDDS_STRING, &heightGuessPar, 1, GUESS_HEIGHT_GIVEN,
249 "mean", SDDS_STRING, &meanGuessPar, 1, GUESS_MEAN_GIVEN,
250 "sigma", SDDS_STRING, &sigmaGuessPar, 1, GUESS_SIGMA_GIVEN, NULL)) {
251 SDDS_Bomb("invalid -guesses syntax");
252 }
253 if (baselineGuessPar) {
254 if (baselineGuessPar[0] == '@') {
255 baselineGuessPar++;
256 } else {
257 if (sscanf(baselineGuessPar, "%lf", &baselineGuess) != 1) {
258 SDDS_Bomb("Invalid baseline guess value provided.");
259 }
260 free(baselineGuessPar);
261 baselineGuessPar = NULL;
262 }
263 }
264 if (heightGuessPar) {
265 if (heightGuessPar[0] == '@') {
266 heightGuessPar++;
267 } else {
268 if (sscanf(heightGuessPar, "%lf", &heightGuess) != 1) {
269 SDDS_Bomb("Invalid height guess value provided.");
270 }
271 free(heightGuessPar);
272 heightGuessPar = NULL;
273 }
274 }
275 if (meanGuessPar) {
276 if (meanGuessPar[0] == '@') {
277 meanGuessPar++;
278 } else {
279 if (sscanf(meanGuessPar, "%lf", &meanGuess) != 1) {
280 SDDS_Bomb("Invalid mean guess value provided.");
281 }
282 free(meanGuessPar);
283 meanGuessPar = NULL;
284 }
285 }
286 if (sigmaGuessPar) {
287 if (sigmaGuessPar[0] == '@') {
288 sigmaGuessPar++;
289 } else {
290 if (sscanf(sigmaGuessPar, "%lf", &sigmaGuess) != 1) {
291 SDDS_Bomb("Invalid sigma guess value provided.");
292 }
293 free(sigmaGuessPar);
294 sigmaGuessPar = NULL;
295 }
296 }
297 if ((dummyFlags >> 4) & guessFlags) {
298 SDDS_Bomb("can't have -fixedValue and -guesses for the same item");
299 }
300 guessFlags |= dummyFlags;
301 break;
302
303 case SET_FIXVALUE:
304 if (s_arg[i_arg].n_items < 2) {
305 SDDS_Bomb("incorrect -fixValue syntax");
306 }
307 s_arg[i_arg].n_items -= 1;
308 dummyFlags = guessFlags;
309 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
310 "baseline", SDDS_STRING, &baselineGuessPar, 1, FIX_BASELINE_GIVEN,
311 "height", SDDS_STRING, &heightGuessPar, 1, FIX_HEIGHT_GIVEN,
312 "mean", SDDS_STRING, &meanGuessPar, 1, FIX_MEAN_GIVEN,
313 "sigma", SDDS_STRING, &sigmaGuessPar, 1, FIX_SIGMA_GIVEN, NULL)) {
314 SDDS_Bomb("invalid -fixValue syntax");
315 }
316 if (dummyFlags & (guessFlags >> 4)) {
317 SDDS_Bomb("can't have -fixValue and -guesses for the same item");
318 }
319 guessFlags |= dummyFlags;
320 if (baselineGuessPar) {
321 if (baselineGuessPar[0] == '@') {
322 baselineGuessPar++;
323 } else {
324 if (sscanf(baselineGuessPar, "%lf", &baselineGuess) != 1) {
325 SDDS_Bomb("Invalid baseline guess value provided.");
326 }
327 free(baselineGuessPar);
328 baselineGuessPar = NULL;
329 }
330 }
331 if (heightGuessPar) {
332 if (heightGuessPar[0] == '@') {
333 heightGuessPar++;
334 } else {
335 if (sscanf(heightGuessPar, "%lf", &heightGuess) != 1) {
336 SDDS_Bomb("Invalid height guess value provided.");
337 }
338 free(heightGuessPar);
339 heightGuessPar = NULL;
340 }
341 }
342 if (meanGuessPar) {
343 if (meanGuessPar[0] == '@') {
344 meanGuessPar++;
345 } else {
346 if (sscanf(meanGuessPar, "%lf", &meanGuess) != 1) {
347 SDDS_Bomb("Invalid mean guess value provided.");
348 }
349 free(meanGuessPar);
350 meanGuessPar = NULL;
351 }
352 }
353 if (sigmaGuessPar) {
354 if (sigmaGuessPar[0] == '@') {
355 sigmaGuessPar++;
356 } else {
357 if (sscanf(sigmaGuessPar, "%lf", &sigmaGuess) != 1) {
358 SDDS_Bomb("Invalid sigma guess value provided.");
359 }
360 free(sigmaGuessPar);
361 sigmaGuessPar = NULL;
362 }
363 }
364 break;
365
366 case SET_COLUMNS:
367 if (s_arg[i_arg].n_items != 3 && s_arg[i_arg].n_items != 4) {
368 SDDS_Bomb("invalid -columns syntax");
369 }
370 xName = s_arg[i_arg].list[1];
371 yName = s_arg[i_arg].list[2];
372 s_arg[i_arg].n_items -= 3;
373 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0,
374 "ysigma", SDDS_STRING, &syName, 1, 0, NULL)) {
375 SDDS_Bomb("invalid -columns syntax");
376 }
377 break;
378
379 case SET_FULLOUTPUT:
380 fullOutput = 1;
381 break;
382
383 case SET_LIMITS:
384 if (s_arg[i_arg].n_items < 2) {
385 SDDS_Bomb("incorrect -limits syntax");
386 }
387 s_arg[i_arg].n_items -= 1;
388 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
389 "evaluations", SDDS_LONG, &nEvalMax, 1, 0,
390 "passes", SDDS_LONG, &nPassMax, 1, 0, NULL) ||
391 nEvalMax <= 0 || nPassMax <= 0) {
392 SDDS_Bomb("invalid -limits syntax");
393 }
394 break;
395
396 case SET_PIPE:
397 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
398 SDDS_Bomb("invalid -pipe syntax");
399 }
400 break;
401
402 default:
403 fprintf(stderr, "error: unknown/ambiguous option: %s\n", s_arg[i_arg].list[0]);
404 exit(EXIT_FAILURE);
405 break;
406 }
407 } else {
408 if (input == NULL) {
409 input = s_arg[i_arg].list[0];
410 } else if (output == NULL) {
411 output = s_arg[i_arg].list[0];
412 } else {
413 SDDS_Bomb("too many filenames");
414 }
415 }
416 }
417
418 processFilenames("sddsgfit", &input, &output, pipeFlags, 0, NULL);
419
420 for (i = 0; i < 4; i++) {
421 if ((guessFlags >> 4) & (1 << i)) {
422 disable[i] = 1;
423 }
424 }
425
426 if (!xName || !yName) {
427 SDDS_Bomb("-columns option must be given");
428 }
429
430 if (!SDDS_InitializeInput(&InputTable, input)) {
431 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
432 }
433 if (!SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, xName, NULL) ||
434 !SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, yName, NULL) ||
435 (syName && !SDDS_FindColumn(&InputTable, FIND_NUMERIC_TYPE, syName, NULL))) {
436 SDDS_Bomb("one or more of the given data columns is nonexistent or nonnumeric");
437 }
438
439 setupOutputFile(&OutputTable, &xIndex, &yIndex, &syIndex_out, &fitIndex, &residualIndex,
440 fullOutput, output, &InputTable, xName, yName, syName, columnMajorOrder);
441
442 while ((retval = SDDS_ReadPage(&InputTable)) > 0) {
443 xData = yData = syData = NULL;
444 fitData = residualData = NULL;
445 if (!(xData = SDDS_GetColumnInDoubles(&InputTable, xName)) ||
446 !(yData = SDDS_GetColumnInDoubles(&InputTable, yName))) {
447 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
448 }
449 if (syName && !(syData = SDDS_GetColumnInDoubles(&InputTable, syName))) {
450 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
451 }
452 if (lowerPar && !SDDS_GetParameterAsDouble(&InputTable, lowerPar, &lower)) {
453 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
454 }
455 if (upperPar && !SDDS_GetParameterAsDouble(&InputTable, upperPar, &upper)) {
456 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
457 }
458 if (baselineGuessPar && !SDDS_GetParameterAsDouble(&InputTable, baselineGuessPar, &baselineGuess)) {
459 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
460 }
461 if (heightGuessPar && !SDDS_GetParameterAsDouble(&InputTable, heightGuessPar, &heightGuess)) {
462 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
463 }
464 if (meanGuessPar && !SDDS_GetParameterAsDouble(&InputTable, meanGuessPar, &meanGuess)) {
465 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
466 }
467 if (sigmaGuessPar && !SDDS_GetParameterAsDouble(&InputTable, sigmaGuessPar, &sigmaGuess)) {
468 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
469 }
470
471 if ((nData = SDDS_CountRowsOfInterest(&InputTable)) < 5) {
472 continue;
473 }
474 if (lower < upper) {
475 if ((nDataFit = makeFilteredCopy(&xDataFit, &yDataFit, &syDataFit, xData, yData, syData, nData, lower, upper)) < 5) {
476 continue;
477 }
478 } else {
479 xDataFit = xData;
480 yDataFit = yData;
481 syDataFit = syData;
482 nDataFit = nData;
483 }
484
485 if (!computeStartingPoint(a, da, xDataFit, yDataFit, nDataFit, guessFlags, sigmaGuess, meanGuess,
486 baselineGuess, heightGuess, stepSize)) {
487 fprintf(stderr, "error: couldn't compute starting point for page %ld--skipping\n", retval);
488 continue;
489 }
490 if (verbosity > 2) {
491 fprintf(stderr, "starting values: sigma=%.6e mean=%.6e baseline=%.6e height=%.6e\n",
492 a[SIGMA_INDEX], a[MEAN_INDEX], a[BASELINE_INDEX], a[HEIGHT_INDEX]);
493 }
494 if (verbosity > 3) {
495 fprintf(stderr, "starting steps: sigma=%.6e mean=%.6e baseline=%.6e height=%.6e\n",
496 da[SIGMA_INDEX], da[MEAN_INDEX], da[BASELINE_INDEX], da[HEIGHT_INDEX]);
497 }
498
499 nEval = simplexMin(&result, a, da, aLow, aHigh, disable, 4, -DBL_MAX, tolerance,
500 fitFunction, (verbosity > 0 ? report : NULL),
501 nEvalMax, nPassMax, 12, 3, 1.0, 0);
502 if (xData != xDataFit) {
503 free(xDataFit);
504 free(yDataFit);
505 if (syDataFit) {
506 free(syDataFit);
507 }
508 }
509
510 if (verbosity > 3) {
511 fprintf(stderr, "%ld evaluations of fit function required, giving result %e\n", nEval, result);
512 }
513
514 fitData = trealloc(fitData, sizeof(*fitData) * nData);
515 residualData = trealloc(residualData, sizeof(*residualData) * nData);
516 for (i = 0, result = 0; i < nData; i++) {
517 fitData[i] = a[BASELINE_INDEX] + a[HEIGHT_INDEX] * exp(-ipow((xData[i] - a[MEAN_INDEX]) / a[SIGMA_INDEX], 2) / 2);
518 residualData[i] = yData[i] - fitData[i];
519 result += sqr(residualData[i]);
520 }
521 rmsResidual = sqrt(result / nData);
522 if (syData) {
523 for (i = 0, chiSqr = 0; i < nData; i++) {
524 chiSqr += sqr(residualData[i] / syData[i]);
525 }
526 } else {
527 double sy2 = result / (nData - 4);
528 for (i = 0, chiSqr = 0; i < nData; i++) {
529 chiSqr += sqr(residualData[i]) / sy2;
530 }
531 }
532 sigLevel = ChiSqrSigLevel(chiSqr, nData - 4);
533 if (verbosity > 0) {
534 fprintf(stderr, "sigma: %.15e\nmean: %.15e\nbaseline: %.15e\nheight: %.15e\n",
535 a[SIGMA_INDEX], a[MEAN_INDEX], a[BASELINE_INDEX], a[HEIGHT_INDEX]);
536 }
537 if (verbosity > 1) {
538 if (syData) {
539 fprintf(stderr, "Significance level: %.5e\n", sigLevel);
540 }
541 fprintf(stderr, "RMS deviation: %.15e\n", rmsResidual);
542 }
543
544 if (!SDDS_StartPage(&OutputTable, nData) ||
545 !SDDS_CopyParameters(&OutputTable, &InputTable) ||
546 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, xData, nData, xIndex) ||
547 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, fitData, nData, fitIndex) ||
548 !SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
549 "gfitSigma", a[SIGMA_INDEX],
550 "gfitMean", a[MEAN_INDEX],
551 "gfitBaseline", a[BASELINE_INDEX],
552 "gfitHeight", a[HEIGHT_INDEX],
553 "gfitRmsResidual", rmsResidual,
554 "gfitSigLevel", sigLevel, NULL) ||
555 (fullOutput &&
556 (!SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yData, nData, yIndex) ||
557 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, residualData, nData, residualIndex) ||
558 (syName && !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, syData, nData, syIndex_out)))) ||
559 !SDDS_WritePage(&OutputTable)) {
560 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
561 }
562
563 if (xData) {
564 free(xData);
565 }
566 if (yData) {
567 free(yData);
568 }
569 if (syData) {
570 free(syData);
571 }
572 if (fitData) {
573 free(fitData);
574 }
575 if (residualData) {
576 free(residualData);
577 }
578 }
579
580 if (!SDDS_Terminate(&InputTable) || !SDDS_Terminate(&OutputTable)) {
581 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
582 exit(EXIT_FAILURE);
583 }
584 if (lowerPar) {
585 free(lowerPar);
586 }
587 if (upperPar) {
588 free(upperPar);
589 }
590 if (baselineGuessPar) {
591 free(baselineGuessPar);
592 }
593 if (heightGuessPar) {
594 free(heightGuessPar);
595 }
596 if (sigmaGuessPar) {
597 free(sigmaGuessPar);
598 }
599 free_scanargs(&s_arg, argc);
600 return EXIT_SUCCESS;
601}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
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.
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...
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.
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
char * SDDS_FindColumn(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Finds the first column in the SDDS dataset that matches the specified criteria.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#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
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33
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:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.
double ChiSqrSigLevel(double ChiSquared0, long nu)
Computes the probability that a chi-squared variable exceeds a given value.
Definition sigLevel.c:64
long simplexMin(double *yReturn, double *xGuess, double *dxGuess, double *xLowerLimit, double *xUpperLimit, short *disable, long dimensions, double target, double tolerance, double(*func)(double *x, long *invalid), void(*report)(double ymin, double *xmin, long pass, long evals, long dims), long maxEvaluations, long maxPasses, long maxDivisions, double divisorFactor, double passRangeFactor, unsigned long flags)
Top-level convenience function for simplex-based minimization.
Definition simplex.c:472

◆ makeFilteredCopy()

int64_t makeFilteredCopy ( double ** xFit,
double ** yFit,
double ** syFit,
double * x,
double * y,
double * sy,
int64_t n,
double lower,
double upper )

Definition at line 782 of file sddsgfit.c.

783 {
784 int64_t i, j;
785
786 if (!(*xFit = (double *)malloc(sizeof(**xFit) * n)) ||
787 !(*yFit = (double *)malloc(sizeof(**yFit) * n)) ||
788 (sy && !(*syFit = (double *)malloc(sizeof(**syFit) * n)))) {
789 return 0;
790 }
791
792 for (i = j = 0; i < n; i++) {
793 if (x[i] < lower || x[i] > upper) {
794 continue;
795 }
796 (*xFit)[j] = x[i];
797 (*yFit)[j] = y[i];
798 if (sy) {
799 (*syFit)[j] = sy[i];
800 }
801 j++;
802 }
803 return j;
804}

◆ report()

void report ( double res,
double * a,
long pass,
long n_eval,
long n_dimen )

Definition at line 701 of file sddsgfit.c.

701 {
702 long i;
703
704 fprintf(stderr, "pass %ld, after %ld evaluations: result = %.16e\na = ", pass, nEval, y);
705 for (i = 0; i < n_dimen; i++) {
706 fprintf(stderr, "%.8e ", x[i]);
707 }
708 fputc('\n', stderr);
709}

◆ setupOutputFile()

void setupOutputFile ( SDDS_DATASET * OutputTable,
long * xIndex,
long * yIndex,
long * syIndex,
long * fitIndex,
long * residualIndex,
long fullOutput,
char * output,
SDDS_DATASET * InputTable,
char * xName,
char * yName,
char * syName,
short columnMajorOrder )

Definition at line 603 of file sddsgfit.c.

605 {
606 char *name, *yUnits, *description, *xUnits;
607 int32_t typeValue = SDDS_DOUBLE;
608 static char *residualNamePart = "Residual";
609 static char *residualDescriptionPart = "Residual of Gaussian fit to ";
610
611 if (!SDDS_InitializeOutput(OutputTable, SDDS_BINARY, 0, NULL, "sddsgfit output", output) ||
612 !SDDS_TransferColumnDefinition(OutputTable, InputTable, xName, NULL) ||
613 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, xName) ||
614 (*xIndex = SDDS_GetColumnIndex(OutputTable, xName)) < 0 ||
615 !SDDS_GetColumnInformation(InputTable, "units", &xUnits, SDDS_BY_NAME, xName) ||
616 !SDDS_GetColumnInformation(InputTable, "units", &yUnits, SDDS_BY_NAME, yName)) {
617 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
618 }
619
620 if (columnMajorOrder != -1) {
621 OutputTable->layout.data_mode.column_major = columnMajorOrder;
622 } else {
623 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
624 }
625
626 name = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
627 description = tmalloc(sizeof(*description) * (strlen(yName) + strlen(residualDescriptionPart) + 1));
628
629 if (fullOutput) {
630 if (!SDDS_TransferColumnDefinition(OutputTable, InputTable, yName, NULL) ||
631 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, yName) ||
632 (*yIndex = SDDS_GetColumnIndex(OutputTable, yName)) < 0) {
633 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
634 }
635 if (syName && (!SDDS_TransferColumnDefinition(OutputTable, InputTable, syName, NULL) ||
636 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, syName) ||
637 (*syIndex = SDDS_GetColumnIndex(OutputTable, syName)) < 0)) {
638 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
639 }
640 sprintf(name, "%s%s", yName, residualNamePart);
641 sprintf(description, "%s%s", yName, residualDescriptionPart);
642 if ((*residualIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0) {
643 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
644 }
645 }
646
647 sprintf(name, "%sFit", yName);
648 sprintf(description, "Gaussian fit to %s", yName);
649 if ((*fitIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0) {
650 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
651 }
652
653 if (SDDS_DefineParameter(OutputTable, "gfitBaseline", NULL, yUnits, "Baseline from Gaussian fit",
654 NULL, SDDS_DOUBLE, 0) < 0 ||
655 SDDS_DefineParameter(OutputTable, "gfitHeight", NULL, yUnits, "Height from Gaussian fit",
656 NULL, SDDS_DOUBLE, 0) < 0 ||
657 SDDS_DefineParameter(OutputTable, "gfitMean", "$gm$r", xUnits, "Mean from Gaussian fit",
658 NULL, SDDS_DOUBLE, 0) < 0 ||
659 SDDS_DefineParameter(OutputTable, "gfitSigma", "$gs$r", xUnits, "Sigma from Gaussian fit",
660 NULL, SDDS_DOUBLE, 0) < 0 ||
661 SDDS_DefineParameter(OutputTable, "gfitRmsResidual", NULL, yUnits, "RMS residual from Gaussian fit",
662 NULL, SDDS_DOUBLE, 0) < 0 ||
663 SDDS_DefineParameter(OutputTable, "gfitSigLevel", NULL, NULL, "Significance level from chi-squared test",
664 NULL, SDDS_DOUBLE, 0) < 0 ||
665 !SDDS_TransferAllParameterDefinitions(OutputTable, InputTable, SDDS_TRANSFER_KEEPOLD) ||
666 !SDDS_WriteLayout(OutputTable)) {
667 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
668 }
669
670 free(name);
671 free(description);
672}
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_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
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_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_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
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.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59