Repository: e2nIEE/pandapower

Issue:
State estimation module error when net has disabled branches
Hi, i came across a bug in the state estimation module, when I run the following code for the new functionality for trafo3w added in 5234059ca65a6c8e1bdb27ddbbd57cceb620a960 . The net was modified with one disabled line. The reason seems to be that,  the branch mapping from pp to ppci will change if some branches were disabled or connected between two disabled buses.

```
import pandapower as pp
from pandapower.estimation import estimate

net = pp.create_empty_network()

bus_slack = pp.create_bus(net, vn_kv=110)
pp.create_ext_grid(net, bus=bus_slack)

bus_20_1 = pp.create_bus(net, vn_kv=20,name="b")
pp.create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02)

bus_10_1 = pp.create_bus(net, vn_kv=10)
pp.create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02)

bus_10_2 = pp.create_bus(net, vn_kv=10)
pp.create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01)
pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2)
disabled_line = pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2)
net.line.at[disabled_line, 'in_service'] = False

pp.create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV")

pp.runpp(net)

pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from')
pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from')
pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to')
pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to')

pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv')
pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv')
pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv')
pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv')
pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv')
pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv')

pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0)
pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1)

success = estimate(net)
```



Discussion:

Resolving patch:
diff --git a/pandapower/estimation/wls_ppc_conversions.py b/pandapower/estimation/wls_ppc_conversions.py
--- a/pandapower/estimation/wls_ppc_conversions.py
+++ b/pandapower/estimation/wls_ppc_conversions.py
@@ -66,19 +66,30 @@ def _add_measurements_to_ppc(net, ppci):
         std_logger.warning("Measurement defined in pp-grid does not exist in ppci! Will be deleted!")
         meas_bus = meas_bus[map_bus[meas_bus['element']] < ppci["bus"].shape[0]]
 
-    map_line, map_trafo, map_trafo3w = None, None, None
     # mapping to dict instead of np array ensures good performance for large indices
     # (e.g., 999999999 requires a large np array even if there are only 2 buses)
     # downside is loop comprehension to access the map
+    map_line, map_trafo, map_trafo3w = None, None, None
+    branch_mask = ppci['internal']['branch_is']
     if "line" in net["_pd2ppc_lookups"]["branch"]:
-        map_line = dict(zip(net.line.index, range(*net["_pd2ppc_lookups"]["branch"]["line"])))
+        map_line = {line_ix: br_ix for line_ix, br_ix in
+                    zip(net.line.index, range(*net["_pd2ppc_lookups"]["branch"]["line"])) if branch_mask[br_ix]}
+
     if "trafo" in net["_pd2ppc_lookups"]["branch"]:
-        map_trafo = dict(zip(net.trafo.index, range(*net["_pd2ppc_lookups"]["branch"]["trafo"])))
+        trafo_ix_start, trafo_ix_end = net["_pd2ppc_lookups"]["branch"]["trafo"]
+        trafo_ix_offset = np.sum(~branch_mask[:trafo_ix_start])
+        trafo_ix_start, trafo_ix_end = trafo_ix_start - trafo_ix_offset, trafo_ix_end - trafo_ix_offset
+        map_trafo = {trafo_ix: br_ix for trafo_ix, br_ix in
+                     zip(net.trafo.index, range(trafo_ix_start, trafo_ix_end))
+                     if branch_mask[br_ix+trafo_ix_offset]}
 
     if "trafo3w" in net["_pd2ppc_lookups"]["branch"]:
-        map_trafo3w = {ix: {'hv': br_ix, 'mv': br_ix+1, 'lv': br_ix+2}
-                       for ix, br_ix in zip(net.trafo3w.index,
-                                            range(*(net["_pd2ppc_lookups"]["branch"]["trafo3w"]+(3,))))}
+        trafo3w_ix_start, trafo3w_ix_end = net["_pd2ppc_lookups"]["branch"]["trafo3w"]
+        trafo3w_ix_offset = np.sum(~branch_mask[:trafo3w_ix_start])
+        trafo3w_ix_start, trafo3w_ix_end = trafo3w_ix_start - trafo3w_ix_offset, trafo3w_ix_end - trafo3w_ix_offset
+        map_trafo3w = {trafo3w_ix: {'hv': br_ix, 'mv': br_ix+1, 'lv': br_ix+2} for trafo3w_ix, br_ix in
+                       zip(net.trafo3w.index, range(trafo3w_ix_start, trafo3w_ix_end, 3))
+                       if branch_mask[br_ix+trafo3w_ix_offset]}
 
     # set measurements for ppc format
     # add 9 columns to ppc[bus] for Vm, Vm std dev, P, P std dev, Q, Q std dev,
@@ -120,52 +131,56 @@ def _add_measurements_to_ppc(net, ppci):
     branch_append = np.full((ppci["branch"].shape[0], branch_cols_se),
                             np.nan, dtype=ppci["branch"].dtype)
 
-    i_measurements = meas[(meas.measurement_type == "i") & (meas.element_type == "line")]
-    if len(i_measurements):
-        meas_from = i_measurements[(i_measurements.side.values.astype(int) ==
-                                    net.line.from_bus[i_measurements.element]).values]
-        meas_to = i_measurements[(i_measurements.side.values.astype(int) ==
-                                  net.line.to_bus[i_measurements.element]).values]
-        ix_from = [map_line[l] for l in meas_from.element.values.astype(int)]
-        ix_to = [map_line[l] for l in meas_to.element.values.astype(int)]
-        i_ka_to_pu_from = (net.bus.vn_kv[meas_from.side]).values * 1e3
-        i_ka_to_pu_to = (net.bus.vn_kv[meas_to.side]).values * 1e3
-        branch_append[ix_from, IM_FROM] = meas_from.value.values * i_ka_to_pu_from
-        branch_append[ix_from, IM_FROM_STD] = meas_from.std_dev.values * i_ka_to_pu_from
-        branch_append[ix_from, IM_FROM_IDX] = meas_from.index.values
-        branch_append[ix_to, IM_TO] = meas_to.value.values * i_ka_to_pu_to
-        branch_append[ix_to, IM_TO_STD] = meas_to.std_dev.values * i_ka_to_pu_to
-        branch_append[ix_to, IM_TO_IDX] = meas_to.index.values
-
-    p_measurements = meas[(meas.measurement_type == "p") & (meas.element_type == "line")]
-    if len(p_measurements):
-        meas_from = p_measurements[(p_measurements.side.values.astype(int) ==
-                                    net.line.from_bus[p_measurements.element]).values]
-        meas_to = p_measurements[(p_measurements.side.values.astype(int) ==
-                                  net.line.to_bus[p_measurements.element]).values]
-        ix_from = [map_line[l] for l in meas_from.element.values.astype(int)]
-        ix_to = [map_line[l] for l in meas_to.element.values.astype(int)]
-        branch_append[ix_from, P_FROM] = meas_from.value.values
-        branch_append[ix_from, P_FROM_STD] = meas_from.std_dev.values
-        branch_append[ix_from, P_FROM_IDX] = meas_from.index.values
-        branch_append[ix_to, P_TO] = meas_to.value.values
-        branch_append[ix_to, P_TO_STD] = meas_to.std_dev.values
-        branch_append[ix_to, P_TO_IDX] = meas_to.index.values
-
-    q_measurements = meas[(meas.measurement_type == "q") & (meas.element_type == "line")]
-    if len(q_measurements):
-        meas_from = q_measurements[(q_measurements.side.values.astype(int) ==
-                                    net.line.from_bus[q_measurements.element]).values]
-        meas_to = q_measurements[(q_measurements.side.values.astype(int) ==
-                                  net.line.to_bus[q_measurements.element]).values]
-        ix_from = [map_line[l] for l in meas_from.element.values.astype(int)]
-        ix_to = [map_line[l] for l in meas_to.element.values.astype(int)]
-        branch_append[ix_from, Q_FROM] = meas_from.value.values
-        branch_append[ix_from, Q_FROM_STD] = meas_from.std_dev.values
-        branch_append[ix_from, Q_FROM_IDX] = meas_from.index.values
-        branch_append[ix_to, Q_TO] = meas_to.value.values
-        branch_append[ix_to, Q_TO_STD] = meas_to.std_dev.values
-        branch_append[ix_to, Q_TO_IDX] = meas_to.index.values
+    if map_line is not None:
+        i_measurements = meas[(meas.measurement_type == "i") & (meas.element_type == "line") &\
+                              meas.element.isin(map_line)]
+        if len(i_measurements):
+            meas_from = i_measurements[(i_measurements.side.values.astype(int) ==
+                                        net.line.from_bus[i_measurements.element]).values]
+            meas_to = i_measurements[(i_measurements.side.values.astype(int) ==
+                                      net.line.to_bus[i_measurements.element]).values]
+            ix_from = [map_line[l] for l in meas_from.element.values.astype(int)]
+            ix_to = [map_line[l] for l in meas_to.element.values.astype(int)]
+            i_ka_to_pu_from = (net.bus.vn_kv[meas_from.side]).values * 1e3
+            i_ka_to_pu_to = (net.bus.vn_kv[meas_to.side]).values * 1e3
+            branch_append[ix_from, IM_FROM] = meas_from.value.values * i_ka_to_pu_from
+            branch_append[ix_from, IM_FROM_STD] = meas_from.std_dev.values * i_ka_to_pu_from
+            branch_append[ix_from, IM_FROM_IDX] = meas_from.index.values
+            branch_append[ix_to, IM_TO] = meas_to.value.values * i_ka_to_pu_to
+            branch_append[ix_to, IM_TO_STD] = meas_to.std_dev.values * i_ka_to_pu_to
+            branch_append[ix_to, IM_TO_IDX] = meas_to.index.values
+    
+        p_measurements = meas[(meas.measurement_type == "p") & (meas.element_type == "line") &
+                              meas.element.isin(map_line)]
+        if len(p_measurements):
+            meas_from = p_measurements[(p_measurements.side.values.astype(int) ==
+                                        net.line.from_bus[p_measurements.element]).values]
+            meas_to = p_measurements[(p_measurements.side.values.astype(int) ==
+                                      net.line.to_bus[p_measurements.element]).values]
+            ix_from = [map_line[l] for l in meas_from.element.values.astype(int)]
+            ix_to = [map_line[l] for l in meas_to.element.values.astype(int)]
+            branch_append[ix_from, P_FROM] = meas_from.value.values
+            branch_append[ix_from, P_FROM_STD] = meas_from.std_dev.values
+            branch_append[ix_from, P_FROM_IDX] = meas_from.index.values
+            branch_append[ix_to, P_TO] = meas_to.value.values
+            branch_append[ix_to, P_TO_STD] = meas_to.std_dev.values
+            branch_append[ix_to, P_TO_IDX] = meas_to.index.values
+    
+        q_measurements = meas[(meas.measurement_type == "q") & (meas.element_type == "line") &
+                              meas.element.isin(map_line)]
+        if len(q_measurements):
+            meas_from = q_measurements[(q_measurements.side.values.astype(int) ==
+                                        net.line.from_bus[q_measurements.element]).values]
+            meas_to = q_measurements[(q_measurements.side.values.astype(int) ==
+                                      net.line.to_bus[q_measurements.element]).values]
+            ix_from = [map_line[l] for l in meas_from.element.values.astype(int)]
+            ix_to = [map_line[l] for l in meas_to.element.values.astype(int)]
+            branch_append[ix_from, Q_FROM] = meas_from.value.values
+            branch_append[ix_from, Q_FROM_STD] = meas_from.std_dev.values
+            branch_append[ix_from, Q_FROM_IDX] = meas_from.index.values
+            branch_append[ix_to, Q_TO] = meas_to.value.values
+            branch_append[ix_to, Q_TO_STD] = meas_to.std_dev.values
+            branch_append[ix_to, Q_TO_IDX] = meas_to.index.values
 
     # TODO review in 2019 -> is this a use case? create test with switches on lines
     # determine number of lines in ppci["branch"]
@@ -180,120 +195,128 @@ def _add_measurements_to_ppc(net, ppci):
     #         & (np.in1d(net["switch"]["element"].values, lines_is.index)) \
     #         & (np.in1d(net["switch"]["bus"].values, bus_is_idx))
     # ppci_lines = len(lines_is) - np.count_nonzero(slidx)
-
-    i_tr_measurements = meas[(meas.measurement_type == "i") & (meas.element_type == "trafo")]
-    if len(i_tr_measurements):
-        meas_from = i_tr_measurements[(i_tr_measurements.side.values.astype(int) ==
-                                       net.trafo.hv_bus[i_tr_measurements.element]).values]
-        meas_to = i_tr_measurements[(i_tr_measurements.side.values.astype(int) ==
-                                     net.trafo.lv_bus[i_tr_measurements.element]).values]
-        ix_from = [map_trafo[t] for t in meas_from.element.values.astype(int)]
-        ix_to = [map_trafo[t] for t in meas_to.element.values.astype(int)]
-        i_ka_to_pu_from = (net.bus.vn_kv[meas_from.side]).values * 1e3
-        i_ka_to_pu_to = (net.bus.vn_kv[meas_to.side]).values * 1e3
-        branch_append[ix_from, IM_FROM] = meas_from.value.values * i_ka_to_pu_from
-        branch_append[ix_from, IM_FROM_STD] = meas_from.std_dev.values * i_ka_to_pu_from
-        branch_append[ix_from, IM_FROM_IDX] = meas_from.index.values
-        branch_append[ix_to, IM_TO] = meas_to.value.values * i_ka_to_pu_to
-        branch_append[ix_to, IM_TO_STD] = meas_to.std_dev.values * i_ka_to_pu_to
-        branch_append[ix_to, IM_TO_IDX] = meas_to.index.values
-
-    p_tr_measurements = meas[(meas.measurement_type == "p") & (meas.element_type == "trafo")]
-    if len(p_tr_measurements):
-        meas_from = p_tr_measurements[(p_tr_measurements.side.values.astype(int) ==
-                                       net.trafo.hv_bus[p_tr_measurements.element]).values]
-        meas_to = p_tr_measurements[(p_tr_measurements.side.values.astype(int) ==
-                                     net.trafo.lv_bus[p_tr_measurements.element]).values]
-        ix_from = [map_trafo[t] for t in meas_from.element.values.astype(int)]
-        ix_to = [map_trafo[t] for t in meas_to.element.values.astype(int)]
-        branch_append[ix_from, P_FROM] = meas_from.value.values
-        branch_append[ix_from, P_FROM_STD] = meas_from.std_dev.values
-        branch_append[ix_from, P_FROM_IDX] = meas_from.index.values
-        branch_append[ix_to, P_TO] = meas_to.value.values
-        branch_append[ix_to, P_TO_STD] = meas_to.std_dev.values
-        branch_append[ix_to, P_TO_IDX] = meas_to.index.values
-
-    q_tr_measurements = meas[(meas.measurement_type == "q") & (meas.element_type == "trafo")]
-    if len(q_tr_measurements):
-        meas_from = q_tr_measurements[(q_tr_measurements.side.values.astype(int) ==
-                                       net.trafo.hv_bus[q_tr_measurements.element]).values]
-        meas_to = q_tr_measurements[(q_tr_measurements.side.values.astype(int) ==
-                                     net.trafo.lv_bus[q_tr_measurements.element]).values]
-        ix_from = [map_trafo[t] for t in meas_from.element.values.astype(int)]
-        ix_to = [map_trafo[t] for t in meas_to.element.values.astype(int)]
-        branch_append[ix_from, Q_FROM] = meas_from.value.values
-        branch_append[ix_from, Q_FROM_STD] = meas_from.std_dev.values
-        branch_append[ix_from, Q_FROM_IDX] = meas_from.index.values
-        branch_append[ix_to, Q_TO] = meas_to.value.values
-        branch_append[ix_to, Q_TO_STD] = meas_to.std_dev.values
-        branch_append[ix_to, Q_TO_IDX] = meas_to.index.values
+    
+    if map_trafo is not None:
+        i_tr_measurements = meas[(meas.measurement_type == "i") & (meas.element_type == "trafo") &
+                                 meas.element.isin(map_trafo)]
+        if len(i_tr_measurements):
+            meas_from = i_tr_measurements[(i_tr_measurements.side.values.astype(int) ==
+                                           net.trafo.hv_bus[i_tr_measurements.element]).values]
+            meas_to = i_tr_measurements[(i_tr_measurements.side.values.astype(int) ==
+                                         net.trafo.lv_bus[i_tr_measurements.element]).values]
+            ix_from = [map_trafo[t] for t in meas_from.element.values.astype(int)]
+            ix_to = [map_trafo[t] for t in meas_to.element.values.astype(int)]
+            i_ka_to_pu_from = (net.bus.vn_kv[meas_from.side]).values * 1e3
+            i_ka_to_pu_to = (net.bus.vn_kv[meas_to.side]).values * 1e3
+            branch_append[ix_from, IM_FROM] = meas_from.value.values * i_ka_to_pu_from
+            branch_append[ix_from, IM_FROM_STD] = meas_from.std_dev.values * i_ka_to_pu_from
+            branch_append[ix_from, IM_FROM_IDX] = meas_from.index.values
+            branch_append[ix_to, IM_TO] = meas_to.value.values * i_ka_to_pu_to
+            branch_append[ix_to, IM_TO_STD] = meas_to.std_dev.values * i_ka_to_pu_to
+            branch_append[ix_to, IM_TO_IDX] = meas_to.index.values
+    
+        p_tr_measurements = meas[(meas.measurement_type == "p") & (meas.element_type == "trafo") &
+                                 meas.element.isin(map_trafo)]
+        if len(p_tr_measurements):
+            meas_from = p_tr_measurements[(p_tr_measurements.side.values.astype(int) ==
+                                           net.trafo.hv_bus[p_tr_measurements.element]).values]
+            meas_to = p_tr_measurements[(p_tr_measurements.side.values.astype(int) ==
+                                         net.trafo.lv_bus[p_tr_measurements.element]).values]
+            ix_from = [map_trafo[t] for t in meas_from.element.values.astype(int)]
+            ix_to = [map_trafo[t] for t in meas_to.element.values.astype(int)]
+            branch_append[ix_from, P_FROM] = meas_from.value.values
+            branch_append[ix_from, P_FROM_STD] = meas_from.std_dev.values
+            branch_append[ix_from, P_FROM_IDX] = meas_from.index.values
+            branch_append[ix_to, P_TO] = meas_to.value.values
+            branch_append[ix_to, P_TO_STD] = meas_to.std_dev.values
+            branch_append[ix_to, P_TO_IDX] = meas_to.index.values
+    
+        q_tr_measurements = meas[(meas.measurement_type == "q") & (meas.element_type == "trafo") &
+                                 meas.element.isin(map_trafo)]
+        if len(q_tr_measurements):
+            meas_from = q_tr_measurements[(q_tr_measurements.side.values.astype(int) ==
+                                           net.trafo.hv_bus[q_tr_measurements.element]).values]
+            meas_to = q_tr_measurements[(q_tr_measurements.side.values.astype(int) ==
+                                         net.trafo.lv_bus[q_tr_measurements.element]).values]
+            ix_from = [map_trafo[t] for t in meas_from.element.values.astype(int)]
+            ix_to = [map_trafo[t] for t in meas_to.element.values.astype(int)]
+            branch_append[ix_from, Q_FROM] = meas_from.value.values
+            branch_append[ix_from, Q_FROM_STD] = meas_from.std_dev.values
+            branch_append[ix_from, Q_FROM_IDX] = meas_from.index.values
+            branch_append[ix_to, Q_TO] = meas_to.value.values
+            branch_append[ix_to, Q_TO_STD] = meas_to.std_dev.values
+            branch_append[ix_to, Q_TO_IDX] = meas_to.index.values
         
-    # Add measurements for trafo3w   
-    i_tr3w_measurements = meas[(meas.measurement_type == "i") & (meas.element_type == "trafo3w")]
-    if len(i_tr3w_measurements):
-        meas_hv = i_tr3w_measurements[(i_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.hv_bus[i_tr3w_measurements.element]).values]
-        meas_mv = i_tr3w_measurements[(i_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.mv_bus[i_tr3w_measurements.element]).values]
-        meas_lv = i_tr3w_measurements[(i_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.lv_bus[i_tr3w_measurements.element]).values]
-        ix_hv = [map_trafo3w[t]['hv'] for t in meas_hv.element.values.astype(int)]
-        ix_mv = [map_trafo3w[t]['mv'] for t in meas_mv.element.values.astype(int)]
-        ix_lv = [map_trafo3w[t]['lv'] for t in meas_lv.element.values.astype(int)]
-        i_ka_to_pu_hv = (net.bus.vn_kv[meas_hv.side]).values
-        i_ka_to_pu_mv = (net.bus.vn_kv[meas_mv.side]).values
-        i_ka_to_pu_lv = (net.bus.vn_kv[meas_lv.side]).values
-        branch_append[ix_hv, IM_FROM] = meas_hv.value.values * i_ka_to_pu_hv
-        branch_append[ix_hv, IM_FROM_STD] = meas_hv.std_dev.values * i_ka_to_pu_hv
-        branch_append[ix_hv, IM_FROM_IDX] = meas_hv.index.values
-        branch_append[ix_mv, IM_TO] = meas_mv.value.values * i_ka_to_pu_mv
-        branch_append[ix_mv, IM_TO_STD] = meas_mv.std_dev.values * i_ka_to_pu_mv
-        branch_append[ix_mv, IM_TO_IDX] = meas_mv.index.values
-        branch_append[ix_lv, IM_TO] = meas_lv.value.values * i_ka_to_pu_lv
-        branch_append[ix_lv, IM_TO_STD] = meas_lv.std_dev.values * i_ka_to_pu_lv
-        branch_append[ix_lv, IM_TO_IDX] = meas_lv.index.values
-
-    p_tr3w_measurements = meas[(meas.measurement_type == "p") & (meas.element_type == "trafo3w")]
-    if len(p_tr3w_measurements):
-        meas_hv = p_tr3w_measurements[(p_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.hv_bus[p_tr3w_measurements.element]).values]
-        meas_mv = p_tr3w_measurements[(p_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.mv_bus[p_tr3w_measurements.element]).values]
-        meas_lv = p_tr3w_measurements[(p_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.lv_bus[p_tr3w_measurements.element]).values]
-        ix_hv = [map_trafo3w[t]['hv'] for t in meas_hv.element.values.astype(int)]
-        ix_mv = [map_trafo3w[t]['mv'] for t in meas_mv.element.values.astype(int)]
-        ix_lv = [map_trafo3w[t]['lv'] for t in meas_lv.element.values.astype(int)]
-        branch_append[ix_hv, P_FROM] = meas_hv.value.values
-        branch_append[ix_hv, P_FROM_STD] = meas_hv.std_dev.values
-        branch_append[ix_hv, P_FROM_IDX] = meas_hv.index.values
-        branch_append[ix_mv, P_TO] = meas_mv.value.values
-        branch_append[ix_mv, P_TO_STD] = meas_mv.std_dev.values
-        branch_append[ix_mv, P_TO_IDX] = meas_mv.index.values
-        branch_append[ix_lv, P_TO] = meas_lv.value.values
-        branch_append[ix_lv, P_TO_STD] = meas_lv.std_dev.values
-        branch_append[ix_lv, P_TO_IDX] = meas_lv.index.values
-
-    q_tr3w_measurements = meas[(meas.measurement_type == "q") & (meas.element_type == "trafo3w")]
-    if len(q_tr3w_measurements):
-        meas_hv = q_tr3w_measurements[(q_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.hv_bus[q_tr3w_measurements.element]).values]
-        meas_mv = q_tr3w_measurements[(q_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.mv_bus[q_tr3w_measurements.element]).values]
-        meas_lv = q_tr3w_measurements[(q_tr3w_measurements.side.values.astype(int) ==
-                                       net.trafo3w.lv_bus[q_tr3w_measurements.element]).values]
-        ix_hv = [map_trafo3w[t]['hv'] for t in meas_hv.element.values.astype(int)]
-        ix_mv = [map_trafo3w[t]['mv'] for t in meas_mv.element.values.astype(int)]
-        ix_lv = [map_trafo3w[t]['lv'] for t in meas_lv.element.values.astype(int)]
-        branch_append[ix_hv, Q_FROM] = meas_hv.value.values
-        branch_append[ix_hv, Q_FROM_STD] = meas_hv.std_dev.values
-        branch_append[ix_hv, Q_FROM_IDX] = meas_hv.index.values
-        branch_append[ix_mv, Q_TO] = meas_mv.value.values
-        branch_append[ix_mv, Q_TO_STD] = meas_mv.std_dev.values
-        branch_append[ix_mv, Q_TO_IDX] = meas_mv.index.values
-        branch_append[ix_lv, Q_TO] = meas_lv.value.values
-        branch_append[ix_lv, Q_TO_STD] = meas_lv.std_dev.values
-        branch_append[ix_lv, Q_TO_IDX] = meas_lv.index.values
+    # Add measurements for trafo3w
+    if map_trafo3w is not None:
+        i_tr3w_measurements = meas[(meas.measurement_type == "i") & (meas.element_type == "trafo3w") &
+                                   meas.element.isin(map_trafo3w)]
+        if len(i_tr3w_measurements):
+            meas_hv = i_tr3w_measurements[(i_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.hv_bus[i_tr3w_measurements.element]).values]
+            meas_mv = i_tr3w_measurements[(i_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.mv_bus[i_tr3w_measurements.element]).values]
+            meas_lv = i_tr3w_measurements[(i_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.lv_bus[i_tr3w_measurements.element]).values]
+            ix_hv = [map_trafo3w[t]['hv'] for t in meas_hv.element.values.astype(int)]
+            ix_mv = [map_trafo3w[t]['mv'] for t in meas_mv.element.values.astype(int)]
+            ix_lv = [map_trafo3w[t]['lv'] for t in meas_lv.element.values.astype(int)]
+            i_ka_to_pu_hv = (net.bus.vn_kv[meas_hv.side]).values
+            i_ka_to_pu_mv = (net.bus.vn_kv[meas_mv.side]).values
+            i_ka_to_pu_lv = (net.bus.vn_kv[meas_lv.side]).values
+            branch_append[ix_hv, IM_FROM] = meas_hv.value.values * i_ka_to_pu_hv
+            branch_append[ix_hv, IM_FROM_STD] = meas_hv.std_dev.values * i_ka_to_pu_hv
+            branch_append[ix_hv, IM_FROM_IDX] = meas_hv.index.values
+            branch_append[ix_mv, IM_TO] = meas_mv.value.values * i_ka_to_pu_mv
+            branch_append[ix_mv, IM_TO_STD] = meas_mv.std_dev.values * i_ka_to_pu_mv
+            branch_append[ix_mv, IM_TO_IDX] = meas_mv.index.values
+            branch_append[ix_lv, IM_TO] = meas_lv.value.values * i_ka_to_pu_lv
+            branch_append[ix_lv, IM_TO_STD] = meas_lv.std_dev.values * i_ka_to_pu_lv
+            branch_append[ix_lv, IM_TO_IDX] = meas_lv.index.values
+    
+        p_tr3w_measurements = meas[(meas.measurement_type == "p") & (meas.element_type == "trafo3w") &
+                                   meas.element.isin(map_trafo3w)]
+        if len(p_tr3w_measurements):
+            meas_hv = p_tr3w_measurements[(p_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.hv_bus[p_tr3w_measurements.element]).values]
+            meas_mv = p_tr3w_measurements[(p_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.mv_bus[p_tr3w_measurements.element]).values]
+            meas_lv = p_tr3w_measurements[(p_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.lv_bus[p_tr3w_measurements.element]).values]
+            ix_hv = [map_trafo3w[t]['hv'] for t in meas_hv.element.values.astype(int)]
+            ix_mv = [map_trafo3w[t]['mv'] for t in meas_mv.element.values.astype(int)]
+            ix_lv = [map_trafo3w[t]['lv'] for t in meas_lv.element.values.astype(int)]
+            branch_append[ix_hv, P_FROM] = meas_hv.value.values
+            branch_append[ix_hv, P_FROM_STD] = meas_hv.std_dev.values
+            branch_append[ix_hv, P_FROM_IDX] = meas_hv.index.values
+            branch_append[ix_mv, P_TO] = meas_mv.value.values
+            branch_append[ix_mv, P_TO_STD] = meas_mv.std_dev.values
+            branch_append[ix_mv, P_TO_IDX] = meas_mv.index.values
+            branch_append[ix_lv, P_TO] = meas_lv.value.values
+            branch_append[ix_lv, P_TO_STD] = meas_lv.std_dev.values
+            branch_append[ix_lv, P_TO_IDX] = meas_lv.index.values
+    
+        q_tr3w_measurements = meas[(meas.measurement_type == "q") & (meas.element_type == "trafo3w") &
+                                   meas.element.isin(map_trafo3w)]
+        if len(q_tr3w_measurements):
+            meas_hv = q_tr3w_measurements[(q_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.hv_bus[q_tr3w_measurements.element]).values]
+            meas_mv = q_tr3w_measurements[(q_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.mv_bus[q_tr3w_measurements.element]).values]
+            meas_lv = q_tr3w_measurements[(q_tr3w_measurements.side.values.astype(int) ==
+                                           net.trafo3w.lv_bus[q_tr3w_measurements.element]).values]
+            ix_hv = [map_trafo3w[t]['hv'] for t in meas_hv.element.values.astype(int)]
+            ix_mv = [map_trafo3w[t]['mv'] for t in meas_mv.element.values.astype(int)]
+            ix_lv = [map_trafo3w[t]['lv'] for t in meas_lv.element.values.astype(int)]
+            branch_append[ix_hv, Q_FROM] = meas_hv.value.values
+            branch_append[ix_hv, Q_FROM_STD] = meas_hv.std_dev.values
+            branch_append[ix_hv, Q_FROM_IDX] = meas_hv.index.values
+            branch_append[ix_mv, Q_TO] = meas_mv.value.values
+            branch_append[ix_mv, Q_TO_STD] = meas_mv.std_dev.values
+            branch_append[ix_mv, Q_TO_IDX] = meas_mv.index.values
+            branch_append[ix_lv, Q_TO] = meas_lv.value.values
+            branch_append[ix_lv, Q_TO_STD] = meas_lv.std_dev.values
+            branch_append[ix_lv, Q_TO_IDX] = meas_lv.index.values
 
     ppci["bus"] = np.hstack((ppci["bus"], bus_append))
     ppci["branch"] = np.hstack((ppci["branch"], branch_append))


Test patch:
diff --git a/pandapower/test/estimation/test_wls_estimation.py b/pandapower/test/estimation/test_wls_estimation.py
--- a/pandapower/test/estimation/test_wls_estimation.py
+++ b/pandapower/test/estimation/test_wls_estimation.py
@@ -585,6 +585,49 @@ def test_network_with_trafo3w_pq():
     assert success
     assert (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006)
     assert (np.nanmax(np.abs(net.res_bus.va_degree.values- net.res_bus_est.va_degree.values)) < 0.006)
+    
+
+def test_network_with_trafo3w_with_disabled_branch():
+    net = pp.create_empty_network()
+    
+    bus_slack = pp.create_bus(net, vn_kv=110)
+    pp.create_ext_grid(net, bus=bus_slack)
+    
+    bus_20_1 = pp.create_bus(net, vn_kv=20,name="b")
+    pp.create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02)
+    
+    bus_10_1 = pp.create_bus(net, vn_kv=10)
+    pp.create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02)
+    
+    bus_10_2 = pp.create_bus(net, vn_kv=10)
+    pp.create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01)
+    pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2)
+    disabled_line = pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2)
+    net.line.at[disabled_line, 'in_service'] = False
+    
+    pp.create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV")
+    
+    pp.runpp(net)
+    
+    pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from')
+    pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from')
+    pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to')
+    pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to')
+    
+    pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv')
+    pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv')
+    pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv')
+    pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv')
+    pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv')
+    pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv')
+    
+    pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0)
+    pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1)
+    
+    success = estimate(net)
+    assert success
+    assert (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006)
+    assert (np.nanmax(np.abs(net.res_bus.va_degree.values- net.res_bus_est.va_degree.values)) < 0.006)
 
 
 def r(v=0.03):