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

Detailed Description

Performs exponential fitting for input data using the SDDS library.

This program fits data to an exponential function of the form:

y = a0 + a1 * exp(a2 * x)

It reads input data, applies the fitting model, and writes the results to an output file. The program supports flexible configuration of input/output formats, fitting parameters, and other operational settings.

Usage

sddsexpfit [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
[-fulloutput]
-columns=<x-name>,<y-name>[,ySigma=<name>]
[-tolerance=<value>]
[-verbosity=<integer>]
[-clue={grows|decays}]
[-guess=<constant>,<factor>,<rate>]
[-startValues=[constant=<value>][,factor=<value>][,rate=<value>]]
[-fixValue=[constant=<value>][,factor=<value>][,rate=<value>]]
[-autoOffset]
[-limits=[evaluations=<number>][,passes=<number>]]
[-majorOrder=row|column]

Options

Required Description
-columns Specify column names for x, y, and optional ySigma.
Optional Description
-pipe Use input/output pipes instead of files.
-fulloutput Include detailed results in the output.
-tolerance Set convergence tolerance for the fitting algorithm.
-verbosity Define verbosity level for logging.
-clue Provide a hint for exponential behavior.
-guess Initial guesses for parameters a0, a1, a2.
-startValues Set specific starting values for fit parameters.
-fixValue Fix certain fit parameters during optimization.
-autoOffset Automatically adjust offset for input data.
-limits Set algorithm limits (e.g., evaluations, passes).
-majorOrder Specify data processing order (row or column).

Incompatibilities

  • -guess is incompatible with:
    • -startValues
  • -fixValue and -startValues cannot be applied to the same parameter simultaneously.
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, L. Emery, R. Soliday, H. Shang, N. Kuklev

Definition in file sddsexpfit.c.

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

Go to the source code of this file.

Functions

double fitFunction (double *a, long *invalid)
 
void report (double res, double *a, long pass, long n_eval, long n_dimen)
 
void setupOutputFile (SDDS_DATASET *OutputTable, long *xIndex, long *yIndex, long *fitIndex, long *residualIndex, char *output, long fullOutput, SDDS_DATASET *InputTable, char *xName, char *yName, short columnMajorOrder)
 
char * makeInverseUnits (char *units)
 
int main (int argc, char **argv)
 

Function Documentation

◆ fitFunction()

double fitFunction ( double * a,
long * invalid )

Definition at line 512 of file sddsexpfit.c.

512 {
513 int64_t i;
514 double chi = 0.0, diff;
515 static double min_chi;
516
517 min_chi = DBL_MAX;
518
519 *invalid = 0;
520 for (i = 0; i < nData; i++) {
521 diff = yData[i] - (a[0] + a[1] * exp(a[2] * xData[i]));
522 if (syData)
523 diff /= syData[i];
524 chi += sqr(diff);
525 }
526 if (isnan(chi) || isinf(chi))
527 *invalid = 1;
528 if (verbosity > 3)
529 fprintf(stderr, "trial: a = %e, %e, %e --> chi = %e, invalid = %ld\n", a[0], a[1], a[2], chi, *invalid);
530 if (min_chi > chi) {
531 min_chi = chi;
532 fit[0] = a[0];
533 fit[1] = a[1];
534 fit[2] = a[2];
535 if (verbosity > 2)
536 fprintf(stderr, "new best chi = %e: a = %e, %e, %e\n", chi, fit[0], fit[1], fit[2]);
537 }
538 return chi;
539}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 146 of file sddsexpfit.c.

146 {
147 double tolerance, result, chiSqr, sigLevel;
148 int32_t nEvalMax = 5000, nPassMax = 100;
149 double guess[3];
150 double a[3], da[3];
151 double alo[3], ahi[3];
152 long n_dimen = 3, guessGiven, startGiven;
153 SDDS_DATASET InputTable, OutputTable;
154 SCANNED_ARG *s_arg;
155 long i_arg, clue, fullOutput;
156 int64_t i;
157 char *input, *output, *xName, *yName, *syName;
158 long xIndex, yIndex, fitIndex, residualIndex, retval;
159 double *fitData, *residualData, rmsResidual;
160 unsigned long guessFlags, pipeFlags, dummyFlags, majorOrderFlag;
161 double constantStart, factorStart, rateStart;
162 short disable[3] = {0, 0, 0};
163 short autoOffset = 0;
164 short columnMajorOrder = -1;
165
167 argc = scanargs(&s_arg, argc, argv);
168 if (argc < 2 || argc > (2 + N_OPTIONS))
169 bomb(NULL, USAGE);
170
171 input = output = NULL;
172 tolerance = 1e-6;
173 verbosity = fullOutput = guessGiven = startGiven = 0;
174 clue = -1;
175 xName = yName = syName = NULL;
176 pipeFlags = guessFlags = 0;
177 constantStart = factorStart = rateStart = 0;
178
179 for (i_arg = 1; i_arg < argc; i_arg++) {
180 if (s_arg[i_arg].arg_type == OPTION) {
181 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
182 case SET_MAJOR_ORDER:
183 majorOrderFlag = 0;
184 s_arg[i_arg].n_items--;
185 if (s_arg[i_arg].n_items > 0 && (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
186 SDDS_Bomb("invalid -majorOrder syntax/values");
187 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
188 columnMajorOrder = 1;
189 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
190 columnMajorOrder = 0;
191 break;
192 case SET_AUTOOFFSET:
193 autoOffset = 1;
194 break;
195 case SET_TOLERANCE:
196 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%lf", &tolerance) != 1)
197 SDDS_Bomb("incorrect -tolerance syntax");
198 break;
199 case SET_VERBOSITY:
200 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &verbosity) != 1)
201 SDDS_Bomb("incorrect -verbosity syntax");
202 break;
203 case SET_CLUE:
204 if (s_arg[i_arg].n_items != 2 || (clue = match_string(s_arg[i_arg].list[1], clue_name, N_CLUE_TYPES, 0)) < 0)
205 SDDS_Bomb("incorrect -clue syntax");
206 break;
207 case SET_GUESS:
208 if (startGiven)
209 SDDS_Bomb("can't have -startValues and -guess at once");
210 if (s_arg[i_arg].n_items != 4 || sscanf(s_arg[i_arg].list[1], "%lf", guess + 0) != 1 || sscanf(s_arg[i_arg].list[2], "%lf", guess + 1) != 1 || sscanf(s_arg[i_arg].list[3], "%lf", guess + 2) != 1)
211 SDDS_Bomb("invalid -guess syntax");
212 guessGiven = 1;
213 break;
214 case SET_STARTVALUES:
215 if (s_arg[i_arg].n_items < 2)
216 SDDS_Bomb("incorrect -startValues syntax");
217 if (guessGiven)
218 SDDS_Bomb("can't have -startValues and -guess at once");
219 s_arg[i_arg].n_items -= 1;
220 dummyFlags = guessFlags;
221 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "constant", SDDS_DOUBLE, &constantStart, 1, START_CONSTANT_GIVEN, "factor", SDDS_DOUBLE, &factorStart, 1, START_FACTOR_GIVEN, "rate", SDDS_DOUBLE, &rateStart, 1, START_RATE_GIVEN, NULL))
222 SDDS_Bomb("invalid -fixValue syntax");
223 if ((dummyFlags >> 3) & (guessFlags))
224 SDDS_Bomb("can't have -fixValue and -startValue for the same item");
225 guessFlags |= dummyFlags;
226 startGiven = 1;
227 break;
228 case SET_FIXVALUE:
229 if (s_arg[i_arg].n_items < 2)
230 SDDS_Bomb("incorrect -fixValue syntax");
231 s_arg[i_arg].n_items -= 1;
232 dummyFlags = guessFlags;
233 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "constant", SDDS_DOUBLE, &constantStart, 1, FIX_CONSTANT_GIVEN, "factor", SDDS_DOUBLE, &factorStart, 1, FIX_FACTOR_GIVEN, "rate", SDDS_DOUBLE, &rateStart, 1, FIX_RATE_GIVEN, NULL))
234 SDDS_Bomb("invalid -fixValue syntax");
235 if ((dummyFlags) & (guessFlags >> 3))
236 SDDS_Bomb("can't have -fixValue and -startValue for the same item");
237 guessFlags |= dummyFlags;
238 break;
239 case SET_COLUMNS:
240 if (s_arg[i_arg].n_items != 3 && s_arg[i_arg].n_items != 4)
241 SDDS_Bomb("invalid -columns syntax");
242 xName = s_arg[i_arg].list[1];
243 yName = s_arg[i_arg].list[2];
244 s_arg[i_arg].n_items -= 3;
245 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0, "ysigma", SDDS_STRING, &syName, 1, 0, NULL))
246 SDDS_Bomb("invalid -columns syntax");
247 break;
248 case SET_FULLOUTPUT:
249 fullOutput = 1;
250 break;
251 case SET_PIPE:
252 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
253 SDDS_Bomb("invalid -pipe syntax");
254 break;
255 case SET_LIMITS:
256 if (s_arg[i_arg].n_items < 2)
257 SDDS_Bomb("incorrect -limits syntax");
258 s_arg[i_arg].n_items -= 1;
259 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0, "evaluations", SDDS_LONG, &nEvalMax, 1, 0, "passes", SDDS_LONG, &nPassMax, 1, 0, NULL) || nEvalMax <= 0 || nPassMax <= 0)
260 SDDS_Bomb("invalid -limits syntax");
261 break;
262 default:
263 fprintf(stderr, "error: unknown/ambiguous option: %s\n", s_arg[i_arg].list[0]);
264 exit(EXIT_FAILURE);
265 break;
266 }
267 } else {
268 if (input == NULL)
269 input = s_arg[i_arg].list[0];
270 else if (output == NULL)
271 output = s_arg[i_arg].list[0];
272 else
273 SDDS_Bomb("too many filenames");
274 }
275 }
276
277 processFilenames("sddsexpfit", &input, &output, pipeFlags, 0, NULL);
278
279 for (i = 0; i < 3; i++) {
280 if ((guessFlags >> 3) & (1 << i)) {
281 disable[i] = 1;
282 }
283 }
284
285 if (!xName || !yName)
286 SDDS_Bomb("-columns option must be given");
287
288 if (!SDDS_InitializeInput(&InputTable, input) || SDDS_GetColumnIndex(&InputTable, xName) < 0 ||
289 SDDS_GetColumnIndex(&InputTable, yName) < 0 || (syName && SDDS_GetColumnIndex(&InputTable, syName) < 0))
290 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
291
292 setupOutputFile(&OutputTable, &xIndex, &yIndex, &fitIndex, &residualIndex, output, fullOutput, &InputTable, xName, yName, columnMajorOrder);
293
294 while ((retval = SDDS_ReadPage(&InputTable)) > 0) {
295 fitData = residualData = NULL;
296 xData = yData = syData = NULL;
297 if (!(xData = SDDS_GetColumnInDoubles(&InputTable, xName)) ||
298 !(yData = SDDS_GetColumnInDoubles(&InputTable, yName)) ||
299 (syName && !(syData = SDDS_GetColumnInDoubles(&InputTable, syName))))
300 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
301 if ((nData = SDDS_CountRowsOfInterest(&InputTable)) < 4)
302 continue;
303
304 if (xData[0] > xData[nData - 1])
305 fputs("warning: data reverse-ordered", stderr);
306
307 find_min_max(&yMin, &yMax, yData, nData);
308 find_min_max(&xMin, &xMax, xData, nData);
309 for (i = 0; i < nData; i++)
310 xData[i] -= xMin;
311
312 fill_double_array(alo, 3, -DBL_MAX / 2);
313 fill_double_array(ahi, 3, DBL_MAX / 2);
314
315 if (!guessGiven) {
316 if (clue == CLUE_GROWS) {
317 a[0] = 0.9 * yData[0];
318 a[1] = yData[nData - 1] - yData[0];
319 a[2] = 1 / (xData[nData - 1] - xData[0]);
320 alo[2] = 0;
321 if (a[1] > 0)
322 alo[1] = 0;
323 else
324 ahi[1] = 0;
325 } else if (clue == CLUE_DECAYS) {
326 a[0] = 0.9 * yData[nData - 1];
327 a[1] = yData[0] - yData[nData - 1];
328 a[2] = 0;
329 ahi[2] = 0;
330 if (a[1] > 0)
331 alo[1] = 0;
332 else
333 ahi[1] = 0;
334 } else {
335 a[0] = yMin * 0.9;
336 a[1] = yMax - yMin;
337 a[2] = 0;
338 }
339 } else {
340 a[0] = guess[0];
341 a[1] = guess[1];
342 a[2] = guess[2];
343 }
344
345 if (guessFlags & (START_CONSTANT_GIVEN + FIX_CONSTANT_GIVEN))
346 a[0] = constantStart;
347 if (guessFlags & (START_FACTOR_GIVEN + FIX_FACTOR_GIVEN))
348 a[1] = factorStart;
349 if (guessFlags & (START_RATE_GIVEN + FIX_RATE_GIVEN))
350 a[2] = rateStart;
351
352 da[0] = da[1] = fabs(a[1] - a[0]) / 20.0;
353 da[2] = 0.1 / (xData[nData - 1] - xData[0]);
354 if (verbosity > 3)
355 fprintf(stderr, "starting guess: %e, %e, %e\n", a[0], a[1], a[2]);
356
357 simplexMin(&result, a, da, alo, ahi, disable, n_dimen, -DBL_MAX, tolerance, fitFunction, (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, 0);
358
359 da[0] = a[0] / 10;
360 da[1] = a[1] / 10;
361 da[2] = a[2] / 10;
362 simplexMin(&result, a, da, alo, ahi, disable, n_dimen, -DBL_MAX, tolerance, fitFunction, (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, 0);
363
364 if (!autoOffset) {
365 /* user wants the coefficients with the offset removed */
366 a[1] *= exp(-a[2] * xMin);
367 for (i = 0; i < nData; i++)
368 xData[i] += xMin;
369 }
370
371 fitData = trealloc(fitData, sizeof(*fitData) * nData);
372 residualData = trealloc(residualData, sizeof(*residualData) * nData);
373 for (i = result = 0; i < nData; i++) {
374 fitData[i] = a[0] + a[1] * exp(a[2] * xData[i]);
375 residualData[i] = yData[i] - fitData[i];
376 result += sqr(residualData[i]);
377 }
378 rmsResidual = sqrt(result / nData);
379 if (syData) {
380 for (i = chiSqr = 0; i < nData; i++)
381 chiSqr += sqr(residualData[i] / syData[i]);
382 } else {
383 double sy2;
384 sy2 = result / (nData - 3);
385 for (i = chiSqr = 0; i < nData; i++)
386 chiSqr += sqr(residualData[i]) / sy2;
387 }
388 sigLevel = ChiSqrSigLevel(chiSqr, nData - 3);
389 if (verbosity > 1) {
390 fprintf(stderr, "RMS deviation: %.15e\n", rmsResidual);
391 fprintf(stderr, "(RMS deviation)/(largest value): %.15e\n", rmsResidual / MAX(fabs(yMin), fabs(yMax)));
392 if (syData)
393 fprintf(stderr, "Significance level: %.5e\n", sigLevel);
394 }
395 if (verbosity > 0) {
396 fprintf(stderr, "coefficients of fit to the form y = a0 + a1*exp(a2*x), a = \n");
397 for (i = 0; i < 3; i++)
398 fprintf(stderr, "%.8e ", a[i]);
399 fprintf(stderr, "\n");
400 }
401
402 if (!SDDS_StartPage(&OutputTable, nData) ||
403 !SDDS_CopyParameters(&OutputTable, &InputTable) ||
404 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, xData, nData, xIndex) ||
405 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, fitData, nData, fitIndex) ||
406 !SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
407 "expfitConstant", a[0],
408 "expfitFactor", a[1],
409 "expfitRate", a[2],
410 "expfitRmsResidual", rmsResidual,
411 "expfitSigLevel", sigLevel, NULL) ||
412 (fullOutput && (!SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yData, nData, yIndex) ||
413 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, residualData, nData, residualIndex))) ||
414 !SDDS_WritePage(&OutputTable))
415 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
416 if (xData)
417 free(xData);
418 if (yData)
419 free(yData);
420 if (syData)
421 free(syData);
422 if (fitData)
423 free(fitData);
424 if (residualData)
425 free(residualData);
426 }
427 if (!SDDS_Terminate(&InputTable) || !SDDS_Terminate(&OutputTable)) {
428 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
429 exit(EXIT_FAILURE);
430 }
431 return EXIT_SUCCESS;
432}
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.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
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
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
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
void fill_double_array(double *array, long n, double value)
Fills a double array with the specified value.
Definition fill_array.c:27
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
Definition findMinMax.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
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

◆ makeInverseUnits()

char * makeInverseUnits ( char * units)

Definition at line 490 of file sddsexpfit.c.

490 {
491 char *inverseUnits;
492
493 if (!units || SDDS_StringIsBlank(units))
494 return NULL;
495 inverseUnits = tmalloc(sizeof(*inverseUnits) * (strlen(units) + 5));
496
497 if (strncmp(units, "1/(", 3) == 0 && units[strlen(units) - 1] == ')') {
498 /* special case of "1/(<unit>)" */
499 strcpy(inverseUnits, units + 3);
500 inverseUnits[strlen(inverseUnits) - 1] = '\0';
501 } else if (!strchr(units, ' ')) {
502 /* special case of units string without spaces */
503 sprintf(inverseUnits, "1/%s", units);
504 } else {
505 /* general case */
506 sprintf(inverseUnits, "1/(%s)", units);
507 }
508
509 return inverseUnits;
510}
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59

◆ report()

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

Definition at line 541 of file sddsexpfit.c.

541 {
542 long i;
543
544 fprintf(stderr, "Pass %ld, after %ld evaluations: result = %.16e\na = ", pass, nEval, y);
545 for (i = 0; i < n_dimen; i++)
546 fprintf(stderr, "%.8e ", x[i]);
547 fputc('\n', stderr);
548}

◆ setupOutputFile()

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

Definition at line 434 of file sddsexpfit.c.

434 {
435 char *name, *yUnits, *description, *xUnits, *inverse_xUnits;
436 int32_t typeValue = SDDS_DOUBLE;
437 static char *residualNamePart = "Residual";
438 static char *residualDescriptionPart = "Residual of exponential fit to ";
439
440 if (!SDDS_InitializeOutput(OutputTable, SDDS_BINARY, 0, NULL, "sddsexpfit output", output) ||
441 !SDDS_TransferColumnDefinition(OutputTable, InputTable, xName, NULL) ||
442 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, xName) ||
443 (*xIndex = SDDS_GetColumnIndex(OutputTable, xName)) < 0 ||
444 !SDDS_GetColumnInformation(InputTable, "units", &xUnits, SDDS_BY_NAME, xName) ||
445 !SDDS_GetColumnInformation(InputTable, "units", &yUnits, SDDS_BY_NAME, yName)) {
446 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
447 exit(EXIT_FAILURE);
448 }
449
450 if (columnMajorOrder != -1)
451 OutputTable->layout.data_mode.column_major = columnMajorOrder;
452 else
453 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
454
455 name = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
456 description = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualDescriptionPart) + 1));
457
458 if (fullOutput) {
459 if (!SDDS_TransferColumnDefinition(OutputTable, InputTable, yName, NULL) ||
460 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, yName) ||
461 (*yIndex = SDDS_GetColumnIndex(OutputTable, yName)) < 0)
462 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
463 sprintf(name, "%s%s", yName, residualNamePart);
464 sprintf(description, "%s%s", yName, residualDescriptionPart);
465 if ((*residualIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
466 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
467 }
468
469 sprintf(name, "%sFit", yName);
470 sprintf(description, "Exponential fit to %s", yName);
471 if ((*fitIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
472 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
473
474 inverse_xUnits = makeInverseUnits(xUnits);
475
476 if (SDDS_DefineParameter(OutputTable, "expfitConstant", NULL, yUnits, "Constant term from exponential fit",
477 NULL, SDDS_DOUBLE, 0) < 0 ||
478 SDDS_DefineParameter(OutputTable, "expfitFactor", NULL, yUnits, "Factor from exponential fit",
479 NULL, SDDS_DOUBLE, 0) < 0 ||
480 SDDS_DefineParameter(OutputTable, "expfitRate", NULL, inverse_xUnits, "Rate from exponential fit",
481 NULL, SDDS_DOUBLE, 0) < 0 ||
482 SDDS_DefineParameter(OutputTable, "expfitRmsResidual", NULL, yUnits, "RMS residual from exponential fit",
483 NULL, SDDS_DOUBLE, 0) < 0 ||
484 SDDS_DefineParameter(OutputTable, "expfitSigLevel", NULL, NULL, "Significance level from chi-squared test", NULL, SDDS_DOUBLE, 0) < 0 ||
485 !SDDS_TransferAllParameterDefinitions(OutputTable, InputTable, SDDS_TRANSFER_KEEPOLD) ||
486 !SDDS_WriteLayout(OutputTable))
487 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
488}
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.