e2nIEE / pandapower
1
# -*- coding: utf-8 -*-
2

3
# Copyright (c) 2016-2021 by University of Kassel and Fraunhofer Institute for Energy Economics
4
# and Energy System Technology (IEE), Kassel. All rights reserved.
5

6 1
import numpy as np
7 1
import pandas as pd
8 1
from packaging import version
9

10 1
from pandapower import __version__
11 1
from pandapower.create import create_empty_network, create_poly_cost
12 1
from pandapower.results import reset_results
13

14

15 1
def convert_format(net):
16
    """
17
    Converts old nets to new format to ensure consistency. The converted net is returned.
18
    """
19 1
    from pandapower.toolbox import set_data_type_of_columns_to_default
20 1
    if isinstance(net.version, str) and version.parse(net.version) >= version.parse(__version__):
21 1
        return net
22 1
    _add_nominal_power(net)
23 1
    _add_missing_tables(net)
24 1
    _rename_columns(net)
25 1
    _add_missing_columns(net)
26 1
    _create_seperate_cost_tables(net)
27 1
    if version.parse(str(net.version)) < version.parse("2.4.0"):
28 1
        _convert_bus_pq_meas_to_load_reference(net)
29 1
    if isinstance(net.version, float) and net.version < 2:
30 1
        _convert_to_generation_system(net)
31 1
        _convert_costs(net)
32 1
        _convert_to_mw(net)
33 1
        _update_trafo_parameter_names(net)
34 1
        reset_results(net)
35 1
    if isinstance(net.version, float) and net.version < 1.6:
36 1
        set_data_type_of_columns_to_default(net)
37 1
    _convert_objects(net)
38 1
    net.version = __version__
39 1
    return net
40

41

42 1
def _convert_bus_pq_meas_to_load_reference(net):
43 1
    bus_pq_meas_mask = net.measurement.measurement_type.isin(["p", "q"])&\
44
        (net.measurement.element_type=="bus")
45 1
    net.measurement.loc[bus_pq_meas_mask, "value"] *= -1
46

47

48 1
def _convert_to_generation_system(net):
49 1
    net.sgen.p_kw *= -1
50 1
    net.sgen.q_kvar *= -1
51 1
    net.gen.p_kw *= -1
52 1
    for element in ["gen", "sgen", "ext_grid"]:
53 1
        for suffix in ["p_kw", "q_kvar"]:
54 1
            constraints = {}
55 1
            if "min_%s" % suffix in net[element]:
56 1
                constraints["max_%s" % suffix] = net[element]["min_%s" % suffix] * -1
57 1
                del net[element]["min_%s" % suffix]
58 1
            if "max_%s" % suffix in net[element]:
59 1
                constraints["min_%s" % suffix] = net[element]["max_%s" % suffix] * -1
60 1
                del net[element]["max_%s" % suffix]
61 1
            for column, values in constraints.items():
62 1
                net[element][column] = values
63 1
    pq_measurements = net.measurement[net.measurement.measurement_type.isin(["p", "q"])].index
64 1
    net.measurement.loc[pq_measurements, ["value", "std_dev"]] *= 1e-3
65

66

67 1
def _convert_costs(net):
68 1
    if "polynomial_cost" in net:
69 1
        for cost in net.polynomial_cost.itertuples():
70 0
            values = cost.c[0]
71 0
            if len(values) == 2:
72 0
                cp0 = values[1]
73 0
                cp1 = values[0]
74 0
                cp2 = 0
75 0
            elif len(values) == 3:
76 0
                cp0 = values[2]
77 0
                cp1 = values[1]
78 0
                cp2 = values[0]
79 0
            create_poly_cost(net, et=cost.element_type, element=cost.element, cp0_eur=cp0,
80
                             cp1_eur_per_mw=cp1 * 1e3, cp2_eur_per_mw2=cp2 * 1e6)
81 1
        del net.polynomial_cost
82 1
    if "piecewise_linear_cost" in net:
83 1
        if len(net.piecewise_linear_cost) > 0:
84 0
            raise NotImplementedError
85 1
        del net.piecewise_linear_cost
86

87

88 1
def _add_nominal_power(net):
89 1
    if "sn_kva" in net:
90 1
        net.sn_mva = net.pop("sn_kva") * 1e-3
91

92
    # Reset sn_mva only if sn_mva not available
93 1
    if "sn_mva" not in net:
94 0
        net.sn_mva = 1.0
95

96

97 1
def _add_missing_tables(net):
98 1
    net_new = create_empty_network()
99 1
    for key in net_new.keys():
100 1
        if key.startswith("_empty_res"):
101 1
            net[key] = net_new[key]
102 1
        elif key not in net.keys():
103 1
            net[key] = net_new[key]
104

105

106 1
def _create_seperate_cost_tables(net):
107 1
    if "cost_per_kw" in net.gen:
108 0
        for index, cost in net.gen.cost_per_kw.iteritems():
109 0
            if not np.isnan(cost):
110 0
                create_poly_cost(net, index, "gen", cp1_eur_per_mw=cost * 1e3)
111

112 1
    if "cost_per_kw" in net.sgen:
113 0
        for index, cost in net.sgen.cost_per_kw.iteritems():
114 0
            if not np.isnan(cost):
115 0
                create_poly_cost(net, index, "sgen", cp1_eur_per_kw=cost)
116

117 1
    if "cost_per_kw" in net.ext_grid:
118 0
        for index, cost in net.ext_grid.cost_per_kw.iteritems():
119 0
            if not np.isnan(cost):
120 0
                create_poly_cost(net, index, "ext_grid", cp1_eur_per_kw=cost)
121

122 1
    if "cost_per_kvar" in net.gen:
123 0
        for index, cost in net.gen.cost_per_kvar.iteritems():
124 0
            if not np.isnan(cost):
125 0
                create_poly_cost(net, index, "ext_grid", cp1_eur_per_mw=0,
126
                                 cq1_eur_per_mvar=cost * 1e3)
127

128 1
    if "cost_per_kvar" in net.sgen:
129 0
        for index, cost in net.sgen.cost_per_kvar.iteritems():
130 0
            if not np.isnan(cost):
131 0
                create_poly_cost(net, index, "sgen", cp1_eur_per_mw=0,
132
                                 cq1_eur_per_mvar=cost * 1e3)
133

134 1
    if "cost_per_kvar" in net.ext_grid:
135 0
        for index, cost in net.ext_grid.cost_per_kvar.iteritems():
136 0
            if not np.isnan(cost):
137 0
                create_poly_cost(net, index, "ext_grid", cp1_eur_per_mw=0,
138
                                 cq1_eur_per_mvar=cost * 1e3)
139

140

141 1
def _rename_columns(net):
142 1
    net.line.rename(columns={'imax_ka': 'max_i_ka'}, inplace=True)
143 1
    for typ, data in net.std_types["line"].items():
144 1
        if "imax_ka" in data:
145 0
            net.std_types["line"][typ]["max_i_ka"] = net.std_types["line"][typ].pop("imax_ka")
146 1
    _update_trafo_parameter_names(net)
147
    # initialize measurement dataframe
148 1
    if "measurement" in net and "type" in net.measurement:
149 1
        if net.measurement.empty:
150 1
            net["measurement"] = create_empty_network()["measurement"]
151
        else:
152 0
            net.measurement["side"] = None
153 0
            bus_measurements = net.measurement.element_type == "bus"
154 0
            net.measurement.loc[bus_measurements, "element"] = \
155
                net.measurement.loc[bus_measurements, "bus"].values
156 0
            net.measurement.loc[~bus_measurements, "side"] = \
157
                net.measurement.loc[~bus_measurements, "bus"].values
158 0
            net.measurement.rename(columns={'type': 'measurement_type'}, inplace=True)
159 0
            net.measurement.drop(["bus"], axis=1, inplace=True)
160 1
    if "controller" in net:
161 1
        net["controller"].rename(columns={"controller": "object"}, inplace=True)
162 1
    if "options" in net:
163 0
        if "recycle" in net["options"]:
164 0
            if "Ybus" in net["options"]["recycle"]:
165 0
                if net["options"]["recycle"]["Ybus"]:
166 0
                    net["options"]["recycle"]["trafo"] = False
167 0
                del net["options"]["recycle"]["Ybus"]
168
            else:
169 0
                net["options"]["recycle"]["trafo"] = True
170 0
            if "ppc" in net["options"]["recycle"]:
171 0
                if net["options"]["recycle"]["ppc"]:
172 0
                    net["options"]["recycle"]["bus_pq"] = False
173 0
                del net["options"]["recycle"]["ppc"]
174
            else:
175 0
                net["options"]["recycle"]["bus_pq"] = True
176

177

178 1
def _add_missing_columns(net):
179 1
    for element in ["trafo", "line"]:
180 1
        if "df" not in net[element]:
181 1
            net[element]["df"] = 1.0
182 1
    if "coords" not in net.bus_geodata:
183 1
        net.bus_geodata["coords"] = None
184 1
    if not "tap_at_star_point" in net.trafo3w:
185 1
        net.trafo3w["tap_at_star_point"] = False
186 1
    if not "tap_step_degree" in net.trafo3w:
187 1
        net.trafo3w["tap_step_degree"] = 0
188 1
    if "const_z_percent" not in net.load or "const_i_percent" not in net.load:
189 1
        net.load["const_z_percent"] = np.zeros(net.load.shape[0])
190 1
        net.load["const_i_percent"] = np.zeros(net.load.shape[0])
191

192 1
    if "vn_kv" not in net["shunt"]:
193 1
        net.shunt["vn_kv"] = net.bus.vn_kv.loc[net.shunt.bus.values].values
194 1
    if "step" not in net["shunt"]:
195 1
        net.shunt["step"] = 1
196 1
    if "max_step" not in net["shunt"]:
197 1
        net.shunt["max_step"] = 1
198 1
    if "std_type" not in net.trafo3w:
199 0
        net.trafo3w["std_type"] = None
200

201 1
    if "current_source" not in net.sgen:
202 1
        net.sgen["current_source"] = net.sgen["type"].apply(
203
            func=lambda x: False if x == "motor" else True)
204

205 1
    if "g_us_per_km" not in net.line:
206 1
        net.line["g_us_per_km"] = 0.
207

208 1
    if "slack" not in net.gen:
209 1
        net.gen["slack"] = False
210

211 1
    if "tap_phase_shifter" not in net.trafo and "tp_phase_shifter" not in net.trafo:
212 1
        net.trafo["tap_phase_shifter"] = False
213

214
    # unsymmetric impedance
215 1
    if "r_pu" in net.impedance:
216 1
        net.impedance["rft_pu"] = net.impedance["rtf_pu"] = net.impedance["r_pu"]
217 1
        net.impedance["xft_pu"] = net.impedance["xtf_pu"] = net.impedance["x_pu"]
218

219
    # Update the switch table with 'z_ohm'
220 1
    if 'z_ohm' not in net.switch:
221 1
        net.switch['z_ohm'] = 0
222

223 1
    if "name" not in net.measurement:
224 0
        net.measurement.insert(0, "name", None)
225

226 1
    if "initial_run" not in net.controller:
227 1
        net.controller.insert(4, 'initial_run', False)
228 1
        for _, ctrl in net.controller.iterrows():
229 1
            if hasattr(ctrl['object'], 'initial_run'):
230 1
                net.controller.at[ctrl.name, 'initial_run'] = ctrl['object'].initial_run
231
            else:
232 1
                net.controller.at[ctrl.name, 'initial_run'] = ctrl['object'].initial_powerflow
233

234 1
def _update_trafo_type_parameter_names(net):
235 1
    for element in ('trafo', 'trafo3w'):
236 1
        for type in net.std_types[element].keys():
237 1
            keys = {col: _update_column(col) for col in net.std_types[element][type].keys() if
238
                    col.startswith("tp") or col.startswith("vsc")}
239 1
            for old_key, new_key in keys.items():
240 1
                net.std_types[element][type][new_key] = net.std_types[element][type].pop(old_key)
241

242

243 1
def _update_trafo_parameter_names(net):
244 1
    for element in ["trafo", "trafo3w"]:
245 1
        replace_cols = {col: _update_column(col) for col in net[element].columns if
246
                        col.startswith("tp") or col.startswith("vsc")}
247 1
        net[element].rename(columns=replace_cols, inplace=True)
248 1
    _update_trafo_type_parameter_names(net)
249

250

251 1
def _update_column(column):
252 1
    column = column.replace("tp_", "tap_")
253 1
    column = column.replace("_st_", "_step_")
254 1
    column = column.replace("_mid", "_neutral")
255 1
    column = column.replace("vsc", "vk")
256 1
    return column
257

258

259 1
def _set_data_type_of_columns(net):
260 0
    new_net = create_empty_network()
261 0
    for key, item in net.items():
262 0
        if isinstance(item, pd.DataFrame):
263 0
            for col in item.columns:
264 0
                if col == "tap_pos":
265 0
                    continue
266 0
                if key in new_net and col in new_net[key].columns:
267 0
                    if set(item.columns) == set(new_net[key]):
268 0
                        if version.parse(pd.__version__) < version.parse("0.21"):
269 0
                            net[key] = net[key].reindex_axis(new_net[key].columns, axis=1)
270
                        else:
271 0
                            net[key] = net[key].reindex(new_net[key].columns, axis=1)
272 0
                    if version.parse(pd.__version__) < version.parse("0.20.0"):
273 0
                        net[key][col] = net[key][col].astype(new_net[key][col].dtype,
274
                                                             raise_on_error=False)
275
                    else:
276 0
                        net[key][col] = net[key][col].astype(new_net[key][col].dtype,
277
                                                             errors="ignore")
278

279

280 1
def _convert_to_mw(net):
281 1
    replace = [("kw", "mw"), ("kvar", "mvar"), ("kva", "mva")]
282 1
    for element, tab in net.items():
283 1
        if isinstance(tab, pd.DataFrame):
284 1
            for old, new in replace:
285 1
                diff = {column: column.replace(old, new) for column in tab.columns if old in column
286
                        and column != "pfe_kw"}
287 1
                tab.rename(columns=diff, inplace=True)
288 1
                if len(tab) == 0:
289 1
                    continue
290 1
                for old, new in diff.items():
291 1
                    tab[new] *= 1e-3
292

293 1
    for element, std_types in net.std_types.items():
294 1
        for std_type, parameters in std_types.items():
295 1
            for parameter in set(parameters.keys()):
296 1
                for old, new in replace:
297 1
                    if old in parameter and parameter != "pfe_kw":
298 1
                        parameters[parameter.replace(old, new)] = parameters[parameter] * 1e-3
299 1
                        del parameters[parameter]
300

301

302 1
def _update_object_attributes(obj):
303
    """
304
    Rename attributes of a given object. A new attribute is added and the old one is removed.
305
    """
306 1
    to_rename = {"u_set": "vm_set_pu",
307
                 "u_lower": "vm_lower_pu",
308
                 "u_upper": "vm_upper_pu"}
309

310 1
    for key, val in to_rename.items():
311 1
        if key in obj.__dict__:
312 1
            obj.__dict__[val] = obj.__dict__.pop(key)
313

314

315 1
def _convert_objects(net):
316
    """
317
    The function updates attribute names in pandapower objects. For now, it affects TrafoController.
318
    Should be expanded for other objects if necessary.
319
    """
320 1
    if "controller" in net.keys():
321 1
        for obj in net["controller"].object.values:
322 1
            _update_object_attributes(obj)

Read our documentation on viewing source code .

Loading