Skip to content

Commit

Permalink
Merge pull request #69 from sedos-project/feature/add_mimo_adapter
Browse files Browse the repository at this point in the history
Feature/add mimo adapter
  • Loading branch information
henhuy authored Apr 15, 2024
2 parents fabd98b + e204862 commit 8e3a976
Show file tree
Hide file tree
Showing 5 changed files with 556 additions and 508 deletions.
65 changes: 64 additions & 1 deletion data_adapter_oemof/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import dataclasses
import difflib
import itertools
import json
import logging
import warnings
from typing import Optional, Type, Union

import pandas as pd
from oemof.tabular import facades
from oemof.tabular._facade import Facade
from oemof_industry.mimo_converter import MIMO

from data_adapter_oemof import calculations

Expand Down Expand Up @@ -176,7 +178,7 @@ def get(self, key, field_type: Optional[Type] = None):
mapped_key = self.map_key(key)
return self.get_data(mapped_key, field_type)

def get_busses(self):
def get_busses(self) -> dict:
"""
Identify mentioned buses in the facade.
Determine if each bus in the facade is classified as an "input"/"output".
Expand Down Expand Up @@ -400,6 +402,67 @@ class VolatileAdapter(Adapter):
facade = facades.Volatile


class MIMOAdapter(Adapter):
"""
MIMOAdapter
"""

type = "mimo"
facade = MIMO
extra_fields = (
Field(name="name", type=str),
Field(name="region", type=str),
Field(name="year", type=int),
Field(name="groups", type=dict),
Field(name="capacity_cost", type=float),
Field(name="capacity", type=float),
Field(name="max", type=float),
Field(name="expandable", type=bool),
)

def get_default_parameters(self) -> dict:
defaults = super().get_default_parameters()
defaults["groups"] = self.get_groups()
keywords = (
"emission_factor_",
"emissions_factor_",
"conversion_factor_",
"flow_share_",
)
for key, value in self.data.items():
for keyword in keywords:
if key.startswith(keyword):
defaults[key] = value
return defaults

def get_busses(self) -> dict:
def get_bus_from_struct(bus_list: list, prefix: str) -> dict:
buses = {}
counter = 0
for bus_group in bus_list:
if isinstance(bus_group, str):
buses[f"{prefix}{counter}"] = bus_group
counter += 1
continue
if isinstance(bus_group, list):
for bus in bus_group:
buses[f"{prefix}{counter}"] = bus
counter += 1
return buses

return get_bus_from_struct(
self.structure["inputs"], prefix="from_bus_"
) | get_bus_from_struct(self.structure["outputs"], prefix="to_bus_")

def get_groups(self) -> str:
groups = {}
group_counter = 0
for bus_group in self.structure["inputs"] + self.structure["outputs"]:
if isinstance(bus_group, list):
groups[f"group_{group_counter}"] = bus_group
return json.dumps(groups)


# Create a dictionary of all adapter classes defined in this module
FACADE_ADAPTERS = {
name: adapter for name, adapter in globals().items() if name.endswith("Adapter")
Expand Down
Binary file added examples/industry/Industriestruktur.xlsx
Binary file not shown.
50 changes: 37 additions & 13 deletions examples/industry/data_adapter_industry.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,74 @@
import os
import pathlib

os.environ["COLLECTIONS_DIR"] = "./collections/"
os.environ["STRUCTURES_DIR"] = "./structures"
os.environ["STRUCTURES_DIR"] = ""

from data_adapter.databus import download_collection # noqa
from data_adapter.preprocessing import Adapter # noqa: E402
from data_adapter.structure import Structure # noqa: E402

from data_adapter_oemof.build_datapackage import DataPackage # noqa: E402

# Download Collection
# download_collection(
# "https://databus.openenergyplatform.org/felixmaur/collections/steel_industry_test/"
# )

# After download, comment `download_collection` and adapt `collection.json`!
# If uncommented, collection might be downloaded again and changes will be
# reversed!
# Replace each `NaN` value in `names` of "ind_scalar" with "ind_scalar"
# in `collection.json`

structure = Structure(
"SEDOS_Modellstruktur", process_sheet="Processes_steel_industry_2"
"Industriestruktur",
process_sheet="process_set_steel_casting",
parameter_sheet="parameter_input_output_steel_ca",
helper_sheet="steel_casting_helper",
)

adapter = Adapter(
"steel_industry_test_adapted",
"steel_industry_test",
structure=structure,
)
process_adapter_map = {
"modex_tech_storage_battery": "StorageAdapter",
"modex_tech_generator_gas": "ConversionAdapter",
"modex_tech_wind_turbine_onshore": "VolatileAdapter",
"modex_demand": "LoadAdapter",
"ind_scalars": "LoadAdapter",
"pow_combustion_gt_natgas": "ConversionAdapter",
"x2x_import_natural_gas": "CommodityAdapter",
"x2x_import_crudesteel": "CommodityAdapter",
"x2x_import_coke_oven_gas": "CommodityAdapter",
"x2x_import_h2": "CommodityAdapter",
"ind_steel_casting_1": "MIMOAdapter",
"ind_steel_casting_0": "MIMOAdapter",
"ind_steel_hyddri_1": "MIMOAdapter",
"ind_steel_demand": "LoadAdapter",
"x2x_import_elec": "CommodityAdapter",
"ind_steel_boiler_0": "ConversionAdapter",
"excess_co2": "ExcessAdapter",
"excess_ch4": "ExcessAdapter",
"excess_n2o": "ExcessAdapter",
}

parameter_map = {
"DEFAULT": {
"marginal_cost": "cost_var",
"fixed_cost": "fixed_costs",
"capacity_cost": "capital_costs",
},
"ExtractionTurbineAdapter": {
"carrier_cost": "fuel_costs",
"capacity": "installed_capacity",
},
"DEFAULT": {},
"StorageAdapter": {
"capacity_potential": "expansion_limit",
"capacity": "installed_capacity",
"invest_relation_output_capacity": "e2p_ratio",
"inflow_conversion_factor": "input_ratio",
"outflow_conversion_factor": "output_ratio",
},
"MIMOAdapter": {
"capacity_cost": "cost_fix_capacity_w",
"capacity": "capacity_w_resid",
"max": "activity_bound_fix",
"expandable": "capacity_w_abs_new_max",
},
"modex_tech_wind_turbine_onshore": {"profile": "onshore"},
}

Expand All @@ -54,4 +77,5 @@
process_adapter_map=process_adapter_map,
parameter_map=parameter_map,
)
dp.save_datapackage_to_csv("./datapackage")
datapackage_path = pathlib.Path(__file__).parent / "datapackage"
dp.save_datapackage_to_csv(str(datapackage_path))
Loading

0 comments on commit 8e3a976

Please sign in to comment.