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

Detailed Description

Computes straight-line fits of numerical column data from an SDDS experiment output file.

This program reads an SDDS input file, performs linear fits on specified columns using a defined independent variable, and writes the slopes and intercepts to an output file. It supports options to generate residuals, handle sigma values for error calculations, and configure output formats and ordering.

Usage

sddsslopes [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
-independentVariable=<columnName>
[-range=<lower>,<upper>]
[-columns=<list-of-names>]
[-excludeColumns=<list-of-names>]
[-sigma[=generate][,minimum=<val>]
[-residual=<file>]
[-ascii]
[-verbose]
[-majorOrder=row|column]
[-nowarnings]

Options

Required Description
-independentVariable Specifies the independent variable column for the linear fits.
Optional Description
-pipe Read input or write output through a pipe.
-range Specifies the range of the independent variable for fitting.
-columns Comma-separated list of columns to perform fits on.
-excludeColumns Comma-separated list of columns to exclude from fitting.
-sigma Calculates errors using sigma columns or generates them.
-residual Outputs residuals of the linear fit to a specified file.
-ascii Outputs the slopes file in ASCII format (default is binary).
-verbose Enables verbose output to stderr.
-majorOrder Specifies output file ordering.
-nowarnings Suppresses warning messages.

Incompatibilities

  • For -sigma:
    • generate and minimum=<val> cannot be used together.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
L. Emery, M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddsslopes.c.

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

Go to the source code of this file.

Functions

long set_multicolumn_flags (SDDS_TABLE *SDDSin, char ***column, int32_t *columns, char **exclude, long excludes)
 
int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 141 of file sddsslopes.c.

141 {
142 SCANNED_ARG *scanned;
143 SDDS_TABLE inputPage, outputPage, residualPage;
144 char *inputfile, *outputfile;
145 char **column, **excludeColumn;
146 int32_t columns;
147 long excludeColumns;
148 char *indColumnName;
149 long verbose;
150 long iArg, ipage;
151 double *indVar, *indVarOrig;
152 char *indVarUnits;
153 char **intColumn, **slopeColumn, **slopeSigmaColumn, **interceptSigmaColumn;
154 char *Units, *slopeUnits;
155 double *depVar, *depVarOrig;
156 long order;
157 double *coef, *coefsigma, *weight, *diff, *diffOrig, chi;
158 long iCol;
159 int64_t i, j, rows, rowsOrig, iRow;
160 double rmsResidual;
161 double slopeSigma, interceptSigma;
162 char **sigmaColumn, **chiSquaredColumn;
163 long *sigmaColumnExists;
164 long doSlopeSigma, generateSigma, doPreliminaryFit;
165 int64_t validSigmas;
166 double sigmaSum, averageSigma, minSigma;
167 long ascii;
168 char *residualFile;
169 unsigned long pipeFlags;
170 long tmpfile_used, noWarnings;
171 long unsigned int majorOrderFlag;
172 double xMin, xMax;
173 short columnMajorOrder = -1;
174
175 indVar = indVarOrig = depVar = depVarOrig = coef = coefsigma = weight = diff = NULL;
176 intColumn = slopeColumn = slopeSigmaColumn = interceptSigmaColumn = sigmaColumn = chiSquaredColumn = NULL;
177 slopeUnits = NULL;
178 sigmaColumnExists = NULL;
179
181 argc = scanargs(&scanned, argc, argv);
182 if (argc == 1)
183 bomb(NULL, USAGE);
184
185 inputfile = outputfile = NULL;
186 columns = excludeColumns = 0;
187 column = excludeColumn = NULL;
188 indColumnName = NULL;
189 verbose = 0;
190 doSlopeSigma = 0;
191 generateSigma = 0;
192 minSigma = 0;
193 doPreliminaryFit = 0;
194 ascii = 0;
195 pipeFlags = 0;
196 tmpfile_used = 0;
197 noWarnings = 0;
198 residualFile = NULL;
199 xMin = xMax = 0;
200
201 for (iArg = 1; iArg < argc; iArg++) {
202 if (scanned[iArg].arg_type == OPTION) {
203 delete_chars(scanned[iArg].list[0], "_");
204 switch (match_string(scanned[iArg].list[0], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
205 case CLO_MAJOR_ORDER:
206 majorOrderFlag = 0;
207 scanned[iArg].n_items--;
208 if (scanned[iArg].n_items > 0 &&
209 (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
210 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
211 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
212 SDDS_Bomb("invalid -majorOrder syntax/values");
213 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
214 columnMajorOrder = 1;
215 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
216 columnMajorOrder = 0;
217 break;
218 case CLO_INDEPENDENT_COLUMN:
219 if (!(indColumnName = scanned[iArg].list[1]))
220 SDDS_Bomb("no string given for option -independentVariable");
221 break;
222 case CLO_COLUMNS:
223 if (columns)
224 SDDS_Bomb("only one -columns option may be given");
225 if (scanned[iArg].n_items < 2)
226 SDDS_Bomb("invalid -columns syntax");
227 column = tmalloc(sizeof(*column) * (columns = scanned[iArg].n_items - 1));
228 for (i = 0; i < columns; i++)
229 column[i] = scanned[iArg].list[i + 1];
230 break;
231 case CLO_EXCLUDE:
232 if (excludeColumns)
233 SDDS_Bomb("only one -excludecolumns option may be given");
234 if (scanned[iArg].n_items < 2)
235 SDDS_Bomb("invalid -excludecolumns syntax");
236 excludeColumn = tmalloc(sizeof(*excludeColumn) * (excludeColumns = scanned[iArg].n_items - 1));
237 for (i = 0; i < excludeColumns; i++)
238 excludeColumn[i] = scanned[iArg].list[i + 1];
239 break;
240 case CLO_VERBOSE:
241 verbose = 1;
242 break;
243 case CLO_ASCII:
244 ascii = 1;
245 break;
246 case CLO_PIPE:
247 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
248 SDDS_Bomb("invalid -pipe syntax");
249 break;
250 case CLO_SIGMA:
251 doSlopeSigma = 1;
252 if (scanned[iArg].n_items > 1) {
253 unsigned long sigmaFlags = 0;
254 scanned[iArg].n_items--;
255 if (!scanItemList(&sigmaFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
256 "generate", -1, NULL, 0, 1,
257 "minimum", SDDS_DOUBLE, &minSigma, 1, 0,
258 NULL) ||
259 minSigma < 0)
260 SDDS_Bomb("invalid -sigma syntax");
261 if (sigmaFlags & 1)
262 generateSigma = 1;
263 }
264 break;
265 case CLO_RESIDUAL:
266 if (!(residualFile = scanned[iArg].list[1])) {
267 fprintf(stderr, "No file specified in -residual option.\n");
268 exit(EXIT_FAILURE);
269 }
270 break;
271 case CLO_RANGE:
272 if (scanned[iArg].n_items != 3 ||
273 1 != sscanf(scanned[iArg].list[1], "%lf", &xMin) ||
274 1 != sscanf(scanned[iArg].list[2], "%lf", &xMax) ||
275 xMin >= xMax)
276 SDDS_Bomb("incorrect -range syntax");
277 break;
278 case CLO_NO_WARNINGS:
279 noWarnings = 1;
280 break;
281 default:
282 SDDS_Bomb("unrecognized option given");
283 break;
284 }
285 } else {
286 if (!inputfile)
287 inputfile = scanned[iArg].list[0];
288 else if (!outputfile)
289 outputfile = scanned[iArg].list[0];
290 else
291 SDDS_Bomb("too many filenames given");
292 }
293 }
294
295 if (residualFile && outputfile) {
296 if (!strcmp(residualFile, outputfile)) {
297 fprintf(stderr, "Residual file can't be the same as the output file.\n");
298 exit(EXIT_FAILURE);
299 }
300 }
301
302 processFilenames("sddsslopes", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
303
304 if (!indColumnName) {
305 fprintf(stderr, "independentVariable not given\n");
306 exit(EXIT_FAILURE);
307 }
308
309 if (!excludeColumns) {
310 excludeColumn = defaultExcludedColumn;
311 excludeColumns = DEFAULT_EXCLUDED_COLUMNS;
312 }
313
314 if (verbose)
315 fprintf(stderr, "Reading file %s.\n", inputfile);
316 if (!SDDS_InitializeInput(&inputPage, inputfile))
317 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
318 while (0 < (ipage = SDDS_ReadTable(&inputPage))) {
319 if (verbose) {
320 fprintf(stderr, "working on page %ld\n", ipage);
321 }
322 rows = SDDS_CountRowsOfInterest(&inputPage);
323 rowsOrig = rows;
324 /*************************************\
325 * make array of independent variable
326 \*************************************/
327 if (ipage == 1) {
328 indVar = (double *)malloc(sizeof(*indVar) * rows);
329 if (!indVar) {
330 fprintf(stderr, "Memory allocation failed for indVar.\n");
331 exit(EXIT_FAILURE);
332 }
333 } else {
334 indVar = (double *)realloc(indVar, sizeof(*indVar) * rows);
335 if (!indVar) {
336 fprintf(stderr, "Memory reallocation failed for indVar.\n");
337 exit(EXIT_FAILURE);
338 }
339 }
340 if (ipage == 1) {
341 if (!SDDS_FindColumn(&inputPage, FIND_NUMERIC_TYPE, indColumnName, NULL)) {
342 fprintf(stderr, "Something wrong with column %s.\n", indColumnName);
343 SDDS_CheckColumn(&inputPage, indColumnName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr);
344 exit(EXIT_FAILURE);
345 }
346 }
347 /* filter out the specified range in independent variable */
348 if (xMin != xMax) {
349 if (!(indVarOrig = SDDS_GetColumnInDoubles(&inputPage, indColumnName)))
350 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
351 for (i = j = 0; i < rowsOrig; i++) {
352 if (indVarOrig[i] <= xMax && indVarOrig[i] >= xMin) {
353 indVar[j] = indVarOrig[i];
354 j++;
355 }
356 }
357 } else {
358 if (!(indVar = SDDS_GetColumnInDoubles(&inputPage, indColumnName)))
359 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
360 }
361 if (ipage == 1) {
362 if (!SDDS_GetColumnInformation(&inputPage, "units", &indVarUnits, SDDS_GET_BY_NAME, indColumnName))
363 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
364 if (!indVarUnits) {
365 indVarUnits = (char *)malloc(sizeof(*indVarUnits));
366 indVarUnits[0] = 0;
367 }
368 }
369 /************************************\
370 * initialize residual file
371 \************************************/
372 if (residualFile) {
373 if (ipage == 1) {
374 if (!SDDS_InitializeOutput(&residualPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, "Residual of 2-term fit", NULL, outputfile) ||
375 !SDDS_InitializeCopy(&residualPage, &inputPage, residualFile, "w"))
376 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
377 if (columnMajorOrder != -1)
378 residualPage.layout.data_mode.column_major = columnMajorOrder;
379 else
380 residualPage.layout.data_mode.column_major = inputPage.layout.data_mode.column_major;
381 if (!SDDS_WriteLayout(&residualPage))
382 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
383 }
384 if (!SDDS_CopyPage(&residualPage, &inputPage))
385 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
386 }
387
388 /************************************\
389 * get columns of interest. use set_multicolumn_flags to simply
390 * return new values for array column.
391 \************************************/
392 if (!set_multicolumn_flags(&inputPage, &column, &columns, excludeColumn, excludeColumns)) {
393 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
394 exit(EXIT_FAILURE);
395 }
396 /************************************\
397 * make column names for the output
398 \************************************/
399 if (ipage == 1) {
400 intColumn = (char **)malloc((sizeof(char *) * columns));
401 slopeColumn = (char **)malloc((sizeof(char *) * columns));
402 if (doSlopeSigma) {
403 slopeSigmaColumn = (char **)malloc((sizeof(char *) * columns));
404 interceptSigmaColumn = (char **)malloc((sizeof(char *) * columns));
405 chiSquaredColumn = (char **)malloc((sizeof(char *) * columns));
406 }
407 for (i = 0; i < columns; i++) {
408 intColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("Intercept") + 1)));
409 snprintf(intColumn[i], strlen(column[i]) + strlen("Intercept") + 1, "%sIntercept", column[i]);
410
411 slopeColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("Slope") + 1)));
412 snprintf(slopeColumn[i], strlen(column[i]) + strlen("Slope") + 1, "%sSlope", column[i]);
413
414 if (doSlopeSigma) {
415 slopeSigmaColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("SlopeSigma") + 1)));
416 snprintf(slopeSigmaColumn[i], strlen(column[i]) + strlen("SlopeSigma") + 1, "%sSlopeSigma", column[i]);
417
418 interceptSigmaColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("InterceptSigma") + 1)));
419 snprintf(interceptSigmaColumn[i], strlen(column[i]) + strlen("InterceptSigma") + 1, "%sInterceptSigma", column[i]);
420
421 chiSquaredColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("ChiSquared") + 1)));
422 snprintf(chiSquaredColumn[i], strlen(column[i]) + strlen("ChiSquared") + 1, "%sChiSquared", column[i]);
423 }
424 }
425 }
426 /************************************\
427 * Write layout for output file
428 \************************************/
429 if (ipage == 1) {
430 if (verbose)
431 fprintf(stderr, "Opening file %s.\n", outputfile);
432 if (!SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, "2-term fit", NULL, outputfile) ||
433 0 > SDDS_DefineParameter(&outputPage, "InputFile", "InputFile", NULL, "InputFile", NULL, SDDS_STRING, 0) ||
434 0 > SDDS_DefineColumn(&outputPage, "IndependentVariable", NULL, NULL, NULL, NULL, SDDS_STRING, 0))
435 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
436 if (columnMajorOrder != -1)
437 outputPage.layout.data_mode.column_major = columnMajorOrder;
438 else
439 outputPage.layout.data_mode.column_major = inputPage.layout.data_mode.column_major;
440 for (iCol = 0; iCol < columns; iCol++) {
441 if (!SDDS_GetColumnInformation(&inputPage, "units", &Units, SDDS_GET_BY_NAME, column[iCol]))
442 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
443 if (!Units) {
444 Units = (char *)malloc(sizeof(*Units));
445 Units[0] = 0;
446 }
447 if (0 > SDDS_DefineColumn(&outputPage, intColumn[iCol], NULL, Units, NULL, NULL, SDDS_DOUBLE, 0))
448 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
449 /* units for slopes columns */
450 if (strlen(indVarUnits) && strlen(Units)) {
451 slopeUnits = (char *)malloc(sizeof(*slopeUnits) * (strlen(Units) + strlen(indVarUnits) + 2));
452 snprintf(slopeUnits, strlen(Units) + strlen(indVarUnits) + 2, "%s/%s", Units, indVarUnits);
453 }
454 if (strlen(indVarUnits) && !strlen(Units)) {
455 slopeUnits = (char *)malloc(sizeof(*slopeUnits) * (strlen(indVarUnits) + 2));
456 snprintf(slopeUnits, strlen(indVarUnits) + 2, "1/%s", indVarUnits);
457 }
458 if (!strlen(indVarUnits) && strlen(Units)) {
459 slopeUnits = (char *)malloc(sizeof(*slopeUnits) * (strlen(Units) + 1));
460 strcpy(slopeUnits, indVarUnits); // Fix this
461 }
462 if (!strlen(indVarUnits) && !strlen(Units)) {
463 slopeUnits = (char *)malloc(sizeof(*slopeUnits));
464 strcpy(slopeUnits, "");
465 }
466 if (0 > SDDS_DefineColumn(&outputPage, slopeColumn[iCol], NULL, slopeUnits, NULL, NULL, SDDS_DOUBLE, 0))
467 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
468 if (doSlopeSigma) {
469 if (0 > SDDS_DefineColumn(&outputPage, interceptSigmaColumn[iCol], NULL, Units, NULL, NULL, SDDS_DOUBLE, 0) ||
470 0 > SDDS_DefineColumn(&outputPage, slopeSigmaColumn[iCol], NULL, slopeUnits, NULL, NULL, SDDS_DOUBLE, 0) ||
471 0 > SDDS_DefineColumn(&outputPage, chiSquaredColumn[iCol], NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0))
472 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
473 }
474 free(slopeUnits);
475 }
476 if (!SDDS_WriteLayout(&outputPage))
477 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
478 }
479
480 if (!SDDS_StartTable(&outputPage, 1) ||
481 !SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, "InputFile", inputfile ? inputfile : "pipe", NULL) ||
482 !SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, 0, "IndependentVariable", indColumnName, NULL))
483 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
484
485 /* determine which included columns has a Sigma column defined in the input file */
486 if (ipage == 1) {
487 sigmaColumn = (char **)malloc(sizeof(*sigmaColumn) * columns);
488 sigmaColumnExists = (long *)malloc(columns * sizeof(*sigmaColumnExists));
489 for (iCol = 0; iCol < columns; iCol++) {
490 sigmaColumn[iCol] = (char *)malloc(sizeof(**sigmaColumn) * (strlen(column[iCol]) + strlen("Sigma") + 1));
491 snprintf(sigmaColumn[iCol], strlen(column[iCol]) + strlen("Sigma") + 1, "%sSigma", column[iCol]);
492 switch (SDDS_CheckColumn(&inputPage, sigmaColumn[iCol], NULL, SDDS_DOUBLE, NULL)) {
493 case SDDS_CHECK_WRONGUNITS:
494 case SDDS_CHECK_OKAY:
495 sigmaColumnExists[iCol] = 1;
496 break;
497 default:
498 /* try other possible spelling */
499 snprintf(sigmaColumn[iCol], strlen("Sigma") + strlen(column[iCol]) + 1, "Sigma%s", column[iCol]);
500 switch (SDDS_CheckColumn(&inputPage, sigmaColumn[iCol], NULL, SDDS_DOUBLE, NULL)) {
501 case SDDS_CHECK_WRONGUNITS:
502 case SDDS_CHECK_OKAY:
503 sigmaColumnExists[iCol] = 1;
504 break;
505 default:
506 sigmaColumnExists[iCol] = 0;
507 }
508 break;
509 }
510 }
511 }
512
513 if (ipage == 1) {
514 weight = (double *)malloc(sizeof(*weight) * rows);
515 diff = (double *)malloc(sizeof(*diff) * rows);
516 order = 1;
517 coef = (double *)malloc(sizeof(*coef) * (order + 1));
518 coefsigma = (double *)malloc(sizeof(*coefsigma) * (order + 1));
519 if (!weight || !diff || !coef || !coefsigma) {
520 fprintf(stderr, "Memory allocation failed.\n");
521 exit(EXIT_FAILURE);
522 }
523 } else {
524 weight = (double *)realloc(weight, sizeof(*weight) * rows);
525 diff = (double *)realloc(diff, sizeof(*diff) * rows);
526 coef = (double *)realloc(coef, sizeof(*coef) * (order + 1));
527 coefsigma = (double *)realloc(coefsigma, sizeof(*coefsigma) * (order + 1));
528 if (!weight || !diff || !coef || !coefsigma) {
529 fprintf(stderr, "Memory reallocation failed.\n");
530 exit(EXIT_FAILURE);
531 }
532 }
533
534 if (ipage == 1) {
535 depVar = (double *)malloc(sizeof(*depVar) * rows);
536 if (!depVar) {
537 fprintf(stderr, "Memory allocation failed for depVar.\n");
538 exit(EXIT_FAILURE);
539 }
540 } else {
541 depVar = (double *)realloc(depVar, sizeof(*depVar) * rows);
542 if (!depVar) {
543 fprintf(stderr, "Memory reallocation failed for depVar.\n");
544 exit(EXIT_FAILURE);
545 }
546 }
547 for (iCol = 0; iCol < columns; iCol++) {
548 if (verbose)
549 fprintf(stderr, "Doing column %s.\n", column[iCol]);
550 /* filter out the specified range in independent variable */
551 if (xMin != xMax) {
552 if (!(depVarOrig = (double *)SDDS_GetColumnInDoubles(&inputPage, column[iCol])))
553 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
554 for (i = j = 0; i < rowsOrig; i++) {
555 if (xMin <= indVarOrig[i] && indVarOrig[i] <= xMax) {
556 depVar[j] = depVarOrig[i];
557 j++;
558 }
559 }
560 rows = j;
561 } else {
562 if (!(depVar = SDDS_GetColumnInDoubles(&inputPage, column[iCol])))
563 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
564 }
565
566 /*********************
567 three possibilities:
568 1) don't do or write slope errors. (doSlopeSigma=0)
569 do one lsf call with all weights = 1
570 2) calculated slope errors from sigma columns in the input file.
571 (doSlopeSigma=1 && generateSigma=0 && sigmaColumnExists[iCol]=1 )
572 do one lsf call with weights from sigma columns
573 3) calculate slope errors from generated sigma from a preliminary fit.
574 (doSlopeSigma=1 && (generateSigma=1 || sigmaColumnExists[iCol]=NULL)
575 do preliminary fit to generate sigma
576 *********************/
577
578 for (iRow = 0; iRow < rows; iRow++)
579 weight[iRow] = 1;
580 if (doSlopeSigma) {
581 /*********************
582 check validity of sigma column values
583 *********************/
584 if (!generateSigma && sigmaColumnExists[iCol]) {
585 if (verbose)
586 fprintf(stderr, "\tUsing column %s for sigma.\n", sigmaColumn[iCol]);
587 if (!(weight = SDDS_GetColumnInDoubles(&inputPage, sigmaColumn[iCol])))
588 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
589 if (minSigma > 0) {
590 for (iRow = 0; iRow < rows; iRow++) {
591 if (weight[iRow] < minSigma)
592 weight[iRow] = minSigma;
593 }
594 }
595 /* check for zero weight values which will give lsfn problems */
596 validSigmas = rows;
597 sigmaSum = 0;
598 for (iRow = 0; iRow < rows; iRow++) {
599 sigmaSum += weight[iRow];
600 if (!weight[iRow]) {
601 validSigmas--;
602 /*
603 fprintf(stderr,"Warning: %s of row number %ld is zero. Using average sigma.\n",sigmaColumn[iCol],iRow); */
604 }
605 }
606 if (!validSigmas) {
607 if (!noWarnings)
608 fprintf(stderr, "Warning: All sigmas are zero.\n");
609 doPreliminaryFit = 1;
610 } else if (validSigmas != rows) {
611 /* fix some sigmas */
612 averageSigma = sigmaSum / validSigmas;
613 if (!noWarnings)
614 fprintf(stderr, "Warning: replacing %" PRId64 " invalid sigmas with average (%e)\n", rows - validSigmas, averageSigma);
615 for (iRow = 0; iRow < rows; iRow++) {
616 if (!weight[iRow]) {
617 weight[iRow] = averageSigma;
618 }
619 }
620 }
621 } else {
622 doPreliminaryFit = 1;
623 }
624 }
625
626 if (doPreliminaryFit) {
627 if (verbose)
628 fprintf(stderr, "\tGenerating sigmas from rms residual of a preliminary fit.\n");
629 if (!(lsfn(indVar, depVar, weight, rows, order, coef, coefsigma, &chi, diff))) {
630 fprintf(stderr, "Problem with call to lsfn\n.");
631 exit(EXIT_FAILURE);
632 }
633 rmsResidual = 0;
634 /* calculate rms residual */
635 for (iRow = 0; iRow < rows; iRow++) {
636 rmsResidual += sqr(diff[iRow]);
637 }
638 rmsResidual = sqrt(rmsResidual / (rows));
639 for (iRow = 0; iRow < rows; iRow++) {
640 weight[iRow] = rmsResidual;
641 }
642 if (minSigma > 0) {
643 for (iRow = 0; iRow < rows; iRow++) {
644 if (weight[iRow] < minSigma)
645 weight[iRow] = minSigma;
646 }
647 }
648 }
649
650 if (!(lsfn(indVar, depVar, weight, rows, order, coef, coefsigma, &chi, diff))) {
651 fprintf(stderr, "Problem with call to lsfn\n.");
652 exit(EXIT_FAILURE);
653 }
654 if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, 0,
655 intColumn[iCol], coef[0], slopeColumn[iCol], coef[1], NULL))
656 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
657 if (doSlopeSigma) {
658 interceptSigma = coefsigma[0];
659 slopeSigma = coefsigma[1];
660 if (!SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, 0,
661 chiSquaredColumn[iCol], chi, interceptSigmaColumn[iCol],
662 interceptSigma, slopeSigmaColumn[iCol], slopeSigma, NULL))
663 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
664 }
665 if (residualFile) {
666 if (xMin != xMax) {
667 /* calculate the residuals for the whole column explicitly since there
668 are points outside the range of which the lsf call did not calculate
669 the difference. */
670 diffOrig = (double *)malloc(rowsOrig * sizeof(double));
671 if (!diffOrig) {
672 fprintf(stderr, "Memory allocation failed for diffOrig.\n");
673 exit(EXIT_FAILURE);
674 }
675 for (i = 0; i < rowsOrig; i++) {
676 diffOrig[i] = depVarOrig[i] - coef[0] - coef[1] * indVarOrig[i];
677 }
678 if (!SDDS_SetColumnFromDoubles(&residualPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE,
679 diffOrig, rowsOrig, column[iCol]))
680 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
681 free(diffOrig);
682 } else {
683 if (!SDDS_SetColumnFromDoubles(&residualPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE,
684 diff, rows, column[iCol]))
685 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
686 }
687 }
688 }
689
690 if (residualFile) {
691 if (!SDDS_WriteTable(&residualPage))
692 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
693 }
694
695 if (!SDDS_WriteTable(&outputPage))
696 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
697 }
698
699 if (residualFile) {
700 if (!SDDS_Terminate(&residualPage))
701 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
702 }
703 if (!SDDS_Terminate(&inputPage) || !SDDS_Terminate(&outputPage))
704 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
705
706 if (tmpfile_used && !replaceFileAndBackUp(inputfile, outputfile))
707 exit(EXIT_FAILURE);
708
709 /* Free allocated memory */
710 free(indVar);
711 free(indVarOrig);
712 free(depVar);
713 free(depVarOrig);
714 free(coef);
715 free(coefsigma);
716 free(weight);
717 free(diff);
718 if (intColumn) {
719 for (i = 0; i < columns; i++) {
720 free(intColumn[i]);
721 free(slopeColumn[i]);
722 if (doSlopeSigma) {
723 free(slopeSigmaColumn[i]);
724 free(interceptSigmaColumn[i]);
725 free(chiSquaredColumn[i]);
726 }
727 free(sigmaColumn[i]);
728 }
729 free(intColumn);
730 free(slopeColumn);
731 if (doSlopeSigma) {
732 free(slopeSigmaColumn);
733 free(interceptSigmaColumn);
734 free(chiSquaredColumn);
735 }
736 free(sigmaColumn);
737 free(sigmaColumnExists);
738 }
739 free(column);
740 if (excludeColumn && excludeColumn != defaultExcludedColumn)
741 free(excludeColumn);
742
743 return EXIT_SUCCESS;
744}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
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_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_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_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_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
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_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
#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
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
long lsfn(double *xd, double *yd, double *sy, long nd, long nf, double *coef, double *s_coef, double *chi, double *diff)
Computes nth order polynomial least squares fit.
Definition lsfn.c:34
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.
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
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.

◆ set_multicolumn_flags()

long set_multicolumn_flags ( SDDS_TABLE * SDDSin,
char *** column,
int32_t * columns,
char ** exclude,
long excludes )

Definition at line 746 of file sddsslopes.c.

746 {
747 long index, i;
748
749 if (*column) {
750 SDDS_SetColumnFlags(SDDSin, 0);
751 for (i = 0; i < *columns; i++) {
752 if (!SDDS_SetColumnsOfInterest(SDDSin, SDDS_MATCH_STRING, (*column)[i], SDDS_OR))
753 return 0;
754 }
755 } else {
756 SDDS_SetColumnFlags(SDDSin, 1);
757 if (!(*column = SDDS_GetColumnNames(SDDSin, columns)) || *columns == 0) {
758 SDDS_SetError("no columns found");
759 return 0;
760 }
761 for (i = 0; i < *columns; i++) {
762 index = SDDS_GetColumnIndex(SDDSin, (*column)[i]);
763 if (!SDDS_NUMERIC_TYPE(SDDS_GetColumnType(SDDSin, index)) &&
764 !SDDS_AssertColumnFlags(SDDSin, SDDS_INDEX_LIMITS, index, index, 0))
765 return 0;
766 }
767 }
768 free(*column);
769
770 for (i = 0; i < excludes; i++)
771 if (!SDDS_SetColumnsOfInterest(SDDSin, SDDS_MATCH_STRING, exclude[i], SDDS_NEGATE_MATCH | SDDS_AND))
772 return 0;
773
774 if (!(*column = SDDS_GetColumnNames(SDDSin, columns)) || *columns == 0) {
775 SDDS_SetError("Selected columns not found.");
776 return 0;
777 }
778
779 return 1;
780}
int32_t SDDS_AssertColumnFlags(SDDS_DATASET *SDDS_dataset, uint32_t mode,...)
Sets acceptance flags for columns based on specified criteria.
int32_t SDDS_SetColumnsOfInterest(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
Sets the acceptance flags for columns based on specified naming criteria.
int32_t SDDS_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns in the current data table of a data set.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
int32_t SDDS_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138