From cfc38c3a359a56a4c40aefc52370088047a150c6 Mon Sep 17 00:00:00 2001 From: Santiago Figueroa Manrique Date: Thu, 10 Oct 2024 14:43:24 +0200 Subject: [PATCH 1/4] bug fix Signed-off-by: Santiago Figueroa Manrique --- src/power_grid_model/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/power_grid_model/_utils.py b/src/power_grid_model/_utils.py index f396967ba..23e230d4b 100644 --- a/src/power_grid_model/_utils.py +++ b/src/power_grid_model/_utils.py @@ -418,7 +418,7 @@ def compatibility_convert_row_columnar_dataset( ) if is_sparse(data[comp_name]): - result_data[comp_name] = {"indptr": _extract_indptr(data), "data": converted_sub_data} + result_data[comp_name] = {"indptr": _extract_indptr(data[comp_name]), "data": converted_sub_data} else: result_data[comp_name] = converted_sub_data return result_data From 3e2b881648fa3a04f51883ea9dd9cdd83575c857 Mon Sep 17 00:00:00 2001 From: Santiago Figueroa Manrique Date: Fri, 11 Oct 2024 16:22:07 +0200 Subject: [PATCH 2/4] additional tests for columnar-row conversion functions Signed-off-by: Santiago Figueroa Manrique --- tests/unit/test_internal_utils.py | 75 ++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_internal_utils.py b/tests/unit/test_internal_utils.py index 9045e5520..840072c2e 100644 --- a/tests/unit/test_internal_utils.py +++ b/tests/unit/test_internal_utils.py @@ -8,7 +8,7 @@ import numpy as np import pytest -from power_grid_model import initialize_array +from power_grid_model import ComponentType, DatasetType, initialize_array from power_grid_model._utils import ( compatibility_convert_row_columnar_dataset, convert_batch_dataset_to_batch_list, @@ -17,6 +17,7 @@ get_batch_size, get_dataset_type, is_nan, + is_sparse, process_data_filter, split_dense_batch_data_in_batches, split_sparse_batch_data_in_batches, @@ -803,3 +804,75 @@ def test_get_dataset_type__conflicting_data(): else: with pytest.raises(PowerGridError): get_dataset_type(data=data) + + +@pytest.fixture +def row_dense_data(): + source = initialize_array(DatasetType.update, ComponentType.source, (2, 3)) + source["id"] = [[0, 2, 3], [0, 2, 3]] + source["u_ref"] = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]] + + sym_load = initialize_array(DatasetType.update, ComponentType.sym_load, (2, 1)) + sym_load["id"] = [[1], [1]] + sym_load["p_specified"] = [[100.0], [200.0]] + + return { + ComponentType.source: source, + ComponentType.sym_load: sym_load, + } + + +@pytest.fixture +def row_sparse_data(): + transformer = initialize_array(DatasetType.update, ComponentType.transformer, 1) + transformer["id"] = 1 + transformer["tap_pos"] = 3 + + sym_gen = initialize_array(DatasetType.update, ComponentType.sym_gen, (2, 4)) + sym_gen["id"] = [[5, 6, 7, 8], [5, 6, 7, 8]] + sym_gen["q_specified"] = [[1.1, 2.2, 3.3, 4.4], [4.4, 3.3, 2.2, 1.1]] + + return { + ComponentType.transformer: { + "data": transformer, + "indptr": np.array([0, 1, 1]), + }, + ComponentType.sym_gen: { + "data": sym_gen, + "indptr": np.array([0, 1, 2]), + }, + } + + +@pytest.fixture(params=["row_dense_data", "row_sparse_data"]) +def row_data(request): + return request.getfixturevalue(request.param) + + +def compare_row_data(actual_row_data, desired_row_data): + assert actual_row_data.keys() == desired_row_data.keys() + for comp_name in actual_row_data.keys(): + actual_component = actual_row_data[comp_name] + desired_component = desired_row_data[comp_name] + if is_sparse(actual_component): + assert actual_component.keys() == desired_component.keys() + assert np.array_equal(actual_component["indptr"], desired_component["indptr"]) + actual_component = actual_component["data"] + desired_component = desired_component["data"] + assert actual_component.dtype == desired_component.dtype + assert actual_component.shape == desired_component.shape + + for field in actual_component.dtype.names: + assert np.all( + (np.isnan(actual_component[field]) & np.isnan(desired_component[field])) + | (actual_component[field] == desired_component[field]) + ) + + +def test_dense_row_data_to_from_col_data(row_data): + # row data to columnar data and back + col_data = compatibility_convert_row_columnar_dataset( + row_data, ComponentAttributeFilterOptions.ALL, DatasetType.update + ) + new_row_data = compatibility_convert_row_columnar_dataset(col_data, None, DatasetType.update) + compare_row_data(row_data, new_row_data) From 2ca6c90564b45d31d91c82c989fb0752a2298cf4 Mon Sep 17 00:00:00 2001 From: Santiago Figueroa Manrique Date: Fri, 11 Oct 2024 16:24:59 +0200 Subject: [PATCH 3/4] minor typo Signed-off-by: Santiago Figueroa Manrique --- tests/unit/validation/test_batch_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/validation/test_batch_validation.py b/tests/unit/validation/test_batch_validation.py index b26e566f2..ae02a4e53 100644 --- a/tests/unit/validation/test_batch_validation.py +++ b/tests/unit/validation/test_batch_validation.py @@ -103,7 +103,7 @@ def test_validate_batch_data(input_data, batch_data): def test_validate_batch_data_input_error(input_data, batch_data): - if is_columnar(input_data): + if is_columnar(input_data["node"]): input_data["node"]["id"][-1] = 123 input_data["line"]["id"][-1] = 123 else: From bf207584f6e3cacaed1a27d01713802d69d2f076 Mon Sep 17 00:00:00 2001 From: Santiago Figueroa Manrique Date: Fri, 11 Oct 2024 16:58:32 +0200 Subject: [PATCH 4/4] addressed comments Signed-off-by: Santiago Figueroa Manrique --- tests/unit/test_internal_utils.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/unit/test_internal_utils.py b/tests/unit/test_internal_utils.py index 840072c2e..1e876f7ea 100644 --- a/tests/unit/test_internal_utils.py +++ b/tests/unit/test_internal_utils.py @@ -828,9 +828,9 @@ def row_sparse_data(): transformer["id"] = 1 transformer["tap_pos"] = 3 - sym_gen = initialize_array(DatasetType.update, ComponentType.sym_gen, (2, 4)) - sym_gen["id"] = [[5, 6, 7, 8], [5, 6, 7, 8]] - sym_gen["q_specified"] = [[1.1, 2.2, 3.3, 4.4], [4.4, 3.3, 2.2, 1.1]] + sym_gen = initialize_array(DatasetType.update, ComponentType.sym_gen, 8) + sym_gen["id"] = [5, 6, 7, 8, 5, 6, 7, 8] + sym_gen["q_specified"] = [1.1, 2.2, 3.3, 4.4, 4.4, 3.3, 2.2, 1.1] return { ComponentType.transformer: { @@ -839,7 +839,7 @@ def row_sparse_data(): }, ComponentType.sym_gen: { "data": sym_gen, - "indptr": np.array([0, 1, 2]), + "indptr": np.array([0, 4, 8]), }, } @@ -851,6 +851,7 @@ def row_data(request): def compare_row_data(actual_row_data, desired_row_data): assert actual_row_data.keys() == desired_row_data.keys() + for comp_name in actual_row_data.keys(): actual_component = actual_row_data[comp_name] desired_component = desired_row_data[comp_name] @@ -863,10 +864,12 @@ def compare_row_data(actual_row_data, desired_row_data): assert actual_component.shape == desired_component.shape for field in actual_component.dtype.names: - assert np.all( - (np.isnan(actual_component[field]) & np.isnan(desired_component[field])) - | (actual_component[field] == desired_component[field]) - ) + actual_attr = actual_component[field] + desired_attr = desired_component[field] + nan_a = np.isnan(actual_attr) + nan_b = np.isnan(desired_attr) + np.testing.assert_array_equal(nan_a, nan_b) + np.testing.assert_allclose(actual_attr[~nan_a], desired_attr[~nan_b], rtol=1e-15) def test_dense_row_data_to_from_col_data(row_data):