Skip to content
4 changes: 1 addition & 3 deletions workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ configfile: "config/config.common.yaml"
configfile: "config/config.plotting.yaml"
configfile: "config/config.api.yaml"
configfile: "config/config.sector.yaml"


# configfile: "config/config.default.yaml"
configfile: "config/config.default.yaml"


run = config.get("run", {})
Expand Down
4 changes: 2 additions & 2 deletions workflow/envs/environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ dependencies:
- python==3.11.9
- pip

- pypsa==0.30.2
- pypsa>=0.35.2
- atlite==0.3.0
- linopy==0.3.14
- linopy>=0.6.1

# Dependencies of the workflow itself
- pandas==2.2.2
Expand Down
6 changes: 4 additions & 2 deletions workflow/scripts/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

REGION_COLS = ["geometry", "name", "x", "y", "country"]

PYPSA_V1 = bool(re.match(r"^1\.\d", pypsa.__version__))


def configure_logging(snakemake, skip_handlers=False):
"""
Expand Down Expand Up @@ -103,7 +105,7 @@ def load_network(import_name=None, custom_components=None):
-------
pypsa.Network
"""
from pypsa.descriptors import Dict
from pypsa.definitions.structures import Dict

override_components = None
override_component_attrs = None
Expand Down Expand Up @@ -373,7 +375,7 @@ def mock_snakemake(rulename, **wildcards):

import snakemake as sm
from packaging.version import Version, parse
from pypsa.descriptors import Dict
from pypsa.definitions.structures import Dict
from snakemake.script import Snakemake

script_dir = Path(__file__).parent.resolve()
Expand Down
2 changes: 1 addition & 1 deletion workflow/scripts/add_demand.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def attach_demand(n: pypsa.Network, df: pd.DataFrame, carrier: str, suffix: str)
n.snapshots,
), "Demand time series length does not match network snapshots"
df.index = n.snapshots
n.madd(
n.add(
"Load",
df.columns,
suffix=suffix,
Expand Down
34 changes: 19 additions & 15 deletions workflow/scripts/add_electricity.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import pypsa
import xarray as xr
from _helpers import (
PYPSA_V1,
calculate_annuity,
configure_logging,
export_network_for_gis_mapping,
Expand Down Expand Up @@ -78,7 +79,7 @@ def add_missing_carriers(n, carriers):
"""Function to add missing carriers to the network without raising errors."""
missing_carriers = set(carriers) - set(n.carriers.index)
if len(missing_carriers) > 0:
n.madd("Carrier", missing_carriers)
n.add("Carrier", missing_carriers)


def clean_locational_multiplier(df: pd.DataFrame):
Expand Down Expand Up @@ -265,7 +266,8 @@ def match_nearest_bus(plants_subset, buses_subset):
)

# Map the nearest bus information back to the plants subset
plants_subset["bus_assignment"] = buses_subset.reset_index().iloc[indices.flatten()]["Bus"].values
level = "name" if PYPSA_V1 else "Bus"
plants_subset["bus_assignment"] = buses_subset.reset_index().iloc[indices.flatten()][level].values
plants_subset["distance_nearest"] = distances.flatten()

return plants_subset
Expand Down Expand Up @@ -467,10 +469,10 @@ def attach_conventional_generators(
plants["efficiency"] = plants.efficiency.astype(float).fillna(plants.efficiency_r)

committable_fields = ["start_up_cost", "min_down_time", "min_up_time"]
defaults = pypsa.components.component_attrs["Generator"].default
# defaults = pypsa.components.component_attrs["Generator"].default
if unit_commitment:
for attr in committable_fields:
plants[attr] = plants[attr].astype(float).fillna(defaults[attr])
# for attr in committable_fields:
# plants[attr] = plants[attr].astype(float).fillna(defaults[attr])
plants["p_min_pu"] = (
(plants.minimum_load_mw / plants.p_nom)
.clip(
Expand All @@ -481,15 +483,15 @@ def attach_conventional_generators(
.fillna(0)
.mul(0.95)
)
else:
for attr in committable_fields:
plants[attr] = defaults[attr]
# else:
# for attr in committable_fields:
# plants[attr] = defaults[attr]
committable_attrs = {attr: plants[attr] for attr in committable_fields}

# Define generators using modified ppl DataFrame
caps = plants.groupby("carrier").p_nom.sum().div(1e3).round(2)
logger.info(f"Adding {len(plants)} generators with capacities [GW] \n{caps}")
n.madd(
n.add(
"Generator",
plants.index,
carrier=plants.carrier,
Expand Down Expand Up @@ -539,6 +541,7 @@ def attach_wind_and_solar(
config.get("renewable", {}).get("dataset") == "godeeep" and config["renewable_scenarios"][0] != "historical"
)

level = "name" if PYPSA_V1 else "Bus"
for car in carriers:
if car in ["hydro", "EGS"]:
continue
Expand All @@ -548,7 +551,7 @@ def attach_wind_and_solar(
bus2sub = (
pd.read_csv(input_profiles.bus2sub, dtype=str)
.drop("interconnect", axis=1)
.rename(columns={"Bus": "bus_id"})
.rename(columns={level: "bus_id"})
.drop_duplicates(subset="sub_id")
)

Expand Down Expand Up @@ -656,7 +659,7 @@ def attach_wind_and_solar(

logger.info(f"Adding {car} capacity-factor profiles to the network.")

n.madd(
n.add(
"Generator",
bus_list,
" " + car,
Expand Down Expand Up @@ -694,6 +697,7 @@ def attach_egs(
discount_rate = 0.07 # load_costs(snakemake.input.tech_costs).loc["geothermal", "wacc_real"]
drilling_cost = snakemake.config["renewable"]["EGS"]["drilling_cost"]

level = "name" if PYPSA_V1 else "Bus"
with (
xr.open_dataset(
getattr(input_profiles, "specs_egs"),
Expand All @@ -705,7 +709,7 @@ def attach_egs(
bus2sub = (
pd.read_csv(input_profiles.bus2sub, dtype=str)
.drop("interconnect", axis=1)
.rename(columns={"Bus": "bus_id"})
.rename(columns={level: "bus_id"})
)

# IGNORE: Remove dropna(). Rather, apply dropna when creating the original dataset
Expand Down Expand Up @@ -769,7 +773,7 @@ def attach_egs(
f"Adding EGS (Resource Quality-{q}) capacity-factor profiles to the network.",
)

n.madd(
n.add(
"Generator",
bus_list,
suffix,
Expand Down Expand Up @@ -801,7 +805,7 @@ def attach_battery_storage(
)

plants_filt = plants_filt.dropna(subset=["energy_storage_capacity_mwh"])
n.madd( # Adds storage units which can retire economically or at their lifetime
n.add( # Adds storage units which can retire economically or at their lifetime
"StorageUnit",
plants_filt.index,
carrier="battery",
Expand Down Expand Up @@ -960,7 +964,7 @@ def attach_breakthrough_renewable_plants(
p_max_pu = p_max_pu.drop(leap_day.index)
p_max_pu = broadcast_investment_horizons_index(n, p_max_pu)

n.madd(
n.add(
"Generator",
tech_plants.index,
bus=tech_plants.bus_id,
Expand Down
Loading