Skip to content

Audit and update documentation#286

Open
idelder wants to merge 27 commits intoTemoaProject:unstablefrom
idelder:audit_docs
Open

Audit and update documentation#286
idelder wants to merge 27 commits intoTemoaProject:unstablefrom
idelder:audit_docs

Conversation

@idelder
Copy link
Collaborator

@idelder idelder commented Mar 25, 2026

Builds on three commits in the doc_mapping branch (rebased)

A gargantuan opus 4.6 assisted audit of documentation.

  • Update docstrings, definitions, descriptions, etc for outdated index sets, acronyms, etc.
  • Update docstrings for outdated equations
  • Update param and set tables, lists, and descriptions
  • Rewrite Treatment of Time section for considerable changes
  • Rewrite Anatomy of a Constraint section to update for v4 architecture
  • Write a new section on evolving myopic mode

Summary by CodeRabbit

  • New Features

    • Interactive HTML network graph visualization
    • check-units CLI command
    • Myopic "evolving" mode with evolution-script hook
  • Documentation

    • Major reorganization: notation, parameter, and set reference pages added/consolidated
    • Streamlined visualization and quick-start guides; removed DB-vs-model comparison doc
  • Updates

    • Revised mathematical descriptions and indexing across capacity, demand, storage, reserves, emissions, operations, and costs

@coderabbitai
Copy link

coderabbitai bot commented Mar 25, 2026

Walkthrough

Restructures and expands documentation across many rst files, removes one DB-vs-model comparison doc, and updates constraint/math notation and docstrings in multiple component modules; a few component constraint formulas/indexing were adjusted, but public APIs were not changed.

Changes

Cohort / File(s) Summary
Top-level docs & includes
docs/source/Documentation.rst, docs/source/visualization.rst, docs/source/mathematical_formulation.rst
Replaced inline sections with includes and reorganized notation/time treatment and visualization guidance (interactive HTML + Graphviz); adjusted many displayed formulas and formatting.
New reference pages
docs/source/param_desc_and_tables.rst, docs/source/set_desc_and_tables.rst
Added comprehensive parameter and set reference pages with CSV tables mapping DB → model → code and lists of model-computed parameters.
Computational implementation & quick start
docs/source/computational_implementation.rst, docs/source/quick_start.rst, docs/source/unit_checking.rst
Rewrote demand-constraint documentation and Pyomo examples (index/sig changes); updated CLI/config snippets and unit-checking example config/file reference.
Deleted doc
docs/source/db_model_comparison.rst
Removed the entire DB-vs-model comparison document and its CSV tables.
Visualization include in top doc
docs/source/Documentation.rst
Replaced inline “Network Diagrams” subsection with .. include:: visualization.rst.
Myopic docs
docs/source/myopic.rst
Added [myopic] options (evolving, evolution_script) and documented the iterate() evolution-script contract and behavior.
Capacity component
temoa/components/capacity.py
Adjusted capacity constraint indexing to period-vintage CAP_{r,p,t,v} and changed annual-capacity constraint relation to a lower bound (doc/code update).
Commodities / demand logic
temoa/components/commodities.py
Reformulated demand constraint to annual equality over {r,p,dem} using v_flow_out_annual sums; removed slice-level FO/DSD coupling in documentation and examples; updated commodity-balance annual term to use FOA directly.
Costs & emissions
temoa/components/costs.py, temoa/components/emissions.py
Fixed EAC index ordering in cost summations; updated linked-emissions docstring/LaTeX labels and explanatory math (no signature changes).
Constraint docstring/math updates
temoa/components/limits.py, temoa/components/operations.py, temoa/components/reserves.py, temoa/components/storage.py
Extensive LaTeX/docstring revisions: switched many displayed terms to period-indexed CAP, replaced CAPAVL with CAP, updated ramp/rate/ΔH/SEG/SFS notation, revised reserve and storage seasonal-scaling expressions (doc-only changes).

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Audit and update documentation' is partially related to the changeset. It describes a real aspect of the change (documentation updates), but is overly broad and does not clearly specify the main scope or nature of the documentation audit. Consider using a more specific title that indicates the scope of changes, such as 'Audit and update documentation for v4.6 architecture changes' or 'Update constraint formulations and parameter documentation'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
temoa/components/capacity.py (1)

396-403: ⚠️ Potential issue | 🟠 Major

Document the missing capacity_constraint() branches.

Line 402 now scopes CapacityAnnual to all T^a, but capacity_annual_constraint_indices() excludes tech_demand, and Lines 448-459 still constrain those annual demand technologies via scaled v_flow_out_annual. The adjacent Capacity block only shows the FO (+ CUR) equality, so neither that FOA branch nor the default >= branch appears in the audited formulation.

Also applies to: 431-440

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@temoa/components/capacity.py` around lines 396 - 403, The
capacity_constraint() implementation is missing branches for the annual-capacity
cases noted: update capacity_constraint() to handle the CapacityAnnual index set
returned by capacity_annual_constraint_indices() and include the FOA branch
(flow-out-annual) and the default >= branch for annual technologies
(tech_demand) that were previously excluded; specifically, add logic mirroring
the Capacity block's FO (+ CUR) equality for the non-annual case and add a FOA
handling path that enforces sum_{I,O} FOA_{r,p,i,t∈T^a,v,o} <= C2A_{r,t} *
CAP_{r,p,t,v} (or the intended >= direction per model sign) when the index
belongs to CapacityAnnual, and ensure capacity_annual_constraint_indices() and
capacity_constraint() use the same membership test so tech_demand entries are
consistently included.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@temoa/components/limits.py`:
- Around line 334-338: The displayed Limit Activity Share formula currently sums
only FO (mathbf{FO}_{...}) while the implementation includes the annual flow
term v_flow_out_annual (FOA); update the math notation in the Limit Activity
Share expression to either: (a) add the FOA term to both numerator and
denominator (e.g., include \mathbf{FOA}_{r,p,s,d,i,t,v,o} or v_flow_out_annual
in the summed terms alongside \mathbf{FO}), or (b) explicitly restrict the
summation index to t \notin T^a (make clear the scope T^{g_1}, T^{g_2} exclude
T^a) so the displayed formula matches the code that omits annual flows;
reference the LAS_{r,p,g_1,g_2}, \mathbf{FO}_{...}, v_flow_out_annual (FOA) and
T^a/T^{g_1}/T^{g_2} symbols when making the change.

In `@temoa/components/reserves.py`:
- Around line 80-85: The reserve-margin annual-term currently multiplies all
annual FOA generation by DSD_{r,s,d,o}, but per the model the non-demand annual
outputs should use segment_fraction instead; update the reserve equations in
reserves.py so that for FOA terms you use DSD_{r,s,d,o}·FOA only when the output
o is a demand output (i.e., when using demand_specific_distribution), and use
segment_fraction_{r,s,d,o}·FOA for annual outputs that are not demand-serving;
adjust the logic around the FOA/FO terms where demand_specific_distribution and
segment_fraction are applied so both demand and non-demand annual reserve
providers are handled correctly.

---

Outside diff comments:
In `@temoa/components/capacity.py`:
- Around line 396-403: The capacity_constraint() implementation is missing
branches for the annual-capacity cases noted: update capacity_constraint() to
handle the CapacityAnnual index set returned by
capacity_annual_constraint_indices() and include the FOA branch
(flow-out-annual) and the default >= branch for annual technologies
(tech_demand) that were previously excluded; specifically, add logic mirroring
the Capacity block's FO (+ CUR) equality for the non-annual case and add a FOA
handling path that enforces sum_{I,O} FOA_{r,p,i,t∈T^a,v,o} <= C2A_{r,t} *
CAP_{r,p,t,v} (or the intended >= direction per model sign) when the index
belongs to CapacityAnnual, and ensure capacity_annual_constraint_indices() and
capacity_constraint() use the same membership test so tech_demand entries are
consistently included.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3482b223-8d87-4b0d-845b-a30c4bd08386

📥 Commits

Reviewing files that changed from the base of the PR and between cb703e5 and ee32a17.

📒 Files selected for processing (17)
  • docs/source/Documentation.rst
  • docs/source/computational_implementation.rst
  • docs/source/db_model_comparison.rst
  • docs/source/mathematical_formulation.rst
  • docs/source/param_desc_and_tables.rst
  • docs/source/quick_start.rst
  • docs/source/set_desc_and_tables.rst
  • docs/source/unit_checking.rst
  • docs/source/visualization.rst
  • temoa/components/capacity.py
  • temoa/components/commodities.py
  • temoa/components/costs.py
  • temoa/components/emissions.py
  • temoa/components/limits.py
  • temoa/components/operations.py
  • temoa/components/reserves.py
  • temoa/components/storage.py
💤 Files with no reviewable changes (1)
  • docs/source/db_model_comparison.rst

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/source/myopic.rst`:
- Around line 111-114: Update the docs to state that last_instance_status may be
None on the first iteration: modify the description for last_instance_status in
docs to mention it can be None (type str | None) in addition to 'optimal' and
'roll_back', and reference the initializer in myopic_sequencer.py where
last_instance_status is set to None; keep the existing text about 'optimal' and
'roll_back' but append a note that on the initial iteration last_instance_status
== None.
- Line 39: Change the self.evolving assignment in the MyopicSequencer class so
it never becomes None by using myopic_options.get('evolving', False) (i.e.,
replace self.evolving: bool = myopic_options.get('evolving') with
myopic_options.get('evolving', False)), and then align the type annotation
accordingly (prefer keeping it as bool if you supply the default; if you
intentionally want to allow None, change the annotation to bool | None instead).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f985fd63-9ffe-4779-9a5e-a2aa609989c7

📥 Commits

Reviewing files that changed from the base of the PR and between ee32a17 and 3964304.

📒 Files selected for processing (3)
  • docs/source/myopic.rst
  • temoa/components/limits.py
  • temoa/components/reserves.py

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/source/computational_implementation.rst`:
- Around line 144-147: The text incorrectly calls the sum(...) usage a "list
comprehension" — it is a generator expression; update the wording around the
example (mentioning sum(...)) to refer to a "generator expression" instead of
"list comprehension", and briefly note that generator expressions produce an
iterator evaluated lazily (unlike list comprehensions which build a list) to
keep the Python terminology precise in the computational_implementation.rst
teaching section.
- Around line 122-123: Update the documentation to use the correct set name
`regions` (not `region`) wherever the text refers to the first index coming from
the set; replace occurrences like :code:`region` with :code:`regions` in the
sentences that describe index origins (e.g., the phrase "the first index comes
from :code:`region`"), and make the same plural correction at the other
occurrence noted (the later paragraph referencing the same index mapping).
Ensure the rest of the set names (`time_optimize`, `commodity_demand`) are left
unchanged.
- Around line 211-233: The docs refer to self.demand_constraint_rpc and
self.demand as if those are the model index names but the actual model uses
self.n for the regions * time_optimize * commodity_demand index and declares
self.demand = Param(self.n); update the narrative and any loader-mapping
examples (including the HybridLoader snippet mentioned) to use the correct
symbol self.n everywhere (and remove or rename references to
demand_constraint_rpc) so the documentation matches the actual TemoaModel
declarations (e.g., adjust the loader mapping lines that currently reference
demand_constraint_rpc to reference self.n and confirm self.demand =
Param(self.n) is shown).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9c38203e-2084-401b-a251-5948934e0d6a

📥 Commits

Reviewing files that changed from the base of the PR and between 3964304 and b0848e5.

📒 Files selected for processing (1)
  • docs/source/computational_implementation.rst

Comment on lines 122 to +123
will be an item from :code:`region`, the second from :code:`time_optimize`,
the third from :code:`time_season`, fourth from :code:`time_of_day`, and the
fifth from :code:`commodity_demand`. Though one could choose :code:`a`, :code:`b`,
:code:`c`, :code:`d`, and :code:`e` (or any naming scheme), we chose :code:`p`, :code:`s`,
:code:`d`, and :code:`dem` as part of a :ref:`naming scheme
and the third from :code:`commodity_demand`. Though one could choose :code:`a`,
Copy link

@coderabbitai coderabbitai bot Mar 26, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Set name should be regions, not region.

The narrative says the first index comes from region, but the model set is regions. Please make this consistent with the actual set naming used throughout the model docs/examples.

Also applies to: 320-321

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/source/computational_implementation.rst` around lines 122 - 123, Update
the documentation to use the correct set name `regions` (not `region`) wherever
the text refers to the first index coming from the set; replace occurrences like
:code:`region` with :code:`regions` in the sentences that describe index origins
(e.g., the phrase "the first index comes from :code:`region`"), and make the
same plural correction at the other occurrence noted (the later paragraph
referencing the same index mapping). Ensure the rest of the set names
(`time_optimize`, `commodity_demand`) are left unchanged.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

live with it

Copy link

Choose a reason for hiding this comment

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

@idelder, understood — I'll leave it as-is. Thanks for the clarification!


🧠 Learnings used
Learnt from: idelder
Repo: TemoaProject/temoa PR: 277
File: temoa/model_checking/network_model_data.py:357-361
Timestamp: 2026-03-16T18:27:06.688Z
Learning: In TemoaProject/temoa, `NetworkModelData.demand_commodities` in `temoa/model_checking/network_model_data.py` is used only as a starting-node set for the commodity network sweep, not as a validation or filter set. Having extra period keys outside the myopic window is harmless because `available_techs` is already strictly filtered to the active myopic periods; unreachable demand entries are simply ignored during the sweep. Do not flag unfiltered demand_commodities in myopic mode as a correctness issue.

Comment on lines +144 to 147
Lines 5 through 9 also showcase a very common idiom in Python:
list-comprehension. List comprehension is a concise and efficient syntax to
create lists. As opposed to building a list element-by-element with for-loops,
list comprehension can convert many statements into a single operation.
Copy link

@coderabbitai coderabbitai bot Mar 26, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

This is a generator expression, not a list comprehension.

The shown sum(...) form is using a generator expression. Please update wording to keep the Python terminology precise in this teaching section.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/source/computational_implementation.rst` around lines 144 - 147, The
text incorrectly calls the sum(...) usage a "list comprehension" — it is a
generator expression; update the wording around the example (mentioning
sum(...)) to refer to a "generator expression" instead of "list comprehension",
and briefly note that generator expressions produce an iterator evaluated lazily
(unlike list comprehensions which build a list) to keep the Python terminology
precise in the computational_implementation.rst teaching section.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm tapping out

Copy link

Choose a reason for hiding this comment

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

@idelder, no worries — understood! I'll drop this one. Thanks for all the documentation work in this PR.


🧠 Learnings used
Learnt from: idelder
Repo: TemoaProject/temoa PR: 277
File: temoa/model_checking/network_model_data.py:357-361
Timestamp: 2026-03-16T18:27:06.688Z
Learning: In TemoaProject/temoa, `NetworkModelData.demand_commodities` in `temoa/model_checking/network_model_data.py` is used only as a starting-node set for the commodity network sweep, not as a validation or filter set. Having extra period keys outside the myopic window is harmless because `available_techs` is already strictly filtered to the active myopic periods; unreachable demand entries are simply ignored during the sweep. Do not flag unfiltered demand_commodities in myopic mode as a correctness issue.

Comment on lines +211 to +233
self.demand_constraint_rpc = Set(
within=self.regions * self.time_optimize * self.commodity_demand
)
self.demand = Param(self.demand_constraint_rpc)

...

self.demand_constraint = Constraint(
self.demand_constraint_rpc, rule=commodities.demand_constraint
)


As discussed above, the demand_constraint is only valid for certain
:math:`\{r, p, s, d, dem\}` tuples. Since the modeler can specify the demand
distribution per commodity (necessary to model demands like heating, that do not
apply in all time slices), Temoa must ascertain the valid tuples. We have
implemented this logic in the function :code:`demand_constraint_indices` in
``temoa/components/technology.py``. Thus, Line 1 tells Pyomo to instantiate
:code:`demand_constraint_rpsdc` as a Set of 5-length tuples indices
(:code:`dimen=5`), and populate it with what Temoa's rule
:code:`demand_constraint_indices` returns. We omit here an explanation of the
implementation of the :code:`demand_constraint_indices` function, stating merely
that it returns the exact indices over which the demand_constraint must to be
created. With the sparse set :code:`demand_constraint_rpsdc` created, we can now
can use it in place of the five sets specified in the non-sparse
:math:`\{r, p, dem\}` tuples. Since not all combinations of region, period, and
demand commodity may be valid, Temoa must ascertain the valid tuples.
Thus, Line 1 tells Pyomo to instantiate
:code:`demand_constraint_rpc` as a Set of 3-length tuple indices
within the dimensions of the :code:`regions`, :code:`time_optimize`, and
:code:`commodity_demand` sets, and populate it only with entries loaded from
the database. Demand values are stored in the parameter :code:`self.demand` declared in line 4.
Data from the database is loaded into this index set and parameter via the
:code:`HybridLoader` class in :code:`temoa/data_io/hybrid_loader.py`, declared in
the :code:`component_manifest.py` file.
Copy link

@coderabbitai coderabbitai bot Mar 26, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use the actual demand index set name from TemoaModel (self.n) in this section.

This section documents self.demand_constraint_rpc, but the current model definition uses self.n for regions * time_optimize * commodity_demand and defines self.demand = Param(self.n). Please align the names here (and in the loader mapping snippet) with temoa/core/model.py to avoid misleading implementation guidance.

Also applies to: 240-247

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/source/computational_implementation.rst` around lines 211 - 233, The
docs refer to self.demand_constraint_rpc and self.demand as if those are the
model index names but the actual model uses self.n for the regions *
time_optimize * commodity_demand index and declares self.demand = Param(self.n);
update the narrative and any loader-mapping examples (including the HybridLoader
snippet mentioned) to use the correct symbol self.n everywhere (and remove or
rename references to demand_constraint_rpc) so the documentation matches the
actual TemoaModel declarations (e.g., adjust the loader mapping lines that
currently reference demand_constraint_rpc to reference self.n and confirm
self.demand = Param(self.n) is shown).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

wat

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

Let me check the actual model code before saying anything further.


🏁 Script executed:

#!/bin/bash
rg -n "demand_constraint_rpc|demand_constraint_rpsdc|self\.demand\s*=" temoa/core/model.py -A2 -B2

Length of output: 574


@idelder, apologies — my original review comment was incorrect. I checked temoa/core/model.py and the actual definitions are exactly as the documentation states:

  • self.demand_constraint_rpc is the real index set name (Line 370)
  • self.demand = Param(self.demand_constraint_rpc) is the real parameter declaration (Line 373)

There is no self.n anywhere. The documentation accurately reflects the code. I should not have flagged this. Sorry for the noise!


🧠 Learnings used
Learnt from: idelder
Repo: TemoaProject/temoa PR: 277
File: temoa/model_checking/network_model_data.py:357-361
Timestamp: 2026-03-16T18:27:06.688Z
Learning: In TemoaProject/temoa, `NetworkModelData.demand_commodities` in `temoa/model_checking/network_model_data.py` is used only as a starting-node set for the commodity network sweep, not as a validation or filter set. Having extra period keys outside the myopic window is harmless because `available_techs` is already strictly filtered to the active myopic periods; unreachable demand entries are simply ignored during the sweep. Do not flag unfiltered demand_commodities in myopic mode as a correctness issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants