Skip to content

feat(eeio): electricity generation and a delivery sector behind a flag - #1223

Open
WesIngwersen wants to merge 4 commits into
electricity_delivery_splitfrom
electricity_delivery_sector
Open

WesIngwersen wants to merge 4 commits into
electricity_delivery_splitfrom
electricity_delivery_sector

Conversation

@WesIngwersen

@WesIngwersen WesIngwersen commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Closes #1216. Implements most of #1217, which stays open for the time series rerun. Stacked on #1221. Part of the plan in #902.

Adds the flag electricity_delivery_margin, off by default, so no config's output changes. With it on, the model has electricity generation in 221100 and buyer-specific delivery in its own sector, after Step 7. There is no nowcast rebuild, and the 402-sector BEA tables don't change.

What the flag does

Keeps 405 sectors (#1216). 425000 merges into 423A00, and its slot holds delivery. The axes keep the code 425000, because released configs and old snapshots use it, and emission factor tables show 42ELEC. The Excel commodity sheet keeps the code, since it has to match the matrix axes, and changes the name. A permanent code change can come with the release.

Splits electric power (#1217). All in restructure_tables:

Generation (221100) Delivery (slot)
Row: each buyer's bill gen_i delivery_i
Column: fuel, own purchases all none
Column: other inputs the rest FERC share, about 60%
Line losses sells them buys them
Value added what its output leaves what its output leaves
Emissions eGRID SF6
  • FERC share: transmission, distribution and customer costs against other production costs, Table 8.3, by year.
  • Coproduction: the flag also runs reallocate_electricity_coproduction. Electric utilities make $14bn of gas distribution in 2024, and without this it took generation's factor per dollar and rose 62%.
  • Margins: A_margin gets delivery for electricity, and Phi becomes generation over the bill. So the published purchaser-price factor for electricity combines the two.
  • Checks: restructure_tables raises if delivery's value added doesn't fit electric value added, or if generation output isn't positive.

Results with the flag on

Every year builds, 2017-2024. These compare the 2024 model with snapshot c9b69d94.

$bn 2017 2018 2019 2020 2021 2022 2023 2024
Generation output 189 184 180 171 196 231 246 245
Delivery output 274 297 297 295 306 341 331 355
Delivery value added 195 216 217 210 210 228 234 252
Generation value added 89 75 77 86 79 86 122 129
N of generation, kg/$ 10.6 11.2 10.5 9.9 9.4 7.9 6.6 6.6
N of delivery, kg/$ 0.41 0.35 0.35 0.31 0.34 0.29 0.26 0.26

2024:

Total direct emissions 4,812.6 Mt, unchanged
Purchaser-price electricity factor 2.70 kg/$, against 2.65 today
Median change in N +5.2%; industrial +7.6%, commercial +0.8%, rail and transit +1.2%
Sectors above 5% / 10% / 20% 205 / 53 / 2
Largest rises 331410 +25%, 334413 +20%, 331420 +20%
Largest fall 221200 gas distribution -40%
423A00 with brokers merged +9.5%

Gas distribution falls 40% because the coproduction step removes electricity's emissions from it. In today's model, 13% of its output comes from the electric industry at electricity's factor. That is a correction to an existing artefact, and it should be read as one.

Inputs plus value added miss output in some columns, by $0.4-1.7bn for generation and the host. This isn't from the split. With the flag off, about 270 sectors have such a gap in 2024, -$181.8bn in total, and the largest are 523A00 at -$57.6bn and 481000 at -$45.3bn. With the flag on, generation's gap barely moves, the host takes over brokers' gap, and delivery has none. The total moves by $0.35bn, mostly 517110 at -$0.28bn, which isn't explained yet.

Diagnostics: 2024 against snapshot c9b69d94, from 2026_usa_cornerstone_v1_0_electricity_delivery_margin, which differs from the v1.0 config only by this flag.

Time series

IV_score --electricity-delivery-margin runs the IV score with the flag on for every year, and leaves the configs as written. Its span cache and results go to separate folders, so a flag-on run can't replace the tracker's results.

  • stratified_E now moves SF6 and brokers' emissions the same way the model does, through move_delivery_flows.
  • electricity_delivery and sector_disagg_pipeline are now in CACHE_BEARING_MODULES, so each year in a loop gets its own split.

In one run over all years, generation and delivery output match the single-year runs for each year, and 2024 N from the span equals the model's for every sector. Generation scores an IV of 2.36, delivery 0.01 and 423A00 0.02.

Not in this PR

Checks

Unit tests cover the row and column identities, value added, losses, emissions, margins and labels, on synthetic tables. black, ruff and mypy are clean on the changed files. The results above came from local runs of the full model for each year. The suite is left to CI.

🤖 Generated with Claude Code

#1216, #1217)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@WesIngwersen
WesIngwersen added this pull request to stack #1222 November 7, 2026 02:20
WesIngwersen and others added 3 commits November 6, 2026 21:36
…#1217)

Adds --electricity-delivery-margin to IV_score, with its own span cache and
output folder. The time series emissions now move SF6 and brokers the way the
model does, and the delivery split is cleared between years.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Differs from 2026_usa_cornerstone_v1_0 only by electricity_delivery_margin, so
diagnostics measure that change alone. The release config stays as it is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Free a wholesale code for 42ELEC: merge 425000 and keep 405 sectors

1 participant