Skip to content

Commit

Permalink
Fix list() and tabulate() for existing optimization items with sp…
Browse files Browse the repository at this point in the history
…ecific run-request (#107)

* Fix and test indexset, scalar, table list and tabulate for specific runs
* Make new tests more efficient
* Make indexset-creation a test utility
* Include final suggestions for new util function
  • Loading branch information
glatterf42 authored Aug 9, 2024
1 parent 5fabaec commit f57d533
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 173 deletions.
8 changes: 6 additions & 2 deletions ixmp4/core/optimization/indexset.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ def get(self, name: str) -> IndexSet:
return IndexSet(_backend=self.backend, _model=indexset)

def list(self, name: str | None = None) -> list[IndexSet]:
indexsets = self.backend.optimization.indexsets.list(name=name)
indexsets = self.backend.optimization.indexsets.list(
run_id=self._run.id, name=name
)
return [
IndexSet(
_backend=self.backend,
Expand All @@ -104,4 +106,6 @@ def list(self, name: str | None = None) -> list[IndexSet]:
]

def tabulate(self, name: str | None = None) -> pd.DataFrame:
return self.backend.optimization.indexsets.tabulate(name=name)
return self.backend.optimization.indexsets.tabulate(
run_id=self._run.id, name=name
)
4 changes: 3 additions & 1 deletion ixmp4/core/optimization/scalar.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,6 @@ def list(self, name: str | None = None) -> Iterable[Scalar]:
]

def tabulate(self, name: str | None = None) -> pd.DataFrame:
return self.backend.optimization.scalars.tabulate(name=name)
return self.backend.optimization.scalars.tabulate(
run_id=self._run.id, name=name
)
2 changes: 1 addition & 1 deletion ixmp4/core/optimization/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,4 @@ def list(self, name: str | None = None) -> Iterable[Table]:
]

def tabulate(self, name: str | None = None) -> pd.DataFrame:
return self.backend.optimization.tables.tabulate(name=name)
return self.backend.optimization.tables.tabulate(run_id=self._run.id, name=name)
78 changes: 47 additions & 31 deletions tests/core/test_indexset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import pandas.testing as pdt
import pytest

from ixmp4 import IndexSet
from ixmp4.core import IndexSet, Platform

from ..utils import all_platforms
from ..utils import all_platforms, create_indexsets_for_run


def df_from_list(indexsets: list[IndexSet]):
Expand Down Expand Up @@ -36,37 +36,38 @@ def df_from_list(indexsets: list[IndexSet]):
@all_platforms
class TestCoreIndexSet:
def test_create_indexset(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
indexset_1 = run.optimization.indexsets.create("IndexSet 1")
indexset_1 = run.optimization.indexsets.create("Indexset 1")
assert indexset_1.id == 1
assert indexset_1.name == "IndexSet 1"
assert indexset_1.name == "Indexset 1"

indexset_2 = run.optimization.indexsets.create("IndexSet 2")
indexset_2 = run.optimization.indexsets.create("Indexset 2")
assert indexset_1.id != indexset_2.id

with pytest.raises(IndexSet.NotUnique):
_ = run.optimization.indexsets.create("IndexSet 1")
_ = run.optimization.indexsets.create("Indexset 1")

def test_get_indexset(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
_ = run.optimization.indexsets.create("IndexSet 1")
indexset = run.optimization.indexsets.get("IndexSet 1")
run.set_as_default()
create_indexsets_for_run(platform=test_mp, run_id=run.id, amount=1)
indexset = run.optimization.indexsets.get("Indexset 1")
assert indexset.id == 1
assert indexset.name == "IndexSet 1"
assert indexset.name == "Indexset 1"

with pytest.raises(IndexSet.NotFound):
_ = run.optimization.indexsets.get("Foo")

def test_add_elements(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
test_elements = ["foo", "bar"]
indexset_1 = run.optimization.indexsets.create("IndexSet 1")
indexset_1 = run.optimization.indexsets.create("Indexset 1")
indexset_1.add(test_elements)
run.optimization.indexsets.create("IndexSet 2").add(test_elements)
indexset_2 = run.optimization.indexsets.get("IndexSet 2")
run.optimization.indexsets.create("Indexset 2").add(test_elements)
indexset_2 = run.optimization.indexsets.get("Indexset 2")
assert indexset_1.elements == indexset_2.elements

with pytest.raises(ValueError):
Expand All @@ -76,24 +77,28 @@ def test_add_elements(self, test_mp, request):
indexset_2.add(["baz", "baz"])

indexset_1.add(1)
indexset_3 = run.optimization.indexsets.get("IndexSet 1")
indexset_3 = run.optimization.indexsets.get("Indexset 1")
indexset_2.add("1")
indexset_4 = run.optimization.indexsets.get("IndexSet 2")
indexset_4 = run.optimization.indexsets.get("Indexset 2")
assert indexset_3.elements != indexset_4.elements
assert len(indexset_3.elements) == len(indexset_4.elements)

test_elements_2 = ["One", 2, 3.141]
indexset_5 = run.optimization.indexsets.create("IndexSet 5")
indexset_5 = run.optimization.indexsets.create("Indexset 5")
indexset_5.add(test_elements_2)
assert indexset_5.elements == test_elements_2

def test_list_indexsets(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
# Per default, list() lists only `default` version runs:
run.set_as_default()
indexset_1 = run.optimization.indexsets.create("Indexset 1")
indexset_2 = run.optimization.indexsets.create("Indexset 2")
indexset_1, indexset_2 = create_indexsets_for_run(
platform=test_mp, run_id=run.id
)
# Create indexset in another run to test listing indexsets for specific run
test_mp.runs.create("Model", "Scenario").optimization.indexsets.create(
"Indexset 1"
)

expected_ids = [indexset_1.id, indexset_2.id]
list_ids = [indexset.id for indexset in run.optimization.indexsets.list()]
assert not (set(expected_ids) ^ set(list_ids))
Expand All @@ -107,12 +112,18 @@ def test_list_indexsets(self, test_mp, request):
assert not (set(expected_id) ^ set(list_id))

def test_tabulate_indexsets(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
# Per default, tabulate() lists only `default` version runs:
run.set_as_default()
indexset_1 = run.optimization.indexsets.create("Indexset 1")
indexset_2 = run.optimization.indexsets.create("Indexset 2")
# Convert to core.indexset; util uses db.indexset for efficiency
indexset_1, indexset_2 = tuple(
IndexSet(_backend=test_mp.backend, _model=model)
for model in create_indexsets_for_run(platform=test_mp, run_id=run.id)
)
# Create indexset in another run to test tabulating indexsets for specific run
test_mp.runs.create("Model", "Scenario").optimization.indexsets.create(
"Indexset 1"
)

expected = df_from_list(indexsets=[indexset_1, indexset_2])
result = run.optimization.indexsets.tabulate()
# utils.assert_unordered_equality doesn't like lists, so make sure the order in
Expand All @@ -124,10 +135,15 @@ def test_tabulate_indexsets(self, test_mp, request):
pdt.assert_frame_equal(expected, result)

def test_indexset_docs(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
indexset_1 = run.optimization.indexsets.create("IndexSet 1")
docs = "Documentation of IndexSet 1"
(indexset_1,) = tuple(
IndexSet(_backend=test_mp.backend, _model=model)
for model in create_indexsets_for_run(
platform=test_mp, run_id=run.id, amount=1
)
)
docs = "Documentation of Indexset 1"
indexset_1.docs = docs
assert indexset_1.docs == docs

Expand Down
28 changes: 17 additions & 11 deletions tests/core/test_scalar.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pandas as pd
import pytest

from ixmp4 import Scalar
from ixmp4.core import Platform, Scalar

from ..utils import all_platforms, assert_unordered_equality

Expand Down Expand Up @@ -35,7 +35,7 @@ def df_from_list(scalars: list[Scalar]):
@all_platforms
class TestCoreScalar:
def test_create_scalar(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
unit = test_mp.units.create("Test Unit")
scalar_1 = run.optimization.scalars.create(
Expand Down Expand Up @@ -63,7 +63,7 @@ def test_create_scalar(self, test_mp, request):
assert scalar_3.unit.name == ""

def test_get_scalar(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
unit = test_mp.units.create("Test Unit")
scalar = run.optimization.scalars.create("Scalar", value=10, unit=unit.name)
Expand All @@ -77,7 +77,7 @@ def test_get_scalar(self, test_mp, request):
_ = run.optimization.scalars.get("Foo")

def test_update_scalar(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
unit = test_mp.units.create("Test Unit")
unit2 = test_mp.units.create("Test Unit 2")
Expand All @@ -100,15 +100,18 @@ def test_update_scalar(self, test_mp, request):
assert scalar.unit.id == result.unit.id == 1

def test_list_scalars(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
# Per default, list() lists only `default` version runs:
run.set_as_default()
unit = test_mp.units.create("Test Unit")
scalar_1 = run.optimization.scalars.create(
"Scalar 1", value=1, unit="Test Unit"
)
scalar_2 = run.optimization.scalars.create("Scalar 2", value=2, unit=unit.name)
# Create scalar in another run to test listing scalars for specific run
test_mp.runs.create("Model", "Scenario").optimization.scalars.create(
"Scalar 1", value=1, unit=unit
)

expected_ids = [scalar_1.id, scalar_2.id]
list_ids = [scalar.id for scalar in run.optimization.scalars.list()]
assert not (set(expected_ids) ^ set(list_ids))
Expand All @@ -121,13 +124,16 @@ def test_list_scalars(self, test_mp, request):
assert not (set(expected_id) ^ set(list_id))

def test_tabulate_scalars(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
# Per default, tabulate() lists only `default` version runs:
run.set_as_default()
unit = test_mp.units.create("Test Unit")
scalar_1 = run.optimization.scalars.create("Scalar 1", value=1, unit=unit.name)
scalar_2 = run.optimization.scalars.create("Scalar 2", value=2, unit=unit.name)
# Create scalar in another run to test tabulating scalars for specific run
test_mp.runs.create("Model", "Scenario").optimization.scalars.create(
"Scalar 1", value=1, unit=unit
)

expected = df_from_list(scalars=[scalar_1, scalar_2])
result = run.optimization.scalars.tabulate()
assert_unordered_equality(expected, result, check_dtype=False)
Expand All @@ -137,7 +143,7 @@ def test_tabulate_scalars(self, test_mp, request):
assert_unordered_equality(expected, result, check_dtype=False)

def test_scalar_docs(self, test_mp, request):
test_mp = request.getfixturevalue(test_mp)
test_mp: Platform = request.getfixturevalue(test_mp) # type: ignore
run = test_mp.runs.create("Model", "Scenario")
unit = test_mp.units.create("Test Unit")
scalar = run.optimization.scalars.create("Scalar 1", value=4, unit=unit.name)
Expand Down
Loading

0 comments on commit f57d533

Please sign in to comment.