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