FNL檔案之自動化下載
Table of contents
背景
- FNL的全名是(FiNaL) Operational Global Analysis data,是全球數據同化系統(GDAS)的作業結果,空間解析度0.25(083.3)~1度(083.2)、時間間距是6小時。
- FNL在40項WPS可接受的再分析檔案中,屬於穩定性高、解析度較高的選擇。
- 不過FNL沒有提供自動切割的界面,如果要下載全球0.25度的數據,檔案會非常大,要注意頻寬與磁碟空間。
批次執行與自動執行
詳見樓上。
程式分段說明
- 使用py27、有較高的穩定性、避免更新可能造成的錯誤。
- 引進模組,使用urllib2、cookielib來下載,不從檔案匯入,直接讀取遠端cookie,詳見Python 中讓 urllib 使用 cookie 的方法。
kuang@114-32-164-198 ~/python_eg/NCEP_fetch
$ cat -n ff.py
1 #!/opt/anaconda3/envs/py27/bin/python
2 #
3 # python script to download selected files from rda.ucar.edu
4 # after you save the file, don't forget to make it executable
5 # i.e. - "chmod 755 <name_of_script>"
6 #
7 import sys
8 import os
9 import urllib2
10 import cookielib
11 import datetime
12 import subprocess
13
- datetime轉str之副程式
14 def dt2str(dt):
15 a=[int(i) for i in str(dt).split()[0].split('-')]
16 return str(a[0]*100*100+a[1]*100+a[2])
- 在command line 操作時相關指令(無用)
17 #
18 #if (len(sys.argv) == 0):
19 # print "usage: "+sys.argv[0]+" [-q] password_on_RDA_webserver"
20 # print "-q suppresses the progress message for each file that is downloaded"
21 # sys.exit(1)
22 #
23 passwd_idx=1
24 verbose=True
25 if (len(sys.argv) == 3 and sys.argv[1] == "-q"):
26 passwd_idx=2
27 verbose=False
28 #
- cookie的管理
- 這段程式碼是NCEP網站自動產生的
- 同一批次登入時網站會先產生一登入驗證檔案,因此如有舊檔會需要先去除。
- 需先在網站登錄email及密碼,將帳密寫在**處,如此才能登入網站。
29 cj=cookielib.MozillaCookieJar()
30 opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
31 #
32 # check for existing cookies file and authenticate if necessary
33 do_authentication=False
34 if (os.path.isfile("auth.rda.ucar.edu")):
35 cj.load("auth.rda.ucar.edu",False,True)
36 for cookie in cj:
37 if (cookie.name == "sess" and cookie.is_expired()):
38 do_authentication=True
39 else:
40 do_authentication=True
41 if (do_authentication):
42 # passwd=sys.argv[1]
43 passwd='******'
44 login=opener.open("https://rda.ucar.edu/cgi-bin/login","email=*****@***&password="+passwd+"&action=login")
45 #
46 # save the authentication cookies for future downloads
47 # NOTE! - cookies are saved for future sessions because overly-frequent authentication to our server can cause your data access to be blocked
48 cj.clear_session_cookies()
49 cj.save("auth.rda.ucar.edu",True,True)
50 #
- 由檔案系統目錄讀取舊年代
yrold
、並讀取上次作業的最後日期blk
50 #
51 # download the data file(s)
52 #os.system('/Users/kuang/bin/ncep.cs')
53 path='/Users/WRF4.1/NCEP/FNL/'
54 yrold=os.popen('ls -d '+path+'20*|tail -n1').read().strip('\n').split('/')[-1]
55 blk=os.popen('ls '+path+yrold+'|tail -n1').read().strip('\n').split('_')
- 計算下載起始日期
bdate
,由date指令取得今天日期。FNL更新到實際時間的前2天,即為結束日期。
56 try:
57 begd=int(blk[1])
58 except:
59 begd=(int(yrold)-1)*10000+1231
60 ldate = datetime.datetime(begd/100/100,begd/100%100,begd%100)
61 bdate = ldate+datetime.timedelta(days=1)
62 nowd = int(subprocess.check_output("date +%Y%m%d%H", shell=True)[:-3])
63 tdate = datetime.datetime(nowd/100/100,nowd/100%100,nowd%100)
64 edate = tdate+datetime.timedelta(days=-2)
- 由起訖日期計算總日數
leng
65 E_B=str(edate-bdate)
66 if 'day' not in E_B:
67 leng=1
68 else:
69 leng=int(str(edate-bdate).split('day')[0])+1
70 if leng<=0:sys.exit('no need to download, bdate='+str(bdate)+' edate='+str(edate))
- 產生需要下載的日期、年代(有可能要建新目錄)、月份
71 ymds=[dt2str(bdate+datetime.timedelta(days=i)) for i in xrange(leng)]
72 yrs=[ymd[:4] for ymd in ymds]
73 #add new year directory if necessary
74 for yr in yrs:
75 os.system('mkdir -p '+path+'/'+yr)
76 mos=[ymd[4:6] for ymd in ymds]
- 拆解檔案url、形成逐日、逐6小時之url序列
listoffiles
77 head=['grib2/'+yr+'/'+yr+'.' for yr in yrs]
78 med='/fnl_'
79 udl='_'
80 tail='_00.grib2'
81 listoffiles=[head[i]+mos[i]+med+ymds[i]+udl+str(h)+tail for i in xrange(len(ymds)) for h in ['00','06','12','18']]
82 #sys.exit('OK')
- 逐一下載檔案
- 這段程式碼主要是NCEP網站自動產生的
- 因部分作業系統對檔名中的冒號
:
會出現亂碼,如果是,需將其改成底線_
。 - 不適用fnl檔名命名規則
83 for file in listoffiles:
84 idx=file.rfind("/")
85 if (idx > 0):
86 ofile=file[idx+1:].replace(':','_')
87 else:
88 ofile=file.replace(':','_')
89 yr=file.split('/')[1]
90 path1=path+yr+'/'
91 if os.path.isfile(path1+ofile):continue
92 if (verbose):
93 sys.stdout.write("downloading "+ofile+"...")
94 sys.stdout.flush()
95 try:
96 infile=opener.open("http://rda.ucar.edu/data/ds083.2/"+file)
97 except:
98 continue
99 outfile=open(ofile,"wb")
100 outfile.write(infile.read())
101 outfile.close()