Skip to content

Commit b7cf7cc

Browse files
authored
More pp tests (#28)
1 parent 45eb9c6 commit b7cf7cc

File tree

17 files changed

+564
-328
lines changed

17 files changed

+564
-328
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repos:
1010
- id: mixed-line-ending
1111
- id: check-case-conflict
1212
- repo: https://github.com/astral-sh/ruff-pre-commit
13-
rev: v0.12.0 # must match uv.lock
13+
rev: v0.12.1 # must match uv.lock
1414
hooks:
1515
- id: ruff
1616
- id: ruff-format

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ tests = [
2222
"networkx>=3.2.1",
2323
"geopandas>=1.0.0",
2424
"pandapower>=3.1.2",
25+
"types-networkx>=3.4.2",
2526
]
2627
dev = [
2728
"ruff>=0.9.2",

stubs/pandapower-stubs/estimation/algorithm/base.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ from _typeshed import Incomplete
22

33
from pandapower.estimation.ppc_conversion import ExtendedPPCI
44

5+
__all__ = ["WLSAlgorithm", "WLSZeroInjectionConstraintsAlgorithm", "IRWLSAlgorithm"]
6+
57
class BaseAlgorithm:
68
tolerance: Incomplete
79
max_iterations: Incomplete
@@ -23,7 +25,7 @@ class WLSAlgorithm(BaseAlgorithm):
2325
H: Incomplete
2426
hx: Incomplete
2527
def __init__(self, tolerance, maximum_iterations, logger=...) -> None: ...
26-
def estimate(self, eppci: ExtendedPPCI, **kwargs): ...
28+
def estimate(self, eppci: ExtendedPPCI, debug_mode: bool = False, **kwargs): ...
2729

2830
class WLSZeroInjectionConstraintsAlgorithm(BaseAlgorithm):
2931
def estimate(self, eppci: ExtendedPPCI, **kwargs): ...

stubs/pandapower-stubs/estimation/algorithm/matrix_base.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ from _typeshed import Incomplete
22

33
from pandapower.estimation.ppc_conversion import ExtendedPPCI
44

5+
__all__ = ["BaseAlgebra", "BaseAlgebraZeroInjConstraints"]
6+
57
class BaseAlgebra:
68
eppci: Incomplete
79
fb: Incomplete
Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
IM_FROM: int
2-
IM_FROM_STD: int
3-
IM_TO: int
4-
IM_TO_STD: int
5-
P_FROM: int
6-
P_FROM_STD: int
7-
P_TO: int
8-
P_TO_STD: int
9-
Q_FROM: int
10-
Q_FROM_STD: int
11-
Q_TO: int
12-
Q_TO_STD: int
13-
IM_FROM_IDX: int
14-
P_FROM_IDX: int
15-
Q_FROM_IDX: int
16-
IM_TO_IDX: int
17-
P_TO_IDX: int
18-
Q_TO_IDX: int
19-
IA_FROM: int
20-
IA_FROM_STD: int
21-
IA_TO: int
22-
IA_TO_STD: int
23-
IA_FROM_IDX: int
24-
IA_TO_IDX: int
25-
branch_cols_se: int
1+
from typing import Final
2+
3+
IM_FROM: Final = 0
4+
IM_FROM_STD: Final = 1
5+
IM_TO: Final = 2
6+
IM_TO_STD: Final = 3
7+
P_FROM: Final = 4
8+
P_FROM_STD: Final = 5
9+
P_TO: Final = 6
10+
P_TO_STD: Final = 7
11+
Q_FROM: Final = 8
12+
Q_FROM_STD: Final = 9
13+
Q_TO: Final = 10
14+
Q_TO_STD: Final = 11
15+
IM_FROM_IDX: Final = 12
16+
P_FROM_IDX: Final = 13
17+
Q_FROM_IDX: Final = 14
18+
IM_TO_IDX: Final = 15
19+
P_TO_IDX: Final = 16
20+
Q_TO_IDX: Final = 17
21+
IA_FROM: Final = 18
22+
IA_FROM_STD: Final = 19
23+
IA_TO: Final = 20
24+
IA_TO_STD: Final = 21
25+
IA_FROM_IDX: Final = 22
26+
IA_TO_IDX: Final = 23
27+
branch_cols_se: Final = 24
Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
VM: int
2-
VM_STD: int
3-
P: int
4-
P_STD: int
5-
Q: int
6-
Q_STD: int
7-
VM_IDX: int
8-
P_IDX: int
9-
Q_IDX: int
10-
ZERO_INJ_FLAG: int
11-
VA: int
12-
VA_STD: int
13-
VA_IDX: int
14-
bus_cols_se: int
1+
from typing import Final
2+
3+
VM: Final = 0
4+
VM_STD: Final = 1
5+
P: Final = 2
6+
P_STD: Final = 3
7+
Q: Final = 4
8+
Q_STD: Final = 5
9+
VM_IDX: Final = 6
10+
P_IDX: Final = 7
11+
Q_IDX: Final = 8
12+
ZERO_INJ_FLAG: Final = 9
13+
VA: Final = 10
14+
VA_STD: Final = 11
15+
VA_IDX: Final = 12
16+
bus_cols_se: Final = 13
Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,61 @@
1-
from _typeshed import Incomplete
21
from collections import UserDict
2+
from collections.abc import Collection
3+
from typing import (
4+
Any,
5+
Any as csr_matrix, # scipy.sparse.csr_matrix
6+
Literal,
7+
)
8+
9+
import numpy as np
10+
11+
from pandapower._typing import Array1D, Array2D
12+
from pandapower.auxiliary import pandapowerNet
313

414
ZERO_INJECTION_STD_DEV: float
5-
BR_SIDE: Incomplete
6-
BR_MEAS_PPCI_IX: Incomplete
7-
BUS_MEAS_PPCI_IX: Incomplete
15+
BR_SIDE: dict[str, dict[str, str]]
16+
BR_MEAS_PPCI_IX: dict[tuple[str, str], dict[str, int]]
17+
BUS_MEAS_PPCI_IX: dict[str, dict[str, int]]
818

919
def pp2eppci(
10-
net,
11-
v_start: Incomplete | None = None,
12-
delta_start: Incomplete | None = None,
20+
net: pandapowerNet,
21+
v_start: Collection[float] | str | None = None,
22+
delta_start: Collection[float] | str | None = None,
1323
calculate_voltage_angles: bool = True,
1424
zero_injection: str = "aux_bus",
15-
ppc: Incomplete | None = None,
16-
eppci: Incomplete | None = None,
17-
): ...
25+
algorithm: str = "wls",
26+
ppc: dict[str, Any] | None = None,
27+
eppci: ExtendedPPCI | None = None,
28+
) -> tuple[pandapowerNet, dict[str, Any] | None, ExtendedPPCI]: ...
1829

19-
class ExtendedPPCI(UserDict[str, Incomplete]):
20-
data: Incomplete
21-
z: Incomplete
22-
r_cov: Incomplete
23-
pp_meas_indices: Incomplete
24-
non_nan_meas_mask: Incomplete
25-
non_nan_meas_selector: Incomplete
30+
class ExtendedPPCI(UserDict[str, Any]):
31+
data: dict[str, Any]
32+
algorithm: Literal["wls", "wls_with_zero_constraint", "opt", "irwls", "lp", "af-wls"]
33+
z: Array2D[np.float64] | None
34+
r_cov: Array2D[np.float64] | None
35+
pp_meas_indices: Array2D[np.int64] | None
36+
non_nan_meas_mask: dict[str, Array1D[np.int64]] | None
37+
non_nan_meas_selector: Array1D[np.int64] | None
38+
idx_non_imeas: Array1D[np.int64] | None
2639
any_i_meas: bool
2740
any_degree_meas: bool
28-
non_slack_buses: Incomplete
29-
non_slack_bus_mask: Incomplete
30-
num_non_slack_bus: Incomplete
31-
delta_v_bus_mask: Incomplete
32-
delta_v_bus_selector: Incomplete
33-
v_init: Incomplete
34-
delta_init: Incomplete
35-
E_init: Incomplete
36-
v: Incomplete
37-
delta: Incomplete
38-
E: Incomplete
39-
def __init__(self, ppci) -> None: ...
41+
non_slack_buses: Array1D[np.int64]
42+
non_slack_bus_mask: Array1D[np.bool]
43+
num_non_slack_bus: np.int64
44+
delta_v_bus_mask: Array1D[np.bool]
45+
delta_v_bus_selector: Array1D[np.int64]
46+
v_init: Array1D[np.float64]
47+
delta_init: Array1D[np.float64]
48+
E_init: Array1D[np.float64]
49+
v: Array1D[np.float64]
50+
delta: Array1D[np.float64]
51+
E: Array1D[np.float64]
52+
def __init__(
53+
self, ppci: dict[str, Any], algorithm: Literal["wls", "wls_with_zero_constraint", "opt", "irwls", "lp", "af-wls"]
54+
) -> None: ...
4055
def update_meas(self) -> None: ...
4156
@property
42-
def V(self): ...
57+
def V(self) -> Array1D[np.complex128]: ...
4358
def reset(self) -> None: ...
44-
def update_E(self, E) -> None: ...
45-
def E2V(self, E): ...
46-
def get_Y(self): ...
59+
def update_E(self, E: Array1D[np.float64]) -> None: ...
60+
def E2V(self, E: Array1D[np.float64]) -> Array1D[np.complex128]: ...
61+
def get_Y(self) -> tuple[csr_matrix, csr_matrix, csr_matrix]: ...
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
def eppci2pp(net, ppc, eppci): ...
1+
from pandapower.auxiliary import pandapowerNet
2+
from pandapower.estimation.ppc_conversion import ExtendedPPCI
3+
4+
def eppci2pp(net: pandapowerNet, ppc, eppci: ExtendedPPCI) -> pandapowerNet: ...
Lines changed: 83 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,118 @@
1-
from _typeshed import Incomplete
1+
import logging
2+
from collections.abc import Collection
3+
from typing import Any, Literal, overload
24

3-
ALGORITHM_MAPPING: Incomplete
4-
ALLOWED_OPT_VAR: Incomplete
5+
from pandapower.auxiliary import pandapowerNet
6+
from pandapower.estimation.algorithm.base import BaseAlgorithm
57

8+
ALGORITHM_MAPPING: dict[str, type[BaseAlgorithm]]
9+
ALLOWED_OPT_VAR: set[str]
10+
11+
@overload
612
def estimate(
7-
net,
8-
algorithm: str = "wls",
9-
init: str = "flat",
13+
net: pandapowerNet,
14+
algorithm: Literal["wls", "af-wls"] = "wls",
15+
init: Literal["flat", "results", "slack"] = "flat",
1016
tolerance: float = 1e-06,
11-
maximum_iterations: int = 10,
12-
calculate_voltage_angles: bool = True,
13-
zero_injection: str = "aux_bus",
14-
fuse_buses_with_bb_switch: str = "all",
17+
maximum_iterations: int = 50,
18+
zero_injection: Collection[int] | str = "aux_bus",
19+
fuse_buses_with_bb_switch: Collection[int] | Literal["all"] = "all",
20+
debug_mode: bool = False,
1521
**opt_vars,
16-
): ...
22+
) -> dict[str, Any]: ...
23+
@overload
24+
def estimate(
25+
net: pandapowerNet,
26+
algorithm: Literal["wls_with_zero_constraint", "opt", "irwls", "lp"],
27+
init: Literal["flat", "results", "slack"] = "flat",
28+
tolerance: float = 1e-06,
29+
maximum_iterations: int = 50,
30+
zero_injection: Collection[int] | str = "aux_bus",
31+
fuse_buses_with_bb_switch: Collection[int] | Literal["all"] = "all",
32+
debug_mode: bool = False,
33+
**opt_vars,
34+
) -> bool: ...
1735
def remove_bad_data(
18-
net,
19-
init: str = "flat",
36+
net: pandapowerNet,
37+
init: Literal["flat", "results", "slack"] = "flat",
2038
tolerance: float = 1e-06,
2139
maximum_iterations: int = 10,
2240
calculate_voltage_angles: bool = True,
2341
rn_max_threshold: float = 3.0,
24-
): ...
42+
) -> bool: ...
2543
def chi2_analysis(
2644
net,
2745
init: str = "flat",
2846
tolerance: float = 1e-06,
2947
maximum_iterations: int = 10,
3048
calculate_voltage_angles: bool = True,
3149
chi2_prob_false: float = 0.05,
32-
): ...
50+
) -> bool | None: ...
3351

3452
class StateEstimation:
35-
net: Incomplete
36-
solver: Incomplete
37-
ppc: Incomplete
38-
eppci: Incomplete
39-
recycle: Incomplete
40-
delta: Incomplete
41-
bad_data_present: Incomplete
53+
logger: logging.Logger
54+
net: pandapowerNet
55+
solver: BaseAlgorithm
56+
ppc: dict[str, Any] | None
57+
eppci: dict[str, Any] | None
58+
recycle: bool
59+
algorithm: Literal["wls", "wls_with_zero_constraint", "opt", "irwls", "lp", "af-wls"]
60+
delta: None # not currently used
61+
bad_data_present: bool | None
4262
def __init__(
4363
self,
44-
net,
64+
net: pandapowerNet,
4565
tolerance: float = 1e-06,
46-
maximum_iterations: int = 10,
47-
algorithm: str = "wls",
48-
logger: Incomplete | None = None,
66+
maximum_iterations: int = 50,
67+
algorithm: Literal["wls", "wls_with_zero_constraint", "opt", "irwls", "lp", "af-wls"] = "wls",
68+
logger: logging.Logger | None = None,
4969
recycle: bool = False,
5070
) -> None: ...
71+
@overload
5172
def estimate(
5273
self,
53-
v_start: str = "flat",
54-
delta_start: str = "flat",
55-
calculate_voltage_angles: bool = True,
56-
zero_injection: Incomplete | None = None,
57-
fuse_buses_with_bb_switch: str = "all",
74+
v_start: Collection[float] | str = "flat",
75+
delta_start: Collection[float] | str = "flat",
76+
zero_injection: Collection[int] | str | None = None,
77+
fuse_buses_with_bb_switch: Collection[int] | Literal["all"] = "all",
78+
algorithm: Literal["wls", "af-wls"] = "wls",
79+
debug_mode: bool = False,
80+
**opt_vars,
81+
) -> dict[str, Any]: ...
82+
@overload # algorithm positional
83+
def estimate(
84+
self,
85+
v_start: Collection[float] | str,
86+
delta_start: Collection[float] | str,
87+
zero_injection: Collection[int] | str | None,
88+
fuse_buses_with_bb_switch: Collection[int] | Literal["all"],
89+
algorithm: Literal["wls_with_zero_constraint", "opt", "irwls", "lp"],
90+
debug_mode: bool = False,
91+
**opt_vars,
92+
) -> bool: ...
93+
@overload # algorithm keyword
94+
def estimate(
95+
self,
96+
v_start: Collection[float] | str = "flat",
97+
delta_start: Collection[float] | str = "flat",
98+
zero_injection: Collection[int] | str | None = None,
99+
fuse_buses_with_bb_switch: Collection[int] | Literal["all"] = "all",
100+
*,
101+
algorithm: Literal["wls_with_zero_constraint", "opt", "irwls", "lp"],
102+
debug_mode: bool = False,
58103
**opt_vars,
59-
): ...
104+
) -> bool: ...
60105
def perform_chi2_test(
61106
self,
62-
v_in_out: Incomplete | None = None,
63-
delta_in_out: Incomplete | None = None,
107+
v_in_out: Collection[float] | str | None = None,
108+
delta_in_out: Collection[float] | str | None = None,
64109
calculate_voltage_angles: bool = True,
65110
chi2_prob_false: float = 0.05,
66-
): ...
111+
) -> bool | None: ...
67112
def perform_rn_max_test(
68113
self,
69-
v_in_out: Incomplete | None = None,
70-
delta_in_out: Incomplete | None = None,
114+
v_in_out: Collection[float] | str | None = None,
115+
delta_in_out: Collection[float] | str | None = None,
71116
calculate_voltage_angles: bool = True,
72117
rn_max_threshold: float = 3.0,
73-
): ...
118+
) -> bool: ...

0 commit comments

Comments
 (0)