SDDSlib
Loading...
Searching...
No Matches
sddsnaff.c
Go to the documentation of this file.
1/**
2 * @file sddsnaff.c
3 * @brief Determines frequency components of signals using Laskar's NAFF method.
4 *
5 * This program analyzes SDDS data files to extract fundamental frequencies,
6 * amplitudes, phases, and significances using the Numerical Analysis of
7 * Fundamental Frequencies (NAFF) method. It supports various options for
8 * data processing, including truncation, exclusion of certain quantities, and
9 * paired column analysis. FFTs are utilized in the process, and some parameters
10 * refer to FFT configurations.
11 *
12 * ## Usage
13 * ```
14 * sddsnaff [<inputfile>] [<outputfile>]
15 * [-pipe=[input][,output]]
16 * [-columns=<indep-variable>[,<depen-quantity>[,...]]]
17 * [-pair=<column1>,<column2>]
18 * [-exclude=<depen-quantity>[,...]]
19 * [-terminateSearch={changeLimit=<fraction>[,maxFrequencies=<number>] | frequencies=<number>}]
20 * [-iterateFrequency=[cycleLimit=<number>][,accuracyLimit=<fraction>]]
21 * [-truncate]
22 * [-noWarnings]
23 * [-majorOrder=row|column]
24 * ```
25 *
26 * ## Options
27 * - `-pipe`
28 * Use standard SDDS Toolkit pipe option for input and/or output.
29 *
30 * - `-columns=<indep-variable>[,<depen-quantity>[,...]]`
31 * Specify the independent variable and dependent quantities to analyze.
32 * `<depen-quantity>` entries may include wildcards.
33 *
34 * - `-pair=<column1>,<column2>`
35 * Specify a pair of columns where the first column is used to obtain the basic frequency,
36 * and the second column is used to obtain the phase at that frequency.
37 * Multiple `-pair` options can be provided.
38 * `<depen-quantity>` entries may be provided by either `-columns` or `-pair` options.
39 *
40 * - `-exclude=<depen-quantity>[,...]`
41 * Exclude specified quantities from analysis using wildcard patterns.
42 *
43 * - `-terminateSearch={changeLimit=<fraction>[,maxFrequencies=<number>] | frequencies=<number>}`
44 * Terminate the search for frequency components based on RMS change limit or a specific number of frequencies.
45 *
46 * - `-iterateFrequency=[cycleLimit=<number>][,accuracyLimit=<fraction>]`
47 * Configure the iteration parameters for frequency determination, including cycle limits and accuracy.
48 *
49 * - `-truncate`
50 * Truncate data if the number of data points is not a product of small prime numbers to speed up FFTs.
51 *
52 * - `-noWarnings`
53 * Suppress warning messages.
54 *
55 * - `-majorOrder=row|column`
56 * Specify the output file's data order as row-major or column-major.
57 *
58 * ## Description
59 * The program determines the frequency components of signals using Laskar's
60 * method of Numerical Analysis of Fundamental Frequencies (NAFF). FFTs are
61 * involved in this process, hence some of the parameters refer to FFTs.
62 *
63 * @copyright
64 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
65 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
66 *
67 * @license
68 * This file is distributed under the terms of the Software License Agreement
69 * found in the file LICENSE included with this distribution.
70 *
71 * @author M. Borland, R. Soliday, H. Shang
72 */
73
74#include "mdb.h"
75#include "SDDS.h"
76#include "scan.h"
77#include "fftpackC.h"
78#include "SDDSutils.h"
79#include <ctype.h>
80
81/* Enumeration for option types */
82enum option_type {
83 SET_TRUNCATE,
84 SET_COLUMN,
85 SET_EXCLUDE,
86 SET_PIPE,
87 SET_NOWARNINGS,
88 SET_TERM_SEARCH,
89 SET_ITERATE_FREQ,
90 SET_PAIR,
91 SET_MAJOR_ORDER,
92 N_OPTIONS
93};
94
95char *option[N_OPTIONS] = {
96 "truncate",
97 "columns",
98 "exclude",
99 "pipe",
100 "nowarnings",
101 "terminatesearch",
102 "iteratefrequency",
103 "pair",
104 "majorOrder",
105};
106
107static char *USAGE1 =
108 "Usage: sddsnaff [<inputfile>] [<outputfile>]\n"
109 " [-pipe=[input][,output]]\n"
110 " [-columns=<indep-variable>[,<depen-quantity>[,...]]]\n"
111 " [-pair=<column1>,<column2>]\n"
112 " [-exclude=<depen-quantity>[,...]]\n"
113 " [-terminateSearch={changeLimit=<fraction>[,maxFrequencies=<number>] | frequencies=<number>}]\n"
114 " [-iterateFrequency=[cycleLimit=<number>][,accuracyLimit=<fraction>]]\n"
115 " [-truncate]\n"
116 " [-noWarnings]\n"
117 " [-majorOrder=row|column]\n\n"
118 "Determines frequency components of signals using Laskar's NAFF method.\n"
119 "FFTs are involved in this process, hence some parameters refer to FFT configurations.\n\n"
120 "Options:\n"
121 " -pipe Use standard SDDS Toolkit pipe option for input and/or output.\n"
122 " -columns Specify the independent variable and dependent quantities to analyze.\n"
123 " <depen-quantity> entries may include wildcards.\n"
124 " -pair Specify a pair of columns for frequency and phase analysis.\n"
125 " Multiple -pair options can be provided.\n"
126 " -exclude Exclude specified quantities from analysis using wildcard patterns.\n"
127 " -terminateSearch Terminate the search based on RMS change limit or a specific number of frequencies.\n"
128 " -iterateFrequency Configure iteration parameters for frequency determination.\n"
129 " -truncate Truncate data to optimize FFT performance.\n"
130 " -noWarnings Suppress warning messages.\n"
131 " -majorOrder Specify output file's data order as row-major or column-major.\n\n";
132
133static char *USAGE2 =
134 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
135
136long SetupNAFFOutput(SDDS_DATASET *SDDSout, char *output, SDDS_DATASET *SDDSin,
137 char *indepQuantity, long depenQuantities, char **depenQuantity, long **frequencyIndex,
138 long **amplitudeIndex, long **phaseIndex, long **significanceIndex, char **depenQuantityPair,
139 long **amplitudeIndex1, long **phaseIndex1, long **significanceIndex1, short columnMajorOrder);
140
141#ifdef DEBUG
142double trialFn(double x, long *invalid) {
143 *invalid = 0;
144 x -= 1;
145 if (x == 0)
146 return 1;
147 return (sin(x) / x + sqr(x - 0.5) * x * 0.5);
148}
149#endif
150
151int main(int argc, char **argv) {
152 char *indepQuantity, **depenQuantity, **exclude, **depenQuantityPair;
153 long depenQuantities, excludes;
154 char *input, *output;
155 long iArg, j, readCode, noWarnings, items;
156 int64_t i, rows, rowsToUse;
157 unsigned long flags, pairFlags, tmpFlags, pipeFlags, majorOrderFlag;
158 SCANNED_ARG *scArg;
159 SDDS_DATASET SDDSin, SDDSout;
160 double *tdata, *data, t0, dt;
161 double fracRMSChangeLimit, fracFreqAccuracyLimit;
162 int32_t frequenciesDesired, maxFrequencies, freqCycleLimit;
163 short truncate;
164 double *frequency, *amplitude = NULL, *phase = NULL, *significance = NULL, *phase1 = NULL, *amplitude1 = NULL, *significance1 = NULL;
165 long *frequencyIndex, *amplitudeIndex, *phaseIndex, *significanceIndex, pairs;
166 long *amplitudeIndex1, *phaseIndex1, *significanceIndex1;
167 short columnMajorOrder = -1;
168
170
171#ifdef DEBUG
172 if (1) {
173 long code;
174 double x, y;
175 x = 1.1;
176 code = OneDFunctionOptimize(&y, &x, 0.07, -4, 4, trialFn, 50, 1e-6, 0, 1);
177 fprintf(stderr, "code: %ld x=%e, y=%e\n", code, x, y);
178
179 x = .9;
180 code = OneDFunctionOptimize(&y, &x, 0.15, -4, 4, trialFn, 50, 1e-6, 0, 1);
181 fprintf(stderr, "code: %ld x=%e, y=%e\n", code, x, y);
182
183 x = .999;
184 code = OneDFunctionOptimize(&y, &x, 0.11, -4, 4, trialFn, 50, 1e-6, 0, 1);
185 fprintf(stderr, "code: %ld x=%e, y=%e\n", code, x, y);
186 exit(EXIT_SUCCESS);
187 }
188#endif
189
190 argc = scanargs(&scArg, argc, argv);
191 if (argc < 3) {
192 fprintf(stderr, "%s%s", USAGE1, USAGE2);
193 exit(EXIT_FAILURE);
194 }
195 output = input = NULL;
196 flags = pipeFlags = excludes = truncate = pairFlags = 0;
197 indepQuantity = NULL;
198 depenQuantity = exclude = depenQuantityPair = NULL;
199 depenQuantities = 0;
200 noWarnings = 0;
201 fracRMSChangeLimit = 0.0;
202 fracFreqAccuracyLimit = 0.00001;
203 frequenciesDesired = 1;
204 maxFrequencies = 4;
205 freqCycleLimit = 100;
206 pairs = 0;
207
208 for (iArg = 1; iArg < argc; iArg++) {
209 if (scArg[iArg].arg_type == OPTION) {
210 /* Process options */
211 switch (match_string(scArg[iArg].list[0], option, N_OPTIONS, 0)) {
212 case SET_MAJOR_ORDER:
213 majorOrderFlag = 0;
214 scArg[iArg].n_items--;
215 if (scArg[iArg].n_items > 0 &&
216 (!scanItemList(&majorOrderFlag, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
217 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
218 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
219 SDDS_Bomb("invalid -majorOrder syntax/values");
220 }
221 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
222 columnMajorOrder = 1;
223 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
224 columnMajorOrder = 0;
225 break;
226
227 case SET_TRUNCATE:
228 truncate = 1;
229 break;
230
231 case SET_PAIR:
232 if (depenQuantities)
233 SDDS_Bomb("Invalid -pair option, the depen-quantity is provided by -columns option already.");
234 if (scArg[iArg].n_items != 3)
235 SDDS_Bomb("invalid -pair syntax");
236 depenQuantity = SDDS_Realloc(depenQuantity, sizeof(*depenQuantity) * (pairs + 1));
237 depenQuantityPair = SDDS_Realloc(depenQuantityPair, sizeof(*depenQuantityPair) * (pairs + 1));
238 depenQuantity[pairs] = scArg[iArg].list[1];
239 depenQuantityPair[pairs] = scArg[iArg].list[2];
240 pairs++;
241 break;
242
243 case SET_COLUMN:
244 if (indepQuantity)
245 SDDS_Bomb("only one -columns option may be given");
246 if (scArg[iArg].n_items < 2)
247 SDDS_Bomb("invalid -columns syntax");
248 indepQuantity = scArg[iArg].list[1];
249 if (scArg[iArg].n_items >= 2) {
250 if (pairs)
251 SDDS_Bomb("Invalid -columns syntax, the depen-quantity is provided by -pair option already.");
252 depenQuantity = tmalloc(sizeof(*depenQuantity) * (depenQuantities = scArg[iArg].n_items - 2));
253 for (i = 0; i < depenQuantities; i++)
254 depenQuantity[i] = scArg[iArg].list[i + 2];
255 }
256 break;
257
258 case SET_PIPE:
259 if (!processPipeOption(scArg[iArg].list + 1, scArg[iArg].n_items - 1, &pipeFlags))
260 SDDS_Bomb("invalid -pipe syntax");
261 break;
262
263 case SET_EXCLUDE:
264 if (scArg[iArg].n_items < 2)
265 SDDS_Bomb("invalid -exclude syntax");
266 moveToStringArray(&exclude, &excludes, scArg[iArg].list + 1, scArg[iArg].n_items - 1);
267 break;
268
269 case SET_NOWARNINGS:
270 noWarnings = 1;
271 break;
272
273 case SET_TERM_SEARCH:
274 items = scArg[iArg].n_items - 1;
275 flags &= ~(NAFF_RMS_CHANGE_LIMIT | NAFF_FREQS_DESIRED | NAFF_MAX_FREQUENCIES);
276 fracRMSChangeLimit = 0;
277 frequenciesDesired = 0;
278 maxFrequencies = 10;
279 if (!scanItemList(&tmpFlags, scArg[iArg].list + 1, &items, 0,
280 "changelimit", SDDS_DOUBLE, &fracRMSChangeLimit, 1, NAFF_RMS_CHANGE_LIMIT,
281 "maxfrequencies", SDDS_LONG, &maxFrequencies, 1, NAFF_MAX_FREQUENCIES,
282 "frequencies", SDDS_LONG, &frequenciesDesired, 1, NAFF_FREQS_DESIRED, NULL) ||
283 (tmpFlags & NAFF_RMS_CHANGE_LIMIT && tmpFlags & NAFF_FREQS_DESIRED) ||
284 maxFrequencies < 1) {
285 SDDS_Bomb("invalid -terminateSearch syntax");
286 }
287 flags |= tmpFlags;
288 if (frequenciesDesired)
289 maxFrequencies = frequenciesDesired;
290 break;
291
292 case SET_ITERATE_FREQ:
293 items = scArg[iArg].n_items - 1;
294 flags &= ~(NAFF_FREQ_CYCLE_LIMIT | NAFF_FREQ_ACCURACY_LIMIT);
295 if (!scanItemList(&tmpFlags, scArg[iArg].list + 1, &items, 0,
296 "cyclelimit", SDDS_LONG, &freqCycleLimit, 1, NAFF_FREQ_CYCLE_LIMIT,
297 "accuracylimit", SDDS_DOUBLE, &fracFreqAccuracyLimit, 1, NAFF_FREQ_ACCURACY_LIMIT, NULL) ||
298 !bitsSet(tmpFlags) ||
299 freqCycleLimit < 2) {
300 SDDS_Bomb("invalid -iterateFrequency syntax");
301 }
302 flags |= tmpFlags;
303 break;
304
305 default:
306 fprintf(stderr, "Error: unknown or ambiguous option: %s\n", scArg[iArg].list[0]);
307 exit(EXIT_FAILURE);
308 break;
309 }
310 } else {
311 if (!input)
312 input = scArg[iArg].list[0];
313 else if (!output)
314 output = scArg[iArg].list[0];
315 else
316 SDDS_Bomb("too many filenames provided");
317 }
318 }
319
320 processFilenames("sddsnaff", &input, &output, pipeFlags, 0, NULL);
321
322 if (!indepQuantity)
323 SDDS_Bomb("Supply the independent quantity name with the -columns option");
324
325 if (!SDDS_InitializeInput(&SDDSin, input))
326 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
327
328 if (SDDS_CheckColumn(&SDDSin, indepQuantity, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OKAY)
329 exit(EXIT_FAILURE);
330
331 excludes = appendToStringArray(&exclude, excludes, indepQuantity);
332 if (pairs) {
333 pairFlags = flags | NAFF_FREQ_FOUND;
334 depenQuantities = pairs;
335 }
336 if (!depenQuantities)
337 depenQuantities = appendToStringArray(&depenQuantity, depenQuantities, "*");
338 if (!pairs) {
339 if ((depenQuantities = expandColumnPairNames(&SDDSin, &depenQuantity, NULL, depenQuantities, exclude, excludes, FIND_NUMERIC_TYPE, 0)) <= 0) {
340 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
341 SDDS_Bomb("No quantities selected to FFT");
342 }
343 }
344
345 if (!SetupNAFFOutput(&SDDSout, output, &SDDSin, indepQuantity, depenQuantities, depenQuantity,
346 &frequencyIndex, &amplitudeIndex, &phaseIndex, &significanceIndex,
347 depenQuantityPair, &amplitudeIndex1, &phaseIndex1, &significanceIndex1,
348 columnMajorOrder)) {
349 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
350 }
351
352 if (!(frequency = SDDS_Malloc(sizeof(*frequency) * maxFrequencies)) ||
353 !(amplitude = SDDS_Malloc(sizeof(*amplitude) * maxFrequencies)) ||
354 !(phase = SDDS_Malloc(sizeof(*phase) * maxFrequencies)) ||
355 !(significance = SDDS_Malloc(sizeof(*significance) * maxFrequencies))) {
356 SDDS_Bomb("Memory allocation failure");
357 }
358 if (pairs) {
359 if (!(amplitude1 = SDDS_Malloc(sizeof(*amplitude1) * maxFrequencies)) ||
360 !(phase1 = SDDS_Malloc(sizeof(*phase1) * maxFrequencies)) ||
361 !(significance1 = SDDS_Malloc(sizeof(*significance1) * maxFrequencies))) {
362 SDDS_Bomb("Memory allocation failure");
363 }
364 }
365
366 while ((readCode = SDDS_ReadPage(&SDDSin)) > 0) {
367 if ((rows = SDDS_CountRowsOfInterest(&SDDSin)) < 0)
368 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
369 if (rows) {
370 int64_t primeRows;
371 rowsToUse = rows;
372 primeRows = greatestProductOfSmallPrimes(rows);
373 if (rows != primeRows) {
374 if (truncate)
375 rowsToUse = greatestProductOfSmallPrimes(rows);
376 else if (largest_prime_factor(rows) > 100 && !noWarnings)
377 fputs("Warning: Number of points has large prime factors.\n"
378 "This could take a very long time.\nConsider using the -truncate option.\n",
379 stderr);
380 }
381 if (!SDDS_StartPage(&SDDSout, maxFrequencies) ||
382 !SDDS_CopyParameters(&SDDSout, &SDDSin)) {
383 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
384 }
385 if (!(tdata = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
386 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
387 for (i = 1; i < rowsToUse; i++)
388 if (tdata[i] <= tdata[i - 1])
389 SDDS_Bomb("Independent data is not monotonically increasing");
390 dt = (tdata[rowsToUse - 1] - tdata[0]) / (rowsToUse - 1.0);
391 t0 = tdata[0];
392 free(tdata);
393 tdata = NULL;
394 for (i = 0; i < depenQuantities; i++) {
395 if (!(data = SDDS_GetColumnInDoubles(&SDDSin, depenQuantity[i])))
396 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
397 for (j = 0; j < maxFrequencies; j++)
398 frequency[j] = amplitude[j] = phase[j] = significance[j] = -1;
399 PerformNAFF(frequency, amplitude, phase, significance, t0, dt, data, rowsToUse, flags,
400 fracRMSChangeLimit, maxFrequencies, freqCycleLimit, fracFreqAccuracyLimit, 0, 0);
401#ifdef DEBUG
402 fprintf(stderr, "Column %s: ", depenQuantity[i]);
403 fprintf(stderr, "f=%10.3e a=%10.3e p=%10.3e s=%10.3e\n", frequency[0], amplitude[0], phase[0], significance[0]);
404#endif
405 free(data);
406 data = NULL;
407 if (pairs) {
408 if (!(data = SDDS_GetColumnInDoubles(&SDDSin, depenQuantityPair[i])))
409 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
410 PerformNAFF(frequency, amplitude1, phase1, significance1, t0, dt, data, rowsToUse,
411 pairFlags, fracRMSChangeLimit, maxFrequencies, freqCycleLimit, fracFreqAccuracyLimit, 0, 0);
412
413 for (j = 0; j < maxFrequencies; j++)
414 if (frequency[j] != -1)
415 frequency[j] = adjustFrequencyHalfPlane(frequency[j], phase[j], phase1[j], dt);
416 free(data);
417 data = NULL;
418 }
419 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, frequency, maxFrequencies, frequencyIndex[i]) ||
420 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, amplitude, maxFrequencies, amplitudeIndex[i]) ||
421 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, phase, maxFrequencies, phaseIndex[i]) ||
422 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, significance, maxFrequencies, significanceIndex[i])) {
423 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
424 }
425 if (pairs) {
426 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, amplitude1, maxFrequencies, amplitudeIndex1[i]) ||
427 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, phase1, maxFrequencies, phaseIndex1[i]) ||
428 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, significance1, maxFrequencies, significanceIndex1[i])) {
429 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
430 }
431 }
432 }
433 } else {
434 if (!SDDS_StartPage(&SDDSout, 0) || !SDDS_CopyParameters(&SDDSout, &SDDSin)) {
435 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
436 }
437 }
438 if (!SDDS_WritePage(&SDDSout))
439 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
440 }
441
442 if (!SDDS_Terminate(&SDDSin)) {
443 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
444 exit(EXIT_FAILURE);
445 }
446 if (!SDDS_Terminate(&SDDSout)) {
447 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
448 exit(EXIT_FAILURE);
449 }
450 free(frequency);
451 free(amplitude);
452 free(phase);
453 free(significance);
454 if (pairs) {
455 free(amplitude1);
456 free(phase1);
457 free(significance1);
458 free(amplitudeIndex1);
459 free(phaseIndex1);
460 free(significanceIndex1);
461 free(depenQuantityPair);
462 }
463 free(depenQuantity);
464 free(frequencyIndex);
465 free(amplitudeIndex);
466 free(phaseIndex);
467 free(significanceIndex);
468 return EXIT_SUCCESS;
469}
470
471long SetupNAFFOutput(SDDS_DATASET *SDDSout, char *output, SDDS_DATASET *SDDSin,
472 char *indepQuantity, long depenQuantities, char **depenQuantity, long **frequencyIndex,
473 long **amplitudeIndex, long **phaseIndex, long **significanceIndex, char **depenQuantityPair,
474 long **amplitudeIndex1, long **phaseIndex1, long **significanceIndex1, short columnMajorOrder) {
475 char *freqUnits, *buffer, *ampUnits;
476 long i, maxBuffer, bufferNeeded;
477
478 if (!(*frequencyIndex = SDDS_Malloc(sizeof(**frequencyIndex) * depenQuantities)) ||
479 !(*amplitudeIndex = SDDS_Malloc(sizeof(**amplitudeIndex) * depenQuantities)) ||
480 !(*phaseIndex = SDDS_Malloc(sizeof(**phaseIndex) * depenQuantities)) ||
481 !(*significanceIndex = SDDS_Malloc(sizeof(**significanceIndex) * depenQuantities)) ||
482 !(buffer = SDDS_Malloc(sizeof(*buffer) * (maxBuffer = 1024)))) {
483 SDDS_SetError("Memory allocation failure");
484 return 0;
485 }
486 if (!(freqUnits = makeFrequencyUnits(SDDSin, indepQuantity)) ||
487 !SDDS_InitializeOutput(SDDSout, SDDS_BINARY, 0, NULL, "sddsnaff output", output)) {
488 return 0;
489 }
490 if (columnMajorOrder != -1)
491 SDDSout->layout.data_mode.column_major = columnMajorOrder;
492 else
493 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
494
495 for (i = 0; i < depenQuantities; i++) {
496 if ((bufferNeeded = strlen(depenQuantity[i]) + 12) > maxBuffer &&
497 !(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * bufferNeeded))) {
498 SDDS_Bomb("Memory allocation failure");
499 }
500 sprintf(buffer, "%sFrequency", depenQuantity[i]);
501 if (((*frequencyIndex)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, freqUnits, NULL, NULL, SDDS_DOUBLE, 0)) < 0 ||
502 SDDS_GetColumnInformation(SDDSin, "units", &ampUnits, SDDS_GET_BY_NAME, depenQuantity[i]) != SDDS_STRING) {
503 return 0;
504 }
505 sprintf(buffer, "%sAmplitude", depenQuantity[i]);
506 if (((*amplitudeIndex)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, ampUnits, NULL, NULL, SDDS_DOUBLE, 0)) < 0)
507 return 0;
508 sprintf(buffer, "%sPhase", depenQuantity[i]);
509 if (((*phaseIndex)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0)
510 return 0;
511 sprintf(buffer, "%sSignificance", depenQuantity[i]);
512 if (((*significanceIndex)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0)
513 return 0;
514 }
515 if (depenQuantityPair) {
516 if (!(*amplitudeIndex1 = SDDS_Malloc(sizeof(**amplitudeIndex1) * depenQuantities)) ||
517 !(*phaseIndex1 = SDDS_Malloc(sizeof(**phaseIndex1) * depenQuantities)) ||
518 !(*significanceIndex1 = SDDS_Malloc(sizeof(**significanceIndex1) * depenQuantities))) {
519 SDDS_SetError("Memory allocation failure");
520 return 0;
521 }
522 for (i = 0; i < depenQuantities; i++) {
523 if ((bufferNeeded = strlen(depenQuantityPair[i]) + 12) > maxBuffer &&
524 !(buffer = SDDS_Realloc(buffer, sizeof(*buffer) * bufferNeeded))) {
525 SDDS_Bomb("Memory allocation failure");
526 }
527 sprintf(buffer, "%sAmplitude", depenQuantityPair[i]);
528 if (((*amplitudeIndex1)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, ampUnits, NULL, NULL, SDDS_DOUBLE, 0)) < 0)
529 return 0;
530 sprintf(buffer, "%sPhase", depenQuantityPair[i]);
531 if (((*phaseIndex1)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0)
532 return 0;
533 sprintf(buffer, "%sSignificance", depenQuantityPair[i]);
534 if (((*significanceIndex1)[i] = SDDS_DefineColumn(SDDSout, buffer, NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0)) < 0)
535 return 0;
536 }
537 }
538 free(ampUnits);
539 free(freqUnits);
540
541 if (!SDDS_TransferAllParameterDefinitions(SDDSout, SDDSin, SDDS_TRANSFER_KEEPOLD) ||
542 !SDDS_WriteLayout(SDDSout)) {
543 return 0;
544 }
545 free(buffer);
546 return 1;
547}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
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_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
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_ReadPage(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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
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_TransferAllParameterDefinitions(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, uint32_t mode)
Transfers all parameter definitions 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:379
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_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:639
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
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
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#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
long bitsSet(unsigned long data)
Counts the number of set bits (1s) in the given data.
Definition binary.c:52
int64_t largest_prime_factor(int64_t number)
Find the largest prime factor of a number.
Definition factorize.c:83
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.