Skip to content

Commit cce7fa6

Browse files
yunjunzyuankailiu
andauthored
update to the official new CDS (#44)
+ `autoget.py`: - update `cds_url` link - update to the latest syntax of `cdsapi` for the request dictionary input - use `f'{}'` instead of `.format` syntax + `README.md`: update account setup doc for the official new CDS + `requirements.txt`: the new CDS requires cdsapi>=0.7.2 + update `model.cfg` and `tests/test_dload.py` for the new CDS + `processor.intP2H()`: add whitespace for better readability --------- Co-authored-by: Yuan-Kai Liu <[email protected]>
1 parent 11143ec commit cce7fa6

File tree

6 files changed

+54
-50
lines changed

6 files changed

+54
-50
lines changed

README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,19 @@ python PyAPS/tests/test_calc.py
5959

6060
### 2. Account setup for [ERA5](https://www.ecmwf.int/en/forecasts/dataset/ecmwf-reanalysis-v5)
6161

62-
ERA5 data set is redistributed over the Copernicus Climate Data Store (CDS)-beta ([migration guide](https://confluence.ecmwf.int/display/CKB/Please+read%3A+CDS+and+ADS+migrating+to+new+infrastructure%3A+Common+Data+Store+%28CDS%29+Engine)). Registration is required for the data access and downloading.
62+
ERA5 data set is redistributed over the Copernicus Climate Data Store (CDS). Registration is required for the data access and downloading.
6363

64-
+ [Create a new account](https://cds-beta.climate.copernicus.eu/) on the CDS-beta website if you don't own a user account yet. Note: the old CDS account won't work.
65-
+ [CDS API setup](https://cds-beta.climate.copernicus.eu/how-to-api#install-the-cds-api-client): Create the local file `$HOME/.cdsapirc` (in your Unix/Linux environment) and add the following two lines:
64+
+ [Create a new account](https://cds.climate.copernicus.eu/) on the CDS website if you don't own a user account yet. Note: the old CDS account won't work ([Goodbye legacy CDS, Hellow New CDS!](https://forum.ecmwf.int/t/goodbye-legacy-climate-data-store-hello-new-climate-data-store-cds/6380)).
65+
+ [CDS API setup](https://cds.climate.copernicus.eu/how-to-api): Create the local file `$HOME/.cdsapirc` (in your Unix/Linux environment) and add the following two lines:
6666

6767
```shell
68-
url: https://cds-beta.climate.copernicus.eu/api
68+
url: https://cds.climate.copernicus.eu/api
6969
key: your-personal-access-token
7070
```
7171

72-
Your Personal Access Token can be found under [Your profile > Personal Access Token](https://cds-beta.climate.copernicus.eu/profile) section or on the [setup guide](https://cds-beta.climate.copernicus.eu/how-to-api#install-the-cds-api-client) page. Alternatively, you could add the token to the `[CDS]` section in `model.cfg` file in the package directory, `site-packages/pyaps3` if installed via conda. Note: using your [old CDS API key](https://cds.climate.copernicus.eu/) will lead to a 401 Client Error and Authentication failed.
72+
Your Personal Access Token can be found under [Your profile > Personal Access Token](https://cds.climate.copernicus.eu/profile) section or on the [setup guide](https://cds.climate.copernicus.eu/how-to-api) page. Alternatively, you could add the token to the `[CDS]` section in `model.cfg` file in the package directory, `site-packages/pyaps3` if installed via conda. Note: using your legacy CDS API key will lead to a 401 Client Error and Authentication failed.
7373

74-
+ **Make sure** that you accept the data license in the Terms of use on ECMWF website: Login, under [Datasets > ERA5 hourly data on pressure levels from 1940 to present > Download > Terms of use](https://cds-beta.climate.copernicus.eu/datasets/reanalysis-era5-pressure-levels?tab=download), click **Accept** to accespt the license to use Copernicus Products.
74+
+ **Make sure** that you accept the data license in the Terms of use on ECMWF website: Login, under [Datasets > ERA5 hourly data on pressure levels from 1940 to present > Download > Terms of use](https://cds.climate.copernicus.eu/datasets/reanalysis-era5-pressure-levels?tab=download), click **Accept** to accespt the license to use Copernicus Products.
7575

7676
+ Test the account setup by running:
7777

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cdsapi>=0.7.0
1+
cdsapi>=0.7.2
22
numpy
33
pygrib
44
scipy

src/pyaps3/autoget.py

+37-33
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,26 @@ def ECMWFdload(bdate,hr,filedir,model='ERA5',datatype='fc',humidity='Q',snwe=Non
4141
# Initialize
4242

4343
# Check data
44-
assert model in ('ERA5', 'ERAINT', 'HRES'), 'Unknown model for ECMWF: {}'.format(model)
44+
assert model in ('ERA5', 'ERAINT', 'HRES'), f'Unknown model for ECMWF: {model}'
4545

4646
# Infos for downloading
47-
if model in 'ERAINT':
48-
print('WARNING: you are downloading from the old ECMWF platform. '
47+
if model == 'ERAINT':
48+
print('WARNING: you are downloading from the legacy ECMWF platform. '
4949
'ERA-Interim is deprecated, use ERA-5 instead.')
50-
if model in 'ERA5':
51-
cds_url = 'https://cds-beta.climate.copernicus.eu/api'
50+
if model == 'ERA5':
51+
cds_url = 'https://cds.climate.copernicus.eu/api'
5252
print('INFO: You are using the latest ECMWF platform for downloading datasets: ', cds_url)
5353

5454
#-------------------------------------------
5555
# Define parameters
5656

5757
# Humidity
5858
assert humidity in ('Q','R'), 'Unknown humidity field for ECMWF'
59-
if humidity in 'Q':
59+
if humidity == 'Q':
6060
humidparam = 'specific_humidity' if model == 'ERA5' else 133
61-
elif humidity in 'R':
61+
elif humidity == 'R':
6262
humidparam = 'relative_humidity' if model == 'ERA5' else 157
6363

64-
# Grid size (only for HRES and ERA-Interim)
65-
if model in 'HRES':
66-
gridsize = '0.10/0.10'
67-
elif model in 'ERAINT':
68-
gridsize = '0.75/0.75'
69-
7064
#-------------------------------------------
7165
# file name
7266
if not flist:
@@ -92,7 +86,7 @@ def ECMWFdload(bdate,hr,filedir,model='ERA5',datatype='fc',humidity='Q',snwe=Non
9286

9387
#-------------------------------------------
9488
# CASE 1: request for CDS API client (new ECMWF platform, for ERA5)
95-
if model in 'ERA5':
89+
if model == 'ERA5':
9690
# Contact the server
9791
rc_file = os.path.expanduser('~/.cdsapirc')
9892
if os.path.isfile(rc_file):
@@ -102,39 +96,49 @@ def ECMWFdload(bdate,hr,filedir,model='ERA5',datatype='fc',humidity='Q',snwe=Non
10296
key = config.get('CDS', 'key')
10397
c = cdsapi.Client(url=url, key=key)
10498

105-
# Pressure levels
106-
pressure_lvls = ['1','2','3','5','7','10','20','30','50',
107-
'70','100','125','150','175','200','225',
108-
'250','300','350','400','450','500','550',
109-
'600','650','700','750','775','800','825',
110-
'850','875','900','925','950','975','1000']
111-
112-
# Dictionary
113-
indict = {'product_type' :'reanalysis',
114-
'format' :'grib',
115-
'variable' :['geopotential','temperature','{}'.format(humidparam)],
116-
'pressure_level' : pressure_lvls,
117-
'year' :'{}'.format(day[0:4]),
118-
'month' :'{}'.format(day[4:6]),
119-
'day' :'{}'.format(day[6:8]),
120-
'time' :'{}:00'.format(hr)}
99+
# request dictionary
100+
pressure_lvls = [
101+
'1','2','3','5','7','10','20','30','50',
102+
'70','100','125','150','175','200','225',
103+
'250','300','350','400','450','500','550',
104+
'600','650','700','750','775','800','825',
105+
'850','875','900','925','950','975','1000',
106+
]
107+
108+
indict = {
109+
'product_type' : ['reanalysis'],
110+
'variable' : ['geopotential', 'temperature', f'{humidparam}'],
111+
'year' : [f'{day[0:4]}'],
112+
'month' : [f'{day[4:6]}'],
113+
'day' : [f'{day[6:8]}'],
114+
'time' : [f'{hr}:00'],
115+
'pressure_level' : pressure_lvls,
116+
'data_format' : 'grib',
117+
}
121118

122119
# download a geographical area subset
123120
if snwe is not None:
124121
s, n, w, e = snwe
125-
indict['area'] = '/'.join(['{:.2f}'.format(x) for x in [n, w, s, e]])
122+
indict['area'] = [n, w, s, e]
126123

127124
# Assert grib file not yet downloaded
128125
if not os.path.exists(fname):
129-
print('Downloading %d of %d: %s '%(i+1, len(bdate), fname))
126+
print(f'Downloading {i+1} of {len(bdate)}: {fname} ')
130127
print(indict)
131128

132129
# Make the request
133-
c.retrieve('reanalysis-{}-pressure-levels'.format(model.lower()),indict,target=fname)
130+
ds_name = f'reanalysis-{model.lower()}-pressure-levels'
131+
c.retrieve(ds_name, indict, target=fname)
134132

135133
#-------------------------------------------
136134
# CASE 2: request for WEB API client (old ECMWF platform, deprecated, for ERA-Int and HRES)
137135
else:
136+
# Grid size (only for HRES and ERA-Interim)
137+
if model == 'HRES':
138+
gridsize = '0.10/0.10'
139+
elif model == 'ERAINT':
140+
gridsize = '0.75/0.75'
141+
138142
# Contact the server
139143
from pyaps3.ecmwfapi import ECMWFDataServer
140144
url = "https://api.ecmwf.int/v1"

src/pyaps3/model.cfg

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# vim: set filetype=cfg:
2-
#####key for ECMWF in Climate Data Store Application Program Interface
3-
#Get it from https://retostauffer.org/code/Download-ERA5/
2+
#####Personal Access Token for ECMWF in Climate Data Store Application Program Interface
3+
#Get it from https://cds.climate.copernicus.eu/profile
44
#for ERA5
55
[CDS]
66
key = your-personal-access-token

src/pyaps3/processor.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,12 @@ def intP2H(lvls,hgt,gph,tmp,vpr,cdic,verbose=False):
111111
#Interpolating pressure values
112112
hy = lvls.copy()
113113
if (sFlag == True):
114-
val = hy[-1] +(hx[-1] - hx[-2])* (hy[-1] - hy[-2])/(hx[-2]-hx[-3])
114+
val = hy[-1] + (hx[-1] - hx[-2]) * (hy[-1] - hy[-2]) / (hx[-2] - hx[-3])
115115
#changed from 1 to 0 (-1 should also work), CL
116116
hy = np.concatenate((hy,[val]),axis=0)
117117

118118
if (eFlag == True):
119-
val = hy[0] - (hx[0] - hx[1]) * (hy[0] - hy[1])/(hx[1]-hx[2])
119+
val = hy[0] - (hx[0] - hx[1]) * (hy[0] - hy[1]) / (hx[1] - hx[2])
120120
#changed from 1 to 0 (-1 should also work), CL
121121
hy = np.concatenate(([val],hy),axis=0)
122122

@@ -130,12 +130,12 @@ def intP2H(lvls,hgt,gph,tmp,vpr,cdic,verbose=False):
130130
temp = tmp[:,i,j]
131131
hy = temp.copy()
132132
if (sFlag == True):
133-
val = hy[-1] +(hx[-1] - hx[-2])* (hy[-1] - hy[-2])/(hx[-2]-hx[-3])
133+
val = hy[-1] + (hx[-1] - hx[-2]) * (hy[-1] - hy[-2]) / (hx[-2] - hx[-3])
134134
#changed from 1 to 0 (-1 should also work), CL
135135
hy = np.concatenate((hy,[val]),axis=0)
136136

137137
if (eFlag == True):
138-
val = hy[0] - (hx[0] - hx[1]) * (hy[0] - hy[1])/(hx[1]-hx[2])
138+
val = hy[0] - (hx[0] - hx[1]) * (hy[0] - hy[1]) / (hx[1] - hx[2])
139139
#changed from 1 to 0 (-1 should also work), CL
140140
hy = np.concatenate(([val],hy),axis=0)
141141

@@ -148,12 +148,12 @@ def intP2H(lvls,hgt,gph,tmp,vpr,cdic,verbose=False):
148148
temp = vpr[:,i,j]
149149
hy = temp.copy()
150150
if (sFlag == True):
151-
val = hy[-1] +(hx[-1] - hx[-2])* (hy[-1] - hy[-2])/(hx[-2]-hx[-3])
151+
val = hy[-1] + (hx[-1] - hx[-2]) * (hy[-1] - hy[-2]) / (hx[-2] - hx[-3])
152152
#changed from 1 to 0 (-1 should also work), CL
153153
hy = np.concatenate((hy,[val]),axis=0)
154154

155155
if (eFlag == True):
156-
val = hy[0] - (hx[0] - hx[1]) * (hy[0] - hy[1])/(hx[1]-hx[2])
156+
val = hy[0] - (hx[0] - hx[1]) * (hy[0] - hy[1]) / (hx[1] - hx[2])
157157
#changed from 1 to 0 (-1 should also work), CL
158158
hy = np.concatenate(([val],hy),axis=0)
159159

tests/test_dload.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
print('import pyaps3 from {}'.format(pa.__file__))
99
print('------------------------------------------------')
1010
print('test ERA5 data download')
11-
print('NOTE: Account setup is required on the Copernicus Climate Data Store (CDS)-beta.')
12-
print(' More detailed info can be found on: https://cds-beta.climate.copernicus.eu/how-to-api')
11+
print('NOTE: Account setup is required on the Copernicus Climate Data Store (CDS).')
12+
print(' More detailed info can be found on: https://cds.climate.copernicus.eu/how-to-api')
1313
print(' Add your account info to ~/.cdsapirc file.')
1414
filedir = os.path.join(os.path.dirname(__file__), 'data', 'ERA5')
1515
pa.ECMWFdload(['20200601','20200901'], hr='14', filedir=filedir, model='ERA5', snwe=(30,40,120,140))

0 commit comments

Comments
 (0)