PyPSA / atlite

Atlite: A Lightweight Python Package for Calculating Renewable Power Potentials and Time Series
https://atlite.readthedocs.io
265 stars 89 forks source link

Enable dataset: ERA5 forecast #184

Open euronion opened 3 years ago

euronion commented 3 years ago

Detailed Description

Request to enable retrieving data from the ERA5 forecast stream (in addition to the ERA5 analysis stream currently implemented)

Context

At the moment the ERA5 data used is from the ERA5 analysis stream.

This dataset has known issues for wind speeds at 09:00-10:00 UTC and 22:00-23:00 UTC. See e.g. fig. 3 in Jourdier (2020) and the recent discussion in the openmod list.

CDS (which we use for ERA5) provides only forecast values if a parameter is not available from the analysis product (wind speeds are available from analysis). As such we would need to access MARS rather than CDS for the forecast data (stream=fc).

For more information and starting queues see this message from Matteo De Felice: https://groups.google.com/g/openmod-initiative/c/FV61CWUY1L8/m/sq-ei5oIAwAJ

euronion commented 3 years ago

To get an impression on what the effect may be (@FabianHofmann @fneum ):

The below plot uses the tutorial dataset from PyPSA-EUR (onshore wind profiles, aggregated over individual normalised bus profiles). Of the 90 days in the tutorial dataset, only the daily time-series are plotted where the 10:00 value differs from the expected value (linear interpolation using 09:00 and 11:00 value) by more than 15%:

image

Some but not all I would consider false positives.

Code used to produce the plot: ``` ``` import xarray as xr import matplotlib.pyplot as plt onwind = xr.open_dataset("./profile_onwind.nc") op = onwind['profile'] opn = op.groupby('bus')/op.groupby('bus').max('time') plt.figure(figsize=(16,10)) data = opn eligibility_range = 0.15 for idx, group in data.sum('bus').groupby('time.dayofyear'): expected_value = group[9]+(group[11]-group[9])/2 if expected_value*(1.-eligibility_range) <= group[10] <= expected_value*(1+eligibility_range): continue plt.plot(group/group.max(), '--', marker='.') plt.plot([10,10],[0,1],'-', c='gray', alpha=.3) ``` ```