SDDSlib
Loading...
Searching...
No Matches
sdds2dfft.c File Reference

SDDS-format 2D FFT program. More...

#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.

Macros

#define FL_TRUNCATE   0x0001
 
#define FL_PADWITHZEROES   0x0002
 
#define FL_NORMALIZE   0x0004
 
#define FL_SUPPRESSAVERAGE   0x0008
 
#define FL_FULLOUTPUT   0x0010
 
#define FL_MAKEFREQDATA   0x0020
 
#define FL_PSDOUTPUT   0x0040
 
#define FL_PSDINTEGOUTPUT   0x0080
 
#define FL_PSDRINTEGOUTPUT   0x0100
 
#define FL_FULLOUTPUT_FOLDED   0x0200
 
#define FL_FULLOUTPUT_UNFOLDED   0x0400
 
#define FL_COMPLEXINPUT_FOLDED   0x0800
 
#define FL_COMPLEXINPUT_UNFOLDED   0x1000
 
#define FL_UNWRAP_PHASE   0x2000
 

Enumerations

enum  option_type {
  SET_NORMALIZE , SET_PADWITHZEROES , SET_TRUNCATE , SET_SUPPRESSAVERAGE ,
  SET_SAMPLEINTERVAL , SET_COLUMNS , SET_FULLOUTPUT , SET_PIPE ,
  SET_PSDOUTPUT , SET_EXCLUDE , SET_NOWARNINGS , SET_COMPLEXINPUT ,
  SET_INVERSE , SET_MAJOR_ORDER , N_OPTIONS
}
 

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)
 

Variables

char * option [N_OPTIONS]
 
static char * USAGE1
 
static char * USAGE2
 
static long psdOffset
 
static long argOffset
 
static long realOffset
 
static long imagOffset
 
static long fftOffset = -1
 
static long psdIntOffset
 
static long unwrappedArgOffset = -1
 

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 allows for various options such as normalization, padding with zeroes, 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]
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
H. Shang, R. Soliday

Definition in file sdds2dfft.c.

Macro Definition Documentation

◆ FL_COMPLEXINPUT_FOLDED

#define FL_COMPLEXINPUT_FOLDED   0x0800

Definition at line 93 of file sdds2dfft.c.

◆ FL_COMPLEXINPUT_UNFOLDED

#define FL_COMPLEXINPUT_UNFOLDED   0x1000

Definition at line 94 of file sdds2dfft.c.

◆ FL_FULLOUTPUT

#define FL_FULLOUTPUT   0x0010

Definition at line 86 of file sdds2dfft.c.

◆ FL_FULLOUTPUT_FOLDED

#define FL_FULLOUTPUT_FOLDED   0x0200

Definition at line 91 of file sdds2dfft.c.

◆ FL_FULLOUTPUT_UNFOLDED

#define FL_FULLOUTPUT_UNFOLDED   0x0400

Definition at line 92 of file sdds2dfft.c.

◆ FL_MAKEFREQDATA

#define FL_MAKEFREQDATA   0x0020

Definition at line 87 of file sdds2dfft.c.

◆ FL_NORMALIZE

#define FL_NORMALIZE   0x0004

Definition at line 84 of file sdds2dfft.c.

◆ FL_PADWITHZEROES

#define FL_PADWITHZEROES   0x0002

Definition at line 83 of file sdds2dfft.c.

◆ FL_PSDINTEGOUTPUT

#define FL_PSDINTEGOUTPUT   0x0080

Definition at line 89 of file sdds2dfft.c.

◆ FL_PSDOUTPUT

#define FL_PSDOUTPUT   0x0040

Definition at line 88 of file sdds2dfft.c.

◆ FL_PSDRINTEGOUTPUT

#define FL_PSDRINTEGOUTPUT   0x0100

Definition at line 90 of file sdds2dfft.c.

◆ FL_SUPPRESSAVERAGE

#define FL_SUPPRESSAVERAGE   0x0008

Definition at line 85 of file sdds2dfft.c.

◆ FL_TRUNCATE

#define FL_TRUNCATE   0x0001

Definition at line 82 of file sdds2dfft.c.

◆ FL_UNWRAP_PHASE

#define FL_UNWRAP_PHASE   0x2000

Definition at line 95 of file sdds2dfft.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 47 of file sdds2dfft.c.

47 {
48 SET_NORMALIZE,
49 SET_PADWITHZEROES,
50 SET_TRUNCATE,
51 SET_SUPPRESSAVERAGE,
52 SET_SAMPLEINTERVAL,
53 SET_COLUMNS,
54 SET_FULLOUTPUT,
55 SET_PIPE,
56 SET_PSDOUTPUT,
57 SET_EXCLUDE,
58 SET_NOWARNINGS,
59 SET_COMPLEXINPUT,
60 SET_INVERSE,
61 SET_MAJOR_ORDER,
62 N_OPTIONS
63};

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 653 of file sdds2dfft.c.

655 {
656 char s[SDDS_MAXLINE];
657 char *origUnits, *origSymbol;
658 char *description, *name, *symbol, *units;
659 long index0, index1;
660 long offset = 0;
661
662 if (complexInput)
663 offset = 4;
664 if (SDDS_GetColumnInformation(SDDSin, "units", &origUnits, SDDS_GET_BY_NAME, origName) != SDDS_STRING ||
665 SDDS_GetColumnInformation(SDDSin, "symbol", &origSymbol, SDDS_GET_BY_NAME, origName) != SDDS_STRING)
666 return 0;
667 if (!inverse)
668 sprintf(s, "FFT%s", origName + offset);
669 else {
670 if (strncmp(origName, "FFT", 3) == 0)
671 offset = 3;
672 else if (strncmp(origName, "RealFFT", 7) == 0)
673 offset = 7;
674 else
675 offset = 0;
676 sprintf(s, "%s", origName + offset);
677 }
678 SDDS_CopyString(&name, s);
679 if (!origSymbol)
680 SDDS_CopyString(&origSymbol, origName + offset);
681 sprintf(s, "FFT %s", origSymbol);
682 SDDS_CopyString(&symbol, s);
683
684 sprintf(s, "Amplitude of FFT of %s", origSymbol);
685 SDDS_CopyString(&description, s);
686
687 if (SDDS_NumberOfErrors() ||
688 (index0 = SDDS_DefineColumn(SDDSout, name, symbol, origUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
689 return 0;
690 free(name);
691 free(symbol);
692 free(description);
693
694 if (fftOffset == -1)
695 fftOffset = 0;
696
697 if (psd_output & FL_PSDOUTPUT) {
698 if (origUnits && !SDDS_StringIsBlank(origUnits)) {
699 if (freqUnits && !SDDS_StringIsBlank(freqUnits)) {
700 sprintf(s, "(%s)$a2$n/(%s)", origUnits, freqUnits);
701 } else
702 sprintf(s, "(%s)$a2$n", origUnits);
703 SDDS_CopyString(&units, s);
704 } else
705 units = NULL;
706
707 sprintf(s, "PSD%s", origName + offset);
708 SDDS_CopyString(&name, s);
709
710 if (!origSymbol)
711 SDDS_CopyString(&origSymbol, origName + offset);
712 sprintf(s, "PSD %s", origSymbol);
713 SDDS_CopyString(&symbol, s);
714
715 sprintf(s, "PSD of %s", origSymbol);
716 SDDS_CopyString(&description, s);
717
718 if (SDDS_NumberOfErrors() ||
719 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, units, description, NULL, SDDS_DOUBLE, 0)) < 0)
720 return 0;
721 psdOffset = index1 - index0;
722 free(name);
723 if (units)
724 free(units);
725 free(symbol);
726 free(description);
727 }
728
729 if (psd_output & (FL_PSDINTEGOUTPUT + FL_PSDRINTEGOUTPUT)) {
730 if (origUnits && !SDDS_StringIsBlank(origUnits)) {
731 SDDS_CopyString(&units, origUnits);
732 } else
733 units = NULL;
734
735 sprintf(s, "SqrtIntegPSD%s", origName + offset);
736 SDDS_CopyString(&name, s);
737
738 if (!origSymbol)
739 SDDS_CopyString(&origSymbol, origName + offset);
740 sprintf(s, "Sqrt Integ PSD %s", origSymbol);
741 SDDS_CopyString(&symbol, s);
742
743 sprintf(s, "Sqrt Integ PSD of %s", origSymbol);
744 SDDS_CopyString(&description, s);
745
746 if (SDDS_NumberOfErrors() ||
747 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, units, description, NULL, SDDS_DOUBLE, 0)) < 0)
748 return 0;
749 psdIntOffset = index1 - index0;
750 free(name);
751 if (units)
752 free(units);
753 free(symbol);
754 free(description);
755 }
756
757 if (full_output) {
758 if (!inverse)
759 sprintf(s, "RealFFT%s", origName + offset);
760 else
761 sprintf(s, "Real%s", origName + offset);
762 SDDS_CopyString(&name, s);
763
764 if (!origSymbol)
765 SDDS_CopyString(&origSymbol, origName + offset);
766 if (!inverse)
767 sprintf(s, "Re[FFT %s]", origSymbol);
768 else
769 sprintf(s, "Re[%s]", origSymbol);
770 SDDS_CopyString(&symbol, s);
771
772 if (!inverse)
773 sprintf(s, "Real part of FFT of %s", origSymbol);
774 else
775 sprintf(s, "Real part of %s", origSymbol);
776 SDDS_CopyString(&description, s);
777
778 if (SDDS_NumberOfErrors() ||
779 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, origUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
780 return 0;
781 realOffset = index1 - index0;
782 free(name);
783 free(symbol);
784 free(description);
785
786 if (!inverse)
787 sprintf(s, "ImagFFT%s", origName + offset);
788 else
789 sprintf(s, "Imag%s", origName + offset);
790 SDDS_CopyString(&name, s);
791
792 if (!origSymbol)
793 SDDS_CopyString(&origSymbol, origName + offset);
794 if (!inverse)
795 sprintf(s, "Im[FFT %s]", origSymbol);
796 else
797 sprintf(s, "Im[%s]", origSymbol);
798 SDDS_CopyString(&symbol, s);
799
800 if (!inverse)
801 sprintf(s, "Imaginary part of FFT of %s", origSymbol);
802 else
803 sprintf(s, "Imaginary part of %s", origSymbol);
804 SDDS_CopyString(&description, s);
805
806 if (SDDS_NumberOfErrors() ||
807 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, origUnits, description, NULL, SDDS_DOUBLE, 0)) < 0)
808 return 0;
809 imagOffset = index1 - index0;
810 free(name);
811 free(symbol);
812 free(description);
813
814 if (!inverse)
815 sprintf(s, "ArgFFT%s", origName + offset);
816 else
817 sprintf(s, "Arg%s", origName + offset);
818 SDDS_CopyString(&name, s);
819
820 if (!origSymbol)
821 SDDS_CopyString(&origSymbol, origName + offset);
822 if (!inverse)
823 sprintf(s, "Arg[FFT %s]", origSymbol);
824 else
825 sprintf(s, "Arg[%s]", origSymbol);
826 SDDS_CopyString(&symbol, s);
827
828 if (!inverse)
829 sprintf(s, "Phase of FFT of %s", origSymbol);
830 else
831 sprintf(s, "Phase of %s", origSymbol);
832 SDDS_CopyString(&description, s);
833
834 if (SDDS_NumberOfErrors() ||
835 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, "degrees", description, NULL, SDDS_DOUBLE, 0)) < 0)
836 return 0;
837 argOffset = index1 - index0;
838 free(name);
839 free(symbol);
840 free(description);
841 if (unwrap_phase) {
842 if (!inverse)
843 sprintf(s, "UnwrapArgFFT%s", origName + offset);
844 else
845 sprintf(s, "UnwrapArg%s", origName + offset);
846 SDDS_CopyString(&name, s);
847
848 if (!origSymbol)
849 SDDS_CopyString(&origSymbol, origName + offset);
850 if (!inverse)
851 sprintf(s, "UnwrapArg[FFT %s]", origSymbol);
852 else
853 sprintf(s, "UnwrapArg[%s]", origSymbol);
854 SDDS_CopyString(&symbol, s);
855
856 if (!inverse)
857 sprintf(s, "Unwrapped Phase of FFT of %s", origSymbol);
858 else
859 sprintf(s, "Unwrapped Phase of %s", origSymbol);
860 SDDS_CopyString(&description, s);
861
862 if (SDDS_NumberOfErrors() ||
863 (index1 = SDDS_DefineColumn(SDDSout, name, symbol, "degrees", description, NULL, SDDS_DOUBLE, 0)) < 0)
864 return 0;
865 unwrappedArgOffset = index1 - index0;
866 free(name);
867 free(symbol);
868 free(description);
869 }
870 }
871
872 free(origSymbol);
873 return 1;
874}
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 621 of file sdds2dfft.c.

621 {
622 char s[SDDS_MAXLINE];
623 char *timeSymbol;
624 char *description;
625
626 if (SDDS_GetColumnInformation(SDDSin, "symbol", &timeSymbol, SDDS_GET_BY_NAME, timeName) != SDDS_STRING)
627 return 0;
628 if (!timeSymbol || SDDS_StringIsBlank(timeSymbol))
629 SDDS_CopyString(&timeSymbol, timeName);
630
631 sprintf(s, "Frequency for %s", timeSymbol);
632 SDDS_CopyString(&description, s);
633 if (!inverse) {
634 if (SDDS_DefineColumn(SDDSout, "f", NULL, freqUnits, description, NULL, SDDS_DOUBLE, 0) < 0) {
635 free(timeSymbol);
636 free(description);
637 return 0;
638 }
639 } else {
640 sprintf(s, "inverse for %s", timeSymbol);
641 SDDS_CopyString(&description, s);
642 if (SDDS_DefineColumn(SDDSout, "t", NULL, freqUnits, description, NULL, SDDS_DOUBLE, 0) < 0) {
643 free(timeSymbol);
644 free(description);
645 return 0;
646 }
647 }
648 free(timeSymbol);
649 free(description);
650 return 1;
651}

◆ 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 876 of file sdds2dfft.c.

877 {
878 long i, j, k, realNames, imagNames, names2;
879 char **realName1, **imagName1, **realName2, **imagName2;
880 char *realPattern, *imagPattern = NULL;
881 long longest;
882
883 if (!names || !name)
884 return 0;
885 realName1 = imagName1 = realName2 = imagName2 = NULL;
886 realNames = imagNames = names2 = 0;
887 for (i = longest = 0; i < names; i++) {
888 if (strlen(name[i]) > longest)
889 longest = strlen(name[i]);
890 }
891 longest += 10;
892 if (!(realPattern = SDDS_Malloc(sizeof(*realPattern) * longest)) ||
893 !(imagPattern = SDDS_Malloc(sizeof(*imagPattern) * longest)))
894 SDDS_Bomb("Memory allocation failure");
895
896 for (i = 0; i < names; i++) {
897 for (j = 0; j < 2; j++) {
898 if (j == 0) {
899 sprintf(realPattern, "Real%s", name[i]);
900 sprintf(imagPattern, "Imag%s", name[i]);
901 } else {
902 sprintf(realPattern, "%sReal", name[i]);
903 sprintf(imagPattern, "%sImag", name[i]);
904 }
905 switch (typeMode) {
906 case FIND_ANY_TYPE:
907 case FIND_NUMERIC_TYPE:
908 case FIND_INTEGER_TYPE:
909 case FIND_FLOATING_TYPE:
910 realNames = SDDS_MatchColumns(SDDSin, &realName1, SDDS_MATCH_STRING, typeMode, realPattern, SDDS_0_PREVIOUS | SDDS_OR);
911 imagNames = SDDS_MatchColumns(SDDSin, &imagName1, SDDS_MATCH_STRING, typeMode, imagPattern, SDDS_0_PREVIOUS | SDDS_OR);
912 break;
913 case FIND_SPECIFIED_TYPE:
914 if (!SDDS_VALID_TYPE(typeValue))
915 SDDS_Bomb("Invalid type value in expandColumnPairNames");
916 realNames = SDDS_MatchColumns(SDDSin, &realName1, SDDS_MATCH_STRING, typeMode, typeValue, realPattern, SDDS_0_PREVIOUS | SDDS_OR);
917 imagNames = SDDS_MatchColumns(SDDSin, &imagName1, SDDS_MATCH_STRING, typeMode, typeValue, imagPattern, SDDS_0_PREVIOUS | SDDS_OR);
918 break;
919 default:
920 SDDS_Bomb("Invalid typeMode in expandColumnPairNames");
921 exit(EXIT_FAILURE);
922 break;
923 }
924 if (realNames == 0)
925 continue;
926 if (realNames == -1 || imagNames == -1) {
927 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
928 SDDS_Bomb("Unable to perform column name match in expandColumnPairNames");
929 }
930 if (realNames != imagNames)
931 SDDS_Bomb("Found different number of real and imaginary columns");
932 if (excludeNames) {
933 for (j = 0; j < excludeNames; j++)
934 for (k = 0; k < realNames; k++)
935 if (wild_match(realName1[k], excludeName[j])) {
936 free(realName1[k]);
937 free(imagName1[k]);
938 imagName1[k] = realName1[k] = NULL;
939 }
940 }
941 moveToStringArrayComplex(&realName2, &imagName2, &names2, realName1, imagName1, realNames);
942 free(realName1);
943 free(imagName1);
944 }
945 }
946 free(realPattern);
947 free(imagPattern);
948 if (names2 == 0)
949 return 0;
950 *realName = realName2;
951 *imagName = imagName2;
952 return names2;
953}
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 311 of file SDDSutils.c.

313{
314 int64_t bestResult = 0, result, nPrimes;
315 static int64_t prime[MAXPRIMES] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
316 71, 73, 79, 83, 89, 97};
317
318 for (nPrimes = 1; nPrimes <= MAXPRIMES; nPrimes++) {
319 if ((result = greatestProductOfSmallPrimes1(rows, prime, nPrimes)) > bestResult &&
320 result <= rows)
321 bestResult = result;
322 }
323 if (bestResult == 0)
324 SDDS_Bomb("couldn't find acceptable number of rows for truncation/padding");
325 return bestResult;
326}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 161 of file sdds2dfft.c.

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

269 {
270 char *timeUnits;
271 char *units;
272 long reciprocal = 0, end;
273
274 if (SDDS_GetColumnInformation(SDDSin, "units", &timeUnits, SDDS_GET_BY_NAME, indepName) != SDDS_STRING)
275 return 0;
276 if (timeUnits) {
277 while (1) {
278 end = strlen(timeUnits) - 1;
279 if (timeUnits[0] == '(' && timeUnits[end] == ')') {
280 timeUnits[end] = 0;
281 strslide(timeUnits, 1);
282 } else if (timeUnits[0] == '1' && timeUnits[1] == '/' && timeUnits[2] == '(' && timeUnits[end] == ')') {
283 timeUnits[end] = 0;
284 strslide(timeUnits, 3);
285 reciprocal = !reciprocal;
286 } else
287 break;
288 }
289 }
290 if (!timeUnits || SDDS_StringIsBlank(timeUnits)) {
291 units = tmalloc(sizeof(*units) * 1);
292 units[0] = 0;
293 return units;
294 }
295
296 if (reciprocal) {
297 if (!SDDS_CopyString(&units, timeUnits))
298 return NULL;
299 return units;
300 }
301
302 units = tmalloc(sizeof(*units) * (strlen(timeUnits) + 5));
303 if (strchr(timeUnits, ' '))
304 sprintf(units, "1/(%s)", timeUnits);
305 else
306 sprintf(units, "1/%s", timeUnits);
307 return units;
308}
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 955 of file sdds2dfft.c.

955 {
956 long i, j;
957 if (!sources)
958 return;
959 if (!(*targetReal = SDDS_Realloc(*targetReal, sizeof(**targetReal) * (*targets + sources))) ||
960 !(*targetImag = SDDS_Realloc(*targetImag, sizeof(**targetImag) * (*targets + sources))))
961 SDDS_Bomb("Memory allocation failure");
962 for (i = 0; i < sources; i++) {
963 if (sourceReal[i] == NULL || sourceImag[i] == NULL)
964 continue;
965 for (j = 0; j < *targets; j++)
966 if (strcmp(sourceReal[i], (*targetReal)[j]) == 0)
967 break;
968 if (j == *targets) {
969 (*targetReal)[j] = sourceReal[i];
970 (*targetImag)[j] = sourceImag[i];
971 *targets += 1;
972 }
973 }
974}

Variable Documentation

◆ argOffset

long argOffset
static

Definition at line 619 of file sdds2dfft.c.

◆ fftOffset

long fftOffset = -1
static

Definition at line 619 of file sdds2dfft.c.

◆ imagOffset

long imagOffset
static

Definition at line 619 of file sdds2dfft.c.

◆ option

char* option[N_OPTIONS]
Initial value:
= {
"normalize",
"padwithzeroes",
"truncate",
"suppressaverage",
"sampleinterval",
"columns",
"fulloutput",
"pipe",
"psdoutput",
"exclude",
"nowarnings",
"complexinput",
"inverse",
"majorOrder",
}

Definition at line 65 of file sdds2dfft.c.

65 {
66 "normalize",
67 "padwithzeroes",
68 "truncate",
69 "suppressaverage",
70 "sampleinterval",
71 "columns",
72 "fulloutput",
73 "pipe",
74 "psdoutput",
75 "exclude",
76 "nowarnings",
77 "complexinput",
78 "inverse",
79 "majorOrder",
80};

◆ psdIntOffset

long psdIntOffset
static

Definition at line 619 of file sdds2dfft.c.

◆ psdOffset

long psdOffset
static

Definition at line 619 of file sdds2dfft.c.

◆ realOffset

long realOffset
static

Definition at line 619 of file sdds2dfft.c.

◆ unwrappedArgOffset

long unwrappedArgOffset = -1
static

Definition at line 619 of file sdds2dfft.c.

◆ USAGE1

char* USAGE1
static
Initial value:
=
"Usage: sdds2dfft [<inputfile>] [<outputfile>]\n"
" [options]\n\n"
"Options:\n"
" -pipe=[input][,output]\n"
" The standard SDDS Toolkit pipe option.\n"
" -columns=<indep-variable>[,<depen-quantity>[,...]]\n"
" Specifies the independent variable and dependent quantities to Fourier analyze.\n"
" <depen-quantity> entries may contain wildcards.\n"
" -complexInput[=unfolded|folded]\n"
" Indicates that the input columns are in complex form.\n"
" Options:\n"
" unfolded - The input frequency space is unfolded and must include negative frequencies.\n"
" folded - The input frequency space is folded (default).\n"
" -inverse\n"
" Produces the inverse Fourier transform. The output is always an unfolded spectrum.\n"
" If combined with -fullOutput=folded, it will be changed to -fullOutput=unfolded.\n"
" -exclude=<depen-quantity>[,...]\n"
" Specifies a list of wild-card patterns to exclude certain quantities from analysis.\n"

Definition at line 97 of file sdds2dfft.c.

◆ USAGE2

char* USAGE2
static

Definition at line 117 of file sdds2dfft.c.