Skip to content

fix: report myopic loan costs to the end of the study horizon - #388

Open
inayatku wants to merge 1 commit into
TemoaProject:unstablefrom
inayatku:fix-myopic-loan-cost
Open

inayatku wants to merge 1 commit into
TemoaProject:unstablefrom
inayatku:fix-myopic-loan-cost

Conversation

@inayatku

@inayatku inayatku commented Oct 16, 2026 •

Copy link
Copy Markdown

Fixes #364.

In myopic mode each window is a separate model, so time_future.last() is the end of the window. poll_cost_results() in table_data_puller.py passes that year to loan_cost() as p_e, so the investment costs written to output_cost stop at the end of the window. A technology's costs are written only in the window where it is built, so no later window reports the remaining payments. The total cost of a myopic run in output_objective is the sum of output_cost, so it is too low as well.

Change

  • New parameter myopic_horizon_end. In myopic runs the loader sets it to the last future period of the study, next to myopic_discounting_year. Otherwise it is 0.
  • costs.loan_payment_end() returns it, or time_future.last() outside myopic runs.
  • table_data_puller.py and the economies-of-scale data puller use it for p_e in the reported loan costs.
  • The objective is unchanged: it still uses the window end, as described under "Investment Amortization" in docs/source/myopic.rst. So the model decisions do not change. The last sentence of that paragraph, on output_cost, is updated.

Results on the myopic Utopia test case (view depth 2, periods 1990 to 2020)

before after
sum of d_invest in output_cost 10963.10 11287.05
sum of flow in output_flow_out 673.948 673.948
sum of capacity in output_net_capacity 267.841 267.841

The technologies built in 1990 are solved in the first window, which ends in 2010. They now report loan payments to 2020, not 2010. For example, the undiscounted invest of RHO goes from 2124.65 to 3186.97, which is 30/20 times the old value. The 2000 and 2010 builds are solved in the last window and do not change.

Tests

  • test_myopic_utopia: new expected sum, with a comment. New check: RHO built in 1990 has a 30-year life that ends with the study, and its loan rate equals the global discount rate. So its discounted investment cost must equal built capacity times cost_invest (1633.052). Before the change it was the present value of 20 of the 30 payments, and the test fails on unstable.
  • Full suite on Windows, Python 3.14: all tests pass except smoke_test.py::test_cli and test_help, which time out on this machine without the change too.
  • ruff check, ruff format and mypy temoa pass.

Whether the objective of a window should also count payments to the end of the study is a modeling choice. This PR leaves it as it is.

In myopic mode each window is a separate model, so time_future.last()
is the end of the window. The cost reporting used that year as the end
of loan payments, and no later window reports the remaining payments,
so output_cost and the total cost of a myopic run were too low.

Add myopic_horizon_end, set by the loader in myopic runs to the last
future period of the study, and use it for the reported loan costs.
The objective still uses the window end, as described in the myopic
docs, so the model decisions do not change.

Fixes TemoaProject#364
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: TemoaProject/temoa/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: bb24eb32-6ee2-4bda-9697-014d84237366
📥 Commits

Reviewing files that changed from the base of the PR and between d5148db and 02cb641.

📒 Files selected for processing: 7
  • docs/source/myopic.rst
  • temoa/_internal/table_data_puller.py
  • temoa/components/costs.py
  • temoa/core/model.py
  • temoa/data_io/hybrid_loader.py
  • temoa/extensions/economies_of_scale/core/data_puller.py
  • tests/test_full_runs.py

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

Walkthrough

Myopic runs now retain the full study-horizon end for loan-payment reporting. Cost polling uses that end period, and a full-run test checks reported payments for capacity built in 1990.

Changes

Myopic loan payment reporting

Layer / File(s) Summary
Capture the study-horizon end
temoa/core/model.py, temoa/data_io/hybrid_loader.py
TemoaModel adds myopic_horizon_end, which myopic data loading sets from the maximum future period.
Apply the horizon to loan-payment reporting
temoa/components/costs.py, temoa/_internal/table_data_puller.py, temoa/extensions/economies_of_scale/core/data_puller.py, tests/test_full_runs.py, docs/source/myopic.rst
costs.loan_payment_end returns the full study-horizon end when configured, or the last future period otherwise. Standard and economies-of-scale cost polling use this helper. The full-run test updates the expected investment sum and checks payments for RHO capacity built in 1990. The documentation describes payment reporting through the study horizon.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: particularlypythonicbs, idelder

Merge Risk: ⚪ Minimal · up to 02cb6

Myopic loan-cost reporting now extends through the study horizon, while objective calculations retain their window-end behavior. The updated test checks the extended reporting path; no actionable merge-blocking risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Linked Issues check Warning Issue #364 requires myopic technologies to include loan payments through the planning-horizon end. This PR corrects reported costs in table_data_puller.py and the economies-of-scale puller. However,… Use loan_payment_end(model) or the equivalent study-horizon end for the objective loan-cost calculation in myopic mode. Update objective regression tests and the docs/source/myopic.rst description to match the required behavior.
Passed Passed checks: 4 passed
Check name Status Explanation
Out of Scope Changes check Passed The new myopic_horizon_end parameter, loader assignment, loan-end helper, reporting-puller changes, documentation update, and myopic regression checks all support issue #364 or validate its behavior…
Docstring Coverage Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 6 files. (1 skipped: 1 u…
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: reporting myopic loan costs through the end of the study horizon.
Full details: Out of Scope Changes check

Explanation

The new myopic_horizon_end parameter, loader assignment, loan-end helper, reporting-puller changes, documentation update, and myopic regression checks all support issue #364 or validate its behavior. No unrelated change is established by the reviewed summary or inspected files.

Full details: Docstring Coverage

Explanation

Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 6 files. (1 skipped: 1 unsupported.)

Full details: Linked Issues check

Explanation

Issue #364 requires myopic technologies to include loan payments through the planning-horizon end. This PR corrects reported costs in table_data_puller.py and the economies-of-scale puller. However, period_cost_rule() in temoa/components/costs.py still passes model.time_future.last() to loan_cost(). Therefore, the myopic output_objective calculation still ends at the window boundary. The added test checks output_cost, not the objective requirement.

Resolution

Use loan_payment_end(model) or the equivalent study-horizon end for the objective loan-cost calculation in myopic mode. Update objective regression tests and the docs/source/myopic.rst description to match the required behavior.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

This branch has not been deployed

No deployments
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