Skip to content

Price calculation using dispatch without candidates#1389

Open
tsmbland wants to merge 3 commits into
mainfrom
price_calculation_dispatch_without_candidates
Open

Price calculation using dispatch without candidates#1389
tsmbland wants to merge 3 commits into
mainfrom
price_calculation_dispatch_without_candidates

Conversation

@tsmbland

@tsmbland tsmbland commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Description

Implements the changes discussed in #1364 to line up prices with the flows reported in commodity_flows.csv.

It's a bit fiddly because we now have to pass around both solution_without_candidates and solution_with_candidates when calculating prices (we need the latter for shadow prices and to get activity keys for candidates). I wasn't quite sure about scarcity prices, so I kept it as it was before (using the solution with candidates).

Mostly just small changes to prices in the example models. The only model where this substantially changes results is muse1_default - not really sure why, but I guess no reason that tiny price changes couldn't impact investment decisions. Some of the price changes actually look a bit more substantial in this model compared to others.

Fixes #1364

Type of change

  • Bug fix (non-breaking change to fix an issue)
  • New feature (non-breaking change to add functionality)
  • Refactoring (non-breaking, non-functional change to improve maintainability)
  • Optimization (non-breaking change to speed up the code)
  • Breaking change (whatever its nature)
  • Documentation (improve or add documentation)

Key checklist

  • All tests pass: $ cargo test
  • The documentation builds and looks OK: $ cargo doc
  • Update release notes for the latest release if this PR adds a new feature or fixes a bug
    present in the previous release

Further checks

  • Code is commented, particularly in hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.01887% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.57%. Comparing base (3e9d3b5) to head (8738ce8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/simulation.rs 55.55% 4 Missing and 4 partials ⚠️
src/simulation/prices.rs 97.14% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1389      +/-   ##
==========================================
- Coverage   89.60%   89.57%   -0.04%     
==========================================
  Files          58       58              
  Lines        8338     8351      +13     
  Branches     8338     8351      +13     
==========================================
+ Hits         7471     7480       +9     
- Misses        550      554       +4     
  Partials      317      317              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tsmbland tsmbland marked this pull request as ready for review July 1, 2026 13:36
Copilot AI review requested due to automatic review settings July 1, 2026 13:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns commodity price calculation with the flows reported in commodity_flows.csv by basing cost-derived prices on the “final without candidates” dispatch solution, while still using the “final with candidates” solution for shadow prices (per #1364).

Changes:

  • Split price calculation inputs into solution_without_candidates vs solution_with_candidates and route each pricing strategy to the appropriate source solution.
  • Adjust dispatch-year execution to always compute flows from the “without candidates” run and shadow prices from the “with candidates” run (when candidates exist).
  • Update expected CSV outputs for prices/debug appraisal across example models/tests.

Reviewed changes

Copilot reviewed 22 out of 24 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/simulation.rs Uses separate dispatch runs for flows vs shadow-prices and wires both solutions into pricing.
src/simulation/prices.rs Updates pricing pipeline to accept both dispatch solutions and use the correct one per strategy.
tests/data/two_regions/commodity_prices.csv Updates expected prices to reflect new pricing inputs.
tests/data/simple/debug_appraisal_results.csv Updates expected debug appraisal outputs from dispatch/pricing changes.
tests/data/simple/commodity_prices.csv Updates expected commodity prices for the simple model.
tests/data/simple_shadow/commodity_prices.csv Updates expected commodity prices for the shadow-pricing variant.
tests/data/simple_npv/commodity_prices.csv Updates expected commodity prices for the NPV variant.
tests/data/simple_marginal/commodity_prices.csv Updates expected commodity prices for marginal pricing variant.
tests/data/simple_marginal_average/commodity_prices.csv Updates expected commodity prices for marginal-average variant.
tests/data/simple_ironing_out/commodity_prices.csv Updates expected prices for ironing-out convergence scenario.
tests/data/simple_full/commodity_prices.csv Updates expected prices for full-cost variant.
tests/data/simple_divisible/commodity_prices.csv Updates expected prices for divisible-assets variant.
tests/data/muse1_default/commodity_prices.csv Updates expected prices for the muse1_default example where results change most.
tests/data/muse1_default/assets.csv Removes an asset row consistent with updated scenario outputs.
tests/data/muse1_default/asset_capacities.csv Updates capacities to match revised dispatch/pricing behaviour and asset set.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/simulation.rs
Comment on lines +193 to +203
let prices = match (
solution_existing.as_ref(),
solution_with_candidates.as_ref(),
) {
(None, None) => Prices::default(),
(Some(existing), None) => calculate_prices(model, existing, existing, year)?,
(Some(existing), Some(with_candidates)) => {
calculate_prices(model, existing, with_candidates, year)?
}
(None, Some(_)) => unreachable!("candidates without existing assets"),
};

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True... hadn't thought about having no existing assets in the base year. I guess we should keep the behaviour as it was, but to be honest I'm not sure if the price calculation code is really set up to handle this scenario. Maybe we need a test for this (i.e a model with no existing assets in the base year (and no demand))? Seem to recall at some point that this was something we explicitly wanted to allow

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.

Small discrepancy between prices and reported flows

2 participants