-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnarrn_download.py
executable file
·114 lines (106 loc) · 4.09 KB
/
narrn_download.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals, division, print_function
# description: Download NARR from nomads.
# author: Hui ZHENG
# email: woolf1988@qq.com
import sys
import os.path
import urllib.request
import urllib.error
import subprocess
import time
import datetime
RROOT = 'ftp://nomads.ncdc.noaa.gov/NARR'
DIR_TMP = '{year:04d}{month:02d}/{year:04d}{month:02d}{day:02d}'
FLNM_TMP = 'narr-{subset:1s}_221_{year:04d}{month:02d}{day:02d}_{hour:02d}00_000.grb'
TIME_DELTA = datetime.timedelta(hours=3)
def download_file(rpath, lpath):
"""
download file from rpath to lpath
try globus-url-copy firstly, then urllib
"""
os.makedirs(os.path.dirname(lpath), exist_ok=True)
# globus-url-copy
try:
DLD_EXE='globus-url-copy'
DLD_OPT='-q'
subprocess.check_call([DLD_EXE, DLD_OPT, rpath, lpath],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return
except Exception:
pass
# urllib
MAXTRY = 3
for itry in range(MAXTRY):
try:
req = urllib.request.Request(rpath)
with open(lpath, 'wb') as lf, \
urllib.request.urlopen(req) as rf:
lf.write(rf.read())
break
except (urllib.error.URLError, urllib.error.HTTPError) as e:
if itry < MAXTRY - 1:
time.sleep(0.5)
else:
raise e
except Exception as e:
raise e
return
def download_dataset(root='.', begtime=None, endtime=None, subset=None,
flatdir=False, verbosity=False):
if subset is None or subset == '':
subset = 'a'
dt = begtime
while dt < endtime:
for ss in subset:
fold = DIR_TMP.format(year=dt.year, month=dt.month, day=dt.day)
flnm = FLNM_TMP.format(subset=ss,
year=dt.year, month=dt.month, day=dt.day, hour=dt.hour)
if flatdir:
lpath = os.path.join(root, flnm)
else:
lpath = os.path.join(root, fold, flnm)
rpath = os.path.join(RROOT, fold, flnm)
if verbosity: print(os.path.basename(rpath) + ' ... ', end='',flush=True)
try:
download_file(rpath, lpath)
if verbosity: print('Done.')
except KeyboardInterrupt as e:
return
except Exception:
if verbosity: print('Error.')
dt += TIME_DELTA
return
import argparse
import dateutil.parser
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Download NARR 3-hourly product from NOMADS.')
parser.add_argument('root', type=str,
help='root directory for local storage')
parser.add_argument('-s', '--subset', choices=['a', 'b', 'ab'],
help='subset (default: ab)',
default='ab', type=str)
parser.add_argument('-b', '--begtime',
help='start date and time (default: 19790101T00)',
default='19790101T00', type=str)
parser.add_argument('-e', '--endtime',
help='end date and time (exclusive, default: 20140101T00)',
default='20140101T00', type=str)
parser.add_argument('-f', '--flatdir',
help='download all file into one directory',
default=False, action='store_true')
parser.add_argument('-v', '--verbosity',
help='explain what is being done', action='store_true')
args = parser.parse_args()
try:
os.makedirs(args.root, exist_ok=True)
except:
print('unable to write directory: ' + args.root, file=sys.stderr)
sys.exit(1)
download_dataset(root=os.path.abspath(args.root),
begtime=dateutil.parser.parse(args.begtime),
endtime=dateutil.parser.parse(args.endtime),
subset=args.subset,
flatdir=args.flatdir,
verbosity=args.verbosity)