diff --git a/bed/read_data.py b/bed/read_data.py index e58d70f..9195d92 100644 --- a/bed/read_data.py +++ b/bed/read_data.py @@ -1,6 +1,7 @@ import logging import pandas as pd import xarray as xr +import numpy as np import os as os from bed.read_config import read_config @@ -65,3 +66,44 @@ def __init__(self, config_file=''): self.population = xr.open_dataset(self.config['path_population_ncdf']) logging.info('Class Data inside module read_data completed.') + + @staticmethod + def set_global_coords(ds, resolution): + offset = resolution / 2 + ds['lat'] = np.linspace(90 - offset, -90 + offset, round(180 / resolution)) + ds['lon'] = np.linspace(-180 + offset, 180 - offset, round(360 / resolution)) + + return ds + + @staticmethod + def regrid(ds, target_resolution, method='extensive'): + """Simple regridding algorithm + + :param ds: xarray Dataset or DataArray, needs lat and lon and global extent + :param target_resolution: target resolution in degrees + :param method: choice of 'extensive' (preserves sums, default), 'intensive' (take average), or 'label' (for maps) + :return: ds regridded to target_resolution + """ + + target_lat_size = round(180 / target_resolution) + + lcm = np.lcm(ds.lat.size, target_lat_size) + r = lcm // ds.lat.size + s = lcm // target_lat_size + + if method == 'label': + ds = ds.isel(lon=np.arange(ds.lon.size).repeat(r)).coarsen(lon=s, boundary='pad').max() + ds = ds.isel(lat=np.arange(ds.lat.size).repeat(r)).coarsen(lat=s, boundary='pad').max() + else: + ds = ds.isel(lon=np.arange(ds.lon.size).repeat(r)).coarsen(lon=s, boundary='pad').sum() + ds = ds.isel(lat=np.arange(ds.lat.size).repeat(r)).coarsen(lat=s, boundary='pad').sum() + if method == 'extensive': + ds = ds / (r * r) # preserve original sum + elif method == 'intensive': + ds = ds / (s * s) # take average + + # set coordinates + ds = set_global_coords(ds, target_resolution) + + return ds + diff --git a/extras/dev_tests.py b/extras/dev_tests.py index 38a1c23..9ab48f1 100644 --- a/extras/dev_tests.py +++ b/extras/dev_tests.py @@ -18,7 +18,11 @@ data = bed.Data(config_file=os.path.join(data_folder, "example_config.yml")) data.example_dataset data.temperature -data.population +ds=data.population +target_resolution=0.5 +method='extensive' + +regrid_ds = data.regrid(ds=data.population, target_resolution=0.5, method='extensive') # Run Diagnsotics bed.diagnostics(data=data)