Skip to content

Commit

Permalink
fix: Sienna exporter incompatibility when starting from ReEDS (#108)
Browse files Browse the repository at this point in the history
We missed on the testing the full translation from ReEDS to Sienna. This
PR incorporate more robust testing and fixes the incompatibility issues.

List of changes:
- New test that will run entire workflows,
- Added `from_json` and `to_json` from `infrasy` to allow
deserialization from the CLI,
- Simplify storage export for the `SiennaExporter`,
- Added `row["active_power_limits"] = MinMax(min=0,
max=row["active_power"])` for `ReEDSParser`
  • Loading branch information
pesap authored Jan 23, 2025
1 parent 40137fd commit 05befac
Show file tree
Hide file tree
Showing 29 changed files with 3,489 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.0.0
current_version = 1.0.1
commit = true
tag = true

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = [
"infrasys~=0.2.3",
"infrasys~=0.2.4",
"jsonschema~=4.23",
"loguru~=0.7.2",
"pandas~=2.2",
Expand Down
2 changes: 1 addition & 1 deletion src/r2x/__version__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# This file containts the version # noqa: D100
__version__ = "v1.0.0"
__version__ = "v1.0.1"
__data_model_version__ = "0.0.1"
7 changes: 7 additions & 0 deletions src/r2x/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def version(self):
"""The version property."""
return __data_model_version__

def to_json(self, filename: Path | str, overwrite=False, indent=None, data=None) -> None: # noqa: D102
return super().to_json(filename, overwrite=overwrite, indent=indent, data=data)

@classmethod
def from_json(cls, filename: Path | str, upgrade_handler: Callable | None = None, **kwargs) -> "System": # noqa: D102
return super().from_json(filename=filename, upgrade_handler=upgrade_handler, **kwargs) # type: ignore

def export_component_to_csv(
self,
component: type[Component],
Expand Down
10 changes: 6 additions & 4 deletions src/r2x/exporter/sienna.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,15 +418,17 @@ def process_storage_data(self, fname="storage.csv") -> None:
"unit_type",
]

generic_storage = get_export_records(
list(self.system.to_records(Storage)),
storage_list = get_export_records(
list(
self.system.to_records(
Generator, filter_func=lambda x: isinstance(x, Storage | HydroPumpedStorage)
)
),
partial(apply_property_map, property_map=self.property_map),
partial(apply_flatten_key, keys_to_flatten={"active_power_limits"}),
partial(apply_pint_deconstruction, unit_map=self.unit_map),
# partial(apply_valid_properties, valid_properties=output_fields),
)
hydro_pump = list(self.system.to_records(HydroPumpedStorage))
storage_list = generic_storage + hydro_pump

if not storage_list:
logger.warning("No storage devices found")
Expand Down
6 changes: 5 additions & 1 deletion src/r2x/models/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from typing import Annotated, Any

from pint import Quantity
from pydantic import Field, NonNegativeFloat, field_serializer

from r2x.models.core import Device, MinMax
Expand Down Expand Up @@ -131,7 +132,10 @@ class Generator(Device):
@field_serializer("active_power_limits")
def serialize_active_power_limits(self, min_max: MinMax) -> dict[str, Any]:
if min_max is not None:
return {"min": min_max.min, "max": min_max.max}
return {
"min": min_max.min.magnitude if isinstance(min_max.min, Quantity) else min_max.min,
"max": min_max.max.magnitude if isinstance(min_max.max, Quantity) else min_max.max,
}


class RenewableGen(Generator):
Expand Down
5 changes: 5 additions & 0 deletions src/r2x/parser/reeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,11 @@ def _construct_generators(self) -> None: # noqa: C901
row["must_run"] = (
True if row["tech"] in self.reeds_config.defaults["commit_technologies"] else None
)

# NOTE: If there is a point when ReEDs enforces minimum capacity for a technology here is where we
# will need to change it.
row["active_power_limits"] = MinMax(min=0, max=row["active_power"])

valid_fields = {
key: value for key, value in row.items() if key in gen_model.model_fields if value is not None
}
Expand Down
2 changes: 1 addition & 1 deletion src/r2x/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
from importlib.resources import files
from pathlib import Path

from infrasys.system import System
from loguru import logger

from r2x.exporter.handler import get_exporter

from .api import System
from .config_scenario import Scenario, get_scenario_configuration
from .exporter import exporter_list
from .parser import parser_list
Expand Down
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
DATA_FOLDER = "tests/data"
OUTPUT_FOLDER = "r2x_output"
DEFAULT_SCENARIO = "pacific"
DEFAULT_INFRASYS = "pjm_2area"


@pytest.fixture
Expand All @@ -31,6 +32,11 @@ def reeds_data_folder(pytestconfig):
return pytestconfig.rootpath.joinpath(DATA_FOLDER).joinpath(DEFAULT_SCENARIO)


@pytest.fixture
def infrasys_data_folder(pytestconfig):
return pytestconfig.rootpath.joinpath(DATA_FOLDER).joinpath(DEFAULT_INFRASYS)


@pytest.fixture
def default_scenario() -> str:
return DEFAULT_SCENARIO
Expand Down
Loading

0 comments on commit 05befac

Please sign in to comment.