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

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

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

Go to the source code of this file.

Macros

#define SIGMA_GENERATE   0
 
#define SIGMA_OPTIONS   1
 
#define DEFAULT_EXCLUDED_COLUMNS   1
 

Enumerations

enum  option_type {
  CLO_INDEPENDENT_COLUMN , CLO_COLUMNS , CLO_EXCLUDE , CLO_VERBOSE ,
  CLO_SIGMA , CLO_ASCII , CLO_PIPE , CLO_RESIDUAL ,
  CLO_RANGE , CLO_MAJOR_ORDER , CLO_NO_WARNINGS , N_OPTIONS
}
 

Functions

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

Variables

char * commandline_option [N_OPTIONS]
 
char * sigma_option [SIGMA_OPTIONS]
 
char * defaultExcludedColumn [DEFAULT_EXCLUDED_COLUMNS]
 
static char * USAGE
 

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. Optionally, it can generate residuals, handle sigma values for error calculations, and support various output formats and ordering.

The independent variable must be a defined column in the input file. The output file will contain one table with the slopes and intercepts for each specified column. The independent column from the input file is excluded in the output file but its name is converted to a parameter string.

Usage

Syntax:

sddsslopes <inputfile> <outputfile> [OPTIONS]

Options

-pipe=[input][,output] -independentVariable=<name> -range=<lower>,<upper> -columns=

excludeColumns=

sigma[=generate][,minimum=<val>] -residual=<file> -ascii -verbose -majorOrder=<row|column> -nowarnings

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.

Macro Definition Documentation

◆ DEFAULT_EXCLUDED_COLUMNS

#define DEFAULT_EXCLUDED_COLUMNS   1

Definition at line 87 of file sddsslopes.c.

◆ SIGMA_GENERATE

#define SIGMA_GENERATE   0

Definition at line 81 of file sddsslopes.c.

◆ SIGMA_OPTIONS

#define SIGMA_OPTIONS   1

Definition at line 82 of file sddsslopes.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 52 of file sddsslopes.c.

52 {
53 CLO_INDEPENDENT_COLUMN,
54 CLO_COLUMNS,
55 CLO_EXCLUDE,
56 CLO_VERBOSE,
57 CLO_SIGMA,
58 CLO_ASCII,
59 CLO_PIPE,
60 CLO_RESIDUAL,
61 CLO_RANGE,
62 CLO_MAJOR_ORDER,
63 CLO_NO_WARNINGS,
64 N_OPTIONS
65};

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 116 of file sddsslopes.c.

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

721 {
722 long index, i;
723
724 if (*column) {
725 SDDS_SetColumnFlags(SDDSin, 0);
726 for (i = 0; i < *columns; i++) {
727 if (!SDDS_SetColumnsOfInterest(SDDSin, SDDS_MATCH_STRING, (*column)[i], SDDS_OR))
728 return 0;
729 }
730 } else {
731 SDDS_SetColumnFlags(SDDSin, 1);
732 if (!(*column = SDDS_GetColumnNames(SDDSin, columns)) || *columns == 0) {
733 SDDS_SetError("no columns found");
734 return 0;
735 }
736 for (i = 0; i < *columns; i++) {
737 index = SDDS_GetColumnIndex(SDDSin, (*column)[i]);
738 if (!SDDS_NUMERIC_TYPE(SDDS_GetColumnType(SDDSin, index)) &&
739 !SDDS_AssertColumnFlags(SDDSin, SDDS_INDEX_LIMITS, index, index, 0))
740 return 0;
741 }
742 }
743 free(*column);
744
745 for (i = 0; i < excludes; i++)
746 if (!SDDS_SetColumnsOfInterest(SDDSin, SDDS_MATCH_STRING, exclude[i], SDDS_NEGATE_MATCH | SDDS_AND))
747 return 0;
748
749 if (!(*column = SDDS_GetColumnNames(SDDSin, columns)) || *columns == 0) {
750 SDDS_SetError("Selected columns not found.");
751 return 0;
752 }
753
754 return 1;
755}
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

Variable Documentation

◆ commandline_option

char* commandline_option[N_OPTIONS]
Initial value:
= {
"independentVariable",
"columns",
"excludeColumns",
"verbose",
"sigma",
"ascii",
"pipe",
"residual",
"range",
"majorOrder",
"nowarnings"
}

Definition at line 67 of file sddsslopes.c.

67 {
68 "independentVariable",
69 "columns",
70 "excludeColumns",
71 "verbose",
72 "sigma",
73 "ascii",
74 "pipe",
75 "residual",
76 "range",
77 "majorOrder",
78 "nowarnings"
79};

◆ defaultExcludedColumn

char* defaultExcludedColumn[DEFAULT_EXCLUDED_COLUMNS]
Initial value:
= {
"Time",
}

Definition at line 88 of file sddsslopes.c.

88 {
89 "Time",
90};

◆ sigma_option

char* sigma_option[SIGMA_OPTIONS]
Initial value:
= {
"generate"
}

Definition at line 83 of file sddsslopes.c.

83 {
84 "generate"
85};

◆ USAGE

char* USAGE
static
Initial value:
=
"Usage: sddsslopes <inputfile> <outputfile> [OPTIONS]\n\n"
"Options:\n"
" -pipe=[input][,output] Read input or write output from/to a pipe.\n"
" -independentVariable=<columnName> Specify the independent variable column.\n"
" -range=<lower>,<upper> Specify the range of the independent variable for fitting.\n"
" -columns=<list-of-names> Comma-separated list of columns to perform fits on.\n"
" -excludeColumns=<list-of-names> Comma-separated list of columns to exclude from fitting.\n"
" -sigma[=generate][,minimum=<val>] Calculate errors using sigma columns or generate them.\n"
" -residual=<file> Output file for residuals of the linear fit.\n"
" -ascii Output slopes file in ASCII mode (default is binary).\n"
" -verbose Enable verbose output to stderr.\n"
" -majorOrder=<row|column> Specify output file ordering.\n"
" -nowarnings Suppress warning messages.\n\n"
"Description:\n"
" Performs straight line fits on numerical columns in the input SDDS file using a specified\n"
" independent variable. Outputs the slope and intercept for each selected column.\n"
" The independent variable column is excluded from the output but its name is stored as a parameter.\n\n"
"Example:\n"
" sddsslopes data_input.sdds data_output.sdds -independentVariable=Time -columns=X,Y,Z -verbose\n"
"Program by Louis Emery, ANL (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 92 of file sddsslopes.c.