WEMC Tech Blog 4.5: Calculating NUTS2 Regional Averages with Land Sea Mask.

This post serves as a continuation on the techniques described in Tech Blog #4. So please familiarise with those steps beforehand.

NUTS2

As before, load in the NUTS shapefiles, this time selecting NUTS2.

NUTS2 is higher resolution and as a result, there are many more shapefiles. NUTS2 contains polygons at a regional (sub-country) level. In total there are 332 shapes for the Eurostat EU region.

Obtain the latest shapefiles from Eurostat.

Select a particular region with the 4 character NUTS_ID string.

For example, Stuttgart (DE):

[pastacode lang=”python” manual=”region%20%3D%20nuts%5Bnuts%5B’NUTS_ID’%5D%20%3D%3D%20’DE11’%5D” message=”” highlight=”” provider=”manual”/]

 

Land Sea Mask (LSM)

The land-sea mask is a field that contains, for every grid point, the proportion of land in the grid box. The values are between 0 (sea) and 1 (land).

You can obtain the ECMWF LSM NetCDF file here

A quick plot of the LSM gives this visual representation of the mask:

Calculate NUT2 Area Averages, with LSM

Now, following the same steps as described in Tech Blog #4, it is possible to calculate the area averages, with the LSM applied.

14/5/19 Update:

The code has been updated and now uses pre-computed LSM from the NUTS shape files as individual .nc files.

This speeds up the computation process considerably, so the shape files don’t have to be computed in the loop on each iteration. You can download the precomputed shapes here.

[pastacode lang=”python” manual=”%0A%23%20coding%3A%20utf-8%0A%0A%23%20NUTS%20Averaging%20V3%0A%23%20if%20running%20on%20C3S_Energy%20VM%2C%20activate%20conda%20before%20running%3A%20source%20activate%20c3s_wemc%0A%23%20luke.sanger%40wemcouncil.org%0A%0A%23%20import%20packages%0Aimport%20iris%0Aimport%20geopandas%20as%20gpd%0Aimport%20pandas%20as%20pd%0Aimport%20numpy%20as%20np%0Aimport%20iris.pandas%0Aimport%20iris.analysis.cartography%0Aimport%20shapely%0Aimport%20glob%2C%20os%0Aimport%20warnings%0Aimport%20time%0A%0A%23%20IMPORTANT%3A%20place%20this%20file%20in%20directory%20where%20ERA5%20files%20are%20located%20and%20define%20path%20below%3A%0Apath%20%3D%20r’your%2Fpath%2Fhere’%0AallFiles%20%3D%20%5Bos.path.basename(x)%20for%20x%20in%20glob.glob(path%20%2B%20r%22%2F*.nc%22)%5D%0A%0A%23%20IMPORTANT%3A%20specify%20one%20nuts%20level%20for%20processing%20.nc%20files%20(Must%20be%20nut0%20or%20nut2)%0Anuts%20%3D%20’nut0’%0A%23%20nuts%20%3D%20’nut2’%0A%0Aif%20nuts%20%3D%3D%20’nut0’%3A%0A%23%20load%20nuts0%20country%20regions%20for%20processing%0A%20%20%20%20path2%20%3D%20r’your%2Fpath%2Fhere%2Fnuts0_masked_nc%2F’%0A%20%20%20%20nutsFiles%20%3D%20%5Bos.path.basename(x)%20for%20x%20in%20glob.glob(path2%20%2B%20r%22%2F*.nc%22)%5D%0Aelif%20nuts%20%3D%3D%20’nut2’%3A%0A%23%20load%20nuts2%20sub-country%20regions%20for%20processing%0A%20%20%20%20path2%20%3D%20r’your%2Fpath%2Fhere%2Fnuts2_masked_nc%2F’%0A%20%20%20%20nutsFiles%20%3D%20%5Bos.path.basename(x)%20for%20x%20in%20glob.glob(path2%20%2B%20r%22%2F*.nc%22)%5D%0A%0A%23%20get%20first%20cube%20in%20list%20to%20get%20cosine%20weights%0Anutslist2%20%3D%20iris.load(path2%20%2B%20nutsFiles%5B0%5D)%0Anutcube2%20%3D%20nutslist2%5B0%5D%0Anutcube2%20%3D%20nutcube2.intersection(longitude%3D(-180%2C%20180))%0Alats2%20%3D%20nutcube2.coord(‘latitude’).points%0Alons2%20%3D%20nutcube2.coord(‘longitude’).points%0A%0A%23%20get%20array%20of%20latitudes%20from%20nutcube%0Acos_lat%20%3D%20iris.analysis.cartography.cosine_latitude_weights(nutcube2)%0A%0A%23%20hide%20pointless%20iris%20warning%20message%20about%20lat%2Flon%0Awarnings.filterwarnings(%22ignore%22%2C%20category%3DUserWarning)%0A%0A%23%20run%20timer%20for%20measuring%20operation%20speed%0Astart%20%3D%20time.time()%0A%0A%23%20literate%20through%20nc%20files%20for%20processing%0Afor%20file_%20in%20allFiles%3A%0A%20%20%20%20cubelist%20%3D%20iris.load(file_)%0A%20%20%20%20cube%20%3D%20cubelist%5B0%5D%0A%20%20%20%20cube%20%3D%20cube.intersection(longitude%3D(-180%2C%20180))%0A%20%20%20%20df%20%3D%20pd.DataFrame()%0A%20%20%20%20name%20%3D%20os.path.splitext(file_)%5B0%5D%0A%20%20%20%20print(‘loaded%20’%20%2B%20name%20%2B%20’%20for%20’%20%2B%20nuts%20%2B%20’%20averaging’)%0A%0A%20%20%20%20%23%20iterate%20through%20nuts%20regions%20%0A%20%20%20%20for%20nut%20in%20nutsFiles%3A%0A%20%20%20%20%20%20%20%20nutslist%20%3D%20iris.load(path2%20%2B%20nut)%0A%20%20%20%20%20%20%20%20nutcube%20%3D%20nutslist%5B0%5D%0A%20%20%20%20%20%20%20%20nutcube%20%3D%20nutcube.intersection(longitude%3D(-180%2C%20180))%0A%20%20%20%20%20%20%20%20lats%20%3D%20nutcube.coord(‘latitude’).points%0A%20%20%20%20%20%20%20%20lons%20%3D%20nutcube.coord(‘longitude’).points%0A%0A%20%20%20%20%20%20%20%20%23%20get%20NUTSID%20from%20filename%20for%20column%20naming%0A%20%20%20%20%20%20%20%20if%20nuts%20%3D%3D%20’nut0’%3A%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20edit%20%3D%20str(nut)%0A%20%20%20%20%20%20%20%20%20%20%20%20NUTSID%20%3D%20edit%5B%3A-15%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘processing%20’%20%2B%20NUTSID%20%2B%20’%20area%2C%20level%20%3D%20’%20%2B%20nuts)%0A%20%20%20%20%20%20%20%20elif%20nuts%20%3D%3D%20’nut2’%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20edit%20%3D%20str(nut)%0A%20%20%20%20%20%20%20%20%20%20%20%20NUTSID%20%3D%20edit%5B%3A-13%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘processing%20’%20%2B%20NUTSID%20%2B%20’%20area%2C%20level%20%3D%20’%20%2B%20nuts)%20%20%20%20%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20multiply%20region%20by%20cosine%20lats%0A%20%20%20%20%20%20%20%20lsm_cos_lat%20%3D%20nutcube.copy()%0A%20%20%20%20%20%20%20%20lsm_cos_lat.data%20*%3D%20cos_lat%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20apply%20the%20lsm_cos_lat%20to%20the%20main%20cube%0A%20%20%20%20%20%20%20%20cube_lsm_cos_lat%20%3D%20cube.copy()%0A%20%20%20%20%20%20%20%20cube_lsm_cos_lat.data%20*%3D%20lsm_cos_lat.data%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23sum%20of%20lsm_cos_lat%20%0A%20%20%20%20%20%20%20%20lsm_cos_lat_sum%20%3D%20lsm_cos_lat.collapsed(%5B’latitude’%2C’longitude’%5D%2C%20iris.analysis.SUM%2C%20weights%3DNone)%0A%0A%20%20%20%20%20%20%20%20%23%20sum%20of%20mc_lsm_cos_lat%0A%20%20%20%20%20%20%20%20cube_lsm_cos_lat_sum%20%3D%20cube_lsm_cos_lat.collapsed(%5B’latitude’%2C’longitude’%5D%2C%20iris.analysis.SUM%2C%20weights%3DNone)%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20divide%20sum%20of%20cube_lsm_cos_lat%20by%20sum%20of%20lsm_cos_lat%0A%20%20%20%20%20%20%20%20end_nuts_lsm_cos_lat_sum%20%3D%20cube_lsm_cos_lat_sum.copy()%0A%20%20%20%20%20%20%20%20end_nuts_lsm_cos_lat_sum.data%20%2F%3D%20lsm_cos_lat_sum.data%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%23%20save%20as%20series%2C%20rename%20colume%20to%20NUTSID%20and%20concat%20to%20dataframe%0A%20%20%20%20%20%20%20%20dfs%20%3D%20iris.pandas.as_series(end_nuts_lsm_cos_lat_sum%2C%20copy%3DTrue)%0A%20%20%20%20%20%20%20%20dfs.rename(columns%3D%7B1%3A%20NUTSID%7D%2C%20inplace%3DTrue)%20%0A%20%20%20%20%20%20%20%20df%20%3D%20pd.concat((df%2C%20dfs.rename(NUTSID))%2C%20axis%3D1)%0A%20%20%20%20%0A%20%20%20%20%23%20organise%20dataframe%20columns%20alphabetically%0A%20%20%20%20df1%20%3D%20df.groupby(axis%3D1%2C%20level%3D0).first()%20%0A%20%20%0A%20%20%20%20%23%20create%20csv%20name%0A%20%20%20%20n1%20%3D%20str(name)%0A%20%20%20%20n2%20%3D%20n1.rstrip(%22.nc%22)%0A%20%20%20%20csv_name%20%3D%20n2%5B%3A32%5D%20%2B%20nuts%20%2B%20n2%5B36%3A%5D%20%2B%20%22.csv%22%0A%0A%20%20%20%20df1.to_csv(csv_name%2C%20mode%3D’a’)%0A%20%20%20%20%0A%20%20%20%20print(csv_name%20%2B’%20created’)%0A%20%20%20%20%0Aprint(nuts%20%2B%20’%20processing%20complete!’)%0Aend%20%3D%20time.time()%0Aprint(‘time%20elapsed%20in%20seconds%3A’)%0Aprint(end%20-%20start)%0A%0A” message=”NUTS2 Area Average” highlight=”” provider=”manual”/]

As usual, you can also get the code from my GitHub page.

by Luke Sanger (WEMC Data Engineer, 2019)

Recommended Posts