muse2/example/
patches.rs

1//! Patches to be used in integration tests.
2//!
3//! This is used to test small variations on existing example models.
4use crate::patch::FilePatch;
5use anyhow::{Context, Result};
6use std::{collections::BTreeMap, sync::LazyLock};
7
8/// Map of patches keyed by name, with the file patches and an optional TOML patch
9type PatchMap = BTreeMap<&'static str, (Vec<FilePatch>, Option<&'static str>)>;
10
11/// The patches, keyed by name
12static PATCHES: LazyLock<PatchMap> = LazyLock::new(get_all_patches);
13
14/// Get all patches
15fn get_all_patches() -> PatchMap {
16    [
17        // The simple example with gas boiler process made divisible
18        (
19            "simple_divisible",
20            (
21                vec![
22                    FilePatch::new("processes.csv")
23                        .with_deletion("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,")
24                        .with_addition("RGASBR,Gas boiler,all,RSHEAT,2020,2040,1.0,1000"),
25                ],
26                None,
27            ),
28        ),
29        // The simple example with objective type set to NPV for one agent
30        (
31            "simple_npv",
32            (
33                vec![
34                    FilePatch::new("agent_objectives.csv")
35                        .with_deletion("A0_RES,all,lcox,,")
36                        .with_addition("A0_RES,all,npv,,"),
37                ],
38                None,
39            ),
40        ),
41        (
42            // The simple example with electricity priced using marginal costs
43            "simple_marginal",
44            (
45                vec![FilePatch::new("commodities.csv").with_replacement(&[
46                    "id,description,type,time_slice_level,pricing_strategy,units",
47                    "GASPRD,Gas produced,sed,season,shadow,PJ",
48                    "GASNAT,Natural gas,sed,season,shadow,PJ",
49                    "ELCTRI,Electricity,sed,daynight,marginal,PJ",
50                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
51                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
52                ])],
53                None,
54            ),
55        ),
56        (
57            // The simple example with gas commodities priced using full costs
58            "simple_full",
59            (
60                vec![FilePatch::new("commodities.csv").with_replacement(&[
61                    "id,description,type,time_slice_level,pricing_strategy,units",
62                    "GASPRD,Gas produced,sed,season,full,PJ",
63                    "GASNAT,Natural gas,sed,season,full,PJ",
64                    "ELCTRI,Electricity,sed,daynight,shadow,PJ",
65                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
66                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
67                ])],
68                None,
69            ),
70        ),
71        (
72            // The simple example with electricity priced using average marginal costs
73            "simple_marginal_average",
74            (
75                vec![FilePatch::new("commodities.csv").with_replacement(&[
76                    "id,description,type,time_slice_level,pricing_strategy,units",
77                    "GASPRD,Gas produced,sed,season,shadow,PJ",
78                    "GASNAT,Natural gas,sed,season,shadow,PJ",
79                    "ELCTRI,Electricity,sed,daynight,marginal_average,PJ",
80                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
81                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
82                ])],
83                None,
84            ),
85        ),
86        (
87            // The simple example with gas commodities priced using average full costs
88            "simple_full_average",
89            (
90                vec![FilePatch::new("commodities.csv").with_replacement(&[
91                    "id,description,type,time_slice_level,pricing_strategy,units",
92                    "GASPRD,Gas produced,sed,season,full_average,PJ",
93                    "GASNAT,Natural gas,sed,season,full_average,PJ",
94                    "ELCTRI,Electricity,sed,daynight,shadow,PJ",
95                    "RSHEAT,Residential heating,svd,daynight,shadow,PJ",
96                    "CO2EMT,CO2 emitted,oth,annual,unpriced,ktCO2",
97                ])],
98                None,
99            ),
100        ),
101        // The simple example with the ironing-out loop turned on
102        (
103            "simple_ironing_out",
104            (vec![], Some("max_ironing_out_iterations = 10")),
105        ),
106    ]
107    .into_iter()
108    .collect()
109}
110
111/// Get the names for all the patches
112pub fn get_patch_names() -> impl Iterator<Item = &'static str> {
113    PATCHES.keys().copied()
114}
115
116/// Get patches for the named patched example
117pub fn get_patches(name: &str) -> Result<&'static (Vec<FilePatch>, Option<&'static str>)> {
118    PATCHES
119        .get(name)
120        .with_context(|| format!("Patched example '{name}' not found"))
121}