EOF 分析实例:学习和使用ferret
(2011-11-08 01:26:18)
标签:
eofferret |
分类: 学术科研 |
采用与前一篇文章相同的数据,这次改用ferret进行EOF分析。
use tsw, slp, ustrw,
vstrw
show data
set
reg/x=110s:70w/y=20s:60n/t=1-Jan-3500:31-Dec-3600
use etopo120
5>
./etopo120.cdf (default)
name
title
I
J
K
L
ROSE
RELIEF OF THE SURFACE OF THE EA
1:180 1:90
...
...
show grid tsw
name
axis
# pts
start
end
LON
LONGITUDE
48mr 112.5E
71.25W
LAT
LATITUDE
21 i 16.7S
57.52N
normal
Z
TIME1
TIME
1212 i
31-JAN-3500 12:00 31-DEC-3600
12:00
define grid/x=lon/y=lat
p86grid
let
roseinterp=rose[d=5,g=p86grid]
rose[d=5,g=p86grid]
let
tswmasked=if roseinterp gt 0 then (-999) else tsw[d=1]
let a = if b gt c then d
else e
set var/bad=-999
tswmasked
let
tswann=tswmasked-tswmasked[t=1-Jan-3500:31-Dec-3600@ave]
let
eofs=eof_space(tswann, 20, 0.8)
let pcs=eof_tfunc(tswann,
20,0.8)
let
sta=eof_stat(tswann,20,0.8)
set var/title='eofs'
eofs; set var/title='time functions' pcs; set
var/title='statistics' sta
save/file=eofresult.nc
eofs,pcs,sta
1. 导入要分析的数据:
在ferret中输入命令
察看数据属性:
ferret会显示当前打开的数据文件及其中所包含的数据变量的列表和信息。这些数据文件中只有一个处于当前激活状态,在列表中标记为(default),它所包含的数据变量可以直接访问。非激活状态的数据文件中的变量不能直接使用,而需要以var[d=file]的形式访问。其中var是变量名,file是数据文件名。要改变当前激活的数据文件,使用set
data file或set data n,其中file为数据文件名,n为数据文件的编号。
2. 设定时间和空间范围
reg是region的简写。set命令用于设置属性,region是要设置的对象,/后面分隔的是不同的属性。ferret中的经纬度可以用110e,70w,20s,60n这样的写法表示,同时也支持用负数表示西经和南纬。时间的写法必须按照dd-mmm-yyyy的格式来写。这样设置了时空范围以后,下面的所有操作都是限定在这个范围内进行的。
3. 使用etopo地形数据将陆地点设为无效数据
3.1 首先打开etopo120数据:
show data显示
说明其中有一个名为rose的变量。
3.2 将水深数据插值到其他数据的网格上:
首先需要获取tsw等数据的网格信息:
显示
说明其x、y、z、t坐标轴的名字分别为lon、lat、normal和time1. 我们用已有的坐标轴建立网格:
define命令用来定义坐标轴(axis)、网格(grid)等。坐标轴和网格都是特殊形式的变量,其中网格是定义在2-4个坐标轴的基础上的。这里使用坐标轴lon和lat定义了网格p86grid。
接下来将etopo数据插值到p86grid网格上。ferret中的插值相当简单,采用一种叫做regridding的机制:
这里用到了let命令,它的作用是定义新的变量。这样定义的变量不属于任何数据文件,因此可以随时使用。roseinterp就是新变量的名字,等号后面是赋值表达式。
这种形式是对变量的附加描述,指明该变量来源的数据文件编号为5,网格为p86grid。这样就完成了插值。
事实上,现在ferret还没有进行实际的插值操作,它只是将新的网格信息以变量描述的形式保存下来,而只有当真正需要使用新变量roseinterp的值的时候才会进行插值计算。
3.3 设置陆地点为无效数据
利用if-then-else语句来实现区域条件赋值,即把水深大于0的点设为无效数据,而小于0的数据则保留:
if-then-else结构按条件返回不同的值。例如
判断b gt
c的真假(gt是大于的意思),如果为真,则返回d,否则返回e,而a接收其返回值。这种条件赋值是面向矩阵元素的,也就是要求b、c、d、e的形状相同,对于矩阵中每一个对应位置的元素,分别进行判断和选择,最终a的形状也与bcde相同。
这里是利用roseinterp变量是否大于零来判断,大于零的地方新变量的值设为-999(ferret中负数常量应该加括
号),其他地方新变量的值等于编号为1的数据文件中的tsw变量。因为我们会同时用到不同数据文件中的变量,因此应该总是指定变量的来源。
下面将-999设为无效数据:
ferret中的默认无效值是-1e34,但可以给变量任意指定无效值。通过改变变量tswmasked的bad属性即可完成。
这样tswmasked变量中就保存了去掉陆地点的数据。
4. 计算异常
这里的变量描述用到了变换(transform)@ave。ferret中以@ave开头的就是变换,写在某个坐标轴的后面,表示对这个坐标轴进行一定的操作。上面的@ave就是平均,t=1-Jan-3500:31-Dec-3600@ave表示对3500年1月1日到3600年12月31日的时间范围进行平均。
5. 计算EOF
ferret中函数eof_space用于EOF分析,它的语法为:
其中第一个参数就是要分析的数据,是一个三维(xyt)的数据,第二个参数是最低计算到多少方差贡献的eof,如果想要得到方差贡献不小于0.2的eof,就写20;第三个参量一般取0.8.返回的结果也是一个三维矩阵,其中第三维表示不同的eof。
相应的eof_tfunc函数用来计算时间系数(PC),而eof_stat函数返回满足最低方差贡献要求的eof的个数、特征值、方差贡献等统计量:
ferret不会马上计算eof,而是把变量的表达式保存下来,在需要使用它的值(如画图)的时候才真正进行计算。
6. 保存结果到nc文件
同一行内写多个命令要用分号分开,而一个命令分在多行书写要在每行末尾加;\。
save命令是用来将数据写入文件的,除了nc,ferret还支持很多其他格式。
可见ferret处理海洋大气数据也是相当方便的。它的变量其实只是保存了一个表达式,真正要使用变量值的时候才会进行计算。这样一般来讲会节省时间和内存。但似乎每次使用变量值的时候都会重新计算,而不是第一次计算之后把结果保存下来,下次再使用的时候直接从内存调用。对于eof这样比较消耗时间的操作,这样做似乎不是很好。
上面从第三步开始的操作就只针对tsw变量了,要对每个变量都进行eof分析,需要重复步骤3-6.
可以写脚本文件用循环来完成。
ferret的另一个主要特点就是它的方便又强大的绘图功能。下一步会介绍使用ferret绘制eof的结果图,其中会包含ferret脚本文件的写法。