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

Detailed Description

Calculates derivatives of specified columns in an SDDS data set.

This program calculates the derivative of specified columns in an SDDS data set. It supports various options including handling error columns, Savitzky-Golay filtering, and customizable output templates. The templates allow users to customize names, symbols, and descriptions for both primary and error derivatives.

Usage

sddsderiv [<input>] [<output>]
[-pipe=[input][,output]]
-differentiate=<column-name>[,<sigma-name>]...
[-exclude=<column-name>[,...]]
-versus=<column-name>
[-interval=<integer>]
[-SavitzkyGolay=<left>,<right>,<fitOrder>[,<derivOrder>]]
[-mainTemplates=<item>=<string>[,...]]
[-errorTemplates=<item>=<string>[,...]]
[-majorOrder=row|column]

Options

Required Description
-differentiate Specifies the columns to differentiate, optionally specifying sigma.
-versus Specifies the column to differentiate with respect to.
Optional Description
-pipe Use standard input/output.
-exclude Exclude specific columns from differentiation.
-interval Set interval for finite difference method.
-SavitzkyGolay Apply Savitzky-Golay filter with the specified parameters.
-mainTemplates Templates for main output columns.
-errorTemplates Templates for error output columns.
-majorOrder Specifies the major order of the data layout.

Incompatibilities

  • -interval is incompatible with:
    • -SavitzkyGolay
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file sddsderiv.c.

#include "mdb.h"
#include "SDDS.h"
#include "SDDSutils.h"
#include "scan.h"
#include <ctype.h>

Go to the source code of this file.

Functions

long checkErrorNames (char **yErrorName, long nDerivatives)
 
void makeSubstitutions (char *buffer1, char *buffer2, char *template, char *nameRoot, char *symbolRoot, char *xName, char *xSymbol)
 
char * changeInformation (SDDS_DATASET *SDDSout, char *name, char *nameRoot, char *symbolRoot, char *xName, char *xSymbol, char **template, char *newUnits)
 
long setupOutputFile (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, char *output, char ***yOutputName, char ***yOutputErrorName, char ***yOutputUnits, char *xName, char *xErrorName, char **yName, char **yErrorName, long yNames, char **mainTemplate, char **errorTemplate, int32_t interval, long order, short columnMajorOrder)
 
long findDerivIndices (int64_t *i1, int64_t *i2, long interval, int64_t i, int64_t rows)
 
void takeDerivative (double *x, double *y, double *sy, int64_t rows, double *deriv, double *derivSigma, double *derivPosition, long interval)
 
void takeSGDerivative (double *x, double *y, int64_t rows, double *deriv, double *derivPosition, long left, long right, long sgOrder, long derivOrder)
 
int main (int argc, char **argv)
 

Function Documentation

◆ changeInformation()

char * changeInformation ( SDDS_DATASET * SDDSout,
char * name,
char * nameRoot,
char * symbolRoot,
char * xName,
char * xSymbol,
char ** template,
char * newUnits )

Definition at line 506 of file sddsderiv.c.

506 {
507 char buffer1[SDDS_MAXLINE], buffer2[SDDS_MAXLINE], *ptr;
508
509 if (!SDDS_ChangeColumnInformation(SDDSout, "units", newUnits, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
510 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
511
512 makeSubstitutions(buffer1, buffer2, template[2], nameRoot, symbolRoot, xName, xSymbol);
513 if (!SDDS_ChangeColumnInformation(SDDSout, "symbol", buffer2, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
514 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
515
516 makeSubstitutions(buffer1, buffer2, template[1], nameRoot, symbolRoot, xName, xSymbol);
517 if (!SDDS_ChangeColumnInformation(SDDSout, "description", buffer2, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
518 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
519
520 makeSubstitutions(buffer1, buffer2, template[0], nameRoot, symbolRoot, xName, xSymbol);
521 if (!SDDS_ChangeColumnInformation(SDDSout, "name", buffer2, SDDS_PASS_BY_VALUE | SDDS_SET_BY_NAME, name))
522 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
523 SDDS_CopyString(&ptr, buffer2);
524 return ptr;
525}
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
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856

◆ checkErrorNames()

long checkErrorNames ( char ** yErrorName,
long nDerivatives )

Definition at line 536 of file sddsderiv.c.

536 {
537 long i;
538 if (yErrorName[0]) {
539 for (i = 1; i < yNames; i++)
540 if (!yErrorName[i])
541 return 0;
542 } else {
543 for (i = 1; i < yNames; i++)
544 if (yErrorName[i])
545 return 0;
546 }
547 return 1;
548}

◆ findDerivIndices()

long findDerivIndices ( int64_t * i1,
int64_t * i2,
long interval,
int64_t i,
int64_t rows )

Definition at line 378 of file sddsderiv.c.

378 {
379 int64_t index, rows1;
380
381 rows1 = rows - 1;
382 *i1 = index = i - interval / 2;
383 if (index < 0) {
384 *i2 = 2 * i;
385 *i1 = 0;
386 if (*i1 == *i2)
387 *i2 += 1;
388 if (*i2 < rows)
389 return 1;
390 return 0;
391 }
392 *i2 = i + interval / 2;
393 index = rows1 - *i2;
394 if (index < 0) {
395 *i1 = 2 * i - rows1;
396 *i2 = rows1;
397 if (*i1 == *i2)
398 *i1 -= 1;
399 if (*i1 >= 0)
400 return 1;
401 return 0;
402 }
403 if (*i1 == *i2) {
404 if (*i2 < rows1)
405 *i2 = *i1 + 1;
406 else
407 *i1 = *i1 - 1;
408 }
409 if (*i2 < rows && *i1 >= 0)
410 return 1;
411 return 0;
412}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 127 of file sddsderiv.c.

127 {
128 double *xData, *yData, *xError, *yError, *derivative, *derivativeError, *derivativePosition;
129 char *input, *output, *xName, *xErrorName, **yName, **yErrorName, **yOutputName, **yOutputErrorName, *ptr;
130 char **yOutputUnits, **yExcludeName;
131 char *mainTemplate[3] = {NULL, NULL, NULL};
132 char *errorTemplate[3] = {NULL, NULL, NULL};
133 long i, iArg, yNames, yExcludeNames;
134 int64_t rows;
135 int32_t interval;
136 SDDS_DATASET SDDSin, SDDSout;
137 SCANNED_ARG *scanned;
138 unsigned long flags, pipeFlags, majorOrderFlag;
139 long SGLeft, SGRight, SGOrder, SGDerivOrder, intervalGiven, yErrorsSeen;
140 short columnMajorOrder = -1;
141
143
144 argc = scanargs(&scanned, argc, argv);
145 if (argc == 1)
146 bomb(NULL, USAGE);
147
148 input = output = xName = xErrorName = NULL;
149 yName = yErrorName = yExcludeName = NULL;
150 derivative = derivativeError = derivativePosition = yError = yData = xData = xError = NULL;
151 yNames = yExcludeNames = 0;
152 pipeFlags = 0;
153 interval = 2;
154 SGOrder = -1;
155 SGDerivOrder = 1;
156 intervalGiven = 0;
157 yErrorsSeen = 0;
158
159 for (iArg = 1; iArg < argc; iArg++) {
160 if (scanned[iArg].arg_type == OPTION) {
161 /* process options here */
162 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
163 case CLO_MAJOR_ORDER:
164 majorOrderFlag = 0;
165 scanned[iArg].n_items--;
166 if (scanned[iArg].n_items > 0 && (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER, "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
167 SDDS_Bomb("invalid -majorOrder syntax/values");
168 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
169 columnMajorOrder = 1;
170 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
171 columnMajorOrder = 0;
172 break;
173 case CLO_DIFFERENTIATE:
174 if (scanned[iArg].n_items != 2 && scanned[iArg].n_items != 3)
175 SDDS_Bomb("invalid -differentiate syntax");
176 yName = SDDS_Realloc(yName, sizeof(*yName) * (yNames + 1));
177 yErrorName = SDDS_Realloc(yErrorName, sizeof(*yErrorName) * (yNames + 1));
178 yName[yNames] = scanned[iArg].list[1];
179 if (scanned[iArg].n_items == 3) {
180 yErrorsSeen = 1;
181 yErrorName[yNames] = scanned[iArg].list[2];
182 } else
183 yErrorName[yNames] = NULL;
184 yNames++;
185 break;
186 case CLO_EXCLUDE:
187 if (scanned[iArg].n_items < 2)
188 SDDS_Bomb("invalid -exclude syntax");
189 moveToStringArray(&yExcludeName, &yExcludeNames, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
190 break;
191 case CLO_VERSUS:
192 if (xName)
193 SDDS_Bomb("give -versus only once");
194 if (scanned[iArg].n_items != 2)
195 SDDS_Bomb("invalid -versus syntax");
196 xName = scanned[iArg].list[1];
197 xErrorName = NULL;
198 break;
199 case CLO_MAINTEMPLATE:
200 if (scanned[iArg].n_items < 2)
201 SDDS_Bomb("invalid -mainTemplate syntax");
202 scanned[iArg].n_items--;
203 if (!scanItemList(&flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "name", SDDS_STRING, mainTemplate + 0, 1, 0, "description", SDDS_STRING, mainTemplate + 1, 1, 0, "symbol", SDDS_STRING, mainTemplate + 2, 1, 0, NULL))
204 SDDS_Bomb("invalid -mainTemplate syntax");
205 break;
206 case CLO_ERRORTEMPLATE:
207 if (scanned[iArg].n_items < 2)
208 SDDS_Bomb("invalid -errorTemplate syntax");
209 scanned[iArg].n_items--;
210 if (!scanItemList(&flags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "name", SDDS_STRING, errorTemplate + 0, 1, 0, "description", SDDS_STRING, errorTemplate + 1, 1, 0, "symbol", SDDS_STRING, errorTemplate + 2, 1, 0, NULL))
211 SDDS_Bomb("invalid -errorTemplate syntax");
212 break;
213 case CLO_PIPE:
214 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
215 SDDS_Bomb("invalid -pipe syntax");
216 break;
217 case CLO_INTERVAL:
218 if (scanned[iArg].n_items != 2 || sscanf(scanned[iArg].list[1], "%" SCNd32, &interval) != 1 || interval <= 0)
219 SDDS_Bomb("invalid -interval syntax/value");
220 intervalGiven = 1;
221 break;
222 case CLO_SAVITZKYGOLAY:
223 if ((scanned[iArg].n_items != 4 && scanned[iArg].n_items != 5) ||
224 sscanf(scanned[iArg].list[1], "%ld", &SGLeft) != 1 ||
225 sscanf(scanned[iArg].list[2], "%ld", &SGRight) != 1 ||
226 sscanf(scanned[iArg].list[3], "%ld", &SGOrder) != 1 ||
227 (scanned[iArg].n_items == 5 && sscanf(scanned[iArg].list[4], "%ld", &SGDerivOrder) != 1) ||
228 SGLeft < 0 ||
229 SGRight < 0 ||
230 (SGLeft + SGRight) < SGOrder ||
231 SGOrder < 0 ||
232 SGDerivOrder < 0)
233 SDDS_Bomb("invalid -SavitzkyGolay syntax/values");
234 break;
235 default:
236 fprintf(stderr, "invalid option seen: %s\n", scanned[iArg].list[0]);
237 exit(EXIT_FAILURE);
238 break;
239 }
240 } else {
241 if (!input)
242 input = scanned[iArg].list[0];
243 else if (!output)
244 output = scanned[iArg].list[0];
245 else
246 SDDS_Bomb("too many filenames");
247 }
248 }
249
250 if (intervalGiven && SGOrder >= 0)
251 SDDS_Bomb("-interval and -SavitzkyGolay options are incompatible");
252 if (SGOrder >= 0 && (xErrorName || yErrorsSeen))
253 SDDS_Bomb("Savitzky-Golay method does not support errors in data");
254
255 processFilenames("sddsderiv", &input, &output, pipeFlags, 0, NULL);
256
257 if (!yNames)
258 SDDS_Bomb("-differentiate option must be given at least once");
259 if (!checkErrorNames(yErrorName, yNames))
260 SDDS_Bomb("either all -differentiate quantities must have errors, or none");
261
262 if (!SDDS_InitializeInput(&SDDSin, input))
263 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
264 if (!(ptr = SDDS_FindColumn(&SDDSin, FIND_NUMERIC_TYPE, xName, NULL))) {
265 fprintf(stderr, "error: column %s doesn't exist\n", xName);
266 exit(EXIT_FAILURE);
267 }
268 free(xName);
269 xName = ptr;
270 if (xErrorName) {
271 if (!(ptr = SDDS_FindColumn(&SDDSin, FIND_NUMERIC_TYPE, xErrorName, NULL))) {
272 fprintf(stderr, "error: column %s doesn't exist\n", xErrorName);
273 exit(EXIT_FAILURE);
274 } else {
275 free(xErrorName);
276 xErrorName = ptr;
277 }
278 }
279
280 if (!(yNames = expandColumnPairNames(&SDDSin, &yName, &yErrorName, yNames, yExcludeName, yExcludeNames, FIND_NUMERIC_TYPE, 0))) {
281 fprintf(stderr, "error: no quantities to differentiate found in file\n");
282 exit(EXIT_FAILURE);
283 }
284
285 setupOutputFile(&SDDSout, &SDDSin, output, &yOutputName, &yOutputErrorName, &yOutputUnits, xName, xErrorName, yName, yErrorName, yNames, mainTemplate, errorTemplate, interval, SGOrder >= 0 ? SGDerivOrder : 1, columnMajorOrder);
286
287 while (SDDS_ReadPage(&SDDSin) > 0) {
288 if ((rows = SDDS_CountRowsOfInterest(&SDDSin)) < 2)
289 SDDS_Bomb("Can't compute derivatives: too little data.");
290 derivative = SDDS_Realloc(derivative, sizeof(*derivative) * rows);
291 derivativeError = SDDS_Realloc(derivativeError, sizeof(*derivativeError) * rows);
292 derivativePosition = SDDS_Realloc(derivativePosition, sizeof(*derivativePosition) * rows);
293 if (!SDDS_StartPage(&SDDSout, rows) || !SDDS_CopyParameters(&SDDSout, &SDDSin))
294 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
295 xError = NULL;
296 if (!(xData = SDDS_GetColumnInDoubles(&SDDSin, xName)) ||
297 (xErrorName && !(xError = SDDS_GetColumnInDoubles(&SDDSin, xErrorName))))
298 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
299 for (i = 0; i < yNames; i++) {
300 yError = NULL;
301 if (!(yData = SDDS_GetColumnInDoubles(&SDDSin, yName[i])) ||
302 (yErrorName && yErrorName[i] && !(yError = SDDS_GetColumnInDoubles(&SDDSin, yErrorName[i]))))
303 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
304 if (SGOrder >= 0)
305 takeSGDerivative(xData, yData, rows, derivative, derivativePosition, SGLeft, SGRight, SGOrder, SGDerivOrder);
306 else
307 takeDerivative(xData, yData, yError, rows, derivative, derivativeError, derivativePosition, interval);
308 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, derivative, rows, yOutputName[i]) ||
309 (yOutputErrorName && yOutputErrorName[i] && !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, derivativeError, rows, yOutputErrorName[i])))
310 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
311 if (yData)
312 free(yData);
313 if (yError)
314 free(yError);
315 yData = yError = NULL;
316 }
317 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, derivativePosition, rows, xName) ||
318 (xErrorName && !SDDS_SetColumnFromDoubles(&SDDSout, SDDS_BY_NAME, xError, rows, xErrorName)))
319 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
320 if (!SDDS_WritePage(&SDDSout))
321 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
322 if (xData)
323 free(xData);
324 if (xError)
325 free(xError);
326 xData = xError = NULL;
327 }
328 if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
329 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
330 exit(EXIT_FAILURE);
331 }
332 if (derivative)
333 free(derivative);
334 if (derivativeError)
335 free(derivativeError);
336 if (derivativePosition)
337 free(derivativePosition);
338 return EXIT_SUCCESS;
339}
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_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_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.
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
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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.

◆ makeSubstitutions()

void makeSubstitutions ( char * buffer1,
char * buffer2,
char * template,
char * nameRoot,
char * symbolRoot,
char * xName,
char * xSymbol )

Definition at line 527 of file sddsderiv.c.

527 {
528 strcpy(buffer2, template);
529 replace_string(buffer1, buffer2, "%ySymbol", symbolRoot);
530 replace_string(buffer2, buffer1, "%xSymbol", xSymbol);
531 replace_string(buffer1, buffer2, "%yName", nameRoot);
532 replace_string(buffer2, buffer1, "%xName", xName);
533 strcpy(buffer1, buffer2);
534}
int replace_string(char *t, char *s, char *orig, char *repl)
Replace all occurrences of one string with another string.

◆ setupOutputFile()

long setupOutputFile ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
char * output,
char *** yOutputName,
char *** yOutputErrorName,
char *** yOutputUnits,
char * xName,
char * xErrorName,
char ** yName,
char ** yErrorName,
long yNames,
char ** mainTemplate,
char ** errorTemplate,
int32_t interval,
long order,
short columnMajorOrder )

Definition at line 414 of file sddsderiv.c.

415 {
416 long i;
417 char *xSymbol, *ySymbol;
418 char *mainTemplate[3] = {"%yNameDeriv", "Derivative w.r.t. %xSymbol of %ySymbol", "d[%ySymbol]/d[%xSymbol]"};
419 char *errorTemplate[3] = {"%yNameDerivSigma", "Sigma of derivative w.r.t. %xSymbol of %ySymbol",
420 "Sigma[d[%ySymbol]/d[%xSymbol]]"};
421 char buffer[1024];
422
423 for (i = 0; i < 3; i++) {
424 if (!mainTemplate0[i]) {
425 if (order != 1) {
426 switch (i) {
427 case 0:
428 /* name */
429 snprintf(buffer, sizeof(buffer), "%%yNameDeriv%ld", order);
430 break;
431 case 1:
432 /* description */
433 snprintf(buffer, sizeof(buffer), "Derivative %ld w.r.t. %%xSymbol of %%ySymbol", order);
434 break;
435 case 2:
436 /* symbol */
437 snprintf(buffer, sizeof(buffer), "d[%s%ld]/d[%s]", "ySymbol", order, "xSymbol"); // Adjusted for clarity
438 break;
439 }
440 cp_str(&mainTemplate[i], buffer);
441 }
442 } else {
443 mainTemplate[i] = mainTemplate0[i];
444 }
445 if (errorTemplate0[i]) {
446 errorTemplate[i] = errorTemplate0[i];
447 }
448 }
449
450 *yOutputName = tmalloc(sizeof(**yOutputName) * yNames);
451 *yOutputErrorName = tmalloc(sizeof(**yOutputErrorName) * yNames);
452 *yOutputUnits = tmalloc(sizeof(**yOutputUnits) * yNames);
453 if (!SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL, "sddsderiv output", output) ||
454 SDDS_DefineParameter1(SDDSout, "derivInterval", NULL, NULL, NULL, NULL, SDDS_LONG, &interval) < 0)
455 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
456 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, xName, NULL) ||
457 (xErrorName && !SDDS_TransferColumnDefinition(SDDSout, SDDSin, xErrorName, NULL)))
458 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
459 if (SDDS_GetColumnInformation(SDDSout, "symbol", &xSymbol, SDDS_GET_BY_NAME, xName) != SDDS_STRING) {
460 fprintf(stderr, "error: problem getting symbol for column %s\n", xName);
461 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
462 }
463 if (!xSymbol)
464 SDDS_CopyString(&xSymbol, xName);
465 for (i = 0; i < yNames; i++) {
466 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, yName[i], NULL)) {
467 fprintf(stderr, "error: problem transferring definition for column %s\n", yName[i]);
468 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
469 }
470 if (SDDS_GetColumnInformation(SDDSout, "symbol", &ySymbol, SDDS_GET_BY_NAME, yName[i]) != SDDS_STRING) {
471 fprintf(stderr, "error: problem getting symbol for column %s\n", yName[i]);
472 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
473 }
474 if (!ySymbol || SDDS_StringIsBlank(ySymbol))
475 SDDS_CopyString(&ySymbol, yName[i]);
476 (*yOutputUnits)[i] = divideColumnUnits(SDDSout, yName[i], xName);
477 (*yOutputName)[i] = changeInformation(SDDSout, yName[i], yName[i], ySymbol, xName, xSymbol, mainTemplate, (*yOutputUnits)[i]);
478 if (yErrorName || xErrorName) {
479 if (yErrorName && yErrorName[i]) {
480 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, yErrorName[i], NULL)) {
481 fprintf(stderr, "error: problem transferring definition for column %s\n", yErrorName[i]);
482 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
483 }
484 (*yOutputErrorName)[i] = changeInformation(SDDSout, yErrorName[i], yName[i], ySymbol, xName, xSymbol, errorTemplate, (*yOutputUnits)[i]);
485 } else {
486 if (!SDDS_TransferColumnDefinition(SDDSout, SDDSin, yName[i], NULL)) {
487 fprintf(stderr, "error: problem transferring error definition for column %s\n", yName[i]);
488 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
489 }
490 (*yOutputErrorName)[i] = changeInformation(SDDSout, yName[i], yName[i], ySymbol, xName, xSymbol, errorTemplate, (*yOutputUnits)[i]);
491 }
492 } else {
493 (*yOutputErrorName)[i] = NULL;
494 }
495 }
496 if (columnMajorOrder != -1)
497 SDDSout->layout.data_mode.column_major = columnMajorOrder;
498 else
499 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
500 if (!SDDS_TransferAllParameterDefinitions(SDDSout, SDDSin, SDDS_TRANSFER_KEEPOLD) ||
501 !SDDS_WriteLayout(SDDSout))
502 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
503 return 1;
504}
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_DefineParameter1(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, void *fixed_value)
Defines a data parameter with a fixed numerical value.
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_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_TransferColumnDefinition(SDDS_DATASET *target, SDDS_DATASET *source, char *name, char *newName)
Transfers a column definition from a source dataset to a target dataset.
int32_t SDDS_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions from a source dataset to a target dataset.
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28

◆ takeDerivative()

void takeDerivative ( double * x,
double * y,
double * sy,
int64_t rows,
double * deriv,
double * derivSigma,
double * derivPosition,
long interval )

Definition at line 354 of file sddsderiv.c.

354 {
355 int64_t i, i1, i2;
356 double dx;
357
358 if (sy) {
359 for (i = 0; i < rows; i++) {
360 if (findDerivIndices(&i1, &i2, interval, i, rows) && (dx = x[i2] - x[i1])) {
361 deriv[i] = (y[i2] - y[i1]) / dx;
362 derivSigma[i] = sqrt(sqr(sy[i1]) + sqr(sy[i2])) / fabs(dx);
363 derivPosition[i] = (x[i2] + x[i1]) / 2;
364 } else
365 deriv[i] = derivSigma[i] = derivPosition[i] = DBL_MAX;
366 }
367 } else {
368 for (i = 0; i < rows; i++) {
369 if (findDerivIndices(&i1, &i2, interval, i, rows) && (dx = x[i2] - x[i1])) {
370 deriv[i] = (y[i2] - y[i1]) / dx;
371 derivPosition[i] = (x[i2] + x[i1]) / 2;
372 } else
373 deriv[i] = derivPosition[i] = DBL_MAX;
374 }
375 }
376}

◆ takeSGDerivative()

void takeSGDerivative ( double * x,
double * y,
int64_t rows,
double * deriv,
double * derivPosition,
long left,
long right,
long sgOrder,
long derivOrder )

Definition at line 341 of file sddsderiv.c.

341 {
342 int64_t i;
343 double spacing, df;
344
345 spacing = (x[rows - 1] - x[0]) / (rows - 1);
346 df = dfactorial(derivOrder) / ipow(spacing, derivOrder);
347 for (i = 0; i < rows; i++) {
348 derivPosition[i] = x[i];
349 deriv[i] = df * y[i];
350 }
351 SavitzkyGolaySmooth(deriv, rows, sgOrder, left, right, derivOrder);
352}
double dfactorial(long n)
Computes the factorial of a given number as a double.
Definition factorial.c:43
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33
long SavitzkyGolaySmooth(double *data, long rows, long order, long nLeft, long nRight, long derivativeOrder)
Applies Savitzky-Golay smoothing or differentiation to a data array.