Repository: e2nIEE/pandapower

Issue:
create_bus_traces  type of infofunc changed?
Did the required type of infofunc for plotting.plotly.create_bus_traces change?

V2.1.0:
`bus_trace['text'] = net.bus.loc[bus_plot_index, 'name'] if infofunc is None else infofunc.loc[buses]`
V2.0.1:
`bus_trace['text'] = net.bus.loc[bus_plot_index, 'name'] if infofunc is None else infofunc`

Docs and comments in code still suggest infofunc should be of type list. Thus it throws following error:
`AttributeError: 'list' object has no attribute 'loc'`



Discussion:

Resolving patch:
diff --git a/pandapower/estimation/ppc_conversion.py b/pandapower/estimation/ppc_conversion.py
--- a/pandapower/estimation/ppc_conversion.py
+++ b/pandapower/estimation/ppc_conversion.py
@@ -130,7 +130,7 @@ def _add_measurements_to_ppci(net, ppci, zero_injection):
         bus_positions = map_bus[p_measurements.element.values.astype(int)]
         unique_bus_positions = np.unique(bus_positions)
         if len(unique_bus_positions) < len(bus_positions):
-            std_logger.info("P Measurement duplication will be automatically merged!")
+            std_logger.debug("P Measurement duplication will be automatically merged!")
             for bus in unique_bus_positions:
                 p_meas_on_bus = p_measurements.iloc[np.argwhere(bus_positions==bus).ravel(), :]
                 bus_append[bus, P] = p_meas_on_bus.value.sum()
@@ -146,7 +146,7 @@ def _add_measurements_to_ppci(net, ppci, zero_injection):
         bus_positions = map_bus[q_measurements.element.values.astype(int)]
         unique_bus_positions = np.unique(bus_positions)
         if len(unique_bus_positions) < len(bus_positions):
-            std_logger.info("Q Measurement duplication will be automatically merged!")
+            std_logger.debug("Q Measurement duplication will be automatically merged!")
             for bus in unique_bus_positions:
                 q_meas_on_bus = q_measurements.iloc[np.argwhere(bus_positions==bus).ravel(), :]
                 bus_append[bus, Q] = q_meas_on_bus.value.sum()
diff --git a/pandapower/file_io.py b/pandapower/file_io.py
--- a/pandapower/file_io.py
+++ b/pandapower/file_io.py
@@ -311,7 +311,7 @@ def from_json(filename, convert=True):
         net = json.load(filename, cls=PPJSONDecoder)
         restore_jsoned_objects(net)
     elif not os.path.isfile(filename):
-        raise UserWarning("File %s does not exist!!" % filename)
+        raise UserWarning("File {} does not exist!!".format(filename))
     else:
         with open(filename) as fp:
             net = json.load(fp, cls=PPJSONDecoder)
diff --git a/pandapower/plotting/plotly/traces.py b/pandapower/plotting/plotly/traces.py
--- a/pandapower/plotting/plotly/traces.py
+++ b/pandapower/plotting/plotly/traces.py
@@ -173,7 +173,7 @@ def create_bus_trace(net, buses=None, size=5, patch_type="circle", color="blue",
     bus_trace['x'], bus_trace['y'] = (net.bus_geodata.loc[bus_plot_index, 'x'].tolist(),
                                       net.bus_geodata.loc[bus_plot_index, 'y'].tolist())
 
-    bus_trace['text'] = net.bus.loc[bus_plot_index, 'name'] if infofunc is None else infofunc.loc[buses]
+    bus_trace['text'] = net.bus.loc[bus_plot_index, 'name'] if infofunc is None else infofunc.loc[buses] if isinstance(infofunc, pd.Series) else infofunc
 
     if legendgroup:
         bus_trace['legendgroup'] = legendgroup
@@ -353,7 +353,7 @@ def create_line_trace(net, lines=None, use_line_geodata=True, respect_switches=F
         if cmap is not None:
             try:
                 line_color = cmap_lines[col_i]
-                line_info = line['name'] if infofunc is None else infofunc.loc[idx]
+                line_info = line['name'] if infofunc is None else infofunc.loc[idx] if isinstance(infofunc, pd.Series) else infofunc
             except IndexError:
                 logger.warning("No color and info for line {:d} (name: {}) available".format(idx, line['name']))
 
@@ -504,7 +504,7 @@ def create_trafo_trace(net, trafos=None, color='green', width=5, infofunc=None,
         trafo_trace = dict(type='scatter', text=[], line=Line(width=width, color=color),
                            hoverinfo='text', mode='lines', name=trace_name)
 
-        trafo_trace['text'] = trafo['name'] if infofunc is None else infofunc.loc[idx]
+        trafo_trace['text'] = trafo['name'] if infofunc is None else infofunc.loc[idx] if isinstance(infofunc, pd.Series) else infofunc
 
         from_bus = net.bus_geodata.loc[trafo.hv_bus, 'x']
         to_bus = net.bus_geodata.loc[trafo.lv_bus, 'x']


Test patch:
diff --git a/pandapower/test/estimation/test_conditions.py b/pandapower/test/estimation/test_conditions.py
new file mode 100644
--- /dev/null
+++ b/pandapower/test/estimation/test_conditions.py
@@ -0,0 +1,39 @@
+import pytest
+from pandapower.estimation import estimate
+from pandapower.test.estimation.test_wls_estimation import create_net_with_bb_switch
+import pandapower as pp
+
+
+def test_none_net():
+    with pytest.raises(UserWarning):
+        estimate(None)
+
+
+def test_nonexistant_alg():
+    with pytest.raises(UserWarning):
+        estimate(None, "superalg")
+
+
+def test_wrong_fuse_setting():
+    grid = create_net_with_bb_switch()
+    with pytest.raises(UserWarning):
+        estimate(grid, fuse_buses_with_bb_switch="no")
+
+
+def test_wrong_init():
+    grid = create_net_with_bb_switch()
+    with pytest.raises(UserWarning):
+        estimate(grid, init="no")
+
+
+def test_wrong_zero_inj():
+    grid = create_net_with_bb_switch()
+    with pytest.raises(UserWarning):
+        estimate(grid, zero_injection="no")
+
+
+def test_no_observability():
+    grid = create_net_with_bb_switch()
+    grid.measurement.drop(grid.measurement.index[int(len(grid.measurement) * 0.1):], inplace=True)
+    with pytest.raises(UserWarning):
+        estimate(grid)
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
@@ -113,6 +113,9 @@ def test_3bus_with_bad_data():
     pp.create_measurement(net, "v", "bus", 1.08, 0.05, 0)  # u1
     pp.create_measurement(net, "v", "bus", 1.015, 0.05, 2)  # u3
 
+    # 0. Do chi2-test for corret data
+    assert not chi2_analysis(net, init='flat')
+
     # 1. Create false voltage measurement for testing bad data detection (-> should be removed)
     pp.create_measurement(net, "v", "bus", 1.3, 0.01, 1)   # V at bus 2
 
@@ -833,7 +836,8 @@ def test_zero_injection_aux_bus():
     
     # in case zero injection was set to none, the results should be different
     assert ~np.allclose(net.res_bus_est.vm_pu.values,net_aux.res_bus_est.vm_pu.values, 1e-2, equal_nan=True)
-    
+
+
 @pytest.mark.xfail
 def test_net_unobserved_island():
     net = pp.create_empty_network()