101 {
102 SCANNED_ARG *scanned;
103 SDDS_TABLE inputPage, *copiedPage, outputPage;
104 long copiedPages;
105 char *inputfile, *outputfile;
106 char **column, **excludeColumn = NULL;
107 int32_t columns;
108 long excludeColumns;
109 char *indParameterName;
110 char **copyColumn;
111 int32_t copyColumns;
112 long verbose;
113 long slopeErrors;
114 long iArg, i;
115 double *indVar;
116 char *indVarUnits;
117 char **intColumn, **slopeColumn, **slopeSigmaColumn;
118 char *Units, *slopeUnits;
119 double *depVar;
120 long order;
121 double *coef, *coefsigma, *weight, *diff, chi;
122 long iCol, iPage;
123 int64_t rows, iRow;
124 double *slope, slope2, slopeAve, slopeSigma;
125 unsigned long pipeFlags, majorOrderFlag;
126 long tmpfile_used, noWarnings;
127 long generateIndex;
128 short columnMajorOrder = -1;
129
130 copiedPage = NULL;
131 slopeSigmaColumn = NULL;
132 slopeUnits = Units = indVarUnits = NULL;
133 rows = 0;
134 slope = NULL;
135 slope2 = 0;
136 coef = coefsigma = weight = diff = slope = NULL;
137
138 argc =
scanargs(&scanned, argc, argv);
139 if (argc == 1)
141
142 inputfile = outputfile = NULL;
143 columns = excludeColumns = 0;
144 column = excludeColumn = NULL;
145 indParameterName = NULL;
146 verbose = 0;
147 slopeErrors = 0;
148 pipeFlags = 0;
149 tmpfile_used = 0;
150 noWarnings = 0;
151 for (iArg = 1; iArg < argc; iArg++) {
152 if (scanned[iArg].arg_type == OPTION) {
154 switch (
match_string(scanned[iArg].list[0], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
155 case CLO_MAJOR_ORDER:
156 majorOrderFlag = 0;
157 scanned[iArg].n_items--;
158 if (scanned[iArg].n_items > 0 &&
159 (!
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
160 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
161 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
162 SDDS_Bomb(
"invalid -majorOrder syntax/values");
163 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
164 columnMajorOrder = 1;
165 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
166 columnMajorOrder = 0;
167 break;
168 case CLO_INDEPENDENT_PARAMETER:
169 if (!(indParameterName = scanned[iArg].list[1]))
170 SDDS_Bomb(
"no string given for option -independentVariable");
171 break;
172 case CLO_COLUMNS:
173 if (columns)
174 SDDS_Bomb(
"only one -columns option may be given");
175 if (scanned[iArg].n_items < 2)
177 column =
tmalloc(
sizeof(*column) * (columns = scanned[iArg].n_items - 1));
178 for (i = 0; i < columns; i++)
179 column[i] = scanned[iArg].list[i + 1];
180 break;
181 case CLO_EXCLUDE:
182 if (excludeColumns)
183 SDDS_Bomb(
"only one -excludeColumns option may be given");
184 if (scanned[iArg].n_items < 2)
185 SDDS_Bomb(
"invalid -excludeColumns syntax");
186 excludeColumn =
tmalloc(
sizeof(*excludeColumn) * (excludeColumns = scanned[iArg].n_items - 1));
187 for (i = 0; i < excludeColumns; i++)
188 excludeColumn[i] = scanned[iArg].list[i + 1];
189 break;
190 case CLO_VERBOSE:
191 verbose = 1;
192 break;
193 case CLO_PIPE:
194 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
196 break;
197 case CLO_SLOPE_ERRORS:
198 slopeErrors = 1;
199 break;
200 default:
202 break;
203 }
204 } else {
205 if (!inputfile)
206 inputfile = scanned[iArg].list[0];
207 else if (!outputfile)
208 outputfile = scanned[iArg].list[0];
209 else
211 }
212 }
213
214 processFilenames(
"sddsvslopes", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
215
216 if (!indParameterName)
217 SDDS_Bomb(
"independentVariable not given");
218
219 if (!excludeColumns) {
220 excludeColumn = defaultExcludedColumn;
221 excludeColumns = DEFAULT_EXCLUDED_COLUMNS;
222 }
223
224 if (verbose)
225 fprintf(stderr, "Reading file %s.\n", inputfile);
227 copiedPages = 0;
228 while (SDDS_ReadTable(&inputPage) > 0) {
229 if (!copiedPages) {
232 } else {
234 }
237 if (!SDDS_CopyTable(&copiedPage[copiedPages], &inputPage))
239 copiedPages++;
240 }
241 if (copiedPages < 2) {
242 fprintf(stderr, "Insufficient data (i.e., number of data pages) to fit a straight line.\n");
243 exit(EXIT_FAILURE);
244 }
246 case SDDS_CHECK_WRONGUNITS:
247 case SDDS_CHECK_OKAY:
248 break;
249 default:
250 fprintf(stderr, "Something wrong with column %s.\n", "Rootname");
251 exit(EXIT_FAILURE);
252 }
254 case SDDS_CHECK_WRONGUNITS:
255 case SDDS_CHECK_OKAY:
256 generateIndex = 0;
257 break;
258 case SDDS_CHECK_NONEXISTENT:
259 generateIndex = 1;
260 break;
261 default:
262 fprintf(stderr, "Something wrong with column %s.\n", "Index");
263 exit(EXIT_FAILURE);
264 }
265
266
267
268 indVar = (double *)malloc(sizeof(*indVar) * copiedPages);
270 case SDDS_CHECK_WRONGUNITS:
271 case SDDS_CHECK_OKAY:
272 break;
273 default:
274 fprintf(stderr, "Something wrong with parameter %s.\n", indParameterName);
275 exit(EXIT_FAILURE);
276 }
277 for (iPage = 0; iPage < copiedPages; iPage++) {
280 }
283 if (!indVarUnits) {
284 indVarUnits = (char *)malloc(sizeof(*indVarUnits));
285 indVarUnits[0] = 0;
286 }
287
288
289
290
291 if (!set_multicolumn_flags(&inputPage, &column, &columns, excludeColumn, excludeColumns)) {
293 exit(EXIT_FAILURE);
294 }
295
296
297
298 intColumn = (char **)malloc((sizeof(char *) * columns));
299 slopeColumn = (char **)malloc((sizeof(char *) * columns));
300 if (slopeErrors)
301 slopeSigmaColumn = (char **)malloc((sizeof(char *) * columns));
302 for (i = 0; i < columns; i++) {
303 intColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("Intercept") + 1)));
304 strcat(strcpy(intColumn[i], column[i]), "Intercept");
305 slopeColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("Slope") + 1)));
306 strcat(strcpy(slopeColumn[i], column[i]), "Slope");
307 if (slopeErrors) {
308 slopeSigmaColumn[i] = (char *)malloc((sizeof(char) * (strlen(column[i]) + strlen("SlopeSigma") + 1)));
309 strcat(strcpy(slopeSigmaColumn[i], column[i]), "SlopeSigma");
310 }
311 }
312
313
314
315 if (verbose)
316 fprintf(stderr, "Opening file %s.\n", outputfile);
317 if (!
SDDS_InitializeOutput(&outputPage, SDDS_BINARY, 1,
"lsf of sddsvexperiment", NULL, outputfile) ||
323 if (columnMajorOrder != -1)
324 outputPage.layout.data_mode.column_major = columnMajorOrder;
325 else
326 outputPage.layout.data_mode.column_major = inputPage.layout.data_mode.column_major;
327 for (iCol = 0; iCol < columns; iCol++) {
330 if (!Units) {
331 Units = (char *)malloc(sizeof(*Units));
332 Units[0] = 0;
333 }
336
337 if (strlen(indVarUnits) && strlen(Units)) {
338 slopeUnits = (char *)malloc(sizeof(*slopeUnits) * (strlen(Units) + strlen(indVarUnits) + 2));
339 strcat(strcat(strcpy(slopeUnits, Units), "/"), indVarUnits);
340 }
341 if (strlen(indVarUnits) && !strlen(Units)) {
342 slopeUnits = (char *)malloc(sizeof(*slopeUnits) * (strlen(indVarUnits) + 2));
343 strcat(strcpy(slopeUnits, "1/"), indVarUnits);
344 }
345 if (!strlen(indVarUnits) && strlen(Units)) {
346 slopeUnits = (char *)malloc(sizeof(*slopeUnits) * (strlen(Units) + 2));
347 strcpy(slopeUnits, Units);
348 }
349 if (!strlen(indVarUnits) && !strlen(Units)) {
350 slopeUnits = (char *)malloc(sizeof(*slopeUnits));
351 slopeUnits[0] = '\0';
352 }
355 if (slopeErrors) {
358 }
359 free(slopeUnits);
360 }
362 !SDDS_StartTable(&outputPage, rows) ||
363 !
SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
"InputFile", inputfile ? inputfile :
"pipe", NULL) ||
364 !
SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, 0,
"IndependentVariable", indParameterName, NULL))
366
367
368
369
370 copyColumns = DEFAULT_COPY_COLUMNS;
371 copyColumn = defaultCopyColumn;
372 if (!set_multicolumn_flags(&inputPage, ©Column, ©Columns, NULL, 0)) {
374 exit(EXIT_FAILURE);
375 }
378 depVar = (double *)malloc(sizeof(*depVar) * copiedPages);
379 weight = (double *)malloc(sizeof(*weight) * copiedPages);
380 diff = (double *)malloc(sizeof(*diff) * copiedPages);
381 order = 1;
382 coef = (double *)malloc(sizeof(*coef) * (order + 1));
383 coefsigma = (double *)malloc(sizeof(*coefsigma) * (order + 1));
384 if (slopeErrors)
385 slope = (double *)malloc(sizeof(*slope) * copiedPages);
386 for (iCol = 0; iCol < columns; iCol++) {
387 for (iPage = 0; iPage < copiedPages; iPage++)
388 weight[iPage] = 1;
389 if (verbose)
390 fprintf(stderr, "Doing column %s.\n", column[iCol]);
391 for (iRow = 0; iRow < rows; iRow++) {
392 for (iPage = 0; iPage < copiedPages; iPage++) {
393 if (!
SDDS_GetValue(&copiedPage[iPage], column[iCol], iRow, &depVar[iPage]))
395 }
396 if (!(
lsfn(indVar, depVar, weight, copiedPages, order, coef, coefsigma, &chi, diff))) {
397 fprintf(stderr, "Problem with call to lsfn.\n");
398 exit(EXIT_FAILURE);
399 }
400 if (generateIndex) {
401 if (!
SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, iRow,
"Index", iRow, intColumn[iCol], coef[0], slopeColumn[iCol], coef[1], NULL))
403 } else {
404 if (!
SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, iRow, intColumn[iCol], coef[0], slopeColumn[iCol], coef[1], NULL))
406 }
407 if (slopeErrors) {
408
409 slopeAve = slope2 = 0;
410 for (iPage = 0; iPage < copiedPages; iPage++) {
411 weight[iPage] = 1e10;
412 if (iPage)
413 weight[iPage - 1] = 1;
414 if (!(
lsfn(indVar, depVar, weight, copiedPages, order, coef, coefsigma, &chi, diff))) {
415 fprintf(stderr, "Problem with call to lsfn.\n");
416 exit(EXIT_FAILURE);
417 }
418 slope[iPage] = coef[1];
419 slopeAve += slope[iPage];
420 slope2 += slope[iPage] * slope[iPage];
421 }
422 slopeSigma = sqrt(slope2 / copiedPages - (slopeAve / copiedPages) * (slopeAve / copiedPages));
423 if (!
SDDS_SetRowValues(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, iRow, slopeSigmaColumn[iCol], slopeSigma, NULL))
425 }
426 }
427 }
428
431 for (iPage = 0; iPage < copiedPages; iPage++) {
434 }
435
439 exit(EXIT_FAILURE);
441 free(column);
444 free(intColumn);
445 free(slopeColumn);
446 if (slopeErrors) {
448 free(slopeSigmaColumn);
449 }
450
451 free(copiedPage);
452 free(indVar);
453 free(depVar);
454 if (weight)
455 free(weight);
456 if (diff)
457 free(diff);
458 if (slope)
459 free(slope);
460 if (coef)
461 free(coef);
462 if (coefsigma)
463 free(coefsigma);
464 if (Units)
465 free(Units);
466 if (indVarUnits)
467 free(indVarUnits);
468
470
471 return EXIT_SUCCESS;
472}
int32_t SDDS_CopyColumns(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
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_GetParameterInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified parameter in the SDDS dataset.
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.
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_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
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.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_ANY_INTEGER_TYPE
Special identifier used by SDDS_Check*() routines to accept any integer type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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.
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.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
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.