-
Notifications
You must be signed in to change notification settings - Fork 7
feat: support merge of two grids #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
I, wander.wadman <wander.wadman@alliander.com>, hereby add my Signed-off-by to this commit: e0fe4f2 Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com> # Conflicts: # src/power_grid_model_ds/_core/model/grids/_helpers.py # src/power_grid_model_ds/_core/model/grids/base.py # tests/unit/model/grids/test_modify.py
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: jaapschoutenalliander <jaap.schouten@alliander.com>
jaapschoutenalliander
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the good work
Signed-off-by: jaapschoutenalliander <jaap.schouten@alliander.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some small remarks, but looks good overall!
Thanks for the PR
| """Merge another grid into this grid. When ids overlap, ids of other_grid are offset to avoid conflicts. | ||
| Args: | ||
| other_grid (G): The grid to merge into this grid. | ||
| mode (str): The merge mode: | ||
| - "recalculate_ids": Recalculate ids of other_grid to avoid conflicts. | ||
| - "keep_ids": Keep ids of other_grid. Raises an error if grids contain overlapping indices. | ||
| """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update docstring to explicitely mention the current hardcoded support.
| """Merge another grid into this grid. When ids overlap, ids of other_grid are offset to avoid conflicts. | |
| Args: | |
| other_grid (G): The grid to merge into this grid. | |
| mode (str): The merge mode: | |
| - "recalculate_ids": Recalculate ids of other_grid to avoid conflicts. | |
| - "keep_ids": Keep ids of other_grid. Raises an error if grids contain overlapping indices. | |
| """ | |
| """Merge another grid into this grid. | |
| Args: | |
| other_grid (G): The grid to merge into this grid. | |
| mode (str): The merge mode: | |
| - "recalculate_ids": ids in the arays of other_grid are offset to avoid conflicts. | |
| IMPORTANT: we currently only update any `id` column and all id references in the default PGM-DS grid. | |
| - "keep_ids": Keep ids of other_grid. Raises an error if grids contain overlapping indices. | |
| """ |
| ) | ||
| return save_grid_to_pickle(self, cache_dir=cache_dir, cache_name=cache_name, compress=compress) | ||
|
|
||
| def merge(self, other_grid: G, mode: str) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type hinting wise, we now allow any Grid. However I think that here we want it to be the same as the current grid.
So I think this should be Self?
| return grid_class(**empty_fields) | ||
|
|
||
|
|
||
| def merge_grids(grid: G, other_grid: G, mode: str) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also use the literal here.
| case SymGenArray() | SymLoadArray() | SourceArray(): | ||
| columns = ["node"] | ||
| case _: | ||
| raise NotImplementedError(f"The array of type {type(array)} is not implemented for appending") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could maybe add an call for action?
To signal that we are willing to think about a more general solution if this is needed by anyone?
Something along the line of:
| raise NotImplementedError(f"The array of type {type(array)} is not implemented for appending") | |
| raise NotImplementedError(f"The array of type {type(array)} is not implemented for appending. Let us know if more general support is needed.") |
| def test_merge_two_grids(self): | ||
| grid1 = Grid.from_txt("S1 2", "S1 3 link", "3 4 transformer") | ||
| grid2 = Grid.from_txt("S11 12", "S11 13 link", "13 14 transformer") | ||
| grid1_size = grid1.node.size | ||
| grid2_size = grid2.node.size | ||
|
|
||
| grid1.merge(grid2, mode="keep_ids") | ||
| merged_grid_size = grid1.node.size | ||
|
|
||
| assert merged_grid_size == grid1_size + grid2_size, "Merged grid size should be the sum of both grids' sizes" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also test that we didn't alter the ids. I'm also in facor of more direct values if the example is small enough, so we could do something like below.
So something like below?
| def test_merge_two_grids(self): | |
| grid1 = Grid.from_txt("S1 2", "S1 3 link", "3 4 transformer") | |
| grid2 = Grid.from_txt("S11 12", "S11 13 link", "13 14 transformer") | |
| grid1_size = grid1.node.size | |
| grid2_size = grid2.node.size | |
| grid1.merge(grid2, mode="keep_ids") | |
| merged_grid_size = grid1.node.size | |
| assert merged_grid_size == grid1_size + grid2_size, "Merged grid size should be the sum of both grids' sizes" | |
| def test_merge_two_grids(self): | |
| grid1 = Grid.from_txt("S1 2", "S1 3 link", "3 4 transformer") | |
| grid2 = Grid.from_txt("S11 12", "S11 13 link", "13 14 transformer") | |
| grid1.merge(grid2, mode="keep_ids") | |
| assert grid1.node.id.tolist() == [1,2,3,4,11,12,13], "Merged node ids should be equal to those of grid1 and grid2 combined" |
| ) | ||
|
|
||
| # assert node in grid.source is updated by checking if the node column contains values that are all node ids: | ||
| assert set(grid1.source.node).issubset(grid1.node.id), "All source nodes should be valid node ids!" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
Same here, I would prefer hardcoded values since the example is small enough. This removes the complexity from the test.
We now the grid_counter should be 501 (or maybe 502?)
So than it becomes like (have not updated all checks)
grid1 = Grid.from_txt("S1 2", "S1 3 link", "3 4 transformer")
grid2 = Grid.from_txt("S1 2", "S1 13 link", "13 14 transformer")
source = SourceArray(id=[501], node=[1], status=[1], u_ref=[0.0])
grid1.append(source)
grid2.append(source)
grid1.merge(grid2, mode="recalculate_ids")
assert grid1.check_ids() is None, "Asset ids are not unique after merging!"
expected_offset = 501
assert grid1.node.id = [1, 2, 3, 4, expected_offset +1, expected_offset + 2, expected_offset + 13,expected_offset + 14]
assert grid1.link.from_node = [.....]
| def test_merge_two_grids_with_overlapping_line(self): | ||
| # Now both grids have 14 as highest node id, so both will have branch ids 15, 16 and 17: | ||
| grid1 = Grid.from_txt("S1 2", "S1 3 link", "3 14 transformer") | ||
| grid2 = Grid.from_txt("S1 2", "S1 13 link", "13 14 transformer") | ||
|
|
||
| grid1.merge(grid2, mode="recalculate_ids") | ||
| assert grid1.check_ids() is None, "Asset ids are not unique after merging!" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't see what this tests?
Missing asserts on the ids?
| from power_grid_model_ds._core.model.arrays import SourceArray | ||
|
|
||
|
|
||
| class TestMergeGrids: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a test that we give a runtime error if we have an ExtendedGrid with a new array type and use recalculate_ids.
| from power_grid_model_ds._core.model.arrays import SourceArray | ||
|
|
||
|
|
||
| class TestMergeGrids: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test not implemented error for invalid call to the merge function. (so mode="invalid" in the call)
…grid Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Signed-off-by: wander.wadman <wander.wadman@alliander.com>
Fixes issue:
#118Changes proposed in this PR include:
Adding function Grid.merge(self, other_grid) that merges another grid into this grid.
Could you please pay extra attention to the points below when reviewing the PR:
Search forQuestion for reviewerin the diffChecks
I added some tests that in my view cover most of the workings.