Viewing contents of file '../idllib/contrib/groupk/multipsd.pro'
;+
; NAME:
; MULTIPSD
;
; PURPOSE:
; Given an array of times, ts divide the data into equal time segments,
; calculate the FFT power spectra of these segments and average
; the power spectra.
;
; CATEGORY:
; Math.
;
; CALLING SEQUENCE:
;
; Result = MULTIPSD( Ts, Bin, Nbin, Npsd, Mean, Sigma )
;
; INPUTS:
; Ts: An array of times with starting time, Ts(0)=0.
;
; Bin: The length of one time bin in the same UNITS as the Ts array.
;
; Nbin: The number of time bins in each time segment.
;
; OPTIONAL INPUT KEYWORD PARAMETERS:
;
; VERBOSE: Setting the keyword will display messages updating the user
; on which time segment the routine is currently processing.
;
; OUTPUTS:
; This function returns the average FFT power spectra and the standard
; deviations about each average in an array, FLTARR((nbin/2), 2). The
; first column, (*,0) holds the power spectra
; averaged over Npsd time segments and the second column (*,1) holds the
; standard deviations about those averages.
;
; OPTIONAL OUTPUTS:
;
; Npsd: The number of equal time segments the data was divided into.
;
; Mean: Average number of counts/bin over all times FFTed.
;
; Sigma: Sqrt of the variance of the counts/bin about the Mean over
; all times FFTed.
;
; PROCEDURE:
;
; The average power spectra is usually normalized in one of two ways:
; Leahy or fractional RMS amplitude. The Leahy normalized power is
; determined by multiplying (2/<Ncts>) with the results of this function:
;
; Pwrarray = MULTIPSD( Ts, Bin, Nbin, Npsd, Mean, Sigma )
; Ncts = Mean*Nbin
; Pleahy = (2/Ncts)*Pwrarry(*,0)
;
; where Ncts is the average total number of counts in one time segment.
;
; The fractional RMS amplitude is a dimensionaless quantity defined as
; the square root of the variance of the counts/bin divided by the
; average counts/bin. Its normalization can be determined by dividing
; the Leahy normalized power by the average intensity, <I>:
;
; Iavg = Mean/Bin
; Prms = Pleahy/Iavg
;
; To relate Prms to the actual fractional RMS amplitude, (Sigma/Mean):
;
; rms = Sigma/Mean
; dFreq = 1/(Bin*Nbin)
; TOTAL(Prms)= rms^2/dFreq
;
; EXAMPLE:
;
; The input parameters, nbin and bin are related to the limits of the FFT
; frequencies in the following manner:
;
; 1/(nbin*bin) = Minimum frequency
; 1/(2*bin) = Nyquist frequency
;
; Given a time array, ts=LONARR(500000)=[0,1000000], determine the average
; power spectra if Bin = 50 and Nbin = 4096.
;
; Bin = 50
; Nbin = 1024 -> Npsd = 19 time segments
;
; pwr_result = MULTIPSD( Ts, Bin, Nbin, Npsd, RMS, /VERB )
;
; MODIFICATION HISTORY:
; Written by: Han Wen, August 1996.
; 14-AUG-1996 Eliminated LEAHY, RMS keywords, added RMS output parameter,
; check number of parameters.
; 15-AUG-1996 Removed RMS parameter, added Mean and Sigma parameters.
; 30-AUG-1996 Bugfix: return sigma instead of variance.
;
;-
function MULTIPSD, Ts, Bin, Nbin, Npsd, MeanCts, SigmaCts, VERBOSE=Verbose
NP = N_PARAMS()
if (NP lt 3) then message, $
'Must be called with 3-5 parameters: Ts, Bin, Nbin [, Npsd, RMS ]'
; Determine the number of data points that will be truncated past
; the last time segment
nts = LONG(N_ELEMENTS(ts))
tPSD = bin*LONG(nbin)
nexac = ts(nts-1)/DOUBLE(tPSD)
nPSD = FLOOR(nexac + 0.01)
if (nexac ne nPSD) then begin
hbad = WHERE(ts gt nPSD*tPSD,ntrunc)
percent = 100*FLOAT(ntrunc)/nts
if (percent gt 0) then $
print,'Number of data points truncated: ', $
STRTRIM(ntrunc,2),'/',STRTRIM(nts,2),$
', ',STRING(percent,FORMAT='(F6.2)'),'%'
endif
; Loop over each time segment
j = 0L
mu =( mu2 = 0d0 )
pj = FLTARR( nbin/2, 2 )
for i=0,nPSD-1 do begin
if (KEYWORD_SET(Verbose)) then begin
print,SYSTIME()+'// Calculating PSD: ', $
STRTRIM(i+1,2),'/',STRTRIM(nPSD,2)
endif
cts = FIX(HIST1D(ts,MIN=j,MAX=j+tPSD-1,BINSIZE=bin))
ncts = TOTAL(cts,/DOUBLE)
mu = mu + ncts
mu2 = mu2 + TOTAL(DOUBLE(cts)^2)
avg_cts = ncts/nbin
coeffs = FFT(cts-avg_cts,1)
fft_pwr = ABS(coeffs(1:nbin/2))^2
pj(*,0) = pj(*,0) + fft_pwr
pj(*,1) = pj(*,1) + fft_pwr^2
j = j + tPSD
endfor
; Average over all time segments
avgpwr = REFORM(pj(*,0))/nPSD
avgpwr2 = REFORM(pj(*,1))/nPSD
pj =( coeffs = 0 )
var_pwr = (nPSD/(nPSD-1d0))*(avgpwr2 - avgpwr^2)
sigpwr = SQRT(var_pwr/nPSD)
; Determine parameters needed for normalization
nbin_tot = nPSD*nbin
mu = mu /nbin_tot
mu2 = mu2/nbin_tot
var_mu = (nbin_tot/(nbin_tot-1d0))*(mu2 - mu^2)
MeanCts = mu
SigmaCts = SQRT(var_mu)
return, REFORM([avgpwr,sigpwr],nbin/2,2)
end