SLD readability & loading coherence on PyPSA grids (3 fixes)#180
Merged
Conversation
Three related fixes for the SLD overlay on the PyPSA-EUR grids, where equipment carries both a raw IIDM id (relation_8423569-225) and a friendly operator name (MARSIL61PRAGN): 1. Feeders labelled by the far-end voltage level. Every SLD endpoint now returns a `feeder_labels` map (build_feeder_labels) and the frontend relabels each branch feeder with the name of the VL at the OTHER end of the line (e.g. "MARSILLON 225kV") instead of the raw IIDM branch id, keeping a 1/2 index for parallel circuits. Falls back to the branch's own name, then the raw id, so already-readable grids are untouched. 2. Overload halo on the extremity SLD. The N-1 overload halo was missing because the overload list uses grid2op friendly names while the SLD cells are keyed by IIDM id; the feeder_labels `name` now bridges the two so the halo lands on the right feeder. 3. Disconnected-overload loading coherence. When an action disconnects the overloaded line itself, the card showed a stale grid2op loading (e.g. 33 %) while the SLD/NAD correctly drew zero flow. compute_action_metrics now reads connectivity from the post-action pypowsybl variant (build_branch_connectivity / disconnected_branch_names_from_obs) and reports 0 % for disconnected branches, so card and diagrams agree. The two large SLD label passes (feeder relabel + injection name buttons) were extracted into hooks/utils to keep SldOverlay under the LoC ceiling. Tests: feeder labels, branch connectivity, disconnected-overload zeroing (backend); feeder relabel + friendly-name overload halo (frontend). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TXqGodvLG69petEgm4GPrR
Follow-up to the SLD readability work. The "33% loading after disconnecting the overloaded line" turned out NOT to be a bug: reproducing the exact scenario against expert_op4grid_recommender's PypowsyblObservation on the real grid showed the line, once opened at one end, carries i1≈43A with q1≈-16.8 MVAr and p1=0 — i.e. real reactive CHARGING current of a line whose capacitance stays energised from the live end. rho = 43/130 ≈ 33% is therefore physically correct; the diagrams just show active power (p=0). So instead of suppressing the value we keep it and explain it: - Revert the compute_action_metrics zeroing and its build_branch_connectivity / disconnected_branch_names_from_obs helpers. - Add build_half_open_reactive / half_open_branch_reactive_from_obs / half_open_overload_notes: for a still-"overloaded" line left open at one end with loading >1%, capture the live-end reactive power (MVAr). - simulate_manual_action attaches it as `half_open_overloads` on the result (serialized + carried through the save/reload triad). - ActionCard annotates the loading: "open one end · 16.8 MVAr capacitive", with a tooltip explaining it is charging current, not real flow. The recommender library is correct and was left unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TXqGodvLG69petEgm4GPrR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three coordinated fixes for the Single Line Diagram on PyPSA-EUR grids, where equipment carries both a raw IIDM id (
relation_8423569-225) and a friendly operator name (MARSIL61PRAGN). These changes make the SLD honest and readable while fixing overload-halo visibility and explaining the physics of half-open lines.Key Changes
1. Feeders labelled by far-end voltage level (Issue 1)
build_feeder_labels(network, vl_id)insld_render.pythat returns{equipment_id: {name, other_vl, label}}for every line/2-winding transformer touching a voltage levellabel= far-end VL friendly name, disambiguated with 1-based index for parallel circuits (LANNEMEZAN 225kV 1/… 2)_vl_name_map()and_collect_vl_branches()with defensive exception handlinguseSldFeederRelabel+ utilityapplyFeederRelabels()inutils/svg/feederLabels.tsthat swaps matching<text>content, idempotently restoring on tab/VL switchtest_feeder_labels.pycovering single/parallel branches, unnamed far-ends, and fallback logic2. Overload halo now visible on extremity SLD (Issue 2)
MARSIL61PRAGN) but SLD cells are keyed by IIDM id (relation_8423569-225) — direct lookup missedbuildFriendlyToEquip()andoverloadCandidates()infeederLabels.tsbridge friendly name → IIDM id via thefeeder_labelsmapSldOverlay.tsxoverload-highlight pass to resolve through the bridge beforefindCellForEquipment, with fallback to raw value (covers id-keyed overload lists)SldOverlay.test.tsxverifying halo lands on correct feeder when friendly name is mapped3. Annotate charging-current loading of half-open lines (Issue 3)
build_half_open_reactive(network)insimulation_helpers.pyreturns{branch_id_or_name: live_end_reactive_mvar}for lines/transformers open at exactly one terminalrhoreads non-zero (e.g. ~33%) — not a bug, but easy to misread as residual overloadhalf_open_overload_notes()insimulation_helpers.pygates annotation to lines still "overloaded" (loading > ~1%) after action, returning reactive power for UI explanationhalf_open_branch_reactive_from_obs()insimulation_helpers.pyreads post-action variant via network manager, with proper variant restorationActionCard.tsxto display annotation whenhalf_open_overloadspresent, explaining the loading as charging currenthalf_open_overloads?: Record<string, number>toActionDetailinterfacetest_half_open_overload.pycovering variant switching, reactive power extraction, and annotation gatingImplementation Details
https://claude.ai/code/session_01TXqGodvLG69petEgm4GPrR