Multi-Weather-Year Input Generation
The weatheryear module converts outputs from external models (CorRES, demand, hydro, and COP models) into Balmorel-compatible .inc files for a chosen historical weather year. The year must be covered by every input time series. This allows you to run Balmorel with multiple weather-year scenarios to capture annual variability of renewable energy sources and demand.
Installation
pyyaml, xlsxwriter and openpyxl are required by this module but are not installed by default with pybalmorel. Install them via the weatheryear extra:
pip install pybalmorel[weatheryear]
Overview
The module produces Balmorel .inc files for the following data types:
Data type |
Method |
Key outputs |
|---|---|---|
VRE time series (wind & solar) |
|
Excel review files + |
VRE-related investment data |
|
|
Electricity & heat demand |
|
|
Hydro inflow |
|
|
Heat-pump COP factors |
|
|
Each method generates both Day-Ahead and CapDev time series.
Configuration File
All methods are driven by a single YAML configuration file. Below is an annotated template:
# Optional convenience key: weather-year input root folder.
# If provided, defaults are inferred for:
# corres_results, VRE_tech_costs, Existing_wind_cap, Existing_solar_cap,
# VRE_potentials, demand_model_results, hydro_model_results, cop_model_results.
weatheryear_inputs_folder: path/to/weatheryear_inputs
# Backward-compatible alternative key:
# multiweather_other_inputs_folder: path/to/weatheryear_inputs/multiweather_other_inputs
# Technology-run folders to process (required). This is the only switch for
# including or excluding a technology.
tech_to_keep:
- Future_Onshore
- Future_Offshore_bottom_fixed
- PV_Rooftop
# Wind turbine models (future installations only)
# Onshore Future available turbines: SP199-HH100, SP199-HH150,SP199-HH200, SP277-HH100, SP277-HH150,SP277-HH200 , SP335-HH100, SP335-HH150,SP335-HH200
# Offshore Future available turbines: SP316-HH155 , SP370-HH155
turbine_to_keep:
- SP335-HH100
- SP277-HH150
- SP199-HH150
# Resource grades to include per technology (RGA/B/C → RG1/2/3 in Balmorel)
RGs_to_keep:
Future_Onshore: [RGA, RGB, RGC]
Future_Offshore_bottom_fixed: [RGB]
PV_Rooftop: [RGA, RGB, RGC]
# Every technology in tech_to_keep needs an entry here, or loading fails.
# Geographic regions to include
Regions_to_keep:
onshore: [DK1, DK2, FIN, DE4-E, DE4-N, ...]
offshore: [DK1_OFF, DK2_OFF, FIN_OFF, DE4-N_OFF, ...]
# --- VRE investment
ANNUITYCG_calculation:
DEBT_SHARE: 0
INTEREST_RATE: 0.04
DISCOUNTRATE: 0.04
# --- Demand data ---
spaceHeat_to_hotWater_ratio: 0.7 # fraction of heat demand attributed to space heating
ann_corr_fac_ref_year: 2012 # reference year for annual correction factors
# --- CapDev time-series aggregation ---
# Representative seasons (S) and hours (T) used for the aggregated resolution
CapDev_timesteps_to_keep:
S: [S02, S08, S15, S21, S28, S34, S41, S47]
T: [T073, T076, T079, T082, T085, T088, T091, T094,
T097, T100, T103, T106, T109, T112, T115, T118,
T121, T124, T127, T130, T133, T136, T139, T142]
When weatheryear_inputs_folder is set, the module assumes this structure:
weatheryear_inputs/
├── Corres_runs/
├── demand_data/
├── hydro_data/
├── cop_data/
└── multiweather_other_inputs/
Defaults are resolved as follows:
corres_resultsfromCorres_runs(orCorRES_runsif present)VRE_tech_costs,VRE_potentials,Existing_wind_cap,Existing_solar_capfrommultiweather_other_inputsdemand_model_resultsfromdemand_data(falls back tomultiweather_other_inputs/Demand_model_Bal_ready_csv*)hydro_model_resultsfromhydro_datacop_model_resultsfromcop_data
Basic Usage
from pybalmorel import WEATHERYEAR
# Instantiate for a specific weather year
mly = WEATHERYEAR(
year=2013,
config_fn="config.yml",
output_folder="results/",
)
# 1. Export VRE time series from CorRES to Excel and .inc files
mly.get_vre_data()
# 2. Generate VRE-related investment .inc files
mly.get_vre_related_files()
# 3. Generate electricity and heat demand .inc files
mly.get_demand_data()
# 4. Generate hydro inflow .inc files
mly.get_hydro_data()
# 5. Generate heat-pump COP .inc files
mly.get_cop_data()
After running, the output folder will have the structure:
results/
└── 2013/
├── Future_Onshore/ ← Excel stats files for review
├── Future_Offshore_bottom_fixed/
├── Existing_ERA5_GWA2/
├── PV_Rooftop/
├── ...
└── to_balmorel/ ← .inc files ready for Balmorel
├── AAA_renewable.inc ← investment data (get_vre_related_files)
├── GDATA_renewable.inc
├── ...
├── HourlyDispatch/ ← Day-Ahead (full hourly) time series
│ ├── raw/
│ └── scaled_long_term/
└── CapDev/ ← time series at the CapDev timesteps
├── raw/ ← the actual weather of the year
├── scaled_long_term/
└── scaled_full_year/
Each time series folder holds the wind, solar, demand, hydro and COP files, e.g. WND_VAR_T.inc, SOLE_VAR_T.inc, WNDFLH.inc, DE_VAR_T_RESE.inc and WTRRRVAR_T_WY.inc.
Writing a Balmorel Scenario
Some of the WEATHERYEAR output can’t be dropped straight into a Balmorel scenario: Balmorel only reads a scenario’s own data/<NAME>.inc when the filename matches exactly, and some output is split across several files or holds scaling factors rather than values. write_scenario_data turns one year’s CapDev output into the files a scenario’s data/ folder needs:
from pybalmorel.weatheryear.scenario_data import write_scenario_data
written = write_scenario_data(
capdev_dir="results/2013/to_balmorel/CapDev/raw",
to_balmorel_dir="results/2013/to_balmorel",
dest_dir="path/to/Balmorel/WY2013/data",
)
print(f"Wrote {len(written)} files")
What it does:
Wind and solar profiles and full-load hours keep their names. Wind gets a fallback profile for existing areas CorRES has no profile for.
Hydro files lose the
_WYsuffix. The full-load-hour files are scaling factors, so the base values are loaded first and multiplied.Demand is split by user in the WEATHERYEAR output, but Balmorel reads one
DE_VAR_T.incand oneDH_VAR_T.inc. The files are concatenated on top of the base defaults, since the weather year only sets its own users’ values.Individual-user heat is loaded inside
DH.incandDH_VAR_T.inc, and emptyINDIVUSERS_DH*.incoverrides are written so it isn’t applied twice.Investment files at the top of
to_balmorel/are copied, exceptGKFX_renewable.inc(the existing fleet comes from base) andSUBTECHGROUPKPOT.inc.Heat-pump COP files are not written; models that use them need their own wrapper.
Optional arguments:
base_data_dir— GAMS path, relative to the scenario’smodel/folder, of the base data the weather year is applied on top of. Defaults to'../../base/data'.drop_areas— areas your model doesn’t have, removed wherever they appear (matched as substrings), e.g.drop_areas=('AL_', 'IT_OFF1').
Existing files in dest_dir with the same names are overwritten.
Processing Multiple Years
Loop over years to build a full multi-weather-year dataset:
from pybalmorel import WEATHERYEAR
for year in range(1980, 2026): # the years your inputs cover
mly = WEATHERYEAR(year=year, config_fn="config.yml", output_folder="results/")
mly.get_vre_data()
mly.get_vre_related_files()
mly.get_demand_data()
mly.get_hydro_data()
mly.get_cop_data()
API Reference
See the auto-generated API docs under Reference → pybalmorel.weatheryear for the full list of classes and functions exposed by this module.