Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
ac4e193
test(bounds): add optest4 to verify complex bounds with non-trivial t…
claude Apr 8, 2026
b35d1b8
test(bounds): rework optest4 with 2 scenarios and genuine time+scenar…
claude Apr 8, 2026
c699708
expected results
aoustry Apr 8, 2026
a6af2e9
add test
aoustry Apr 8, 2026
24ec8cb
Refactor to vectorized linopy solver and remove OR-Tools dependency (#1)
tbittar Apr 8, 2026
a616ff4
Fix/merge conflict (#25)
tbittar Apr 8, 2026
2707bf8
Added performance tests of optimization problem building with simple …
Apr 8, 2026
5fe1345
Merge pull request #27 from tbittar/performance-tests
YassineAbdelouadoud Apr 8, 2026
cd53620
Merge pull request #22 from tbittar/claude/issue-9-refactor-98UMY
aoustry Apr 8, 2026
05e83ed
Remove test for time-dependent bounds in model behaviour
aoustry Apr 8, 2026
7a04fa8
Build simulation table from linopy problem
tbittar Apr 8, 2026
65a129a
Fix tests
tbittar Apr 8, 2026
a437e2a
Remove dead dependencies: antares_craft and scipy
claude Apr 8, 2026
52e4cdd
Remove dead code: ProblemVar/Param nodes and operators_expansion pipe…
claude Apr 8, 2026
5ce94bf
Merge pull request #32 from tbittar/claude/remove-dead-dependencies-y…
aoustry Apr 8, 2026
330b921
Merge pull request #31 from tbittar/claude/remove-dead-code-UJG5x
aoustry Apr 8, 2026
48be671
Merge pull request #29 from tbittar/feature/export-simulation-table
aoustry Apr 8, 2026
ebf8a3b
Fix missing and undeclared production dependencies
claude Apr 8, 2026
05be325
Replace OutputValues with SimulationTable across codebase
claude Apr 8, 2026
0194ee8
Added vectorized call of param_data.get_value in _build_param_arrays_…
Apr 8, 2026
7284b1b
Apply black==23.7.0 formatting to modified files
claude Apr 8, 2026
937f82a
Merge pull request #36 from tbittar/claude/check-dead-dependencies-a4CxO
aoustry Apr 8, 2026
6f45261
Merge pull request #37 from tbittar/claude/replace-outputvalues-simul…
aoustry Apr 8, 2026
df04aae
Fix/clear trajectory investment (#38)
tbittar Apr 8, 2026
c975595
Remove ComponentParameterNode/ComponentVariableNode and output_values…
aoustry Apr 9, 2026
c4eaba4
fix: resolve all mypy type errors across 5 files
Apr 9, 2026
c4042cc
fixed formatting issues in data.py
Apr 9, 2026
27e10d1
Remove objective_operational_contribution and objective_investment_co…
tbittar Apr 9, 2026
fa005de
Enforce model id uniqueness (#44)
tbittar Apr 9, 2026
43a3b30
Use lid_id.model_id (#46)
tbittar Apr 9, 2026
9ca30cf
fixed issue in linopy_problem.py when use_time and use_scenario are a…
Apr 9, 2026
b8c51be
Merge branch 'main' into 20-improve-building-of-parameters-array-for-…
tbittar Apr 9, 2026
bb10735
fixed wrong comments anr removed CLAUDE.md
Apr 9, 2026
9a9539c
Merge pull request #45 from tbittar/20-improve-building-of-parameters…
aoustry Apr 9, 2026
821ebc9
Remove dead code in gems/expression and gems/simulation
claude Apr 9, 2026
4d78f4f
refactor: extract VectorizedBuilderBase to eliminate duplicated visit…
claude Apr 9, 2026
c72a4ca
Merge pull request #49 from tbittar/claude/find-unused-code-8jlGz-main
aoustry Apr 9, 2026
8971a38
style: apply black 23.7.0 formatting to vectorized_builder.py
claude Apr 9, 2026
a093a3f
Fix all mypy type errors across source and test files
claude Apr 9, 2026
e2a29a5
Merge pull request #54 from tbittar/claude/fix-mypy-issues-qVABP
aoustry Apr 9, 2026
5d969d9
formatting
aoustry Apr 9, 2026
5013dda
Drop Network class, keep System as unified mutable concept
claude Apr 9, 2026
e9b540e
merge main
aoustry Apr 9, 2026
6f8fda0
Apply black 23.7.0 formatting to resolve_components.py
claude Apr 9, 2026
67dd4c2
fix: resolve mypy override errors by removing T_expr generic from Vec…
claude Apr 9, 2026
5f5e696
Merge pull request #57 from tbittar/claude/fix-mypy-return-type-f2bYg
aoustry Apr 9, 2026
277e418
added test for systems with varying time shifts and generators with d…
Apr 9, 2026
1a127e3
fixed import sort
Apr 9, 2026
65b95cf
formatting
aoustry Apr 9, 2026
e41bbc0
added missing demand time series file for tests
Apr 9, 2026
fe9dbcf
typing
aoustry Apr 9, 2026
b7def35
formatting
aoustry Apr 9, 2026
c4b58e7
fix: make VectorizedBuilderBase generic with T_expr bound to Vectoriz…
claude Apr 9, 2026
610c085
Merge pull request #59 from tbittar/claude/fix-vectorized-builder-typ…
aoustry Apr 9, 2026
3cd86fe
Merge pull request #58 from tbittar/8-test-advanced-expressions-with-…
aoustry Apr 9, 2026
9808e0f
fix: cast visit() result to xr.DataArray in simulation_table.py
claude Apr 9, 2026
fe2e725
Merge pull request #61 from tbittar/claude/fix-mypy-simulation-table-…
aoustry Apr 9, 2026
0f9e962
Fix isort, black (23.7.0), and mypy type errors
claude Apr 9, 2026
a4f7c9b
Merge pull request #51 from tbittar/claude/refactor-vectorized-builde…
aoustry Apr 9, 2026
89f0150
Fix isort in tests/ directory
claude Apr 9, 2026
e296316
Merge branch 'main' into claude/review-class-redundancy-WFHI9
aoustry Apr 9, 2026
fb915b2
Fix black formatting: use black 23.7.0 (not 26.x)
claude Apr 9, 2026
a59e5ef
Merge pull request #62 from tbittar/claude/fix-code-formatting-lintin…
aoustry Apr 9, 2026
0f96cc9
Rename network→system: fix terminology across codebase
claude Apr 9, 2026
49530e2
Fix black 23.7.0 formatting (revert black 26.x style changes)
claude Apr 9, 2026
a054058
Merge pull request #64 from tbittar/claude/refactor-system-classes-IHZGr
aoustry Apr 9, 2026
eee2ec6
fix: replace undefined Network type hint with System in test_varying_…
claude Apr 9, 2026
e3f0ac9
Merge pull request #65 from tbittar/claude/fix-ci-error-wfhi9-LgGt9
aoustry Apr 9, 2026
24b2486
remove perf tests
aoustry Apr 9, 2026
4397fff
Add optim-config for decomposition (#53)
tbittar Apr 9, 2026
dd5dc10
feat: Add study reader to load and run simulations from a folder
Apr 9, 2026
f598b58
Merge branch 'main' into claude/review-class-redundancy-WFHI9
aoustry Apr 9, 2026
c61fe65
Merge branch 'main' into 60-add-study-reader-for-an-api-similar-to-cpp
Apr 9, 2026
a2768cb
Remove stale Network references, replace with System
claude Apr 9, 2026
157d2d9
Apply black 23.7 formatting
claude Apr 9, 2026
4f1906c
Merge pull request #67 from tbittar/claude/fix-mypy-errors-9pkEL
aoustry Apr 9, 2026
76322d8
merge of main and fix of path provided to load_optim_config
Apr 9, 2026
9d9b019
Fix black formatting for abstract method stubs and type annotation
claude Apr 9, 2026
358f8e1
Merge pull request #68 from tbittar/claude/fix-black-formatting-3nE9C
aoustry Apr 9, 2026
027c697
fixed formatting and typing issues
Apr 9, 2026
6c655fc
Fix stale build_network import in e2e test
claude Apr 9, 2026
fbd8f4b
Merge pull request #70 from tbittar/claude/fix-coverage-import-warnin…
aoustry Apr 9, 2026
41a5e65
Merge pull request #56 from tbittar/claude/review-class-redundancy-WFHI9
aoustry Apr 9, 2026
217c931
Delete Node class and fully deprecate nodes as a distinct concept
claude Apr 9, 2026
cb0dafe
Fix isort: expand single-line gems.study imports to multi-line
claude Apr 9, 2026
5eff5a0
Merge pull request #71 from tbittar/claude/delete-node-class-KEdQw
aoustry Apr 9, 2026
828dce3
Add SimulationTable fluent accessor API (component / output / value)
claude Apr 9, 2026
21f9ac4
Add uv.lock generated by adding pytest dev dependency
claude Apr 9, 2026
1a1852f
isort'
aoustry Apr 9, 2026
080eec9
Merge branch 'main' into 60-add-study-reader-for-an-api-similar-to-cpp
aoustry Apr 9, 2026
c08b5f1
Refactor load_study to use System instead of Network
aoustry Apr 9, 2026
a9b3acc
Refactor output file generation with timestamp
aoustry Apr 9, 2026
03e0b17
Merge pull request #69 from tbittar/60-add-study-reader-for-an-api-si…
aoustry Apr 9, 2026
041255d
Fix black formatting for CI
claude Apr 9, 2026
a221297
Merge pull request #77 from tbittar/claude/fix-ci-black-formatting-NJxov
aoustry Apr 9, 2026
a96be23
Fix mypy arg-type error for float() call on pandas .loc scalar
claude Apr 9, 2026
42a52fc
Merge pull request #79 from tbittar/claude/fix-mypy-simulation-table-…
aoustry Apr 9, 2026
88974cf
Merge pull request #72 from tbittar/claude/simulation-table-attribute…
aoustry Apr 9, 2026
d494a4a
Module cleaning: rename network.py to system.py, delete probability_l…
claude Apr 9, 2026
f4fae49
Add unit tests for VectorizedLinopyBuilder (closes #15)
claude Apr 9, 2026
1988700
Fix isort import ordering in perf_pypsa.py and test_libs_yaml_system_…
claude Apr 9, 2026
ed6ab47
Apply black formatting to fix CI
claude Apr 10, 2026
56b4049
Merge pull request #80 from tbittar/claude/issue-74-HyOR6
aoustry Apr 10, 2026
32981b2
Merge pull request #81 from tbittar/claude/fix-issue-15-ZB88X
aoustry Apr 10, 2026
b9b71f8
Fix SimulationTable.to_csv mypy error in folder.py
claude Apr 10, 2026
f2d850e
Merge pull request #83 from tbittar/claude/fix-simulationtable-to-csv…
aoustry Apr 10, 2026
727968e
refactor: rename linopy-specific files and classes (issue #82)
claude Apr 10, 2026
f678545
style: fix black formatting for long function signatures
claude Apr 10, 2026
015a60c
Merge pull request #84 from tbittar/claude/issue-82-naming-plan-7YjVT
aoustry Apr 10, 2026
3ff45ff
Rename components_input to system_input in examples (fixes #73)
claude Apr 10, 2026
d3cf4bf
Merge pull request #86 from tbittar/claude/plan-issue-73-gY5LS
aoustry Apr 10, 2026
59635c6
Vectorize SimulationTableBuilder and add Parquet/NetCDF export (Issue…
claude Apr 10, 2026
e48613d
Rename _collect_solver_outputs to _collect_vars_outputs
claude Apr 10, 2026
944e2ec
Use None for missing time/scenario indices in _da_to_df
claude Apr 10, 2026
b02373c
Fix isort: remove extra blank line after imports in test_simulation_t…
claude Apr 10, 2026
c3bc90e
Apply black formatting fixes across 4 files
claude Apr 10, 2026
df06ac3
Fix two CI failures: KeyError in accessor API and missing pyarrow
claude Apr 10, 2026
d883bbf
Apply black formatting to test_simulation_table_accessor.py
claude Apr 10, 2026
8a56ea9
Merge pull request #87 from tbittar/claude/simulationtable-export-pla…
aoustry Apr 10, 2026
9cf0604
Introduce Study container class to gather System and DataBase (closes…
claude Apr 10, 2026
a8f206b
Fix mypy and isort issues in main.py and folder.py
claude Apr 10, 2026
84be47b
Fix isort ordering in all updated test files
claude Apr 10, 2026
97d5f41
Remove extra blank line at end of data.py to satisfy black
claude Apr 11, 2026
004c89e
Refactor tests to use Study instead of System
aoustry Apr 11, 2026
8a3947d
Refactor input system and library handling in tests
aoustry Apr 11, 2026
0ef72f8
Merge pull request #88 from tbittar/claude/review-issue-78-CCUpc
aoustry Apr 13, 2026
ce86583
Update Agents file
tbittar Apr 14, 2026
f451ec8
fix module name in ci cov (#89)
tbittar Apr 14, 2026
7f34316
Update
tbittar Apr 14, 2026
8da2c08
Remove problem context
tbittar Apr 14, 2026
ffa3bf4
Merge pull request #90 from tbittar/feature/update-gantes
aoustry Apr 15, 2026
a92e5e8
Merge pull request #91 from tbittar/fix/remove-problem-context
aoustry Apr 15, 2026
30e74ef
Refactor OptimizationProblem to take Study instead of System+Database
claude Apr 15, 2026
9e7c722
Tolerate absence of expec() in objective contributions (Issue #76) (#95)
aoustry Apr 16, 2026
b02798f
Further refactor
tbittar Apr 16, 2026
afcf536
remove useless attributes from OptimizationProblem
aoustry Apr 16, 2026
9d54784
formatting
aoustry Apr 16, 2026
35b99e3
fix: add FakeStudy to test stubs so FakeProblem exposes problem.study
claude Apr 17, 2026
10141f2
Merge pull request #97 from tbittar/claude/fix-ci-test-failure-m12Xv
aoustry Apr 17, 2026
c246d9f
Merge pull request #96 from tbittar/claude/refactor-optimization-prob…
aoustry Apr 17, 2026
c38e6bd
refactor: rename Input[X] Pydantic classes to [X]Schema (issue #75) (…
aoustry Apr 17, 2026
6edb2af
feat: add SimulationSession with new resolution modes
claude Apr 19, 2026
b8c3c4a
style: fix black 23.7.0 formatting in optimization.py
claude Apr 19, 2026
9d1f5f2
feat: add ScenarioBuilder, propagate scenario_group, fix scenario dat…
claude Apr 20, 2026
48dce4f
refactor: MAP returns (problem, SimulationTable); fix absolute_time_o…
claude Apr 20, 2026
0db6d5e
Refactor session.py to simplify table handling
aoustry Apr 20, 2026
91e021a
fix: add timesteps to FakeBlock in test_simulation_table_export
claude Apr 20, 2026
cc672d6
Update session.py
aoustry Apr 20, 2026
c7e24d3
Merge pull request #108 from tbittar/refactor/merge_tables
aoustry Apr 20, 2026
66325b4
Add unit test for SimulationTable correctness on partial TimeBlock (i…
claude Apr 20, 2026
d181231
Apply black formatting to test_simtable_timeblock.py
claude Apr 20, 2026
a17cab3
Add LinopyModel alias to distinguish from gems.model.Model
claude Apr 20, 2026
f2400a3
Merge pull request #111 from tbittar/claude/issue-107-strategy-aIdos
aoustry Apr 21, 2026
a2469c0
refactor: rename horizon/overlap/total_timesteps to clearer names
claude Apr 24, 2026
4e7d4fb
avoid silent error
aoustry Apr 24, 2026
77f4d1d
formatting
aoustry Apr 24, 2026
29b6300
more explicit vars
aoustry Apr 24, 2026
e0d1c4e
remove redundant scenarios var
aoustry Apr 24, 2026
cf6f2f1
remove redundant scenarios var
aoustry Apr 24, 2026
c171319
remove scenarios count
aoustry Apr 24, 2026
48fab1f
fix docstring
aoustry Apr 24, 2026
9ce2a5e
remove scenarios count
aoustry Apr 24, 2026
0c4567f
fix dim size
aoustry Apr 24, 2026
d994cda
Merge pull request #99 from tbittar/claude/explain-optim-config-ePFQG
aoustry Apr 24, 2026
188d97d
Merge pull request #109 from tbittar/claude/issue-103-strategy-FiT67
aoustry Apr 24, 2026
5dec26a
Parse binary variable
tbittar Apr 25, 2026
4dc661e
Merge pull request #118 from tbittar/feature/parse-binary-variable
aoustry Apr 26, 2026
f452b55
Feature/non cyclic constraints (#92)
tbittar Apr 27, 2026
202f60c
Harmonize the interactions between CLI, main.py, folder.py, Simulatio…
aoustry Apr 27, 2026
e334e47
Reorganize tests (#119)
tbittar Apr 27, 2026
5e4fb41
Fix description, remove imports (#131)
tbittar Apr 27, 2026
8082844
Add E2E test for rolling-horizon suboptimality (Issue #102) and fix s…
aoustry Apr 28, 2026
941aa7b
Consolidate project config into pyproject.toml and update dependencie…
aoustry Apr 28, 2026
60d3266
Fix import sorting in main.py to satisfy isort check (#137)
aoustry Apr 28, 2026
47ac1e3
Implement scenario builder: vectorized MC scenario → column dispatch …
aoustry Apr 28, 2026
2858095
Add unit tests for untested code in recent commits (#134)
aoustry Apr 28, 2026
5b4f935
fix: resolve mypy type errors in TimeSeriesData.get_value (#139)
aoustry Apr 28, 2026
4c46696
update pre-commit (#140)
tbittar Apr 28, 2026
6501945
Add tests
tbittar Apr 29, 2026
6d3e824
WIP
tbittar Jun 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 11 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,29 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: 3.11
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
run: uv sync --group dev

- name: Check imports sort order
uses: isort/isort-action@v1
with:
sort-paths: src, tests
configuration: --profile black --check-only --diff
requirements-files: "requirements.txt requirements-dev.txt"
run: uv run isort --profile black --check-only --diff src tests

- name: Check formatting
uses: psf/black@stable
with:
# Version of Black should match the versions set in `requirements-dev.txt`
version: "~=23.7.0"
options: --check --diff
run: uv run black --check --diff src tests

- name: Check typing
run: |
python -m mypy
run: uv run mypy

- name: Test
run: |
pytest --cov antarest --cov-report xml
run: uv run pytest --cov gems --cov-report xml

- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: python-code-coverage-report
path: coverage.xml

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ outputs
build
src/gems.egg-info/
src/gemspy.egg-info/
build_time_scalability.csv
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ repos:
hooks:
- id: mypy
name: Run mypy
entry: mypy
entry: uv run mypy
language: system
files: ^src/
types: [python]
Expand All @@ -12,7 +12,7 @@ repos:
hooks:
- id: black
name: Run black
entry: black
entry: uv run black
args: ["--config", "pyproject.toml"]
language: system
types: [python]
Expand All @@ -21,7 +21,7 @@ repos:
hooks:
- id: isort
name: Run isort
entry: isort
args: ["--profile", "black", "--filter-files"]
entry: uv run isort
args: ["--profile", "black", "--filter-files", "src", "tests"]
language: system
types: [python]
7 changes: 5 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ build:
mkdocs:
configuration: mkdocs.yml

# Optionally declare the Python requirements required to build your docs
# Install the package with doc optional dependencies
python:
install:
- requirements: requirements-doc.txt
- method: pip
path: .
extra_requirements:
- doc
64 changes: 39 additions & 25 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pip install -r requirements.txt -r requirements-dev.txt
```bash
pytest # run all tests
pytest tests/path/to/test_file.py::test_name # run a single test
pytest --cov gems --cov-report xml # with coverage
pytest --cov gems --cov-report xml # with coverage
```

**Lint & Format:**
Expand All @@ -37,51 +37,65 @@ gemspy \
--duration 8760 \
--scenarios 1

# Python API (minimal example)
from gems.main.main import build_problem
# Python API — directory-based study
from gems.study.folder import load_study, run_study
from gems.simulation import TimeBlock

study = load_study(Path("path/to/study_dir")) # reads input/, model-libraries/, data-series/
problem = run_study(Path("path/to/study_dir"), scenarios=1, time_block=TimeBlock(1, list(range(8760))))

# Python API — programmatic study
from gems.study import Study
from gems.simulation import build_problem, TimeBlock

study = Study(system=system, database=database)
problem = build_problem(study, TimeBlock(1, list(range(8760))), scenarios=1)
problem.solve(solver_name="highs")
```

## Architecture

The pipeline flows: **YAML input → parsing → model resolution → network building → optimization problem → OR-Tools solver → results**
The pipeline flows: **YAML input → parsing → model resolution → system instantiation → optimization problem → HiGHS solver (via linopy) → results**

An optional `optim-config.yml` activates decomposition: variables and constraints are split across a master problem and subproblems, with either sequential resolution or full Benders decomposition.

### Core Modules (`src/gems/`)

**`model/`** — Immutable model templates.
- `Model`: defines component behavior (parameters, variables, constraints, ports)
- `Library`: a collection of models, loaded from YAML
- Models are never instantiated directly — they are referenced by components

**`expression/`** — Mathematical expression language and AST.
- `ExpressionNode`: base frozen dataclass for all expression tree nodes
- Node types cover: arithmetic (`+`, `-`, `*`, `/`), comparisons (`<=`, `>=`, `==`), time/scenario operators (`time_sum()`), and functions (`max()`, `min()`, `ceil()`, `floor()`)
- Grammar is defined in `/grammar/` and parsed via ANTLR4 (generated files live in `expression/parsing/antlr/`)
- Grammar is defined in `grammar/Expr.g4` and parsed via ANTLR4 (generated files live in `expression/parsing/antlr/` — do not edit directly)
- `ExpressionVisitor` is the dominant pattern for traversing and transforming expression trees (evaluation, linearization, printing, degree analysis)
- Expressions support operator overloading: `var('x') + 5 * param('p')`

**`study/`** — Study definition and network instantiation.
- `System`: top-level structure parsed from YAML (before instantiation)
- `Network`: instantiated graph of `Node`s, `Component`s, and connections
- `Component`: an instance of a `Model` with concrete parameter values
- `DataBase`: manages time series and scenario data
**`study/`** — Study definition and instantiation.
- `System` (`system.py`): resolved topology — graph of `Component`s, `PortRef`s, and `PortsConnection`s after library references are substituted
- `Study` (`study.py`): dataclass pairing a `System` with a `DataBase`; validates that the database supplies every parameter required by the system
- `DataBase` (`data.py`): manages time-series and scenario data;
- `load_study` / `run_study` (`folder.py`): convenience functions for directory-based studies (`input/system.yml`, `input/model-libraries/`, `input/data-series/`)

**`simulation/`** — Optimization problem construction and solving.
- `OptimizationProblem`: main interface; translates network + database into OR-Tools constraints
- `LinearExpression`: the linearized form of model constraints used by the solver
- `BendersDecomposedProblem`: temporal decomposition strategy for large problems
- `TimeBlock`: structure for defining temporal decomposition
- `OutputValues`: result extraction and formatting
- `OptimizationProblem` (`optimization.py`): main interface; translates a `Study` into a linopy model solved by HiGHS
- `DecomposedProblems` (`optimization.py`): holds the master problem and subproblem produced by temporal decomposition
- `VectorizedLinearExprBuilder` (`linearize.py`): `ExpressionVisitor` subclass that converts an expression AST into a `VectorizedExpr`
- `VectorizedBuilderBase` (`vectorized_builder.py`): shared base for all vectorized visitors (used by both `linearize.py` and `extra_output.py`)
- `TimeBlock` (`time_block.py`): defines the temporal window for one solve
- `SimulationTableBuilder` / `SimulationTableWriter` (`simulation_table.py`): result extraction as a flat pandas `DataFrame`

### Key Design Patterns
**`optim_config/`** — Optional decomposition configuration.
- `OptimConfig` (`parsing.py`): top-level config loaded from `optim-config.yml`
- `ResolutionMode` (`parsing.py`): `SEQUENTIAL_SUBPROBLEMS` (default) or `BENDERS_DECOMPOSITION`
- `ModelDecompositionConfig` (`parsing.py`): per-model assignment of variables/constraints/objective contributions to master or subproblems

- **Frozen dataclasses** throughout for immutability (models, expressions, constraints)
- **Visitor pattern** for all expression tree operations (`ExpressionVisitor` subclasses)
- **Indexing dimensions**: parameters and variables carry time and scenario indices explicitly; expressions track these automatically
- **`ValueType`** enum (`INTEGER`, `CONTINUOUS`, `BOOLEAN`) for variable typing
**`libs/`** — Resolves the path to bundled YAML model libraries shipped with the package.

### Type Checking
### Key Design Patterns

Strict mypy is enforced (`disallow_untyped_defs`, `disallow_untyped_calls`). All new code must be fully typed. Configuration is in `mypy.ini`.
- **Visitor pattern** for all expression tree operations (`ExpressionVisitor` subclasses). Use `ExpressionVisitorOperations` as a base when the return type supports `+, -, *, /` — it provides those four method implementations for free.
- **Template-method via single abstract method**: `VectorizedBuilderBase` implements all 18+ visitor methods once with `xr.DataArray`-compatible semantics; concrete subclasses only override `variable()` (and optionally a few linopy-specific methods).
- **Indexing dimensions**: parameters and variables carry time and scenario indices explicitly via `IndexingStructure`; expressions track these automatically.

## Further Reading

Expand Down
13 changes: 7 additions & 6 deletions docs/agents/python-convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

## Code Style & Conventions

- **Formatter**: Black, line-length 88. Never adjust line breaks manually—let Black decide.
- **Import order**: isort with `profile = "black"`. One `import` block, no manual blank lines between
groups.
- **Type annotations**: All functions and methods **must** have full type annotations. mypy is run in
strict mode (`disallow_untyped_defs`, `disallow_untyped_calls`).
- **Formatter**: Black `23.7.0`, line-length 88. Never adjust line breaks manually—let Black decide.
- **Import order**: isort `5.12.0` with `profile = "black"`. One `import` block, no manual blank
lines between groups.
- **Type annotations**: All functions and methods **must** have full type annotations. mypy `1.7.1`
is run with `disallow_untyped_defs = true` and `disallow_untyped_calls = true` (see `mypy.ini`).
- **Dataclasses**: Prefer `@dataclass(frozen=True)` for value objects (expression nodes, model
definitions). Mutability must be justified explicitly.
- **Pydantic**: Use `ConfigDict(alias_generator=to_camel)` or kebab-case alias generation for YAML
round-tripping; use Pydantic v2 APIs only.
- **Naming**:
- Classes: `PascalCase`
- Functions / variables: `snake_case`
- Functions / variables: `snake_case` — use descriptive names; avoid single-letter or two-letter
names except for well-established loop indices (`i`, `j`) or type parameters (`T`).
- Constants / type-level aliases: `UPPER_SNAKE_CASE`
- YAML keys: `kebab-case`
- **Commit messages**: Follow Conventional Commits — `<type>(<scope>): <summary>`, e.g.
Expand Down
16 changes: 11 additions & 5 deletions docs/agents/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
## Philosophy

Tests live alongside the module they exercise. Fixtures (YAML snippets, small networks) are kept
in `tests/` sub-directories. No mocking of the solver—tests use real OR-Tools calls.
in `tests/` sub-directories. No mocking of the solver—tests use real HiGHS calls via linopy
(`problem.solve(solver_name="highs")`).

## Layers

| Layer | Location | Description |
|---|---|---|
| Unit | `tests/unittests/` | One file per module area; covers AST visitors, parsing, model loading, linearisation |
| Integration | `tests/unittests/simulation/` | Full problem build + solve on tiny networks |
| End-to-end | `tests/e2e/` | CLI-level tests reading real YAML fixtures |
| Converter | `tests/input_converter/`, `tests/pypsa_converter/`, `tests/antares_historic/` | Format-specific conversion tests |
| Unit — expressions | `tests/unittests/expressions/` | AST visitors and expression parsing (parsing/, visitor/) |
| Unit — libraries | `tests/unittests/lib_parsing/` | Model library YAML parsing |
| Unit — system | `tests/unittests/system/` | Model, network, and port object behaviour |
| Unit — system parsing | `tests/unittests/system_parsing/` | System YAML parsing |
| Unit — scenario builder | `tests/unittests/scenario_builder/` | Scenario and time-series builder |
| Integration | `tests/unittests/simulation/` | Full problem build + solve on small networks |
| End-to-end — functional | `tests/e2e/functional/` | Cross-cutting tests: library/system combinations, stochastic, investment, scenario builder |
| End-to-end — models | `tests/e2e/models/` | Model-level tests (andromede-v1 models, operator tests, proof-of-concept models) |
| End-to-end — studies | `tests/e2e/studies/` | Study-level tests reading full YAML study fixtures |
7 changes: 3 additions & 4 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,18 @@ with open("system.yml") as lib_file:
input_libraries = [parse_yaml_library(lib_file)]

result_lib = resolve_library(input_libraries)
components_input = resolve_system(input_system, result_lib)
system_input = resolve_system(input_system, result_lib)
database = build_data_base(input_system, Path(series_dir))
~~~

### Building the optimisation problem

~~~ python

network = build_network(components_input)
network = build_network(system_input)

problem = build_problem(
network,
database,
Study(network, database),
TimeBlock(1, [i for i in range(0, timespan)]),
scenarios,
)
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ with open("simple_library.yml") as lib_file:
input_libraries = [parse_yaml_library(lib_file)]

result_lib = resolve_library(input_libraries)
components_input = resolve_system(input_system, result_lib)
system_input = resolve_system(input_system, result_lib)
database = build_data_base(input_system, Path(series_dir))
~~~

Expand Down
5 changes: 2 additions & 3 deletions docs/user-guide/optimisation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

~~~ python

network = build_network(components_input)
network = build_network(system_input)

problem = build_problem(
network,
database,
Study(network, database),
TimeBlock(1, [i for i in range(0, timespan)]),
scenarios,
)
Expand Down
22 changes: 17 additions & 5 deletions docs/user-guide/outputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@
Once the optimisation problem was built and solved, one can retrieve the results as follows:

~~~ python
problem.solver.Solve()
results = OutputValues(problem)
from gems.simulation.simulation_table import SimulationTableBuilder

df = SimulationTableBuilder().build(problem)
~~~

The result is a `pandas.DataFrame` with columns: `block`, `component`, `output`,
`absolute-time-index`, `block-time-index`, `scenario-index`, `value`, `basis-status`.

Reading the value of the optimisation variable `var_id` of component `component_id`
for a single time step and scenario reads:

~~~ python
value = df[(df["component"] == component_id) & (df["output"] == var_id)]["value"].iloc[0]
~~~

Reading the timeseries of the optimisation variable ''var_id'' of component "component_id" reads:
For multi-time or multi-scenario results, filter additionally by `block-time-index`
and `scenario-index`:

~~~ python
var_timeseries = results.component(component_id).var(var_id).value
~~~
sub = df[(df["component"] == component_id) & (df["output"] == var_id)]
value_s0_t1 = sub[(sub["scenario-index"] == 0) & (sub["block-time-index"] == 1)]["value"].iloc[0]
~~~
17 changes: 0 additions & 17 deletions mypy.ini

This file was deleted.

Loading
Loading