source: trunk/procs/tools_wavelets/wavetest.pro @ 27

Last change on this file since 27 was 2, checked in by post_it, 17 years ago

Initial import from ~/POST_IT/

File size: 5.8 KB
Line 
1;************************************************************** WAVETEST
2;+
3; NAME:   WAVETEST
4;
5; PURPOSE:   Example IDL program for WAVELET, using NINO3 SST dataset
6;
7; EXECUTION:
8;
9;            IDL> .run wavetest
10;
11;
12; See "http://paos.colorado.edu/research/wavelets/"
13; Written January 1998 by C. Torrence
14;
15;-
16;**************************************************************
17
18        n = 504
19        sst = FLTARR(n)
20        OPENR,1,'sst_nino3.dat'   ; input SST time series
21        READF,1,sst
22        CLOSE,1
23
24;------------------------------------------------------ Computation
25
26; normalize by standard deviation (not necessary, but makes it easier
27; to compare with plot on Interactive Wavelet page, at
28; "http://paos.colorado.edu/research/wavelets/plot/"
29        sst = (sst - TOTAL(sst)/n)
30
31        dt = 0.25
32        time = FINDGEN(n)*dt + 1871.0  ; construct time array
33        xrange = [1870,2000]  ; plotting range
34        pad = 1
35        s0 = dt    ; this says start at a scale of 3 months
36        dj = 0.25  ; this will do 4 sub-octaves per octave
37        j1 = 9./dj  ; this says do 9 powers-of-two with dj sub-octaves each
38        mother = 'Morlet'
39        recon_sst = sst   ; save an extra copy, so we don't erase original sst
40
41; estimate lag-1 autocorrelation, for red-noise significance tests
42; Note that we actually use the global wavelet spectrum (GWS)
43; for the significance tests, but if you wanted to use red noise,
44; here's how you could calculate it...
45        lag1 = (A_CORRELATE(sst,1) + SQRT(A_CORRELATE(sst,2)))/2.
46       
47; Wavelet transform:
48        wave = WAVELET(recon_sst,dt,PERIOD=period,SCALE=scale,S0=s0, $
49                PAD=pad,COI=coi,DJ=dj,J=j1,MOTHER=mother,/RECON)
50        power = (ABS(wave))^2  ; compute wavelet power spectrum
51        global_ws = TOTAL(power,1)/n   ; global wavelet spectrum (GWS)
52        J = N_ELEMENTS(scale) - 1
53
54; Significance levels, assuming the GWS as background spectrum:
55        signif = WAVE_SIGNIF(sst,dt,scale,0, $
56                GWS=global_ws,SIGLVL=0.90,MOTHER=mother)
57        signif = REBIN(TRANSPOSE(signif),n,J+1)  ; expand signif --> (J+1)x(N) array
58        signif = power/signif   ; where ratio > 1, power is significant
59
60; GWS significance levels:
61        dof = n - scale   ; the -scale corrects for padding at edges
62        global_signif = WAVE_SIGNIF(sst,dt,scale,1, $
63                LAG1=0.0,DOF=dof,MOTHER=mother,CDELTA=Cdelta,PSI0=psi0)
64
65; check total variance (Parseval's theorem) [Eqn(14)]
66        scale_avg = REBIN(TRANSPOSE(scale),n,J+1)  ; expand scale-->(J+1)x(N) array
67        power_norm = power/scale_avg
68        variance = (MOMENT(sst))(1)
69        recon_variance = dj*dt/(Cdelta*n)*TOTAL(power_norm)  ; [Eqn(14)]
70       
71        IF (N_ELEMENTS(recon_sst) GT 1) THEN BEGIN
72                recon_variance = (MOMENT(recon_sst))(1)
73; RMS of Reconstruction [Eqn(11)]
74                rms_error = SQRT(TOTAL((sst - recon_sst)^2)/n)
75                PRINT
76                PRINT,'        ******** RECONSTRUCTION ********'
77                PRINT,'original variance =',variance,' degC^2'
78                PRINT,'reconstructed var =',FLOAT(recon_variance),' degC^2'
79                PRINT,'Ratio = ',recon_variance/variance
80                PRINT,'root-mean-square error of reconstructed sst = ',rms_error,' degC'
81                PRINT
82                IF (mother EQ 'DOG') THEN BEGIN
83                        PRINT,'Note: for better reconstruction with the DOG, you need'
84                        PRINT,'      to use a very small s0.'
85                ENDIF
86                PRINT
87        ENDIF
88       
89; Scale-average between El Nino periods of 2--8 years
90        avg = WHERE((scale GE 2) AND (scale LT 8))
91        scale_avg = dj*dt/Cdelta*TOTAL(power_norm(*,avg),2)  ; [Eqn(24)]
92        scaleavg_signif = WAVE_SIGNIF(sst,dt,scale,2, $
93                GWS=global_ws,SIGLVL=0.90,DOF=[2,7.9],MOTHER=mother)
94
95
96;------------------------------------------------------ Plotting
97printfile = 1
98
99!P.FONT = -1
100!P.CHARSIZE = 1
101IF (printfile) THEN BEGIN
102        SET_PLOT,'ps'
103        DEVICE,/PORT,/INCH,XSIZE=6.5,XOFF=1,YSIZE=6,YOFF=3,/COLOR,BITS=8
104        !P.FONT = 0
105        !P.CHARSIZE = 0.75
106ENDIF ELSE WINDOW,0,XSIZE=600,YSIZE=600
107!P.MULTI = 0
108!X.STYLE = 1
109!Y.STYLE = 1
110LOADCT,39
111
112;--- Plot time series
113        pos1 = [0.1,0.75,0.7,0.95]
114        PLOT,time,sst,XRANGE=xrange, $
115                XTITLE='Time (year)',YTITLE='NINO3 SST (!Uo!NC)', $
116                TITLE='a) NINO3 Sea Surface Temperature (seasonal)', $
117                POSITION=pos1
118        IF (N_ELEMENTS(recon_sst) GT 1) THEN OPLOT,time,recon_sst,COLOR=144
119        XYOUTS,0.85,0.9,/NORMAL,ALIGN=0.5, $
120                '!5WAVELET ANALYSIS!X'+$
121                '!C!CC. Torrence & G.P. Compo'+$
122                '!C!Chttp://paos.colorado.edu/!Cresearch/wavelets/'
123
124;--- Contour plot wavelet power spectrum
125        yrange = [64,0.5]   ; years
126        levels = [0.5,1,2,4]
127        colors = [64,128,208,254]
128        period2 = FIX(ALOG(period)/ALOG(2))   ; integer powers of 2 in period
129        ytickv = 2.^(period2(UNIQ(period2)))  ; unique powers of 2
130        pos2 = [pos1(0),0.35,pos1(2),0.65]
131
132        CONTOUR,power,time,period,/NOERASE,POSITION=pos2, $
133                XRANGE=xrange,YRANGE=yrange,/YTYPE, $
134                YTICKS=N_ELEMENTS(ytickv)-1,YTICKV=ytickv, $
135                LEVELS=levels,C_COLORS=colors,/FILL, $
136                XTITLE='Time (year)',YTITLE='Period (years)', $
137                TITLE='b) Wavelet Power Spectrum (contours at 0.5,1,2,4!Uo!NC!U2!N)'
138; significance contour, levels at -99 (fake) and 1 (significant)
139        CONTOUR,signif,time,period,/OVERPLOT,LEVEL=1,THICK=2, $
140                C_LABEL=1,C_ANNOT='90%',C_CHARSIZE=1
141; cone-of-influence, anything "below" is dubious
142        x = [time(0),time,MAX(time)]
143        y = [MAX(period),coi,MAX(period)]
144        color = 4
145        POLYFILL,x,y,ORIEN=+45,SPACING=0.5,COLOR=color,NOCLIP=0,THICK=1
146        POLYFILL,x,y,ORIEN=-45,SPACING=0.5,COLOR=color,NOCLIP=0,THICK=1
147        PLOTS,time,coi,COLOR=color,NOCLIP=0,THICK=1
148
149;--- Plot global wavelet spectrum
150        pos3 = [0.74,pos2(1),0.95,pos2(3)]
151        blank = REPLICATE(' ',29)
152        PLOT,global_ws,period,/NOERASE,POSITION=pos3, $
153                THICK=2,XSTYLE=10,YSTYLE=9, $
154                YRANGE=yrange,/YTYPE,YTICKLEN=-0.02, $
155                XTICKS=2,XMINOR=2, $
156                YTICKS=N_ELEMENTS(ytickv)-1,YTICKV=ytickv,YTICKNAME=blank, $
157                XTITLE='Power (!Uo!NC!U2!N)',TITLE='c) Global'
158        OPLOT,global_signif,period,LINES=1
159        XYOUTS,1.7,60,'95%'
160       
161;--- Plot 2--8 yr scale-average time series
162        pos4 = [pos1(0),0.05,pos1(2),0.25]
163        PLOT,time,scale_avg,/NOERASE,POSITION=pos4, $
164                XRANGE=xrange,YRANGE=[0,MAX(scale_avg)*1.25],THICK=2, $
165                XTITLE='Time (year)',YTITLE='Avg variance (!Uo!NC!U2!N)', $
166                TITLE='d) 2-8 yr Scale-average Time Series'
167        OPLOT,xrange,scaleavg_signif+[0,0],LINES=1
168
169IF (printfile) THEN DEVICE,/CLOSE
170END
Note: See TracBrowser for help on using the repository browser.