/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * This file is distributed subject to a Software License Agreement found * in the file LICENSE that is included with this distribution. \*************************************************************************/ #include "mdb.h" /*#include "SDDS.h"*/ #include "fftpackC.h" #include /* functions to perform Numerical Analysis of Fundamental Frequencies * (Laskar's method). * M. Borland, ANL/APS, 2001 */ /* basic FFT of real data: return the magnitude */ long simpleFFT(double *magnitude2, double *data, long points) { static double *real_imag = NULL; static long sizeLimit; long FFTFreqs, i; if (sizeLimit<(points+2) && !(real_imag = malloc(sizeof(*real_imag)*(sizeLimit=points+2)))) return 0; realFFT2(real_imag, data, points, 0); FFTFreqs = points/2+1; for (i=0; imaxMag2) { if (lowerFreqLimitupperFreqLimit)) continue; iBest = i; maxMag2 = magnitude2[i]; } } if (iBest==0) break; wStart = frequency[freqsFound] = iBest*freqSpacing*PIx2; scale = NAFFFunc(wStart, &invalid); for (try=0; try<2; try++) { code = OneDParabolicOptimization(amplitude+freqsFound, frequency+freqsFound, PIx2*freqSpacing, 0.0, PI/dt, NAFFFunc, freqCycleLimit, fracFreqAccuracyLimit*PI/dt, 0.0, 1); if (code<0) { amplitude[freqsFound] = frequency[freqsFound] = -1; break; } } if (code<0) break; /* remove this component by computing the overlap with cosine and sine functions * then subtracting it */ /* fprintf(stderr, "f=%10.3e a=%10.3e p=%10.3e s=%10.3e\n", frequency[freqsFound], amplitude[freqsFound], phase[freqsFound], significance[freqsFound]); */ CalculatePhaseAndAmplitudeFromFreq(hanning, points, NAFFdt, frequency[freqsFound], t0, &phase[freqsFound], &litude[freqsFound], &significance[freqsFound], cosine, sine, flags); frequency[freqsFound] /=PIx2; freqsFound ++; rmsNow = 0; if (fracRMSChangeLimit) { /* determine if residual is too small to bother with */ for (i=rmsNow=0; i0) *significance = sum2/sum1; else *significance = -1; if (flags&NAFF_FREQ_FOUND) freq0 = frequency; else freq0 = frequency / PIx2; *amplitude = sqrt(sqr(sum_ef1/sum_ee1)+sqr(sum_ef2/sum_ee2)); /* compute the phase and ensure that it is in the range [-PI, PI] */ *phase = fmod(atan2(-sum_ef2/sum_ee2, sum_ef1/sum_ee1) + freq0*t0*PIx2, PIx2); if (*phase<-PI) *phase += PIx2; if (*phase>PI) *phase -= PIx2; return 0; } double adjustFrequencyHalfPlane(double frequency, double phase0, double phase1, double dt) { if (fabs(phase0-phase1)>PI) { if (phase0