Skip to content

Write a Sienna investments portfolio from an expansion plan - #20

Open
thomaschristopherking wants to merge 1 commit into
issue-116-plexos-constraints-sidecarfrom
issue-116-write-sienna-investments-portfolio
Open

Write a Sienna investments portfolio from an expansion plan#20
thomaschristopherking wants to merge 1 commit into
issue-116-plexos-constraints-sidecarfrom
issue-116-write-sienna-investments-portfolio

Conversation

@thomaschristopherking

@thomaschristopherking thomaschristopherking commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

TL;DR

The parts below this one carry a PLEXOS expansion plan as far as PyPSA and no further: there
was no Sienna investments vocabulary, no translation, no sink and no pipeline, so an extendable
network had nowhere to go. plexos-to-sienna-investments now writes a SiennaSchemas
PortfolioDocument beside the operations system it expands, and pypsa-to-sienna-investments
does the same for a PyPSA network that states its own expansion.

Fourth of five for transition-zero/tz-infra-interop#116,
stacked on #19. The fifth adds the AEMO case study.

Files to review (30, +4383 / -27):

File Why
docs/translation_mappings/translation-from-plexos-to-sienna-investments.md (start here) The whole mapping in PLEXOS words, and where the hub loses something.
interop/plugins/shared/sienna_investments_constants.py (new) The Investments vocabulary, which the repository had none of.
interop/plugins/steps/pypsa_to_sienna_investments_map_technologies.py (new) Every candidate becomes a technology, a requirement or an attribute.
interop/plugins/shared/pypsa_sienna_investments_translations/_supply.py (new) A SupplyTechnology: capital cost, operation cost, capacity limits.
interop/plugins/shared/pypsa_sienna_investments_translations/_carbon_caps.py (new) A carbon cap read out of the constraint sidecar part 3 fills.
interop/plugins/sinks/emit_sienna_portfolio.py (new) Writes the PortfolioDocument beside the operations system.
tests/features/pypsa_to_sienna_investments/portfolio.feature (new) Every field of every portfolio component.

Why

SiennaSchemas Investments/ is a separate, parallel data model rather than an extension of
Operations: its spatial unit is a region, its components are buildable technologies, and it
carries policy requirements and financials that Operations has no home for. An extendable PyPSA
network maps onto it and onto nothing in Operations, so without this the expansion plan reached
PyPSA and stopped.

How

Each extendable component becomes a technology. A generator becomes a SupplyTechnology,
a storage unit a StorageTechnology, and each carries its capital cost, its operation cost,
its capacity limits, its lifetime and its financial data. The base-system devices a technology
stands for become its existing fleet, with the build year off the network and the retirement
year off the sidecar.

The rest of the document comes from beside the components. A carbon cap comes from the
constraint records part 3 carries, the regions from the bus-to-area mapping, the demand from
the loads, and the financials from one base year the user states because no PyPSA field
carries one.

yearly_fixed_charge is the one place the two pipelines differ. Sienna's
operation_costs.fixed is a yearly charge; PyPSA's fom_cost is a charge for the whole
modelled horizon. A network this translator wrote carries the yearly figure in the sidecar, so
the portfolio reads that; a network a user wrote states fom_cost alone, so it falls back to
that.

Reviewer notes

  • This is the largest part, and it is one format. The vocabulary, the eight translation
    modules, the step and the sink arrive together because a reviewer reading "what does a
    portfolio look like" wants the whole document. It splits further if you would rather have a
    skeleton first: the vocabulary, sink and two technology types in one PR, then the
    requirements and attributes in a second.
  • A portfolio is written beside an operations system, not instead of it.
    plexos-to-sienna-investments runs the operations steps and the investments steps over one
    model and writes both documents, which is why part 1's candidate drop matters: without it the
    base system would contain the candidates the portfolio is about.
  • Focus area: pypsa_to_sienna_investments_map_technologies.py is 635 lines and
    orchestrates every table. I would like a second opinion on whether the existing-fleet and
    supplemental-attribute paths belong in it or in modules of their own.

Tests

638 scenarios pass, and all 17 pre-commit hooks.

uv run pytest -q

Open workspace in Conductor

The parts below this one carry a PLEXOS expansion plan as far as PyPSA and no
further. There was no Sienna investments vocabulary, no translation, no sink and
no pipeline, so an extendable network had nowhere to go.

`plexos-to-sienna-investments` writes a SiennaSchemas `PortfolioDocument` beside
the operations system it expands, and `pypsa-to-sienna-investments` does the same
for a PyPSA network that states its own expansion. Each extendable component
becomes a `SupplyTechnology` or a `StorageTechnology` carrying its capital cost,
its operation cost, its capacity limits and its financial data. The base-system
devices a technology stands for become its existing fleet, a carbon cap from the
constraint sidecar becomes a `CarbonCaps` requirement, and the regions, demand
and financials fill the rest of the document.

`yearly_fixed_charge` reads the yearly fixed charge from the extensions sidecar
where a PLEXOS model stated one, and falls back to `fom_cost` for a network a user
wrote themselves. Sienna's `operation_costs.fixed` is yearly, and PyPSA's
`fom_cost` is a charge for the whole modelled horizon, so the two are not the same
number.

Signed-off-by: Thomas C. King <thomas.k@transitionzero.org>
@thomaschristopherking
thomaschristopherking requested a review from a team as a code owner September 11, 2026 09:24
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 130db0e0-f155-4764-b3d2-5f1a8267fe52

📥 Commits

Reviewing files that changed from the base of the PR and between 44548a9 and fffff65.

📒 Files selected for processing (30)
  • docs/translation_mappings/translation-from-plexos-to-sienna-investments.md
  • docs/translation_mappings/translation-from-pypsa-to-sienna.md
  • interop/pipelines/plexos-to-sienna-investments.yaml
  • interop/pipelines/pypsa-to-sienna-investments.yaml
  • interop/plugins/shared/pypsa_sienna_investments_translations/__init__.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_associations.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_carbon_caps.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_demand.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_existing.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_financials.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_shared.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_storage.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_supply.py
  • interop/plugins/shared/pypsa_sienna_investments_translations/_topology.py
  • interop/plugins/shared/sienna_constants.py
  • interop/plugins/shared/sienna_investments_constants.py
  • interop/plugins/sinks/_sienna_files.py
  • interop/plugins/sinks/emit_sienna_portfolio.py
  • interop/plugins/sinks/emit_sienna_system_json.py
  • interop/plugins/steps/pypsa_to_sienna_investments_map_technologies.py
  • libs/interop-testing/src/interop_testing/builders/sienna_documents.py
  • libs/interop-testing/src/interop_testing/steps/__init__.py
  • libs/interop-testing/src/interop_testing/steps/pypsa_network/build_network.py
  • libs/interop-testing/src/interop_testing/steps/sienna_portfolio.py
  • libs/interop-testing/src/interop_testing/steps/sienna_system.py
  • tests/features/plexos_to_sienna_investments.feature
  • tests/features/pypsa_to_sienna_investments/portfolio.feature
  • tests/step_defs/pypsa_to_sienna_investments/conftest.py
  • tests/step_defs/pypsa_to_sienna_investments/test_portfolio.py
  • tests/step_defs/test_plexos_to_sienna_investments.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant