def add_chirps( urls: Dict[Any, Any], ds: xr.Dataset, era: str, training: bool = True, dask_chunks: Dict[Any, Any] = { "x": "auto", "y": "auto" }, ) -> Optional[xr.Dataset]: # load rainfall climatology if era == "_S1": chirps = rio_slurp_xarray(urls["chirps"][0]) if era == "_S2": chirps = rio_slurp_xarray(urls["chirps"][1]) if chirps.size >= 2: if training: chirps = xr_reproject(chirps, ds.geobox, "bilinear") ds["rain"] = chirps else: # Clip CHIRPS to ~ S2 tile boundaries so we can handle NaNs local to S2 tile xmin, xmax = ds.x.values[0], ds.x.values[-1] ymin, ymax = ds.y.values[0], ds.y.values[-1] inProj = Proj("epsg:6933") outProj = Proj("epsg:4326") xmin, ymin = transform(inProj, outProj, xmin, ymin) xmax, ymax = transform(inProj, outProj, xmax, ymax) # create lat/lon indexing slices - buffer S2 bbox by 0.05deg if (xmin < 0) & (xmax < 0): x_slice = list(np.arange(xmin + 0.05, xmax - 0.05, -0.05)) else: x_slice = list(np.arange(xmax - 0.05, xmin + 0.05, 0.05)) y_slice = list(np.arange(ymin - 0.05, ymax + 0.1, 0.05)) # index global chirps using buffered s2 tile bbox chirps = assign_crs( chirps.sel(longitude=y_slice, latitude=x_slice, method="nearest")) # fill any NaNs in CHIRPS with local (s2-tile bbox) mean chirps = chirps.fillna(chirps.mean()) chirps = xr_reproject(chirps, ds.geobox, "bilinear") chirps = chirps.chunk(dask_chunks) ds["rain"] = chirps # rename bands to include era for band in ds.data_vars: ds = ds.rename({band: band + era}) return ds return None
def annual_gm_mads_evi_training(ds): dc = datacube.Datacube(app='training') # grab gm+tmads gm_mads=dc.load(product='ga_s2_gm',time='2019',like=ds.geobox, measurements=['red', 'blue', 'green', 'nir', 'swir_1', 'swir_2', 'red_edge_1', 'red_edge_2', 'red_edge_3', 'SMAD', 'BCMAD','EMAD']) gm_mads['SMAD'] = -np.log(gm_mads['SMAD']) gm_mads['BCMAD'] = -np.log(gm_mads['BCMAD']) gm_mads['EMAD'] = -np.log(gm_mads['EMAD']/10000) #calculate band indices on gm gm_mads = calculate_indices(gm_mads, index=['EVI','LAI','MNDWI'], drop=False, collection='s2') #normalise spectral GM bands 0-1 for band in gm_mads.data_vars: if band not in ['SMAD', 'BCMAD','EMAD', 'EVI', 'LAI', 'MNDWI']: gm_mads[band] = gm_mads[band] / 10000 #calculate EVI on annual timeseries evi = calculate_indices(ds,index=['EVI'], drop=True, normalise=True, collection='s2') # EVI stats gm_mads['evi_std'] = evi.EVI.std(dim='time') gm_mads['evi_10'] = evi.EVI.quantile(0.1, dim='time') gm_mads['evi_25'] = evi.EVI.quantile(0.25, dim='time') gm_mads['evi_75'] = evi.EVI.quantile(0.75, dim='time') gm_mads['evi_90'] = evi.EVI.quantile(0.9, dim='time') gm_mads['evi_range'] = gm_mads['evi_90'] - gm_mads['evi_10'] #rainfall climatology chirps_S1 = xr_reproject(assign_crs(xr.open_rasterio('/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc'), crs='epsg:4326'), ds.geobox,"bilinear") chirps_S2 = xr_reproject(assign_crs(xr.open_rasterio('/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc'), crs='epsg:4326'), ds.geobox,"bilinear") gm_mads['rain_S1'] = chirps_S1 gm_mads['rain_S2'] = chirps_S2 #slope url_slope = "https://deafrica-data.s3.amazonaws.com/ancillary/dem-derivatives/cog_slope_africa.tif" slope = rio_slurp_xarray(url_slope, gbox=ds.geobox) slope = slope.to_dataset(name='slope')#.chunk({'x':2000,'y':2000}) result = xr.merge([gm_mads,slope],compat='override') return result.squeeze()
def add_chirps(ds, era, training=True, dask_chunks={'x': 'auto', 'y': 'auto'}): # load rainfall climatology if era == "_S1": chirps = rio_slurp_xarray( "s3://deafrica-input-datasets/rainfall/CHPclim_jan_jun_cumulative_rainfall.tif" ) if era == "_S2": chirps = rio_slurp_xarray( "s3://deafrica-input-datasets/rainfall/CHPclim_jul_dec_cumulative_rainfall.tif" ) if training: chirps = xr_reproject(chirps, ds.geobox, "bilinear") ds["rain"] = chirps else: # Clip CHIRPS to ~ S2 tile boundaries so we can handle NaNs local to S2 tile xmin, xmax = ds.x.values[0], ds.x.values[-1] ymin, ymax = ds.y.values[0], ds.y.values[-1] inProj = Proj("epsg:6933") outProj = Proj("epsg:4326") xmin, ymin = transform(inProj, outProj, xmin, ymin) xmax, ymax = transform(inProj, outProj, xmax, ymax) # create lat/lon indexing slices - buffer S2 bbox by 0.05deg if (xmin < 0) & (xmax < 0): x_slice = list(np.arange(xmin + 0.05, xmax - 0.05, -0.05)) else: x_slice = list(np.arange(xmax - 0.05, xmin + 0.05, 0.05)) if (ymin < 0) & (ymax < 0): y_slice = list(np.arange(ymin + 0.05, ymax - 0.05, -0.05)) else: y_slice = list(np.arange(ymin - 0.05, ymax + 0.05, 0.05)) # index global chirps using buffered s2 tile bbox chirps = assign_crs( chirps.sel(longitude=y_slice, latitude=x_slice, method="nearest")) # fill any NaNs in CHIRPS with local (s2-tile bbox) mean chirps = chirps.fillna(chirps.mean()) chirps = xr_reproject(chirps, ds.geobox, "bilinear") chirps = chirps.chunk(dask_chunks) ds["rain"] = chirps #rename bands to include era for band in ds.data_vars: ds = ds.rename({band: band + era}) return ds
def fun(ds, era): #geomedian and tmads gm_mads = xr_geomedian_tmad(ds) gm_mads = calculate_indices(gm_mads, index=['NDVI','LAI','MNDWI'], drop=False, normalise=False, collection='s2') gm_mads['sdev'] = -np.log(gm_mads['sdev']) gm_mads['bcdev'] = -np.log(gm_mads['bcdev']) gm_mads['edev'] = -np.log(gm_mads['edev']) #rainfall climatology if era == '_S1': chirps = assign_crs(xr.open_rasterio('/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc'), crs='epsg:4326') if era == '_S2': chirps = assign_crs(xr.open_rasterio('/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc'), crs='epsg:4326') chirps = xr_reproject(chirps,ds.geobox,"bilinear") gm_mads['rain'] = chirps for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band:band+era}) return gm_mads
def complete_gm_mads(era_base_ds: xr.Dataset, geobox: GeoBox, era: str) -> xr.Dataset: """ merge the geomedian and rainfall chirps data together :param era_base_ds: :param geobox: :param era: :return: """ # TODO: this is half year data, require integration tests # TODO: load this data once use dask publish (?) gm_mads = assign_crs(calculate_indices(era_base_ds)) rainfall = assign_crs(xr.open_rasterio( FeaturePathConfig.rainfall_path[era]), crs="epsg:4326") rainfall = chirp_clip(gm_mads, rainfall) rainfall = (xr_reproject(rainfall, geobox, "bilinear").drop(["band", "spatial_ref"]).squeeze()) gm_mads["rain"] = rainfall return gm_mads.rename( dict((var_name, str(var_name) + era.upper()) for var_name in gm_mads.data_vars))
def fun(ds, era): # six-month geomedians gm_mads = xr_geomedian(ds) gm_mads = calculate_indices( gm_mads, index=["NDVI", "LAI", "MNDWI"], drop=False, normalise=False, collection="s2", ) # rainfall climatology if era == "_S1": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc" ), crs="epsg:4326", ) if era == "_S2": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc" ), crs="epsg:4326", ) chirps = xr_reproject(chirps, ds.geobox, "bilinear") gm_mads["rain"] = chirps for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band: band + era}) return gm_mads
def fun(ds, era): # geomedian and tmads # gm_mads = xr_geomedian_tmad(ds) gm_mads = xr_geomedian_tmad_new(ds).compute() gm_mads = calculate_indices( gm_mads, index=["NDVI", "LAI", "MNDWI"], drop=False, normalise=False, collection="s2", ) gm_mads["sdev"] = -np.log(gm_mads["sdev"]) gm_mads["bcdev"] = -np.log(gm_mads["bcdev"]) gm_mads["edev"] = -np.log(gm_mads["edev"]) gm_mads = gm_mads.chunk({"x": 2000, "y": 2000}) # rainfall climatology if era == "_S1": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc" ), crs="epsg:4326", ) if era == "_S2": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc" ), crs="epsg:4326", ) chirps = xr_reproject(chirps, ds.geobox, "bilinear") chirps = chirps.chunk({"x": 2000, "y": 2000}) gm_mads["rain"] = chirps for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band: band + era}) return gm_mads
def fun(ds, era): # normalise SR and edev bands for band in ds.data_vars: if band not in ["sdev", "bcdev"]: ds[band] = ds[band] / 10000 gm_mads = calculate_indices( ds, index=["NDVI", "LAI", "MNDWI"], drop=False, normalise=False, collection="s2", ) gm_mads["sdev"] = -np.log(gm_mads["sdev"]) gm_mads["bcdev"] = -np.log(gm_mads["bcdev"]) gm_mads["edev"] = -np.log(gm_mads["edev"]) # rainfall climatology if era == "_S1": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc" ), crs="epsg:4326", ) if era == "_S2": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc" ), crs="epsg:4326", ) chirps = xr_reproject(chirps, ds.geobox, "bilinear") gm_mads["rain"] = chirps for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band: band + era}) return gm_mads
def _load_with_native_transform_1( sources: xr.DataArray, bands: Tuple[str, ...], geobox: GeoBox, native_transform: Callable[[xr.Dataset], xr.Dataset], basis: Optional[str] = None, groupby: Optional[str] = None, fuser: Optional[Callable[[xr.Dataset], xr.Dataset]] = None, resampling: str = "nearest", chunks: Optional[Dict[str, int]] = None, load_chunks: Optional[Dict[str, int]] = None, pad: Optional[int] = None, ) -> xr.Dataset: if basis is None: basis = bands[0] if load_chunks is None: load_chunks = chunks (ds, ) = sources.data[0] load_geobox = compute_native_load_geobox(geobox, ds, basis) if pad is not None: load_geobox = gbox.pad(load_geobox, pad) mm = ds.type.lookup_measurements(bands) xx = Datacube.load_data(sources, load_geobox, mm, dask_chunks=load_chunks) xx = native_transform(xx) if groupby is not None: if fuser is None: fuser = _nodata_fuser xx = xx.groupby(groupby).map(fuser) _chunks = None if chunks is not None: _chunks = tuple(chunks.get(ax, -1) for ax in ("y", "x")) return xr_reproject(xx, geobox, chunks=_chunks, resampling=resampling)
def gm_mads_evi_rainfall(ds): """ 6 monthly and annual gm + mads evi stats (10, 50, 90 percentile, range, std) rainfall actual stats (min, mean, max, range, std) from monthly data rainfall clim stats (min, mean, max, range, std) from monthly data """ dc = datacube.Datacube(app='training') ds = ds / 10000 ds = ds.rename({'nir_1':'nir_wide', 'nir_2':'nir'}) ds1 = ds.sel(time=slice('2019-01', '2019-06')) ds2 = ds.sel(time=slice('2019-07', '2019-12')) chirps = [] chpclim = [] for m in range(1,13): chirps.append(xr_reproject(assign_crs(xr.open_rasterio(f'/g/data/CHIRPS/monthly_2019/chirps-v2.0.2019.{m:02d}.tif').squeeze().expand_dims({'time':[m]}), crs='epsg:4326'), ds.geobox, "bilinear")) chpclim.append(rio_slurp_xarray(f'https://deafrica-data-dev.s3.amazonaws.com/product-dev/deafrica_chpclim_50n_50s_{m:02d}.tif', gbox=ds.geobox, resapling='bilinear').expand_dims({'time':[m]})) chirps = xr.concat(chirps, dim='time') chpclim = xr.concat(chpclim, dim='time') def fun(ds, chirps, chpclim, era): ds = calculate_indices(ds, index=['EVI'], drop=False, normalise=False, collection='s2') #geomedian and tmads gm_mads = xr_geomedian_tmad(ds) gm_mads = calculate_indices(gm_mads, index=['EVI','NDVI','LAI','MNDWI'], drop=False, normalise=False, collection='s2') gm_mads['sdev'] = -np.log(gm_mads['sdev']) gm_mads['bcdev'] = -np.log(gm_mads['bcdev']) gm_mads['edev'] = -np.log(gm_mads['edev']) # EVI stats gm_mads['evi_10'] = ds.EVI.quantile(0.1, dim='time') gm_mads['evi_50'] = ds.EVI.quantile(0.5, dim='time') gm_mads['evi_90'] = ds.EVI.quantile(0.9, dim='time') gm_mads['evi_range'] = gm_mads['evi_90'] - gm_mads['evi_10'] gm_mads['evi_std'] = ds.EVI.std(dim='time') # rainfall actual gm_mads['rain_min'] = chirps.min(dim='time') gm_mads['rain_mean'] = chirps.mean(dim='time') gm_mads['rain_max'] = chirps.max(dim='time') gm_mads['rain_range'] = gm_mads['rain_max'] - gm_mads['rain_min'] gm_mads['rain_std'] = chirps.std(dim='time') # rainfall climatology gm_mads['rainclim_min'] = chpclim.min(dim='time') gm_mads['rainclim_mean'] = chpclim.mean(dim='time') gm_mads['rainclim_max'] = chpclim.max(dim='time') gm_mads['rainclim_range'] = gm_mads['rainclim_max'] - gm_mads['rainclim_min'] gm_mads['rainclim_std'] = chpclim.std(dim='time') for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band:band+era}) return gm_mads epoch0 = fun(ds, chirps, chpclim, era='_S0') time, month = slice('2019-01', '2019-06'), slice(1, 6) epoch1 = fun(ds.sel(time=time), chirps.sel(time=month), chpclim.sel(time=month), era='_S1') time, month = slice('2019-07', '2019-12'), slice(7, 12) epoch2 = fun(ds.sel(time=time), chirps.sel(time=month), chpclim.sel(time=month), era='_S2') #slope url_slope = "https://deafrica-data.s3.amazonaws.com/ancillary/dem-derivatives/cog_slope_africa.tif" slope = rio_slurp_xarray(url_slope, gbox=ds.geobox) slope = slope.to_dataset(name='slope') result = xr.merge([epoch0, epoch1, epoch2, slope],compat='override') return result.squeeze()
def gm_mads_evi_rainfall(ds): """ 6 monthly and annual gm + mads evi stats (10, 50, 90 percentile, range, std) rainfall actual stats (min, mean, max, range, std) from monthly data rainfall clim stats (min, mean, max, range, std) from monthly data """ dc = datacube.Datacube(app="training") ds = ds / 10000 ds = ds.rename({"nir_1": "nir_wide", "nir_2": "nir"}) ds1 = ds.sel(time=slice("2019-01", "2019-06")) ds2 = ds.sel(time=slice("2019-07", "2019-12")) chirps = [] chpclim = [] for m in range(1, 13): chirps.append( xr_reproject( assign_crs( xr.open_rasterio( f"/g/data/CHIRPS/monthly_2019/chirps-v2.0.2019.{m:02d}.tif" ) .squeeze() .expand_dims({"time": [m]}), crs="epsg:4326", ), ds.geobox, "bilinear", ) ) chpclim.append( rio_slurp_xarray( f"https://deafrica-data-dev.s3.amazonaws.com/product-dev/deafrica_chpclim_50n_50s_{m:02d}.tif", gbox=ds.geobox, resapling="bilinear", ).expand_dims({"time": [m]}) ) chirps = xr.concat(chirps, dim="time") chpclim = xr.concat(chpclim, dim="time") def fun(ds, chirps, chpclim, era): ds = calculate_indices( ds, index=["EVI"], drop=False, normalise=False, collection="s2" ) # geomedian and tmads gm_mads = xr_geomedian_tmad(ds) gm_mads = calculate_indices( gm_mads, index=["EVI", "NDVI", "LAI", "MNDWI"], drop=False, normalise=False, collection="s2", ) gm_mads["sdev"] = -np.log(gm_mads["sdev"]) gm_mads["bcdev"] = -np.log(gm_mads["bcdev"]) gm_mads["edev"] = -np.log(gm_mads["edev"]) # EVI stats gm_mads["evi_10"] = ds.EVI.quantile(0.1, dim="time") gm_mads["evi_50"] = ds.EVI.quantile(0.5, dim="time") gm_mads["evi_90"] = ds.EVI.quantile(0.9, dim="time") gm_mads["evi_range"] = gm_mads["evi_90"] - gm_mads["evi_10"] gm_mads["evi_std"] = ds.EVI.std(dim="time") # rainfall actual gm_mads["rain_min"] = chirps.min(dim="time") gm_mads["rain_mean"] = chirps.mean(dim="time") gm_mads["rain_max"] = chirps.max(dim="time") gm_mads["rain_range"] = gm_mads["rain_max"] - gm_mads["rain_min"] gm_mads["rain_std"] = chirps.std(dim="time") # rainfall climatology gm_mads["rainclim_min"] = chpclim.min(dim="time") gm_mads["rainclim_mean"] = chpclim.mean(dim="time") gm_mads["rainclim_max"] = chpclim.max(dim="time") gm_mads["rainclim_range"] = gm_mads["rainclim_max"] - gm_mads["rainclim_min"] gm_mads["rainclim_std"] = chpclim.std(dim="time") for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band: band + era}) return gm_mads epoch0 = fun(ds, chirps, chpclim, era="_S0") time, month = slice("2019-01", "2019-06"), slice(1, 6) epoch1 = fun( ds.sel(time=time), chirps.sel(time=month), chpclim.sel(time=month), era="_S1" ) time, month = slice("2019-07", "2019-12"), slice(7, 12) epoch2 = fun( ds.sel(time=time), chirps.sel(time=month), chpclim.sel(time=month), era="_S2" ) # slope url_slope = "https://deafrica-data.s3.amazonaws.com/ancillary/dem-derivatives/cog_slope_africa.tif" slope = rio_slurp_xarray(url_slope, gbox=ds.geobox) slope = slope.to_dataset(name="slope") result = xr.merge([epoch0, epoch1, epoch2, slope], compat="override") return result.squeeze()
def annual_gm_mads_evi_training(ds): dc = datacube.Datacube(app="training") # grab gm+tmads gm_mads = dc.load( product="ga_s2_gm", time="2019", like=ds.geobox, measurements=[ "red", "blue", "green", "nir", "swir_1", "swir_2", "red_edge_1", "red_edge_2", "red_edge_3", "SMAD", "BCMAD", "EMAD", ], ) gm_mads["SMAD"] = -np.log(gm_mads["SMAD"]) gm_mads["BCMAD"] = -np.log(gm_mads["BCMAD"]) gm_mads["EMAD"] = -np.log(gm_mads["EMAD"] / 10000) # calculate band indices on gm gm_mads = calculate_indices( gm_mads, index=["EVI", "LAI", "MNDWI"], drop=False, collection="s2" ) # normalise spectral GM bands 0-1 for band in gm_mads.data_vars: if band not in ["SMAD", "BCMAD", "EMAD", "EVI", "LAI", "MNDWI"]: gm_mads[band] = gm_mads[band] / 10000 # calculate EVI on annual timeseries evi = calculate_indices( ds, index=["EVI"], drop=True, normalise=True, collection="s2" ) # EVI stats gm_mads["evi_std"] = evi.EVI.std(dim="time") gm_mads["evi_10"] = evi.EVI.quantile(0.1, dim="time") gm_mads["evi_25"] = evi.EVI.quantile(0.25, dim="time") gm_mads["evi_75"] = evi.EVI.quantile(0.75, dim="time") gm_mads["evi_90"] = evi.EVI.quantile(0.9, dim="time") gm_mads["evi_range"] = gm_mads["evi_90"] - gm_mads["evi_10"] # rainfall climatology chirps_S1 = xr_reproject( assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc" ), crs="epsg:4326", ), ds.geobox, "bilinear", ) chirps_S2 = xr_reproject( assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc" ), crs="epsg:4326", ), ds.geobox, "bilinear", ) gm_mads["rain_S1"] = chirps_S1 gm_mads["rain_S2"] = chirps_S2 # slope url_slope = "https://deafrica-data.s3.amazonaws.com/ancillary/dem-derivatives/cog_slope_africa.tif" slope = rio_slurp_xarray(url_slope, gbox=ds.geobox) slope = slope.to_dataset(name="slope") # .chunk({'x':2000,'y':2000}) result = xr.merge([gm_mads, slope], compat="override") return result.squeeze()
def fun(ds, era): # normalise SR and edev bands for band in ds.data_vars: if band not in ["sdev", "bcdev"]: ds[band] = ds[band] / 10000 gm_mads = calculate_indices( ds, index=["NDVI", "LAI", "MNDWI"], drop=False, normalise=False, collection="s2", ) gm_mads["sdev"] = -np.log(gm_mads["sdev"]) gm_mads["bcdev"] = -np.log(gm_mads["bcdev"]) gm_mads["edev"] = -np.log(gm_mads["edev"]) # rainfall climatology if era == "_S1": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc" ), crs="epsg:4326", ) if era == "_S2": chirps = assign_crs( xr.open_rasterio( "/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc" ), crs="epsg:4326", ) # Clip CHIRPS to ~ S2 tile boundaries so we can handle NaNs local to S2 tile xmin, xmax = ds.x.values[0], ds.x.values[-1] ymin, ymax = ds.y.values[0], ds.y.values[-1] inProj = Proj("epsg:6933") outProj = Proj("epsg:4326") xmin, ymin = transform(inProj, outProj, xmin, ymin) xmax, ymax = transform(inProj, outProj, xmax, ymax) # create lat/lon indexing slices - buffer S2 bbox by 0.05deg if (xmin < 0) & (xmax < 0): x_slice = list(np.arange(xmin + 0.05, xmax - 0.05, -0.05)) else: x_slice = list(np.arange(xmax - 0.05, xmin + 0.05, 0.05)) if (ymin < 0) & (ymax < 0): y_slice = list(np.arange(ymin + 0.05, ymax - 0.05, -0.05)) else: y_slice = list(np.arange(ymin - 0.05, ymax + 0.05, 0.05)) # index global chirps using buffered s2 tile bbox chirps = assign_crs(chirps.sel(x=y_slice, y=x_slice, method="nearest")) # fill any NaNs in CHIRPS with local (s2-tile bbox) mean chirps = chirps.fillna(chirps.mean()) chirps = xr_reproject(chirps, ds.geobox, "bilinear") gm_mads["rain"] = chirps for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band: band + era}) return gm_mads
def features(ds, era): #normalise SR and edev bands for band in ds.data_vars: if band not in ['sdev', 'bcdev']: ds[band] = ds[band] / 10000 gm_mads = calculate_indices(ds, index=['NDVI', 'LAI', 'MNDWI'], drop=False, normalise=False, collection='s2') gm_mads['sdev'] = -np.log(gm_mads['sdev']) gm_mads['bcdev'] = -np.log(gm_mads['bcdev']) gm_mads['edev'] = -np.log(gm_mads['edev']) #rainfall climatology if era == '_S1': chirps = assign_crs(xr.open_rasterio( '/g/data/CHIRPS/cumulative_alltime/CHPclim_jan_jun_cumulative_rainfall.nc' ), crs='epsg:4326') if era == '_S2': chirps = assign_crs(xr.open_rasterio( '/g/data/CHIRPS/cumulative_alltime/CHPclim_jul_dec_cumulative_rainfall.nc' ), crs='epsg:4326') #Clip CHIRPS to ~ S2 tile boundaries so we can handle NaNs local to S2 tile xmin, xmax = ds.x.values[0], ds.x.values[-1] ymin, ymax = ds.y.values[0], ds.y.values[-1] inProj = Proj('epsg:6933') outProj = Proj('epsg:4326') xmin, ymin = transform(inProj, outProj, xmin, ymin) xmax, ymax = transform(inProj, outProj, xmax, ymax) #create lat/lon indexing slices - buffer S2 bbox by 0.05deg if (xmin < 0) & (xmax < 0): x_slice = list(np.arange(xmin + 0.05, xmax - 0.05, -0.05)) else: x_slice = list(np.arange(xmax - 0.05, xmin + 0.05, 0.05)) if (ymin < 0) & (ymax < 0): y_slice = list(np.arange(ymin + 0.05, ymax - 0.05, -0.05)) else: y_slice = list(np.arange(ymin - 0.05, ymax + 0.05, 0.05)) #index global chirps using buffered s2 tile bbox chirps = assign_crs(chirps.sel(x=y_slice, y=x_slice, method='nearest')) #fill any NaNs in CHIRPS with local (s2-tile bbox) mean chirps = chirps.fillna(chirps.mean()) #reproject to match satellite data chirps = xr_reproject(chirps, ds.geobox, "bilinear") gm_mads['rain'] = chirps for band in gm_mads.data_vars: gm_mads = gm_mads.rename({band: band + era}) return gm_mads