Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions pandapower/create/trafo_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def create_transformers(
xn_ohm: float | Iterable[float] = nan,
tap2_pos: int | Iterable[int] | float = nan,
**kwargs,
) -> npt.NDArray[Int]:
) -> npt.NDArray[integer]:
"""
Creates several two-winding transformers in table net.trafo.
Additional parameters passed will be added to the transformers dataframe. If keywords are passed that are present
Expand Down Expand Up @@ -252,19 +252,18 @@ def create_transformers(

std_params = load_std_type(net, std_type, "trafo")

required_params = ("sn_mva", "vn_lv_kv", "vn_hv_kv", "vk_percent", "vkr_percent", "pfe_kw")
if not all(param in std_params for param in required_params):
raise ValueError(f"std_type is missing a required value. Required values: {', '.join(required_params)}")
params_from_std_type = (
"i0_percent", "vk0_percent", "vkr0_percent", "mag0_percent", "mag0_rx", "si0_hv_partial", "vector_group",
*required_params
)
params = {param: std_params[param] for param in params_from_std_type if param in std_params}
params.update(kwargs)
create_transformers_required_parameters = ("sn_mva", "vn_lv_kv", "vn_hv_kv", "vkr_percent", "vk_percent", "pfe_kw", "i0_percent")
missing = [p for p in create_transformers_required_parameters if p not in std_params]
if missing:
raise ValueError(f"std_type is missing a required value. Required values: {', '.join(create_transformers_required_parameters)}")
params = {**std_params, **kwargs}

if tap_changer_type is not None:
params["tap_changer_type"] = tap_changer_type
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think this change is a good Idea there seems to be one issue.

If the standard type includes one of the explicitly passed parameters this will fail.
Standard types in pandapower have a set of minimal required values that need to be set, but can take any additional values.
So I could create a standard_type that includes e.g a derating factor df, with you're code change this would lead to df being passed twice as a keyword and lead to a TypeError: pandapower.create.trafo_create.create_transformers_from_parameters() got multiple values for keyword argument 'df'

Reproducible example:

from pandapower.std_types import create_std_type, load_std_type
from pandapower.networks.mv_oberrhein import mv_oberrhein
from pandapower.create.trafo_create import create_transformers

net = mv_oberrhein()
std_params = load_std_type(net, "63 MVA 110/10 kV", "trafo")
create_std_type(net, {**std_params, "df": .8}, "MyTrafoType", "trafo")
create_transformers(net, [58], [0], "MyTrafoType")
print(net)


return create_transformers_from_parameters(
net=net, hv_buses=hv_buses, lv_buses=lv_buses, name=name, tap_pos=tap_pos, in_service=in_service, index=index,
max_loading_percent=max_loading_percent, parallel=parallel, df=df, tap_changer_type=tap_changer_type,
max_loading_percent=max_loading_percent, parallel=parallel, df=df,
tap_dependency_table=tap_dependency_table, id_characteristic_table=id_characteristic_table,
pt_percent=pt_percent, oltc=oltc, xn_ohm=xn_ohm, tap2_pos=tap2_pos, std_type=std_type,
**params
Expand All @@ -282,7 +281,7 @@ def create_transformer_from_parameters(
vk_percent: float,
pfe_kw: float,
i0_percent: float,
shift_degree: float = 0,
shift_degree: float = 0.0,
tap_side: HVLVType | None = None,
tap_neutral: int | float = nan,
tap_max: int | float = nan,
Expand Down Expand Up @@ -514,7 +513,7 @@ def create_transformers_from_parameters( # index missing ?
vk_percent: float | Iterable[float],
pfe_kw: float | Iterable[float],
i0_percent: float | Iterable[float],
shift_degree: float | Iterable[float] = 0,
shift_degree: float | Iterable[float] = 0.0,
tap_side: HVLVType | Iterable[str] | None = None,
tap_neutral: int | Iterable[int] | float = nan,
tap_max: int | Iterable[int] | float = nan,
Expand Down
178 changes: 116 additions & 62 deletions pandapower/test/api/test_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -983,37 +983,34 @@ def test_create_transformers():
name=["trafo1", "trafo2"],
test_kwargs="TestKW"
)
res_df = pd.DataFrame({
'name': ['trafo1', 'trafo2'],
'std_type': ['0.4 MVA 10/0.4 kV', '0.4 MVA 10/0.4 kV'],
'hv_bus': pd.Series([0, 0], dtype=np.uint32),
'lv_bus': pd.Series([1, 2], dtype=np.uint32),
'sn_mva': [0.4, 0.4],
'vn_hv_kv': [10.0, 10.0],
'vn_lv_kv': [0.4, 0.4],
'vk_percent': [4.0, 4.0],
'vkr_percent': [1.325, 1.325],
'pfe_kw': [0.95, 0.95],
'i0_percent': [0.2375, 0.2375],
'shift_degree': [0.0, 0.0],
'tap_side': ['', ''],
'tap_neutral': [nan, nan],
'tap_min': [nan, nan],
'tap_max': [nan, nan],
'tap_step_percent': [nan, nan],
'tap_step_degree': [nan, nan],
'tap_pos': [nan, nan],
'tap_changer_type': ['', ''],
'id_characteristic_table': pd.Series([pd.NA, pd.NA], dtype=pd.Int64Dtype),
'tap_dependency_table': [False, False],
'parallel': pd.Series([1, 1], dtype=np.uint32),
'df': [1.0, 1.0],
'in_service': [True, True],
'oltc': [False, False],
'test_kwargs': ['TestKW', 'TestKW'],
'vector_group': ['Dyn5', 'Dyn5'],
})
assert dataframes_equal(net.trafo, res_df)

assert net.trafo["name"].tolist() == ["trafo1", "trafo2"]
assert net.trafo["std_type"].tolist() == ["0.4 MVA 10/0.4 kV", "0.4 MVA 10/0.4 kV"]
assert net.trafo["hv_bus"].tolist() == [0, 0]
assert net.trafo["lv_bus"].tolist() == [1, 2]
assert np.allclose(net.trafo["sn_mva"].tolist(), [0.4, 0.4])
assert np.allclose(net.trafo["vn_hv_kv"].tolist(), [10.0, 10.0])
assert np.allclose(net.trafo["vn_lv_kv"].tolist(), [0.4, 0.4])
assert np.allclose(net.trafo["vk_percent"].tolist(), [4.0, 4.0])
assert np.allclose(net.trafo["vkr_percent"].tolist(), [1.325, 1.325])
assert np.allclose(net.trafo["pfe_kw"].tolist(), [0.95, 0.95])
assert np.allclose(net.trafo["i0_percent"].tolist(), [0.2375, 0.2375])
assert np.allclose(net.trafo["shift_degree"].tolist(), [150.0, 150.0])
assert net.trafo["tap_side"].tolist() == ["hv", "hv"]
assert net.trafo["tap_neutral"].tolist(), [0, 0]
assert net.trafo["tap_min"].tolist(), [-2, -2]
assert net.trafo["tap_max"].tolist(), [2, 2]
assert np.allclose(net.trafo["tap_step_percent"].tolist(), [2.5, 2.5])
assert net.trafo["tap_step_degree"].tolist(), [0, 0]
assert net.trafo["tap_pos"].tolist(), [0, 0]
assert net.trafo["tap_changer_type"].tolist() == ["Ratio", "Ratio"]
assert net.trafo["id_characteristic_table"].isna().all()
assert net.trafo["parallel"].tolist() == [1, 1]
assert np.allclose(net.trafo["df"].tolist(), [1.0, 1.0])
assert net.trafo["in_service"].tolist() == [True, True]
assert net.trafo["oltc"].tolist() == [False, False]
assert net.trafo["test_kwargs"].tolist() == ["TestKW", "TestKW"]
assert net.trafo["vector_group"].tolist() == ["Dyn5", "Dyn5"]

def test_create_transformers_for_single():
net = create_empty_network()
Expand All @@ -1028,37 +1025,94 @@ def test_create_transformers_for_single():
test_kwargs="TestKW",
sn_mva=.4
)
res_df = pd.DataFrame({
'name': ['trafo1'],
'std_type': ['0.4 MVA 10/0.4 kV'],
'hv_bus': pd.Series([0], dtype=np.uint32),
'lv_bus': pd.Series([1], dtype=np.uint32),
'sn_mva': [0.4],
'vn_hv_kv': [10.0],
'vn_lv_kv': [0.4],
'vk_percent': [4.0],
'vkr_percent': [1.325],
'pfe_kw': [0.95],
'i0_percent': [0.2375],
'shift_degree': [0.0],
'tap_side': [''],
'tap_neutral': [nan],
'tap_min': [nan],
'tap_max': [nan],
'tap_step_percent': [nan],
'tap_step_degree': [nan],
'tap_pos': [nan],
'tap_changer_type': [''],
'id_characteristic_table': pd.Series([pd.NA], dtype=pd.Int64Dtype),
'tap_dependency_table': [False],
'parallel': pd.Series([1], dtype=np.uint32),
'df': [1.0],
'in_service': [True],
'oltc': [False],
'test_kwargs': ['TestKW'],
'vector_group': ['Dyn5'],
})
assert dataframes_equal(net.trafo, res_df)
assert net.trafo["name"].tolist() == ["trafo1"]
assert net.trafo["std_type"].tolist() == ["0.4 MVA 10/0.4 kV"]
assert net.trafo["hv_bus"].tolist() == [0]
assert net.trafo["lv_bus"].tolist() == [1]
assert np.allclose(net.trafo["sn_mva"].tolist(), [0.4])
assert np.allclose(net.trafo["vn_hv_kv"].tolist(), [10.0])
assert np.allclose(net.trafo["vn_lv_kv"].tolist(), [0.4])
assert np.allclose(net.trafo["vk_percent"].tolist(), [4.0])
assert np.allclose(net.trafo["vkr_percent"].tolist(), [1.325])
assert np.allclose(net.trafo["pfe_kw"].tolist(), [0.95])
assert np.allclose(net.trafo["i0_percent"].tolist(), [0.2375])
assert np.allclose(net.trafo["shift_degree"].tolist(), [150.0])
assert net.trafo["tap_side"].tolist() == ["hv"]
assert net.trafo["tap_neutral"].tolist(), [0]
assert net.trafo["tap_min"].tolist(), [-2]
assert net.trafo["tap_max"].tolist(), [2]
assert np.allclose(net.trafo["tap_step_percent"].tolist(), [2.5])
assert net.trafo["tap_step_degree"].tolist(), [0]
assert net.trafo["tap_pos"].tolist(), [0]
assert net.trafo["tap_changer_type"].tolist() == ["Ratio"]
assert net.trafo["id_characteristic_table"].isna().all()
assert net.trafo["parallel"].tolist() == [1]
assert np.allclose(net.trafo["df"].tolist(), [1.0])
assert net.trafo["in_service"].tolist() == [True]
assert net.trafo["oltc"].tolist() == [False]
assert net.trafo["test_kwargs"].tolist() == ["TestKW"]
assert net.trafo["vector_group"].tolist() == ["Dyn5"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems to be unrelated to the PR.

I would also not approve of it as this seems overly complex, if the original assert fails you can get slightly better output if you have CLI logging enabled while testing.

Same for the test above.


def test_create_transformers_for_single_override_std_type():
net = create_empty_network()
b1 = create_bus(net, 22)
b2 = create_bus(net, .5)
create_transformers(
net,
hv_buses=[b1],
lv_buses=[b2],
std_type="0.4 MVA 10/0.4 kV",
name="trafo1",
sn_mva = 0.5,
vn_hv_kv = 22,
vn_lv_kv = 0.5,
vk_percent = 5,
vkr_percent = 1.532,
pfe_kw = 0.65,
i0_percent = 0.1264,
shift_degree = 90,
vector_group = "Dd5",
tap_side = "lv",
tap_neutral = 1,
tap_min = -4,
tap_max = 4,
tap_step_degree = 3,
tap_step_percent = 1.5,
tap_changer_type = "Symmetrical",
trafo_characteristic_table = True,
parallel = 2,
df = 2,
in_service = False,
oltc = True,
test_kwargs = "TestKW"
)
assert net.trafo["name"].tolist() == ["trafo1"]
assert net.trafo["std_type"].tolist() == ["0.4 MVA 10/0.4 kV"]
assert net.trafo["hv_bus"].tolist() == [0]
assert net.trafo["lv_bus"].tolist() == [1]
assert np.allclose(net.trafo["sn_mva"].tolist(), [0.5])
assert np.allclose(net.trafo["vn_hv_kv"].tolist(), [22.0])
assert np.allclose(net.trafo["vn_lv_kv"].tolist(), [0.5])
assert np.allclose(net.trafo["vk_percent"].tolist(), [5.0])
assert np.allclose(net.trafo["vkr_percent"].tolist(), [1.532])
assert np.allclose(net.trafo["pfe_kw"].tolist(), [0.65])
assert np.allclose(net.trafo["i0_percent"].tolist(), [0.1264])
assert np.allclose(net.trafo["shift_degree"].tolist(), [90.0])
assert net.trafo["tap_side"].tolist() == ["lv"]
assert net.trafo["tap_neutral"].tolist(), [1]
assert net.trafo["tap_min"].tolist(), [-4]
assert net.trafo["tap_max"].tolist(), [4]
assert np.allclose(net.trafo["tap_step_percent"].tolist(), [1.5])
assert net.trafo["tap_step_degree"].tolist(), [3]
assert net.trafo["tap_pos"].tolist(), [1]
assert net.trafo["tap_changer_type"].tolist() == ["Symmetrical"]
assert net.trafo["id_characteristic_table"].isna().all()
assert net.trafo["parallel"].tolist() == [2]
assert np.allclose(net.trafo["df"].tolist(), [2.0])
assert net.trafo["in_service"].tolist() == [False]
assert net.trafo["oltc"].tolist() == [True]
assert net.trafo["test_kwargs"].tolist() == ["TestKW"]
assert net.trafo["vector_group"].tolist() == ["Dd5"]


def test_create_transformers3w():
Expand Down
Loading