Skip to content

Commit 3b49be4

Browse files
author
Diana
committed
add functions for working with downscaled data
1 parent 27bf3f8 commit 3b49be4

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
import gcsfs
2+
import xarray as xr
3+
def read_gcs_zarr(zarr_url, token='/opt/gcsfuse_tokens/impactlab-data.json', check=False):
4+
"""
5+
takes in a GCSFS zarr url, bucket token, and returns a dataset
6+
Note that you will need to have the proper bucket authentication.
7+
"""
8+
fs = gcsfs.GCSFileSystem(token=token)
9+
10+
store_path = fs.get_mapper(zarr_url, check=check)
11+
ds = xr.open_zarr(store_path)
12+
13+
return ds
14+
def get_cmip6_models():
15+
models_dict = {'BCC-CSM2-MR': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
16+
'FGOALS-g3': ['historical', 'ssp245', 'ssp370', 'ssp585'],
17+
'ACCESS-ESM1-5': ['historical', 'ssp126', 'ssp245', 'ssp370'],
18+
'ACCESS-CM2': ['historical', 'ssp245', 'ssp370'],
19+
'INM-CM4-8': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
20+
'INM-CM5-0': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
21+
'MIROC-ES2L': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
22+
'MIROC6': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
23+
'NorESM2-LM': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
24+
'NorESM2-MM': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
25+
'GFDL-ESM4': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
26+
'GFDL-CM4': ['historical', 'ssp245', 'ssp585'],
27+
'NESM3': ['historical', 'ssp126', 'ssp245', 'ssp585'],
28+
'MPI-ESM1-2-HR': ['historical', 'ssp126', 'ssp585'],
29+
'HadGEM3-GC31-LL': ['historical', 'ssp126', 'ssp245', 'ssp585'],
30+
'UKESM1-0-LL': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
31+
'MPI-ESM1-2-LR': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
32+
'CMCC-CM2-SR5': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
33+
'CMCC-ESM2': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
34+
'CanESM5': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
35+
'EC-Earth3': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
36+
'EC-Earth3-AerChem': ['historical', 'ssp370'],
37+
'EC-Earth3-CC': ['historical', 'ssp245', 'ssp585'],
38+
'EC-Earth3-Veg': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
39+
'EC-Earth3-Veg-LR': ['historical', 'ssp126', 'ssp245', 'ssp370', 'ssp585'],
40+
}
41+
return models_dict
42+
43+
def get_cmip6_institutions():
44+
institutions = {'BCC-CSM2-MR': 'BCC', 'FGOALS-g3': 'CAS', 'ACCESS-ESM1-5': 'CSIRO', 'ACCESS-CM2': 'CSIRO-ARCCSS',
45+
'INM-CM4-8': 'INM',
46+
'INM-CM5-0': 'INM',
47+
'MIROC-ES2L': 'MIROC',
48+
'MIROC6': 'MIROC',
49+
'NorESM2-LM': 'NCC',
50+
'NorESM2-MM': 'NCC',
51+
'GFDL-ESM4': 'NOAA-GFDL',
52+
'GFDL-CM4': 'NOAA-GFDL',
53+
'NESM3': 'NUIST',
54+
'MPI-ESM1-2-HR': 'DKRZ',
55+
'HadGEM3-GC31-LL': 'MOHC',
56+
'UKESM1-0-LL': 'MOHC',
57+
'MPI-ESM1-2-LR': 'MPI-M',
58+
'CMCC-CM2-SR5': 'CMCC',
59+
'CMCC-ESM2': 'CMCC',
60+
'CanESM5': 'CCCma',
61+
'EC-Earth3': 'EC-Earth-Consortium',
62+
'EC-Earth3-AerChem': 'EC-Earth-Consortium',
63+
'EC-Earth3-CC': 'EC-Earth-Consortium',
64+
'EC-Earth3-Veg': 'EC-Earth-Consortium',
65+
'EC-Earth3-Veg-LR': 'EC-Earth-Consortium',
66+
}
67+
return institutions
68+
69+
def get_cmip6_grids():
70+
grids = {'BCC-CSM2-MR': 'gn', 'FGOALS-g3': 'gn', 'ACCESS-ESM1-5': 'gn', 'ACCESS-CM2': 'gn',
71+
'INM-CM4-8': 'gr1',
72+
'INM-CM5-0': 'gr1',
73+
'MIROC-ES2L': 'gn',
74+
'MIROC6': 'gn',
75+
'NorESM2-LM': 'gn',
76+
'NorESM2-MM': 'gn',
77+
'GFDL-ESM4': 'gr1',
78+
'GFDL-CM4': 'gr1',
79+
'NESM3': 'gn',
80+
'MPI-ESM1-2-HR': 'gn',
81+
'HadGEM3-GC31-LL': 'gn',
82+
'UKESM1-0-LL': 'gn',
83+
'MPI-ESM1-2-LR': 'gn',
84+
'CMCC-CM2-SR5': 'gn',
85+
'CMCC-ESM2': 'gn',
86+
'CanESM5': 'gn',
87+
'EC-Earth3': 'gr',
88+
'EC-Earth3-AerChem': 'gr',
89+
'EC-Earth3-CC': 'gr',
90+
'EC-Earth3-Veg': 'gr',
91+
'EC-Earth3-Veg-LR': 'gr',
92+
}
93+
return grids
94+
95+
def get_cmip6_ensemble_members():
96+
ensemble_members = {'BCC-CSM2-MR': 'r1i1p1f1',
97+
'FGOALS-g3': 'r1i1p1f1',
98+
'ACCESS-ESM1-5': 'r1i1p1f1',
99+
'ACCESS-CM2': 'r1i1p1f1',
100+
'INM-CM4-8': 'r1i1p1f1',
101+
'INM-CM5-0': 'r1i1p1f1',
102+
'MIROC-ES2L': 'r1i1p1f2',
103+
'MIROC6': 'r1i1p1f1',
104+
'NorESM2-LM': 'r1i1p1f1',
105+
'NorESM2-MM': 'r1i1p1f1',
106+
'GFDL-ESM4': 'r1i1p1f1',
107+
'GFDL-CM4': 'r1i1p1f1',
108+
'NESM3': 'r1i1p1f1',
109+
'MPI-ESM1-2-HR': 'r1i1p1f1',
110+
'HadGEM3-GC31-LL': 'r1i1p1f3',
111+
'UKESM1-0-LL': 'r1i1p1f2',
112+
'MPI-ESM1-2-LR': 'r1i1p1f1',
113+
'CMCC-CM2-SR5': 'r1i1p1f1',
114+
'CMCC-ESM2': 'r1i1p1f1',
115+
'CanESM5': 'r1i1p1f1',
116+
'EC-Earth3': 'r1i1p1f1',
117+
'EC-Earth3-AerChem': 'r1i1p1f1',
118+
'EC-Earth3-CC': 'r1i1p1f1',
119+
'EC-Earth3-Veg': 'r1i1p1f1',
120+
'EC-Earth3-Veg-LR': 'r1i1p1f1',
121+
}
122+
return ensemble_members
123+
124+
def get_ds_filepath(varname, model, stage, scen):
125+
filepath = all_paths[model + '-' + varname][scen][stage]
126+
return filepath
127+
128+
def load_zarr(filepath):
129+
ds = read_gcs_zarr(filepath)
130+
return ds
131+
132+
def get_diagnostics_filepath(diag_type, data_type, institutions, ensemble_members, variable, model, ssp,
133+
validation_period=False):
134+
"""
135+
variables: {'tasmax', 'tasmin', 'precip'}
136+
ssps: {'ssp126', 'ssp245', 'ssp370', 'ssp585'}
137+
period: {'historical', 'future'}
138+
diag_type: {'city', 'annual'}
139+
data_type: {'clean', 'bias_corrected', 'downscaled', 'reanalysis'}
140+
validation_period: {True, False} defaults to False, if True then the 0p25x0p25 grid is used for ERA-5
141+
"""
142+
143+
if variable == "precip":
144+
file_var_name = "pr"
145+
var_name = 'pr'
146+
else:
147+
file_var_name = variable
148+
var_name = variable
149+
150+
if diag_type == 'city':
151+
agg_period = 'daily'
152+
elif diag_type == 'annual':
153+
agg_period = 'annual'
154+
155+
if data_type == "clean":
156+
diag_folder = 'clean-{agg_period}-{variable}-diagnostics'.format(agg_period=agg_period, variable=variable)
157+
elif data_type == 'bias_corrected':
158+
diag_folder = 'biascorrected-{agg_period}-{variable}-diagnostics'.format(agg_period=agg_period, variable=variable)
159+
elif data_type == 'downscaled' or data_type == 'reanalysis':
160+
diag_folder = '{agg_period}-{variable}-diagnostics'.format(agg_period=agg_period, variable=variable)
161+
162+
if ssp == 'historical':
163+
experiment = 'CMIP'
164+
else:
165+
experiment = 'ScenarioMIP'
166+
167+
if data_type == 'reanalysis':
168+
if validation_period:
169+
filepath = ('gs://downscaled-288ec5ac/diagnostics/RELEASE-v1.1/{diag_folder}/reanalysis/ERA5/0p25x0p25/{variable}/v1.1.zarr').format(diag_folder=diag_folder, variable=file_var_name)
170+
else:
171+
filepath = ('gs://downscaled-288ec5ac/diagnostics/RELEASE-v1.1/{diag_folder}/reanalysis/ERA5/F320/{variable}/v1.1.zarr').format(diag_folder=diag_folder, variable=file_var_name)
172+
else:
173+
filepath = ('gs://downscaled-288ec5ac/diagnostics/RELEASE-v1.1/{diag_folder}/{experiment}/{institution}/{model}/{ssp}/{ensemble_member}/day/{variable}/v1.1.zarr').format(diag_folder=diag_folder, experiment=experiment, institution=institutions[model], model=model, ssp=ssp, ensemble_member=ensemble_members[model], variable=file_var_name)
174+
175+
return filepath
176+
177+
def convert_longitudes(ds, lon_name):
178+
179+
# Adjust lon values to make sure they are within (-180, 180)
180+
ds['_longitude_adjusted'] = xr.where(
181+
ds[lon_name] > 180,
182+
ds[lon_name] - 360,
183+
ds[lon_name])
184+
185+
# reassign the new coords to as the main lon coords
186+
# and sort DataArray using new coordinate values
187+
ds = (
188+
ds
189+
.swap_dims({lon_name: '_longitude_adjusted'})
190+
.sel(**{'_longitude_adjusted': sorted(ds._longitude_adjusted)})
191+
.drop(lon_name))
192+
193+
ds = ds.rename({'_longitude_adjusted': lon_name})
194+
195+
return ds

0 commit comments

Comments
 (0)