1 | ;******************************************************************* WAVELET |
---|
2 | ;+ |
---|
3 | ; NAME: WAVELET |
---|
4 | ; |
---|
5 | ; PURPOSE: Compute the WAVELET transform of a 1D time series. |
---|
6 | ; |
---|
7 | ; |
---|
8 | ; CALLING SEQUENCE: |
---|
9 | ; |
---|
10 | ; wave = WAVELET(Y,DT) |
---|
11 | ; |
---|
12 | ; |
---|
13 | ; INPUTS: |
---|
14 | ; |
---|
15 | ; Y = the time series of length N. |
---|
16 | ; |
---|
17 | ; DT = amount of time between each Y value, i.e. the sampling time. |
---|
18 | ; |
---|
19 | ; |
---|
20 | ; OUTPUTS: |
---|
21 | ; |
---|
22 | ; WAVE is the WAVELET transform of Y. This is a complex array |
---|
23 | ; of dimensions (N,J+1). FLOAT(WAVE) gives the WAVELET amplitude, |
---|
24 | ; ATAN(IMAGINARY(WAVE),FLOAT(WAVE)) gives the WAVELET phase. |
---|
25 | ; The WAVELET power spectrum is ABS(WAVE)^2. |
---|
26 | ; |
---|
27 | ; |
---|
28 | ; OPTIONAL KEYWORD INPUTS: |
---|
29 | ; |
---|
30 | ; S0 = the smallest scale of the wavelet. Default is 2*DT. |
---|
31 | ; |
---|
32 | ; DJ = the spacing between discrete scales. Default is 0.125. |
---|
33 | ; A smaller # will give better scale resolution, but be slower to plot. |
---|
34 | ; |
---|
35 | ; J = the # of scales minus one. Scales range from S0 up to S0*2^(J*DJ), |
---|
36 | ; to give a total of (J+1) scales. Default is J = (LOG2(N DT/S0))/DJ. |
---|
37 | ; |
---|
38 | ; MOTHER = A string giving the mother wavelet to use. |
---|
39 | ; Currently, 'Morlet','Paul','DOG' (derivative of Gaussian) |
---|
40 | ; are available. Default is 'Morlet'. |
---|
41 | ; |
---|
42 | ; PARAM = optional mother wavelet parameter. |
---|
43 | ; For 'Morlet' this is k0 (wavenumber), default is 6. |
---|
44 | ; For 'Paul' this is m (order), default is 4. |
---|
45 | ; For 'DOG' this is m (m-th derivative), default is 2. |
---|
46 | ; |
---|
47 | ; PAD = if set, then pad the time series with enough zeroes to get |
---|
48 | ; N up to the next higher power of 2. This prevents wraparound |
---|
49 | ; from the end of the time series to the beginning, and also |
---|
50 | ; speeds up the FFT's used to do the wavelet transform. |
---|
51 | ; This will not eliminate all edge effects (see COI below). |
---|
52 | ; |
---|
53 | ; LAG1 = LAG 1 Autocorrelation, used for SIGNIF levels. Default is 0.0 |
---|
54 | ; |
---|
55 | ; SIGLVL = significance level to use. Default is 0.95 |
---|
56 | ; |
---|
57 | ; VERBOSE = if set, then print out info for each analyzed scale. |
---|
58 | ; |
---|
59 | ; RECON = if set, then reconstruct the time series, and store in Y. |
---|
60 | ; Note that this will destroy the original time series, |
---|
61 | ; so be sure to input a dummy copy of Y. |
---|
62 | ; |
---|
63 | ; FFT_THEOR = theoretical background spectrum as a function of |
---|
64 | ; Fourier frequency. This will be smoothed by the |
---|
65 | ; wavelet function and returned as a function of PERIOD. |
---|
66 | ; |
---|
67 | ; |
---|
68 | ; OPTIONAL KEYWORD OUTPUTS: |
---|
69 | ; |
---|
70 | ; PERIOD = the vector of "Fourier" periods (in time units) that corresponds |
---|
71 | ; to the SCALEs. |
---|
72 | ; |
---|
73 | ; SCALE = the vector of scale indices, given by S0*2^(j*DJ), j=0...J |
---|
74 | ; where J+1 is the total # of scales. |
---|
75 | ; |
---|
76 | ; COI = if specified, then return the Cone-of-Influence, which is a vector |
---|
77 | ; of N points that contains the maximum period of useful information |
---|
78 | ; at that particular time. |
---|
79 | ; Periods greater than this are subject to edge effects. |
---|
80 | ; This can be used to plot COI lines on a contour plot by doing: |
---|
81 | ; IDL> CONTOUR,wavelet,time,period |
---|
82 | ; IDL> PLOTS,time,coi,NOCLIP=0 |
---|
83 | ; |
---|
84 | ; YPAD = returns the padded time series that was actually used in the |
---|
85 | ; wavelet transform. |
---|
86 | ; |
---|
87 | ; DAUGHTER = if initially set to 1, then return the daughter wavelets. |
---|
88 | ; This is a complex array of the same size as WAVELET. At each scale |
---|
89 | ; the daughter wavelet is located in the center of the array. |
---|
90 | ; |
---|
91 | ; SIGNIF = output significance levels as a function of PERIOD |
---|
92 | ; |
---|
93 | ; FFT_THEOR = output theoretical background spectrum (smoothed by the |
---|
94 | ; wavelet function), as a function of PERIOD. |
---|
95 | ; |
---|
96 | ; |
---|
97 | ; [ Defunct INPUTS: |
---|
98 | ; [ OCT = the # of octaves to analyze over. ] |
---|
99 | ; [ Largest scale will be S0*2^OCT. ] |
---|
100 | ; [ Default is (LOG2(N) - 1). ] |
---|
101 | ; [ VOICE = # of voices in each octave. Default is 8. ] |
---|
102 | ; [ Higher # gives better scale resolution, ] |
---|
103 | ; [ but is slower to plot. ] |
---|
104 | ; ] |
---|
105 | ; |
---|
106 | ;---------------------------------------------------------------------------- |
---|
107 | ; |
---|
108 | ; EXAMPLE: |
---|
109 | ; |
---|
110 | ; IDL> ntime = 256 |
---|
111 | ; IDL> y = RANDOMN(s,ntime) ;*** create a random time series |
---|
112 | ; IDL> dt = 0.25 |
---|
113 | ; IDL> time = FINDGEN(ntime)*dt ;*** create the time index |
---|
114 | ; IDL> |
---|
115 | ; IDL> wave = WAVELET(y,dt,PERIOD=period,COI=coi,/PAD,SIGNIF=signif) |
---|
116 | ; IDL> nscale = N_ELEMENTS(period) |
---|
117 | ; IDL> LOADCT,39 |
---|
118 | ; IDL> CONTOUR,ABS(wave)^2,time,period, $ |
---|
119 | ; XSTYLE=1,XTITLE='Time',YTITLE='Period',TITLE='Noise Wavelet', $ |
---|
120 | ; YRANGE=[MAX(period),MIN(period)], $ ;*** Large-->Small period |
---|
121 | ; /YTYPE, $ ;*** make y-axis logarithmic |
---|
122 | ; NLEVELS=25,/FILL |
---|
123 | ; IDL> |
---|
124 | ; IDL> signif = REBIN(TRANSPOSE(signif),ntime,nscale) |
---|
125 | ; IDL> CONTOUR,ABS(wave)^2/signif,time,period, $ |
---|
126 | ; /OVERPLOT,LEVEL=1.0,C_ANNOT='95%' |
---|
127 | ; IDL> PLOTS,time,coi,NOCLIP=0 ;*** anything "below" this line is dubious |
---|
128 | ; |
---|
129 | ; |
---|
130 | ;---------------------------------------------------------------------------- |
---|
131 | ; Copyright (C) 1995-2004, Christopher Torrence and Gilbert P. Compo |
---|
132 | ; |
---|
133 | ; This software may be used, copied, or redistributed as long as it is not |
---|
134 | ; sold and this copyright notice is reproduced on each copy made. |
---|
135 | ; This routine is provided as is without any express or implied warranties |
---|
136 | ; whatsoever. |
---|
137 | ; |
---|
138 | ; Notice: Please acknowledge the use of the above software in any publications: |
---|
139 | ; ``Wavelet software was provided by C. Torrence and G. Compo, |
---|
140 | ; and is available at URL: http://paos.colorado.edu/research/wavelets/''. |
---|
141 | ; |
---|
142 | ; Reference: Torrence, C. and G. P. Compo, 1998: A Practical Guide to |
---|
143 | ; Wavelet Analysis. <I>Bull. Amer. Meteor. Soc.</I>, 79, 61-78. |
---|
144 | ; |
---|
145 | ; Please send a copy of such publications to either C. Torrence or G. Compo: |
---|
146 | ; Dr. Christopher Torrence Dr. Gilbert P. Compo |
---|
147 | ; Research Systems, Inc. Climate Diagnostics Center |
---|
148 | ; 4990 Pearl East Circle 325 Broadway R/CDC1 |
---|
149 | ; Boulder, CO 80301, USA Boulder, CO 80305-3328, USA |
---|
150 | ; E-mail: chris[AT]rsinc[DOT]com E-mail: compo[AT]colorado[DOT]edu |
---|
151 | ;---------------------------------------------------------------------------- |
---|
152 | ;- |
---|
153 | |
---|
154 | FUNCTION morlet, $ ;*********************************************** MORLET |
---|
155 | k0,scale,k,period,coi,dofmin,Cdelta,psi0 |
---|
156 | |
---|
157 | IF (k0 EQ -1) THEN k0 = 6d |
---|
158 | n = N_ELEMENTS(k) |
---|
159 | expnt = -(scale*k - k0)^2/2d*(k GT 0.) |
---|
160 | dt = 2*!PI/(n*k(1)) |
---|
161 | norm = SQRT(2*!PI*scale/dt)*(!PI^(-0.25)) ; total energy=N [Eqn(7)] |
---|
162 | morlet = norm*EXP(expnt > (-100d)) |
---|
163 | morlet = morlet*(expnt GT -100) ; avoid underflow errors |
---|
164 | morlet = morlet*(k GT 0.) ; Heaviside step function (Morlet is complex) |
---|
165 | fourier_factor = (4*!PI)/(k0 + SQRT(2+k0^2)) ; Scale-->Fourier [Sec.3h] |
---|
166 | period = scale*fourier_factor |
---|
167 | coi = fourier_factor/SQRT(2) ; Cone-of-influence [Sec.3g] |
---|
168 | dofmin = 2 ; Degrees of freedom with no smoothing |
---|
169 | Cdelta = -1 |
---|
170 | IF (k0 EQ 6) THEN Cdelta = 0.776 ; reconstruction factor |
---|
171 | psi0 = !PI^(-0.25) |
---|
172 | ; PRINT,scale,n,SQRT(TOTAL(ABS(morlet)^2,/DOUBLE)) |
---|
173 | RETURN,morlet |
---|
174 | END |
---|
175 | |
---|
176 | FUNCTION paul, $ ;************************************************** PAUL |
---|
177 | m,scale,k,period,coi,dofmin,Cdelta,psi0 |
---|
178 | |
---|
179 | IF (m EQ -1) THEN m = 4d |
---|
180 | n = N_ELEMENTS(k) |
---|
181 | expnt = -(scale*k)*(k GT 0.) |
---|
182 | dt = 2d*!PI/(n*k(1)) |
---|
183 | norm = SQRT(2*!PI*scale/dt)*(2^m/SQRT(m*FACTORIAL(2*m-1))) |
---|
184 | paul = norm*((scale*k)^m)*EXP(expnt > (-100d))*(expnt GT -100) |
---|
185 | paul = paul*(k GT 0.) |
---|
186 | fourier_factor = 4*!PI/(2*m+1) |
---|
187 | period = scale*fourier_factor |
---|
188 | coi = fourier_factor*SQRT(2) |
---|
189 | dofmin = 2 ; Degrees of freedom with no smoothing |
---|
190 | Cdelta = -1 |
---|
191 | IF (m EQ 4) THEN Cdelta = 1.132 ; reconstruction factor |
---|
192 | psi0 = 2.^m*FACTORIAL(m)/SQRT(!PI*FACTORIAL(2*m)) |
---|
193 | ; PRINT,scale,n,norm,SQRT(TOTAL(paul^2,/DOUBLE))*SQRT(n) |
---|
194 | RETURN,paul |
---|
195 | END |
---|
196 | |
---|
197 | FUNCTION dog, $ ;*************************************************** DOG |
---|
198 | m,scale,k,period,coi,dofmin,Cdelta,psi0 |
---|
199 | |
---|
200 | IF (m EQ -1) THEN m = 2 |
---|
201 | n = N_ELEMENTS(k) |
---|
202 | expnt = -(scale*k)^2/2d |
---|
203 | dt = 2d*!PI/(n*k(1)) |
---|
204 | norm = SQRT(2*!PI*scale/dt)*SQRT(1d/GAMMA(m+0.5)) |
---|
205 | I = DCOMPLEX(0,1) |
---|
206 | gauss = -norm*(I^m)*(scale*k)^m*EXP(expnt > (-100d))*(expnt GT -100) |
---|
207 | fourier_factor = 2*!PI*SQRT(2./(2*m+1)) |
---|
208 | period = scale*fourier_factor |
---|
209 | coi = fourier_factor/SQRT(2) |
---|
210 | dofmin = 1 ; Degrees of freedom with no smoothing |
---|
211 | Cdelta = -1 |
---|
212 | psi0 = -1 |
---|
213 | IF (m EQ 2) THEN BEGIN |
---|
214 | Cdelta = 3.541 ; reconstruction factor |
---|
215 | psi0 = 0.867325 |
---|
216 | ENDIF |
---|
217 | IF (m EQ 6) THEN BEGIN |
---|
218 | Cdelta = 1.966 ; reconstruction factor |
---|
219 | psi0 = 0.88406 |
---|
220 | ENDIF |
---|
221 | ; PRINT,scale,n,norm,SQRT(TOTAL(ABS(gauss)^2,/DOUBLE))*SQRT(n) |
---|
222 | RETURN,gauss |
---|
223 | END |
---|
224 | |
---|
225 | |
---|
226 | ;****************************************************************** WAVELET |
---|
227 | FUNCTION wavelet,y1,dt, $ ;*** required inputs |
---|
228 | S0=s0,DJ=dj,J=j, $ ;*** optional inputs |
---|
229 | PAD=pad,MOTHER=mother,PARAM=param, $ |
---|
230 | VERBOSE=verbose,NO_WAVE=no_wave,RECON=recon, $ |
---|
231 | LAG1=lag1,SIGLVL=siglvl,DOF=dof,GLOBAL=global, $ ;*** optional inputs |
---|
232 | SCALE=scale,PERIOD=period,YPAD=ypad, $ ;*** optional outputs |
---|
233 | DAUGHTER=daughter,COI=coi, $ |
---|
234 | SIGNIF=signif,FFT_THEOR=fft_theor, $ |
---|
235 | OCT=oct,VOICE=voice ;*** defunct inputs |
---|
236 | |
---|
237 | ON_ERROR,2 |
---|
238 | r = CHECK_MATH(0,1) |
---|
239 | n = N_ELEMENTS(y1) |
---|
240 | n1 = n |
---|
241 | base2 = FIX(ALOG(n)/ALOG(2) + 0.4999) ; power of 2 nearest to N |
---|
242 | |
---|
243 | ;....check keywords & optional inputs |
---|
244 | IF (N_ELEMENTS(s0) LT 1) THEN s0 = 2.0*dt |
---|
245 | IF (N_ELEMENTS(voice) EQ 1) THEN dj = 1./voice |
---|
246 | IF (N_ELEMENTS(dj) LT 1) THEN dj = 1./8 |
---|
247 | IF (N_ELEMENTS(oct) EQ 1) THEN J = FLOAT(oct)/dj |
---|
248 | IF (N_ELEMENTS(J) LT 1) THEN J=FIX((ALOG(FLOAT(n)*dt/s0)/ALOG(2))/dj) ;[Eqn(10)] |
---|
249 | IF (N_ELEMENTS(mother) LT 1) THEN mother = 'MORLET' |
---|
250 | IF (N_ELEMENTS(param) LT 1) THEN param = -1 |
---|
251 | IF (N_ELEMENTS(siglvl) LT 1) THEN siglvl = 0.95 |
---|
252 | IF (N_ELEMENTS(lag1) LT 1) THEN lag1 = 0.0 |
---|
253 | lag1 = lag1(0) |
---|
254 | verbose = KEYWORD_SET(verbose) |
---|
255 | do_daughter = KEYWORD_SET(daughter) |
---|
256 | do_wave = NOT KEYWORD_SET(no_wave) |
---|
257 | recon = KEYWORD_SET(recon) |
---|
258 | IF KEYWORD_SET(global) THEN MESSAGE, $ |
---|
259 | 'Please use WAVE_SIGNIF for global significance tests' |
---|
260 | |
---|
261 | ;....construct time series to analyze, pad if necessary |
---|
262 | ypad = y1 - TOTAL(y1)/n ; remove mean |
---|
263 | IF KEYWORD_SET(pad) THEN BEGIN ; pad with extra zeroes, up to power of 2 |
---|
264 | ypad = [ypad,FLTARR(2L^(base2 + 1) - n)] |
---|
265 | n = N_ELEMENTS(ypad) |
---|
266 | ENDIF |
---|
267 | |
---|
268 | ;....construct SCALE array & empty PERIOD & WAVE arrays |
---|
269 | na = J + 1 ; # of scales |
---|
270 | scale = DINDGEN(na)*dj ; array of j-values |
---|
271 | scale = 2d0^(scale)*s0 ; array of scales 2^j [Eqn(9)] |
---|
272 | period = FLTARR(na,/NOZERO) ; empty period array (filled in below) |
---|
273 | wave = COMPLEXARR(n,na,/NOZERO) ; empty wavelet array |
---|
274 | IF (do_daughter) THEN daughter = wave ; empty daughter array |
---|
275 | |
---|
276 | ;....construct wavenumber array used in transform [Eqn(5)] |
---|
277 | k = (DINDGEN(n/2) + 1)*(2*!PI)/(DOUBLE(n)*dt) |
---|
278 | k = [0d,k,-REVERSE(k(0:(n-1)/2 - 1))] |
---|
279 | |
---|
280 | ;....compute FFT of the (padded) time series |
---|
281 | yfft = FFT(ypad,-1,/DOUBLE) ; [Eqn(3)] |
---|
282 | |
---|
283 | IF (verbose) THEN BEGIN ;verbose |
---|
284 | PRINT |
---|
285 | PRINT,mother |
---|
286 | PRINT,'#points=',n1,' s0=',s0,' dj=',dj,' J=',FIX(J) |
---|
287 | IF (n1 NE n) THEN PRINT,'(padded with ',n-n1,' zeroes)' |
---|
288 | PRINT,['j','scale','period','variance','mathflag'], $ |
---|
289 | FORMAT='(/,A3,3A11,A10)' |
---|
290 | ENDIF ;verbose |
---|
291 | IF (N_ELEMENTS(fft_theor) EQ n) THEN fft_theor_k = fft_theor ELSE $ |
---|
292 | fft_theor_k = (1-lag1^2)/(1-2*lag1*COS(k*dt)+lag1^2) ; [Eqn(16)] |
---|
293 | fft_theor = FLTARR(na) |
---|
294 | |
---|
295 | ;....loop thru each SCALE |
---|
296 | FOR a1=0,na-1 DO BEGIN ;scale |
---|
297 | psi_fft=CALL_FUNCTION(mother, $ |
---|
298 | param,scale(a1),k,period1,coi,dofmin,Cdelta,psi0) |
---|
299 | IF (do_wave) THEN $ |
---|
300 | wave(*,a1) = FFT(yfft*psi_fft,1,/DOUBLE) ;wavelet transform[Eqn(4)] |
---|
301 | period(a1) = period1 ; save period |
---|
302 | fft_theor(a1) = TOTAL((ABS(psi_fft)^2)*fft_theor_k)/n |
---|
303 | IF (do_daughter) THEN $ |
---|
304 | daughter(*,a1) = FFT(psi_fft,1,/DOUBLE) ; save daughter |
---|
305 | IF (verbose) THEN PRINT,a1,scale(a1),period(a1), $ |
---|
306 | TOTAL(ABS(wave(*,a1))^2),CHECK_MATH(0), $ |
---|
307 | FORMAT='(I3,3F11.3,I6)' |
---|
308 | ENDFOR ;scale |
---|
309 | |
---|
310 | coi = coi*[FINDGEN((n1+1)/2),REVERSE(FINDGEN(n1/2))]*dt ; COI [Sec.3g] |
---|
311 | |
---|
312 | IF (do_daughter) THEN $ ; shift so DAUGHTERs are in middle of array |
---|
313 | daughter = [daughter(n-n1/2:*,*),daughter(0:n1/2-1,*)] |
---|
314 | |
---|
315 | ;....significance levels [Sec.4] |
---|
316 | sdev = (MOMENT(y1))(1) |
---|
317 | fft_theor = sdev*fft_theor ; include time-series variance |
---|
318 | dof = dofmin |
---|
319 | signif = fft_theor*CHISQR_CVF(1. - siglvl,dof)/dof ; [Eqn(18)] |
---|
320 | |
---|
321 | IF (recon) THEN BEGIN ; Reconstruction [Eqn(11)] |
---|
322 | IF (Cdelta EQ -1) THEN BEGIN |
---|
323 | y1 = -1 |
---|
324 | MESSAGE,/INFO, $ |
---|
325 | 'Cdelta undefined, cannot reconstruct with this wavelet' |
---|
326 | ENDIF ELSE BEGIN |
---|
327 | y1=dj*SQRT(dt)/(Cdelta*psi0)*(FLOAT(wave) # (1./SQRT(scale))) |
---|
328 | y1 = y1[0:n1-1] |
---|
329 | ENDELSE |
---|
330 | ENDIF |
---|
331 | |
---|
332 | RETURN,wave(0:n1-1,*) ; get rid of padding before returning |
---|
333 | |
---|
334 | END |
---|