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

Detailed Description

Performs a sinusoidal fit on input data.

This program reads input data from an SDDS (Self Describing Data Sets) file, fits the data to one of two sinusoidal models:

\[
    y(n) = a_0 + a_1 \sin(2\pi a_2 x(n) + a_3)
    \]

or

\[
    y(n) = a_0 + a_1 \sin(2\pi a_2 x(n) + a_3) + a_4 x(n)
    \]

Based on user-provided parameters and options, the program performs fitting and outputs the fitted data along with residuals to an output SDDS file.

Usage

sddssinefit [<inputfile>] [<outputfile>]
[-pipe=<input>[,<output>]]
[-fulloutput]
-columns=<x-name>,<y-name>
[-tolerance=<value>]
[-limits=evaluations=<number>,passes=<number>]
[-verbosity=<integer>]
[-guess=constant=<constant>,factor=<factor>,frequency=<freq>,phase=<phase>,slope=<slope>]
[-lockFrequency]
[-addSlope]
[-majorOrder=row|column]

Options

Required Description
-columns Specifies the x and y data column names.
Optional Description
-pipe Use standard input/output for data streams.
-fulloutput Includes full output with residuals.
-tolerance Sets the tolerance for the fitting algorithm (default: 1e-6).
-limits=evaluations Sets maximum number of evaluations and passes (default: 5000 evaluations, 25 passes).
-verbosity Sets verbosity level (default: 0).
-guess Provides initial guesses for fit parameters.
-lockFrequency Locks the frequency parameter during fitting.
-addSlope Includes a slope term in the fit.
-majorOrder Specifies the major order for data processing.

Incompatibilities

  • -lockFrequency cannot be used with -guess=frequency=<freq>.

Requirements

  • For -guess, at least one of the guess parameters (constant, factor, frequency, phase, slope) is required.
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, L. Emery, H. Shang, N. Kuklev

Definition in file sddssinefit.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)
 
double fitFunctionWithSlope (double *a, long *invalid)
 
void report (double res, double *a, long pass, long n_eval, long n_dimen)
 
void setupOutputFile (SDDS_DATASET *OutputTable, int32_t *xIndex, int32_t *yIndex, int32_t *fitIndex, int32_t *residualIndex, char *output, long fullOutput, SDDS_DATASET *InputTable, char *xName, char *yName, short columnMajorOrder, short addSlope)
 
char * makeInverseUnits (char *units)
 
int main (int argc, char **argv)
 

Function Documentation

◆ fitFunction()

double fitFunction ( double * a,
long * invalid )

Definition at line 516 of file sddssinefit.c.

516 {
517 int64_t i;
518 double chi;
519 static double min_chi;
520
521 min_chi = DBL_MAX;
522
523 *invalid = 0;
524 for (i = chi = 0; i < nData; i++)
525 chi += sqr(yData[i] - (a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3])));
526 if (isnan(chi) || isinf(chi))
527 *invalid = 1;
528 if (verbosity > 3)
529 fprintf(stderr, "Trial: a = %e, %e, %e, %e --> chi = %e, invalid = %ld\n", a[0], a[1], a[2], a[3], 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 fit[3] = a[3];
536 if (verbosity > 2)
537 fprintf(stderr, "New best chi = %e: a = %e, %e, %e, %e\n", chi, fit[0], fit[1], fit[2], fit[3]);
538 }
539 return chi;
540}

◆ fitFunctionWithSlope()

double fitFunctionWithSlope ( double * a,
long * invalid )

Definition at line 542 of file sddssinefit.c.

542 {
543 int64_t i;
544 double chi;
545 static double min_chi;
546
547 min_chi = DBL_MAX;
548
549 *invalid = 0;
550 for (i = chi = 0; i < nData; i++)
551 chi += sqr(yData[i] - (a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3]) + a[4] * xData[i]));
552 if (isnan(chi) || isinf(chi))
553 *invalid = 1;
554 if (verbosity > 3)
555 fprintf(stderr, "Trial: a = %e, %e, %e, %e, %e --> chi = %e, invalid = %ld\n",
556 a[0], a[1], a[2], a[3], a[4], chi, *invalid);
557 if (min_chi > chi) {
558 min_chi = chi;
559 fit[0] = a[0];
560 fit[1] = a[1];
561 fit[2] = a[2];
562 fit[3] = a[3];
563 fit[4] = a[4];
564 if (verbosity > 2)
565 fprintf(stderr, "New best chi = %e: a = %e, %e, %e, %e, %e\n",
566 chi, fit[0], fit[1], fit[2], fit[3], fit[4]);
567 }
568 return chi;
569}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 161 of file sddssinefit.c.

161 {
162 double tolerance, result;
163 int32_t nEvalMax = 5000, nPassMax = 25;
164 double a[5], da[5];
165 double alo[5], ahi[5];
166 long n_dimen = 4;
167 int64_t zeroes;
168 SDDS_DATASET InputTable, OutputTable;
169 SCANNED_ARG *s_arg;
170 long i_arg, fullOutput;
171 int64_t i;
172 char *input, *output, *xName, *yName;
173 int32_t xIndex, yIndex, fitIndex, residualIndex;
174 long retval;
175 double *fitData, *residualData, rmsResidual;
176 unsigned long guessFlags, dummyFlags, pipeFlags;
177 double constantGuess, factorGuess, freqGuess, phaseGuess, slopeGuess;
178 double firstZero, lastZero;
179 unsigned long simplexFlags = 0, majorOrderFlag;
180 short columnMajorOrder = -1;
181 short lockFreq = 0;
182 short addSlope = 0;
183
185 argc = scanargs(&s_arg, argc, argv);
186 if (argc < 2 || argc > (2 + N_OPTIONS))
187 bomb(NULL, USAGE);
188
189 input = output = NULL;
190 tolerance = 1e-6;
191 verbosity = fullOutput = 0;
192 xName = yName = NULL;
193 guessFlags = 0;
194 pipeFlags = 0;
195
196 for (i_arg = 1; i_arg < argc; i_arg++) {
197 if (s_arg[i_arg].arg_type == OPTION) {
198 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
199 case SET_MAJOR_ORDER:
200 majorOrderFlag = 0;
201 s_arg[i_arg].n_items--;
202 if (s_arg[i_arg].n_items > 0 &&
203 (!scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
204 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
205 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
206 SDDS_Bomb("invalid -majorOrder syntax/values");
207 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
208 columnMajorOrder = 1;
209 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
210 columnMajorOrder = 0;
211 break;
212 case SET_TOLERANCE:
213 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%lf", &tolerance) != 1)
214 SDDS_Bomb("incorrect -tolerance syntax");
215 break;
216 case SET_VERBOSITY:
217 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &verbosity) != 1)
218 SDDS_Bomb("incorrect -verbosity syntax");
219 break;
220 case SET_GUESS:
221 if (s_arg[i_arg].n_items < 2)
222 SDDS_Bomb("incorrect -guess syntax");
223 s_arg[i_arg].n_items -= 1;
224 if (!scanItemList(&guessFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
225 "constant", SDDS_DOUBLE, &constantGuess, 1, GUESS_CONSTANT_GIVEN,
226 "factor", SDDS_DOUBLE, &factorGuess, 1, GUESS_FACTOR_GIVEN,
227 "frequency", SDDS_DOUBLE, &freqGuess, 1, GUESS_FREQ_GIVEN,
228 "phase", SDDS_DOUBLE, &phaseGuess, 1, GUESS_PHASE_GIVEN,
229 "slope", SDDS_DOUBLE, &slopeGuess, 1, GUESS_SLOPE_GIVEN, NULL))
230 SDDS_Bomb("invalid -guess syntax");
231 break;
232 case SET_COLUMNS:
233 if (s_arg[i_arg].n_items != 3)
234 SDDS_Bomb("invalid -columns syntax");
235 xName = s_arg[i_arg].list[1];
236 yName = s_arg[i_arg].list[2];
237 break;
238 case SET_FULLOUTPUT:
239 fullOutput = 1;
240 break;
241 case SET_LOCK_FREQ:
242 lockFreq = 1;
243 break;
244 case SET_ADD_SLOPE:
245 addSlope = 1;
246 n_dimen = 5;
247 break;
248 case SET_LIMITS:
249 if (s_arg[i_arg].n_items < 2)
250 SDDS_Bomb("incorrect -limits syntax");
251 s_arg[i_arg].n_items -= 1;
252 if (!scanItemList(&dummyFlags, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
253 "evaluations", SDDS_LONG, &nEvalMax, 1, 0,
254 "passes", SDDS_LONG, &nPassMax, 1, 0, NULL) ||
255 nEvalMax <= 0 || nPassMax <= 0)
256 SDDS_Bomb("invalid -limits syntax");
257 break;
258 case SET_PIPE:
259 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
260 SDDS_Bomb("invalid -pipe syntax");
261 break;
262 default:
263 fprintf(stderr, "Error: Unknown or 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 provided.");
274 }
275 }
276
277 processFilenames("sddssinefit", &input, &output, pipeFlags, 0, NULL);
278
279 if (!xName || !yName)
280 SDDS_Bomb("-columns option must be specified.");
281
282 if (!SDDS_InitializeInput(&InputTable, input) ||
283 SDDS_GetColumnIndex(&InputTable, xName) < 0 ||
284 SDDS_GetColumnIndex(&InputTable, yName) < 0)
285 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
286
287 setupOutputFile(&OutputTable, &xIndex, &yIndex, &fitIndex, &residualIndex, output, fullOutput,
288 &InputTable, xName, yName, columnMajorOrder, addSlope);
289
290 fitData = residualData = NULL;
291
292 alo[0] = -(ahi[0] = DBL_MAX);
293 alo[1] = alo[2] = 0;
294 ahi[1] = ahi[2] = DBL_MAX;
295 alo[3] = -(ahi[3] = PIx2);
296 if (addSlope) {
297 alo[4] = -(ahi[4] = DBL_MAX);
298 }
299 firstZero = lastZero = 0;
300 while ((retval = SDDS_ReadPage(&InputTable)) > 0) {
301 if (!(xData = SDDS_GetColumnInDoubles(&InputTable, xName)) ||
302 !(yData = SDDS_GetColumnInDoubles(&InputTable, yName)))
303 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
304 if ((nData = SDDS_CountRowsOfInterest(&InputTable)) < 4)
305 continue;
306
307 find_min_max(&yMin, &yMax, yData, nData);
308 find_min_max(&xMin, &xMax, xData, nData);
309 zeroes = 0;
310 for (i = 1; i < nData; i++)
311 if (yData[i] * yData[i - 1] <= 0) {
312 i++;
313 if (!zeroes)
314 firstZero = (xData[i] + xData[i - 1]) / 2;
315 else
316 lastZero = (xData[i] + xData[i - 1]) / 2;
317 zeroes++;
318 }
319 a[0] = (yMin + yMax) / 2;
320 a[1] = (yMax - yMin) / 2;
321 if (!zeroes)
322 a[2] = 2 / fabs(xMax - xMin);
323 else
324 a[2] = zeroes / (2 * fabs(lastZero - firstZero));
325 a[3] = 0;
326 if (addSlope) {
327 a[4] = 0;
328 }
329 if (guessFlags & GUESS_CONSTANT_GIVEN)
330 a[0] = constantGuess;
331 if (guessFlags & GUESS_FACTOR_GIVEN)
332 a[1] = factorGuess;
333 if (guessFlags & GUESS_FREQ_GIVEN)
334 a[2] = freqGuess;
335 if (guessFlags & GUESS_PHASE_GIVEN)
336 a[3] = phaseGuess;
337 if (guessFlags & GUESS_SLOPE_GIVEN)
338 a[4] = slopeGuess;
339
340 alo[1] = a[1] / 2;
341 if (!(da[0] = a[0] * 0.1))
342 da[0] = 0.01;
343 if (!(da[1] = a[1] * 0.1))
344 da[1] = 0.01;
345 da[2] = a[2] * 0.25;
346 da[3] = 0.01;
347 if (addSlope) {
348 da[4] = 0.01;
349 }
350
351 if (lockFreq) {
352 alo[2] = ahi[2] = a[2];
353 da[2] = 0;
354 }
355
356 if (addSlope) {
357 simplexMin(&result, a, da, alo, ahi, NULL, n_dimen, -DBL_MAX, tolerance, fitFunctionWithSlope,
358 (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, simplexFlags);
359 } else {
360 simplexMin(&result, a, da, alo, ahi, NULL, n_dimen, -DBL_MAX, tolerance, fitFunction,
361 (verbosity > 0 ? report : NULL), nEvalMax, nPassMax, 12, 3, 1.0, simplexFlags);
362 }
363 fitData = trealloc(fitData, sizeof(*fitData) * nData);
364 residualData = trealloc(residualData, sizeof(*residualData) * nData);
365 if (addSlope) {
366 for (i = result = 0; i < nData; i++) {
367 fitData[i] = a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3]) + a[4] * xData[i];
368 residualData[i] = yData[i] - fitData[i];
369 result += sqr(residualData[i]);
370 }
371 } else {
372 for (i = result = 0; i < nData; i++) {
373 fitData[i] = a[0] + a[1] * sin(PIx2 * a[2] * xData[i] + a[3]);
374 residualData[i] = yData[i] - fitData[i];
375 result += sqr(residualData[i]);
376 }
377 }
378 rmsResidual = sqrt(result / nData);
379 if (verbosity > 1) {
380 fprintf(stderr, "RMS deviation: %.15e\n", rmsResidual);
381 fprintf(stderr, "(RMS deviation)/(largest value): %.15e\n", rmsResidual / MAX(fabs(yMin), fabs(yMax)));
382 }
383 if (verbosity > 0) {
384 if (addSlope) {
385 fprintf(stderr, "Coefficients of fit to the form y = a0 + a1*sin(2*PI*a2*x + a3) + a4*x, a = \n");
386 for (i = 0; i < 5; i++)
387 fprintf(stderr, "%.8e ", a[i]);
388 } else {
389 fprintf(stderr, "Coefficients of fit to the form y = a0 + a1*sin(2*PI*a2*x + a3), a = \n");
390 for (i = 0; i < 4; i++)
391 fprintf(stderr, "%.8e ", a[i]);
392 }
393 fprintf(stderr, "\n");
394 }
395
396 if (!SDDS_StartPage(&OutputTable, nData) ||
397 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, xData, nData, xIndex) ||
398 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, fitData, nData, fitIndex) ||
399 !SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
400 "sinefitConstant", a[0],
401 "sinefitFactor", a[1],
402 "sinefitFrequency", a[2],
403 "sinefitPhase", a[3],
404 "sinefitRmsResidual", rmsResidual,
405 NULL) ||
406 (addSlope &&
407 (!SDDS_SetParameters(&OutputTable, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME,
408 "sinefitSlope", a[4], NULL))) ||
409 (fullOutput && (!SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, yData, nData, yIndex) ||
410 !SDDS_SetColumn(&OutputTable, SDDS_SET_BY_INDEX, residualData, nData, residualIndex))) ||
411 !SDDS_WritePage(&OutputTable))
412 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
413 }
414
415 if (SDDS_Terminate(&InputTable) != 1) {
416 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
417 return EXIT_FAILURE;
418 }
419 if (SDDS_Terminate(&OutputTable) != 1) {
420 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
421 return EXIT_FAILURE;
422 }
423
424 return EXIT_SUCCESS;
425}
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_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
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.
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 494 of file sddssinefit.c.

494 {
495 char *inverseUnits;
496
497 if (!units || SDDS_StringIsBlank(units))
498 return NULL;
499 inverseUnits = tmalloc(sizeof(*inverseUnits) * (strlen(units) + 5));
500
501 if (strncmp(units, "1/(", 3) == 0 && units[strlen(units) - 1] == ')') {
502 /* Special case of "1/(<unit>)" */
503 strcpy(inverseUnits, units + 3);
504 inverseUnits[strlen(inverseUnits) - 1] = '\0';
505 } else if (!strchr(units, ' ')) {
506 /* Special case of units string without spaces */
507 sprintf(inverseUnits, "1/%s", units);
508 } else {
509 /* General case */
510 sprintf(inverseUnits, "1/(%s)", units);
511 }
512
513 return inverseUnits;
514}
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 571 of file sddssinefit.c.

571 {
572 long i;
573
574 fprintf(stderr, "Pass %ld, after %ld evaluations: result = %.16e\n", pass, nEval, y);
575 fprintf(stderr, "a = ");
576 for (i = 0; i < n_dimen; i++)
577 fprintf(stderr, "%.8e ", x[i]);
578 fputc('\n', stderr);
579}

◆ setupOutputFile()

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

Definition at line 427 of file sddssinefit.c.

429 {
430 char *name, *yUnits, *description, *xUnits, *inverse_xUnits;
431 int32_t typeValue = SDDS_DOUBLE;
432 static char *residualNamePart = "Residual";
433 static char *residualDescriptionPart = "Residual of sinusoidal fit to ";
434
435 if (!SDDS_InitializeOutput(OutputTable, SDDS_BINARY, 0, NULL, "sddssinefit output", output) ||
436 !SDDS_TransferColumnDefinition(OutputTable, InputTable, xName, NULL) ||
437 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, xName) ||
438 (*xIndex = SDDS_GetColumnIndex(OutputTable, xName)) < 0 ||
439 !SDDS_GetColumnInformation(InputTable, "units", &xUnits, SDDS_BY_NAME, xName) ||
440 !SDDS_GetColumnInformation(InputTable, "units", &yUnits, SDDS_BY_NAME, yName)) {
441 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
442 exit(EXIT_FAILURE);
443 }
444 if (columnMajorOrder != -1)
445 OutputTable->layout.data_mode.column_major = columnMajorOrder;
446 else
447 OutputTable->layout.data_mode.column_major = InputTable->layout.data_mode.column_major;
448
449 name = tmalloc(sizeof(*name) * (strlen(yName) + strlen(residualNamePart) + 1));
450 description = tmalloc(sizeof(*description) * (strlen(yName) + strlen(residualDescriptionPart) + 1));
451
452 if (fullOutput) {
453 if (!SDDS_TransferColumnDefinition(OutputTable, InputTable, yName, NULL) ||
454 !SDDS_ChangeColumnInformation(OutputTable, "type", &typeValue, SDDS_BY_NAME, yName) ||
455 (*yIndex = SDDS_GetColumnIndex(OutputTable, yName)) < 0)
456 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
457 sprintf(name, "%s%s", yName, residualNamePart);
458 sprintf(description, "%s%s", yName, residualDescriptionPart);
459 if ((*residualIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
460 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
461 }
462
463 sprintf(name, "%sFit", yName);
464 sprintf(description, "Sinusoidal fit to %s", yName);
465 if ((*fitIndex = SDDS_DefineColumn(OutputTable, name, NULL, yUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
466 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
467
468 inverse_xUnits = makeInverseUnits(xUnits);
469
470 if (SDDS_DefineParameter(OutputTable, "sinefitConstant", NULL, yUnits, "Constant term from sinusoidal fit",
471 NULL, SDDS_DOUBLE, 0) < 0 ||
472 SDDS_DefineParameter(OutputTable, "sinefitFactor", NULL, yUnits, "Factor from sinusoidal fit",
473 NULL, SDDS_DOUBLE, 0) < 0 ||
474 SDDS_DefineParameter(OutputTable, "sinefitFrequency", NULL, inverse_xUnits, "Frequency from sinusoidal fit",
475 NULL, SDDS_DOUBLE, 0) < 0 ||
476 SDDS_DefineParameter(OutputTable, "sinefitPhase", NULL, xUnits, "Phase from sinusoidal fit",
477 NULL, SDDS_DOUBLE, 0) < 0 ||
478 SDDS_DefineParameter(OutputTable, "sinefitRmsResidual", NULL, yUnits, "RMS residual from sinusoidal fit",
479 NULL, SDDS_DOUBLE, 0) < 0)
480 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
481
482 if (addSlope) {
483 if (SDDS_DefineParameter(OutputTable, "sinefitSlope", NULL, yUnits, "Slope term added to sinusoidal fit",
484 NULL, SDDS_DOUBLE, 0) < 0)
485 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
486 }
487 if (!SDDS_WriteLayout(OutputTable))
488 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
489
490 free(name);
491 free(description);
492}
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.