Skip to content

Commit 2dce7c9

Browse files
committed
skeleton for validation checks for auto tap
Signed-off-by: Martijn Govers <[email protected]> resolve comments Signed-off-by: Martijn Govers <[email protected]> Update src/power_grid_model/validation/validation.py Signed-off-by: Martijn Govers <[email protected]> Co-authored-by: Nitish Bharambe <[email protected]> Signed-off-by: Martijn Govers <[email protected]> tmp Signed-off-by: Martijn Govers <[email protected]> tmp Signed-off-by: Martijn Govers <[email protected]>
1 parent d74097b commit 2dce7c9

File tree

4 files changed

+50
-8
lines changed

4 files changed

+50
-8
lines changed

Diff for: src/power_grid_model/validation/errors.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def field_str(self) -> str:
160160

161161
class MultiComponentValidationError(ValidationError):
162162
"""
163-
Base class for an error that applies to multiple component, and as a consequence also to multiple fields.
163+
Base class for an error that applies to multiple components, and as a consequence also to multiple fields.
164164
Even if both fields have the same name, they are considered to be different fields and notated as such.
165165
E.g. the two fields `id` fields of the `node` and `line` component: [('node', 'id'), ('line', 'id')].
166166
"""
@@ -237,9 +237,9 @@ class InvalidEnumValueError(SingleFieldValidationError):
237237
"""
238238

239239
_message = "Field {field} contains invalid {enum} values for {n} {objects}."
240-
enum: Type[Enum]
240+
enum: Union[Type[Enum], List[Type[Enum]]]
241241

242-
def __init__(self, component: str, field: str, ids: List[int], enum: Type[Enum]):
242+
def __init__(self, component: str, field: str, ids: List[int], enum: Union[Type[Enum], List[Type[Enum]]]):
243243
super().__init__(component, field, ids)
244244
self.enum = enum
245245

@@ -248,6 +248,9 @@ def enum_str(self) -> str:
248248
"""
249249
A string representation of the field to which this error applies.
250250
"""
251+
if isinstance(self.enum, list):
252+
return ",".join(e.__name__ for e in self.enum)
253+
251254
return self.enum.__name__
252255

253256
def __eq__(self, other):

Diff for: src/power_grid_model/validation/rules.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ def all_cross_unique(
471471

472472

473473
def all_valid_enum_values(
474-
data: SingleDataset, component: str, field: str, enum: Type[Enum]
474+
data: SingleDataset, component: str, field: str, enum: Union[Type[Enum], List[Type[Enum]]]
475475
) -> List[InvalidEnumValueError]:
476476
"""
477477
Check that for all records of a particular type of component, the values in the 'field' column are valid values for
@@ -481,14 +481,19 @@ def all_valid_enum_values(
481481
data (SingleDataset): The input/update data set for all components
482482
component (str): The component of interest
483483
field (str): The field of interest
484-
enum (Type[Enum]): The enum type to validate against
484+
enum (Type[Enum]): The enum type to validate against, or a list of such enum types
485485
486486
Returns:
487487
A list containing zero or one InvalidEnumValueError, listing all ids where the value in the field of interest
488488
was not a valid value in the supplied enum type.
489489
"""
490-
valid = [nan_type(component, field)] + list(enum)
491-
invalid = np.isin(data[component][field], np.array(valid, dtype=np.int8), invert=True)
490+
enums: List[Type[Enum]] = enum if isinstance(enum, list) else [enum]
491+
492+
valid = {nan_type(component, field)}
493+
for enum_type in enums:
494+
valid.update(list(enum_type))
495+
496+
invalid = np.isin(data[component][field], np.array(list(valid), dtype=np.int8), invert=True)
492497
if invalid.any():
493498
ids = data[component]["id"][invalid].flatten().tolist()
494499
return [InvalidEnumValueError(component, field, ids, enum)]

Diff for: src/power_grid_model/validation/validation.py

+25
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,9 @@ def validate_values(data: SingleDataset, calculation_type: Optional[CalculationT
476476
if calculation_type in (None, CalculationType.short_circuit) and "fault" in data:
477477
errors += validate_fault(data)
478478

479+
if calculation_type in (None, CalculationType.power_flow) and "transformer_tap_regulator" in data:
480+
errors += validate_transformer_tap_regulator(data)
481+
479482
return errors
480483

481484

@@ -806,3 +809,25 @@ def validate_fault(data: SingleDataset) -> List[ValidationError]:
806809
errors += all_enabled_identical(data, "fault", "fault_type", "status")
807810
errors += all_enabled_identical(data, "fault", "fault_phase", "status")
808811
return errors
812+
813+
814+
def validate_regulator(data: SingleDataset, component: str) -> List[ValidationError]:
815+
errors = validate_base(data, component)
816+
errors += all_valid_ids(
817+
data,
818+
component,
819+
field="regulated_object",
820+
ref_components=["transformer", "three_winding_transformer"],
821+
)
822+
return errors
823+
824+
825+
def validate_transformer_tap_regulator(data: SingleDataset) -> List[ValidationError]:
826+
errors = validate_regulator(data, "transformer_tap_regulator")
827+
errors += all_boolean(data, "transformer_tap_regulator", "status")
828+
errors += all_valid_enum_values(data, "transformer_tap_regulator", "control_side", [BranchSide, Branch3Side])
829+
errors += all_greater_than_or_equal_to_zero(data, "transformer_tap_regulator", "u_set")
830+
errors += all_greater_than_zero(data, "transformer_tap_regulator", "u_band")
831+
errors += all_greater_than_or_equal_to_zero(data, "transformer_tap_regulator", "line_drop_compensation_r", 0.0)
832+
errors += all_greater_than_or_equal_to_zero(data, "transformer_tap_regulator", "line_drop_compensation_x", 0.0)
833+
return errors

Diff for: tests/unit/validation/test_rules.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pytest
99

1010
from power_grid_model import LoadGenType, initialize_array
11-
from power_grid_model.enum import FaultPhase, FaultType
11+
from power_grid_model.enum import Branch3Side, BranchSide, FaultPhase, FaultType
1212
from power_grid_model.validation.errors import (
1313
ComparisonError,
1414
FaultPhaseError,
@@ -329,6 +329,15 @@ def test_all_valid_enum_values():
329329
errors = all_valid_enum_values(valid, "sym_load", "type", LoadGenType)
330330
assert not errors
331331

332+
valid = {"transformer_tap_regulator": initialize_array("input", "transformer_tap_regulator", 5)}
333+
valid["transformer_tap_regulator"]["id"] = np.arange(5)
334+
valid["transformer_tap_regulator"]["control_side"] = np.arange(-1, 4)
335+
errors = all_valid_enum_values(valid, "transformer_tap_regulator", "control_side", [BranchSide, Branch3Side])
336+
assert len(errors) == 1
337+
assert (
338+
InvalidEnumValueError("transformer_tap_regulator", "control_side", [0, 4], [BranchSide, Branch3Side]) in errors
339+
)
340+
332341

333342
def test_all_valid_ids():
334343
# This data is for testing purpuse

0 commit comments

Comments
 (0)