diff --git a/.github/actions/generate-docs/action.yml b/.github/actions/generate-docs/action.yml index 4f2328b5d..9784ab9e5 100644 --- a/.github/actions/generate-docs/action.yml +++ b/.github/actions/generate-docs/action.yml @@ -1,9 +1,5 @@ name: Generate documentation description: Generate all documentation -inputs: - build: - description: Just subcommand for `build-docs` to run - default: all runs: using: composite @@ -22,4 +18,4 @@ runs: enable-cache: true - name: Build documentation shell: bash - run: just build-docs::${{ inputs.build }} + run: just build-docs diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 14f254db1..822574943 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,13 +9,7 @@ updates: directory: "/" schedule: interval: "weekly" - groups: - rust: - patterns: ["*"] - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" - groups: - github-actions: - patterns: ["*"] diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 103bc3d0a..a0b3d4aad 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -23,17 +23,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 - with: - fetch-tags: true - fetch-depth: 0 - - name: Set user name and email for git - run: | - # Needed so we can apply patches - git config --global user.name "GitHub Actions" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - uses: ./.github/actions/generate-docs - with: - build: all_with_old - name: Setup pages uses: actions/configure-pages@v5 - name: Upload artifact diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index bcf789263..bc8476281 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -16,10 +16,9 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false - - uses: actions/setup-python@v6 - - uses: actions-rust-lang/setup-rust-toolchain@v1 + - uses: actions/setup-python@v5 - uses: browniebroke/pre-commit-autoupdate-action@main - - uses: peter-evans/create-pull-request@v8 + - uses: peter-evans/create-pull-request@v7 with: token: ${{ secrets.GH_TOKEN_FOR_UPDATES }} branch: update/pre-commit-hooks diff --git a/.lycheeignore b/.lycheeignore index 097724f09..a1358272f 100644 --- a/.lycheeignore +++ b/.lycheeignore @@ -1,6 +1,5 @@ # For some reason these spurious links appear in some cargo doc-generated files ^file://.+/MUSE2/book/api/index\.html$ -^file://.+/MUSE2/book/README\.html$ # Some of these links give a 404, even though they're generated in the API docs. No idea why. ^https://docs.rs/erased-serde/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8edd70794..076379741 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: files: /settings\.toml$ types_or: [toml] - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.48.0 + rev: v0.47.0 hooks: - id: markdownlint-fix - repo: https://github.com/pre-commit/mirrors-prettier @@ -53,7 +53,7 @@ repos: - id: clippy args: ["--all-targets", "--", "-D", "warnings"] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.5 + rev: v0.15.4 hooks: - id: ruff-check types_or: [python] @@ -65,12 +65,12 @@ repos: hooks: - id: nbstripout - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.1 hooks: - id: codespell args: [--ignore-words, .codespell_ignore.txt] exclude: \.svg$ - - repo: https://github.com/EnergySystemsModellingLab/cffconvert - rev: 2.1.0 + - repo: https://github.com/citation-file-format/cffconvert + rev: b6045d78aac9e02b039703b030588d54d53262ac hooks: - id: validate-cff diff --git a/Cargo.lock b/Cargo.lock index ef2fef354..2875291ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,9 +99,9 @@ checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] name = "assert_cmd" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a686bbee5efb88a82df0621b236e74d925f470e5445d3220a5648b892ec99c9" +checksum = "9c5bcfa8749ac45dd12cb11055aeeb6b27a3895560d60d71e3c23bf979e60514" dependencies = [ "anstyle", "bstr", @@ -467,9 +467,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" dependencies = [ "serde", "serde_core", @@ -1020,7 +1020,7 @@ dependencies = [ "serde_string_enum", "strum 0.28.0", "tempfile", - "toml 1.0.6+spec-1.1.0", + "toml 1.0.3+spec-1.1.0", "unicase", "yaml-rust2", ] @@ -1565,9 +1565,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.27.0" +version = "3.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" dependencies = [ "fastrand", "getrandom 0.3.3", @@ -1626,9 +1626,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.0.6+spec-1.1.0" +version = "1.0.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399b1124a3c9e16766831c6bba21e50192572cdd98706ea114f9502509686ffc" +checksum = "c7614eaf19ad818347db24addfa201729cf2a9b6fdfd9eb0ab870fcacc606c0c" dependencies = [ "indexmap", "serde_core", diff --git a/Cargo.toml b/Cargo.toml index 7c86b5593..6c2c1950f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,8 @@ float-cmp = "0.10.0" itertools = "0.14.0" serde = {version = "1.0.228", features = ["derive", "rc"]} serde_string_enum = "0.2.1" -tempfile = "3.27.0" -toml = "1.0.6" +tempfile = "3.26.0" +toml = "1.0.3" unicase = "2.9.0" fern = {version = "0.7.1", features = ["chrono", "colored"]} chrono = "0.4" @@ -37,10 +37,10 @@ strum = {version = "0.28.0", features = ["derive"]} documented = "0.9.2" dirs = "6.0.0" edit = "0.1.5" -erased-serde = "0.4.10" +erased-serde = "0.4.9" [dev-dependencies] -assert_cmd = "2.2.0" +assert_cmd = "2.1.2" map-macro = "0.3.0" rstest = {version = "0.26.1", default-features = false, features = ["crate-name"]} yaml-rust2 = {version = "0.11.0", default-features = false} diff --git a/build-docs.just b/build-docs.just index 1a5cf67cd..d84474184 100644 --- a/build-docs.just +++ b/build-docs.just @@ -1,11 +1,8 @@ # Make rustdoc warnings fatal export RUSTDOCFLAGS := "-D warnings" -# Build all documentation, except old docs -all: cli-help file-format examples versions book api - -# Build all documentation, including old docs -all_with_old: all old +# Build all documentation +all: cli-help file-format examples book api # Build book book: @@ -36,15 +33,3 @@ file-format *ARGS: examples: @echo Building docs for examples @uv run docs/generate_example_docs.py - -# Build TOC for old versions -versions: - @echo Building TOC for old versions of documentation - @uv run docs/generate_versions_docs.py - -# Build documentation for previous releases -old: - @# Clean output dir - @rm -rf book/release - - @uv run docs/build_old_docs.py diff --git a/docs/.gitignore b/docs/.gitignore index 9eece75fc..ab9fc47fa 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,4 +1,3 @@ # Generated documentation files command_line_help.md examples.md -versions.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 9b0c9a264..4df0560d3 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -23,4 +23,3 @@ - [Release notes](release_notes/README.md) - [MUSE2 v2.0.0 (October 14, 2025)](release_notes/v2.0.0.md) - [Next unreleased version](release_notes/upcoming.md) -- [Other versions of documentation](versions.md) diff --git a/docs/build_old_docs.py b/docs/build_old_docs.py deleted file mode 100755 index 71fa35ae2..000000000 --- a/docs/build_old_docs.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python3 -# -# A script to generate documentation for previous releases of MUSE2. - -import os -import shutil -import subprocess as sp -from pathlib import Path -from tempfile import TemporaryDirectory - -from release import get_releases - -DOCS_SITE_ROOT = "https://energysystemsmodellinglab.github.io/MUSE2" -REPO_ROOT = Path(__file__).parent.parent.absolute() -DOCS_DIR = REPO_ROOT / "docs" - - -def clone_repo_to(dest: Path): - """Clone this repo somewhere else.""" - print("Making a copy of repo") - sp.run(("git", "clone", REPO_ROOT, dest), check=True, capture_output=True) - - # Add a symlink to cargo cache dir - try: - os.symlink(REPO_ROOT / "target", dest / "target") - except (NotImplementedError, OSError): - # Only newer versions of Windows support symlinks and these require the user to have - # additional privileges (or to be in developer mode) - print( - "WARN: Could not create symlink to cache directory; cache will not be stored" - ) - - -def apply_patches_for_release(release: str, repo_path: Path) -> None: - """Apply patches (if any) for the given release.""" - patches_dir = DOCS_DIR / "release" / "patches" / release - for patch_path in sorted(patches_dir.glob("*.patch")): - sp.run(("git", "-C", str(repo_path), "am", str(patch_path)), check=True) - - -def build_docs_for_release(release: str, repo_path: Path, outdir: Path) -> None: - """Build documentation for a given release.""" - print(f"Building docs for {release}") - - # Check out release - sp.run( - ("git", "-C", str(repo_path), "checkout", release), - check=True, - capture_output=True, - ) - - # Apply patches, if any - apply_patches_for_release(release, repo_path) - - # Build docs - sp.run(("just", f"{repo_path!s}/build-docs"), check=True) - - # Patch versions.html to redirect to main versions page - with (repo_path / "book" / "versions.html").open("w", encoding="utf-8") as f: - f.write(f""" - -""") - - # Move to output directory - release_outdir = outdir / release - print(f"Copying to {release_outdir}") - shutil.move((repo_path / "book"), release_outdir) - - -def build_old_docs() -> None: - """Build documentation for previous releases.""" - outdir = REPO_ROOT / "book" / "release" - outdir.mkdir(parents=True, exist_ok=True) - - # Clone this repo to a temporary directory - with TemporaryDirectory() as tmpdir: - repo_path = Path(tmpdir) - clone_repo_to(repo_path) - - # Generate documentation for each previous release - for release in get_releases(): - build_docs_for_release(release, repo_path, outdir) - - -if __name__ == "__main__": - build_old_docs() diff --git a/docs/generate_versions_docs.py b/docs/generate_versions_docs.py deleted file mode 100644 index a4cd5a67d..000000000 --- a/docs/generate_versions_docs.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# /// script -# dependencies = [ -# "jinja2", -# ] -# /// -# -# A script to generate the versions.md file, listing links to old versions of documentation. - -from pathlib import Path - -from jinja2 import Environment, FileSystemLoader -from release import get_releases - -DOCS_DIR = Path(__file__).parent.absolute() - - -def generate_versions_md() -> None: - """Write the versions.md file.""" - path = DOCS_DIR / "versions.md" - print(f"Writing {path}") - env = Environment(loader=FileSystemLoader(DOCS_DIR / "templates")) - template = env.get_template("versions.md.jinja") - out = template.render(releases=get_releases()) - - with path.open("w", encoding="utf-8") as f: - f.write(out) - - -if __name__ == "__main__": - generate_versions_md() diff --git a/docs/model/investment.md b/docs/model/investment.md index cc753cdab..6dccf743a 100644 --- a/docs/model/investment.md +++ b/docs/model/investment.md @@ -41,6 +41,12 @@ investments. - \\( \text{FOM}_{opt,r} \\): Annual fixed Operations & Maintenance costs per unit of capacity for \\( opt \\) in \\( r \\). + - \\( FinancingInDecomDec_{ex} \\) (binary flag). This user-defined option specifies whether to + include estimated financing costs in the economic viability threshold when considering the + decommissioning of an existing asset. This can only be used on profit-evaluable assets. Used + with \\( PercentDebt_{ex} \\). Where financing costs are included, the percentage debt is + multiplied by the original capex, and the result is annualised. + - For new candidate assets: - \\( \text{CAPEX}_{ca,r} \\): Upfront capital expenditure required per unit of new capacity for @@ -63,48 +69,33 @@ providing investment and dynamic decommissioning decisions. ### Pre-calculation of metrics for each supply option +> Note: This section contains a reference to "scopes", a feature that is not yet implemented + - Annualised fixed costs per unit of capacity (\\( AFC_{opt,r} \\)): For new candidates, this is their annualised CAPEX plus FOM. For existing assets, the relevant fixed cost is its FOM. -- Calculate the specific process and commodity flow costs (\\(\text{SPCF}\_{t})\\): - - \\[ - \text{SPCF}\_{t} = \sum\_{c} \Big( cost\_{\text{input}}[c] \cdot input\_{\text{coeff}}[c] + - cost\_{\text{output}}[c] \cdot output\_{\text{coeff}}[c] \Big) - \\] - -#### Coefficients of activity - -- Calculate net revenue per unit of activity \\(AC\_{t}^{NPV} \\) (Tool A): - \\[ - \begin{aligned} - AC\_{t}^{NPV} = &-cost\_{\text{var}}[t] \\\\ - &- \text{SPCF}\_{t} \\\\ - &+ \sum\_{c} \Big( output\_{\text{coeff}}[c] - input\_{\text{coeff}}[c] \Big) - \cdot \lambda\_{c,r,t} \\\\ - &+ \varepsilon \\\\ - \end{aligned} - \\] - \\(\varepsilon \approx 1\times 10^{-14}\\) is added to - each \\(AC\_{t}^{NPV} \\) to allow assets which are breakeven (or very close to breakeven) to be - dispatched. +- Costs per unit of activity in each time slice, calculated as follows: -- Calculate cost per unit of activity \\( AC\_{t}^{LCOX} \\) (Tool B). Note that the commodity - of interest (primary output \\( c\_{primary} \\)) is excluded from the price term: \\[ \begin{aligned} - AC\_{t}^{LCOX} = & \quad cost\_{\text{var}}[t] \\\\ - &+ \text{SPCF}\_{t} \\\\ - &- \sum\_{c \neq c\_{primary}} \Big( output\_{\text{coeff}}[c] - input\_{\text{coeff}} - [c] \Big) + AC_t = & \quad cost\_{\text{var}}[t] \\\\ + &+ \sum\_{c} \Big( cost\_{\text{input}}[c] \cdot input\_{\text{coeff}}[c] + + cost\_{\text{output}}[c] \cdot output\_{\text{coeff}}[c] \Big) \\\\ + &+ \sum\_{c} \Big( input\_{\text{coeff}}[c] - output\_{\text{coeff}}[c] \Big) \cdot \lambda\_{c,r,t} \\\\ + &+ \sum\_{s,c} in\\_scope[s] \cdot \Big\\{ \\\\ + &\quad \quad (cost\_{\text{prod}}[s,c] - \mu\_{s,c}^{\text{prod}}) + \cdot output\_{\text{coeff}}[c] \\\\ + &\quad \quad + (cost\_{\text{cons}}[s,c] - \mu\_{s,c}^{\text{cons}}) + \cdot input\_{\text{coeff}}[c] \\\\ + &\quad \quad + (cost\_{\text{net}}[s,c] - \mu\_{s,c}^{\text{net}}) + \cdot (output\_{\text{coeff}}[c] - input\_{\text{coeff}}[c]) \\\\ + &\Big\\} \end{aligned} \\] -- The third term in both activity coefficients accounts for commodity price flow costs, which are - the net costs or revenues associated with the commodity flows. In the LCOX case the commodity of - interest is excluded from this term because the cost of production shouldn't depend on the market - price of the commodity being produced. + When using the LCOX objective, the calculation is adjusted to exclude the commodity of interest + (\\( \lambda\_{c,r,t} \\) are set to zero). ### Initialise demand profiles for commodity of interest @@ -139,8 +130,8 @@ providing investment and dynamic decommissioning decisions. #### Tool A: NPV -This method is used when the decision rule is `single` and the objective is annualised profit for -agents serving commodity \\( c \\). It iteratively builds a supply portfolio by selecting +This method is used when decision rule is single objective and objective is annualised profit for +agents' serving commodity \\( c \\). This method iteratively builds a supply portfolio by selecting options that offer the highest annualised profit for serving the current commodity demand. The economic evaluation uses \\( \pi_{prevMSY} \\) prices and takes account of asset-specific operational constraints (e.g., minimum load levels) and the balance level of the target commodity @@ -148,10 +139,11 @@ operational constraints (e.g., minimum load levels) and the balance level of the - **Optimise capacity and dispatch to maximise annualised profit:** Solve a small optimisation sub-problem to maximise the asset's surplus, subject to its operational rules and the specific - demand tranche it is being asked to serve. + demand tranche it is being asked to serve. \\(\varepsilon \approx 1×10^{-14}\\) is added to each + \\(AC_t \\) to allow assets which are breakeven (or very close to breakeven) to be dispatched. \\[ - maximise \Big\\{\sum_t act_t AC\_{t}^{NPV} + maximise \Big\\{ - \sum_t act_t \* (AC_t + \varepsilon) \Big\\} \\] @@ -163,25 +155,12 @@ operational constraints (e.g., minimum load levels) and the balance level of the - A demand constraint, where output cannot exceed demand in the tranche, which adapts based on the commodity's balance level (time slice, season, annual). - - Capacity is constrained up to \\( CapMaxBuild \\) for candidates, and to known capacity for + - Capacity is constrained to \\( CapMaxBuild \\) for candidates, and to known capacity for existing assets. -- **Decide on metric:** The type of metric used to compare profitability is dependent on the value of - \\(\text{AFC}\\). If \\(\text{AFC} = 0\\) within the tolerance provided by the `float_cmp` crate, - the associated investment option is always prioritised over options with \\(\text{AFC} > 0\\). - -- **If \\(\text{AFC} > 0\\), Use the profitability index \\(\text{PI}\\) metric:** This is the total - annualised surplus divided by the annualised fixed cost. - \\[ - \text{PI} = - \frac{\sum\_t act\_t \cdot \text{AC}\_t^{\text{NPV}}}{\text{AFC} \cdot \text{cap}} - \\] - -- **If \\(\text{AFC} = 0\\), Use the total annualised surplus metric \\(\text{TAS}\\):** - \\[ - \text{TAS} = - \sum\_t act\_t \cdot \text{AC}\_t^{\text{NPV}} - \\] +- **Calculate a profitability index:** This is the total annualised surplus (\\( - \sum_t + act_t \* AC \\)) divided by the annualised fixed cost (\\( + AFC \* cap \\)). #### Tool B: LCOX @@ -196,12 +175,12 @@ commodities are set to zero, and the commodity of interest is assumed to have ze For each asset option: - **Optimise capacity and dispatch to minimise annualised cost:** Solve a small optimisation - sub-problem to minimise the asset's annualised cost, subject to its operational rules and the specific + sub-problem to maximise the asset's surplus, subject to its operational rules and the specific demand tranche it is being asked to serve. \\[ minimise \Big\\{ - \text{AFC} \times cap + \sum\_t act\_t \times AC\_{t}^{LCOX} + VoLL \times UnmetD\_t + AF \* cap + \sum_t act_t \* AC_t + VoLL \* UnmetD_t \Big\\} \\] @@ -214,195 +193,15 @@ For each asset option: each timeslice of the tranche, which adapts based on the commodity's balance level (time slice, season, annual). - - Capacity is constrained up to \\( CapMaxBuild \\) for candidates, and to known capacity for + - Capacity is constrained to \\( CapMaxBuild \\) for candidates, and to known capacity for existing assets. - VoLL variables are active to ensure a feasible solution alongside maximum operation of the asset. -- **Calculate a Cost Index Metric:** This is the total annualised cost divided by the annual output. - \\[ - \text{Cost Index} = \frac{\text{AFC} \times \text{cap}_r + \sum_t act_t - \times \text{AC}_t^{\text{LCOX}}}{\sum_t act_t} - \\] - -#### Equal-Metric Fallback - -If two or more investment options from the same tool have equal metrics, the following tie-breaking -rules are applied in order: - -1. Assets which are already commissioned are preferred over new candidate assets. -2. Newer (commissioned later) assets are preferred over older assets. -3. If there is still a tie, the first option in the data structure storing the metrics is selected, - which is an arbitrary choice. A `debug` level log message is emitted in this case. - -## Example: Gas Power Plant - -The following is an illustrative example of how the NPV and LCOX approaches work, using a simple -gas combined-cycle power plant as the supply option under consideration. -This example demonstrates the evaluation across two time periods -\\(t\_0\\) (peak period) and \\(t\_1\\) (off-peak period) with variable operating costs - \\( cost\_{var}[t] \\) constant in all time periods. - -### Model Parameters - -#### Asset Parameters - -| Parameter | Notation | Value | Description | -|--------------------------------|--------------------------------------|---------------------------|-----------------------------------| -| Primary output (Electricity) | \\( output\_{coeff}[c_{primary}] \\) | 1.0 MWh per unit activity | Main commodity produced | -| By-product output (Waste heat) | \\( output\_{coeff}[c_{heat}] \\) | 0.5 MWh per unit activity | Co-product from generation | -| Input (Natural gas) | \\( input\_{coeff}[c_{gas}] \\) | 2.5 MWh per unit activity | Fuel consumption | -| Variable operating cost | \\( cost\_{var}[t] \\) | £5/MWh of activity | Operating costs per unit activity | - - -All per-flow costs represented in the general formulas as \\( cost\_{input} \\) and -\\( cost\_{output} \\) are assumed to be zero. - -#### Investment Parameters - -| Parameter | Notation | Value | -|-----------------------|----------------------|-----------| -| Annualised fixed cost | \\( AFC\_{opt,r} \\) | £1,000/MW | -| Capacity | \\( cap \\) | 100 MW | - -#### Market Prices by Time Period - -| Commodity | Notation | \\(t_0\\) (Peak) | \\(t_1\\) (Off-peak) | -|-------------|-------------------------------------|------------------|----------------------| -| Electricity | \\( \lambda\_{c\_{primary},r,t} \\) | £90/MWh | £50/MWh | -| Heat | \\( \lambda\_{c\_{heat},r,t} \\) | £25/MWh | £15/MWh | -| Natural gas | \\( \lambda\_{c\_{gas},r,t} \\) | £35/MWh | £25/MWh | - -### NPV Approach (Tool A) - -#### Calculate Net Revenue per Unit of Activity - -**For \\(t\_0\\) (peak period):** - -\\[ -\begin{aligned} -AC_{t_{0}}^{NPV} &= (1.0 \times 90) + (0.5 \times 25) + (-2.5 \times 35) - 5 \\\\ -&= 90 + 12.5 - 87.5 - 5 \\\\ -&= \text{£10/MWh} -\end{aligned} -\\] - -The asset earns £10 profit for every MWh it operates during peak periods. - -**For \\(t\_1\\) (off-peak period):** - -\\[ -\begin{aligned} -AC_{t\_1}^{NPV} &= (1.0 \times 50) + (0.5 \times 15) + (-2.5 \times 25) - 5 \\\\ -&= 50 + 7.5 - 62.5 - 5 \\\\ -&= \text{£} -10 \text{/MWh} -\end{aligned} -\\] - -The asset loses £10 for every MWh it operates during off-peak periods. - -#### Dispatch Optimisation - -The optimisation maximises total net revenue across all time periods: - -\\[ -\max \sum\_t act\_t \cdot AC\_t^{NPV} = act\_{t_{0}} \cdot 10 + act\_{t\_1} \cdot (-10) -\\] - -where \\( act\_t \\) is the activity (operational level) in each time slice, subject to operational - constraints and demand requirements. - -In this case, the optimiser will prefer to dispatch the asset during \\(t\_0\\) (profitable) and -minimise operation during \\(t\_1\\) (unprofitable), subject to technical constraints such as minimum -load requirements. - -#### Profitability Index - -The profitability index is calculated as: - -\\[ -\text{PI} = \frac{\sum\_t act\_t \cdot AC\_t^{NPV}}{AFC \times cap} -\\] - -Suppose the dispatch optimiser determines \\( act\_{t\_{0}} = 80 \\) MWh and \\( act\_{t\_1} = 20 \\) -MWh are the optimal activity levels: - -\\[ -\begin{aligned} -\text{PI} &= \frac{(80 \times 10) + (20 \times (-10))}{1{,}000 \times 100} \\\\ -&= \frac{800 - 200}{100{,}000} \\\\ -&= \frac{600}{100{,}000} \\\\ -&= 0.006 -\end{aligned} -\\] - -The profitability index is then compared against all other options to determine which asset provides - the best return on investment for serving the demand. - -### LCOX Approach (Tool B) - -#### Net Cost per Unit of Activity - -**For \\(t\_0\\) (peak period):** - -\\[ -\begin{aligned} -AC\_{t\_{0}}^{LCOX} &= 5 + (2.5 \times 35) - (0.5 \times 25) \\\\ -&= 5 + 87.5 - 12.5 \\\\ -&= \text{£80/MWh} -\end{aligned} -\\] - -It costs £80 per MWh to operate during peak periods (net of heat by-product sales). - -**For \\(t_1\\) (off-peak period):** - -\\[ -\begin{aligned} -AC\_{t\_1}^{LCOX} &= 5 + (2.5 \times 25) - (0.5 \times 15) \\\\ -&= 5 + 62.5 - 7.5 \\\\ -&= \text{£60/MWh} -\end{aligned} -\\] - -It costs £60 per MWh to operate during off-peak periods, reflecting lower gas prices - and lower heat by-product value. - -#### Capacity and Dispatch Optimisation - -The optimiser determines the most cost-effective capacity and dispatch pattern to meet demand across -both time periods by minimising the total annualised cost with respect to decision variables -\\( cap \\) and \\( act\_t \\): - -\\[ -AFC \cdot cap + \sum\_t act\_t \cdot AC\_t^{LCOX} = 1{,}000 \cdot cap + act\_{t\_{0}} - \cdot 80 + act\_{t\_1} \cdot 60 -\\] - -#### Cost Index (Levelised Cost of X) - -The Cost Index is calculated as: - -\\[ -\text{Cost Index} = \frac{AFC \cdot cap + \sum\_t act\_t \cdot AC\_t^{LCOX}}{\sum\_t act\_t} -\\] - -Suppose the optimiser determines \\( cap = 100 \\) MW, \\( act\_{t\_{0}} = 150 \\) MWh, - and \\( act\_{t\_1} = 80 \\) MWh are the optimal capacity and activity levels: - -\\[ -\begin{aligned} -\text{Cost Index} &= \frac{(1{,}000 \times 100) + (150 \times 80) + (80 \times 60)}{150 + 80} \\\\ -&= \frac{100{,}000 + 12{,}000 + 4{,}800}{230} \\\\ -&= \frac{116{,}800}{230} \\\\ -&= \text{£508/MWh} -\end{aligned} -\\] - -The Cost Index is £508 per MWh of electricity produced. - This metric is compared across all supply options to identify - the lowest-cost solution for meeting demand. +- **Calculate a cost index:** This is the total annualised cost (\\( + AFC \* cap_r + \sum_{t} act_t \* AC_t \\)), divided by the annual output + \\( \sum_t act_t \\). [framework-overview]: https://energysystemsmodellinglab.github.io/MUSE2/model/index.html#framework-overview [Dispatch Optimisation Formulation]: ./dispatch_optimisation.md diff --git a/docs/release/__init__.py b/docs/release/__init__.py deleted file mode 100644 index f2505b426..000000000 --- a/docs/release/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Common functionality for working with different versions.""" - -import re -import subprocess as sp - - -def is_release_tag(tag: str) -> bool: - """Whether the git tag indicates a version. - - We don't include pre-releases. - """ - return re.match(r"^v[0-9]+\.[0-9]+\.[0-9]+$", tag) is not None - - -def get_releases() -> list[str]: - """Get all release tags for this repo, sorted by semantic version.""" - ret = sp.run( - ("git", "tag", "-l", "--sort=-version:refname"), - capture_output=True, - check=True, - encoding="utf-8", - ) - return [tag for tag in ret.stdout.splitlines() if is_release_tag(tag)] diff --git a/docs/release/patches/v2.0.0/0001-remove-unrecognised-parameter.patch b/docs/release/patches/v2.0.0/0001-remove-unrecognised-parameter.patch deleted file mode 100644 index 91602f9dd..000000000 --- a/docs/release/patches/v2.0.0/0001-remove-unrecognised-parameter.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 3129c56aea05dd2b7e88c76bb2050fded0529243 Mon Sep 17 00:00:00 2001 -From: Aurash Karimi -Date: Wed, 19 Nov 2025 09:48:11 +0000 -Subject: [PATCH] remove unrecognised parameter - ---- - book.toml | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/book.toml b/book.toml -index 41fba09c..84d181ee 100644 ---- a/book.toml -+++ b/book.toml -@@ -1,7 +1,6 @@ - [book] - authors = ["Alex Dewar"] - language = "en" --multilingual = false - src = "docs" - title = "MUSE2" - --- -2.53.0 diff --git a/docs/release_notes/upcoming.md b/docs/release_notes/upcoming.md index e4b0ad259..6d94973c4 100644 --- a/docs/release_notes/upcoming.md +++ b/docs/release_notes/upcoming.md @@ -31,6 +31,8 @@ ready to be released, carry out the following steps: - Allow for adding both a `prod` and `cons` levy to a commodity ([#969]) - Availability limits can now be provided at multiple levels for a process ([#1018]) - Pricing strategy can now vary by commodity ([#1021]) +- `marginal` and `full` commodity pricing strategies no longer require enabling + `please_give_me_broken_results` ([#1185]) ## Experimental features diff --git a/docs/templates/versions.md.jinja b/docs/templates/versions.md.jinja deleted file mode 100644 index 66360aa2d..000000000 --- a/docs/templates/versions.md.jinja +++ /dev/null @@ -1,8 +0,0 @@ -# Other versions of documentation - -The MUSE2 documentation for different releases is available below. - -- [Current development version](./README.md) -{%- for release in releases %} -- [{{ release }}](release/{{ release }}/index.html) -{%- endfor %} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index cc6d07f37..71223b651 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.94.0" +channel = "1.93.1" profile = "default" diff --git a/src/asset.rs b/src/asset.rs index 7a59d54e4..c4cc85e57 100644 --- a/src/asset.rs +++ b/src/asset.rs @@ -10,7 +10,7 @@ use crate::simulation::CommodityPrices; use crate::time_slice::{TimeSliceID, TimeSliceSelection}; use crate::units::{ Activity, ActivityPerCapacity, Capacity, Dimensionless, FlowPerActivity, MoneyPerActivity, - MoneyPerCapacity, MoneyPerFlow, Year, + MoneyPerCapacity, MoneyPerFlow, }; use anyhow::{Context, Result, ensure}; use indexmap::IndexMap; @@ -611,35 +611,33 @@ impl Asset { annual_capital_cost(capital_cost, lifetime, discount_rate) } - /// Get the annual fixed costs (AFC) per unit of activity for this asset + /// Get the annual capital cost per unit of activity for this asset /// - /// Total capital costs and fixed opex are shared equally over the year in accordance with the - /// annual activity. - pub fn get_annual_fixed_costs_per_activity( + /// Total capital costs (cost per capacity * capacity) are shared equally over the year in + /// accordance with the annual activity. + pub fn get_annual_capital_cost_per_activity( &self, annual_activity: Activity, ) -> MoneyPerActivity { let annual_capital_cost_per_capacity = self.get_annual_capital_cost_per_capacity(); - let annual_fixed_opex = self.process_parameter.fixed_operating_cost * Year(1.0); - let total_annual_fixed_costs = - (annual_capital_cost_per_capacity + annual_fixed_opex) * self.total_capacity(); + let total_annual_capital_cost = annual_capital_cost_per_capacity * self.total_capacity(); assert!( annual_activity > Activity::EPSILON, - "Cannot calculate annual fixed costs per activity for an asset with zero annual activity" + "Cannot calculate annual capital cost per activity for an asset with zero annual activity" ); - total_annual_fixed_costs / annual_activity + total_annual_capital_cost / annual_activity } - /// Get the annual fixed costs (AFC) per unit of output flow for this asset + /// Get the annual capital cost per unit of output flow for this asset /// - /// Total capital costs and fixed opex are shared equally across all output flows in accordance - /// with the annual activity and total output per unit of activity. - pub fn get_annual_fixed_costs_per_flow(&self, annual_activity: Activity) -> MoneyPerFlow { - let annual_fixed_costs_per_activity = - self.get_annual_fixed_costs_per_activity(annual_activity); + /// Total capital costs (cost per capacity * capacity) are shared equally across all output + /// flows in accordance with the annual activity and total output per unit of activity. + pub fn get_annual_capital_cost_per_flow(&self, annual_activity: Activity) -> MoneyPerFlow { + let annual_capital_cost_per_activity = + self.get_annual_capital_cost_per_activity(annual_activity); let total_output_per_activity = self.get_total_output_per_activity(); assert!(total_output_per_activity > FlowPerActivity::EPSILON); // input checks should guarantee this - annual_fixed_costs_per_activity / total_output_per_activity + annual_capital_cost_per_activity / total_output_per_activity } /// Maximum activity for this asset diff --git a/src/example/patches.rs b/src/example/patches.rs index 66dbd278f..d05f65331 100644 --- a/src/example/patches.rs +++ b/src/example/patches.rs @@ -32,6 +32,30 @@ fn get_all_patches() -> PatchMap { .with_addition("A0_RES,all,npv,,"), ], ), + ( + // The simple example with electricity priced using marginal costs + "simple_marginal", + vec![FilePatch::new("commodities.csv").with_replacement(&[ + "id,description,type,time_slice_level,pricing_strategy,units", + "GASPRD,Gas produced,sed,season,shadow,PJ", + "GASNAT,Natural gas,sed,season,shadow,PJ", + "ELCTRI,Electricity,sed,daynight,marginal,PJ", + "RSHEAT,Residential heating,svd,daynight,shadow,PJ", + "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2", + ])], + ), + ( + // The simple example with gas commodities priced using full costs + "simple_full", + vec![FilePatch::new("commodities.csv").with_replacement(&[ + "id,description,type,time_slice_level,pricing_strategy,units", + "GASPRD,Gas produced,sed,season,full,PJ", + "GASNAT,Natural gas,sed,season,full,PJ", + "ELCTRI,Electricity,sed,daynight,shadow,PJ", + "RSHEAT,Residential heating,svd,daynight,shadow,PJ", + "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2", + ])], + ), ] .into_iter() .collect() diff --git a/src/graph/investment.rs b/src/graph/investment.rs index 4af0d9797..8d014b78a 100644 --- a/src/graph/investment.rs +++ b/src/graph/investment.rs @@ -1,9 +1,8 @@ //! Module for solving the investment order of commodities use super::{CommoditiesGraph, GraphEdge, GraphNode}; -use crate::commodity::{CommodityMap, CommodityType, PricingStrategy}; +use crate::commodity::{CommodityMap, CommodityType}; use crate::region::RegionID; use crate::simulation::investment::InvestmentSet; -use anyhow::{Result, ensure}; use highs::{Col, HighsModelStatus, RowProblem, Sense}; use indexmap::IndexMap; use log::warn; @@ -42,14 +41,14 @@ fn solve_investment_order_for_year( graphs: &IndexMap<(RegionID, u32), CommoditiesGraph>, commodities: &CommodityMap, year: u32, -) -> Result> { +) -> Vec { // Initialise InvestmentGraph for this year from the set of original `CommodityGraph`s let mut investment_graph = init_investment_graph_for_year(graphs, year, commodities); // TODO: condense sibling commodities (commodities that share at least one producer) // Condense strongly connected components - investment_graph = compress_cycles(&investment_graph, commodities)?; + investment_graph = compress_cycles(&investment_graph); // Perform a topological sort on the condensed graph // We can safely unwrap because `toposort` will only return an error in case of cycles, which @@ -57,7 +56,7 @@ fn solve_investment_order_for_year( let order = toposort(&investment_graph, None).unwrap(); // Compute layers for investment - Ok(compute_layers(&investment_graph, &order)) + compute_layers(&investment_graph, &order) } /// Initialise an `InvestmentGraph` for the given year from a set of `CommodityGraph`s @@ -118,39 +117,15 @@ fn init_investment_graph_for_year( } /// Compresses cycles into `InvestmentSet::Cycle` nodes -fn compress_cycles(graph: &InvestmentGraph, commodities: &CommodityMap) -> Result { +fn compress_cycles(graph: &InvestmentGraph) -> InvestmentGraph { // Detect strongly connected components let mut condensed_graph = condensation(graph.clone(), true); // Order nodes within each strongly connected component order_sccs(&mut condensed_graph, graph); - // Pre-scan SCCs for offending pricing strategies (FullCost / MarginalCost). - for node_weight in condensed_graph.node_weights() { - if node_weight.len() <= 1 { - continue; - } - let offenders: Vec<_> = node_weight - .iter() - .flat_map(|s| s.iter_markets()) - .filter(|(cid, _)| { - matches!( - &commodities[cid].pricing_strategy, - PricingStrategy::MarginalCost | PricingStrategy::FullCost - ) - }) - .map(|(cid, _)| cid.clone()) - .collect(); - - ensure!( - offenders.is_empty(), - "Cannot use FullCost/MarginalCost pricing strategies for commodities with circular \ - dependencies. Offending commodities: {offenders:?}" - ); - } - // Map to a new InvestmentGraph - let mapped = condensed_graph.map( + condensed_graph.map( // Map nodes to InvestmentSet // If only one member, keep as-is; if multiple members, create Cycle |_, node_weight| match node_weight.len() { @@ -166,9 +141,7 @@ fn compress_cycles(graph: &InvestmentGraph, commodities: &CommodityMap) -> Resul }, // Keep edges the same |_, edge_weight| edge_weight.clone(), - ); - - Ok(mapped) + ) } /// Order the members of each strongly connected component using a mixed-integer linear program. @@ -517,13 +490,13 @@ pub fn solve_investment_order_for_model( commodity_graphs: &IndexMap<(RegionID, u32), CommoditiesGraph>, commodities: &CommodityMap, years: &[u32], -) -> Result>> { +) -> HashMap> { let mut investment_orders = HashMap::new(); for year in years { - let order = solve_investment_order_for_year(commodity_graphs, commodities, *year)?; + let order = solve_investment_order_for_year(commodity_graphs, commodities, *year); investment_orders.insert(*year, order); } - Ok(investment_orders) + investment_orders } #[cfg(test)] @@ -595,7 +568,7 @@ mod tests { commodities.insert("C".into(), Rc::new(svd_commodity)); let graphs = IndexMap::from([(("GBR".into(), 2020), graph)]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020); // Expected order: C, B, A (leaf nodes first) // No cycles or layers, so all investment sets should be `Single` @@ -623,7 +596,7 @@ mod tests { commodities.insert("B".into(), Rc::new(sed_commodity)); let graphs = IndexMap::from([(("GBR".into(), 2020), graph)]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020); // Should be a single `Cycle` investment set containing both commodities assert_eq!(result.len(), 1); @@ -662,7 +635,7 @@ mod tests { commodities.insert("D".into(), Rc::new(svd_commodity)); let graphs = IndexMap::from([(("GBR".into(), 2020), graph)]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020); // Expected order: D, Layer(B, C), A assert_eq!(result.len(), 3); @@ -701,7 +674,7 @@ mod tests { (("GBR".into(), 2020), graph.clone()), (("FRA".into(), 2020), graph), ]); - let result = solve_investment_order_for_year(&graphs, &commodities, 2020).unwrap(); + let result = solve_investment_order_for_year(&graphs, &commodities, 2020); // Expected order: Should have three layers, each with two commodities (one per region) assert_eq!(result.len(), 3); diff --git a/src/input.rs b/src/input.rs index 8ef1e1f04..7cdfcca23 100644 --- a/src/input.rs +++ b/src/input.rs @@ -263,8 +263,7 @@ pub fn load_model>(model_dir: P) -> Result { )?; // Solve investment order for each region/year - let investment_order = - solve_investment_order_for_model(&commodity_graphs, &commodities, years)?; + let investment_order = solve_investment_order_for_model(&commodity_graphs, &commodities, years); let model_path = model_dir .as_ref() diff --git a/src/input/commodity.rs b/src/input/commodity.rs index d30a79cfa..96e0601ad 100644 --- a/src/input/commodity.rs +++ b/src/input/commodity.rs @@ -164,18 +164,13 @@ fn validate_commodity(commodity: &Commodity) -> Result<()> { } } - // Gatekeep alternative pricing options - if !matches!( - commodity.pricing_strategy, - PricingStrategy::Shadow | PricingStrategy::Unpriced - ) { + // Gatekeep scarcity-adjusted pricing option + if commodity.pricing_strategy == PricingStrategy::ScarcityAdjusted { ensure!( broken_model_options_allowed(), - "Price strategies other than 'shadow' and 'unpriced' are currently experimental. \ + "The 'scarcity' pricing strategy is currently experimental. \ To run anyway, set the {ALLOW_BROKEN_OPTION_NAME} option to true." ); - } - if commodity.pricing_strategy == PricingStrategy::ScarcityAdjusted { warn!( "The pricing strategy for {} is set to 'scarcity'. Commodity prices may be \ incorrect if assets have more than one output commodity. See: {ISSUES_URL}/677", diff --git a/src/patch.rs b/src/patch.rs index 7c28c0db9..6b0b843e1 100644 --- a/src/patch.rs +++ b/src/patch.rs @@ -120,6 +120,8 @@ pub struct FilePatch { filename: String, /// The header row (optional). If `None`, the header is not checked against base files. header_row: Option>, + /// Full replacement content for this file (optional) + replacement_content: Option, /// Rows to delete (each row is a vector of fields) to_delete: CSVTable, /// Rows to add (each row is a vector of fields) @@ -132,6 +134,7 @@ impl FilePatch { FilePatch { filename: filename.into(), header_row: None, + replacement_content: None, to_delete: IndexSet::new(), to_add: IndexSet::new(), } @@ -139,6 +142,10 @@ impl FilePatch { /// Set the header row for this patch (header should be a comma-joined string, e.g. "a,b,c"). pub fn with_header(mut self, header: impl Into) -> Self { + assert!( + self.replacement_content.is_none(), + "Cannot set header when replacement content is set for this FilePatch", + ); assert!( self.header_row.is_none(), "Header already set for this FilePatch", @@ -149,8 +156,48 @@ impl FilePatch { self } + /// Set full replacement content for this file from a slice of lines. + /// + /// Each line is joined with newlines, and a trailing newline is added. + /// All lines must have the same number of columns (commas). + /// Example: `with_replacement(&["header1,header2", "value1,value2"])` + pub fn with_replacement(mut self, lines: &[&str]) -> Self { + assert!( + self.header_row.is_none(), + "Cannot set replacement content when header is set for this FilePatch", + ); + assert!( + self.to_delete.is_empty() && self.to_add.is_empty(), + "Cannot set replacement content when additions/deletions are set for this FilePatch", + ); + assert!( + self.replacement_content.is_none(), + "Replacement content already set for this FilePatch", + ); + + // Validate that all lines have the same number of columns + if !lines.is_empty() { + let first_col_count = lines[0].matches(',').count() + 1; + for (idx, line) in lines.iter().enumerate() { + let col_count = line.matches(',').count() + 1; + assert_eq!( + col_count, first_col_count, + "Line {idx} has {col_count} columns but line 0 has {first_col_count}: {line:?}" + ); + } + } + + let content = lines.join("\n") + "\n"; + self.replacement_content = Some(content); + self + } + /// Add a row to the patch (row should be a comma-joined string, e.g. "a,b,c"). pub fn with_addition(mut self, row: impl Into) -> Self { + assert!( + self.replacement_content.is_none(), + "Cannot add rows when replacement content is set for this FilePatch", + ); let s = row.into(); let v = s.split(',').map(|s| s.trim().to_string()).collect(); self.to_add.insert(v); @@ -159,6 +206,10 @@ impl FilePatch { /// Mark a row for deletion from the base (row should be a comma-joined string, e.g. "a,b,c"). pub fn with_deletion(mut self, row: impl Into) -> Self { + assert!( + self.replacement_content.is_none(), + "Cannot delete rows when replacement content is set for this FilePatch", + ); let s = row.into(); let v = s.split(',').map(|s| s.trim().to_string()).collect(); self.to_delete.insert(v); @@ -167,13 +218,21 @@ impl FilePatch { /// Apply this patch to a base model and return the modified CSV as a string. fn apply(&self, base_model_dir: &Path) -> Result { - // Read the base file to string + // Read and validate the base file path let base_path = base_model_dir.join(&self.filename); ensure!( base_path.exists() && base_path.is_file(), "Base file for patching does not exist: {}", base_path.display() ); + + // If this patch is a full replacement, validate the base file exists + // (checked above) and return the replacement content + if let Some(content) = &self.replacement_content { + return Ok(content.clone()); + } + + // Read the base file to string let base = fs::read_to_string(&base_path)?; // Apply the patch @@ -232,7 +291,6 @@ fn modify_base_with_patch(base: &str, patch: &FilePatch) -> Result { header_row_vec.join(", ") ); } - // Read all rows from the base, preserving order and checking for duplicates let mut base_rows: CSVTable = CSVTable::new(); for result in reader.records() { @@ -278,6 +336,16 @@ fn modify_base_with_patch(base: &str, patch: &FilePatch) -> Result { ); } + // Check all rows match base header length + let expected_len = base_header_vec.len(); + for row in &base_rows { + ensure!( + row.len() == expected_len, + "Row has {} columns but header has {expected_len}: {row:?}", + row.len(), + ); + } + // Serialize CSV output using csv::Writer let mut wtr = Writer::from_writer(vec![]); wtr.write_record(base_header_vec.iter())?; @@ -379,6 +447,73 @@ mod tests { assert!(assets_content.contains("GASDRV,GBR,A0_GEX,4003.26,2020")); } + #[test] + fn file_patch_with_replacement() { + let expected = "col1,col2\nnew1,new2\n"; + + let model_dir = ModelPatch::from_example("simple") + .with_file_patch( + FilePatch::new("assets.csv").with_replacement(&["col1,col2", "new1,new2"]), + ) + .build_to_tempdir() + .unwrap(); + + let assets_path = model_dir.path().join("assets.csv"); + let assets_content = std::fs::read_to_string(assets_path).unwrap(); + assert_eq!(assets_content, expected); + } + + #[test] + #[should_panic( + expected = "Cannot set replacement content when header is set for this FilePatch" + )] + fn file_patch_replacement_after_header_panics() { + let _ = FilePatch::new("assets.csv") + .with_header("col1,col2") + .with_replacement(&["col1,col2", "a,b"]); + } + + #[test] + #[should_panic( + expected = "Cannot set replacement content when additions/deletions are set for this FilePatch" + )] + fn file_patch_replacement_after_addition_panics() { + let _ = FilePatch::new("assets.csv") + .with_addition("a,b") + .with_replacement(&["col1,col2", "a,b"]); + } + + #[test] + #[should_panic(expected = "Cannot add rows when replacement content is set for this FilePatch")] + fn file_patch_addition_after_replacement_panics() { + let _ = FilePatch::new("assets.csv") + .with_replacement(&["col1,col2", "a,b"]) + .with_addition("c,d"); + } + + #[test] + fn file_patch_with_replacement_missing_base_file_fails() { + let model_patch = ModelPatch::from_example("simple").with_file_patch( + FilePatch::new("not_a_real_file.csv").with_replacement(&["x,y", "1,2"]), + ); + + let expected = format!( + "Base file for patching does not exist: {}", + std::path::PathBuf::from("examples") + .join("simple") + .join("not_a_real_file.csv") + .display() + ); + + assert_error!(model_patch.build_to_tempdir(), expected); + } + + #[test] + #[should_panic(expected = "Line 1 has 2 columns but line 0 has 3")] + fn file_patch_replacement_column_count_mismatch_panics() { + let _ = FilePatch::new("test.csv").with_replacement(&["col1,col2,col3", "a,b"]); + } + #[test] fn toml_patch() { // Patch to add an extra milestone year (2050) diff --git a/src/simulation/investment.rs b/src/simulation/investment.rs index 5e9716a7f..688bd524d 100644 --- a/src/simulation/investment.rs +++ b/src/simulation/investment.rs @@ -19,8 +19,7 @@ use std::fmt::Display; pub mod appraisal; use appraisal::coefficients::calculate_coefficients_for_assets; use appraisal::{ - AppraisalOutput, appraise_investment, count_equal_and_best_appraisal_outputs, - sort_appraisal_outputs_by_investment_priority, + AppraisalOutput, appraise_investment, sort_appraisal_outputs_by_investment_priority, }; /// A map of demand across time slices for a specific market @@ -652,7 +651,7 @@ fn get_candidate_assets<'a>( } /// Print debug message if there are multiple equally good outputs -fn log_on_equal_appraisal_outputs( +fn warn_on_equal_appraisal_outputs( outputs: &[AppraisalOutput], agent_id: &AgentID, commodity_id: &CommodityID, @@ -662,7 +661,11 @@ fn log_on_equal_appraisal_outputs( return; } - let num_identical = count_equal_and_best_appraisal_outputs(outputs); + // Count the number of identical (or nearly identical) appraisal outputs + let num_identical = outputs[1..] + .iter() + .take_while(|output| outputs[0].compare_metric(output).is_eq()) + .count(); if num_identical > 0 { let asset_details = outputs[..=num_identical] @@ -826,7 +829,7 @@ fn select_best_assets( } // Warn if there are multiple equally good assets - log_on_equal_appraisal_outputs(&outputs_for_opts, &agent.id, &commodity.id, region_id); + warn_on_equal_appraisal_outputs(&outputs_for_opts, &agent.id, &commodity.id, region_id); let best_output = outputs_for_opts.into_iter().next().unwrap(); diff --git a/src/simulation/investment/appraisal.rs b/src/simulation/investment/appraisal.rs index acbb303cb..7fbf42d68 100644 --- a/src/simulation/investment/appraisal.rs +++ b/src/simulation/investment/appraisal.rs @@ -378,21 +378,6 @@ pub fn sort_appraisal_outputs_by_investment_priority(outputs_for_opts: &mut Vec< }); } -/// Counts the number of top appraisal outputs in a sorted slice that are indistinguishable -/// by both metric and fallback ordering. Excludes the first element from the count. -pub fn count_equal_and_best_appraisal_outputs(outputs: &[AppraisalOutput]) -> usize { - if outputs.is_empty() { - return 0; - } - outputs[1..] - .iter() - .take_while(|output| { - output.compare_metric(&outputs[0]).is_eq() - && compare_asset_fallback(&output.asset, &outputs[0].asset).is_eq() - }) - .count() -} - #[cfg(test)] mod tests { use super::*; @@ -958,137 +943,4 @@ mod tests { // The invalid output should have been filtered out assert_eq!(outputs.len(), 0); } - - /// Tests for counting number of equal metrics using identical assets so only metric values - /// affect the count. - #[rstest] - #[case(vec![5.0], 0, "single_element")] - #[case(vec![5.0, 5.0, 5.0], 2, "all_equal_returns_len_minus_one")] - #[case(vec![1.0, 2.0, 3.0], 0, "none_equal_to_best")] - #[case(vec![5.0, 5.0, 9.0], 1, "partial_equality_stops_at_first_difference")] - #[case(vec![5.0, 5.0, 9.0, 5.0], 1, "equality_does_not_resume_after_gap")] - fn count_equal_best_lcox_metric( - asset: Asset, - #[case] metric_values: Vec, - #[case] expected_count: usize, - #[case] description: &str, - ) { - let metrics: Vec> = metric_values - .into_iter() - .map(|v| Box::new(LCOXMetric::new(MoneyPerActivity(v))) as Box) - .collect(); - - let outputs = - appraisal_outputs_with_investment_priority_invariant_to_assets(metrics, &asset); - - assert_eq!( - count_equal_and_best_appraisal_outputs(&outputs), - expected_count, - "Failed for case: {description}" - ); - } - - /// Empty slice count should return 0. - #[test] - fn count_equal_best_empty_slice_returns_zero() { - let outputs: Vec = vec![]; - assert_eq!(count_equal_and_best_appraisal_outputs(&outputs), 0); - } - - /// Equal metrics but differing asset fallback (commissioned vs. candidate) → - /// outputs are distinguishable, so count should be 0. - #[rstest] - fn count_equal_best_equal_metric_different_fallback_returns_zero( - process: Process, - region_id: RegionID, - agent_id: AgentID, - ) { - let process_rc = Rc::new(process); - let capacity = Capacity(10.0); - - let commissioned = Asset::new_commissioned( - agent_id.clone(), - process_rc.clone(), - region_id.clone(), - capacity, - 2020, - ) - .unwrap(); - let candidate = - Asset::new_candidate(process_rc.clone(), region_id.clone(), capacity, 2020).unwrap(); - - let metric_value = MoneyPerActivity(5.0); - let outputs = appraisal_outputs( - vec![commissioned, candidate], - vec![ - Box::new(LCOXMetric::new(metric_value)), - Box::new(LCOXMetric::new(metric_value)), - ], - ); - - assert_eq!(count_equal_and_best_appraisal_outputs(&outputs), 0); - } - - /// Equal metrics and equal asset fallback (same commissioned status and commission year) → - /// the second element is indistinguishable, so count should be 1. - #[rstest] - fn count_equal_best_equal_metric_and_equal_fallback_returns_one( - process: Process, - region_id: RegionID, - agent_id: AgentID, - ) { - let process_rc = Rc::new(process); - let capacity = Capacity(10.0); - let year = 2020; - - let asset1 = Asset::new_commissioned( - agent_id.clone(), - process_rc.clone(), - region_id.clone(), - capacity, - year, - ) - .unwrap(); - let asset2 = Asset::new_commissioned( - agent_id.clone(), - process_rc.clone(), - region_id.clone(), - capacity, - year, - ) - .unwrap(); - - let metric_value = MoneyPerActivity(5.0); - let outputs = appraisal_outputs( - vec![asset1, asset2], - vec![ - Box::new(LCOXMetric::new(metric_value)), - Box::new(LCOXMetric::new(metric_value)), - ], - ); - - assert_eq!(count_equal_and_best_appraisal_outputs(&outputs), 1); - } - - /// Equal NPV metrics and identical assets → second element should be counted. - #[rstest] - fn count_equal_best_equal_npv_metrics(asset: Asset) { - let make_npv = |surplus: f64, fixed_cost: f64| { - Box::new(NPVMetric::new(ProfitabilityIndex { - total_annualised_surplus: Money(surplus), - annualised_fixed_cost: Money(fixed_cost), - })) as Box - }; - - let metrics = vec![ - make_npv(200.0, 100.0), - make_npv(200.0, 100.0), // Equal to best - make_npv(100.0, 100.0), // Worse - ]; - - let outputs = - appraisal_outputs_with_investment_priority_invariant_to_assets(metrics, &asset); - - assert_eq!(count_equal_and_best_appraisal_outputs(&outputs), 1); - } } diff --git a/src/simulation/optimisation.rs b/src/simulation/optimisation.rs index e14926033..c86638224 100644 --- a/src/simulation/optimisation.rs +++ b/src/simulation/optimisation.rs @@ -263,14 +263,6 @@ impl Solution<'_> { .map(|((asset, time_slice), &value)| (asset, time_slice, Activity(value))) } - /// Iterate over the keys for activity for each existing asset - pub fn iter_activity_keys_for_existing( - &self, - ) -> impl Iterator { - self.iter_activity_for_existing() - .map(|(asset, time_slice, _activity)| (asset, time_slice)) - } - /// Activity for each candidate asset pub fn iter_activity_for_candidates( &self, @@ -283,14 +275,6 @@ impl Solution<'_> { .map(|((asset, time_slice), &value)| (asset, time_slice, Activity(value))) } - /// Iterate over the keys for activity for each candidate asset - pub fn iter_activity_keys_for_candidates( - &self, - ) -> impl Iterator { - self.iter_activity_for_candidates() - .map(|(asset, time_slice, _activity)| (asset, time_slice)) - } - /// Iterate over unmet demand pub fn iter_unmet_demand( &self, diff --git a/src/simulation/prices.rs b/src/simulation/prices.rs index 81c2b4f84..46dabd86d 100644 --- a/src/simulation/prices.rs +++ b/src/simulation/prices.rs @@ -8,8 +8,12 @@ use crate::time_slice::{TimeSliceID, TimeSliceInfo, TimeSliceSelection}; use crate::units::{Activity, Dimensionless, MoneyPerActivity, MoneyPerFlow, Year}; use anyhow::Result; use indexmap::IndexMap; +use itertools::iproduct; use std::collections::{HashMap, HashSet}; +/// Iterator item type for asset activity iterators +type Item<'a> = (&'a AssetRef, &'a TimeSliceID, Activity); + /// Calculate commodity prices. /// /// Calculate prices for each commodity/region/time-slice according to the commodity's configured @@ -26,81 +30,73 @@ use std::collections::{HashMap, HashSet}; /// A `CommodityPrices` mapping `(commodity, region, time_slice)` to `MoneyPerFlow` representing /// endogenous prices computed from the optimisation solution. pub fn calculate_prices(model: &Model, solution: &Solution, year: u32) -> Result { - // Collect shadow prices for all SED/SVD commodities + // Compute shadow prices for all SED/SVD commodities (needed by all strategies) let shadow_prices = CommodityPrices::from_iter(solution.iter_commodity_balance_duals()); + // Partition markets by pricing strategy into a map keyed by `PricingStrategy`. + // For now, commodities use a single strategy for all regions, but this may change in the future. + let mut pricing_sets = HashMap::new(); + for ((commodity_id, commodity), region_id) in + iproduct!(&model.commodities, model.iter_regions()) + { + if commodity.pricing_strategy == PricingStrategy::Unpriced { + continue; + } + pricing_sets + .entry(&commodity.pricing_strategy) + .or_insert_with(HashSet::new) + .insert((commodity_id.clone(), region_id.clone())); + } + // Set up empty prices map let mut result = CommodityPrices::default(); - // Get investment order for the year - prices will be calculated in the reverse of this order - let investment_order = &model.investment_order[&year]; - - // Iterate over investment sets in reverse order. Markets within the same set can be priced - // simultaneously, since they are independent (apart from Cycle sets when using the "marginal" - // and "full" strategies, which get flagged at the validation stage). - for investment_set in investment_order.iter().rev() { - // Partition markets by pricing strategy into a map keyed by `PricingStrategy`. - // For now, commodities use a single strategy for all regions, but this may change in the future. - let mut pricing_sets = HashMap::new(); - for (commodity_id, region_id) in investment_set.iter_markets() { - let commodity = &model.commodities[commodity_id]; - if commodity.pricing_strategy == PricingStrategy::Unpriced { - continue; - } - pricing_sets - .entry(&commodity.pricing_strategy) - .or_insert_with(HashSet::new) - .insert((commodity_id.clone(), region_id.clone())); - } - - // Add prices for shadow-priced commodities - if let Some(shadow_set) = pricing_sets.get(&PricingStrategy::Shadow) { - for (commodity_id, region_id, time_slice) in shadow_prices.keys() { - if shadow_set.contains(&(commodity_id.clone(), region_id.clone())) { - let price = shadow_prices - .get(commodity_id, region_id, time_slice) - .unwrap(); - result.insert(commodity_id, region_id, time_slice, price); - } + // Add prices for shadow-priced commodities + if let Some(shadow_set) = pricing_sets.get(&PricingStrategy::Shadow) { + for (commodity_id, region_id, time_slice) in shadow_prices.keys() { + if shadow_set.contains(&(commodity_id.clone(), region_id.clone())) { + let price = shadow_prices + .get(commodity_id, region_id, time_slice) + .unwrap(); + result.insert(commodity_id, region_id, time_slice, price); } } + } - // Add prices for scarcity-adjusted commodities - if let Some(scarcity_set) = pricing_sets.get(&PricingStrategy::ScarcityAdjusted) { - let scarcity_prices = calculate_scarcity_adjusted_prices( - solution.iter_activity_duals(), - &shadow_prices, - scarcity_set, - ); - result.extend(scarcity_prices); - } + // Add prices for scarcity-adjusted commodities + if let Some(scarcity_set) = pricing_sets.get(&PricingStrategy::ScarcityAdjusted) { + let scarcity_prices = calculate_scarcity_adjusted_prices( + solution.iter_activity_duals(), + &shadow_prices, + scarcity_set, + ); + result.extend(scarcity_prices); + } - // Add prices for marginal cost commodities - if let Some(marginal_set) = pricing_sets.get(&PricingStrategy::MarginalCost) { - let marginal_cost_prices = calculate_marginal_cost_prices( - solution.iter_activity_keys_for_existing(), - solution.iter_activity_keys_for_candidates(), - &result, - year, - marginal_set, - ); - result.extend(marginal_cost_prices); - } + // Add prices for marginal cost commodities + if let Some(marginal_set) = pricing_sets.get(&PricingStrategy::MarginalCost) { + let marginal_cost_prices = calculate_marginal_cost_prices( + solution.iter_activity_for_existing(), + solution.iter_activity_for_candidates(), + &shadow_prices, + year, + marginal_set, + ); + result.extend(marginal_cost_prices); + } - // Add prices for full cost commodities - if let Some(fullcost_set) = pricing_sets.get(&PricingStrategy::FullCost) { - let annual_activities = - calculate_annual_activities(solution.iter_activity_for_existing()); - let full_cost_prices = calculate_full_cost_prices( - solution.iter_activity_keys_for_existing(), - solution.iter_activity_keys_for_candidates(), - &annual_activities, - &result, - year, - fullcost_set, - ); - result.extend(full_cost_prices); - } + // Add prices for full cost commodities + if let Some(fullcost_set) = pricing_sets.get(&PricingStrategy::FullCost) { + let annual_activities = calculate_annual_activities(solution.iter_activity_for_existing()); + let full_cost_prices = calculate_full_cost_prices( + solution.iter_activity_for_existing(), + solution.iter_activity_for_candidates(), + &annual_activities, + &shadow_prices, + year, + fullcost_set, + ); + result.extend(full_cost_prices); } // Return the completed prices map @@ -274,12 +270,12 @@ fn calculate_scarcity_adjusted_prices<'a, I>( activity_duals: I, shadow_prices: &CommodityPrices, markets_to_price: &HashSet<(CommodityID, RegionID)>, -) -> HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> +) -> IndexMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> where I: Iterator, { // Calculate highest activity dual for each commodity/region/time slice - let mut highest_duals = HashMap::new(); + let mut highest_duals = IndexMap::new(); for (asset, time_slice, dual) in activity_duals { let region_id = asset.region_id(); @@ -305,7 +301,7 @@ where } // Add this to the shadow price for each commodity/region/time slice - let mut scarcity_prices = HashMap::new(); + let mut scarcity_prices = IndexMap::new(); for ((commodity, region, time_slice), highest_dual) in &highest_duals { // There should always be a shadow price for commodities we are considering here, so it // should be safe to unwrap @@ -349,12 +345,13 @@ where /// /// --- /// -/// For each region, the price in each time slice is taken from the installed asset with the highest -/// marginal cost. If there are no producers of the commodity in that region (in particular, this -/// may occur when there's no demand for the commodity), then candidate assets are considered: we -/// take the price from the candidate asset with the _lowest_ marginal cost, assuming full -/// utilisation (i.e. the single candidate asset that would be most competitive if a small amount of -/// demand was added). +/// If any existing assets produce a given commodity in a particular region and time slice, the +/// price is taken from the asset with the highest marginal cost among those existing assets. If _no_ +/// existing assets produce the commodity in that region and time slice (in particular, this will +/// occur when there's no demand for the commodity), then candidate assets are considered: we +/// take the price from the candidate asset with the _lowest_ marginal cost, assuming full utilisation +/// (i.e. the single candidate asset that would be most competitive if a small amount of demand was +/// added). /// /// Note: this should be similar to the "shadow price" strategy, which is also based on marginal /// costs of the most expensive producer, but may be more successful in cases where there are @@ -362,40 +359,47 @@ where /// /// # Arguments /// -/// * `activity_keys_for_existing` - Iterator over activity keys from optimisation solution for -/// existing assets -/// * `activity_keys_for_candidates` - Iterator over activity keys from optimisation solution for -/// candidate assets -/// * `upstream_prices` - Prices for commodities upstream of the ones we are calculating prices for +/// * `activity_for_existing` - Iterator over activity from optimisation solution for existing +/// assets +/// * `activity_for_candidates` - Iterator over activity from optimisation solution for candidate +/// assets. Note: we only need the keys, since we assume full utilisation for candidates. +/// * `annual_activities` - Map of annual activities for each asset computed by +/// `calculate_annual_activities`. This only needs to include existing assets. +/// * `shadow_prices` - Shadow prices for all commodities /// * `year` - The year for which prices are being calculated -/// * `markets_to_price` - Set of markets to calculate marginal prices for +/// * `markets_to_price` - Set of markets to calculate full cost prices for /// /// # Returns /// /// A map of marginal cost prices for the specified markets in all time slices fn calculate_marginal_cost_prices<'a, I, J>( - activity_keys_for_existing: I, - activity_keys_for_candidates: J, - upstream_prices: &CommodityPrices, + activity_for_existing: I, + activity_for_candidates: J, + shadow_prices: &CommodityPrices, year: u32, markets_to_price: &HashSet<(CommodityID, RegionID)>, -) -> HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> +) -> IndexMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> where - I: Iterator, - J: Iterator, + I: Iterator>, + J: Iterator>, { - let mut prices: HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> = HashMap::new(); + let mut prices: IndexMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> = IndexMap::new(); // Start by looking at existing assets // Calculate highest marginal cost for each commodity/region/time slice // Keep track of keys with prices - missing keys will be handled by candidates later let mut priced_by_existing = HashSet::new(); - for (asset, time_slice) in activity_keys_for_existing { + for (asset, time_slice, activity) in activity_for_existing { let region_id = asset.region_id(); + // Only proceed if the asset has non-zero activity in this time slice + if activity < Activity::EPSILON { + continue; + } + // Iterate over all the SED/SVD marginal costs for commodities we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - upstream_prices, + shadow_prices, year, time_slice, |commodity_id: &CommodityID| { @@ -414,7 +418,7 @@ where // Next, look at candidate assets for any markets not covered by existing assets // For these, we take the _lowest_ marginal cost - for (asset, time_slice) in activity_keys_for_candidates { + for (asset, time_slice, _activity) in activity_for_candidates { let region_id = asset.region_id(); // Only consider markets not already priced by existing assets @@ -429,7 +433,7 @@ where // Iterate over all the SED/SVD marginal costs for markets we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - upstream_prices, + shadow_prices, year, time_slice, |cid: &CommodityID| should_process(cid), @@ -447,10 +451,10 @@ where prices } -/// Calculate annual activities for each asset by summing across all time slices +/// Calculated annual activities for each asset by summing across all time slices fn calculate_annual_activities<'a, I>(activities: I) -> HashMap where - I: IntoIterator, + I: IntoIterator>, { activities .into_iter() @@ -496,23 +500,23 @@ where /// /// --- /// -/// For each region, the price in each time slice is taken from the installed asset with the highest -/// full cost (excluding assets with zero annual activity, as the full cost of these as calculated -/// above would be infinite). If there are no producers of the commodity in that region (in -/// particular, this may occur when there's no demand for the commodity), then candidate assets are -/// considered: we take the price from the candidate asset with the _lowest_ full cost, assuming -/// maximum possible dispatch (i.e. the single candidate asset that would be most competitive if a -/// small amount of demand was added). +/// If any existing assets produce a given commodity in a particular region and time slice, the +/// price is taken from the asset with the highest full cost among those existing assets. If _no_ +/// existing assets produce the commodity in that region and time slice (in particular, this will +/// occur when there's no demand for the commodity), then candidate assets are considered: we +/// take the price from the candidate asset with the _lowest_ full cost, assuming maximum +/// possible dispatch (i.e. the single candidate asset that would be most competitive if a small +/// amount of demand was added). /// /// # Arguments /// -/// * `activity_keys_for_existing` - Iterator over activity keys from optimisation solution for -/// existing assets -/// * `activity_keys_for_candidates` - Iterator over activity keys from optimisation solution for -/// candidate assets +/// * `activity_for_existing` - Iterator over activity from optimisation solution for existing +/// assets +/// * `activity_for_candidates` - Iterator over activity from optimisation solution for candidate +/// assets. Note: we only need the keys, since we assume full dispatch for candidates. /// * `annual_activities` - Map of annual activities for each asset computed by /// `calculate_annual_activities`. This only needs to include existing assets. -/// * `upstream_prices` - Prices for commodities upstream of the ones we are calculating prices for +/// * `shadow_prices` - Shadow prices for all commodities /// * `year` - The year for which prices are being calculated /// * `markets_to_price` - Set of markets to calculate full cost prices for /// @@ -520,31 +524,30 @@ where /// /// A map of full cost prices for the specified markets in all time slices fn calculate_full_cost_prices<'a, I, J>( - activity_keys_for_existing: I, - activity_keys_for_candidates: J, + activity_for_existing: I, + activity_for_candidates: J, annual_activities: &HashMap, - upstream_prices: &CommodityPrices, + shadow_prices: &CommodityPrices, year: u32, markets_to_price: &HashSet<(CommodityID, RegionID)>, -) -> HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> +) -> IndexMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> where - I: Iterator, - J: Iterator, + I: Iterator>, + J: Iterator>, { - let mut prices: HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> = HashMap::new(); + let mut prices: IndexMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow> = IndexMap::new(); // Start by looking at existing assets // Calculate highest full cost for each commodity/region/time slice // Keep track of keys with prices - missing keys will be handled by candidates later - let mut annual_fixed_costs_cache = HashMap::new(); + let mut annual_capital_costs_cache = HashMap::new(); let mut priced_by_existing = HashSet::new(); - for (asset, time_slice) in activity_keys_for_existing { + for (asset, time_slice, activity) in activity_for_existing { let annual_activity = annual_activities[asset]; let region_id = asset.region_id(); - // If annual activity is zero, we can't calculate a capital cost per flow, so skip this - // asset. - if annual_activity < Activity::EPSILON { + // Only proceed if the asset has non-zero activity in this time slice + if activity < Activity::EPSILON { continue; } @@ -556,20 +559,20 @@ where continue; } - // Calculate/cache annual fixed costs for this asset - let annual_fixed_costs_per_flow = *annual_fixed_costs_cache + // Calculate/cache annual capital cost for this asset + let annual_capital_cost_per_flow = *annual_capital_costs_cache .entry(asset.clone()) - .or_insert_with(|| asset.get_annual_fixed_costs_per_flow(annual_activity)); + .or_insert_with(|| asset.get_annual_capital_cost_per_flow(annual_activity)); // Iterate over all the SED/SVD marginal costs for commodities we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - upstream_prices, + shadow_prices, year, time_slice, |cid: &CommodityID| markets_to_price.contains(&(cid.clone(), region_id.clone())), ) { - // Add annual fixed costs per flow to marginal cost to get full cost - let marginal_cost = marginal_cost + annual_fixed_costs_per_flow; + // Add capital cost per flow to marginal cost to get full cost + let marginal_cost = marginal_cost + annual_capital_cost_per_flow; // Update the highest cost for this commodity/region/time slice let key = (commodity_id.clone(), region_id.clone(), time_slice.clone()); @@ -583,7 +586,7 @@ where // Next, look at candidate assets for any markets not covered by existing assets // For these we assume full utilisation, and take the _lowest_ full cost - for (asset, time_slice) in activity_keys_for_candidates { + for (asset, time_slice, _activity) in activity_for_candidates { let region_id = asset.region_id(); // Only consider markets not already priced by existing assets @@ -604,12 +607,12 @@ where continue; } - // Calculate/cache annual fixed cost per flow for this asset assuming full dispatch + // Calculate/cache annual capital cost per flow for this asset assuming full dispatch // (bound by the activity limits of the asset) - let annual_fixed_costs_per_flow = *annual_fixed_costs_cache + let annual_capital_cost_per_flow = *annual_capital_costs_cache .entry(asset.clone()) .or_insert_with(|| { - asset.get_annual_fixed_costs_per_flow( + asset.get_annual_capital_cost_per_flow( *asset .get_activity_limits_for_selection(&TimeSliceSelection::Annual) .end(), @@ -618,13 +621,13 @@ where // Iterate over all the SED/SVD marginal costs for markets we need prices for for (commodity_id, marginal_cost) in asset.iter_marginal_costs_with_filter( - upstream_prices, + shadow_prices, year, time_slice, |cid: &CommodityID| should_process(cid), ) { - // Add annual fixed costs per flow to marginal cost to get full cost - let full_cost = marginal_cost + annual_fixed_costs_per_flow; + // Add capital cost per flow to marginal cost to get full cost + let full_cost = marginal_cost + annual_capital_cost_per_flow; // Update the _lowest_ cost for this commodity/region/time slice let key = (commodity_id.clone(), region_id.clone(), time_slice.clone()); @@ -677,7 +680,6 @@ mod tests { year: u32, time_slice_info: &TimeSliceInfo, variable_operating_cost: MoneyPerActivity, - fixed_operating_cost: MoneyPerCapacityPerYear, capital_cost: MoneyPerCapacity, lifetime: u32, discount_rate: Dimensionless, @@ -688,7 +690,7 @@ mod tests { let mut process_parameter_map = HashMap::new(); let proc_param = ProcessParameter { capital_cost, - fixed_operating_cost, + fixed_operating_cost: MoneyPerCapacityPerYear(0.0), variable_operating_cost, lifetime, discount_rate, @@ -719,7 +721,7 @@ mod tests { } fn assert_price_approx( - prices: &HashMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow>, + prices: &IndexMap<(CommodityID, RegionID, TimeSliceID), MoneyPerFlow>, commodity: &CommodityID, region: &RegionID, time_slice: &TimeSliceID, @@ -813,11 +815,10 @@ mod tests { ®ion_id, 2015u32, &time_slice_info, - MoneyPerActivity(5.0), // variable operating cost - MoneyPerCapacityPerYear(0.0), // fixed operating cost - MoneyPerCapacity(0.0), // capital cost - 5, // lifetime - Dimensionless(1.0), // discount rate + MoneyPerActivity(5.0), // variable operating cost + MoneyPerCapacity(0.0), // capital cost + 5, // lifetime + Dimensionless(1.0), // discount rate ); let asset = @@ -830,7 +831,7 @@ mod tests { markets.insert((b.id.clone(), region_id.clone())); markets.insert((c.id.clone(), region_id.clone())); - let existing = vec![(&asset_ref, &time_slice)]; + let existing = vec![(&asset_ref, &time_slice, Activity(1.0))]; let candidates = Vec::new(); let prices = calculate_marginal_cost_prices( @@ -889,11 +890,10 @@ mod tests { ®ion_id, 2015u32, &time_slice_info, - MoneyPerActivity(5.0), // variable operating cost - MoneyPerCapacityPerYear(1.0), // fixed operating cost - MoneyPerCapacity(1.5), // capital cost per capacity so annualised=1.5 - 1, // lifetime so annualised = capital_cost - Dimensionless(0.0), // discount rate + MoneyPerActivity(5.0), // variable operating cost + MoneyPerCapacity(2.5), // capital cost per capacity so annualised=2.5 + 1, // lifetime so annualised = capital_cost + Dimensionless(0.0), // discount rate ); let asset = @@ -906,7 +906,7 @@ mod tests { markets.insert((b.id.clone(), region_id.clone())); markets.insert((c.id.clone(), region_id.clone())); - let existing = vec![(&asset_ref, &time_slice)]; + let existing = vec![(&asset_ref, &time_slice, Activity(2.0))]; let candidates = Vec::new(); let mut annual_activities = HashMap::new(); diff --git a/tests/data/circularity/commodity_prices.csv b/tests/data/circularity/commodity_prices.csv index d8042ea00..763694956 100644 --- a/tests/data/circularity/commodity_prices.csv +++ b/tests/data/circularity/commodity_prices.csv @@ -31,22 +31,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASPRD,GBR,autumn.day,2.20452 2020,GASPRD,GBR,autumn.peak,2.20452 2020,GASPRD,GBR,autumn.evening,2.20452 -2020,BIOPRD,GBR,winter.night,3.5869398412698414 -2020,BIOPRD,GBR,winter.day,3.5869398412698414 -2020,BIOPRD,GBR,winter.peak,3.5869398412698414 -2020,BIOPRD,GBR,winter.evening,3.5869398412698414 -2020,BIOPRD,GBR,peak.night,3.5869398412698414 -2020,BIOPRD,GBR,peak.day,3.5869398412698414 -2020,BIOPRD,GBR,peak.peak,3.5869398412698414 -2020,BIOPRD,GBR,peak.evening,3.5869398412698414 -2020,BIOPRD,GBR,summer.night,0.25 -2020,BIOPRD,GBR,summer.day,0.25 -2020,BIOPRD,GBR,summer.peak,0.25 -2020,BIOPRD,GBR,summer.evening,0.25 -2020,BIOPRD,GBR,autumn.night,3.586939841269842 -2020,BIOPRD,GBR,autumn.day,3.586939841269842 -2020,BIOPRD,GBR,autumn.peak,3.586939841269842 -2020,BIOPRD,GBR,autumn.evening,3.586939841269842 2020,GASOLI,GBR,winter.night,8.66986824186952 2020,GASOLI,GBR,winter.day,8.66986824186952 2020,GASOLI,GBR,winter.peak,8.66986824186952 @@ -95,22 +79,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASNAT,GBR,autumn.day,2.9170059999999998 2020,GASNAT,GBR,autumn.peak,2.9170059999999998 2020,GASNAT,GBR,autumn.evening,2.9170059999999998 -2020,BIOPEL,GBR,winter.night,4.7221140833333335 -2020,BIOPEL,GBR,winter.day,4.7221140833333335 -2020,BIOPEL,GBR,winter.peak,4.7221140833333335 -2020,BIOPEL,GBR,winter.evening,4.7221140833333335 -2020,BIOPEL,GBR,peak.night,4.7221140833333335 -2020,BIOPEL,GBR,peak.day,4.7221140833333335 -2020,BIOPEL,GBR,peak.peak,4.7221140833333335 -2020,BIOPEL,GBR,peak.evening,4.7221140833333335 -2020,BIOPEL,GBR,summer.night,1.21832725 -2020,BIOPEL,GBR,summer.day,1.21832725 -2020,BIOPEL,GBR,summer.peak,1.21832725 -2020,BIOPEL,GBR,summer.evening,1.21832725 -2020,BIOPEL,GBR,autumn.night,4.7221140833333335 -2020,BIOPEL,GBR,autumn.day,4.7221140833333335 -2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 -2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2020,ELCTRI,GBR,winter.night,7.993308999999999 2020,ELCTRI,GBR,winter.day,17.26223303030303 2020,ELCTRI,GBR,winter.peak,17.482621345499997 @@ -175,6 +143,38 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,RSHEAT,GBR,autumn.day,5.8665369 2020,RSHEAT,GBR,autumn.peak,5.8665369 2020,RSHEAT,GBR,autumn.evening,5.8665369 +2020,BIOPRD,GBR,winter.night,3.5869398412698414 +2020,BIOPRD,GBR,winter.day,3.5869398412698414 +2020,BIOPRD,GBR,winter.peak,3.5869398412698414 +2020,BIOPRD,GBR,winter.evening,3.5869398412698414 +2020,BIOPRD,GBR,peak.night,3.5869398412698414 +2020,BIOPRD,GBR,peak.day,3.5869398412698414 +2020,BIOPRD,GBR,peak.peak,3.5869398412698414 +2020,BIOPRD,GBR,peak.evening,3.5869398412698414 +2020,BIOPRD,GBR,summer.night,0.25 +2020,BIOPRD,GBR,summer.day,0.25 +2020,BIOPRD,GBR,summer.peak,0.25 +2020,BIOPRD,GBR,summer.evening,0.25 +2020,BIOPRD,GBR,autumn.night,3.586939841269842 +2020,BIOPRD,GBR,autumn.day,3.586939841269842 +2020,BIOPRD,GBR,autumn.peak,3.586939841269842 +2020,BIOPRD,GBR,autumn.evening,3.586939841269842 +2020,BIOPEL,GBR,winter.night,4.7221140833333335 +2020,BIOPEL,GBR,winter.day,4.7221140833333335 +2020,BIOPEL,GBR,winter.peak,4.7221140833333335 +2020,BIOPEL,GBR,winter.evening,4.7221140833333335 +2020,BIOPEL,GBR,peak.night,4.7221140833333335 +2020,BIOPEL,GBR,peak.day,4.7221140833333335 +2020,BIOPEL,GBR,peak.peak,4.7221140833333335 +2020,BIOPEL,GBR,peak.evening,4.7221140833333335 +2020,BIOPEL,GBR,summer.night,1.21832725 +2020,BIOPEL,GBR,summer.day,1.21832725 +2020,BIOPEL,GBR,summer.peak,1.21832725 +2020,BIOPEL,GBR,summer.evening,1.21832725 +2020,BIOPEL,GBR,autumn.night,4.7221140833333335 +2020,BIOPEL,GBR,autumn.day,4.7221140833333335 +2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 +2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2030,OILCRD,GBR,winter.night,3.072868 2030,OILCRD,GBR,winter.day,3.072868 2030,OILCRD,GBR,winter.peak,3.072868 @@ -207,22 +207,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASPRD,GBR,autumn.day,2.20452 2030,GASPRD,GBR,autumn.peak,2.20452 2030,GASPRD,GBR,autumn.evening,2.20452 -2030,BIOPRD,GBR,winter.night,4.249632460317461 -2030,BIOPRD,GBR,winter.day,4.249632460317461 -2030,BIOPRD,GBR,winter.peak,4.249632460317461 -2030,BIOPRD,GBR,winter.evening,4.249632460317461 -2030,BIOPRD,GBR,peak.night,1.822057119047619 -2030,BIOPRD,GBR,peak.day,1.822057119047619 -2030,BIOPRD,GBR,peak.peak,1.822057119047619 -2030,BIOPRD,GBR,peak.evening,1.822057119047619 -2030,BIOPRD,GBR,summer.night,0.25 -2030,BIOPRD,GBR,summer.day,0.25 -2030,BIOPRD,GBR,summer.peak,0.25 -2030,BIOPRD,GBR,summer.evening,0.25 -2030,BIOPRD,GBR,autumn.night,1.822057119047619 -2030,BIOPRD,GBR,autumn.day,1.822057119047619 -2030,BIOPRD,GBR,autumn.peak,1.822057119047619 -2030,BIOPRD,GBR,autumn.evening,1.822057119047619 2030,GASOLI,GBR,winter.night,5.585457080000001 2030,GASOLI,GBR,winter.day,5.585457080000001 2030,GASOLI,GBR,winter.peak,5.585457080000001 @@ -271,22 +255,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASNAT,GBR,autumn.day,2.9170059999999998 2030,GASNAT,GBR,autumn.peak,2.9170059999999998 2030,GASNAT,GBR,autumn.evening,2.9170059999999998 -2030,BIOPEL,GBR,winter.night,4.7221140833333335 -2030,BIOPEL,GBR,winter.day,4.7221140833333335 -2030,BIOPEL,GBR,winter.peak,4.7221140833333335 -2030,BIOPEL,GBR,winter.evening,4.7221140833333335 -2030,BIOPEL,GBR,peak.night,2.173159975 -2030,BIOPEL,GBR,peak.day,2.173159975 -2030,BIOPEL,GBR,peak.peak,2.173159975 -2030,BIOPEL,GBR,peak.evening,2.173159975 -2030,BIOPEL,GBR,summer.night,0.5225 -2030,BIOPEL,GBR,summer.day,0.5225 -2030,BIOPEL,GBR,summer.peak,0.5225 -2030,BIOPEL,GBR,summer.evening,0.5225 -2030,BIOPEL,GBR,autumn.night,2.173159975 -2030,BIOPEL,GBR,autumn.day,2.173159975 -2030,BIOPEL,GBR,autumn.peak,2.173159975 -2030,BIOPEL,GBR,autumn.evening,2.173159975 2030,ELCTRI,GBR,winter.night,7.993308999999999 2030,ELCTRI,GBR,winter.day,17.26223303030303 2030,ELCTRI,GBR,winter.peak,17.482621345499997 @@ -351,6 +319,38 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,RSHEAT,GBR,autumn.day,5.8665369 2030,RSHEAT,GBR,autumn.peak,5.8665369 2030,RSHEAT,GBR,autumn.evening,5.8665369 +2030,BIOPRD,GBR,winter.night,4.249632460317461 +2030,BIOPRD,GBR,winter.day,4.249632460317461 +2030,BIOPRD,GBR,winter.peak,4.249632460317461 +2030,BIOPRD,GBR,winter.evening,4.249632460317461 +2030,BIOPRD,GBR,peak.night,1.822057119047619 +2030,BIOPRD,GBR,peak.day,1.822057119047619 +2030,BIOPRD,GBR,peak.peak,1.822057119047619 +2030,BIOPRD,GBR,peak.evening,1.822057119047619 +2030,BIOPRD,GBR,summer.night,0.25 +2030,BIOPRD,GBR,summer.day,0.25 +2030,BIOPRD,GBR,summer.peak,0.25 +2030,BIOPRD,GBR,summer.evening,0.25 +2030,BIOPRD,GBR,autumn.night,1.822057119047619 +2030,BIOPRD,GBR,autumn.day,1.822057119047619 +2030,BIOPRD,GBR,autumn.peak,1.822057119047619 +2030,BIOPRD,GBR,autumn.evening,1.822057119047619 +2030,BIOPEL,GBR,winter.night,4.7221140833333335 +2030,BIOPEL,GBR,winter.day,4.7221140833333335 +2030,BIOPEL,GBR,winter.peak,4.7221140833333335 +2030,BIOPEL,GBR,winter.evening,4.7221140833333335 +2030,BIOPEL,GBR,peak.night,2.173159975 +2030,BIOPEL,GBR,peak.day,2.173159975 +2030,BIOPEL,GBR,peak.peak,2.173159975 +2030,BIOPEL,GBR,peak.evening,2.173159975 +2030,BIOPEL,GBR,summer.night,0.5225 +2030,BIOPEL,GBR,summer.day,0.5225 +2030,BIOPEL,GBR,summer.peak,0.5225 +2030,BIOPEL,GBR,summer.evening,0.5225 +2030,BIOPEL,GBR,autumn.night,2.173159975 +2030,BIOPEL,GBR,autumn.day,2.173159975 +2030,BIOPEL,GBR,autumn.peak,2.173159975 +2030,BIOPEL,GBR,autumn.evening,2.173159975 2040,OILCRD,GBR,winter.night,3.072868 2040,OILCRD,GBR,winter.day,3.072868 2040,OILCRD,GBR,winter.peak,3.072868 @@ -383,22 +383,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASPRD,GBR,autumn.day,2.20452 2040,GASPRD,GBR,autumn.peak,2.20452 2040,GASPRD,GBR,autumn.evening,2.20452 -2040,BIOPRD,GBR,winter.night,0.25 -2040,BIOPRD,GBR,winter.day,0.25 -2040,BIOPRD,GBR,winter.peak,0.25 -2040,BIOPRD,GBR,winter.evening,0.25 -2040,BIOPRD,GBR,peak.night,0.25 -2040,BIOPRD,GBR,peak.day,0.25 -2040,BIOPRD,GBR,peak.peak,0.25 -2040,BIOPRD,GBR,peak.evening,0.25 -2040,BIOPRD,GBR,summer.night,0.25 -2040,BIOPRD,GBR,summer.day,0.25 -2040,BIOPRD,GBR,summer.peak,0.25 -2040,BIOPRD,GBR,summer.evening,0.25 -2040,BIOPRD,GBR,autumn.night,0.25 -2040,BIOPRD,GBR,autumn.day,0.25 -2040,BIOPRD,GBR,autumn.peak,0.25 -2040,BIOPRD,GBR,autumn.evening,0.25 2040,GASOLI,GBR,winter.night,5.585457080000001 2040,GASOLI,GBR,winter.day,5.585457080000001 2040,GASOLI,GBR,winter.peak,5.585457080000001 @@ -431,22 +415,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASNAT,GBR,autumn.day,2.9170059999999998 2040,GASNAT,GBR,autumn.peak,2.9170059999999998 2040,GASNAT,GBR,autumn.evening,2.9170059999999998 -2040,BIOPEL,GBR,winter.night,0.5225 -2040,BIOPEL,GBR,winter.day,0.5225 -2040,BIOPEL,GBR,winter.peak,0.5225 -2040,BIOPEL,GBR,winter.evening,0.5225 -2040,BIOPEL,GBR,peak.night,0.5225 -2040,BIOPEL,GBR,peak.day,0.5225 -2040,BIOPEL,GBR,peak.peak,0.5225 -2040,BIOPEL,GBR,peak.evening,0.5225 -2040,BIOPEL,GBR,summer.night,0.5225 -2040,BIOPEL,GBR,summer.day,0.5225 -2040,BIOPEL,GBR,summer.peak,0.5225 -2040,BIOPEL,GBR,summer.evening,0.5225 -2040,BIOPEL,GBR,autumn.night,0.5225 -2040,BIOPEL,GBR,autumn.day,0.5225 -2040,BIOPEL,GBR,autumn.peak,0.5225 -2040,BIOPEL,GBR,autumn.evening,0.5225 2040,ELCTRI,GBR,winter.night,7.993308999999999 2040,ELCTRI,GBR,winter.day,7.993308999999999 2040,ELCTRI,GBR,winter.peak,7.993308999999999 @@ -511,3 +479,35 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,RSHEAT,GBR,autumn.day,0.827 2040,RSHEAT,GBR,autumn.peak,0.827 2040,RSHEAT,GBR,autumn.evening,0.827 +2040,BIOPRD,GBR,winter.night,0.25 +2040,BIOPRD,GBR,winter.day,0.25 +2040,BIOPRD,GBR,winter.peak,0.25 +2040,BIOPRD,GBR,winter.evening,0.25 +2040,BIOPRD,GBR,peak.night,0.25 +2040,BIOPRD,GBR,peak.day,0.25 +2040,BIOPRD,GBR,peak.peak,0.25 +2040,BIOPRD,GBR,peak.evening,0.25 +2040,BIOPRD,GBR,summer.night,0.25 +2040,BIOPRD,GBR,summer.day,0.25 +2040,BIOPRD,GBR,summer.peak,0.25 +2040,BIOPRD,GBR,summer.evening,0.25 +2040,BIOPRD,GBR,autumn.night,0.25 +2040,BIOPRD,GBR,autumn.day,0.25 +2040,BIOPRD,GBR,autumn.peak,0.25 +2040,BIOPRD,GBR,autumn.evening,0.25 +2040,BIOPEL,GBR,winter.night,0.5225 +2040,BIOPEL,GBR,winter.day,0.5225 +2040,BIOPEL,GBR,winter.peak,0.5225 +2040,BIOPEL,GBR,winter.evening,0.5225 +2040,BIOPEL,GBR,peak.night,0.5225 +2040,BIOPEL,GBR,peak.day,0.5225 +2040,BIOPEL,GBR,peak.peak,0.5225 +2040,BIOPEL,GBR,peak.evening,0.5225 +2040,BIOPEL,GBR,summer.night,0.5225 +2040,BIOPEL,GBR,summer.day,0.5225 +2040,BIOPEL,GBR,summer.peak,0.5225 +2040,BIOPEL,GBR,summer.evening,0.5225 +2040,BIOPEL,GBR,autumn.night,0.5225 +2040,BIOPEL,GBR,autumn.day,0.5225 +2040,BIOPEL,GBR,autumn.peak,0.5225 +2040,BIOPEL,GBR,autumn.evening,0.5225 diff --git a/tests/data/missing_commodity/commodity_prices.csv b/tests/data/missing_commodity/commodity_prices.csv index 55a52dd42..8bafd7e4b 100644 --- a/tests/data/missing_commodity/commodity_prices.csv +++ b/tests/data/missing_commodity/commodity_prices.csv @@ -15,22 +15,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASPRD,GBR,autumn.day,2.20452 2020,GASPRD,GBR,autumn.peak,2.20452 2020,GASPRD,GBR,autumn.evening,2.20452 -2020,BIOPRD,GBR,winter.night,4.249632460317461 -2020,BIOPRD,GBR,winter.day,4.249632460317461 -2020,BIOPRD,GBR,winter.peak,4.249632460317461 -2020,BIOPRD,GBR,winter.evening,4.249632460317461 -2020,BIOPRD,GBR,peak.night,4.249632460317461 -2020,BIOPRD,GBR,peak.day,4.249632460317461 -2020,BIOPRD,GBR,peak.peak,4.249632460317461 -2020,BIOPRD,GBR,peak.evening,4.249632460317461 -2020,BIOPRD,GBR,summer.night,0.25 -2020,BIOPRD,GBR,summer.day,0.25 -2020,BIOPRD,GBR,summer.peak,0.25 -2020,BIOPRD,GBR,summer.evening,0.25 -2020,BIOPRD,GBR,autumn.night,4.249632460317461 -2020,BIOPRD,GBR,autumn.day,4.249632460317461 -2020,BIOPRD,GBR,autumn.peak,4.249632460317461 -2020,BIOPRD,GBR,autumn.evening,4.249632460317461 2020,GASNAT,GBR,winter.night,2.9170059999999998 2020,GASNAT,GBR,winter.day,2.9170059999999998 2020,GASNAT,GBR,winter.peak,2.9170059999999998 @@ -47,6 +31,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASNAT,GBR,autumn.day,2.9170059999999998 2020,GASNAT,GBR,autumn.peak,2.9170059999999998 2020,GASNAT,GBR,autumn.evening,2.9170059999999998 +2020,BIOPRD,GBR,winter.night,4.249632460317461 +2020,BIOPRD,GBR,winter.day,4.249632460317461 +2020,BIOPRD,GBR,winter.peak,4.249632460317461 +2020,BIOPRD,GBR,winter.evening,4.249632460317461 +2020,BIOPRD,GBR,peak.night,4.249632460317461 +2020,BIOPRD,GBR,peak.day,4.249632460317461 +2020,BIOPRD,GBR,peak.peak,4.249632460317461 +2020,BIOPRD,GBR,peak.evening,4.249632460317461 +2020,BIOPRD,GBR,summer.night,0.25 +2020,BIOPRD,GBR,summer.day,0.25 +2020,BIOPRD,GBR,summer.peak,0.25 +2020,BIOPRD,GBR,summer.evening,0.25 +2020,BIOPRD,GBR,autumn.night,4.249632460317461 +2020,BIOPRD,GBR,autumn.day,4.249632460317461 +2020,BIOPRD,GBR,autumn.peak,4.249632460317461 +2020,BIOPRD,GBR,autumn.evening,4.249632460317461 2020,BIOPEL,GBR,winter.night,4.7221140833333335 2020,BIOPEL,GBR,winter.day,4.7221140833333335 2020,BIOPEL,GBR,winter.peak,4.7221140833333335 @@ -111,22 +111,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASPRD,GBR,autumn.day,2.20452 2030,GASPRD,GBR,autumn.peak,2.20452 2030,GASPRD,GBR,autumn.evening,2.20452 -2030,BIOPRD,GBR,winter.night,4.249632460317461 -2030,BIOPRD,GBR,winter.day,4.249632460317461 -2030,BIOPRD,GBR,winter.peak,4.249632460317461 -2030,BIOPRD,GBR,winter.evening,4.249632460317461 -2030,BIOPRD,GBR,peak.night,1.822057119047619 -2030,BIOPRD,GBR,peak.day,1.822057119047619 -2030,BIOPRD,GBR,peak.peak,1.822057119047619 -2030,BIOPRD,GBR,peak.evening,1.822057119047619 -2030,BIOPRD,GBR,summer.night,0.25 -2030,BIOPRD,GBR,summer.day,0.25 -2030,BIOPRD,GBR,summer.peak,0.25 -2030,BIOPRD,GBR,summer.evening,0.25 -2030,BIOPRD,GBR,autumn.night,1.822057119047619 -2030,BIOPRD,GBR,autumn.day,1.822057119047619 -2030,BIOPRD,GBR,autumn.peak,1.822057119047619 -2030,BIOPRD,GBR,autumn.evening,1.822057119047619 2030,GASNAT,GBR,winter.night,2.9170059999999998 2030,GASNAT,GBR,winter.day,2.9170059999999998 2030,GASNAT,GBR,winter.peak,2.9170059999999998 @@ -143,6 +127,22 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASNAT,GBR,autumn.day,2.9170059999999998 2030,GASNAT,GBR,autumn.peak,2.9170059999999998 2030,GASNAT,GBR,autumn.evening,2.9170059999999998 +2030,BIOPRD,GBR,winter.night,4.249632460317461 +2030,BIOPRD,GBR,winter.day,4.249632460317461 +2030,BIOPRD,GBR,winter.peak,4.249632460317461 +2030,BIOPRD,GBR,winter.evening,4.249632460317461 +2030,BIOPRD,GBR,peak.night,1.822057119047619 +2030,BIOPRD,GBR,peak.day,1.822057119047619 +2030,BIOPRD,GBR,peak.peak,1.822057119047619 +2030,BIOPRD,GBR,peak.evening,1.822057119047619 +2030,BIOPRD,GBR,summer.night,0.25 +2030,BIOPRD,GBR,summer.day,0.25 +2030,BIOPRD,GBR,summer.peak,0.25 +2030,BIOPRD,GBR,summer.evening,0.25 +2030,BIOPRD,GBR,autumn.night,1.822057119047619 +2030,BIOPRD,GBR,autumn.day,1.822057119047619 +2030,BIOPRD,GBR,autumn.peak,1.822057119047619 +2030,BIOPRD,GBR,autumn.evening,1.822057119047619 2030,BIOPEL,GBR,winter.night,4.7221140833333335 2030,BIOPEL,GBR,winter.day,4.7221140833333335 2030,BIOPEL,GBR,winter.peak,4.7221140833333335 diff --git a/tests/data/muse1_default/commodity_prices.csv b/tests/data/muse1_default/commodity_prices.csv index c476f1f02..097e21a2d 100644 --- a/tests/data/muse1_default/commodity_prices.csv +++ b/tests/data/muse1_default/commodity_prices.csv @@ -1,106 +1,106 @@ milestone_year,commodity_id,region_id,time_slice,price -2020,gas,R1,all-year.night,2.55 -2020,gas,R1,all-year.morning,2.55 -2020,gas,R1,all-year.afternoon,2.55 -2020,gas,R1,all-year.early-peak,2.55 -2020,gas,R1,all-year.late-peak,2.55 -2020,gas,R1,all-year.evening,2.55 2020,electricity,R1,all-year.night,-0.0 2020,electricity,R1,all-year.morning,-0.0 2020,electricity,R1,all-year.afternoon,-0.0 2020,electricity,R1,all-year.early-peak,-0.0 2020,electricity,R1,all-year.late-peak,-0.0 2020,electricity,R1,all-year.evening,-0.0 +2020,gas,R1,all-year.night,2.55 +2020,gas,R1,all-year.morning,2.55 +2020,gas,R1,all-year.afternoon,2.55 +2020,gas,R1,all-year.early-peak,2.55 +2020,gas,R1,all-year.late-peak,2.55 +2020,gas,R1,all-year.evening,2.55 2020,heat,R1,all-year.night,8.3380664049 2020,heat,R1,all-year.morning,8.3380664049 2020,heat,R1,all-year.afternoon,8.3380664049 2020,heat,R1,all-year.early-peak,8.3380664049 2020,heat,R1,all-year.late-peak,8.3380664049 2020,heat,R1,all-year.evening,8.3380664049 -2025,gas,R1,all-year.night,2.55 -2025,gas,R1,all-year.morning,2.55 -2025,gas,R1,all-year.afternoon,2.55 -2025,gas,R1,all-year.early-peak,2.55 -2025,gas,R1,all-year.late-peak,2.55 -2025,gas,R1,all-year.evening,2.55 2025,electricity,R1,all-year.night,15.26529810765 2025,electricity,R1,all-year.morning,15.26529810765 2025,electricity,R1,all-year.afternoon,15.26529810765 2025,electricity,R1,all-year.early-peak,15.26529810765 2025,electricity,R1,all-year.late-peak,15.26529810765 2025,electricity,R1,all-year.evening,15.26529810765 +2025,gas,R1,all-year.night,2.55 +2025,gas,R1,all-year.morning,2.55 +2025,gas,R1,all-year.afternoon,2.55 +2025,gas,R1,all-year.early-peak,2.55 +2025,gas,R1,all-year.late-peak,2.55 +2025,gas,R1,all-year.evening,2.55 2025,heat,R1,all-year.night,6.10611924306 2025,heat,R1,all-year.morning,6.10611924306 2025,heat,R1,all-year.afternoon,6.10611924306 2025,heat,R1,all-year.early-peak,6.10611924306 2025,heat,R1,all-year.late-peak,10.727716434449999 2025,heat,R1,all-year.evening,6.10611924306 -2030,gas,R1,all-year.night,-0.0 -2030,gas,R1,all-year.morning,-0.0 -2030,gas,R1,all-year.afternoon,-0.0 -2030,gas,R1,all-year.early-peak,-0.0 -2030,gas,R1,all-year.late-peak,-0.0 -2030,gas,R1,all-year.evening,-0.0 2030,electricity,R1,all-year.night,-0.0 2030,electricity,R1,all-year.morning,-0.0 2030,electricity,R1,all-year.afternoon,-0.0 2030,electricity,R1,all-year.early-peak,-0.0 2030,electricity,R1,all-year.late-peak,-0.0 2030,electricity,R1,all-year.evening,-0.0 +2030,gas,R1,all-year.night,-0.0 +2030,gas,R1,all-year.morning,-0.0 +2030,gas,R1,all-year.afternoon,-0.0 +2030,gas,R1,all-year.early-peak,-0.0 +2030,gas,R1,all-year.late-peak,-0.0 +2030,gas,R1,all-year.evening,-0.0 2030,heat,R1,all-year.night,-0.0 2030,heat,R1,all-year.morning,-0.0 2030,heat,R1,all-year.afternoon,-0.0 2030,heat,R1,all-year.early-peak,-0.0 2030,heat,R1,all-year.late-peak,-0.0 2030,heat,R1,all-year.evening,-0.0 -2035,gas,R1,all-year.night,-0.0 -2035,gas,R1,all-year.morning,-0.0 -2035,gas,R1,all-year.afternoon,-0.0 -2035,gas,R1,all-year.early-peak,-0.0 -2035,gas,R1,all-year.late-peak,-0.0 -2035,gas,R1,all-year.evening,-0.0 2035,electricity,R1,all-year.night,-0.0 2035,electricity,R1,all-year.morning,-0.0 2035,electricity,R1,all-year.afternoon,-0.0 2035,electricity,R1,all-year.early-peak,-0.0 2035,electricity,R1,all-year.late-peak,-0.0 2035,electricity,R1,all-year.evening,-0.0 +2035,gas,R1,all-year.night,-0.0 +2035,gas,R1,all-year.morning,-0.0 +2035,gas,R1,all-year.afternoon,-0.0 +2035,gas,R1,all-year.early-peak,-0.0 +2035,gas,R1,all-year.late-peak,-0.0 +2035,gas,R1,all-year.evening,-0.0 2035,heat,R1,all-year.night,-0.0 2035,heat,R1,all-year.morning,-0.0 2035,heat,R1,all-year.afternoon,-0.0 2035,heat,R1,all-year.early-peak,-0.0 2035,heat,R1,all-year.late-peak,-0.0 2035,heat,R1,all-year.evening,-0.0 -2040,gas,R1,all-year.night,-0.0 -2040,gas,R1,all-year.morning,-0.0 -2040,gas,R1,all-year.afternoon,-0.0 -2040,gas,R1,all-year.early-peak,-0.0 -2040,gas,R1,all-year.late-peak,-0.0 -2040,gas,R1,all-year.evening,-0.0 2040,electricity,R1,all-year.night,-0.0 2040,electricity,R1,all-year.morning,-0.0 2040,electricity,R1,all-year.afternoon,-0.0 2040,electricity,R1,all-year.early-peak,-0.0 2040,electricity,R1,all-year.late-peak,-0.0 2040,electricity,R1,all-year.evening,-0.0 +2040,gas,R1,all-year.night,-0.0 +2040,gas,R1,all-year.morning,-0.0 +2040,gas,R1,all-year.afternoon,-0.0 +2040,gas,R1,all-year.early-peak,-0.0 +2040,gas,R1,all-year.late-peak,-0.0 +2040,gas,R1,all-year.evening,-0.0 2040,heat,R1,all-year.night,-0.0 2040,heat,R1,all-year.morning,-0.0 2040,heat,R1,all-year.afternoon,-0.0 2040,heat,R1,all-year.early-peak,-0.0 2040,heat,R1,all-year.late-peak,-0.0 2040,heat,R1,all-year.evening,-0.0 -2045,gas,R1,all-year.night,-0.0 -2045,gas,R1,all-year.morning,-0.0 -2045,gas,R1,all-year.afternoon,-0.0 -2045,gas,R1,all-year.early-peak,-0.0 -2045,gas,R1,all-year.late-peak,-0.0 -2045,gas,R1,all-year.evening,-0.0 2045,electricity,R1,all-year.night,-0.0 2045,electricity,R1,all-year.morning,-0.0 2045,electricity,R1,all-year.afternoon,-0.0 2045,electricity,R1,all-year.early-peak,-0.0 2045,electricity,R1,all-year.late-peak,-0.0 2045,electricity,R1,all-year.evening,-0.0 +2045,gas,R1,all-year.night,-0.0 +2045,gas,R1,all-year.morning,-0.0 +2045,gas,R1,all-year.afternoon,-0.0 +2045,gas,R1,all-year.early-peak,-0.0 +2045,gas,R1,all-year.late-peak,-0.0 +2045,gas,R1,all-year.evening,-0.0 2045,heat,R1,all-year.night,-0.0 2045,heat,R1,all-year.morning,-0.0 2045,heat,R1,all-year.afternoon,-0.0 diff --git a/tests/data/simple_full/assets.csv b/tests/data/simple_full/assets.csv new file mode 100644 index 000000000..5f4559fa2 --- /dev/null +++ b/tests/data/simple_full/assets.csv @@ -0,0 +1,10 @@ +asset_id,process_id,region_id,agent_id,group_id,commission_year,decommission_year,capacity +0,GASDRV,GBR,A0_GEX,,2020,,4002.26 +1,GASPRC,GBR,A0_GPR,,2020,,3782.13 +2,WNDFRM,GBR,A0_ELC,,2020,2040,3.964844 +3,GASCGT,GBR,A0_ELC,,2020,2040,2.43 +4,RGASBR,GBR,A0_RES,,2020,2035,2900.0 +5,RELCHP,GBR,A0_RES,,2020,2035,399.98 +6,RGASBR,GBR,A0_RES,,2030,,355.83840587648046 +7,GASCGT,GBR,A0_ELC,,2030,2040,0.5151564434825014 +8,RGASBR,GBR,A0_RES,,2040,,3655.8189696 diff --git a/tests/data/simple_full/commodity_flows.csv b/tests/data/simple_full/commodity_flows.csv new file mode 100644 index 000000000..f7217b32f --- /dev/null +++ b/tests/data/simple_full/commodity_flows.csv @@ -0,0 +1,721 @@ +milestone_year,asset_id,commodity_id,time_slice,flow +2020,0,GASPRD,winter.night,0.0 +2020,0,CO2EMT,winter.night,0.0 +2020,0,GASPRD,winter.day,151.10360181069296 +2020,0,CO2EMT,winter.day,772.5927160580732 +2020,0,GASPRD,winter.peak,125.070625 +2020,0,CO2EMT,winter.peak,639.486105625 +2020,0,GASPRD,winter.evening,166.76083466742 +2020,0,CO2EMT,winter.evening,852.6481476545185 +2020,0,GASPRD,peak.night,0.0 +2020,0,CO2EMT,peak.night,0.0 +2020,0,GASPRD,peak.day,0.0 +2020,0,CO2EMT,peak.day,0.0 +2020,0,GASPRD,peak.peak,58.67582562255717 +2020,0,CO2EMT,peak.peak,300.00949640813485 +2020,0,GASPRD,peak.evening,166.76083466742 +2020,0,CO2EMT,peak.evening,852.6481476545185 +2020,0,GASPRD,summer.night,0.0 +2020,0,CO2EMT,summer.night,0.0 +2020,0,GASPRD,summer.day,0.0 +2020,0,CO2EMT,summer.day,0.0 +2020,0,GASPRD,summer.peak,0.0 +2020,0,CO2EMT,summer.peak,0.0 +2020,0,GASPRD,summer.evening,0.16861964795988574 +2020,0,CO2EMT,summer.evening,0.8621522600188959 +2020,0,GASPRD,autumn.night,0.0 +2020,0,CO2EMT,autumn.night,0.0 +2020,0,GASPRD,autumn.day,0.0 +2020,0,CO2EMT,autumn.day,0.0 +2020,0,GASPRD,autumn.peak,0.0 +2020,0,CO2EMT,autumn.peak,0.0 +2020,0,GASPRD,autumn.evening,163.3883025525992 +2020,0,CO2EMT,autumn.evening,835.4043909514398 +2020,1,GASPRD,winter.night,-0.0 +2020,1,GASNAT,winter.night,0.0 +2020,1,CO2EMT,winter.night,0.0 +2020,1,GASPRD,winter.day,-153.36573202936748 +2020,1,GASNAT,winter.day,146.06260193273093 +2020,1,CO2EMT,winter.day,373.40904184102664 +2020,1,GASPRD,winter.peak,-124.10114062500001 +2020,1,GASNAT,winter.peak,118.1915625 +2020,1,CO2EMT,winter.peak,302.15672953125005 +2020,1,GASPRD,winter.evening,-165.4681888237455 +2020,1,GASNAT,winter.evening,157.58875126070998 +2020,1,CO2EMT,winter.evening,402.87564259800513 +2020,1,GASPRD,peak.night,-0.0 +2020,1,GASNAT,peak.night,0.0 +2020,1,CO2EMT,peak.night,0.0 +2020,1,GASPRD,peak.day,-0.0 +2020,1,GASNAT,peak.day,0.0 +2020,1,CO2EMT,peak.day,0.0 +2020,1,GASPRD,peak.peak,-59.96847146623166 +2020,1,GASNAT,peak.peak,57.11282996783967 +2020,1,CO2EMT,peak.peak,146.00894981278213 +2020,1,GASPRD,peak.evening,-165.4681888237455 +2020,1,GASNAT,peak.evening,157.58875126070998 +2020,1,CO2EMT,peak.evening,402.87564259800513 +2020,1,GASPRD,summer.night,-0.0 +2020,1,GASNAT,summer.night,0.0 +2020,1,CO2EMT,summer.night,0.0 +2020,1,GASPRD,summer.day,-0.0 +2020,1,GASNAT,summer.day,0.0 +2020,1,CO2EMT,summer.day,0.0 +2020,1,GASPRD,summer.peak,-0.0 +2020,1,GASNAT,summer.peak,0.0 +2020,1,CO2EMT,summer.peak,0.0 +2020,1,GASPRD,summer.evening,-0.16861964795988574 +2020,1,GASNAT,summer.evening,0.1605901409141769 +2020,1,CO2EMT,summer.evening,0.41054869524709325 +2020,1,GASPRD,autumn.night,-0.0 +2020,1,GASNAT,autumn.night,0.0 +2020,1,CO2EMT,autumn.night,0.0 +2020,1,GASPRD,autumn.day,-0.0 +2020,1,GASNAT,autumn.day,0.0 +2020,1,CO2EMT,autumn.day,0.0 +2020,1,GASPRD,autumn.peak,-0.0 +2020,1,GASNAT,autumn.peak,0.0 +2020,1,CO2EMT,autumn.peak,0.0 +2020,1,GASPRD,autumn.evening,-163.3883025525992 +2020,1,GASNAT,autumn.evening,155.60790719295161 +2020,1,CO2EMT,autumn.evening,397.81161473878086 +2020,2,ELCTRI,winter.night,4.435312795545212 +2020,2,ELCTRI,winter.day,7.075379933645912 +2020,2,ELCTRI,winter.peak,1.9712501261051125 +2020,2,ELCTRI,winter.evening,2.5696653598405335 +2020,2,ELCTRI,peak.night,2.851272517283696 +2020,2,ELCTRI,peak.day,6.3713620320039785 +2020,2,ELCTRI,peak.peak,1.7776452018191917 +2020,2,ELCTRI,peak.evening,1.72484387381507 +2020,2,ELCTRI,summer.night,1.6368416242136155 +2020,2,ELCTRI,summer.day,2.9055524196533997 +2020,2,ELCTRI,summer.peak,0.9567924409494001 +2020,2,ELCTRI,summer.evening,0.7124084843502 +2020,2,ELCTRI,autumn.night,3.203281465982185 +2020,2,ELCTRI,autumn.day,6.001752635595889 +2020,2,ELCTRI,autumn.peak,1.5488393825638174 +2020,2,ELCTRI,autumn.evening,1.9008483513729915 +2020,3,GASNAT,winter.night,-7.783808997678887 +2020,3,ELCTRI,winter.night,5.189205998452591 +2020,3,CO2EMT,winter.night,397.9861540513214 +2020,3,GASNAT,winter.day,-10.010898915527838 +2020,3,ELCTRI,winter.day,6.6739326103518914 +2020,3,CO2EMT,winter.day,511.8572615509383 +2020,3,GASNAT,winter.peak,-3.2303154358423316 +2020,3,ELCTRI,winter.peak,2.1535436238948877 +2020,3,CO2EMT,winter.peak,165.1660282346184 +2020,3,GASNAT,winter.evening,-4.395089526235901 +2020,3,ELCTRI,winter.evening,2.9300596841572673 +2020,3,CO2EMT,winter.evening,224.7209274764416 +2020,3,GASNAT,peak.night,-8.382740663321101 +2020,3,ELCTRI,peak.night,5.5884937755474 +2020,3,CO2EMT,peak.night,428.6095301156078 +2020,3,GASNAT,peak.day,-11.066925767990737 +2020,3,ELCTRI,peak.day,7.3779505119938245 +2020,3,CO2EMT,peak.day,565.8519145173664 +2020,3,GASNAT,peak.peak,-3.520722822271213 +2020,3,ELCTRI,peak.peak,2.3471485481808085 +2020,3,CO2EMT,peak.peak,180.0145579027271 +2020,3,GASNAT,peak.evening,-4.790137538321099 +2020,3,ELCTRI,peak.evening,3.1934250255473997 +2020,3,CO2EMT,peak.evening,244.9197323343578 +2020,3,GASNAT,summer.night,-0.1605901409141769 +2020,3,ELCTRI,summer.night,0.1070600939427846 +2020,3,CO2EMT,summer.night,8.210973904941865 +2020,3,GASNAT,summer.day,-0.0 +2020,3,ELCTRI,summer.day,0.0 +2020,3,CO2EMT,summer.day,0.0 +2020,3,GASNAT,summer.peak,-0.0 +2020,3,ELCTRI,summer.peak,0.0 +2020,3,CO2EMT,summer.peak,0.0 +2020,3,GASNAT,summer.evening,-0.0 +2020,3,ELCTRI,summer.evening,0.0 +2020,3,CO2EMT,summer.evening,0.0 +2020,3,GASNAT,autumn.night,-8.382740663321101 +2020,3,ELCTRI,autumn.night,5.5884937755474 +2020,3,CO2EMT,autumn.night,428.6095301156078 +2020,3,GASNAT,autumn.day,-11.621339862602872 +2020,3,ELCTRI,autumn.day,7.747559908401914 +2020,3,CO2EMT,autumn.day,594.1991071748848 +2020,3,GASNAT,autumn.peak,-3.592603125 +2020,3,ELCTRI,autumn.peak,2.39506875 +2020,3,CO2EMT,autumn.peak,183.68979778124998 +2020,3,GASNAT,autumn.evening,-4.790137538321099 +2020,3,ELCTRI,autumn.evening,3.1934250255473997 +2020,3,CO2EMT,autumn.evening,244.9197323343578 +2020,4,GASNAT,winter.night,-36.31286857370999 +2020,4,RSHEAT,winter.night,31.576407455399995 +2020,4,CO2EMT,winter.night,1856.6769701737921 +2020,4,GASNAT,winter.day,-193.26973453857997 +2020,4,RSHEAT,winter.day,168.06063872919998 +2020,4,CO2EMT,winter.day,9881.881526957595 +2020,4,GASNAT,winter.peak,-104.21872974118598 +2020,4,RSHEAT,winter.peak,90.62498238363999 +2020,4,CO2EMT,winter.peak,5328.7036516668395 +2020,4,GASNAT,winter.evening,-62.62146996467999 +2020,4,RSHEAT,winter.evening,54.453452143199996 +2020,4,CO2EMT,winter.evening,3201.8357592940883 +2020,4,GASNAT,peak.night,-19.52227251698524 +2020,4,RSHEAT,peak.night,16.975889145204558 +2020,4,CO2EMT,peak.night,998.1737937934555 +2020,4,GASNAT,peak.day,-82.18418839575197 +2020,4,RSHEAT,peak.day,71.46451164847998 +2020,4,CO2EMT,peak.day,4202.077552674799 +2020,4,GASNAT,peak.peak,-58.291277616306004 +2020,4,RSHEAT,peak.peak,50.688067492440005 +2020,4,CO2EMT,peak.peak,2980.433024521726 +2020,4,GASNAT,peak.evening,-26.943315907602276 +2020,4,RSHEAT,peak.evening,23.428970354436764 +2020,4,CO2EMT,peak.evening,1377.6117423557046 +2020,4,GASNAT,summer.night,-0.0 +2020,4,RSHEAT,summer.night,0.0 +2020,4,CO2EMT,summer.night,0.0 +2020,4,GASNAT,summer.day,-0.0 +2020,4,RSHEAT,summer.day,0.0 +2020,4,CO2EMT,summer.day,0.0 +2020,4,GASNAT,summer.peak,-0.0 +2020,4,RSHEAT,summer.peak,0.0 +2020,4,CO2EMT,summer.peak,0.0 +2020,4,GASNAT,summer.evening,-0.0 +2020,4,RSHEAT,summer.evening,0.0 +2020,4,CO2EMT,summer.evening,0.0 +2020,4,GASNAT,autumn.night,-9.10896122967321 +2020,4,RSHEAT,autumn.night,7.920835851889748 +2020,4,CO2EMT,autumn.night,465.7411876731913 +2020,4,GASNAT,autumn.day,-56.69422338503598 +2020,4,RSHEAT,autumn.day,49.29932468263999 +2020,4,CO2EMT,autumn.day,2898.7756416768902 +2020,4,GASNAT,autumn.peak,-44.38022605095635 +2020,4,RSHEAT,autumn.peak,38.591500913875095 +2020,4,CO2EMT,autumn.peak,2269.160957985399 +2020,4,GASNAT,autumn.evening,-17.037675338040994 +2020,4,RSHEAT,autumn.evening,14.815369859166085 +2020,4,CO2EMT,autumn.evening,871.1363400340363 +2020,5,ELCTRI,winter.night,-9.624518793997803 +2020,5,RSHEAT,winter.night,29.165208466660005 +2020,5,ELCTRI,winter.day,-13.749312543997803 +2020,5,RSHEAT,winter.day,41.664583466660005 +2020,5,ELCTRI,winter.peak,-4.12479375 +2020,5,RSHEAT,winter.peak,12.499375 +2020,5,ELCTRI,winter.evening,-5.499725043997801 +2020,5,RSHEAT,winter.evening,16.66583346666 +2020,5,ELCTRI,peak.night,-8.439766292831097 +2020,5,RSHEAT,peak.night,25.575049372215442 +2020,5,ELCTRI,peak.day,-13.749312543997803 +2020,5,RSHEAT,peak.day,41.664583466660005 +2020,5,ELCTRI,peak.peak,-4.12479375 +2020,5,RSHEAT,peak.peak,12.499375 +2020,5,ELCTRI,peak.evening,-4.91826889936247 +2020,5,RSHEAT,peak.evening,14.903845149583242 +2020,5,ELCTRI,summer.night,-1.7439017181564 +2020,5,RSHEAT,summer.night,5.28455066108 +2020,5,ELCTRI,summer.day,-2.9055524196533997 +2020,5,RSHEAT,summer.day,8.80470430198 +2020,5,ELCTRI,summer.peak,-0.9567924409494001 +2020,5,RSHEAT,summer.peak,2.89937103318 +2020,5,ELCTRI,summer.evening,-0.7124084843502 +2020,5,RSHEAT,summer.evening,2.1588135889399998 +2020,5,ELCTRI,autumn.night,-8.791775241529585 +2020,5,RSHEAT,autumn.night,26.641743156150255 +2020,5,ELCTRI,autumn.day,-13.749312543997803 +2020,5,RSHEAT,autumn.day,41.664583466660005 +2020,5,ELCTRI,autumn.peak,-3.9439081325638172 +2020,5,RSHEAT,autumn.peak,11.9512367653449 +2020,5,ELCTRI,autumn.evening,-5.094273376920391 +2020,5,RSHEAT,autumn.evening,15.437192051273913 +2030,0,GASPRD,winter.night,0.0 +2030,0,CO2EMT,winter.night,0.0 +2030,0,GASPRD,winter.day,209.007363584943 +2030,0,CO2EMT,winter.day,1068.6546500098136 +2030,0,GASPRD,winter.peak,125.070625 +2030,0,CO2EMT,winter.peak,639.486105625 +2030,0,GASPRD,winter.evening,166.76083466742 +2030,0,CO2EMT,winter.evening,852.6481476545185 +2030,0,GASPRD,peak.night,0.0 +2030,0,CO2EMT,peak.night,0.0 +2030,0,GASPRD,peak.day,0.0 +2030,0,CO2EMT,peak.day,0.0 +2030,0,GASPRD,peak.peak,88.48378530453337 +2030,0,CO2EMT,peak.peak,452.41759426207915 +2030,0,GASPRD,peak.evening,166.76083466742 +2030,0,CO2EMT,peak.evening,852.6481476545185 +2030,0,GASPRD,summer.night,0.0 +2030,0,CO2EMT,summer.night,0.0 +2030,0,GASPRD,summer.day,0.0 +2030,0,CO2EMT,summer.day,0.0 +2030,0,GASPRD,summer.peak,0.0 +2030,0,CO2EMT,summer.peak,0.0 +2030,0,GASPRD,summer.evening,0.464792220809886 +2030,0,CO2EMT,summer.evening,2.3764826250009476 +2030,0,GASPRD,autumn.night,0.0 +2030,0,CO2EMT,autumn.night,0.0 +2030,0,GASPRD,autumn.day,0.0 +2030,0,CO2EMT,autumn.day,0.0 +2030,0,GASPRD,autumn.peak,20.534211026060376 +2030,0,CO2EMT,autumn.peak,104.99142097624672 +2030,0,GASPRD,autumn.evening,166.76083466742 +2030,0,CO2EMT,autumn.evening,852.6481476545185 +2030,1,GASPRD,winter.night,-0.0 +2030,1,GASNAT,winter.night,0.0 +2030,1,CO2EMT,winter.night,0.0 +2030,1,GASPRD,winter.day,-211.26949380361748 +2030,1,GASNAT,winter.day,201.2090417177309 +2030,1,CO2EMT,winter.day,514.3909151513791 +2030,1,GASPRD,winter.peak,-124.10114062500001 +2030,1,GASNAT,winter.peak,118.1915625 +2030,1,CO2EMT,winter.peak,302.15672953125005 +2030,1,GASPRD,winter.evening,-165.4681888237455 +2030,1,GASNAT,winter.evening,157.58875126070998 +2030,1,CO2EMT,winter.evening,402.87564259800513 +2030,1,GASPRD,peak.night,-0.0 +2030,1,GASNAT,peak.night,0.0 +2030,1,CO2EMT,peak.night,0.0 +2030,1,GASPRD,peak.day,-0.0 +2030,1,GASNAT,peak.day,0.0 +2030,1,CO2EMT,peak.day,0.0 +2030,1,GASPRD,peak.peak,-89.77643114820788 +2030,1,GASNAT,peak.peak,85.50136299829322 +2030,1,CO2EMT,peak.peak,218.58423450513664 +2030,1,GASPRD,peak.evening,-165.4681888237455 +2030,1,GASNAT,peak.evening,157.58875126070998 +2030,1,CO2EMT,peak.evening,402.87564259800513 +2030,1,GASPRD,summer.night,-0.0 +2030,1,GASNAT,summer.night,0.0 +2030,1,CO2EMT,summer.night,0.0 +2030,1,GASPRD,summer.day,-0.0 +2030,1,GASNAT,summer.day,0.0 +2030,1,CO2EMT,summer.day,0.0 +2030,1,GASPRD,summer.peak,-0.0 +2030,1,GASNAT,summer.peak,0.0 +2030,1,CO2EMT,summer.peak,0.0 +2030,1,GASPRD,summer.evening,-0.464792220809886 +2030,1,GASNAT,summer.evening,0.44265925791417715 +2030,1,CO2EMT,summer.evening,1.131658392857594 +2030,1,GASPRD,autumn.night,-0.0 +2030,1,GASNAT,autumn.night,0.0 +2030,1,CO2EMT,autumn.night,0.0 +2030,1,GASPRD,autumn.day,-0.0 +2030,1,GASNAT,autumn.day,0.0 +2030,1,CO2EMT,autumn.day,0.0 +2030,1,GASPRD,autumn.peak,-21.826856869734893 +2030,1,GASNAT,autumn.peak,20.78748273308085 +2030,1,CO2EMT,autumn.peak,53.1431996071212 +2030,1,GASPRD,autumn.evening,-165.4681888237455 +2030,1,GASNAT,autumn.evening,157.58875126070998 +2030,1,CO2EMT,autumn.evening,402.87564259800513 +2030,2,ELCTRI,winter.night,4.435312795545212 +2030,2,ELCTRI,winter.day,7.075379933645912 +2030,2,ELCTRI,winter.peak,1.9712501261051125 +2030,2,ELCTRI,winter.evening,2.5696653598405335 +2030,2,ELCTRI,peak.night,2.851272517283696 +2030,2,ELCTRI,peak.day,6.3713620320039785 +2030,2,ELCTRI,peak.peak,1.7776452018191917 +2030,2,ELCTRI,peak.evening,1.72484387381507 +2030,2,ELCTRI,summer.night,1.6368416242136155 +2030,2,ELCTRI,summer.day,3.2188600626534005 +2030,2,ELCTRI,summer.peak,1.0599640039494003 +2030,2,ELCTRI,summer.evening,0.7892279633502001 +2030,2,ELCTRI,autumn.night,3.203281465982185 +2030,2,ELCTRI,autumn.day,6.001752635595889 +2030,2,ELCTRI,autumn.peak,1.5488393825638174 +2030,2,ELCTRI,autumn.evening,1.9008483513729915 +2030,3,GASNAT,winter.night,-7.783808997678887 +2030,3,ELCTRI,winter.night,5.189205998452591 +2030,3,CO2EMT,winter.night,397.9861540513214 +2030,3,GASNAT,winter.day,-10.010898915527838 +2030,3,ELCTRI,winter.day,6.6739326103518914 +2030,3,CO2EMT,winter.day,511.8572615509383 +2030,3,GASNAT,winter.peak,-2.468688831431171 +2030,3,ELCTRI,winter.peak,1.6457925542874472 +2030,3,CO2EMT,winter.peak,126.22405995107574 +2030,3,GASNAT,winter.evening,-3.3795873788970026 +2030,3,ELCTRI,winter.evening,2.253058252598002 +2030,3,CO2EMT,winter.evening,172.79830268300373 +2030,3,GASNAT,peak.night,-8.382740663321101 +2030,3,ELCTRI,peak.night,5.588493775547401 +2030,3,CO2EMT,peak.night,428.60953011560787 +2030,3,GASNAT,peak.day,-11.066925767990737 +2030,3,ELCTRI,peak.day,7.3779505119938245 +2030,3,CO2EMT,peak.day,565.8519145173664 +2030,3,GASNAT,peak.peak,-3.520722822271213 +2030,3,ELCTRI,peak.peak,2.3471485481808085 +2030,3,CO2EMT,peak.peak,180.0145579027271 +2030,3,GASNAT,peak.evening,-4.646819607935198 +2030,3,ELCTRI,peak.evening,3.0978797386234653 +2030,3,CO2EMT,peak.evening,237.59188655372665 +2030,3,GASNAT,summer.night,-0.0 +2030,3,ELCTRI,summer.night,0.0 +2030,3,CO2EMT,summer.night,0.0 +2030,3,GASNAT,summer.day,-0.0 +2030,3,ELCTRI,summer.day,0.0 +2030,3,CO2EMT,summer.day,0.0 +2030,3,GASNAT,summer.peak,-0.0 +2030,3,ELCTRI,summer.peak,0.0 +2030,3,CO2EMT,summer.peak,0.0 +2030,3,GASNAT,summer.evening,-0.0 +2030,3,ELCTRI,summer.evening,0.0 +2030,3,CO2EMT,summer.evening,0.0 +2030,3,GASNAT,autumn.night,-7.854727240273368 +2030,3,ELCTRI,autumn.night,5.236484826848912 +2030,3,CO2EMT,autumn.night,401.61220379517727 +2030,3,GASNAT,autumn.day,-11.621339862602872 +2030,3,ELCTRI,autumn.day,7.747559908401914 +2030,3,CO2EMT,autumn.day,594.1991071748848 +2030,3,GASNAT,autumn.peak,-3.592603125 +2030,3,ELCTRI,autumn.peak,2.39506875 +2030,3,CO2EMT,autumn.peak,183.68979778124998 +2030,3,GASNAT,autumn.evening,-4.3828128915983156 +2030,3,ELCTRI,autumn.evening,2.921875261065544 +2030,3,CO2EMT,autumn.evening,224.09322314742187 +2030,4,GASNAT,winter.night,-43.845148578709995 +2030,4,RSHEAT,winter.night,38.1262161554 +2030,4,CO2EMT,winter.night,2241.8024468294425 +2030,4,GASNAT,winter.day,-219.27676569358 +2030,4,RSHEAT,winter.day,190.6754484292 +2030,4,CO2EMT,winter.day,11211.621029912745 +2030,4,GASNAT,winter.peak,-104.21874999999999 +2030,4,RSHEAT,winter.peak,90.625 +2030,4,CO2EMT,winter.peak,5328.704687500001 +2030,4,GASNAT,winter.evening,-71.44063561968 +2030,4,RSHEAT,winter.evening,62.1222918432 +2030,4,CO2EMT,winter.evening,3652.7596992342387 +2030,4,GASNAT,peak.night,-0.0 +2030,4,RSHEAT,peak.night,0.0 +2030,4,CO2EMT,peak.night,0.0 +2030,4,GASNAT,peak.day,-96.21279149075198 +2030,4,RSHEAT,peak.day,83.66329694848 +2030,4,CO2EMT,peak.day,4919.3600289221495 +2030,4,GASNAT,peak.peak,-66.12685298630602 +2030,4,RSHEAT,peak.peak,57.50161129244002 +2030,4,CO2EMT,peak.peak,3381.0659931898267 +2030,4,GASNAT,peak.evening,-29.670500177964005 +2030,4,RSHEAT,peak.evening,25.800434937360006 +2030,4,CO2EMT,peak.evening,1517.0526740992998 +2030,4,GASNAT,summer.night,-0.0 +2030,4,RSHEAT,summer.night,0.0 +2030,4,CO2EMT,summer.night,0.0 +2030,4,GASNAT,summer.day,-0.0 +2030,4,RSHEAT,summer.day,0.0 +2030,4,CO2EMT,summer.day,0.0 +2030,4,GASNAT,summer.peak,-0.0 +2030,4,RSHEAT,summer.peak,0.0 +2030,4,CO2EMT,summer.peak,0.0 +2030,4,GASNAT,summer.evening,-0.0 +2030,4,RSHEAT,summer.evening,0.0 +2030,4,CO2EMT,summer.evening,0.0 +2030,4,GASNAT,autumn.night,-0.0 +2030,4,RSHEAT,autumn.night,0.0 +2030,4,CO2EMT,autumn.night,0.0 +2030,4,GASNAT,autumn.day,-67.97422666003601 +2030,4,RSHEAT,autumn.day,59.10802318264001 +2030,4,CO2EMT,autumn.day,3475.5222091276414 +2030,4,GASNAT,autumn.peak,-50.017432516103 +2030,4,RSHEAT,autumn.peak,43.49341957922 +2030,4,CO2EMT,autumn.peak,2557.391324548347 +2030,4,GASNAT,autumn.evening,-19.376214580347 +2030,4,RSHEAT,autumn.evening,16.84888224378 +2030,4,CO2EMT,autumn.evening,990.7058514931422 +2030,5,ELCTRI,winter.night,-9.624518793997803 +2030,5,RSHEAT,winter.night,29.165208466660005 +2030,5,ELCTRI,winter.day,-13.749312543997803 +2030,5,RSHEAT,winter.day,41.664583466660005 +2030,5,ELCTRI,winter.peak,-4.12479375 +2030,5,RSHEAT,winter.peak,12.499375 +2030,5,ELCTRI,winter.evening,-5.499725043997801 +2030,5,RSHEAT,winter.evening,16.66583346666 +2030,5,ELCTRI,peak.night,-9.624518793997803 +2030,5,RSHEAT,peak.night,29.165208466660005 +2030,5,ELCTRI,peak.day,-13.749312543997803 +2030,5,RSHEAT,peak.day,41.664583466660005 +2030,5,ELCTRI,peak.peak,-4.12479375 +2030,5,RSHEAT,peak.peak,12.499375 +2030,5,ELCTRI,peak.evening,-5.499725043997801 +2030,5,RSHEAT,peak.evening,16.66583346666 +2030,5,ELCTRI,summer.night,-1.9319477961564002 +2030,5,RSHEAT,summer.night,5.85438726108 +2030,5,ELCTRI,summer.day,-3.2188600626534005 +2030,5,RSHEAT,summer.day,9.75412140198 +2030,5,ELCTRI,summer.peak,-1.0599640039494003 +2030,5,RSHEAT,summer.peak,3.2120121331800005 +2030,5,ELCTRI,summer.evening,-0.7892279633502001 +2030,5,RSHEAT,summer.evening,2.39159988894 +2030,5,ELCTRI,autumn.night,-9.624518793997803 +2030,5,RSHEAT,autumn.night,29.165208466660005 +2030,5,ELCTRI,autumn.day,-13.749312543997803 +2030,5,RSHEAT,autumn.day,41.664583466660005 +2030,5,ELCTRI,autumn.peak,-4.12479375 +2030,5,RSHEAT,autumn.peak,12.499375 +2030,5,ELCTRI,autumn.evening,-5.499725043997801 +2030,5,RSHEAT,autumn.evening,16.66583346666 +2030,6,GASNAT,winter.night,-0.0 +2030,6,RSHEAT,winter.night,0.0 +2030,6,CO2EMT,winter.night,0.0 +2030,6,GASNAT,winter.day,-0.0 +2030,6,RSHEAT,winter.day,0.0 +2030,6,CO2EMT,winter.day,0.0 +2030,6,GASNAT,winter.peak,-12.787942711186016 +2030,6,RSHEAT,winter.peak,11.119950183640015 +2030,6,CO2EMT,winter.peak,653.8475108229411 +2030,6,GASNAT,winter.evening,-0.0 +2030,6,RSHEAT,winter.evening,0.0 +2030,6,CO2EMT,winter.evening,0.0 +2030,6,GASNAT,peak.night,-20.670129843374 +2030,6,RSHEAT,peak.night,17.97402595076 +2030,6,CO2EMT,peak.night,1056.8637388917127 +2030,6,GASNAT,peak.day,-0.0 +2030,6,RSHEAT,peak.day,0.0 +2030,6,CO2EMT,peak.day,0.0 +2030,6,GASNAT,peak.peak,-0.0 +2030,6,RSHEAT,peak.peak,0.0 +2030,6,CO2EMT,peak.peak,0.0 +2030,6,GASNAT,peak.evening,-0.0 +2030,6,RSHEAT,peak.evening,0.0 +2030,6,CO2EMT,peak.evening,0.0 +2030,6,GASNAT,summer.night,-0.0 +2030,6,RSHEAT,summer.night,0.0 +2030,6,CO2EMT,summer.night,0.0 +2030,6,GASNAT,summer.day,-0.0 +2030,6,RSHEAT,summer.day,0.0 +2030,6,CO2EMT,summer.day,0.0 +2030,6,GASNAT,summer.peak,-0.0 +2030,6,RSHEAT,summer.peak,0.0 +2030,6,CO2EMT,summer.peak,0.0 +2030,6,GASNAT,summer.evening,-0.0 +2030,6,RSHEAT,summer.evening,0.0 +2030,6,CO2EMT,summer.evening,0.0 +2030,6,GASNAT,autumn.night,-10.492917792587003 +2030,6,RSHEAT,autumn.night,9.124276341380003 +2030,6,CO2EMT,autumn.night,536.5028867349736 +2030,6,GASNAT,autumn.day,-0.0 +2030,6,RSHEAT,autumn.day,0.0 +2030,6,CO2EMT,autumn.day,0.0 +2030,6,GASNAT,autumn.peak,-0.0 +2030,6,RSHEAT,autumn.peak,0.0 +2030,6,CO2EMT,autumn.peak,0.0 +2030,6,GASNAT,autumn.evening,-0.0 +2030,6,RSHEAT,autumn.evening,0.0 +2030,6,CO2EMT,autumn.evening,0.0 +2030,7,GASNAT,winter.night,-0.0 +2030,7,ELCTRI,winter.night,0.0 +2030,7,CO2EMT,winter.night,0.0 +2030,7,GASNAT,winter.day,-0.0 +2030,7,ELCTRI,winter.day,0.0 +2030,7,CO2EMT,winter.day,0.0 +2030,7,GASNAT,winter.peak,-0.7616266044111606 +2030,7,ELCTRI,winter.peak,0.5077510696074404 +2030,7,CO2EMT,winter.peak,38.94196828354264 +2030,7,GASNAT,winter.evening,-1.0155021473388979 +2030,7,ELCTRI,winter.evening,0.6770014315592653 +2030,7,CO2EMT,winter.evening,51.92262479343785 +2030,7,GASNAT,peak.night,-1.7771287517500585 +2030,7,ELCTRI,peak.night,1.1847525011667057 +2030,7,CO2EMT,peak.night,90.86459307698048 +2030,7,GASNAT,peak.day,-0.0 +2030,7,ELCTRI,peak.day,0.0 +2030,7,CO2EMT,peak.day,0.0 +2030,7,GASNAT,peak.peak,-0.0 +2030,7,ELCTRI,peak.peak,0.0 +2030,7,CO2EMT,peak.peak,0.0 +2030,7,GASNAT,peak.evening,-1.0155021473388979 +2030,7,ELCTRI,peak.evening,0.6770014315592653 +2030,7,CO2EMT,peak.evening,51.92262479343785 +2030,7,GASNAT,summer.night,-0.44265925791417715 +2030,7,ELCTRI,summer.night,0.29510617194278477 +2030,7,CO2EMT,summer.night,22.633167857151875 +2030,7,GASNAT,summer.day,-0.0 +2030,7,ELCTRI,summer.day,0.0 +2030,7,CO2EMT,summer.day,0.0 +2030,7,GASNAT,summer.peak,-0.0 +2030,7,ELCTRI,summer.peak,0.0 +2030,7,CO2EMT,summer.peak,0.0 +2030,7,GASNAT,summer.evening,-0.0 +2030,7,ELCTRI,summer.evening,0.0 +2030,7,CO2EMT,summer.evening,0.0 +2030,7,GASNAT,autumn.night,-1.7771287517500585 +2030,7,ELCTRI,autumn.night,1.1847525011667057 +2030,7,CO2EMT,autumn.night,90.86459307698048 +2030,7,GASNAT,autumn.day,-0.0 +2030,7,ELCTRI,autumn.day,0.0 +2030,7,CO2EMT,autumn.day,0.0 +2030,7,GASNAT,autumn.peak,-0.27132842615427455 +2030,7,ELCTRI,autumn.peak,0.18088561743618303 +2030,7,CO2EMT,autumn.peak,13.873022429268056 +2030,7,GASNAT,autumn.evening,-1.0155021473388979 +2030,7,ELCTRI,autumn.evening,0.6770014315592653 +2030,7,CO2EMT,autumn.evening,51.92262479343785 +2040,0,GASPRD,winter.night,0.0 +2040,0,CO2EMT,winter.night,0.0 +2040,0,GASPRD,winter.day,360.96396982311984 +2040,0,CO2EMT,winter.day,1845.6087777056118 +2040,0,GASPRD,winter.peak,125.070625 +2040,0,CO2EMT,winter.peak,639.486105625 +2040,0,GASPRD,winter.evening,166.76083466742 +2040,0,CO2EMT,winter.evening,852.6481476545185 +2040,0,GASPRD,peak.night,0.0 +2040,0,CO2EMT,peak.night,0.0 +2040,0,GASPRD,peak.day,85.71569060312174 +2040,0,CO2EMT,peak.day,438.2643260537615 +2040,0,GASPRD,peak.peak,125.070625 +2040,0,CO2EMT,peak.peak,639.486105625 +2040,0,GASPRD,peak.evening,166.76083466742 +2040,0,CO2EMT,peak.evening,852.6481476545185 +2040,0,GASPRD,summer.night,0.0 +2040,0,CO2EMT,summer.night,0.0 +2040,0,GASPRD,summer.day,0.0 +2040,0,CO2EMT,summer.day,0.0 +2040,0,GASPRD,summer.peak,0.0 +2040,0,CO2EMT,summer.peak,0.0 +2040,0,GASPRD,summer.evening,28.106738155604855 +2040,0,CO2EMT,summer.evening,143.70975218960763 +2040,0,GASPRD,autumn.night,0.0 +2040,0,CO2EMT,autumn.night,0.0 +2040,0,GASPRD,autumn.day,11.030571054582595 +2040,0,CO2EMT,autumn.day,56.39930980208081 +2040,0,GASPRD,autumn.peak,125.070625 +2040,0,CO2EMT,autumn.peak,639.486105625 +2040,0,GASPRD,autumn.evening,166.76083466742 +2040,0,CO2EMT,autumn.evening,852.6481476545185 +2040,1,GASPRD,winter.night,-289.5693294487456 +2040,1,GASNAT,winter.night,275.78031376071004 +2040,1,CO2EMT,winter.night,705.0323721292552 +2040,1,GASPRD,winter.day,-73.65677059304869 +2040,1,GASNAT,winter.day,70.14930532671303 +2040,1,CO2EMT,winter.day,179.33669906774188 +2040,1,GASPRD,winter.peak,-124.10114062500001 +2040,1,GASNAT,winter.peak,118.1915625 +2040,1,CO2EMT,winter.peak,302.15672953125005 +2040,1,GASPRD,winter.evening,-165.4681888237455 +2040,1,GASNAT,winter.evening,157.58875126070998 +2040,1,CO2EMT,winter.evening,402.87564259800513 +2040,1,GASPRD,peak.night,-0.0 +2040,1,GASNAT,peak.night,0.0 +2040,1,CO2EMT,peak.night,0.0 +2040,1,GASPRD,peak.day,-87.97782082179623 +2040,1,GASNAT,peak.day,83.78840078266308 +2040,1,CO2EMT,peak.day,214.20504660087818 +2040,1,GASPRD,peak.peak,-124.10114062500001 +2040,1,GASNAT,peak.peak,118.1915625 +2040,1,CO2EMT,peak.peak,302.15672953125005 +2040,1,GASPRD,peak.evening,-165.4681888237455 +2040,1,GASNAT,peak.evening,157.58875126070998 +2040,1,CO2EMT,peak.evening,402.87564259800513 +2040,1,GASPRD,summer.night,-0.0 +2040,1,GASNAT,summer.night,0.0 +2040,1,CO2EMT,summer.night,0.0 +2040,1,GASPRD,summer.day,-0.0 +2040,1,GASNAT,summer.day,0.0 +2040,1,CO2EMT,summer.day,0.0 +2040,1,GASPRD,summer.peak,-0.0 +2040,1,GASNAT,summer.peak,0.0 +2040,1,CO2EMT,summer.peak,0.0 +2040,1,GASPRD,summer.evening,-28.106738155604855 +2040,1,GASNAT,summer.evening,26.768322052957004 +2040,1,CO2EMT,summer.evening,68.43321532838459 +2040,1,GASPRD,autumn.night,-0.0 +2040,1,GASNAT,autumn.night,0.0 +2040,1,CO2EMT,autumn.night,0.0 +2040,1,GASPRD,autumn.day,-13.292701273257066 +2040,1,GASNAT,autumn.day,12.659715498340063 +2040,1,CO2EMT,autumn.day,32.36456267150637 +2040,1,GASPRD,autumn.peak,-124.10114062500001 +2040,1,GASNAT,autumn.peak,118.1915625 +2040,1,CO2EMT,autumn.peak,302.15672953125005 +2040,1,GASPRD,autumn.evening,-165.4681888237455 +2040,1,GASNAT,autumn.evening,157.58875126070998 +2040,1,CO2EMT,autumn.evening,402.87564259800513 +2040,6,GASNAT,winter.night,-29.838533129172095 +2040,6,RSHEAT,winter.night,25.94655054710617 +2040,6,CO2EMT,winter.night,1525.6441988945694 +2040,6,GASNAT,winter.day,-42.62647584035811 +2040,6,RSHEAT,winter.day,37.066500730746185 +2040,6,CO2EMT,winter.day,2179.4917097175103 +2040,6,GASNAT,winter.peak,-12.787942711186016 +2040,6,RSHEAT,winter.peak,11.119950183640015 +2040,6,CO2EMT,winter.peak,653.8475108229411 +2040,6,GASNAT,winter.evening,-17.050590417986076 +2040,6,RSHEAT,winter.evening,14.826600363466154 +2040,6,CO2EMT,winter.evening,871.7966880716282 +2040,6,GASNAT,peak.night,-29.838533129172095 +2040,6,RSHEAT,peak.night,25.94655054710617 +2040,6,CO2EMT,peak.night,1525.6441988945694 +2040,6,GASNAT,peak.day,-42.62647584035811 +2040,6,RSHEAT,peak.day,37.066500730746185 +2040,6,CO2EMT,peak.day,2179.4917097175103 +2040,6,GASNAT,peak.peak,-12.787942711186016 +2040,6,RSHEAT,peak.peak,11.119950183640015 +2040,6,CO2EMT,peak.peak,653.8475108229411 +2040,6,GASNAT,peak.evening,-17.050590417986076 +2040,6,RSHEAT,peak.evening,14.826600363466154 +2040,6,CO2EMT,peak.evening,871.7966880716282 +2040,6,GASNAT,summer.night,-0.0 +2040,6,RSHEAT,summer.night,0.0 +2040,6,CO2EMT,summer.night,0.0 +2040,6,GASNAT,summer.day,-0.0 +2040,6,RSHEAT,summer.day,0.0 +2040,6,CO2EMT,summer.day,0.0 +2040,6,GASNAT,summer.peak,-0.0 +2040,6,RSHEAT,summer.peak,0.0 +2040,6,CO2EMT,summer.peak,0.0 +2040,6,GASNAT,summer.evening,-0.0 +2040,6,RSHEAT,summer.evening,0.0 +2040,6,CO2EMT,summer.evening,0.0 +2040,6,GASNAT,autumn.night,-29.838533129172095 +2040,6,RSHEAT,autumn.night,25.94655054710617 +2040,6,CO2EMT,autumn.night,1525.6441988945694 +2040,6,GASNAT,autumn.day,-42.62647584035811 +2040,6,RSHEAT,autumn.day,37.066500730746185 +2040,6,CO2EMT,autumn.day,2179.4917097175103 +2040,6,GASNAT,autumn.peak,-12.787942711186016 +2040,6,RSHEAT,autumn.peak,11.119950183640015 +2040,6,CO2EMT,autumn.peak,653.8475108229411 +2040,6,GASNAT,autumn.evening,-17.050590417986076 +2040,6,RSHEAT,autumn.evening,14.826600363466154 +2040,6,CO2EMT,autumn.evening,871.7966880716282 +2040,8,GASNAT,winter.night,-55.07888519119691 +2040,8,RSHEAT,winter.night,47.894682774953836 +2040,8,CO2EMT,winter.night,2816.183399825898 +2040,8,GASNAT,winter.day,-250.5715919948809 +2040,8,RSHEAT,winter.day,217.88834086511383 +2040,8,CO2EMT,winter.day,12811.72549869826 +2040,8,GASNAT,winter.peak,-131.38099422 +2040,8,RSHEAT,winter.peak,114.2443428 +2040,8,CO2EMT,winter.peak,6717.5102344686 +2040,8,GASNAT,winter.evening,-82.37491934335293 +2040,8,RSHEAT,winter.evening,71.63036464639386 +2040,8,CO2EMT,winter.evening,4211.829626025636 +2040,8,GASNAT,peak.night,-29.648126735860906 +2040,8,RSHEAT,peak.night,25.780979770313834 +2040,8,CO2EMT,peak.night,1515.9087200045683 +2040,8,GASNAT,peak.day,-115.5291897320529 +2040,8,RSHEAT,peak.day,100.46016498439383 +2040,8,CO2EMT,peak.day,5907.007470999865 +2040,8,GASNAT,peak.peak,-75.54876689511998 +2040,8,RSHEAT,peak.peak,65.6945799088 +2040,8,CO2EMT,peak.peak,3862.8084513474855 +2040,8,GASNAT,peak.evening,-36.53908908163693 +2040,8,RSHEAT,peak.evening,31.773120940553852 +2040,8,CO2EMT,peak.evening,1868.2436247440962 +2040,8,GASNAT,summer.night,-7.3878574402420005 +2040,8,RSHEAT,summer.night,6.424223861080001 +2040,8,CO2EMT,summer.night,377.7411509195735 +2040,8,GASNAT,summer.day,-12.309069277277 +2040,8,RSHEAT,summer.day,10.70353850198 +2040,8,CO2EMT,summer.day,629.362712147173 +2040,8,GASNAT,summer.peak,-4.053351218157 +2040,8,RSHEAT,summer.peak,3.5246532331800005 +2040,8,CO2EMT,summer.peak,207.24784778436745 +2040,8,GASNAT,summer.evening,-3.0180441172809997 +2040,8,RSHEAT,summer.evening,2.62438618894 +2040,8,CO2EMT,summer.evening,154.31259571657753 +2040,8,GASNAT,autumn.night,-18.480316070073908 +2040,8,RSHEAT,autumn.night,16.069840060933835 +2040,8,CO2EMT,autumn.night,944.898560662879 +2040,8,GASNAT,autumn.day,-84.54202508133689 +2040,8,RSHEAT,autumn.day,73.51480441855382 +2040,8,CO2EMT,autumn.day,4322.633742408756 +2040,8,GASNAT,autumn.peak,-57.871336489916985 +2040,8,RSHEAT,autumn.peak,50.32290129557999 +2040,8,CO2EMT,autumn.peak,2958.9614347294555 +2040,8,GASNAT,autumn.evening,-25.24280951901992 +2040,8,RSHEAT,autumn.evening,21.950269146973845 +2040,8,CO2EMT,autumn.evening,1290.6648507074885 diff --git a/tests/data/simple_full/commodity_prices.csv b/tests/data/simple_full/commodity_prices.csv new file mode 100644 index 000000000..9667a6a19 --- /dev/null +++ b/tests/data/simple_full/commodity_prices.csv @@ -0,0 +1,166 @@ +milestone_year,commodity_id,region_id,time_slice,price +2020,ELCTRI,GBR,winter.night,7.993308999999999 +2020,ELCTRI,GBR,winter.day,7.993308999999999 +2020,ELCTRI,GBR,winter.peak,7.993308999999999 +2020,ELCTRI,GBR,winter.evening,7.993308999999999 +2020,ELCTRI,GBR,peak.night,17.26223303030303 +2020,ELCTRI,GBR,peak.day,7.993308999999999 +2020,ELCTRI,GBR,peak.peak,7.993308999999999 +2020,ELCTRI,GBR,peak.evening,17.26223303030303 +2020,ELCTRI,GBR,summer.night,7.993308999999999 +2020,ELCTRI,GBR,summer.day,0.4 +2020,ELCTRI,GBR,summer.peak,0.4 +2020,ELCTRI,GBR,summer.evening,0.4 +2020,ELCTRI,GBR,autumn.night,17.26223303030303 +2020,ELCTRI,GBR,autumn.day,7.993308999999999 +2020,ELCTRI,GBR,autumn.peak,17.26223303030303 +2020,ELCTRI,GBR,autumn.evening,17.26223303030303 +2020,RSHEAT,GBR,winter.night,5.8665369 +2020,RSHEAT,GBR,winter.day,5.8665369 +2020,RSHEAT,GBR,winter.peak,5.8665369 +2020,RSHEAT,GBR,winter.evening,5.8665369 +2020,RSHEAT,GBR,peak.night,5.8665369 +2020,RSHEAT,GBR,peak.day,5.8665369 +2020,RSHEAT,GBR,peak.peak,5.8665369 +2020,RSHEAT,GBR,peak.evening,5.8665369 +2020,RSHEAT,GBR,summer.night,2.80779197 +2020,RSHEAT,GBR,summer.day,0.30200000000000005 +2020,RSHEAT,GBR,summer.peak,0.30200000000000005 +2020,RSHEAT,GBR,summer.evening,0.30200000000000005 +2020,RSHEAT,GBR,autumn.night,5.8665369 +2020,RSHEAT,GBR,autumn.day,5.8665369 +2020,RSHEAT,GBR,autumn.peak,5.8665369 +2020,RSHEAT,GBR,autumn.evening,5.8665369 +2020,GASPRD,GBR,winter.day,7.504534967942034 +2020,GASPRD,GBR,winter.peak,7.504534967942034 +2020,GASPRD,GBR,winter.evening,7.504534967942034 +2020,GASPRD,GBR,peak.peak,7.504534967942034 +2020,GASPRD,GBR,peak.evening,7.504534967942034 +2020,GASPRD,GBR,summer.evening,7.504534967942034 +2020,GASPRD,GBR,autumn.evening,7.504534967942034 +2020,GASNAT,GBR,winter.day,6.5982585862326335 +2020,GASNAT,GBR,winter.peak,6.5982585862326335 +2020,GASNAT,GBR,winter.evening,6.5982585862326335 +2020,GASNAT,GBR,peak.peak,6.5982585862326335 +2020,GASNAT,GBR,peak.evening,6.5982585862326335 +2020,GASNAT,GBR,summer.evening,6.5982585862326335 +2020,GASNAT,GBR,autumn.evening,6.5982585862326335 +2020,GASPRD,GBR,winter.night,3.428609686103873 +2020,GASPRD,GBR,peak.night,3.428609686103873 +2020,GASPRD,GBR,peak.day,3.428609686103873 +2020,GASPRD,GBR,summer.night,3.428609686103873 +2020,GASPRD,GBR,summer.day,3.428609686103873 +2020,GASPRD,GBR,summer.peak,3.428609686103873 +2020,GASPRD,GBR,autumn.night,3.428609686103873 +2020,GASPRD,GBR,autumn.day,3.428609686103873 +2020,GASPRD,GBR,autumn.peak,3.428609686103873 +2020,GASNAT,GBR,winter.night,3.7738687802727107 +2020,GASNAT,GBR,peak.night,3.7738687802727107 +2020,GASNAT,GBR,peak.day,3.7738687802727107 +2020,GASNAT,GBR,summer.night,3.7738687802727107 +2020,GASNAT,GBR,summer.day,3.7738687802727107 +2020,GASNAT,GBR,summer.peak,3.7738687802727107 +2020,GASNAT,GBR,autumn.night,3.7738687802727107 +2020,GASNAT,GBR,autumn.day,3.7738687802727107 +2020,GASNAT,GBR,autumn.peak,3.7738687802727107 +2030,ELCTRI,GBR,winter.night,7.993308999999999 +2030,ELCTRI,GBR,winter.day,7.993308999999999 +2030,ELCTRI,GBR,winter.peak,7.993308999999999 +2030,ELCTRI,GBR,winter.evening,7.993308999999999 +2030,ELCTRI,GBR,peak.night,7.993308999999999 +2030,ELCTRI,GBR,peak.day,7.993308999999999 +2030,ELCTRI,GBR,peak.peak,7.993308999999999 +2030,ELCTRI,GBR,peak.evening,7.993308999999999 +2030,ELCTRI,GBR,summer.night,7.993308999999999 +2030,ELCTRI,GBR,summer.day,0.4 +2030,ELCTRI,GBR,summer.peak,0.4 +2030,ELCTRI,GBR,summer.evening,0.4 +2030,ELCTRI,GBR,autumn.night,7.993308999999999 +2030,ELCTRI,GBR,autumn.day,7.993308999999999 +2030,ELCTRI,GBR,autumn.peak,7.993308999999999 +2030,ELCTRI,GBR,autumn.evening,7.993308999999999 +2030,RSHEAT,GBR,winter.night,5.8665369 +2030,RSHEAT,GBR,winter.day,5.8665369 +2030,RSHEAT,GBR,winter.peak,5.8665369 +2030,RSHEAT,GBR,winter.evening,5.8665369 +2030,RSHEAT,GBR,peak.night,5.8665369 +2030,RSHEAT,GBR,peak.day,5.8665369 +2030,RSHEAT,GBR,peak.peak,5.8665369 +2030,RSHEAT,GBR,peak.evening,5.8665369 +2030,RSHEAT,GBR,summer.night,2.80779197 +2030,RSHEAT,GBR,summer.day,0.30200000000000005 +2030,RSHEAT,GBR,summer.peak,0.30200000000000005 +2030,RSHEAT,GBR,summer.evening,0.30200000000000005 +2030,RSHEAT,GBR,autumn.night,5.8665369 +2030,RSHEAT,GBR,autumn.day,5.8665369 +2030,RSHEAT,GBR,autumn.peak,5.8665369 +2030,RSHEAT,GBR,autumn.evening,5.8665369 +2030,GASPRD,GBR,winter.day,6.876080672233131 +2030,GASPRD,GBR,winter.peak,6.876080672233131 +2030,GASPRD,GBR,winter.evening,6.876080672233131 +2030,GASPRD,GBR,peak.peak,6.876080672233131 +2030,GASPRD,GBR,peak.evening,6.876080672233131 +2030,GASPRD,GBR,summer.evening,6.876080672233131 +2030,GASPRD,GBR,autumn.peak,6.876080672233131 +2030,GASPRD,GBR,autumn.evening,6.876080672233131 +2030,GASNAT,GBR,winter.day,6.161750462640322 +2030,GASNAT,GBR,winter.peak,6.161750462640322 +2030,GASNAT,GBR,winter.evening,6.161750462640322 +2030,GASNAT,GBR,peak.peak,6.161750462640322 +2030,GASNAT,GBR,peak.evening,6.161750462640322 +2030,GASNAT,GBR,summer.evening,6.161750462640322 +2030,GASNAT,GBR,autumn.peak,6.161750462640322 +2030,GASNAT,GBR,autumn.evening,6.161750462640322 +2030,GASPRD,GBR,winter.night,3.428609686103873 +2030,GASPRD,GBR,peak.night,3.428609686103873 +2030,GASPRD,GBR,peak.day,3.428609686103873 +2030,GASPRD,GBR,summer.night,3.428609686103873 +2030,GASPRD,GBR,summer.day,3.428609686103873 +2030,GASPRD,GBR,summer.peak,3.428609686103873 +2030,GASPRD,GBR,autumn.night,3.428609686103873 +2030,GASPRD,GBR,autumn.day,3.428609686103873 +2030,GASNAT,GBR,winter.night,3.7738687802727107 +2030,GASNAT,GBR,peak.night,3.7738687802727107 +2030,GASNAT,GBR,peak.day,3.7738687802727107 +2030,GASNAT,GBR,summer.night,3.7738687802727107 +2030,GASNAT,GBR,summer.day,3.7738687802727107 +2030,GASNAT,GBR,summer.peak,3.7738687802727107 +2030,GASNAT,GBR,autumn.night,3.7738687802727107 +2030,GASNAT,GBR,autumn.day,3.7738687802727107 +2040,RSHEAT,GBR,winter.night,5.8665369 +2040,RSHEAT,GBR,winter.day,5.8665369 +2040,RSHEAT,GBR,winter.peak,5.8665369 +2040,RSHEAT,GBR,winter.evening,5.8665369 +2040,RSHEAT,GBR,peak.night,5.8665369 +2040,RSHEAT,GBR,peak.day,5.8665369 +2040,RSHEAT,GBR,peak.peak,5.8665369 +2040,RSHEAT,GBR,peak.evening,5.8665369 +2040,RSHEAT,GBR,summer.night,5.8665369 +2040,RSHEAT,GBR,summer.day,5.8665369 +2040,RSHEAT,GBR,summer.peak,5.8665369 +2040,RSHEAT,GBR,summer.evening,5.8665369 +2040,RSHEAT,GBR,autumn.night,5.8665369 +2040,RSHEAT,GBR,autumn.day,5.8665369 +2040,RSHEAT,GBR,autumn.peak,5.8665369 +2040,RSHEAT,GBR,autumn.evening,5.8665369 +2040,GASPRD,GBR,winter.day,5.443465073396721 +2040,GASPRD,GBR,winter.peak,5.443465073396721 +2040,GASPRD,GBR,winter.evening,5.443465073396721 +2040,GASPRD,GBR,peak.day,5.443465073396721 +2040,GASPRD,GBR,peak.peak,5.443465073396721 +2040,GASPRD,GBR,peak.evening,5.443465073396721 +2040,GASPRD,GBR,summer.evening,5.443465073396721 +2040,GASPRD,GBR,autumn.day,5.443465073396721 +2040,GASPRD,GBR,autumn.peak,5.443465073396721 +2040,GASPRD,GBR,autumn.evening,5.443465073396721 +2040,GASNAT,GBR,winter.night,5.166692883880049 +2040,GASNAT,GBR,winter.day,5.166692883880049 +2040,GASNAT,GBR,winter.peak,5.166692883880049 +2040,GASNAT,GBR,winter.evening,5.166692883880049 +2040,GASNAT,GBR,peak.day,5.166692883880049 +2040,GASNAT,GBR,peak.peak,5.166692883880049 +2040,GASNAT,GBR,peak.evening,5.166692883880049 +2040,GASNAT,GBR,summer.evening,5.166692883880049 +2040,GASNAT,GBR,autumn.day,5.166692883880049 +2040,GASNAT,GBR,autumn.peak,5.166692883880049 +2040,GASNAT,GBR,autumn.evening,5.166692883880049 diff --git a/tests/data/simple_marginal/assets.csv b/tests/data/simple_marginal/assets.csv new file mode 100644 index 000000000..5f4559fa2 --- /dev/null +++ b/tests/data/simple_marginal/assets.csv @@ -0,0 +1,10 @@ +asset_id,process_id,region_id,agent_id,group_id,commission_year,decommission_year,capacity +0,GASDRV,GBR,A0_GEX,,2020,,4002.26 +1,GASPRC,GBR,A0_GPR,,2020,,3782.13 +2,WNDFRM,GBR,A0_ELC,,2020,2040,3.964844 +3,GASCGT,GBR,A0_ELC,,2020,2040,2.43 +4,RGASBR,GBR,A0_RES,,2020,2035,2900.0 +5,RELCHP,GBR,A0_RES,,2020,2035,399.98 +6,RGASBR,GBR,A0_RES,,2030,,355.83840587648046 +7,GASCGT,GBR,A0_ELC,,2030,2040,0.5151564434825014 +8,RGASBR,GBR,A0_RES,,2040,,3655.8189696 diff --git a/tests/data/simple_marginal/commodity_flows.csv b/tests/data/simple_marginal/commodity_flows.csv new file mode 100644 index 000000000..f7217b32f --- /dev/null +++ b/tests/data/simple_marginal/commodity_flows.csv @@ -0,0 +1,721 @@ +milestone_year,asset_id,commodity_id,time_slice,flow +2020,0,GASPRD,winter.night,0.0 +2020,0,CO2EMT,winter.night,0.0 +2020,0,GASPRD,winter.day,151.10360181069296 +2020,0,CO2EMT,winter.day,772.5927160580732 +2020,0,GASPRD,winter.peak,125.070625 +2020,0,CO2EMT,winter.peak,639.486105625 +2020,0,GASPRD,winter.evening,166.76083466742 +2020,0,CO2EMT,winter.evening,852.6481476545185 +2020,0,GASPRD,peak.night,0.0 +2020,0,CO2EMT,peak.night,0.0 +2020,0,GASPRD,peak.day,0.0 +2020,0,CO2EMT,peak.day,0.0 +2020,0,GASPRD,peak.peak,58.67582562255717 +2020,0,CO2EMT,peak.peak,300.00949640813485 +2020,0,GASPRD,peak.evening,166.76083466742 +2020,0,CO2EMT,peak.evening,852.6481476545185 +2020,0,GASPRD,summer.night,0.0 +2020,0,CO2EMT,summer.night,0.0 +2020,0,GASPRD,summer.day,0.0 +2020,0,CO2EMT,summer.day,0.0 +2020,0,GASPRD,summer.peak,0.0 +2020,0,CO2EMT,summer.peak,0.0 +2020,0,GASPRD,summer.evening,0.16861964795988574 +2020,0,CO2EMT,summer.evening,0.8621522600188959 +2020,0,GASPRD,autumn.night,0.0 +2020,0,CO2EMT,autumn.night,0.0 +2020,0,GASPRD,autumn.day,0.0 +2020,0,CO2EMT,autumn.day,0.0 +2020,0,GASPRD,autumn.peak,0.0 +2020,0,CO2EMT,autumn.peak,0.0 +2020,0,GASPRD,autumn.evening,163.3883025525992 +2020,0,CO2EMT,autumn.evening,835.4043909514398 +2020,1,GASPRD,winter.night,-0.0 +2020,1,GASNAT,winter.night,0.0 +2020,1,CO2EMT,winter.night,0.0 +2020,1,GASPRD,winter.day,-153.36573202936748 +2020,1,GASNAT,winter.day,146.06260193273093 +2020,1,CO2EMT,winter.day,373.40904184102664 +2020,1,GASPRD,winter.peak,-124.10114062500001 +2020,1,GASNAT,winter.peak,118.1915625 +2020,1,CO2EMT,winter.peak,302.15672953125005 +2020,1,GASPRD,winter.evening,-165.4681888237455 +2020,1,GASNAT,winter.evening,157.58875126070998 +2020,1,CO2EMT,winter.evening,402.87564259800513 +2020,1,GASPRD,peak.night,-0.0 +2020,1,GASNAT,peak.night,0.0 +2020,1,CO2EMT,peak.night,0.0 +2020,1,GASPRD,peak.day,-0.0 +2020,1,GASNAT,peak.day,0.0 +2020,1,CO2EMT,peak.day,0.0 +2020,1,GASPRD,peak.peak,-59.96847146623166 +2020,1,GASNAT,peak.peak,57.11282996783967 +2020,1,CO2EMT,peak.peak,146.00894981278213 +2020,1,GASPRD,peak.evening,-165.4681888237455 +2020,1,GASNAT,peak.evening,157.58875126070998 +2020,1,CO2EMT,peak.evening,402.87564259800513 +2020,1,GASPRD,summer.night,-0.0 +2020,1,GASNAT,summer.night,0.0 +2020,1,CO2EMT,summer.night,0.0 +2020,1,GASPRD,summer.day,-0.0 +2020,1,GASNAT,summer.day,0.0 +2020,1,CO2EMT,summer.day,0.0 +2020,1,GASPRD,summer.peak,-0.0 +2020,1,GASNAT,summer.peak,0.0 +2020,1,CO2EMT,summer.peak,0.0 +2020,1,GASPRD,summer.evening,-0.16861964795988574 +2020,1,GASNAT,summer.evening,0.1605901409141769 +2020,1,CO2EMT,summer.evening,0.41054869524709325 +2020,1,GASPRD,autumn.night,-0.0 +2020,1,GASNAT,autumn.night,0.0 +2020,1,CO2EMT,autumn.night,0.0 +2020,1,GASPRD,autumn.day,-0.0 +2020,1,GASNAT,autumn.day,0.0 +2020,1,CO2EMT,autumn.day,0.0 +2020,1,GASPRD,autumn.peak,-0.0 +2020,1,GASNAT,autumn.peak,0.0 +2020,1,CO2EMT,autumn.peak,0.0 +2020,1,GASPRD,autumn.evening,-163.3883025525992 +2020,1,GASNAT,autumn.evening,155.60790719295161 +2020,1,CO2EMT,autumn.evening,397.81161473878086 +2020,2,ELCTRI,winter.night,4.435312795545212 +2020,2,ELCTRI,winter.day,7.075379933645912 +2020,2,ELCTRI,winter.peak,1.9712501261051125 +2020,2,ELCTRI,winter.evening,2.5696653598405335 +2020,2,ELCTRI,peak.night,2.851272517283696 +2020,2,ELCTRI,peak.day,6.3713620320039785 +2020,2,ELCTRI,peak.peak,1.7776452018191917 +2020,2,ELCTRI,peak.evening,1.72484387381507 +2020,2,ELCTRI,summer.night,1.6368416242136155 +2020,2,ELCTRI,summer.day,2.9055524196533997 +2020,2,ELCTRI,summer.peak,0.9567924409494001 +2020,2,ELCTRI,summer.evening,0.7124084843502 +2020,2,ELCTRI,autumn.night,3.203281465982185 +2020,2,ELCTRI,autumn.day,6.001752635595889 +2020,2,ELCTRI,autumn.peak,1.5488393825638174 +2020,2,ELCTRI,autumn.evening,1.9008483513729915 +2020,3,GASNAT,winter.night,-7.783808997678887 +2020,3,ELCTRI,winter.night,5.189205998452591 +2020,3,CO2EMT,winter.night,397.9861540513214 +2020,3,GASNAT,winter.day,-10.010898915527838 +2020,3,ELCTRI,winter.day,6.6739326103518914 +2020,3,CO2EMT,winter.day,511.8572615509383 +2020,3,GASNAT,winter.peak,-3.2303154358423316 +2020,3,ELCTRI,winter.peak,2.1535436238948877 +2020,3,CO2EMT,winter.peak,165.1660282346184 +2020,3,GASNAT,winter.evening,-4.395089526235901 +2020,3,ELCTRI,winter.evening,2.9300596841572673 +2020,3,CO2EMT,winter.evening,224.7209274764416 +2020,3,GASNAT,peak.night,-8.382740663321101 +2020,3,ELCTRI,peak.night,5.5884937755474 +2020,3,CO2EMT,peak.night,428.6095301156078 +2020,3,GASNAT,peak.day,-11.066925767990737 +2020,3,ELCTRI,peak.day,7.3779505119938245 +2020,3,CO2EMT,peak.day,565.8519145173664 +2020,3,GASNAT,peak.peak,-3.520722822271213 +2020,3,ELCTRI,peak.peak,2.3471485481808085 +2020,3,CO2EMT,peak.peak,180.0145579027271 +2020,3,GASNAT,peak.evening,-4.790137538321099 +2020,3,ELCTRI,peak.evening,3.1934250255473997 +2020,3,CO2EMT,peak.evening,244.9197323343578 +2020,3,GASNAT,summer.night,-0.1605901409141769 +2020,3,ELCTRI,summer.night,0.1070600939427846 +2020,3,CO2EMT,summer.night,8.210973904941865 +2020,3,GASNAT,summer.day,-0.0 +2020,3,ELCTRI,summer.day,0.0 +2020,3,CO2EMT,summer.day,0.0 +2020,3,GASNAT,summer.peak,-0.0 +2020,3,ELCTRI,summer.peak,0.0 +2020,3,CO2EMT,summer.peak,0.0 +2020,3,GASNAT,summer.evening,-0.0 +2020,3,ELCTRI,summer.evening,0.0 +2020,3,CO2EMT,summer.evening,0.0 +2020,3,GASNAT,autumn.night,-8.382740663321101 +2020,3,ELCTRI,autumn.night,5.5884937755474 +2020,3,CO2EMT,autumn.night,428.6095301156078 +2020,3,GASNAT,autumn.day,-11.621339862602872 +2020,3,ELCTRI,autumn.day,7.747559908401914 +2020,3,CO2EMT,autumn.day,594.1991071748848 +2020,3,GASNAT,autumn.peak,-3.592603125 +2020,3,ELCTRI,autumn.peak,2.39506875 +2020,3,CO2EMT,autumn.peak,183.68979778124998 +2020,3,GASNAT,autumn.evening,-4.790137538321099 +2020,3,ELCTRI,autumn.evening,3.1934250255473997 +2020,3,CO2EMT,autumn.evening,244.9197323343578 +2020,4,GASNAT,winter.night,-36.31286857370999 +2020,4,RSHEAT,winter.night,31.576407455399995 +2020,4,CO2EMT,winter.night,1856.6769701737921 +2020,4,GASNAT,winter.day,-193.26973453857997 +2020,4,RSHEAT,winter.day,168.06063872919998 +2020,4,CO2EMT,winter.day,9881.881526957595 +2020,4,GASNAT,winter.peak,-104.21872974118598 +2020,4,RSHEAT,winter.peak,90.62498238363999 +2020,4,CO2EMT,winter.peak,5328.7036516668395 +2020,4,GASNAT,winter.evening,-62.62146996467999 +2020,4,RSHEAT,winter.evening,54.453452143199996 +2020,4,CO2EMT,winter.evening,3201.8357592940883 +2020,4,GASNAT,peak.night,-19.52227251698524 +2020,4,RSHEAT,peak.night,16.975889145204558 +2020,4,CO2EMT,peak.night,998.1737937934555 +2020,4,GASNAT,peak.day,-82.18418839575197 +2020,4,RSHEAT,peak.day,71.46451164847998 +2020,4,CO2EMT,peak.day,4202.077552674799 +2020,4,GASNAT,peak.peak,-58.291277616306004 +2020,4,RSHEAT,peak.peak,50.688067492440005 +2020,4,CO2EMT,peak.peak,2980.433024521726 +2020,4,GASNAT,peak.evening,-26.943315907602276 +2020,4,RSHEAT,peak.evening,23.428970354436764 +2020,4,CO2EMT,peak.evening,1377.6117423557046 +2020,4,GASNAT,summer.night,-0.0 +2020,4,RSHEAT,summer.night,0.0 +2020,4,CO2EMT,summer.night,0.0 +2020,4,GASNAT,summer.day,-0.0 +2020,4,RSHEAT,summer.day,0.0 +2020,4,CO2EMT,summer.day,0.0 +2020,4,GASNAT,summer.peak,-0.0 +2020,4,RSHEAT,summer.peak,0.0 +2020,4,CO2EMT,summer.peak,0.0 +2020,4,GASNAT,summer.evening,-0.0 +2020,4,RSHEAT,summer.evening,0.0 +2020,4,CO2EMT,summer.evening,0.0 +2020,4,GASNAT,autumn.night,-9.10896122967321 +2020,4,RSHEAT,autumn.night,7.920835851889748 +2020,4,CO2EMT,autumn.night,465.7411876731913 +2020,4,GASNAT,autumn.day,-56.69422338503598 +2020,4,RSHEAT,autumn.day,49.29932468263999 +2020,4,CO2EMT,autumn.day,2898.7756416768902 +2020,4,GASNAT,autumn.peak,-44.38022605095635 +2020,4,RSHEAT,autumn.peak,38.591500913875095 +2020,4,CO2EMT,autumn.peak,2269.160957985399 +2020,4,GASNAT,autumn.evening,-17.037675338040994 +2020,4,RSHEAT,autumn.evening,14.815369859166085 +2020,4,CO2EMT,autumn.evening,871.1363400340363 +2020,5,ELCTRI,winter.night,-9.624518793997803 +2020,5,RSHEAT,winter.night,29.165208466660005 +2020,5,ELCTRI,winter.day,-13.749312543997803 +2020,5,RSHEAT,winter.day,41.664583466660005 +2020,5,ELCTRI,winter.peak,-4.12479375 +2020,5,RSHEAT,winter.peak,12.499375 +2020,5,ELCTRI,winter.evening,-5.499725043997801 +2020,5,RSHEAT,winter.evening,16.66583346666 +2020,5,ELCTRI,peak.night,-8.439766292831097 +2020,5,RSHEAT,peak.night,25.575049372215442 +2020,5,ELCTRI,peak.day,-13.749312543997803 +2020,5,RSHEAT,peak.day,41.664583466660005 +2020,5,ELCTRI,peak.peak,-4.12479375 +2020,5,RSHEAT,peak.peak,12.499375 +2020,5,ELCTRI,peak.evening,-4.91826889936247 +2020,5,RSHEAT,peak.evening,14.903845149583242 +2020,5,ELCTRI,summer.night,-1.7439017181564 +2020,5,RSHEAT,summer.night,5.28455066108 +2020,5,ELCTRI,summer.day,-2.9055524196533997 +2020,5,RSHEAT,summer.day,8.80470430198 +2020,5,ELCTRI,summer.peak,-0.9567924409494001 +2020,5,RSHEAT,summer.peak,2.89937103318 +2020,5,ELCTRI,summer.evening,-0.7124084843502 +2020,5,RSHEAT,summer.evening,2.1588135889399998 +2020,5,ELCTRI,autumn.night,-8.791775241529585 +2020,5,RSHEAT,autumn.night,26.641743156150255 +2020,5,ELCTRI,autumn.day,-13.749312543997803 +2020,5,RSHEAT,autumn.day,41.664583466660005 +2020,5,ELCTRI,autumn.peak,-3.9439081325638172 +2020,5,RSHEAT,autumn.peak,11.9512367653449 +2020,5,ELCTRI,autumn.evening,-5.094273376920391 +2020,5,RSHEAT,autumn.evening,15.437192051273913 +2030,0,GASPRD,winter.night,0.0 +2030,0,CO2EMT,winter.night,0.0 +2030,0,GASPRD,winter.day,209.007363584943 +2030,0,CO2EMT,winter.day,1068.6546500098136 +2030,0,GASPRD,winter.peak,125.070625 +2030,0,CO2EMT,winter.peak,639.486105625 +2030,0,GASPRD,winter.evening,166.76083466742 +2030,0,CO2EMT,winter.evening,852.6481476545185 +2030,0,GASPRD,peak.night,0.0 +2030,0,CO2EMT,peak.night,0.0 +2030,0,GASPRD,peak.day,0.0 +2030,0,CO2EMT,peak.day,0.0 +2030,0,GASPRD,peak.peak,88.48378530453337 +2030,0,CO2EMT,peak.peak,452.41759426207915 +2030,0,GASPRD,peak.evening,166.76083466742 +2030,0,CO2EMT,peak.evening,852.6481476545185 +2030,0,GASPRD,summer.night,0.0 +2030,0,CO2EMT,summer.night,0.0 +2030,0,GASPRD,summer.day,0.0 +2030,0,CO2EMT,summer.day,0.0 +2030,0,GASPRD,summer.peak,0.0 +2030,0,CO2EMT,summer.peak,0.0 +2030,0,GASPRD,summer.evening,0.464792220809886 +2030,0,CO2EMT,summer.evening,2.3764826250009476 +2030,0,GASPRD,autumn.night,0.0 +2030,0,CO2EMT,autumn.night,0.0 +2030,0,GASPRD,autumn.day,0.0 +2030,0,CO2EMT,autumn.day,0.0 +2030,0,GASPRD,autumn.peak,20.534211026060376 +2030,0,CO2EMT,autumn.peak,104.99142097624672 +2030,0,GASPRD,autumn.evening,166.76083466742 +2030,0,CO2EMT,autumn.evening,852.6481476545185 +2030,1,GASPRD,winter.night,-0.0 +2030,1,GASNAT,winter.night,0.0 +2030,1,CO2EMT,winter.night,0.0 +2030,1,GASPRD,winter.day,-211.26949380361748 +2030,1,GASNAT,winter.day,201.2090417177309 +2030,1,CO2EMT,winter.day,514.3909151513791 +2030,1,GASPRD,winter.peak,-124.10114062500001 +2030,1,GASNAT,winter.peak,118.1915625 +2030,1,CO2EMT,winter.peak,302.15672953125005 +2030,1,GASPRD,winter.evening,-165.4681888237455 +2030,1,GASNAT,winter.evening,157.58875126070998 +2030,1,CO2EMT,winter.evening,402.87564259800513 +2030,1,GASPRD,peak.night,-0.0 +2030,1,GASNAT,peak.night,0.0 +2030,1,CO2EMT,peak.night,0.0 +2030,1,GASPRD,peak.day,-0.0 +2030,1,GASNAT,peak.day,0.0 +2030,1,CO2EMT,peak.day,0.0 +2030,1,GASPRD,peak.peak,-89.77643114820788 +2030,1,GASNAT,peak.peak,85.50136299829322 +2030,1,CO2EMT,peak.peak,218.58423450513664 +2030,1,GASPRD,peak.evening,-165.4681888237455 +2030,1,GASNAT,peak.evening,157.58875126070998 +2030,1,CO2EMT,peak.evening,402.87564259800513 +2030,1,GASPRD,summer.night,-0.0 +2030,1,GASNAT,summer.night,0.0 +2030,1,CO2EMT,summer.night,0.0 +2030,1,GASPRD,summer.day,-0.0 +2030,1,GASNAT,summer.day,0.0 +2030,1,CO2EMT,summer.day,0.0 +2030,1,GASPRD,summer.peak,-0.0 +2030,1,GASNAT,summer.peak,0.0 +2030,1,CO2EMT,summer.peak,0.0 +2030,1,GASPRD,summer.evening,-0.464792220809886 +2030,1,GASNAT,summer.evening,0.44265925791417715 +2030,1,CO2EMT,summer.evening,1.131658392857594 +2030,1,GASPRD,autumn.night,-0.0 +2030,1,GASNAT,autumn.night,0.0 +2030,1,CO2EMT,autumn.night,0.0 +2030,1,GASPRD,autumn.day,-0.0 +2030,1,GASNAT,autumn.day,0.0 +2030,1,CO2EMT,autumn.day,0.0 +2030,1,GASPRD,autumn.peak,-21.826856869734893 +2030,1,GASNAT,autumn.peak,20.78748273308085 +2030,1,CO2EMT,autumn.peak,53.1431996071212 +2030,1,GASPRD,autumn.evening,-165.4681888237455 +2030,1,GASNAT,autumn.evening,157.58875126070998 +2030,1,CO2EMT,autumn.evening,402.87564259800513 +2030,2,ELCTRI,winter.night,4.435312795545212 +2030,2,ELCTRI,winter.day,7.075379933645912 +2030,2,ELCTRI,winter.peak,1.9712501261051125 +2030,2,ELCTRI,winter.evening,2.5696653598405335 +2030,2,ELCTRI,peak.night,2.851272517283696 +2030,2,ELCTRI,peak.day,6.3713620320039785 +2030,2,ELCTRI,peak.peak,1.7776452018191917 +2030,2,ELCTRI,peak.evening,1.72484387381507 +2030,2,ELCTRI,summer.night,1.6368416242136155 +2030,2,ELCTRI,summer.day,3.2188600626534005 +2030,2,ELCTRI,summer.peak,1.0599640039494003 +2030,2,ELCTRI,summer.evening,0.7892279633502001 +2030,2,ELCTRI,autumn.night,3.203281465982185 +2030,2,ELCTRI,autumn.day,6.001752635595889 +2030,2,ELCTRI,autumn.peak,1.5488393825638174 +2030,2,ELCTRI,autumn.evening,1.9008483513729915 +2030,3,GASNAT,winter.night,-7.783808997678887 +2030,3,ELCTRI,winter.night,5.189205998452591 +2030,3,CO2EMT,winter.night,397.9861540513214 +2030,3,GASNAT,winter.day,-10.010898915527838 +2030,3,ELCTRI,winter.day,6.6739326103518914 +2030,3,CO2EMT,winter.day,511.8572615509383 +2030,3,GASNAT,winter.peak,-2.468688831431171 +2030,3,ELCTRI,winter.peak,1.6457925542874472 +2030,3,CO2EMT,winter.peak,126.22405995107574 +2030,3,GASNAT,winter.evening,-3.3795873788970026 +2030,3,ELCTRI,winter.evening,2.253058252598002 +2030,3,CO2EMT,winter.evening,172.79830268300373 +2030,3,GASNAT,peak.night,-8.382740663321101 +2030,3,ELCTRI,peak.night,5.588493775547401 +2030,3,CO2EMT,peak.night,428.60953011560787 +2030,3,GASNAT,peak.day,-11.066925767990737 +2030,3,ELCTRI,peak.day,7.3779505119938245 +2030,3,CO2EMT,peak.day,565.8519145173664 +2030,3,GASNAT,peak.peak,-3.520722822271213 +2030,3,ELCTRI,peak.peak,2.3471485481808085 +2030,3,CO2EMT,peak.peak,180.0145579027271 +2030,3,GASNAT,peak.evening,-4.646819607935198 +2030,3,ELCTRI,peak.evening,3.0978797386234653 +2030,3,CO2EMT,peak.evening,237.59188655372665 +2030,3,GASNAT,summer.night,-0.0 +2030,3,ELCTRI,summer.night,0.0 +2030,3,CO2EMT,summer.night,0.0 +2030,3,GASNAT,summer.day,-0.0 +2030,3,ELCTRI,summer.day,0.0 +2030,3,CO2EMT,summer.day,0.0 +2030,3,GASNAT,summer.peak,-0.0 +2030,3,ELCTRI,summer.peak,0.0 +2030,3,CO2EMT,summer.peak,0.0 +2030,3,GASNAT,summer.evening,-0.0 +2030,3,ELCTRI,summer.evening,0.0 +2030,3,CO2EMT,summer.evening,0.0 +2030,3,GASNAT,autumn.night,-7.854727240273368 +2030,3,ELCTRI,autumn.night,5.236484826848912 +2030,3,CO2EMT,autumn.night,401.61220379517727 +2030,3,GASNAT,autumn.day,-11.621339862602872 +2030,3,ELCTRI,autumn.day,7.747559908401914 +2030,3,CO2EMT,autumn.day,594.1991071748848 +2030,3,GASNAT,autumn.peak,-3.592603125 +2030,3,ELCTRI,autumn.peak,2.39506875 +2030,3,CO2EMT,autumn.peak,183.68979778124998 +2030,3,GASNAT,autumn.evening,-4.3828128915983156 +2030,3,ELCTRI,autumn.evening,2.921875261065544 +2030,3,CO2EMT,autumn.evening,224.09322314742187 +2030,4,GASNAT,winter.night,-43.845148578709995 +2030,4,RSHEAT,winter.night,38.1262161554 +2030,4,CO2EMT,winter.night,2241.8024468294425 +2030,4,GASNAT,winter.day,-219.27676569358 +2030,4,RSHEAT,winter.day,190.6754484292 +2030,4,CO2EMT,winter.day,11211.621029912745 +2030,4,GASNAT,winter.peak,-104.21874999999999 +2030,4,RSHEAT,winter.peak,90.625 +2030,4,CO2EMT,winter.peak,5328.704687500001 +2030,4,GASNAT,winter.evening,-71.44063561968 +2030,4,RSHEAT,winter.evening,62.1222918432 +2030,4,CO2EMT,winter.evening,3652.7596992342387 +2030,4,GASNAT,peak.night,-0.0 +2030,4,RSHEAT,peak.night,0.0 +2030,4,CO2EMT,peak.night,0.0 +2030,4,GASNAT,peak.day,-96.21279149075198 +2030,4,RSHEAT,peak.day,83.66329694848 +2030,4,CO2EMT,peak.day,4919.3600289221495 +2030,4,GASNAT,peak.peak,-66.12685298630602 +2030,4,RSHEAT,peak.peak,57.50161129244002 +2030,4,CO2EMT,peak.peak,3381.0659931898267 +2030,4,GASNAT,peak.evening,-29.670500177964005 +2030,4,RSHEAT,peak.evening,25.800434937360006 +2030,4,CO2EMT,peak.evening,1517.0526740992998 +2030,4,GASNAT,summer.night,-0.0 +2030,4,RSHEAT,summer.night,0.0 +2030,4,CO2EMT,summer.night,0.0 +2030,4,GASNAT,summer.day,-0.0 +2030,4,RSHEAT,summer.day,0.0 +2030,4,CO2EMT,summer.day,0.0 +2030,4,GASNAT,summer.peak,-0.0 +2030,4,RSHEAT,summer.peak,0.0 +2030,4,CO2EMT,summer.peak,0.0 +2030,4,GASNAT,summer.evening,-0.0 +2030,4,RSHEAT,summer.evening,0.0 +2030,4,CO2EMT,summer.evening,0.0 +2030,4,GASNAT,autumn.night,-0.0 +2030,4,RSHEAT,autumn.night,0.0 +2030,4,CO2EMT,autumn.night,0.0 +2030,4,GASNAT,autumn.day,-67.97422666003601 +2030,4,RSHEAT,autumn.day,59.10802318264001 +2030,4,CO2EMT,autumn.day,3475.5222091276414 +2030,4,GASNAT,autumn.peak,-50.017432516103 +2030,4,RSHEAT,autumn.peak,43.49341957922 +2030,4,CO2EMT,autumn.peak,2557.391324548347 +2030,4,GASNAT,autumn.evening,-19.376214580347 +2030,4,RSHEAT,autumn.evening,16.84888224378 +2030,4,CO2EMT,autumn.evening,990.7058514931422 +2030,5,ELCTRI,winter.night,-9.624518793997803 +2030,5,RSHEAT,winter.night,29.165208466660005 +2030,5,ELCTRI,winter.day,-13.749312543997803 +2030,5,RSHEAT,winter.day,41.664583466660005 +2030,5,ELCTRI,winter.peak,-4.12479375 +2030,5,RSHEAT,winter.peak,12.499375 +2030,5,ELCTRI,winter.evening,-5.499725043997801 +2030,5,RSHEAT,winter.evening,16.66583346666 +2030,5,ELCTRI,peak.night,-9.624518793997803 +2030,5,RSHEAT,peak.night,29.165208466660005 +2030,5,ELCTRI,peak.day,-13.749312543997803 +2030,5,RSHEAT,peak.day,41.664583466660005 +2030,5,ELCTRI,peak.peak,-4.12479375 +2030,5,RSHEAT,peak.peak,12.499375 +2030,5,ELCTRI,peak.evening,-5.499725043997801 +2030,5,RSHEAT,peak.evening,16.66583346666 +2030,5,ELCTRI,summer.night,-1.9319477961564002 +2030,5,RSHEAT,summer.night,5.85438726108 +2030,5,ELCTRI,summer.day,-3.2188600626534005 +2030,5,RSHEAT,summer.day,9.75412140198 +2030,5,ELCTRI,summer.peak,-1.0599640039494003 +2030,5,RSHEAT,summer.peak,3.2120121331800005 +2030,5,ELCTRI,summer.evening,-0.7892279633502001 +2030,5,RSHEAT,summer.evening,2.39159988894 +2030,5,ELCTRI,autumn.night,-9.624518793997803 +2030,5,RSHEAT,autumn.night,29.165208466660005 +2030,5,ELCTRI,autumn.day,-13.749312543997803 +2030,5,RSHEAT,autumn.day,41.664583466660005 +2030,5,ELCTRI,autumn.peak,-4.12479375 +2030,5,RSHEAT,autumn.peak,12.499375 +2030,5,ELCTRI,autumn.evening,-5.499725043997801 +2030,5,RSHEAT,autumn.evening,16.66583346666 +2030,6,GASNAT,winter.night,-0.0 +2030,6,RSHEAT,winter.night,0.0 +2030,6,CO2EMT,winter.night,0.0 +2030,6,GASNAT,winter.day,-0.0 +2030,6,RSHEAT,winter.day,0.0 +2030,6,CO2EMT,winter.day,0.0 +2030,6,GASNAT,winter.peak,-12.787942711186016 +2030,6,RSHEAT,winter.peak,11.119950183640015 +2030,6,CO2EMT,winter.peak,653.8475108229411 +2030,6,GASNAT,winter.evening,-0.0 +2030,6,RSHEAT,winter.evening,0.0 +2030,6,CO2EMT,winter.evening,0.0 +2030,6,GASNAT,peak.night,-20.670129843374 +2030,6,RSHEAT,peak.night,17.97402595076 +2030,6,CO2EMT,peak.night,1056.8637388917127 +2030,6,GASNAT,peak.day,-0.0 +2030,6,RSHEAT,peak.day,0.0 +2030,6,CO2EMT,peak.day,0.0 +2030,6,GASNAT,peak.peak,-0.0 +2030,6,RSHEAT,peak.peak,0.0 +2030,6,CO2EMT,peak.peak,0.0 +2030,6,GASNAT,peak.evening,-0.0 +2030,6,RSHEAT,peak.evening,0.0 +2030,6,CO2EMT,peak.evening,0.0 +2030,6,GASNAT,summer.night,-0.0 +2030,6,RSHEAT,summer.night,0.0 +2030,6,CO2EMT,summer.night,0.0 +2030,6,GASNAT,summer.day,-0.0 +2030,6,RSHEAT,summer.day,0.0 +2030,6,CO2EMT,summer.day,0.0 +2030,6,GASNAT,summer.peak,-0.0 +2030,6,RSHEAT,summer.peak,0.0 +2030,6,CO2EMT,summer.peak,0.0 +2030,6,GASNAT,summer.evening,-0.0 +2030,6,RSHEAT,summer.evening,0.0 +2030,6,CO2EMT,summer.evening,0.0 +2030,6,GASNAT,autumn.night,-10.492917792587003 +2030,6,RSHEAT,autumn.night,9.124276341380003 +2030,6,CO2EMT,autumn.night,536.5028867349736 +2030,6,GASNAT,autumn.day,-0.0 +2030,6,RSHEAT,autumn.day,0.0 +2030,6,CO2EMT,autumn.day,0.0 +2030,6,GASNAT,autumn.peak,-0.0 +2030,6,RSHEAT,autumn.peak,0.0 +2030,6,CO2EMT,autumn.peak,0.0 +2030,6,GASNAT,autumn.evening,-0.0 +2030,6,RSHEAT,autumn.evening,0.0 +2030,6,CO2EMT,autumn.evening,0.0 +2030,7,GASNAT,winter.night,-0.0 +2030,7,ELCTRI,winter.night,0.0 +2030,7,CO2EMT,winter.night,0.0 +2030,7,GASNAT,winter.day,-0.0 +2030,7,ELCTRI,winter.day,0.0 +2030,7,CO2EMT,winter.day,0.0 +2030,7,GASNAT,winter.peak,-0.7616266044111606 +2030,7,ELCTRI,winter.peak,0.5077510696074404 +2030,7,CO2EMT,winter.peak,38.94196828354264 +2030,7,GASNAT,winter.evening,-1.0155021473388979 +2030,7,ELCTRI,winter.evening,0.6770014315592653 +2030,7,CO2EMT,winter.evening,51.92262479343785 +2030,7,GASNAT,peak.night,-1.7771287517500585 +2030,7,ELCTRI,peak.night,1.1847525011667057 +2030,7,CO2EMT,peak.night,90.86459307698048 +2030,7,GASNAT,peak.day,-0.0 +2030,7,ELCTRI,peak.day,0.0 +2030,7,CO2EMT,peak.day,0.0 +2030,7,GASNAT,peak.peak,-0.0 +2030,7,ELCTRI,peak.peak,0.0 +2030,7,CO2EMT,peak.peak,0.0 +2030,7,GASNAT,peak.evening,-1.0155021473388979 +2030,7,ELCTRI,peak.evening,0.6770014315592653 +2030,7,CO2EMT,peak.evening,51.92262479343785 +2030,7,GASNAT,summer.night,-0.44265925791417715 +2030,7,ELCTRI,summer.night,0.29510617194278477 +2030,7,CO2EMT,summer.night,22.633167857151875 +2030,7,GASNAT,summer.day,-0.0 +2030,7,ELCTRI,summer.day,0.0 +2030,7,CO2EMT,summer.day,0.0 +2030,7,GASNAT,summer.peak,-0.0 +2030,7,ELCTRI,summer.peak,0.0 +2030,7,CO2EMT,summer.peak,0.0 +2030,7,GASNAT,summer.evening,-0.0 +2030,7,ELCTRI,summer.evening,0.0 +2030,7,CO2EMT,summer.evening,0.0 +2030,7,GASNAT,autumn.night,-1.7771287517500585 +2030,7,ELCTRI,autumn.night,1.1847525011667057 +2030,7,CO2EMT,autumn.night,90.86459307698048 +2030,7,GASNAT,autumn.day,-0.0 +2030,7,ELCTRI,autumn.day,0.0 +2030,7,CO2EMT,autumn.day,0.0 +2030,7,GASNAT,autumn.peak,-0.27132842615427455 +2030,7,ELCTRI,autumn.peak,0.18088561743618303 +2030,7,CO2EMT,autumn.peak,13.873022429268056 +2030,7,GASNAT,autumn.evening,-1.0155021473388979 +2030,7,ELCTRI,autumn.evening,0.6770014315592653 +2030,7,CO2EMT,autumn.evening,51.92262479343785 +2040,0,GASPRD,winter.night,0.0 +2040,0,CO2EMT,winter.night,0.0 +2040,0,GASPRD,winter.day,360.96396982311984 +2040,0,CO2EMT,winter.day,1845.6087777056118 +2040,0,GASPRD,winter.peak,125.070625 +2040,0,CO2EMT,winter.peak,639.486105625 +2040,0,GASPRD,winter.evening,166.76083466742 +2040,0,CO2EMT,winter.evening,852.6481476545185 +2040,0,GASPRD,peak.night,0.0 +2040,0,CO2EMT,peak.night,0.0 +2040,0,GASPRD,peak.day,85.71569060312174 +2040,0,CO2EMT,peak.day,438.2643260537615 +2040,0,GASPRD,peak.peak,125.070625 +2040,0,CO2EMT,peak.peak,639.486105625 +2040,0,GASPRD,peak.evening,166.76083466742 +2040,0,CO2EMT,peak.evening,852.6481476545185 +2040,0,GASPRD,summer.night,0.0 +2040,0,CO2EMT,summer.night,0.0 +2040,0,GASPRD,summer.day,0.0 +2040,0,CO2EMT,summer.day,0.0 +2040,0,GASPRD,summer.peak,0.0 +2040,0,CO2EMT,summer.peak,0.0 +2040,0,GASPRD,summer.evening,28.106738155604855 +2040,0,CO2EMT,summer.evening,143.70975218960763 +2040,0,GASPRD,autumn.night,0.0 +2040,0,CO2EMT,autumn.night,0.0 +2040,0,GASPRD,autumn.day,11.030571054582595 +2040,0,CO2EMT,autumn.day,56.39930980208081 +2040,0,GASPRD,autumn.peak,125.070625 +2040,0,CO2EMT,autumn.peak,639.486105625 +2040,0,GASPRD,autumn.evening,166.76083466742 +2040,0,CO2EMT,autumn.evening,852.6481476545185 +2040,1,GASPRD,winter.night,-289.5693294487456 +2040,1,GASNAT,winter.night,275.78031376071004 +2040,1,CO2EMT,winter.night,705.0323721292552 +2040,1,GASPRD,winter.day,-73.65677059304869 +2040,1,GASNAT,winter.day,70.14930532671303 +2040,1,CO2EMT,winter.day,179.33669906774188 +2040,1,GASPRD,winter.peak,-124.10114062500001 +2040,1,GASNAT,winter.peak,118.1915625 +2040,1,CO2EMT,winter.peak,302.15672953125005 +2040,1,GASPRD,winter.evening,-165.4681888237455 +2040,1,GASNAT,winter.evening,157.58875126070998 +2040,1,CO2EMT,winter.evening,402.87564259800513 +2040,1,GASPRD,peak.night,-0.0 +2040,1,GASNAT,peak.night,0.0 +2040,1,CO2EMT,peak.night,0.0 +2040,1,GASPRD,peak.day,-87.97782082179623 +2040,1,GASNAT,peak.day,83.78840078266308 +2040,1,CO2EMT,peak.day,214.20504660087818 +2040,1,GASPRD,peak.peak,-124.10114062500001 +2040,1,GASNAT,peak.peak,118.1915625 +2040,1,CO2EMT,peak.peak,302.15672953125005 +2040,1,GASPRD,peak.evening,-165.4681888237455 +2040,1,GASNAT,peak.evening,157.58875126070998 +2040,1,CO2EMT,peak.evening,402.87564259800513 +2040,1,GASPRD,summer.night,-0.0 +2040,1,GASNAT,summer.night,0.0 +2040,1,CO2EMT,summer.night,0.0 +2040,1,GASPRD,summer.day,-0.0 +2040,1,GASNAT,summer.day,0.0 +2040,1,CO2EMT,summer.day,0.0 +2040,1,GASPRD,summer.peak,-0.0 +2040,1,GASNAT,summer.peak,0.0 +2040,1,CO2EMT,summer.peak,0.0 +2040,1,GASPRD,summer.evening,-28.106738155604855 +2040,1,GASNAT,summer.evening,26.768322052957004 +2040,1,CO2EMT,summer.evening,68.43321532838459 +2040,1,GASPRD,autumn.night,-0.0 +2040,1,GASNAT,autumn.night,0.0 +2040,1,CO2EMT,autumn.night,0.0 +2040,1,GASPRD,autumn.day,-13.292701273257066 +2040,1,GASNAT,autumn.day,12.659715498340063 +2040,1,CO2EMT,autumn.day,32.36456267150637 +2040,1,GASPRD,autumn.peak,-124.10114062500001 +2040,1,GASNAT,autumn.peak,118.1915625 +2040,1,CO2EMT,autumn.peak,302.15672953125005 +2040,1,GASPRD,autumn.evening,-165.4681888237455 +2040,1,GASNAT,autumn.evening,157.58875126070998 +2040,1,CO2EMT,autumn.evening,402.87564259800513 +2040,6,GASNAT,winter.night,-29.838533129172095 +2040,6,RSHEAT,winter.night,25.94655054710617 +2040,6,CO2EMT,winter.night,1525.6441988945694 +2040,6,GASNAT,winter.day,-42.62647584035811 +2040,6,RSHEAT,winter.day,37.066500730746185 +2040,6,CO2EMT,winter.day,2179.4917097175103 +2040,6,GASNAT,winter.peak,-12.787942711186016 +2040,6,RSHEAT,winter.peak,11.119950183640015 +2040,6,CO2EMT,winter.peak,653.8475108229411 +2040,6,GASNAT,winter.evening,-17.050590417986076 +2040,6,RSHEAT,winter.evening,14.826600363466154 +2040,6,CO2EMT,winter.evening,871.7966880716282 +2040,6,GASNAT,peak.night,-29.838533129172095 +2040,6,RSHEAT,peak.night,25.94655054710617 +2040,6,CO2EMT,peak.night,1525.6441988945694 +2040,6,GASNAT,peak.day,-42.62647584035811 +2040,6,RSHEAT,peak.day,37.066500730746185 +2040,6,CO2EMT,peak.day,2179.4917097175103 +2040,6,GASNAT,peak.peak,-12.787942711186016 +2040,6,RSHEAT,peak.peak,11.119950183640015 +2040,6,CO2EMT,peak.peak,653.8475108229411 +2040,6,GASNAT,peak.evening,-17.050590417986076 +2040,6,RSHEAT,peak.evening,14.826600363466154 +2040,6,CO2EMT,peak.evening,871.7966880716282 +2040,6,GASNAT,summer.night,-0.0 +2040,6,RSHEAT,summer.night,0.0 +2040,6,CO2EMT,summer.night,0.0 +2040,6,GASNAT,summer.day,-0.0 +2040,6,RSHEAT,summer.day,0.0 +2040,6,CO2EMT,summer.day,0.0 +2040,6,GASNAT,summer.peak,-0.0 +2040,6,RSHEAT,summer.peak,0.0 +2040,6,CO2EMT,summer.peak,0.0 +2040,6,GASNAT,summer.evening,-0.0 +2040,6,RSHEAT,summer.evening,0.0 +2040,6,CO2EMT,summer.evening,0.0 +2040,6,GASNAT,autumn.night,-29.838533129172095 +2040,6,RSHEAT,autumn.night,25.94655054710617 +2040,6,CO2EMT,autumn.night,1525.6441988945694 +2040,6,GASNAT,autumn.day,-42.62647584035811 +2040,6,RSHEAT,autumn.day,37.066500730746185 +2040,6,CO2EMT,autumn.day,2179.4917097175103 +2040,6,GASNAT,autumn.peak,-12.787942711186016 +2040,6,RSHEAT,autumn.peak,11.119950183640015 +2040,6,CO2EMT,autumn.peak,653.8475108229411 +2040,6,GASNAT,autumn.evening,-17.050590417986076 +2040,6,RSHEAT,autumn.evening,14.826600363466154 +2040,6,CO2EMT,autumn.evening,871.7966880716282 +2040,8,GASNAT,winter.night,-55.07888519119691 +2040,8,RSHEAT,winter.night,47.894682774953836 +2040,8,CO2EMT,winter.night,2816.183399825898 +2040,8,GASNAT,winter.day,-250.5715919948809 +2040,8,RSHEAT,winter.day,217.88834086511383 +2040,8,CO2EMT,winter.day,12811.72549869826 +2040,8,GASNAT,winter.peak,-131.38099422 +2040,8,RSHEAT,winter.peak,114.2443428 +2040,8,CO2EMT,winter.peak,6717.5102344686 +2040,8,GASNAT,winter.evening,-82.37491934335293 +2040,8,RSHEAT,winter.evening,71.63036464639386 +2040,8,CO2EMT,winter.evening,4211.829626025636 +2040,8,GASNAT,peak.night,-29.648126735860906 +2040,8,RSHEAT,peak.night,25.780979770313834 +2040,8,CO2EMT,peak.night,1515.9087200045683 +2040,8,GASNAT,peak.day,-115.5291897320529 +2040,8,RSHEAT,peak.day,100.46016498439383 +2040,8,CO2EMT,peak.day,5907.007470999865 +2040,8,GASNAT,peak.peak,-75.54876689511998 +2040,8,RSHEAT,peak.peak,65.6945799088 +2040,8,CO2EMT,peak.peak,3862.8084513474855 +2040,8,GASNAT,peak.evening,-36.53908908163693 +2040,8,RSHEAT,peak.evening,31.773120940553852 +2040,8,CO2EMT,peak.evening,1868.2436247440962 +2040,8,GASNAT,summer.night,-7.3878574402420005 +2040,8,RSHEAT,summer.night,6.424223861080001 +2040,8,CO2EMT,summer.night,377.7411509195735 +2040,8,GASNAT,summer.day,-12.309069277277 +2040,8,RSHEAT,summer.day,10.70353850198 +2040,8,CO2EMT,summer.day,629.362712147173 +2040,8,GASNAT,summer.peak,-4.053351218157 +2040,8,RSHEAT,summer.peak,3.5246532331800005 +2040,8,CO2EMT,summer.peak,207.24784778436745 +2040,8,GASNAT,summer.evening,-3.0180441172809997 +2040,8,RSHEAT,summer.evening,2.62438618894 +2040,8,CO2EMT,summer.evening,154.31259571657753 +2040,8,GASNAT,autumn.night,-18.480316070073908 +2040,8,RSHEAT,autumn.night,16.069840060933835 +2040,8,CO2EMT,autumn.night,944.898560662879 +2040,8,GASNAT,autumn.day,-84.54202508133689 +2040,8,RSHEAT,autumn.day,73.51480441855382 +2040,8,CO2EMT,autumn.day,4322.633742408756 +2040,8,GASNAT,autumn.peak,-57.871336489916985 +2040,8,RSHEAT,autumn.peak,50.32290129557999 +2040,8,CO2EMT,autumn.peak,2958.9614347294555 +2040,8,GASNAT,autumn.evening,-25.24280951901992 +2040,8,RSHEAT,autumn.evening,21.950269146973845 +2040,8,CO2EMT,autumn.evening,1290.6648507074885 diff --git a/tests/data/simple_marginal/commodity_prices.csv b/tests/data/simple_marginal/commodity_prices.csv new file mode 100644 index 000000000..a9b8ee0fc --- /dev/null +++ b/tests/data/simple_marginal/commodity_prices.csv @@ -0,0 +1,177 @@ +milestone_year,commodity_id,region_id,time_slice,price +2020,GASPRD,GBR,winter.night,2.20452 +2020,GASPRD,GBR,winter.day,2.20452 +2020,GASPRD,GBR,winter.peak,2.20452 +2020,GASPRD,GBR,winter.evening,2.20452 +2020,GASPRD,GBR,peak.night,2.20452 +2020,GASPRD,GBR,peak.day,2.20452 +2020,GASPRD,GBR,peak.peak,2.20452 +2020,GASPRD,GBR,peak.evening,2.20452 +2020,GASPRD,GBR,summer.night,2.20452 +2020,GASPRD,GBR,summer.day,2.20452 +2020,GASPRD,GBR,summer.peak,2.20452 +2020,GASPRD,GBR,summer.evening,2.20452 +2020,GASPRD,GBR,autumn.night,2.20452 +2020,GASPRD,GBR,autumn.day,2.20452 +2020,GASPRD,GBR,autumn.peak,2.20452 +2020,GASPRD,GBR,autumn.evening,2.20452 +2020,GASNAT,GBR,winter.night,2.9170059999999998 +2020,GASNAT,GBR,winter.day,2.9170059999999998 +2020,GASNAT,GBR,winter.peak,2.9170059999999998 +2020,GASNAT,GBR,winter.evening,2.9170059999999998 +2020,GASNAT,GBR,peak.night,2.9170059999999998 +2020,GASNAT,GBR,peak.day,2.9170059999999998 +2020,GASNAT,GBR,peak.peak,2.9170059999999998 +2020,GASNAT,GBR,peak.evening,2.9170059999999998 +2020,GASNAT,GBR,summer.night,2.9170059999999998 +2020,GASNAT,GBR,summer.day,2.9170059999999998 +2020,GASNAT,GBR,summer.peak,2.9170059999999998 +2020,GASNAT,GBR,summer.evening,2.9170059999999998 +2020,GASNAT,GBR,autumn.night,2.9170059999999998 +2020,GASNAT,GBR,autumn.day,2.9170059999999998 +2020,GASNAT,GBR,autumn.peak,2.9170059999999998 +2020,GASNAT,GBR,autumn.evening,2.9170059999999998 +2020,RSHEAT,GBR,winter.night,5.8665369 +2020,RSHEAT,GBR,winter.day,5.8665369 +2020,RSHEAT,GBR,winter.peak,5.8665369 +2020,RSHEAT,GBR,winter.evening,5.8665369 +2020,RSHEAT,GBR,peak.night,5.8665369 +2020,RSHEAT,GBR,peak.day,5.8665369 +2020,RSHEAT,GBR,peak.peak,5.8665369 +2020,RSHEAT,GBR,peak.evening,5.8665369 +2020,RSHEAT,GBR,summer.night,2.80779197 +2020,RSHEAT,GBR,summer.day,0.30200000000000005 +2020,RSHEAT,GBR,summer.peak,0.30200000000000005 +2020,RSHEAT,GBR,summer.evening,0.30200000000000005 +2020,RSHEAT,GBR,autumn.night,5.8665369 +2020,RSHEAT,GBR,autumn.day,5.8665369 +2020,RSHEAT,GBR,autumn.peak,5.8665369 +2020,RSHEAT,GBR,autumn.evening,5.8665369 +2020,ELCTRI,GBR,winter.night,7.993308999999999 +2020,ELCTRI,GBR,winter.day,7.993308999999999 +2020,ELCTRI,GBR,winter.peak,7.993308999999999 +2020,ELCTRI,GBR,winter.evening,7.993308999999999 +2020,ELCTRI,GBR,peak.night,7.993308999999999 +2020,ELCTRI,GBR,peak.day,7.993308999999999 +2020,ELCTRI,GBR,peak.peak,7.993308999999999 +2020,ELCTRI,GBR,peak.evening,7.993308999999999 +2020,ELCTRI,GBR,summer.night,7.993308999999999 +2020,ELCTRI,GBR,summer.day,0.4 +2020,ELCTRI,GBR,summer.peak,0.4 +2020,ELCTRI,GBR,summer.evening,0.4 +2020,ELCTRI,GBR,autumn.night,7.993308999999999 +2020,ELCTRI,GBR,autumn.day,7.993308999999999 +2020,ELCTRI,GBR,autumn.peak,7.993308999999999 +2020,ELCTRI,GBR,autumn.evening,7.993308999999999 +2030,GASPRD,GBR,winter.night,2.20452 +2030,GASPRD,GBR,winter.day,2.20452 +2030,GASPRD,GBR,winter.peak,2.20452 +2030,GASPRD,GBR,winter.evening,2.20452 +2030,GASPRD,GBR,peak.night,2.20452 +2030,GASPRD,GBR,peak.day,2.20452 +2030,GASPRD,GBR,peak.peak,2.20452 +2030,GASPRD,GBR,peak.evening,2.20452 +2030,GASPRD,GBR,summer.night,2.20452 +2030,GASPRD,GBR,summer.day,2.20452 +2030,GASPRD,GBR,summer.peak,2.20452 +2030,GASPRD,GBR,summer.evening,2.20452 +2030,GASPRD,GBR,autumn.night,2.20452 +2030,GASPRD,GBR,autumn.day,2.20452 +2030,GASPRD,GBR,autumn.peak,2.20452 +2030,GASPRD,GBR,autumn.evening,2.20452 +2030,GASNAT,GBR,winter.night,2.9170059999999998 +2030,GASNAT,GBR,winter.day,2.9170059999999998 +2030,GASNAT,GBR,winter.peak,2.9170059999999998 +2030,GASNAT,GBR,winter.evening,2.9170059999999998 +2030,GASNAT,GBR,peak.night,2.9170059999999998 +2030,GASNAT,GBR,peak.day,2.9170059999999998 +2030,GASNAT,GBR,peak.peak,2.9170059999999998 +2030,GASNAT,GBR,peak.evening,2.9170059999999998 +2030,GASNAT,GBR,summer.night,2.9170059999999998 +2030,GASNAT,GBR,summer.day,2.9170059999999998 +2030,GASNAT,GBR,summer.peak,2.9170059999999998 +2030,GASNAT,GBR,summer.evening,2.9170059999999998 +2030,GASNAT,GBR,autumn.night,2.9170059999999998 +2030,GASNAT,GBR,autumn.day,2.9170059999999998 +2030,GASNAT,GBR,autumn.peak,2.9170059999999998 +2030,GASNAT,GBR,autumn.evening,2.9170059999999998 +2030,RSHEAT,GBR,winter.night,5.8665369 +2030,RSHEAT,GBR,winter.day,5.8665369 +2030,RSHEAT,GBR,winter.peak,5.8665369 +2030,RSHEAT,GBR,winter.evening,5.8665369 +2030,RSHEAT,GBR,peak.night,5.8665369 +2030,RSHEAT,GBR,peak.day,5.8665369 +2030,RSHEAT,GBR,peak.peak,5.8665369 +2030,RSHEAT,GBR,peak.evening,5.8665369 +2030,RSHEAT,GBR,summer.night,2.80779197 +2030,RSHEAT,GBR,summer.day,0.30200000000000005 +2030,RSHEAT,GBR,summer.peak,0.30200000000000005 +2030,RSHEAT,GBR,summer.evening,0.30200000000000005 +2030,RSHEAT,GBR,autumn.night,5.8665369 +2030,RSHEAT,GBR,autumn.day,5.8665369 +2030,RSHEAT,GBR,autumn.peak,5.8665369 +2030,RSHEAT,GBR,autumn.evening,5.8665369 +2030,ELCTRI,GBR,winter.night,7.993308999999999 +2030,ELCTRI,GBR,winter.day,7.993308999999999 +2030,ELCTRI,GBR,winter.peak,7.993308999999999 +2030,ELCTRI,GBR,winter.evening,7.993308999999999 +2030,ELCTRI,GBR,peak.night,7.993308999999999 +2030,ELCTRI,GBR,peak.day,7.993308999999999 +2030,ELCTRI,GBR,peak.peak,7.993308999999999 +2030,ELCTRI,GBR,peak.evening,7.993308999999999 +2030,ELCTRI,GBR,summer.night,7.993308999999999 +2030,ELCTRI,GBR,summer.day,0.4 +2030,ELCTRI,GBR,summer.peak,0.4 +2030,ELCTRI,GBR,summer.evening,0.4 +2030,ELCTRI,GBR,autumn.night,7.993308999999999 +2030,ELCTRI,GBR,autumn.day,7.993308999999999 +2030,ELCTRI,GBR,autumn.peak,7.993308999999999 +2030,ELCTRI,GBR,autumn.evening,7.993308999999999 +2040,GASPRD,GBR,winter.night,2.20452 +2040,GASPRD,GBR,winter.day,2.20452 +2040,GASPRD,GBR,winter.peak,2.20452 +2040,GASPRD,GBR,winter.evening,2.20452 +2040,GASPRD,GBR,peak.night,2.20452 +2040,GASPRD,GBR,peak.day,2.20452 +2040,GASPRD,GBR,peak.peak,2.20452 +2040,GASPRD,GBR,peak.evening,2.20452 +2040,GASPRD,GBR,summer.night,2.20452 +2040,GASPRD,GBR,summer.day,2.20452 +2040,GASPRD,GBR,summer.peak,2.20452 +2040,GASPRD,GBR,summer.evening,2.20452 +2040,GASPRD,GBR,autumn.night,2.20452 +2040,GASPRD,GBR,autumn.day,2.20452 +2040,GASPRD,GBR,autumn.peak,2.20452 +2040,GASPRD,GBR,autumn.evening,2.20452 +2040,GASNAT,GBR,winter.night,2.9170059999999998 +2040,GASNAT,GBR,winter.day,2.9170059999999998 +2040,GASNAT,GBR,winter.peak,2.9170059999999998 +2040,GASNAT,GBR,winter.evening,2.9170059999999998 +2040,GASNAT,GBR,peak.night,2.9170059999999998 +2040,GASNAT,GBR,peak.day,2.9170059999999998 +2040,GASNAT,GBR,peak.peak,2.9170059999999998 +2040,GASNAT,GBR,peak.evening,2.9170059999999998 +2040,GASNAT,GBR,summer.night,2.9170059999999998 +2040,GASNAT,GBR,summer.day,2.9170059999999998 +2040,GASNAT,GBR,summer.peak,2.9170059999999998 +2040,GASNAT,GBR,summer.evening,2.9170059999999998 +2040,GASNAT,GBR,autumn.night,2.9170059999999998 +2040,GASNAT,GBR,autumn.day,2.9170059999999998 +2040,GASNAT,GBR,autumn.peak,2.9170059999999998 +2040,GASNAT,GBR,autumn.evening,2.9170059999999998 +2040,RSHEAT,GBR,winter.night,5.8665369 +2040,RSHEAT,GBR,winter.day,5.8665369 +2040,RSHEAT,GBR,winter.peak,5.8665369 +2040,RSHEAT,GBR,winter.evening,5.8665369 +2040,RSHEAT,GBR,peak.night,5.8665369 +2040,RSHEAT,GBR,peak.day,5.8665369 +2040,RSHEAT,GBR,peak.peak,5.8665369 +2040,RSHEAT,GBR,peak.evening,5.8665369 +2040,RSHEAT,GBR,summer.night,5.8665369 +2040,RSHEAT,GBR,summer.day,5.8665369 +2040,RSHEAT,GBR,summer.peak,5.8665369 +2040,RSHEAT,GBR,summer.evening,5.8665369 +2040,RSHEAT,GBR,autumn.night,5.8665369 +2040,RSHEAT,GBR,autumn.day,5.8665369 +2040,RSHEAT,GBR,autumn.peak,5.8665369 +2040,RSHEAT,GBR,autumn.evening,5.8665369 diff --git a/tests/data/two_outputs/commodity_prices.csv b/tests/data/two_outputs/commodity_prices.csv index dd04d0b45..90b7e851e 100644 --- a/tests/data/two_outputs/commodity_prices.csv +++ b/tests/data/two_outputs/commodity_prices.csv @@ -31,22 +31,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASPRD,GBR,autumn.day,2.20452 2020,GASPRD,GBR,autumn.peak,2.20452 2020,GASPRD,GBR,autumn.evening,2.20452 -2020,BIOPRD,GBR,winter.night,3.5869398412698414 -2020,BIOPRD,GBR,winter.day,3.5869398412698414 -2020,BIOPRD,GBR,winter.peak,3.5869398412698414 -2020,BIOPRD,GBR,winter.evening,3.5869398412698414 -2020,BIOPRD,GBR,peak.night,3.5869398412698414 -2020,BIOPRD,GBR,peak.day,3.5869398412698414 -2020,BIOPRD,GBR,peak.peak,3.5869398412698414 -2020,BIOPRD,GBR,peak.evening,3.5869398412698414 -2020,BIOPRD,GBR,summer.night,0.25 -2020,BIOPRD,GBR,summer.day,0.25 -2020,BIOPRD,GBR,summer.peak,0.25 -2020,BIOPRD,GBR,summer.evening,0.25 -2020,BIOPRD,GBR,autumn.night,3.586939841269842 -2020,BIOPRD,GBR,autumn.day,3.586939841269842 -2020,BIOPRD,GBR,autumn.peak,3.586939841269842 -2020,BIOPRD,GBR,autumn.evening,3.586939841269842 2020,GASOLI,GBR,winter.night,10.570299353027398 2020,GASOLI,GBR,winter.day,10.570299353027398 2020,GASOLI,GBR,winter.peak,10.570299353027398 @@ -95,22 +79,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,GASNAT,GBR,autumn.day,2.9170059999999998 2020,GASNAT,GBR,autumn.peak,2.9170059999999998 2020,GASNAT,GBR,autumn.evening,2.9170059999999998 -2020,BIOPEL,GBR,winter.night,4.7221140833333335 -2020,BIOPEL,GBR,winter.day,4.7221140833333335 -2020,BIOPEL,GBR,winter.peak,4.7221140833333335 -2020,BIOPEL,GBR,winter.evening,4.7221140833333335 -2020,BIOPEL,GBR,peak.night,4.7221140833333335 -2020,BIOPEL,GBR,peak.day,4.7221140833333335 -2020,BIOPEL,GBR,peak.peak,4.7221140833333335 -2020,BIOPEL,GBR,peak.evening,4.7221140833333335 -2020,BIOPEL,GBR,summer.night,1.21832725 -2020,BIOPEL,GBR,summer.day,1.21832725 -2020,BIOPEL,GBR,summer.peak,1.21832725 -2020,BIOPEL,GBR,summer.evening,1.21832725 -2020,BIOPEL,GBR,autumn.night,4.7221140833333335 -2020,BIOPEL,GBR,autumn.day,4.7221140833333335 -2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 -2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2020,ELCTRI,GBR,winter.night,7.993308999999999 2020,ELCTRI,GBR,winter.day,17.26223303030303 2020,ELCTRI,GBR,winter.peak,20.410312516918875 @@ -159,6 +127,38 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,RSHEAT,GBR,autumn.day,5.8665369 2020,RSHEAT,GBR,autumn.peak,5.8665369 2020,RSHEAT,GBR,autumn.evening,5.8665369 +2020,BIOPRD,GBR,winter.night,3.5869398412698414 +2020,BIOPRD,GBR,winter.day,3.5869398412698414 +2020,BIOPRD,GBR,winter.peak,3.5869398412698414 +2020,BIOPRD,GBR,winter.evening,3.5869398412698414 +2020,BIOPRD,GBR,peak.night,3.5869398412698414 +2020,BIOPRD,GBR,peak.day,3.5869398412698414 +2020,BIOPRD,GBR,peak.peak,3.5869398412698414 +2020,BIOPRD,GBR,peak.evening,3.5869398412698414 +2020,BIOPRD,GBR,summer.night,0.25 +2020,BIOPRD,GBR,summer.day,0.25 +2020,BIOPRD,GBR,summer.peak,0.25 +2020,BIOPRD,GBR,summer.evening,0.25 +2020,BIOPRD,GBR,autumn.night,3.586939841269842 +2020,BIOPRD,GBR,autumn.day,3.586939841269842 +2020,BIOPRD,GBR,autumn.peak,3.586939841269842 +2020,BIOPRD,GBR,autumn.evening,3.586939841269842 +2020,BIOPEL,GBR,winter.night,4.7221140833333335 +2020,BIOPEL,GBR,winter.day,4.7221140833333335 +2020,BIOPEL,GBR,winter.peak,4.7221140833333335 +2020,BIOPEL,GBR,winter.evening,4.7221140833333335 +2020,BIOPEL,GBR,peak.night,4.7221140833333335 +2020,BIOPEL,GBR,peak.day,4.7221140833333335 +2020,BIOPEL,GBR,peak.peak,4.7221140833333335 +2020,BIOPEL,GBR,peak.evening,4.7221140833333335 +2020,BIOPEL,GBR,summer.night,1.21832725 +2020,BIOPEL,GBR,summer.day,1.21832725 +2020,BIOPEL,GBR,summer.peak,1.21832725 +2020,BIOPEL,GBR,summer.evening,1.21832725 +2020,BIOPEL,GBR,autumn.night,4.7221140833333335 +2020,BIOPEL,GBR,autumn.day,4.7221140833333335 +2020,BIOPEL,GBR,autumn.peak,4.7221140833333335 +2020,BIOPEL,GBR,autumn.evening,4.7221140833333335 2030,OILCRD,GBR,winter.night,3.072868 2030,OILCRD,GBR,winter.day,3.072868 2030,OILCRD,GBR,winter.peak,3.072868 @@ -191,22 +191,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASPRD,GBR,autumn.day,2.20452 2030,GASPRD,GBR,autumn.peak,2.20452 2030,GASPRD,GBR,autumn.evening,2.20452 -2030,BIOPRD,GBR,winter.night,4.249632460317461 -2030,BIOPRD,GBR,winter.day,4.249632460317461 -2030,BIOPRD,GBR,winter.peak,4.249632460317461 -2030,BIOPRD,GBR,winter.evening,4.249632460317461 -2030,BIOPRD,GBR,peak.night,1.822057119047619 -2030,BIOPRD,GBR,peak.day,1.822057119047619 -2030,BIOPRD,GBR,peak.peak,1.822057119047619 -2030,BIOPRD,GBR,peak.evening,1.822057119047619 -2030,BIOPRD,GBR,summer.night,0.25 -2030,BIOPRD,GBR,summer.day,0.25 -2030,BIOPRD,GBR,summer.peak,0.25 -2030,BIOPRD,GBR,summer.evening,0.25 -2030,BIOPRD,GBR,autumn.night,1.822057119047619 -2030,BIOPRD,GBR,autumn.day,1.822057119047619 -2030,BIOPRD,GBR,autumn.peak,1.822057119047619 -2030,BIOPRD,GBR,autumn.evening,1.822057119047619 2030,GASOLI,GBR,winter.night,5.585457080000001 2030,GASOLI,GBR,winter.day,5.585457080000001 2030,GASOLI,GBR,winter.peak,5.585457080000001 @@ -255,22 +239,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,GASNAT,GBR,autumn.day,2.9170059999999998 2030,GASNAT,GBR,autumn.peak,2.9170059999999998 2030,GASNAT,GBR,autumn.evening,2.9170059999999998 -2030,BIOPEL,GBR,winter.night,4.7221140833333335 -2030,BIOPEL,GBR,winter.day,4.7221140833333335 -2030,BIOPEL,GBR,winter.peak,4.7221140833333335 -2030,BIOPEL,GBR,winter.evening,4.7221140833333335 -2030,BIOPEL,GBR,peak.night,2.173159975 -2030,BIOPEL,GBR,peak.day,2.173159975 -2030,BIOPEL,GBR,peak.peak,2.173159975 -2030,BIOPEL,GBR,peak.evening,2.173159975 -2030,BIOPEL,GBR,summer.night,0.5225 -2030,BIOPEL,GBR,summer.day,0.5225 -2030,BIOPEL,GBR,summer.peak,0.5225 -2030,BIOPEL,GBR,summer.evening,0.5225 -2030,BIOPEL,GBR,autumn.night,2.173159975 -2030,BIOPEL,GBR,autumn.day,2.173159975 -2030,BIOPEL,GBR,autumn.peak,2.173159975 -2030,BIOPEL,GBR,autumn.evening,2.173159975 2030,ELCTRI,GBR,winter.night,7.993308999999999 2030,ELCTRI,GBR,winter.day,7.993308999999999 2030,ELCTRI,GBR,winter.peak,7.993308999999999 @@ -319,6 +287,38 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,RSHEAT,GBR,autumn.day,5.8665369 2030,RSHEAT,GBR,autumn.peak,5.8665369 2030,RSHEAT,GBR,autumn.evening,5.8665369 +2030,BIOPRD,GBR,winter.night,4.249632460317461 +2030,BIOPRD,GBR,winter.day,4.249632460317461 +2030,BIOPRD,GBR,winter.peak,4.249632460317461 +2030,BIOPRD,GBR,winter.evening,4.249632460317461 +2030,BIOPRD,GBR,peak.night,1.822057119047619 +2030,BIOPRD,GBR,peak.day,1.822057119047619 +2030,BIOPRD,GBR,peak.peak,1.822057119047619 +2030,BIOPRD,GBR,peak.evening,1.822057119047619 +2030,BIOPRD,GBR,summer.night,0.25 +2030,BIOPRD,GBR,summer.day,0.25 +2030,BIOPRD,GBR,summer.peak,0.25 +2030,BIOPRD,GBR,summer.evening,0.25 +2030,BIOPRD,GBR,autumn.night,1.822057119047619 +2030,BIOPRD,GBR,autumn.day,1.822057119047619 +2030,BIOPRD,GBR,autumn.peak,1.822057119047619 +2030,BIOPRD,GBR,autumn.evening,1.822057119047619 +2030,BIOPEL,GBR,winter.night,4.7221140833333335 +2030,BIOPEL,GBR,winter.day,4.7221140833333335 +2030,BIOPEL,GBR,winter.peak,4.7221140833333335 +2030,BIOPEL,GBR,winter.evening,4.7221140833333335 +2030,BIOPEL,GBR,peak.night,2.173159975 +2030,BIOPEL,GBR,peak.day,2.173159975 +2030,BIOPEL,GBR,peak.peak,2.173159975 +2030,BIOPEL,GBR,peak.evening,2.173159975 +2030,BIOPEL,GBR,summer.night,0.5225 +2030,BIOPEL,GBR,summer.day,0.5225 +2030,BIOPEL,GBR,summer.peak,0.5225 +2030,BIOPEL,GBR,summer.evening,0.5225 +2030,BIOPEL,GBR,autumn.night,2.173159975 +2030,BIOPEL,GBR,autumn.day,2.173159975 +2030,BIOPEL,GBR,autumn.peak,2.173159975 +2030,BIOPEL,GBR,autumn.evening,2.173159975 2040,OILCRD,GBR,winter.night,3.072868 2040,OILCRD,GBR,winter.day,3.072868 2040,OILCRD,GBR,winter.peak,3.072868 @@ -351,22 +351,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASPRD,GBR,autumn.day,2.20452 2040,GASPRD,GBR,autumn.peak,2.20452 2040,GASPRD,GBR,autumn.evening,2.20452 -2040,BIOPRD,GBR,winter.night,0.25 -2040,BIOPRD,GBR,winter.day,0.25 -2040,BIOPRD,GBR,winter.peak,0.25 -2040,BIOPRD,GBR,winter.evening,0.25 -2040,BIOPRD,GBR,peak.night,0.25 -2040,BIOPRD,GBR,peak.day,0.25 -2040,BIOPRD,GBR,peak.peak,0.25 -2040,BIOPRD,GBR,peak.evening,0.25 -2040,BIOPRD,GBR,summer.night,0.25 -2040,BIOPRD,GBR,summer.day,0.25 -2040,BIOPRD,GBR,summer.peak,0.25 -2040,BIOPRD,GBR,summer.evening,0.25 -2040,BIOPRD,GBR,autumn.night,0.25 -2040,BIOPRD,GBR,autumn.day,0.25 -2040,BIOPRD,GBR,autumn.peak,0.25 -2040,BIOPRD,GBR,autumn.evening,0.25 2040,GASOLI,GBR,winter.night,5.585457080000001 2040,GASOLI,GBR,winter.day,5.585457080000001 2040,GASOLI,GBR,winter.peak,5.585457080000001 @@ -399,22 +383,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,GASNAT,GBR,autumn.day,2.9170059999999998 2040,GASNAT,GBR,autumn.peak,2.9170059999999998 2040,GASNAT,GBR,autumn.evening,2.9170059999999998 -2040,BIOPEL,GBR,winter.night,0.5225 -2040,BIOPEL,GBR,winter.day,0.5225 -2040,BIOPEL,GBR,winter.peak,0.5225 -2040,BIOPEL,GBR,winter.evening,0.5225 -2040,BIOPEL,GBR,peak.night,0.5225 -2040,BIOPEL,GBR,peak.day,0.5225 -2040,BIOPEL,GBR,peak.peak,0.5225 -2040,BIOPEL,GBR,peak.evening,0.5225 -2040,BIOPEL,GBR,summer.night,0.5225 -2040,BIOPEL,GBR,summer.day,0.5225 -2040,BIOPEL,GBR,summer.peak,0.5225 -2040,BIOPEL,GBR,summer.evening,0.5225 -2040,BIOPEL,GBR,autumn.night,0.5225 -2040,BIOPEL,GBR,autumn.day,0.5225 -2040,BIOPEL,GBR,autumn.peak,0.5225 -2040,BIOPEL,GBR,autumn.evening,0.5225 2040,ELCTRI,GBR,winter.night,7.993308999999999 2040,ELCTRI,GBR,winter.day,7.993308999999999 2040,ELCTRI,GBR,winter.peak,7.993308999999999 @@ -463,3 +431,35 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,RSHEAT,GBR,autumn.day,0.827 2040,RSHEAT,GBR,autumn.peak,0.827 2040,RSHEAT,GBR,autumn.evening,0.827 +2040,BIOPRD,GBR,winter.night,0.25 +2040,BIOPRD,GBR,winter.day,0.25 +2040,BIOPRD,GBR,winter.peak,0.25 +2040,BIOPRD,GBR,winter.evening,0.25 +2040,BIOPRD,GBR,peak.night,0.25 +2040,BIOPRD,GBR,peak.day,0.25 +2040,BIOPRD,GBR,peak.peak,0.25 +2040,BIOPRD,GBR,peak.evening,0.25 +2040,BIOPRD,GBR,summer.night,0.25 +2040,BIOPRD,GBR,summer.day,0.25 +2040,BIOPRD,GBR,summer.peak,0.25 +2040,BIOPRD,GBR,summer.evening,0.25 +2040,BIOPRD,GBR,autumn.night,0.25 +2040,BIOPRD,GBR,autumn.day,0.25 +2040,BIOPRD,GBR,autumn.peak,0.25 +2040,BIOPRD,GBR,autumn.evening,0.25 +2040,BIOPEL,GBR,winter.night,0.5225 +2040,BIOPEL,GBR,winter.day,0.5225 +2040,BIOPEL,GBR,winter.peak,0.5225 +2040,BIOPEL,GBR,winter.evening,0.5225 +2040,BIOPEL,GBR,peak.night,0.5225 +2040,BIOPEL,GBR,peak.day,0.5225 +2040,BIOPEL,GBR,peak.peak,0.5225 +2040,BIOPEL,GBR,peak.evening,0.5225 +2040,BIOPEL,GBR,summer.night,0.5225 +2040,BIOPEL,GBR,summer.day,0.5225 +2040,BIOPEL,GBR,summer.peak,0.5225 +2040,BIOPEL,GBR,summer.evening,0.5225 +2040,BIOPEL,GBR,autumn.night,0.5225 +2040,BIOPEL,GBR,autumn.day,0.5225 +2040,BIOPEL,GBR,autumn.peak,0.5225 +2040,BIOPEL,GBR,autumn.evening,0.5225 diff --git a/tests/data/two_regions/commodity_prices.csv b/tests/data/two_regions/commodity_prices.csv index 267136d1f..11a49d2bf 100644 --- a/tests/data/two_regions/commodity_prices.csv +++ b/tests/data/two_regions/commodity_prices.csv @@ -1,16 +1,4 @@ milestone_year,commodity_id,region_id,time_slice,price -2020,gas,R1,all-year.night,2.55 -2020,gas,R1,all-year.morning,2.55 -2020,gas,R1,all-year.afternoon,2.55 -2020,gas,R1,all-year.early-peak,2.55 -2020,gas,R1,all-year.late-peak,2.55 -2020,gas,R1,all-year.evening,2.55 -2020,gas,R2,all-year.night,2.55 -2020,gas,R2,all-year.morning,2.55 -2020,gas,R2,all-year.afternoon,2.55 -2020,gas,R2,all-year.early-peak,2.55 -2020,gas,R2,all-year.late-peak,2.55 -2020,gas,R2,all-year.evening,2.55 2020,electricity,R1,all-year.night,-0.0 2020,electricity,R1,all-year.morning,-0.0 2020,electricity,R1,all-year.afternoon,-0.0 @@ -23,6 +11,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,electricity,R2,all-year.early-peak,-0.0 2020,electricity,R2,all-year.late-peak,-0.0 2020,electricity,R2,all-year.evening,-0.0 +2020,gas,R1,all-year.night,2.55 +2020,gas,R1,all-year.morning,2.55 +2020,gas,R1,all-year.afternoon,2.55 +2020,gas,R1,all-year.early-peak,2.55 +2020,gas,R1,all-year.late-peak,2.55 +2020,gas,R1,all-year.evening,2.55 +2020,gas,R2,all-year.night,2.55 +2020,gas,R2,all-year.morning,2.55 +2020,gas,R2,all-year.afternoon,2.55 +2020,gas,R2,all-year.early-peak,2.55 +2020,gas,R2,all-year.late-peak,2.55 +2020,gas,R2,all-year.evening,2.55 2020,heat,R1,all-year.night,8.3380664049 2020,heat,R1,all-year.morning,8.3380664049 2020,heat,R1,all-year.afternoon,8.3380664049 @@ -35,18 +35,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2020,heat,R2,all-year.early-peak,2.9579999999999997 2020,heat,R2,all-year.late-peak,2.9579999999999997 2020,heat,R2,all-year.evening,2.9579999999999997 -2025,gas,R1,all-year.night,2.5500000000000007 -2025,gas,R1,all-year.morning,2.55 -2025,gas,R1,all-year.afternoon,2.55 -2025,gas,R1,all-year.early-peak,2.5500000000000007 -2025,gas,R1,all-year.late-peak,2.55 -2025,gas,R1,all-year.evening,2.5500000000000007 -2025,gas,R2,all-year.night,2.55 -2025,gas,R2,all-year.morning,2.55 -2025,gas,R2,all-year.afternoon,2.55 -2025,gas,R2,all-year.early-peak,2.55 -2025,gas,R2,all-year.late-peak,2.55 -2025,gas,R2,all-year.evening,2.55 2025,electricity,R1,all-year.night,15.26529810765 2025,electricity,R1,all-year.morning,15.26529810765 2025,electricity,R1,all-year.afternoon,15.26529810765 @@ -59,6 +47,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2025,electricity,R2,all-year.early-peak,4.2585 2025,electricity,R2,all-year.late-peak,4.2585 2025,electricity,R2,all-year.evening,4.2585 +2025,gas,R1,all-year.night,2.5500000000000007 +2025,gas,R1,all-year.morning,2.55 +2025,gas,R1,all-year.afternoon,2.55 +2025,gas,R1,all-year.early-peak,2.5500000000000007 +2025,gas,R1,all-year.late-peak,2.55 +2025,gas,R1,all-year.evening,2.5500000000000007 +2025,gas,R2,all-year.night,2.55 +2025,gas,R2,all-year.morning,2.55 +2025,gas,R2,all-year.afternoon,2.55 +2025,gas,R2,all-year.early-peak,2.55 +2025,gas,R2,all-year.late-peak,2.55 +2025,gas,R2,all-year.evening,2.55 2025,heat,R1,all-year.night,6.10611924306 2025,heat,R1,all-year.morning,6.10611924306 2025,heat,R1,all-year.afternoon,6.10611924306 @@ -71,18 +71,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2025,heat,R2,all-year.early-peak,2.9579999999999997 2025,heat,R2,all-year.late-peak,2.9579999999999997 2025,heat,R2,all-year.evening,2.9579999999999997 -2030,gas,R1,all-year.night,-0.0 -2030,gas,R1,all-year.morning,-0.0 -2030,gas,R1,all-year.afternoon,-0.0 -2030,gas,R1,all-year.early-peak,-0.0 -2030,gas,R1,all-year.late-peak,-0.0 -2030,gas,R1,all-year.evening,-0.0 -2030,gas,R2,all-year.night,2.55 -2030,gas,R2,all-year.morning,2.55 -2030,gas,R2,all-year.afternoon,2.55 -2030,gas,R2,all-year.early-peak,2.55 -2030,gas,R2,all-year.late-peak,2.5500000000000003 -2030,gas,R2,all-year.evening,2.55 2030,electricity,R1,all-year.night,-0.0 2030,electricity,R1,all-year.morning,-0.0 2030,electricity,R1,all-year.afternoon,-0.0 @@ -95,6 +83,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,electricity,R2,all-year.early-peak,4.2585 2030,electricity,R2,all-year.late-peak,4.2585 2030,electricity,R2,all-year.evening,4.2585 +2030,gas,R1,all-year.night,-0.0 +2030,gas,R1,all-year.morning,-0.0 +2030,gas,R1,all-year.afternoon,-0.0 +2030,gas,R1,all-year.early-peak,-0.0 +2030,gas,R1,all-year.late-peak,-0.0 +2030,gas,R1,all-year.evening,-0.0 +2030,gas,R2,all-year.night,2.55 +2030,gas,R2,all-year.morning,2.55 +2030,gas,R2,all-year.afternoon,2.55 +2030,gas,R2,all-year.early-peak,2.55 +2030,gas,R2,all-year.late-peak,2.5500000000000003 +2030,gas,R2,all-year.evening,2.55 2030,heat,R1,all-year.night,-0.0 2030,heat,R1,all-year.morning,-0.0 2030,heat,R1,all-year.afternoon,-0.0 @@ -107,18 +107,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2030,heat,R2,all-year.early-peak,2.9579999999999997 2030,heat,R2,all-year.late-peak,2.958 2030,heat,R2,all-year.evening,2.9579999999999997 -2035,gas,R1,all-year.night,-0.0 -2035,gas,R1,all-year.morning,-0.0 -2035,gas,R1,all-year.afternoon,-0.0 -2035,gas,R1,all-year.early-peak,-0.0 -2035,gas,R1,all-year.late-peak,-0.0 -2035,gas,R1,all-year.evening,-0.0 -2035,gas,R2,all-year.night,2.55 -2035,gas,R2,all-year.morning,2.55 -2035,gas,R2,all-year.afternoon,2.55 -2035,gas,R2,all-year.early-peak,2.55 -2035,gas,R2,all-year.late-peak,2.55 -2035,gas,R2,all-year.evening,2.55 2035,electricity,R1,all-year.night,-0.0 2035,electricity,R1,all-year.morning,-0.0 2035,electricity,R1,all-year.afternoon,-0.0 @@ -131,6 +119,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2035,electricity,R2,all-year.early-peak,4.2585 2035,electricity,R2,all-year.late-peak,4.2585 2035,electricity,R2,all-year.evening,4.2585 +2035,gas,R1,all-year.night,-0.0 +2035,gas,R1,all-year.morning,-0.0 +2035,gas,R1,all-year.afternoon,-0.0 +2035,gas,R1,all-year.early-peak,-0.0 +2035,gas,R1,all-year.late-peak,-0.0 +2035,gas,R1,all-year.evening,-0.0 +2035,gas,R2,all-year.night,2.55 +2035,gas,R2,all-year.morning,2.55 +2035,gas,R2,all-year.afternoon,2.55 +2035,gas,R2,all-year.early-peak,2.55 +2035,gas,R2,all-year.late-peak,2.55 +2035,gas,R2,all-year.evening,2.55 2035,heat,R1,all-year.night,-0.0 2035,heat,R1,all-year.morning,-0.0 2035,heat,R1,all-year.afternoon,-0.0 @@ -143,18 +143,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2035,heat,R2,all-year.early-peak,2.9579999999999997 2035,heat,R2,all-year.late-peak,2.9579999999999997 2035,heat,R2,all-year.evening,2.9579999999999997 -2040,gas,R1,all-year.night,-0.0 -2040,gas,R1,all-year.morning,-0.0 -2040,gas,R1,all-year.afternoon,-0.0 -2040,gas,R1,all-year.early-peak,-0.0 -2040,gas,R1,all-year.late-peak,-0.0 -2040,gas,R1,all-year.evening,-0.0 -2040,gas,R2,all-year.night,2.55 -2040,gas,R2,all-year.morning,2.55 -2040,gas,R2,all-year.afternoon,2.55 -2040,gas,R2,all-year.early-peak,2.55 -2040,gas,R2,all-year.late-peak,2.55 -2040,gas,R2,all-year.evening,2.55 2040,electricity,R1,all-year.night,-0.0 2040,electricity,R1,all-year.morning,-0.0 2040,electricity,R1,all-year.afternoon,-0.0 @@ -167,6 +155,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,electricity,R2,all-year.early-peak,4.2585 2040,electricity,R2,all-year.late-peak,4.2585 2040,electricity,R2,all-year.evening,4.2585 +2040,gas,R1,all-year.night,-0.0 +2040,gas,R1,all-year.morning,-0.0 +2040,gas,R1,all-year.afternoon,-0.0 +2040,gas,R1,all-year.early-peak,-0.0 +2040,gas,R1,all-year.late-peak,-0.0 +2040,gas,R1,all-year.evening,-0.0 +2040,gas,R2,all-year.night,2.55 +2040,gas,R2,all-year.morning,2.55 +2040,gas,R2,all-year.afternoon,2.55 +2040,gas,R2,all-year.early-peak,2.55 +2040,gas,R2,all-year.late-peak,2.55 +2040,gas,R2,all-year.evening,2.55 2040,heat,R1,all-year.night,-0.0 2040,heat,R1,all-year.morning,-0.0 2040,heat,R1,all-year.afternoon,-0.0 @@ -179,18 +179,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2040,heat,R2,all-year.early-peak,2.9579999999999997 2040,heat,R2,all-year.late-peak,2.9579999999999997 2040,heat,R2,all-year.evening,2.9579999999999997 -2045,gas,R1,all-year.night,-0.0 -2045,gas,R1,all-year.morning,-0.0 -2045,gas,R1,all-year.afternoon,-0.0 -2045,gas,R1,all-year.early-peak,-0.0 -2045,gas,R1,all-year.late-peak,-0.0 -2045,gas,R1,all-year.evening,-0.0 -2045,gas,R2,all-year.night,2.5500000000000003 -2045,gas,R2,all-year.morning,2.55 -2045,gas,R2,all-year.afternoon,2.55 -2045,gas,R2,all-year.early-peak,2.5500000000000003 -2045,gas,R2,all-year.late-peak,2.55 -2045,gas,R2,all-year.evening,2.55 2045,electricity,R1,all-year.night,-0.0 2045,electricity,R1,all-year.morning,-0.0 2045,electricity,R1,all-year.afternoon,-0.0 @@ -203,6 +191,18 @@ milestone_year,commodity_id,region_id,time_slice,price 2045,electricity,R2,all-year.early-peak,4.2585 2045,electricity,R2,all-year.late-peak,4.2585 2045,electricity,R2,all-year.evening,4.2585 +2045,gas,R1,all-year.night,-0.0 +2045,gas,R1,all-year.morning,-0.0 +2045,gas,R1,all-year.afternoon,-0.0 +2045,gas,R1,all-year.early-peak,-0.0 +2045,gas,R1,all-year.late-peak,-0.0 +2045,gas,R1,all-year.evening,-0.0 +2045,gas,R2,all-year.night,2.5500000000000003 +2045,gas,R2,all-year.morning,2.55 +2045,gas,R2,all-year.afternoon,2.55 +2045,gas,R2,all-year.early-peak,2.5500000000000003 +2045,gas,R2,all-year.late-peak,2.55 +2045,gas,R2,all-year.evening,2.55 2045,heat,R1,all-year.night,-0.0 2045,heat,R1,all-year.morning,-0.0 2045,heat,R1,all-year.afternoon,-0.0 @@ -215,12 +215,6 @@ milestone_year,commodity_id,region_id,time_slice,price 2045,heat,R2,all-year.early-peak,2.958 2045,heat,R2,all-year.late-peak,2.9579999999999997 2045,heat,R2,all-year.evening,2.9579999999999997 -2050,gas,R2,all-year.night,2.55 -2050,gas,R2,all-year.morning,2.55 -2050,gas,R2,all-year.afternoon,2.55 -2050,gas,R2,all-year.early-peak,2.55 -2050,gas,R2,all-year.late-peak,2.55 -2050,gas,R2,all-year.evening,2.55 2050,electricity,R1,all-year.night,-0.0 2050,electricity,R1,all-year.morning,-0.0 2050,electricity,R1,all-year.afternoon,-0.0 @@ -233,6 +227,12 @@ milestone_year,commodity_id,region_id,time_slice,price 2050,electricity,R2,all-year.early-peak,4.2585 2050,electricity,R2,all-year.late-peak,4.2585 2050,electricity,R2,all-year.evening,4.2585 +2050,gas,R2,all-year.night,2.55 +2050,gas,R2,all-year.morning,2.55 +2050,gas,R2,all-year.afternoon,2.55 +2050,gas,R2,all-year.early-peak,2.55 +2050,gas,R2,all-year.late-peak,2.55 +2050,gas,R2,all-year.evening,2.55 2050,heat,R1,all-year.night,-0.0 2050,heat,R1,all-year.morning,-0.0 2050,heat,R1,all-year.afternoon,-0.0 diff --git a/tests/regression.rs b/tests/regression.rs index b60ac228d..254a41546 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -26,6 +26,8 @@ define_regression_test!(circularity); // Patched examples define_regression_test_with_patches!(simple_divisible); define_regression_test_with_patches!(simple_npv); +define_regression_test_with_patches!(simple_marginal); +define_regression_test_with_patches!(simple_full); // ------ END: regression tests ------ @@ -93,18 +95,18 @@ fn compare_lines( // Check for different number of lines if lines1.len() != lines2.len() { errors.push(format!( - "{}: Different number of lines: {} vs {}", - file_name, + "{file_name}: Different number of lines: {} vs {}", lines1.len(), lines2.len() )); } // Compare each line - for (num, (line1, line2)) in lines1.into_iter().zip(lines2).enumerate() { - if !compare_line(num, &line1, &line2, file_name, errors) { + for (idx, (line1, line2)) in lines1.into_iter().zip(lines2).enumerate() { + let line_num = idx + 1; // (1-based) line number + if !compare_line(line_num, &line1, &line2, file_name, errors) { errors.push(format!( - "{file_name}: line {num}:\n + \"{line1}\"\n - \"{line2}\"" + "{file_name}: line {line_num}:\n + \"{line1}\"\n - \"{line2}\"" )); } }