Use Workflows with Zarr
RESKit can read ERA5 directly from regular latitude/longitude Zarr stores.
The current implementation is intended for stores such as the Earth Data Hub ERA5 single-level dataset.
Follow the linked credential instructions and save the generated credentials as ~/.netrc (not in a directory on PATH). On shared systems, restrict access with chmod 600 ~/.netrc.
In [1]:
Copied!
import pandas as pd
import reskit as rk
import pandas as pd
import reskit as rk
In [2]:
Copied!
ERA5_ZARR_PATH = "https://data.earthdatahub.destine.eu/era5/reanalysis-era5-single-levels-v0.zarr"
TIME_SLICE = slice("2014-12-31T23:30:00", "2015-01-06T18:30:00")
ERA5_ZARR_PATH = "https://data.earthdatahub.destine.eu/era5/reanalysis-era5-single-levels-v0.zarr"
TIME_SLICE = slice("2014-12-31T23:30:00", "2015-01-06T18:30:00")
In [3]:
Copied!
placements = pd.DataFrame(
{
"lon": [5.985195, 5.994685, 6.004750],
"lat": [50.797254, 50.794208, 50.784432],
"hub_height": [120, 120, 82],
"capacity": [4000, 4000, 4000],
"rotor_diam": [130, 150, 136],
}
)
placements = pd.DataFrame(
{
"lon": [5.985195, 5.994685, 6.004750],
"lat": [50.797254, 50.794208, 50.784432],
"hub_height": [120, 120, 82],
"capacity": [4000, 4000, 4000],
"rotor_diam": [130, 150, 136],
}
)
The following cells read from the remote store and therefore need the credentials described above. They are marked with # NBVAL_SKIP so that the automated example tests, which have no credentials, do not execute them.
In [4]:
Copied!
# NBVAL_SKIP
reskit_xr = rk.wind.wind_era5_PenaSanchezDunkelWinklerEtAl2025(
placements=placements,
era5_path=ERA5_ZARR_PATH,
gwa_100m_path=rk.TEST_DATA["gwa100-like.tif"],
height_scaling_data={
50: rk.TEST_DATA["gwa50-like.tif"],
200: rk.TEST_DATA["gwa200-like.tif"],
},
time_slice=TIME_SLICE,
)
reskit_xr
# NBVAL_SKIP
reskit_xr = rk.wind.wind_era5_PenaSanchezDunkelWinklerEtAl2025(
placements=placements,
era5_path=ERA5_ZARR_PATH,
gwa_100m_path=rk.TEST_DATA["gwa100-like.tif"],
height_scaling_data={
50: rk.TEST_DATA["gwa50-like.tif"],
200: rk.TEST_DATA["gwa200-like.tif"],
},
time_slice=TIME_SLICE,
)
reskit_xr
2026-04-02 12:32:45.341368 Now extracting correction factors for a total of 3 placements from /fast/home/p-dunkel/playground/RESKit_HA/reskit/wind/core/data/cf_correction_factors_PSDW2025.tif: 2026-04-02 12:32:45.343387 Based on max_batch_size=3, the total of 3 placements were split into 1 sub batches. Proceeding with batch 1/1 (id=0) with 3 placements. 2026-04-02 12:32:45.345871 Maximum rel. deviation after initial simulation is 0.2742, Number/share of placements with deviation > tolerance (0.01): 3/3. More iterations required. 2026-04-02 12:32:45.347691 Maximum rel. deviation after 1 additional iteration(s) is 0.0772, Number/share of placements with deviation > tolerance (0.01): 3/3. More iterations required. 2026-04-02 12:32:45.349447 Maximum rel. deviation after 2 additional iteration(s) is 0.023, Number/share of placements with deviation > tolerance (0.01): 2/3. More iterations required. 2026-04-02 12:32:45.350907 Required tolerance of 0.01 reached after 3 additional iteration(s). Maximum remaining rel. deviation: 0.009.
Out[4]:
<xarray.Dataset> Size: 18kB
Dimensions: (location: 3, time: 140)
Coordinates:
* location (location) int64 24B 0 1 2
* time (time) datetime64[ns] 1kB 2014-12-31T23:3...
Data variables:
lon (location) float64 24B 5.985 5.995 6.005
lat (location) float64 24B 50.8 50.79 50.78
hub_height (location) int64 24B 120 120 82
capacity (location) int64 24B 4000 4000 4000
rotor_diam (location) int64 24B 130 150 136
powerCurve (location) object 24B 'SPC:301,25' ... 'S...
LRA_factor_elevated_wind_speed (location) float64 24B 0.9531 0.9503 0.947
elevated_wind_speed (time, location) float64 3kB 4.695 ... 7.019
surface_pressure (time, location) float64 3kB 1.013e+05 .....
surface_air_temperature (time, location) float64 3kB -0.01103 ......
boundary_layer_height (time, location) float64 3kB 120.3 ... 346.6
capacity_factor (time, location) float64 3kB 0.0539 ... 0...In [6]:
Copied!
# NBVAL_SKIP
reskit_xr["surface_air_temperature"].round(5)
# NBVAL_SKIP
reskit_xr["surface_air_temperature"].round(5)
Out[6]:
<xarray.DataArray 'surface_air_temperature' (time: 140, location: 3)> Size: 3kB
array([[-1.10300e-02, -1.83100e-02, -4.60400e-02],
[-7.02900e-02, -6.68900e-02, -8.45700e-02],
[-2.58230e-01, -2.67370e-01, -2.96700e-01],
[-3.05490e-01, -3.11580e-01, -3.31130e-01],
[-3.08280e-01, -3.12520e-01, -3.31780e-01],
[-3.52740e-01, -3.55790e-01, -3.65560e-01],
[-3.52740e-01, -3.55790e-01, -3.61470e-01],
[-1.14750e-01, -1.10160e-01, -1.11470e-01],
[ 1.32460e-01, 1.38900e-01, 1.37880e-01],
[ 6.32460e-01, 6.38900e-01, 6.38530e-01],
[ 1.44172e+00, 1.43748e+00, 1.42362e+00],
[ 2.48897e+00, 2.48169e+00, 2.45805e+00],
[ 3.42971e+00, 3.43311e+00, 3.42427e+00],
[ 3.97696e+00, 3.97732e+00, 3.95805e+00],
[ 3.97696e+00, 3.97732e+00, 3.95396e+00],
[ 3.24177e+00, 3.23263e+00, 3.20396e+00],
[ 2.53622e+00, 2.52590e+00, 2.48773e+00],
[ 2.24177e+00, 2.23263e+00, 2.20805e+00],
[ 2.24177e+00, 2.23263e+00, 2.20805e+00],
[ 2.22696e+00, 2.22732e+00, 2.20805e+00],
...
[-7.70240e-01, -7.71750e-01, -7.97350e-01],
[-8.05490e-01, -8.11580e-01, -8.31780e-01],
[-1.05549e+00, -1.06158e+00, -1.08178e+00],
[-1.34073e+00, -1.35141e+00, -1.36622e+00],
[-1.64999e+00, -1.64999e+00, -1.64999e+00],
[-1.74450e+00, -1.73841e+00, -1.71886e+00],
[-1.74450e+00, -1.73841e+00, -1.71820e+00],
[-1.24730e+00, -1.23935e+00, -1.22295e+00],
[-1.04455e+00, -1.03356e+00, -1.00608e+00],
[ 2.70000e-03, 1.06500e-02, 2.70500e-02],
[ 1.50550e+00, 1.51159e+00, 1.53589e+00],
[ 2.78795e+00, 2.80048e+00, 2.82032e+00],
[ 3.58240e+00, 3.59375e+00, 3.60541e+00],
[ 3.61765e+00, 3.63358e+00, 3.64050e+00],
[ 3.17691e+00, 3.18217e+00, 3.17493e+00],
[ 2.47416e+00, 2.47638e+00, 2.45871e+00],
[ 1.97696e+00, 1.97732e+00, 1.95805e+00],
[ 1.49177e+00, 1.48263e+00, 1.45396e+00],
[ 1.50377e+00, 1.48701e+00, 1.45330e+00],
[ 2.44451e+00, 2.43842e+00, 2.41887e+00]])
Coordinates:
* time (time) datetime64[ns] 1kB 2014-12-31T23:30:00 ... 2015-01-06T18...
* location (location) int64 24B 0 1 2