* * Compute Empirical Orthogonal Functions (EOFs) * * The current GrADS dimension environment is used for the * estimation of the covariance matrix. * EOFs and PCs are written to separate grads file pairs. * * * USAGE: [run] eof [options ] * * with * fld: Input field (GrADS expression). * Options: * -neof <# eof> : Number of EOFs (default: 12) * -npc <# pc> : Number of PCs (default: # eof) * -tinc : Time increment (default: 1) * -nper : Minimal percent of defined data values required * for a grid point to be considered in the EOF calculation * (default: 70 %) * -o : Prefix for output files: (default: first 6 characters of ) * * Normalization: Variance(PCs)=1 * * NOTES: * i) The data are not weighted. Use cos(lat*3.141/180) for a simple area weight. * ii) The program is not well tested for inputs with data gaps. * Please let me know if you get wrong results with for such input. * iii) Try avoiding GrADS's cyclic continuation for global data. * Otherwise the cyclic points are weighted twice. * * (c) Matthias Munnich (munnich@atmos.ucla.edu) **************************************************** * use MATLAB multivariate EOF by (senya@atmos.umd.edu) * * uses WRITECTL GET_UDEF GXSTATE1 * all variables should be regridded to the same grid * current file grid must correspond to that grid ***************************************************** function eofnew(args) 'disable fwrite' * * get options * rc=parsearg(args) if (rc = 1) return endif **************** _undef=get_undef() **************** ********************** printopt() ********************** *save dimensions ***** dimensions=gxstate1() ********************** ******************************************************** * WRITE EOF and PC CTLs ******************************************************** ********************** *write EOF ctl ********************** i=1 str='' while (i<=_nvars) str=str' '_fld.i'>EOF'i i=i+1 endwhile 'set t 1 '_neof args=str' -o '_outb'_eof 0' result=writectl(args) nx=subwrd(result,1) ny=subwrd(result,2) nz=subwrd(result,3) say '*******************************************' * restore dimensions *** gxstate1(dimensions) ************************* ************************* *write PC ctl ************************* *say 'tinc='_tinc 'set x 1' 'set y 1' 'set z 1 '_neof args='lat>PC -o '_outb'_pc 0 '_tinc result=writectl(args) nt=subwrd(result,4) say '*******************************************' * restore dimensions **** gxstate1(dimensions) ************************** ******************************************************** * ENF OF: WRITE EOF and PC CTLs ******************************************************** ******************************************************** * write input data files ******************************************************** 'set gxout fwrite' 'set fwrite eof_in.gad' ******************************************************** * set undef: default is -9.99e8 in v2 ******************************************************** 'q config' res=sublin(result,1) res1=subwrd(res,2) ver=substr(res1,2,1) if ver=2 'set undef '_undef endif ******* adjust to integer grid points ****************** xl=subwrd(dimensions,1) xr=subwrd(dimensions,2) yb=subwrd(dimensions,5) yt=subwrd(dimensions,6) zb=subwrd(dimensions,9) zt=subwrd(dimensions,10) iz1=subwrd(dimensions,11) iz2=subwrd(dimensions,12) t1=subwrd(dimensions,15) t2=subwrd(dimensions,16) *adjust range to grid 'set lon 'xl xl1=subwrd(result,4) 'set lon 'xr xr1=subwrd(result,4) 'set lat 'yb yb1=subwrd(result,4) 'set lat 'yt yt1=subwrd(result,4) 'set lev 'zb zb1=subwrd(result,4) 'set lev 'zt zt1=subwrd(result,4) 'set lon 'xl1' 'xr1 'set lat 'yb1' 'yt1 'set lev 'zb1' 'zt1 'set t 't1' 't2 **** end adjust to grid **************** say ' Writing data to transfer file...' j=1 while (j<=_nvars) tt=t1 tdim=0 while (tt<=t2) 'set t 'tt 'd '_fld.j tt=tt+_tinc tdim=tdim+1 endwhile j=j+1 endwhile 'disable fwrite' say ' 'tdim ' time steps written' 'set gxout contour' say '*******************************************' ******************************************************** * END OF: write input data files ******************************************************** * restore dimensions **** gxstate1(dimensions) ************************** * write info file dum=write('eof_in.inf','% nx ny nz nt nvars neof nper undef file_name') dum=write('eof_in.inf',nx' 'ny' 'nz' 'nt' '_nvars' '_neof' '_nper' '_undef' '_outb, append) dum=close('eof_in.inf') ************************** ************************************************************ say ' *** computing EOFs ***' ************************************************************ '!matlab -nojvm -r "eofgrads; quit"' *'run_matlab_eof' ************************************************************ ****** cleaning files ************************************** '!rm eof_in.gad eof_in.inf' ************************************************************ return **************************************************** *************************** ***************************************************** function parsearg(arg) * Defaults _neof=12 _nper=70 _npc=-1 _verb=0 _tinc=1 _outb='' i=1 word=subwrd(arg,i) if(word = '') usage() return 1 endif while (substr(word,1,1) = '-') if (word = '-neof') i=i+1 _neof=subwrd(arg,i) else if (word = '-npc') i=i+1 _npc=subwrd(arg,i) else if (word = '-nper') i=i+1 _nper=subwrd(arg,i) else if (word = '-o' | word = '-outname') i=i+1 _outb=subwrd(arg,i) else if(word = '-v' | word = '-verbos') _verb = 1 else if(word = '-tinc') i=i+1 _tinc=subwrd(arg,i) else say ' Unknown option: "'word'"' usage() return 1 endif endif endif endif endif endif i=i+1 word=subwrd(arg,i) endwhile j=1 fld=subwrd(arg,i) if(_outb= '') _outb=substr(fld,1,6) endif if(fld = '') say ' Fatal: Missing field expression' usage() return 1 endif while (fld!='') _fld.j=fld i=i+1 j=j+1 fld=subwrd(arg,i) endwhile _nvars=j-1 if(_verb>0) printopt() endif return 0 ******************************************************* ***************************************************** function printopt() say '***************************************' say ' Number of EOFs: ' _neof *say ' Number of PCs: ' _npc say ' Time increment: ' _tinc say ' Required % of good data:' _nper say ' Output files basename: ' _outb say ' Field undef: ' _undef *say ' Field file is XDF: ' _xdf say ' Number of fields: ' _nvars ivar=1 while (ivar<=_nvars) say ' EOF'ivar' of : ' _fld.ivar ivar=ivar+1 endwhile * say ' Verbose:' _verb say '***************************************' return ***************************************************** function usage() say ' EOF: Compute Empirical Orthogonal Functions (EOFs)' say ' eof.gs Version 0.14' say ' ' say ' USAGE: eof [options] fld' say ' ' say ' with ' say ' fld: Input field (GrADS expression).' say ' ' say ' OPTIONS: ' say ' -neof <# eof> : Number of EOFs (default: 12)' say ' -npc <# pc> : Number of PCs (default: # eof)' say ' -tinc : Time increment (default: 1)' say ' -nper : Minimal percent of defined data values required ' say ' for a grid point to be considered in the EOF calculation' say ' (default: 70 %)' say ' -o : Prefix for files: (default: first 6 characters of )' say ' NOTES: ' say ' i) The data are not weighted. Use cos(lat*3.141/180) for a simple area weight.' say ' ii) The program is not well tested for inputs with data gaps.' say ' Please let me know if you get wrong results with for such input.' say ' (c) Matthias Munnich (munnich@atmos.ucla.edu)' return ***************************************************** function get_undef() 'q ctlinfo' i=1 while i<=100000 res=sublin(result,i) qq=subwrd(res,1) if (qq='undef' | qq='UNDEF' |qq='Undef') undef=subwrd(res,2) return undef endif i=i+1 endwhile return ****************************************************** ****************************************************** function gxstate1(args) * * Get or restore dimensions * get dimension USAGE: gxstate1 * restore dimension USAGE: gxstate1 dimensions * dimeansions is the output of get dimension by gxstate1() ****************** if args='args' | args='' 'query dim' dinf = result lx = sublin(dinf,2) ly = sublin(dinf,3) lz = sublin(dinf,4) lt = sublin(dinf,5) if ( subwrd(lx,7) = 'to') lons = subwrd(lx,6) lone = subwrd(lx,8) xs = subwrd(lx,11) xe = subwrd(lx,13) else lons = subwrd(lx,6) lone = subwrd(lx,6) xs = subwrd(lx,9) xe = subwrd(lx,9) endif if ( subwrd(ly,7) = 'to') lats = subwrd(ly,6) late = subwrd(ly,8) ys = subwrd(ly,11) ye = subwrd(ly,13) else lats = subwrd(ly,6) late = subwrd(ly,6) ys = subwrd(ly,9) ye = subwrd(ly,9) endif if ( subwrd(lz,7) = 'to') levs = subwrd(lz,6) leve = subwrd(lz,8) zs = subwrd(lz,11) ze = subwrd(lz,13) else levs = subwrd(lz,6) leve = subwrd(lz,6) zs = subwrd(lz,9) ze = subwrd(lz,9) endif if ( subwrd(lt,7) = 'to') tims = subwrd(lt,6) time = subwrd(lt,8) ts = subwrd(lt,11) te = subwrd(lt,13) else tims = subwrd(lt,6) time = subwrd(lt,6) ts = subwrd(lt,9) te = subwrd(lt,9) endif return(lons' 'lone' 'xs' 'xe' 'lats' 'late' 'ys' 'ye' 'levs' 'leve' 'zs' 'ze' 'tims' 'time' 'ts' 'te) ********end get dimension*********** else 'set lon 'subwrd(args,1)' 'subwrd(args,2) 'set lat 'subwrd(args,5)' 'subwrd(args,6) 'set lev 'subwrd(args,9)' 'subwrd(args,10) *'set time 'subwrd(args,13)' 'subwrd(args,14) 'set t 'subwrd(args,15)' 'subwrd(args,16) endif ***************************************************** function writectl(args) if args='args' | args='' say 'set area and time' say 'USAGE: writevar var1[>newname1] var2[>newname2] ...' say '...-o fname(no extension) [idat] [tinc]' say '[...] optional, default is the same name, idat=1, tinc=1' return endif *read list variables ans='qq' i=1 while (ans!='' & ans!='-o') var2.i=subwrd(args,i) i=i+1 ans=subwrd(args,i) endwhile nvars=i-1 *read output file name or set default if (ans='') fn='qq#' else fn=subwrd(args,i+1) endif *idat=0 only CTL, idat=1 CTL and DATA idat=subwrd(args,i+2) if idat='' idat=1 endif *tinc tinc=subwrd(args,i+3) if tinc='' tinc=1 endif say 'OUT_FILE: 'fn *check for variable rename********** i=1 while(i<=nvars) vl=strlen(var2.i) j=1 i1=vl while j<=vl if substr(var2.i,j,1)='>' i1=j endif j=j+1 endwhile if i1=vl var.i=var2.i varn.i=var2.i else var.i=substr(var2.i,1,i1-1) varn.i=substr(var2.i,i1+1,vl-i1) endif say var.i '-->'varn.i i=i+1 endwhile *save settings dimensions=gxstate1() xl=subwrd(dimensions,1) xr=subwrd(dimensions,2) yb=subwrd(dimensions,5) yt=subwrd(dimensions,6) zb=subwrd(dimensions,9) zt=subwrd(dimensions,10) iz1=subwrd(dimensions,11) iz2=subwrd(dimensions,12) t1=subwrd(dimensions,15) t2=subwrd(dimensions,16) *adjust range to grid 'set lon 'xl xl1=subwrd(result,4) 'set lon 'xr xr1=subwrd(result,4) 'set lat 'yb yb1=subwrd(result,4) 'set lat 'yt yt1=subwrd(result,4) 'set lev 'zb zb1=subwrd(result,4) 'set lev 'zt zt1=subwrd(result,4) 'set lon 'xl1' 'xr1 'set lat 'yb1' 'yt1 'set lev 'zb1' 'zt1 'set t 't1' 't2 *extract CTL file information 'q dims' xline=sublin(result,2) yline=sublin(result,3) zline=sublin(result,4) tline=sublin(result,5) xstatus=subwrd(xline,3) ystatus=subwrd(yline,3) zstatus=subwrd(zline,3) tstatus=subwrd(tline,3) if xstatus='fixed' xset='XDEF 1 LEVELS '%subwrd(xline,6) endif if ystatus='fixed' yset='YDEF 1 LEVELS '%subwrd(yline,6) endif if zstatus='fixed' zset='ZDEF 1 LEVELS '%subwrd(zline,6) levsize=1 endif if tstatus='fixed' tset='TDEF 1 LINEAR '%subwrd(tline,6) endif 'set gxout stat' if xstatus!='fixed' 'set lon 'xl1' 'xr1 'set y 1' 'set z 1' 'set t 1' 'd ' var.1 sline=sublin(result,5) xline=sublin(result,3) xsize=subwrd(sline,3) xscale=subwrd(xline,7) lonsize=xsize if(xscale = 'Linear'); xsize=2; endif; i=8 while(i