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

Detailed Description

SDDS-format 2D FFT program.

This program performs a two-dimensional Fast Fourier Transform (FFT) on data formatted in the Self Describing Data Set (SDDS) format. It provides various options for normalization, padding, truncation, suppressing averages, and more to customize the FFT process.

Usage

sdds2dfft [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
-columns=<indep-variable>[,<depen-quantity>[,...]]
[-complexInput[=unfolded|folded]]
[-exclude=<depen-quantity>[,...]]
[-sampleInterval=<number>]
[-normalize]
[-fullOutput[=unfolded|folded],unwrapLimit=<value>]
[-psdOutput[=plain][,{integrated|rintegrated[=<cutoff>]}]]
[-inverse]
[-padwithzeroes[=exponent]]
[-truncate]
[-suppressaverage]
[-noWarnings]
[-majorOrder=row|column]

Options

Required Description
-columns Specify independent and dependent variables for FFT analysis.
Optional Description
-pipe Standard SDDS Toolkit pipe option.
-complexInput Indicates the input columns are in complex form.
-exclude Exclude quantities from analysis using wildcards.
-sampleInterval Request sampling of input data points at specified intervals.
-normalize Normalize output to a peak magnitude of 1.
-fullOutput Request real and imaginary parts of the FFT.
-psdOutput Request Power Spectral Density (PSD) output.
-inverse Perform inverse Fourier transform.
-padwithzeroes Pad data with zeroes to match required data points.
-truncate Truncate data to match required data points.
-suppressaverage Suppress the average value before FFT.
-noWarnings Suppress warning messages.
-majorOrder Specify output file's data order (row or column).

Incompatibilities

  • -inverse is incompatible with:
    • -complexInput=folded
  • -padwithzeroes is incompatible with -truncate.
  • For -complexInput:
    • Requires -columns specifying dependent quantities in pairs (real, imaginary).
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
H. Shang, R. Soliday

Definition in file sdds2dfft.c.

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

Go to the source code of this file.

Functions

int64_t greatestProductOfSmallPrimes (int64_t rows)
 
long create_fft_frequency_column (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, char *timeName, char *freqUnits, long inverse)
 
long create_fft_columns (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, char *origName, char *indepName, char *freqUnits, long full_output, unsigned long psd_output, long complexInput, long inverse, long unwrap_phase)
 
long create_fft_parameters (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, char *indepName, char *freqUnits)
 
char * makeFrequencyUnits (SDDS_DATASET *SDDSin, char *indepName)
 
long expandComplexColumnPairNames (SDDS_DATASET *SDDSin, char **name, char ***realName, char ***imagName, long names, char **excludeName, long excludeNames, long typeMode, long typeValue)
 
void moveToStringArrayComplex (char ***targetReal, char ***targetImag, long *targets, char **sourceReal, char **sourceImag, long sources)
 
int main (int argc, char **argv)
 

Function Documentation

◆ create_fft_columns()

long create_fft_columns ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
char * origName,
char * indepName,
char * freqUnits,
long full_output,
unsigned long psd_output,
long complexInput,
long inverse,
long unwrap_phase )

Definition at line 696 of file sdds2dfft.c.

698 {
699 char s[SDDS_MAXLINE];
700 char *origUnits, *origSymbol;
701 char *description, *name, *symbol, *units;
702 long index0, index1;
703 long offset = 0;
704
705 if (complexInput)
706 offset = 4;
707 if (SDDS_GetColumnInformation(SDDSin, "units", &origUnits, SDDS_GET_BY_NAME, origName) != SDDS_STRING ||
708 SDDS_GetColumnInformation(SDDSin, "symbol", &origSymbol, SDDS_GET_BY_NAME, origName) != SDDS_STRING)
709 return 0;
710 if (!inverse)
711 sprintf(s, "FFT%s", origName + offset);
712 else {
713 if (strncmp(origName, "FFT", 3) == 0)
714 offset = 3;
715 else if (strncmp(origName, "RealFFT", 7) == 0)
716 offset = 7;
717 else
718 offset = 0;
719 sprintf(s, "%s", origName + offset);
720 }
721 SDDS_CopyString(&name, s);
722 if (!origSymbol)
723 SDDS_CopyString(&origSymbol, origName + offset);
724 sprintf(s, "FFT %s", origSymbol);
725 SDDS_CopyString(&symbol, s);
726
727 sprintf(s, "Amplitude of FFT of %s", origSymbol);
728 SDDS_CopyString(&description, s);
729
730 if (SDDS_NumberOfErrors() ||
731 (index0 = SDDS_DefineColumn(SDDSout, name, symbol, origUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
732 return 0;
733 free(name);
734 free(symbol);
735 free(description);
736
737 if (fftOffset == -1)
738 fftOffset = 0;
739
740 if (psd_output & FL_PSDOUTPUT) {
741 if (origUnits && !SDDS_StringIsBlank(origUnits)) {
742 if (freqUnits && !SDDS_StringIsBlank(freqUnits)) {
743 sprintf(s, "(%s)$a2$n/(%s)", origUnits, freqUnits);
744 } else
745 sprintf(s, "(%s)$a2$n", origUnits);
746 SDDS_CopyString(&units, s);
747 } else
748 units = NULL;
749
750 sprintf(s, "PSD%s", origName + offset);
751 SDDS_CopyString(&name, s);
752
753 if (!origSymbol)
754 SDDS_CopyString(&origSymbol, origName + offset);
755 sprintf(s, "PSD %s", origSymbol);
756 SDDS_CopyString(&symbol, s);
757
758 sprintf(s, "PSD of %s", origSymbol);
759 SDDS_CopyString(&description, s);
760
761 if (SDDS_NumberOfErrors() ||
762 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, units, description, NULL, SDDS_DOUBLE, 0)) < 0)
763 return 0;
764 psdOffset = index1 - index0;
765 free(name);
766 if (units)
767 free(units);
768 free(symbol);
769 free(description);
770 }
771
772 if (psd_output & (FL_PSDINTEGOUTPUT + FL_PSDRINTEGOUTPUT)) {
773 if (origUnits && !SDDS_StringIsBlank(origUnits)) {
774 SDDS_CopyString(&units, origUnits);
775 } else
776 units = NULL;
777
778 sprintf(s, "SqrtIntegPSD%s", origName + offset);
779 SDDS_CopyString(&name, s);
780
781 if (!origSymbol)
782 SDDS_CopyString(&origSymbol, origName + offset);
783 sprintf(s, "Sqrt Integ PSD %s", origSymbol);
784 SDDS_CopyString(&symbol, s);
785
786 sprintf(s, "Sqrt Integ PSD of %s", origSymbol);
787 SDDS_CopyString(&description, s);
788
789 if (SDDS_NumberOfErrors() ||
790 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, units, description, NULL, SDDS_DOUBLE, 0)) < 0)
791 return 0;
792 psdIntOffset = index1 - index0;
793 free(name);
794 if (units)
795 free(units);
796 free(symbol);
797 free(description);
798 }
799
800 if (full_output) {
801 if (!inverse)
802 sprintf(s, "RealFFT%s", origName + offset);
803 else
804 sprintf(s, "Real%s", origName + offset);
805 SDDS_CopyString(&name, s);
806
807 if (!origSymbol)
808 SDDS_CopyString(&origSymbol, origName + offset);
809 if (!inverse)
810 sprintf(s, "Re[FFT %s]", origSymbol);
811 else
812 sprintf(s, "Re[%s]", origSymbol);
813 SDDS_CopyString(&symbol, s);
814
815 if (!inverse)
816 sprintf(s, "Real part of FFT of %s", origSymbol);
817 else
818 sprintf(s, "Real part of %s", origSymbol);
819 SDDS_CopyString(&description, s);
820
821 if (SDDS_NumberOfErrors() ||
822 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, origUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
823 return 0;
824 realOffset = index1 - index0;
825 free(name);
826 free(symbol);
827 free(description);
828
829 if (!inverse)
830 sprintf(s, "ImagFFT%s", origName + offset);
831 else
832 sprintf(s, "Imag%s", origName + offset);
833 SDDS_CopyString(&name, s);
834
835 if (!origSymbol)
836 SDDS_CopyString(&origSymbol, origName + offset);
837 if (!inverse)
838 sprintf(s, "Im[FFT %s]", origSymbol);
839 else
840 sprintf(s, "Im[%s]", origSymbol);
841 SDDS_CopyString(&symbol, s);
842
843 if (!inverse)
844 sprintf(s, "Imaginary part of FFT of %s", origSymbol);
845 else
846 sprintf(s, "Imaginary part of %s", origSymbol);
847 SDDS_CopyString(&description, s);
848
849 if (SDDS_NumberOfErrors() ||
850 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, origUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
851 return 0;
852 imagOffset = index1 - index0;
853 free(name);
854 free(symbol);
855 free(description);
856
857 if (!inverse)
858 sprintf(s, "ArgFFT%s", origName + offset);
859 else
860 sprintf(s, "Arg%s", origName + offset);
861 SDDS_CopyString(&name, s);
862
863 if (!origSymbol)
864 SDDS_CopyString(&origSymbol, origName + offset);
865 if (!inverse)
866 sprintf(s, "Arg[FFT %s]", origSymbol);
867 else
868 sprintf(s, "Arg[%s]", origSymbol);
869 SDDS_CopyString(&symbol, s);
870
871 if (!inverse)
872 sprintf(s, "Phase of FFT of %s", origSymbol);
873 else
874 sprintf(s, "Phase of %s", origSymbol);
875 SDDS_CopyString(&description, s);
876
877 if (SDDS_NumberOfErrors() ||
878 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, "degrees", description, NULL, SDDS_DOUBLE, 0)) < 0)
879 return 0;
880 argOffset = index1 - index0;
881 free(name);
882 free(symbol);
883 free(description);
884 if (unwrap_phase) {
885 if (!inverse)
886 sprintf(s, "UnwrapArgFFT%s", origName + offset);
887 else
888 sprintf(s, "UnwrapArg%s", origName + offset);
889 SDDS_CopyString(&name, s);
890
891 if (!origSymbol)
892 SDDS_CopyString(&origSymbol, origName + offset);
893 if (!inverse)
894 sprintf(s, "UnwrapArg[FFT %s]", origSymbol);
895 else
896 sprintf(s, "UnwrapArg[%s]", origSymbol);
897 SDDS_CopyString(&symbol, s);
898
899 if (!inverse)
900 sprintf(s, "Unwrapped Phase of FFT of %s", origSymbol);
901 else
902 sprintf(s, "Unwrapped Phase of %s", origSymbol);
903 SDDS_CopyString(&description, s);
904
905 if (SDDS_NumberOfErrors() ||
906 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, "degrees", description, NULL, SDDS_DOUBLE, 0)) < 0)
907 return 0;
908 unwrappedArgOffset = index1 - index0;
909 free(name);
910 free(symbol);
911 free(description);
912 }
913 }
914
915 free(origSymbol);
916 return 1;
917}
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_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_NumberOfErrors()
Retrieves the number of errors recorded by SDDS library routines.
Definition SDDS_utils.c:304
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
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
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37

◆ create_fft_frequency_column()

long create_fft_frequency_column ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
char * timeName,
char * freqUnits,
long inverse )

Definition at line 664 of file sdds2dfft.c.

664 {
665 char s[SDDS_MAXLINE];
666 char *timeSymbol;
667 char *description;
668
669 if (SDDS_GetColumnInformation(SDDSin, "symbol", &timeSymbol, SDDS_GET_BY_NAME, timeName) != SDDS_STRING)
670 return 0;
671 if (!timeSymbol || SDDS_StringIsBlank(timeSymbol))
672 SDDS_CopyString(&timeSymbol, timeName);
673
674 sprintf(s, "Frequency for %s", timeSymbol);
675 SDDS_CopyString(&description, s);
676 if (!inverse) {
677 if (SDDS_DefineColumn(SDDSout, "f", NULL, freqUnits, description, NULL, SDDS_DOUBLE, 0) < 0) {
678 free(timeSymbol);
679 free(description);
680 return 0;
681 }
682 } else {
683 sprintf(s, "inverse for %s", timeSymbol);
684 SDDS_CopyString(&description, s);
685 if (SDDS_DefineColumn(SDDSout, "t", NULL, freqUnits, description, NULL, SDDS_DOUBLE, 0) < 0) {
686 free(timeSymbol);
687 free(description);
688 return 0;
689 }
690 }
691 free(timeSymbol);
692 free(description);
693 return 1;
694}

◆ expandComplexColumnPairNames()

long expandComplexColumnPairNames ( SDDS_DATASET * SDDSin,
char ** name,
char *** realName,
char *** imagName,
long names,
char ** excludeName,
long excludeNames,
long typeMode,
long typeValue )

Definition at line 919 of file sdds2dfft.c.

920 {
921 long i, j, k, realNames, imagNames, names2;
922 char **realName1, **imagName1, **realName2, **imagName2;
923 char *realPattern, *imagPattern = NULL;
924 long longest;
925
926 if (!names || !name)
927 return 0;
928 realName1 = imagName1 = realName2 = imagName2 = NULL;
929 realNames = imagNames = names2 = 0;
930 for (i = longest = 0; i < names; i++) {
931 if (strlen(name[i]) > longest)
932 longest = strlen(name[i]);
933 }
934 longest += 10;
935 if (!(realPattern = SDDS_Malloc(sizeof(*realPattern) * longest)) ||
936 !(imagPattern = SDDS_Malloc(sizeof(*imagPattern) * longest)))
937 SDDS_Bomb("Memory allocation failure");
938
939 for (i = 0; i < names; i++) {
940 for (j = 0; j < 2; j++) {
941 if (j == 0) {
942 sprintf(realPattern, "Real%s", name[i]);
943 sprintf(imagPattern, "Imag%s", name[i]);
944 } else {
945 sprintf(realPattern, "%sReal", name[i]);
946 sprintf(imagPattern, "%sImag", name[i]);
947 }
948 switch (typeMode) {
949 case FIND_ANY_TYPE:
950 case FIND_NUMERIC_TYPE:
951 case FIND_INTEGER_TYPE:
952 case FIND_FLOATING_TYPE:
953 realNames = SDDS_MatchColumns(SDDSin, &realName1, SDDS_MATCH_STRING, typeMode, realPattern, SDDS_0_PREVIOUS | SDDS_OR);
954 imagNames = SDDS_MatchColumns(SDDSin, &imagName1, SDDS_MATCH_STRING, typeMode, imagPattern, SDDS_0_PREVIOUS | SDDS_OR);
955 break;
956 case FIND_SPECIFIED_TYPE:
957 if (!SDDS_VALID_TYPE(typeValue))
958 SDDS_Bomb("Invalid type value in expandColumnPairNames");
959 realNames = SDDS_MatchColumns(SDDSin, &realName1, SDDS_MATCH_STRING, typeMode, typeValue, realPattern, SDDS_0_PREVIOUS | SDDS_OR);
960 imagNames = SDDS_MatchColumns(SDDSin, &imagName1, SDDS_MATCH_STRING, typeMode, typeValue, imagPattern, SDDS_0_PREVIOUS | SDDS_OR);
961 break;
962 default:
963 SDDS_Bomb("Invalid typeMode in expandColumnPairNames");
964 exit(EXIT_FAILURE);
965 break;
966 }
967 if (realNames == 0)
968 continue;
969 if (realNames == -1 || imagNames == -1) {
970 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
971 SDDS_Bomb("Unable to perform column name match in expandColumnPairNames");
972 }
973 if (realNames != imagNames)
974 SDDS_Bomb("Found different number of real and imaginary columns");
975 if (excludeNames) {
976 for (j = 0; j < excludeNames; j++)
977 for (k = 0; k < realNames; k++)
978 if (wild_match(realName1[k], excludeName[j])) {
979 free(realName1[k]);
980 free(imagName1[k]);
981 imagName1[k] = realName1[k] = NULL;
982 }
983 }
984 moveToStringArrayComplex(&realName2, &imagName2, &names2, realName1, imagName1, realNames);
985 free(realName1);
986 free(imagName1);
987 }
988 }
989 free(realPattern);
990 free(imagPattern);
991 if (names2 == 0)
992 return 0;
993 *realName = realName2;
994 *imagName = imagName2;
995 return names2;
996}
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
int32_t SDDS_MatchColumns(SDDS_DATASET *SDDS_dataset, char ***nameReturn, int32_t matchMode, int32_t typeMode,...)
Matches and retrieves column names from an SDDS dataset based on 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_VALID_TYPE(type)
Validates whether the given type identifier is within the defined range of SDDS types.
Definition SDDStypes.h:149
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49

◆ greatestProductOfSmallPrimes()

int64_t greatestProductOfSmallPrimes ( int64_t rows)

Definition at line 277 of file SDDSutils.c.

279{
280 int64_t bestResult = 0, result, nPrimes;
281 static int64_t prime[MAXPRIMES] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
282 71, 73, 79, 83, 89, 97};
283
284 for (nPrimes = 1; nPrimes <= MAXPRIMES; nPrimes++) {
285 if ((result = greatestProductOfSmallPrimes1(rows, prime, nPrimes)) > bestResult &&
286 result <= rows)
287 bestResult = result;
288 }
289 if (bestResult == 0)
290 SDDS_Bomb("couldn't find acceptable number of rows for truncation/padding");
291 return bestResult;
292}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 204 of file sdds2dfft.c.

204 {
205 int iArg, j;
206 char *freqUnits;
207 char *indepQuantity, **depenQuantity, **exclude, **realQuan = NULL, **imagQuan = NULL;
208 long depenQuantities, excludes;
209 char *input, *output;
210 long sampleInterval, readCode, noWarnings, complexInput, inverse, spectrumFoldParExist = 0, colsToUse;
211 int64_t i, rows, rowsToUse, primeRows, pow2Rows, n_freq, fftrows;
212 int32_t spectrumFolded = 0, page = 0, index;
213 unsigned long flags, pipeFlags, complexInputFlags = 0, fullOutputFlags = 0, majorOrderFlag;
214 long primeCols, pow2Cols;
215 SCANNED_ARG *scanned;
216 SDDS_DATASET SDDSin, SDDSout;
217 double *tdata, rintegCutOffFreq, unwrapLimit = 0;
218 long padFactor;
219 short columnMajorOrder = -1;
220 double length, *real_imag = NULL, **real = NULL, **imag = NULL, *real_imag1 = NULL, *fdata = NULL, df, t0, factor;
221 double dtf_real, dtf_imag, *arg = NULL, *magData = NULL;
222 char str[256], *tempStr = NULL;
223
225 argc = scanargs(&scanned, argc, argv);
226 if (argc < 3 || argc > (3 + N_OPTIONS)) {
227 fprintf(stderr, "%s%s", USAGE1, USAGE2);
228 exit(EXIT_FAILURE);
229 }
230 rintegCutOffFreq = 0;
231 output = input = NULL;
232 flags = pipeFlags = excludes = complexInput = inverse = 0;
233 sampleInterval = 1;
234 indepQuantity = NULL;
235 depenQuantity = exclude = NULL;
236 depenQuantities = 0;
237 noWarnings = 0;
238 padFactor = 0;
239
240 for (iArg = 1; iArg < argc; iArg++) {
241 if (scanned[iArg].arg_type == OPTION) {
242 /* process options here */
243 switch (match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
244 case SET_NORMALIZE:
245 flags |= FL_NORMALIZE;
246 break;
247 case SET_PADWITHZEROES:
248 flags |= FL_PADWITHZEROES;
249 if (scanned[iArg].n_items != 1) {
250 if (scanned[iArg].n_items != 2 || sscanf(scanned[iArg].list[1], "%ld", &padFactor) != 1 || padFactor < 1)
251 SDDS_Bomb("invalid -padwithzeroes syntax");
252 }
253 break;
254 case SET_TRUNCATE:
255 flags |= FL_TRUNCATE;
256 break;
257 case SET_SUPPRESSAVERAGE:
258 flags |= FL_SUPPRESSAVERAGE;
259 break;
260 case SET_SAMPLEINTERVAL:
261 if (scanned[iArg].n_items != 2 || sscanf(scanned[iArg].list[1], "%ld", &sampleInterval) != 1 || sampleInterval <= 0)
262 SDDS_Bomb("invalid -sampleinterval syntax");
263 break;
264 case SET_COLUMNS:
265 if (indepQuantity)
266 SDDS_Bomb("only one -columns option may be given");
267 if (scanned[iArg].n_items < 2)
268 SDDS_Bomb("invalid -columns syntax");
269 indepQuantity = scanned[iArg].list[1];
270 if (scanned[iArg].n_items >= 2) {
271 depenQuantity = tmalloc(sizeof(*depenQuantity) * (depenQuantities = scanned[iArg].n_items - 2));
272 for (i = 0; i < depenQuantities; i++)
273 SDDS_CopyString(&depenQuantity[i], scanned[iArg].list[i + 2]);
274 }
275 break;
276 case SET_FULLOUTPUT:
277 flags |= FL_FULLOUTPUT;
278 if (scanned[iArg].n_items >= 2) {
279 scanned[iArg].n_items--;
280 if (!scanItemList(&fullOutputFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "folded", -1, NULL, 0, FL_FULLOUTPUT_FOLDED, "unfolded", -1, NULL, 0, FL_FULLOUTPUT_UNFOLDED, "unwrapLimit", SDDS_DOUBLE, &unwrapLimit, 0, FL_UNWRAP_PHASE, NULL))
281 SDDS_Bomb("Invalid -fullOutput syntax");
282 scanned[iArg].n_items++;
283 if (fullOutputFlags & FL_FULLOUTPUT_UNFOLDED)
284 flags |= FL_FULLOUTPUT_UNFOLDED;
285 else
286 flags |= FL_FULLOUTPUT_FOLDED;
287 if (fullOutputFlags & FL_UNWRAP_PHASE)
288 flags |= FL_UNWRAP_PHASE;
289 }
290 break;
291 case SET_PIPE:
292 if (!processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
293 SDDS_Bomb("invalid -pipe syntax");
294 break;
295 case SET_PSDOUTPUT:
296 if (scanned[iArg].n_items > 1) {
297 unsigned long tmpFlags;
298 if (strchr(scanned[iArg].list[1], '=') == NULL) {
299 if (!scanItemList(&tmpFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "integrated", -1, NULL, 0, FL_PSDINTEGOUTPUT, "rintegrated", -1, NULL, 0, FL_PSDRINTEGOUTPUT, "plain", -1, NULL, 0, FL_PSDOUTPUT, NULL))
300 SDDS_Bomb("invalid -psdOutput syntax");
301 } else {
302 if (!scanItemList(&tmpFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "integrated", -1, NULL, 0, FL_PSDINTEGOUTPUT, "rintegrated", SDDS_DOUBLE, &rintegCutOffFreq, 0, FL_PSDRINTEGOUTPUT, "plain", -1, NULL, 0, FL_PSDOUTPUT, NULL))
303 SDDS_Bomb("invalid -psdOutput syntax");
304 }
305 flags |= tmpFlags;
306 } else {
307 flags |= FL_PSDOUTPUT;
308 }
309 if ((flags & FL_PSDINTEGOUTPUT) && (flags & FL_PSDRINTEGOUTPUT))
310 SDDS_Bomb("invalid -psdOutput syntax: give only one of integrated or rintegrated");
311 break;
312 case SET_EXCLUDE:
313 if (scanned[iArg].n_items < 2)
314 SDDS_Bomb("invalid -exclude syntax");
315 moveToStringArray(&exclude, &excludes, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
316 break;
317 case SET_NOWARNINGS:
318 noWarnings = 1;
319 break;
320 case SET_COMPLEXINPUT:
321 complexInput = 1;
322 if (scanned[iArg].n_items == 2) {
323 scanned[iArg].n_items--;
324 if (!scanItemList(&complexInputFlags, scanned[iArg].list + 1, &scanned[iArg].n_items, 0, "folded", -1, NULL, 0, FL_COMPLEXINPUT_FOLDED, "unfolded", -1, NULL, 0, FL_COMPLEXINPUT_UNFOLDED, NULL))
325 SDDS_Bomb("Invalid -complexInput syntax");
326 scanned[iArg].n_items++;
327 }
328 break;
329 case SET_INVERSE:
330 inverse = 1;
331 break;
332 case SET_MAJOR_ORDER:
333 majorOrderFlag = 0;
334 scanned[iArg].n_items--;
335 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)))
336 SDDS_Bomb("invalid -majorOrder syntax/values");
337 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
338 columnMajorOrder = 1;
339 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
340 columnMajorOrder = 0;
341 break;
342 default:
343 fprintf(stderr, "error: unknown/ambiguous option: %s\n", scanned[iArg].list[0]);
344 exit(EXIT_FAILURE);
345 break;
346 }
347 } else {
348 if (!input)
349 input = scanned[iArg].list[0];
350 else if (!output)
351 output = scanned[iArg].list[0];
352 else
353 SDDS_Bomb("too many filenames seen");
354 }
355 }
356 if (!complexInput) {
357 if (!noWarnings && inverse)
358 fprintf(stderr, "Warning: The inverse option is ignored since it only works with -complexInput.\n");
359 inverse = 0;
360 }
361 if (!noWarnings && inverse && (flags & FL_FULLOUTPUT_FOLDED))
362 fprintf(stderr, "Warning: The combination of -inverse and -fullOutput=folded will be changed to -inverse -fullOutput=unfolded.\n");
363
364 processFilenames("sdds2dfft", &input, &output, pipeFlags, 0, NULL);
365
366 if (!indepQuantity)
367 SDDS_Bomb("Supply the independent quantity name with the -columns option");
368
369 if ((flags & FL_TRUNCATE) && (flags & FL_PADWITHZEROES))
370 SDDS_Bomb("Specify only one of -padwithzeroes and -truncate");
371 if (!inverse) {
372 /* For 2D FFT, always use full output unfolded */
373 flags |= FL_FULLOUTPUT;
374 flags |= FL_FULLOUTPUT_UNFOLDED;
375 }
376 if (!SDDS_InitializeInput(&SDDSin, input))
377 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
378
379 if (SDDS_CheckColumn(&SDDSin, indepQuantity, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OKAY)
380 exit(EXIT_FAILURE);
381
382 excludes = appendToStringArray(&exclude, excludes, indepQuantity);
383 if (!depenQuantities)
384 depenQuantities = appendToStringArray(&depenQuantity, depenQuantities, "*");
385
386 if (!complexInput) {
387 if ((depenQuantities = expandColumnPairNames(&SDDSin, &depenQuantity, NULL, depenQuantities, exclude, excludes, FIND_NUMERIC_TYPE, 0)) <= 0) {
388 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
389 SDDS_Bomb("No quantities selected to FFT");
390 }
391 } else {
392 if ((depenQuantities = expandComplexColumnPairNames(&SDDSin, depenQuantity, &realQuan, &imagQuan, depenQuantities, exclude, excludes, FIND_NUMERIC_TYPE, 0)) <= 0) {
393 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
394 SDDS_Bomb("No quantities selected to FFT");
395 }
396 }
397
398#if 0
399 fprintf(stderr, "%ld dependent quantities:\n", depenQuantities);
400 for (i = 0; i < depenQuantities; i++)
401 fprintf(stderr, " %s\n", depenQuantity[i]);
402#endif
403
404 if (!(freqUnits = makeFrequencyUnits(&SDDSin, indepQuantity)) ||
405 !SDDS_InitializeOutput(&SDDSout, SDDS_BINARY, 0, NULL, "sdds2dfft output", output) ||
406 !create_fft_frequency_column(&SDDSout, &SDDSin, indepQuantity, freqUnits, inverse) ||
407 SDDS_DefineParameter(&SDDSout, "fftFrequencies", NULL, NULL, NULL, NULL, SDDS_LONG, NULL) < 0 ||
408 SDDS_DefineParameter(&SDDSout, "fftFrequencySpacing", "$gD$rf", freqUnits, NULL, NULL, SDDS_DOUBLE, NULL) < 0)
409 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
410 if (columnMajorOrder != -1)
411 SDDSout.layout.data_mode.column_major = columnMajorOrder;
412 else
413 SDDSout.layout.data_mode.column_major = SDDSin.layout.data_mode.column_major;
414
415 if ((flags & FL_FULLOUTPUT) && SDDS_DefineParameter(&SDDSout, "SpectrumFolded", NULL, NULL, NULL, NULL, SDDS_LONG, NULL) < 0)
416 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
417 if (complexInput) {
418 if (!complexInputFlags) {
419 if (SDDS_CheckParameter(&SDDSin, "SpectrumFolded", NULL, SDDS_LONG, NULL) == SDDS_CHECK_OK)
420 spectrumFoldParExist = 1;
421 } else if (complexInputFlags & FL_COMPLEXINPUT_UNFOLDED)
422 flags |= FL_COMPLEXINPUT_UNFOLDED;
423 else
424 flags |= FL_COMPLEXINPUT_FOLDED;
425 }
426 for (i = 0; i < depenQuantities; i++) {
427 if (!complexInput)
428 create_fft_columns(&SDDSout, &SDDSin, depenQuantity[i], indepQuantity, freqUnits,
429 flags & FL_FULLOUTPUT, flags & (FL_PSDOUTPUT + FL_PSDINTEGOUTPUT + FL_PSDRINTEGOUTPUT),
430 0, inverse, flags & FL_UNWRAP_PHASE);
431 else
432 create_fft_columns(&SDDSout, &SDDSin, realQuan[i], indepQuantity, freqUnits,
433 flags & FL_FULLOUTPUT, flags & (FL_PSDOUTPUT + FL_PSDINTEGOUTPUT + FL_PSDRINTEGOUTPUT),
434 1, inverse, flags & FL_UNWRAP_PHASE);
435 }
436
437 if (!SDDS_TransferAllParameterDefinitions(&SDDSout, &SDDSin, SDDS_TRANSFER_KEEPOLD) || !SDDS_WriteLayout(&SDDSout))
438 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
439
440 colsToUse = depenQuantities;
441 primeCols = greatestProductOfSmallPrimes(depenQuantities);
442 if (depenQuantities != primeCols || padFactor) {
443 if (flags & FL_PADWITHZEROES) {
444 pow2Cols = ipow(2., ((long)(log((double)depenQuantities) / log(2.0F))) + (padFactor ? padFactor : 1));
445 if ((primeCols = greatestProductOfSmallPrimes(pow2Cols)) > depenQuantities)
446 colsToUse = primeCols;
447 else
448 colsToUse = pow2Cols;
449 fprintf(stdout, "Using %ld columns\n", colsToUse);
450 } else if (flags & FL_TRUNCATE)
451 colsToUse = greatestProductOfSmallPrimes(depenQuantities);
452 else if (largest_prime_factor(depenQuantities) > 100 && !noWarnings)
453 fputs("Warning: Number of dependent columns has large prime factors.\nThis could take a very long time.\nConsider using the -truncate option.\n", stderr);
454 }
455 real_imag = tmalloc(sizeof(*real_imag) * (2 * colsToUse + 2));
456 real = malloc(sizeof(*real) * colsToUse);
457 imag = malloc(sizeof(*imag) * colsToUse);
458
459 while ((readCode = SDDS_ReadPage(&SDDSin)) > 0) {
460 page++;
461 if ((rows = SDDS_CountRowsOfInterest(&SDDSin)) < 0)
462 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
463 if (page == 1 && spectrumFoldParExist) {
464 if (!SDDS_GetParameterAsLong(&SDDSin, "SpectrumFolded", &spectrumFolded))
465 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
466 if (spectrumFolded)
467 flags |= FL_COMPLEXINPUT_FOLDED;
468 else
469 flags |= FL_COMPLEXINPUT_UNFOLDED;
470 }
471 if (rows) {
472 rowsToUse = rows;
473 primeRows = greatestProductOfSmallPrimes(rows);
474 if (rows != primeRows || padFactor) {
475 if (flags & FL_PADWITHZEROES) {
476 pow2Rows = ipow(2., ((long)(log((double)rows) / log(2.0F))) + (padFactor ? padFactor : 1));
477 if ((primeRows = greatestProductOfSmallPrimes(pow2Rows)) > rows)
478 rowsToUse = primeRows;
479 else
480 rowsToUse = pow2Rows;
481 fprintf(stdout, "Using %" PRId64 " rows\n", rowsToUse);
482 } else if (flags & FL_TRUNCATE)
483 rowsToUse = greatestProductOfSmallPrimes(rows);
484 else if (largest_prime_factor(rows) > 100 && !noWarnings)
485 fputs("Warning: Number of points has large prime factors.\nThis could take a very long time.\nConsider using the -truncate option.\n", stderr);
486 }
487 if (!(tdata = SDDS_GetColumnInDoubles(&SDDSin, indepQuantity)))
488 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
489
490 for (j = 0; j < colsToUse; j++) {
491 real[j] = imag[j] = NULL;
492 if (j < depenQuantities) {
493 if (complexInput) {
494 if (!(real[j] = (double *)SDDS_GetColumnInDoubles(&SDDSin, realQuan[j])) ||
495 !(imag[j] = (double *)SDDS_GetColumnInDoubles(&SDDSin, imagQuan[j])))
496 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
497 } else {
498 if (!(real[j] = (double *)SDDS_GetColumnInDoubles(&SDDSin, depenQuantity[j])))
499 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
500 imag[j] = calloc(sizeof(**imag), rowsToUse);
501 }
502 if (rows < rowsToUse) {
503 real[j] = SDDS_Realloc(real[j], sizeof(**real) * rowsToUse);
504 imag[j] = SDDS_Realloc(imag[j], sizeof(**imag) * rowsToUse);
505 }
506 } else {
507 real[j] = calloc(sizeof(**real), rowsToUse);
508 imag[j] = calloc(sizeof(**imag), rowsToUse);
509 }
510 }
511 fdata = malloc(sizeof(*fdata) * rowsToUse);
512 if (rows < rowsToUse) {
513 length = ((double)rows) * (tdata[rows - 1] - tdata[0]) / ((double)rows - 1.0);
514 } else
515 length = tdata[rows - 1] - tdata[0];
516 t0 = tdata[0];
517 df = factor = 1.0 / length;
518 free(tdata);
519 for (i = 0; i < rows; i++)
520 fdata[i] = i * df;
521 for (i = rows; i < rowsToUse; i++) {
522 fdata[i] = i * df;
523 }
524 /* First perform FFT per row */
525 for (i = 0; i < rows; i++) {
526 for (j = 0; j < colsToUse; j++) {
527 real_imag[2 * j] = real_imag[2 * j + 1] = 0;
528 if (j < depenQuantities) {
529 real_imag[2 * j] = real[j][i];
530 if (imag[j])
531 real_imag[2 * j + 1] = imag[j][i];
532 else
533 real_imag[2 * j + 1] = 0;
534 }
535 }
536 complexFFT(real_imag, colsToUse, inverse);
537 for (j = 0; j < colsToUse; j++) {
538 real[j][i] = real_imag[2 * j];
539 imag[j][i] = real_imag[2 * j + 1];
540 }
541 }
542 /* Then perform FFT by column */
543 n_freq = rowsToUse;
544 fftrows = rowsToUse;
545 arg = malloc(sizeof(*arg) * rowsToUse);
546 magData = malloc(sizeof(*magData) * rowsToUse);
547 real_imag1 = calloc(sizeof(*real_imag1), 2 * fftrows + 2);
548
549 for (j = 0; j < depenQuantities; j++) {
550 for (i = 0; i < rowsToUse; i++) {
551 if (i < rows) {
552 real_imag1[2 * i] = real[j][i];
553 real_imag1[2 * i + 1] = imag[j][i];
554 } else {
555 real_imag1[2 * i] = 0;
556 real_imag1[2 * i + 1] = 0;
557 }
558 }
559 complexFFT(real_imag1, rowsToUse, inverse);
560 for (i = 0; i < n_freq; i++) {
561 dtf_real = cos(-2 * PI * fdata[i] * t0);
562 dtf_imag = sin(-2 * PI * fdata[i] * t0);
563 real[j][i] = real_imag1[2 * i] * dtf_real - real_imag1[2 * i + 1] * dtf_imag;
564 imag[j][i] = real_imag1[2 * i + 1] * dtf_real + real_imag1[2 * i] * dtf_imag;
565 magData[i] = sqrt(sqr(real[j][i]) + sqr(imag[j][i]));
566 if (real[j][i] || imag[j][i])
567 arg[i] = 180.0 / PI * atan2(imag[j][i], real[j][i]);
568 else
569 arg[i] = 0;
570 }
571 if (flags & FL_NORMALIZE) {
572 factor = -DBL_MAX;
573 for (i = 0; i < n_freq; i++)
574 if (magData[i] > factor)
575 factor = magData[i];
576 if (factor != -DBL_MAX)
577 for (i = 0; i < n_freq; i++) {
578 real[j][i] /= factor;
579 imag[j][i] /= factor;
580 magData[i] /= factor;
581 }
582 }
583 if (!inverse)
584 sprintf(str, "FFT%s", depenQuantity[j] + (imagQuan ? 4 : 0));
585 else {
586 if (complexInput)
587 tempStr = realQuan[j];
588 else
589 tempStr = depenQuantity[j];
590
591 if (strncmp(tempStr, "FFT", 3) == 0)
592 sprintf(str, "%s", tempStr + 3);
593 else if (strncmp(tempStr, "RealFFT", 7) == 0)
594 sprintf(str, "%s", tempStr + 7);
595 else
596 sprintf(str, "%s", tempStr);
597 }
598 if ((index = SDDS_GetColumnIndex(&SDDSout, str)) < 0)
599 exit(EXIT_FAILURE);
600 if (!SDDS_StartPage(&SDDSout, rowsToUse) ||
601 !SDDS_CopyParameters(&SDDSout, &SDDSin) ||
602 !SDDS_SetParameters(&SDDSout, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, "fftFrequencies", n_freq, "fftFrequencySpacing", df, NULL))
603 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
604 if (flags & FL_FULLOUTPUT) {
605 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, magData, n_freq, index) ||
606 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, real[j], n_freq, index + 1) ||
607 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, imag[j], n_freq, index + 2) ||
608 !SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, arg, n_freq, index + 3))
609 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
610 } else {
611 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, real[j], n_freq, index))
612 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
613 }
614 }
615 if (!SDDS_SetColumn(&SDDSout, SDDS_SET_BY_INDEX, fdata, n_freq, 0))
616 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
617 free(fdata);
618 free(arg);
619 free(magData);
620 for (j = 0; j < colsToUse; j++) {
621 if (real[j])
622 free(real[j]);
623 if (imag[j])
624 free(imag[j]);
625 }
626 free(real_imag1);
627 } else {
628 if (!SDDS_StartPage(&SDDSout, 0) || !SDDS_CopyParameters(&SDDSout, &SDDSin))
629 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
630 }
631 if (!SDDS_WritePage(&SDDSout))
632 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
633 }
634 if (!SDDS_Terminate(&SDDSin)) {
635 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
636 exit(EXIT_FAILURE);
637 }
638 if (!SDDS_Terminate(&SDDSout)) {
639 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
640 exit(EXIT_FAILURE);
641 }
642 if (excludes) {
643 SDDS_FreeStringArray(exclude, excludes);
644 free(exclude);
645 }
646 free(real);
647 free(imag);
648 if (realQuan) {
649 SDDS_FreeStringArray(realQuan, depenQuantities);
650 SDDS_FreeStringArray(imagQuan, depenQuantities);
651 free(realQuan);
652 free(imagQuan);
653 } else {
654 SDDS_FreeStringArray(depenQuantity, depenQuantities);
655 free(depenQuantity);
656 }
657 free(real_imag);
658 free_scanargs(&scanned, argc);
659 return EXIT_SUCCESS;
660}
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_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
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.
int32_t * SDDS_GetParameterAsLong(SDDS_DATASET *SDDS_dataset, char *parameter_name, int32_t *memory)
Retrieves the value of a specified parameter as a 32-bit integer from the current data table of a dat...
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_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_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_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_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
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_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
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.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#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
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
int64_t largest_prime_factor(int64_t number)
Find the largest prime factor of a number.
Definition factorize.c:83
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33
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
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584
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.

◆ makeFrequencyUnits()

char * makeFrequencyUnits ( SDDS_DATASET * SDDSin,
char * indepName )

Definition at line 235 of file SDDSutils.c.

235 {
236 char *timeUnits;
237 char *units;
238 long reciprocal = 0, end;
239
240 if (SDDS_GetColumnInformation(SDDSin, "units", &timeUnits, SDDS_GET_BY_NAME, indepName) != SDDS_STRING)
241 return 0;
242 if (timeUnits) {
243 while (1) {
244 end = strlen(timeUnits) - 1;
245 if (timeUnits[0] == '(' && timeUnits[end] == ')') {
246 timeUnits[end] = 0;
247 strslide(timeUnits, 1);
248 } else if (timeUnits[0] == '1' && timeUnits[1] == '/' && timeUnits[2] == '(' && timeUnits[end] == ')') {
249 timeUnits[end] = 0;
250 strslide(timeUnits, 3);
251 reciprocal = !reciprocal;
252 } else
253 break;
254 }
255 }
256 if (!timeUnits || SDDS_StringIsBlank(timeUnits)) {
257 units = tmalloc(sizeof(*units) * 1);
258 units[0] = 0;
259 return units;
260 }
261
262 if (reciprocal) {
263 if (!SDDS_CopyString(&units, timeUnits))
264 return NULL;
265 return units;
266 }
267
268 units = tmalloc(sizeof(*units) * (strlen(timeUnits) + 5));
269 if (strchr(timeUnits, ' '))
270 sprintf(units, "1/(%s)", timeUnits);
271 else
272 sprintf(units, "1/%s", timeUnits);
273 return units;
274}
char * strslide(char *s, long distance)
Slides character data within a string by a specified distance.
Definition strslide.c:32

◆ moveToStringArrayComplex()

void moveToStringArrayComplex ( char *** targetReal,
char *** targetImag,
long * targets,
char ** sourceReal,
char ** sourceImag,
long sources )

Definition at line 998 of file sdds2dfft.c.

998 {
999 long i, j;
1000 if (!sources)
1001 return;
1002 if (!(*targetReal = SDDS_Realloc(*targetReal, sizeof(**targetReal) * (*targets + sources))) ||
1003 !(*targetImag = SDDS_Realloc(*targetImag, sizeof(**targetImag) * (*targets + sources))))
1004 SDDS_Bomb("Memory allocation failure");
1005 for (i = 0; i < sources; i++) {
1006 if (sourceReal[i] == NULL || sourceImag[i] == NULL)
1007 continue;
1008 for (j = 0; j < *targets; j++)
1009 if (strcmp(sourceReal[i], (*targetReal)[j]) == 0)
1010 break;
1011 if (j == *targets) {
1012 (*targetReal)[j] = sourceReal[i];
1013 (*targetImag)[j] = sourceImag[i];
1014 *targets += 1;
1015 }
1016 }
1017}