SDDSlib
Loading...
Searching...
No Matches
sddsgfit.c File Reference

Performs a Gaussian fit on input data. More...

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

Go to the source code of this file.

Macros

#define GUESS_BASELINE_GIVEN   0x0001
 
#define FIX_BASELINE_GIVEN   (0x0001 << 4)
 
#define GUESS_HEIGHT_GIVEN   0x0002
 
#define FIX_HEIGHT_GIVEN   (0x0002 << 4)
 
#define GUESS_MEAN_GIVEN   0x0004
 
#define FIX_MEAN_GIVEN   (0x0004 << 4)
 
#define GUESS_SIGMA_GIVEN   0x0008
 
#define FIX_SIGMA_GIVEN   (0x0008 << 4)
 
#define BASELINE_INDEX   0
 
#define HEIGHT_INDEX   1
 
#define MEAN_INDEX   2
 
#define SIGMA_INDEX   3
 

Enumerations

enum  option_type {
  SET_FITRANGE , SET_GUESSES , SET_VERBOSITY , SET_COLUMNS ,
  SET_TOLERANCE , SET_FULLOUTPUT , SET_STEPSIZE , SET_LIMITS ,
  SET_PIPE , SET_FIXVALUE , SET_MAJOR_ORDER , N_OPTIONS
}
 

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)
 

Variables

char * option [N_OPTIONS]
 
static char * USAGE
 
static double * xDataFit = NULL
 
static double * yDataFit = NULL
 
static double * syDataFit = NULL
 
static int64_t nDataFit = 0
 

Detailed Description

Performs a Gaussian fit on input data.

This program fits the data to the Gaussian function:

y(n) = baseline + height * exp(-0.5 * (x(n) - mean)^2 / sigma^2)

The program supports various options for specifying fit ranges, initial guesses, verbosity levels, output formats, and more. It processes input data from a file or via a pipe and outputs the fitted results to a file or pipe.

Usage

To execute the Gaussian fitting program, use the following command structure:

sddsgfit [<inputfile>] [<outputfile>] [options]

Options

The program accepts the following command-line options:

-pipe=[input][,output] -columns=<x-name>,<y-name>[,ySigma=<sy-name>] -fitRange=<lower>|<parameter-name>,<upper>|<parameter-name> -fullOutput -verbosity=<integer> -stepSize=<factor> -tolerance=

-guesses=[baseline=

|<parameter-name>][,mean=

|<parameter-name>][,height=

|<parameter-name>][,sigma=

|<parameter-name>] -fixValue=[baseline=

|<parameter-name>][,mean=

|<parameter-name>][,height=

|<parameter-name>][,sigma=

|<parameter-name>] -limits=[evaluations=<number>][,passes=<number>] -majorOrder=row|column

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.

Macro Definition Documentation

◆ BASELINE_INDEX

#define BASELINE_INDEX   0

Definition at line 123 of file sddsgfit.c.

◆ FIX_BASELINE_GIVEN

#define FIX_BASELINE_GIVEN   (0x0001 << 4)

Definition at line 115 of file sddsgfit.c.

◆ FIX_HEIGHT_GIVEN

#define FIX_HEIGHT_GIVEN   (0x0002 << 4)

Definition at line 117 of file sddsgfit.c.

◆ FIX_MEAN_GIVEN

#define FIX_MEAN_GIVEN   (0x0004 << 4)

Definition at line 119 of file sddsgfit.c.

◆ FIX_SIGMA_GIVEN

#define FIX_SIGMA_GIVEN   (0x0008 << 4)

Definition at line 121 of file sddsgfit.c.

◆ GUESS_BASELINE_GIVEN

#define GUESS_BASELINE_GIVEN   0x0001

Definition at line 114 of file sddsgfit.c.

◆ GUESS_HEIGHT_GIVEN

#define GUESS_HEIGHT_GIVEN   0x0002

Definition at line 116 of file sddsgfit.c.

◆ GUESS_MEAN_GIVEN

#define GUESS_MEAN_GIVEN   0x0004

Definition at line 118 of file sddsgfit.c.

◆ GUESS_SIGMA_GIVEN

#define GUESS_SIGMA_GIVEN   0x0008

Definition at line 120 of file sddsgfit.c.

◆ HEIGHT_INDEX

#define HEIGHT_INDEX   1

Definition at line 124 of file sddsgfit.c.

◆ MEAN_INDEX

#define MEAN_INDEX   2

Definition at line 125 of file sddsgfit.c.

◆ SIGMA_INDEX

#define SIGMA_INDEX   3

Definition at line 126 of file sddsgfit.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 53 of file sddsgfit.c.

53 {
54 SET_FITRANGE,
55 SET_GUESSES,
56 SET_VERBOSITY,
57 SET_COLUMNS,
58 SET_TOLERANCE,
59 SET_FULLOUTPUT,
60 SET_STEPSIZE,
61 SET_LIMITS,
62 SET_PIPE,
63 SET_FIXVALUE,
64 SET_MAJOR_ORDER,
65 N_OPTIONS
66};

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 696 of file sddsgfit.c.

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

◆ fitFunction()

double fitFunction ( double * a,
long * invalid )

Definition at line 659 of file sddsgfit.c.

659 {
660 double sum, tmp, mean, sigma, base, norm;
661 int64_t i;
662
663 *invalid = 0;
664 sigma = a[SIGMA_INDEX];
665 mean = a[MEAN_INDEX];
666 base = a[BASELINE_INDEX];
667 norm = a[HEIGHT_INDEX];
668
669 if (!syDataFit) {
670 for (i = sum = 0; i < nDataFit; i++) {
671 tmp = (xDataFit[i] - mean) / sigma;
672 tmp = yDataFit[i] - base - norm * exp(-sqr(tmp) / 2);
673 sum += sqr(tmp);
674 }
675 return (sum / nDataFit);
676 } else {
677 for (i = sum = 0; i < nDataFit; i++) {
678 tmp = (xDataFit[i] - mean) / sigma;
679 tmp = (yDataFit[i] - base - norm * exp(-sqr(tmp) / 2)) / syDataFit[i];
680 sum += sqr(tmp);
681 }
682 return (sum / nDataFit);
683 }
684}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 128 of file sddsgfit.c.

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

768 {
769 int64_t i, j;
770
771 if (!(*xFit = (double *)malloc(sizeof(**xFit) * n)) ||
772 !(*yFit = (double *)malloc(sizeof(**yFit) * n)) ||
773 (sy && !(*syFit = (double *)malloc(sizeof(**syFit) * n)))) {
774 return 0;
775 }
776
777 for (i = j = 0; i < n; i++) {
778 if (x[i] < lower || x[i] > upper) {
779 continue;
780 }
781 (*xFit)[j] = x[i];
782 (*yFit)[j] = y[i];
783 if (sy) {
784 (*syFit)[j] = sy[i];
785 }
786 j++;
787 }
788 return j;
789}

◆ report()

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

Definition at line 686 of file sddsgfit.c.

686 {
687 long i;
688
689 fprintf(stderr, "pass %ld, after %ld evaluations: result = %.16e\na = ", pass, nEval, y);
690 for (i = 0; i < n_dimen; i++) {
691 fprintf(stderr, "%.8e ", x[i]);
692 }
693 fputc('\n', stderr);
694}

◆ 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 588 of file sddsgfit.c.

590 {
591 char *name, *yUnits, *description, *xUnits;
592 int32_t typeValue = SDDS_DOUBLE;
593 static char *residualNamePart = "Residual";
594 static char *residualDescriptionPart = "Residual of Gaussian fit to ";
595
596 if (!SDDS_InitializeOutput(OutputTable, SDDS_BINARY, 0, NULL, "sddsgfit output", output) ||
597 !SDDS_TransferColumnDefinition(OutputTable, InputTable, xName, NULL) ||
598 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, xName) ||
599 (*xIndex = SDDS_GetColumnIndex(OutputTable, xName)) < 0 ||
600 !SDDS_GetColumnInformation(InputTable, "units", &xUnits, SDDS_BY_NAME, xName) ||
601 !SDDS_GetColumnInformation(InputTable, "units", &yUnits, SDDS_BY_NAME, yName)) {
602 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
603 }
604
605 if (columnMajorOrder != -1) {
606 OutputTable->layout.data_mode.column_major = columnMajorOrder;
607 } else {
608 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
609 }
610
611 name = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
612 description = tmalloc(sizeof(*description) * (strlen(yName) + strlen(residualDescriptionPart) + 1));
613
614 if (fullOutput) {
615 if (!SDDS_TransferColumnDefinition(OutputTable, InputTable, yName, NULL) ||
616 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, yName) ||
617 (*yIndex = SDDS_GetColumnIndex(OutputTable, yName)) < 0) {
618 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
619 }
620 if (syName && (!SDDS_TransferColumnDefinition(OutputTable, InputTable, syName, NULL) ||
621 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, syName) ||
622 (*syIndex = SDDS_GetColumnIndex(OutputTable, syName)) < 0)) {
623 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
624 }
625 sprintf(name, "%s%s", yName, residualNamePart);
626 sprintf(description, "%s%s", yName, residualDescriptionPart);
627 if ((*residualIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0) {
628 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
629 }
630 }
631
632 sprintf(name, "%sFit", yName);
633 sprintf(description, "Gaussian fit to %s", yName);
634 if ((*fitIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0) {
635 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
636 }
637
638 if (SDDS_DefineParameter(OutputTable, "gfitBaseline", NULL, yUnits, "Baseline from Gaussian fit",
639 NULL, SDDS_DOUBLE, 0) < 0 ||
640 SDDS_DefineParameter(OutputTable, "gfitHeight", NULL, yUnits, "Height from Gaussian fit",
641 NULL, SDDS_DOUBLE, 0) < 0 ||
642 SDDS_DefineParameter(OutputTable, "gfitMean", "$gm$r", xUnits, "Mean from Gaussian fit",
643 NULL, SDDS_DOUBLE, 0) < 0 ||
644 SDDS_DefineParameter(OutputTable, "gfitSigma", "$gs$r", xUnits, "Sigma from Gaussian fit",
645 NULL, SDDS_DOUBLE, 0) < 0 ||
646 SDDS_DefineParameter(OutputTable, "gfitRmsResidual", NULL, yUnits, "RMS residual from Gaussian fit",
647 NULL, SDDS_DOUBLE, 0) < 0 ||
648 SDDS_DefineParameter(OutputTable, "gfitSigLevel", NULL, NULL, "Significance level from chi-squared test",
649 NULL, SDDS_DOUBLE, 0) < 0 ||
650 !SDDS_TransferAllParameterDefinitions(OutputTable, InputTable, SDDS_TRANSFER_KEEPOLD) ||
651 !SDDS_WriteLayout(OutputTable)) {
652 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
653 }
654
655 free(name);
656 free(description);
657}
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

Variable Documentation

◆ nDataFit

int64_t nDataFit = 0
static

Definition at line 112 of file sddsgfit.c.

◆ option

char* option[N_OPTIONS]
Initial value:
= {
"fitrange",
"guesses",
"verbosity",
"columns",
"tolerance",
"fulloutput",
"stepsize",
"limits",
"pipe",
"fixvalue",
"majorOrder",
}

Definition at line 68 of file sddsgfit.c.

68 {
69 "fitrange",
70 "guesses",
71 "verbosity",
72 "columns",
73 "tolerance",
74 "fulloutput",
75 "stepsize",
76 "limits",
77 "pipe",
78 "fixvalue",
79 "majorOrder",
80};

◆ syDataFit

double * syDataFit = NULL
static

Definition at line 111 of file sddsgfit.c.

◆ USAGE

char* USAGE
static
Initial value:
=
"Usage: sddsgfit [<inputfile>] [<outputfile>] [-pipe=[input][,output]]\n"
" -columns=<x-name>,<y-name>[,ySigma=<sy-name>]\n"
" -fitRange=<lower>|@<parameter-name>,<upper>|@<parameter-name>\n"
" -fullOutput\n"
" -verbosity=<integer>\n"
" -stepSize=<factor>\n"
" -tolerance=<value>\n"
" -guesses=[baseline=<value>|@<parameter-name>][,mean=<value>|@<parameter-name>]"
"[,height=<value>|@<parameter-name>][,sigma=<value>|@<parameter-name>]\n"
" -fixValue=[baseline=<value>|@<parameter-name>][,mean=<value>|@<parameter-name>]"
"[,height=<value>|@<parameter-name>][,sigma=<value>|@<parameter-name>]\n"
" -limits=[evaluations=<number>][,passes=<number>]\n"
" -majorOrder=row|column\n\n"
"Performs a Gaussian fit of the form:\n"
" y = <baseline> + <height> * exp(-0.5 * (x - <mean>)^2 / <sigma>^2)\n"
"Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 82 of file sddsgfit.c.

◆ xDataFit

double* xDataFit = NULL
static

Definition at line 111 of file sddsgfit.c.

◆ yDataFit

double * yDataFit = NULL
static

Definition at line 111 of file sddsgfit.c.