SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sddssmooth.c
Go to the documentation of this file.
1/**
2 * @file sddssmooth.c
3 * @brief Smooths data columns in SDDS-format files using various techniques.
4 *
5 * @details
6 * This program smooths data columns in SDDS-format files using techniques such as nearest-neighbor averaging,
7 * Gaussian convolution, median filtering, and Savitzky-Golay filtering. It also supports despiking and the
8 * creation of new or difference columns. Users can specify a variety of options for input/output customization
9 * and processing methods.
10 *
11 * @section Usage
12 * ```
13 * sddssmooth [<inputfile>] [<outputfile>]
14 * [-pipe=[input][,output]]
15 * -columns=<name>[,...]
16 * [-points=<oddInteger>]
17 * [-passes=<integer>]
18 * [-gaussian=<sigmaValueIn#Rows>]
19 * [-despike[=neighbors=<integer>,passes=<integer>,averageOf=<integer>,threshold=<value>]]
20 * [-SavitzkyGolay=<left>,<right>,<order>[,<derivativeOrder>]]
21 * [-medianFilter=windowSize=<integer>]
22 * [-newColumns]
23 * [-differenceColumns]
24 * [-nowarnings]
25 * [-majorOrder=row|column]
26 * ```
27 *
28 * @section Options
29 * | Required | Description |
30 * |---------------------------------------|---------------------------------------------------------------------------------------|
31 * | `-columns` | Specifies column names (wildcards allowed). |
32 *
33 * | Optional | Description |
34 * |---------------------------------------|---------------------------------------------------------------------------------------|
35 * | `-pipe` | SDDS pipe input/output. |
36 * | `-points` | Sets points for nearest-neighbor averaging (odd integer, default: 3). |
37 * | `-passes` | Number of smoothing passes (default: 1, 0 disables smoothing). |
38 * | `-gaussian` | Gaussian kernel smoothing with specified sigma. |
39 * | `-despike` | Despike using neighbors, passes, averageOf, and threshold. |
40 * | `-SavitzkyGolay` | Savitzky-Golay filter with specified window and order. |
41 * | `-medianFilter` | Median filtering with specified window size (odd integer, default: 3). |
42 * | `-newColumns` | Create new columns with smoothed data. |
43 * | `-differenceColumns` | Create difference columns (original minus smoothed). |
44 * | `-nowarnings` | Suppress warnings. |
45 * | `-majorOrder` | Specify row or column major order for data. |
46 *
47 * @subsection Incompatibilities
48 * - `-SavitzkyGolay` is incompatible with:
49 * - `-passes` (nearest-neighbor smoothing is not done if `-SavitzkyGolay` is specified).
50 * - `-despike` must be applied before other smoothing options.
51 * - `-medianFilter` requires an odd integer window size.
52 * - `-points` requires an odd integer.
53 *
54 * @copyright
55 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
56 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
57 *
58 * @license
59 * This file is distributed under the terms of the Software License Agreement
60 * found in the file LICENSE included with this distribution.
61 *
62 * @author
63 * M. Borland, C. Saunders, R. Soliday, H. Shang
64 */
65
66#include "mdb.h"
67#include "SDDS.h"
68#include "scan.h"
69#include <ctype.h>
70
71/* Enumeration for option types */
72enum option_type {
73 CLO_POINTS,
74 CLO_PASSES,
75 CLO_COLUMNS,
76 CLO_PIPE,
77 CLO_NEWCOLUMNS,
78 CLO_DIFFERENCECOLUMNS,
79 CLO_DESPIKE,
80 CLO_NOWARNINGS,
81 CLO_SAVITZKYGOLAY,
82 CLO_MAJOR_ORDER,
83 CLO_MEDIAN_FILTER,
84 CLO_GAUSSIAN,
85 N_OPTIONS
86};
87
88char *option[N_OPTIONS] = {
89 "points",
90 "passes",
91 "columns",
92 "pipe",
93 "newcolumns",
94 "differencecolumns",
95 "despike",
96 "nowarnings",
97 "savitzkygolay",
98 "majorOrder",
99 "medianFilter",
100 "gaussian"
101};
102
103static char *USAGE =
104 "sddssmooth [<inputfile>] [<outputfile>]\n"
105 " [-pipe=[input][,output]]\n"
106 " -columns=<name>[,...]\n"
107 " [-points=<oddInteger>]\n"
108 " [-passes=<integer>]\n"
109 " [-gaussian=<sigmaValueIn#Rows>]\n"
110 " [-despike[=neighbors=<integer>,passes=<integer>,averageOf=<integer>,threshold=<value>]]\n"
111 " [-SavitzkyGolay=<left>,<right>,<order>[,<derivativeOrder>]]\n"
112 " [-medianFilter=windowSize=<integer>]\n"
113 " [-newColumns]\n"
114 " [-differenceColumns]\n"
115 " [-nowarnings]\n"
116 " [-majorOrder=row|column]\n"
117 "Options:\n"
118 " -pipe=[input][,output] The standard SDDS Toolkit pipe option.\n"
119 " -columns=<name>[,...] Specifies the names of the column(s) to smooth. The names may include wildcards.\n"
120 " -points=<oddInteger> Specifies the number of points to average to create a smoothed value for each point.\n"
121 " Must be an odd integer. Default is 3.\n"
122 " -passes=<integer> Specifies the number of nearest-neighbor-averaging smoothing passes to make over each column of data.\n"
123 " Default is 1. If 0, no such smoothing is done. In the limit of an infinite number of passes,\n"
124 " every point will tend toward the average value of the original data.\n"
125 " If -despike is also given, then despiking occurs first.\n"
126 " -gaussian=<sigmaValueIn#Rows> Smooths with a Gaussian kernel using the given sigma. Sigma is expressed in terms of the number of rows.\n"
127 " -despike[=neighbors=<integer>,passes=<integer>,averageOf=<integer>,threshold=<value>]\n"
128 " Specifies smoothing by despiking. By default, 4 nearest-neighbors are used and 1 pass is done.\n"
129 " If this option is not given, no despiking is done.\n"
130 " -SavitzkyGolay=<left>,<right>,<order>[,<derivativeOrder>]\n"
131 " Specifies smoothing by using a Savitzky-Golay filter, which involves fitting a polynomial of specified order through left + right + 1 points.\n"
132 " Optionally, takes the derivativeOrder-th derivative of the data.\n"
133 " If this option is given, nearest-neighbor-averaging smoothing is not done.\n"
134 " If -despike is also given, then despiking occurs first.\n"
135 " -medianFilter=windowSize=<integer> Specifies median-filter-based smoothing with the given window size (must be an odd integer, default is 3).\n"
136 " It smooths the original data by finding the median of a data point among the nearest left (W-1)/2 points,\n"
137 " the data point itself, and the nearest right (W-1)/2 points.\n"
138 " -newColumns Specifies that the smoothed data will be placed in new columns, rather than replacing\n"
139 " the data in each column with the smoothed result. The new columns are named columnNameSmoothed,\n"
140 " where columnName is the original name of a column.\n"
141 " -differenceColumns Specifies that additional columns be created in the output file, containing the difference between\n"
142 " the original data and the smoothed data. The new columns are named columnNameUnsmooth,\n"
143 " where columnName is the original name of the column.\n"
144 " -nowarnings Suppresses warning messages.\n"
145 " -majorOrder=row|column Specifies the major order for data processing: row or column.\n"
146 "\nProgram by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
147
148long resolveColumnNames(SDDS_DATASET *SDDSin, char ***column, int32_t *columns);
149void gaussianConvolution(double *data, int64_t rows, double sigma);
150
151#define FL_NEWCOLUMNS 0x0001UL
152#define FL_DIFCOLUMNS 0x0002UL
153
154#define DESPIKE_AVERAGEOF 0x0001U
155
156int main(int argc, char **argv) {
157 int iArg;
158 char **inputColumn, **outputColumn, **difColumn;
159 int32_t columns;
160 long despike, median, smooth;
161 int32_t despikeNeighbors, despikePasses, despikeAverageOf;
162 char *input, *output;
163 long i, readCode;
164 int64_t j, rows;
165 int32_t smoothPoints, smoothPasses;
166 long noWarnings, medianWindowSize = 3;
167 unsigned long pipeFlags, flags, despikeFlags, majorOrderFlag, dummyFlags;
168 SCANNED_ARG *scanned;
169 SDDS_DATASET SDDSin, SDDSout;
170 double *data, despikeThreshold;
171 int32_t SGLeft, SGRight, SGOrder, SGDerivOrder;
172 short columnMajorOrder = -1;
173 double gaussianSigma = 0;
174
176 argc = scanargs(&scanned, argc, argv);
177 if (argc < 3 || argc > (3 + N_OPTIONS))
178 bomb(NULL, USAGE);
179
180 output = input = NULL;
181 inputColumn = outputColumn = NULL;
182 columns = 0;
183 pipeFlags = 0;
184 smoothPoints = 3;
185 smoothPasses = 1;
186 flags = 0;
187 despike = 0;
188 median = 0;
189 smooth = 0;
190 noWarnings = 0;
191 SGOrder = -1;
192 SGDerivOrder = 0;
193
194 for (iArg = 1; iArg < argc; iArg++) {
195 if (scanned[iArg].arg_type == OPTION) {
196 /* process options here */
197 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
198 case CLO_PASSES:
199 smooth = 1;
200 if (scanned[iArg].n_items != 2 ||
201 sscanf(scanned[iArg].list[1], "%" SCNd32, &smoothPasses) != 1 ||
202 smoothPasses < 0)
203 SDDS_Bomb("invalid -passes syntax/value");
204 break;
205 case CLO_GAUSSIAN:
206 gaussianSigma = 0;
207 if (scanned[iArg].n_items != 2 ||
208 sscanf(scanned[iArg].list[1], "%lf", &gaussianSigma) != 1 ||
209 gaussianSigma <= 0)
210 SDDS_Bomb("invalid -gaussian syntax/value");
211 break;
212 case CLO_POINTS:
213 if (scanned[iArg].n_items != 2 ||
214 sscanf(scanned[iArg].list[1], "%" SCNd32, &smoothPoints) != 1 ||
215 smoothPoints < 1 ||
216 smoothPoints % 2 == 0)
217 SDDS_Bomb("invalid -points syntax/value");
218 break;
219 case CLO_COLUMNS:
220 if (scanned[iArg].n_items < 2)
221 SDDS_Bomb("invalid -columns syntax");
222 inputColumn = tmalloc(sizeof(*inputColumn) * (columns = scanned[iArg].n_items - 1));
223 for (i = 0; i < columns; i++)
224 inputColumn[i] = scanned[iArg].list[i + 1];
225 break;
226 case CLO_PIPE:
227 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
228 SDDS_Bomb("invalid -pipe syntax");
229 break;
230 case CLO_NEWCOLUMNS:
231 flags |= FL_NEWCOLUMNS;
232 break;
233 case CLO_DIFFERENCECOLUMNS:
234 flags |= FL_DIFCOLUMNS;
235 break;
236 case CLO_DESPIKE:
237 scanned[iArg].n_items--;
238 despikeNeighbors = 4;
239 despikePasses = 1;
240 despikeThreshold = 0;
241 despikeAverageOf = 2;
242 if (scanned[iArg].n_items > 0 &&
243 (!scanItemList(&despikeFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
244 "neighbors", SDDS_LONG, &despikeNeighbors, 1, 0,
245 "passes", SDDS_LONG, &despikePasses, 1, 0,
246 "averageof", SDDS_LONG, &despikeAverageOf, 1, DESPIKE_AVERAGEOF,
247 "threshold", SDDS_DOUBLE, &despikeThreshold, 1, 0, NULL) ||
248 despikeNeighbors < 2 || despikePasses < 1 || despikeAverageOf < 2 || despikeThreshold < 0)) {
249 fprintf(stderr, "sddssmooth: Invalid -despike syntax/values: neighbors=%" PRId32 ", passes=%" PRId32 ", averageOf=%" PRId32 ", threshold=%e\n", despikeNeighbors, despikePasses, despikeAverageOf, despikeThreshold);
250 exit(EXIT_FAILURE);
251 }
252 if (!(despikeFlags & DESPIKE_AVERAGEOF))
253 despikeAverageOf = despikeNeighbors;
254 if (despikeAverageOf > despikeNeighbors)
255 SDDS_Bomb("invalid -despike syntax/values: averageOf>neighbors");
256 despike = 1;
257 break;
258 case CLO_MEDIAN_FILTER:
259 scanned[iArg].n_items--;
260 medianWindowSize = 0;
261 if (scanned[iArg].n_items > 0 &&
262 (!scanItemList(&dummyFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
263 "windowSize", SDDS_LONG, &medianWindowSize, 1, 0, NULL) ||
264 medianWindowSize < 0 || (medianWindowSize!=0 && medianWindowSize%2!=1))) {
265 fprintf(stderr, "sddssmooth: Invalid -medianFilter syntax/values: windowSize=%ld (0=no median filter, odd value required)\n", medianWindowSize);
266 exit(EXIT_FAILURE);
267 }
268 if (medianWindowSize>1)
269 median = 1;
270 break;
271 case CLO_NOWARNINGS:
272 noWarnings = 1;
273 break;
274 case CLO_SAVITZKYGOLAY:
275 if ((scanned[iArg].n_items != 4 && scanned[iArg].n_items != 5) ||
276 sscanf(scanned[iArg].list[1], "%" SCNd32, &SGLeft) != 1 ||
277 sscanf(scanned[iArg].list[2], "%" SCNd32, &SGRight) != 1 ||
278 sscanf(scanned[iArg].list[3], "%" SCNd32, &SGOrder) != 1 ||
279 (scanned[iArg].n_items == 5 && sscanf(scanned[iArg].list[4], "%" SCNd32, &SGDerivOrder) != 1) ||
280 SGLeft < 0 ||
281 SGRight < 0 ||
282 (SGLeft + SGRight) < SGOrder ||
283 SGOrder < 0 ||
284 SGDerivOrder < 0)
285 SDDS_Bomb("invalid -SavitzkyGolay syntax/values");
286 break;
287 case CLO_MAJOR_ORDER:
288 majorOrderFlag = 0;
289 scanned[iArg].n_items--;
290 if (scanned[iArg].n_items > 0 &&
291 (!scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
292 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
293 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
294 SDDS_Bomb("invalid -majorOrder syntax/values");
295 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
296 columnMajorOrder = 1;
297 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
298 columnMajorOrder = 0;
299 break;
300 default:
301 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
302 exit(EXIT_FAILURE);
303 break;
304 }
305 } else {
306 if (!input)
307 input = scanned[iArg].list[0];
308 else if (!output)
309 output = scanned[iArg].list[0];
310 else
311 SDDS_Bomb("too many filenames seen");
312 }
313 }
314
315 processFilenames("sddssmooth", &input, &output, pipeFlags, 0, NULL);
316 /*do not change the previous setting; before it does smooth by default before adding median */
317 if (!median)
318 smooth = 1;
319
320 if (!despike && !smoothPasses && !median && !noWarnings)
321 fprintf(stderr, "warning: smoothing parameters won't result in any change in data (sddssmooth)\n");
322
323 if (!columns)
324 SDDS_Bomb("supply the names of columns to smooth with the -columns option");
325
326 if (!SDDS_InitializeInput(&SDDSin, input))
327 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
328
329 if (!resolveColumnNames(&SDDSin, &inputColumn, &columns))
330 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
331 if (!columns)
332 SDDS_Bomb("no columns selected for smoothing");
333
334 if (!SDDS_InitializeCopy(&SDDSout, &SDDSin, output, "w"))
335 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
336
337 outputColumn = tmalloc(sizeof(*outputColumn) * columns);
338
339 if (flags & FL_NEWCOLUMNS) {
340 for (i = 0; i < columns; i++) {
341 if (SGDerivOrder <= 0) {
342 outputColumn[i] = tmalloc(sizeof(**outputColumn) * (strlen(inputColumn[i]) + 1 + strlen("Smoothed")));
343 sprintf(outputColumn[i], "%sSmoothed", inputColumn[i]);
344 } else {
345 outputColumn[i] = tmalloc(sizeof(**outputColumn) * (strlen(inputColumn[i]) + 1 + strlen("SmoothedDeriv")) + 5);
346 sprintf(outputColumn[i], "%sSmoothedDeriv%" PRId32, inputColumn[i], SGDerivOrder);
347 }
348 if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, inputColumn[i], outputColumn[i]))
349 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
350 }
351 } else
352 for (i = 0; i < columns; i++)
353 outputColumn[i] = inputColumn[i];
354
355 difColumn = NULL;
356 if (flags & FL_DIFCOLUMNS) {
357 difColumn = tmalloc(sizeof(*difColumn) * columns);
358 for (i = 0; i < columns; i++) {
359 difColumn[i] = tmalloc(sizeof(**difColumn) * (strlen(inputColumn[i]) + 1 + strlen("Unsmooth")));
360 sprintf(difColumn[i], "%sUnsmooth", inputColumn[i]);
361 if (!SDDS_TransferColumnDefinition(&SDDSout, &SDDSin, inputColumn[i], difColumn[i]))
362 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
363 }
364 }
365
366 if ((SDDS_GetParameterIndex(&SDDSout, "SmoothPoints") < 0 &&
367 SDDS_DefineParameter1(&SDDSout, "SmoothPoints", NULL, NULL, NULL, NULL, SDDS_LONG, &smoothPoints) < 0) ||
368 (SDDS_GetParameterIndex(&SDDSout, "SmoothPasses") < 0 &&
369 SDDS_DefineParameter1(&SDDSout, "SmoothPasses", NULL, NULL, NULL, NULL, SDDS_LONG, &smoothPasses) < 0))
370 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
371 if (columnMajorOrder != -1)
372 SDDSout.layout.data_mode.column_major = columnMajorOrder;
373 else
374 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
375
376 if (!SDDS_WriteLayout(&SDDSout))
377 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
378
379 while ((readCode = SDDS_ReadPage(&SDDSin)) > 0) {
380 if (!SDDS_CopyPage(&SDDSout, &SDDSin))
381 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
382 if ((rows = SDDS_CountRowsOfInterest(&SDDSin))) {
383 for (i = 0; i < columns; i++) {
384 if (!(data = SDDS_GetColumnInDoubles(&SDDSin, inputColumn[i])))
385 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
386 if (despike)
387 despikeData(data, rows, despikeNeighbors, despikePasses, despikeAverageOf, despikeThreshold, 0);
388 if (gaussianSigma > 0)
389 gaussianConvolution(data, rows, gaussianSigma);
390 if (median) {
391 double *mData = NULL;
392 mData = malloc(sizeof(*mData) * rows);
393 median_filter(data, mData, rows, medianWindowSize);
394 memcpy(data, mData, sizeof(*mData) * rows);
395 free(mData);
396 }
397 if (SGOrder >= 0) {
398 long pass = 0;
399 for (pass = 0; pass < smoothPasses; pass++)
400 SavitzkyGolaySmooth(data, rows, SGOrder, SGLeft, SGRight, SGDerivOrder);
401 } else if (smooth && smoothPasses)
402 smoothData(data, rows, smoothPoints, smoothPasses);
403
404 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, data, rows, outputColumn[i]))
405 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
406 if (flags & FL_DIFCOLUMNS) {
407 double *data0;
408 if (!(data0 = SDDS_GetColumnInDoubles(&SDDSin, inputColumn[i])))
409 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
410 for (j = 0; j < rows; j++)
411 data0[j] -= data[j];
412 if (!SDDS_SetColumnFromDoubles(&SDDSout, SDDS_SET_BY_NAME, data0, rows, difColumn[i]))
413 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
414 free(data0);
415 }
416 free(data);
417 }
418 }
419 if (!SDDS_WritePage(&SDDSout))
420 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
421 }
422 if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
423 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
424 exit(EXIT_FAILURE);
425 }
426 return EXIT_SUCCESS;
427}
428
429long resolveColumnNames(SDDS_DATASET *SDDSin, char ***column, int32_t *columns) {
430 long i;
431
432 SDDS_SetColumnFlags(SDDSin, 0);
433 for (i = 0; i < *columns; i++) {
434 if (!SDDS_SetColumnsOfInterest(SDDSin, SDDS_MATCH_STRING, (*column)[i], SDDS_OR))
435 return 0;
436 }
437 free(*column);
438 if (!(*column = SDDS_GetColumnNames(SDDSin, columns)) || *columns == 0) {
439 SDDS_SetError("no columns found");
440 return 0;
441 }
442 return 1;
443}
444
445void gaussianConvolution(double *data, int64_t rows, double sigma) {
446 double *data1, *expFactor;
447 int64_t i, j, j1, j2, nsRows, nsPerSide;
448
449 nsPerSide = 6 * sigma;
450 nsRows = 2 * nsPerSide + 1;
451 expFactor = tmalloc(sizeof(*expFactor) * nsRows);
452 for (j = -nsPerSide; j <= nsPerSide; j++)
453 expFactor[j + nsPerSide] = exp(-sqr(j / sigma) / 2.0) / (sigma * sqrt(2 * PI));
454
455 data1 = calloc(rows, sizeof(*data1));
456 for (i = 0; i < rows; i++) {
457 j1 = i - nsPerSide;
458 j2 = i + nsPerSide;
459 if (j1 < 0)
460 j1 = 0;
461 if (j2 >= rows)
462 j2 = rows;
463 for (j = j1; j <= j2; j++)
464 data1[i] += data[j] * expFactor[j - i + nsPerSide];
465 }
466 memcpy(data, data1, sizeof(*data) * rows);
467 free(data1);
468}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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_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.
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.
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:50
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:474
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:380
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:65
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.
void median_filter(double *x, double *m, long n, long W)
Applies a median filter to an input signal.
long SavitzkyGolaySmooth(double *data, long rows, long order, long nLeft, long nRight, long derivativeOrder)
Applies Savitzky-Golay smoothing or differentiation to a data array.
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:357
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:391
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.
void smoothData(double *data, long rows, long smoothPoints, long smoothPasses)
Smooth a data array using a moving average.
Definition smooth.c:35
long despikeData(double *data, long rows, long neighbors, long passes, long averageOf, double threshold, long countLimit)
Remove spikes from a data array by comparing each point to its neighbors.
Definition smooth.c:86