Viewing contents of file '../idllib/contrib/harris/fmoft.pro'
function fmoft, timevals,in_tdata,ft,$
over_sample=ovrsfactor,weights=datawt
;+
; NAME: FMOFT
;
; PURPOSE: Performs a DFT on unequally spaced data by finding
; an orthogonal basis set based on the sine function.
;
; CATEGORY: Signal Processing and Data Analysis
;
; CALLING SEQUENCE: result = FMOFT(time_values, data, direction)
;
; INPUTS:
; time_values = relative spacing of the data
; data = data to be transformed
; direction = direction of the transform
; KEYWORDS:
; OVER_SAMPLE = over-sampling factor. Since this is
; a DFT, frequency space can be sampled
; at any arbitrary resolution. This
; gives the integer factor to
; over-sample by. Default = 1
; (no over-sampling)
; WEIGHTS = weights for the data
; OUTPUTS:
; Result = (n_elements(data)*OVER_SAMPLE) Complex array
;
; OPTIONAL PARAMETERS:
;
;
; COMMON BLOCKS:
; none.
; SIDE EFFECTS:
; none.
; MODIFICATION HISTORY:
; Written by: Trevor Harris, Physics Dept., University of Adelaide,
; 17/9/92 Based on the fortran sub "fmoft.f" in my library source
;
;c v1.0 T.J.H. 14/11/89 based on method of S. Ferraz-Mello
;c " Estimation of Periods from Unequally spaced Observations "
;c 'The Astronomical Journal', vol 86, pg 619, 1981
;c
;c v1.1 T.J.H. 18/01/91 Corrected mintime and maxtime
;
;-
;c...INPUTS
; integer*4 N, ovrsfactor, ft
; real *4 timevals(N),datawt(N)
; complex*4 tdata(N)
;c...OUTPUTS
; complex*4 fdata(ovrsfactor*N)
;c the input data, "tdata", is Fourier Transformed into "fdata"
;c using the data window "datawt" and an orthogonal set h1,h2
;c (NB: oversample frequency space by factor of 'ovrsfactor')
;c
twopi = 2.*!dpi
N = n_elements(timevals)
if (not keyword_set(ovrsfactor)) then ovrsfactor = 1
maxtime = max( timevals, min=mintime )
if ((maxtime le 0) or (mintime lt 0)) then begin
print, ' ERROR in time values, all values zero, or some < 0'
return,-1
endif else $
freqstep = 1/(maxtime-mintime)/float(ovrsfactor)
M = ovrsfactor*N
; ensure tdata is of complex type
;;;sz = size(in_tdata)
;;;if (sz(sz(0)+1) ne 6) then tdata = complex(in_tdata) $
;;;else tdata = in_tdata
tdata = complex(in_tdata)
;c... ..mean correct the data
if (not keyword_set(datawt)) then datawt = 1.
sdx = stdev(float(tdata*datawt),meanx) & sdy = stdev(imaginary(tdata*datawt),meany)
tdata = tdata - complex(meanx,meany)
; Define the output data array
fdata = complexarr(M)
if (not keyword_set(datawt)) then datawt = 1./(sdx^2+sdy^2)
a0 = total(datawt)
if (a0 gt 0) then a0 = 1/sqrt(a0) $
else begin
print,' ERROR in data weights, sum = 0 '
return,-1
endelse
CASE (ft) OF
-1 : begin
whichway = -1.
normfact = sqrt(2.*a0*a0)
end
ELSE: begin
whichway = 1.
normfact = 1/sqrt(2.*a0*a0)
end
ENDCASE
;c... case freq = 0
fdata(0) = complex(meanx,meany)*2.*normfact*normfact
;c... case freq > 0, < maxfrequency
freq = freqstep * findgen(M)
sumc = freq*0.0
sums = sumc
sumcs = sumc
sumc2 = sumc
sums2 = sumc
for f = 1,M-1 do begin
x = freq(f)*(timevals-mintime)
cwt = cos(twopi*x)
swt = sin(twopi*x)
sumc(f) = total(datawt*cwt)
sums(f) = total(datawt*swt)
sumcs(f) = total(datawt*cwt*swt)
sumc2(f) = total(datawt*cwt*cwt)
sums2(f) = total(datawt*swt*swt)
endfor
a1 = sumc2 - a0*a0*sumc*sumc
a1 = 1/sqrt(a1)
temp1 = (sumcs - a0*a0*sumc*sums)*(sumcs - a0*a0*sumc*sums)
a2 = sums2 - a0*a0*sums*sums - a1*a1*temp1
a2 = 1/sqrt(a2)
a1(0) = 1
a2(0) = 1
temp1 = a1*a0*a0*sumc
temp2 = a2*a0*a0*sums
temp3 = (a2*a1*sumcs - a2*temp1*sums)
for f = 1,M-1 do begin
x = freq(f)*(timevals-mintime)
cwt = cos(twopi*x)
swt = sin(twopi*x)
h1 = (a1(f)*cwt - temp1(f))
h2 = (a2(f)*swt - temp2(f) - h1*temp3(f)) * whichway
;;h1 = (a1*cwt - temp1)
;;h2 = (a2*swt - temp2 - h1*temp3) * whichway
fdata(f) = normfact*total(tdata*complex(h1,h2))
endfor
return,fdata
end