File size: 4,433 Bytes
fa58ff0
 
 
 
 
 
 
 
7b4d13c
fa58ff0
 
 
4885a3b
 
 
 
 
fa58ff0
 
 
4885a3b
 
fa58ff0
 
 
 
55ea210
 
 
 
 
 
 
 
fa58ff0
 
 
 
 
 
7b4d13c
 
 
 
 
 
 
 
 
 
fa58ff0
7b4d13c
4885a3b
7b4d13c
 
fa58ff0
 
4885a3b
fa58ff0
 
 
 
4885a3b
fa58ff0
 
7b4d13c
 
 
 
 
 
 
 
 
 
fa58ff0
 
 
7b4d13c
 
fa58ff0
50f75c1
 
fa58ff0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55ea210
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import json
import pandas as pd

CO2_UNIT = "MtCO₂"

with open("data/method_groups.json") as _f:
    method_groups: dict[str, list[str]] = json.load(_f)

csv_taxonomy = pd.read_csv("data/inputs.csv")

# resource_groups: group → [resources], order follows first appearance in CSV
resource_groups: dict[str, list[str]] = {}
for _, row in csv_taxonomy.drop_duplicates(subset=["Resource group", "Resource"]).iterrows():
    group, resource = row["Resource group"], row["Resource"]
    resource_groups.setdefault(group, [])
    if resource not in resource_groups[group]:
        resource_groups[group].append(resource)

# resource_unit_map: group → base unit (e.g. "Mha/MtCO2" → "Mha")
resource_unit_map: dict[str, str] = {}
for _, row in csv_taxonomy.drop_duplicates(subset=["Resource group"]).iterrows():
    resource_unit_map[row["Resource group"]] = str(row["Unit"]).split("/")[0]

resource_order = sum(resource_groups.values(), [])
method_order = sum(method_groups.values(), [])

# Resources whose name contains "other" are hidden from the standard display
# (tabs 1 and 3) but remain available as reference groups in the "Add resource"
# dialog so their coefficients can still be inherited by custom resources.
hidden_resource_names: set[str] = {
    r for r in resource_order
    if "other" in r.lower()
}

try:
    with open("data/secondary_resources.json") as _f:
        secondary_resources: set[tuple[str, str]] = {tuple(p) for p in json.load(_f)}
except FileNotFoundError:
    secondary_resources: set[tuple[str, str]] = set()

# All editable copy (tooltips, per-method "why is this disabled?" notes, and
# each tab's OBJECTIVE intro paragraph) lives in data/ui_text.xlsx, three sheets:
#   "Resources"      — Resource | Tooltip
#   "Methods"        — Method | Tooltip | Note (Note = shown in Tab 2's
#                       "Why is this method disabled?" panel for that method)
#   "Section Intros" — Tab | Text (Text is the OBJECTIVE paragraph for that
#                       tab; Tab is the module name, e.g. "tab2_constraints")
# To add or edit any of this text, open that file: no code change needed.
# If the file (or a given row) is missing, that piece of text is silently
# skipped (no hover text / no note / no intro paragraph shown).
try:
    tooltips_xl = pd.read_excel("data/ui_text.xlsx", sheet_name=None)
    df_res = tooltips_xl.get("Resources", pd.DataFrame(columns=["Resource", "Tooltip"]))
    df_met = tooltips_xl.get("Methods",   pd.DataFrame(columns=["Method",   "Tooltip", "Note"]))
    df_sec = tooltips_xl.get("Section Intros", pd.DataFrame(columns=["Tab", "Text"]))
    resource_tooltips: dict[str, str] = {
        row["Resource"]: row["Tooltip"]
        for _, row in df_res.iterrows()
        if pd.notna(row.get("Tooltip")) and str(row.get("Tooltip", "")).strip()
    }
    method_tooltips: dict[str, str] = {
        row["Method"]: row["Tooltip"]
        for _, row in df_met.iterrows()
        if pd.notna(row.get("Tooltip")) and str(row.get("Tooltip", "")).strip()
    }
    method_notes: dict[str, str] = {
        row["Method"]: row["Note"]
        for _, row in df_met.iterrows()
        if pd.notna(row.get("Note")) and str(row.get("Note", "")).strip()
    }
    section_intros: dict[str, str] = {
        row["Tab"]: row["Text"]
        for _, row in df_sec.iterrows()
        if pd.notna(row.get("Text")) and str(row.get("Text", "")).strip()
    }
except FileNotFoundError:
    resource_tooltips: dict[str, str] = {}
    method_tooltips:   dict[str, str] = {}
    method_notes:      dict[str, str] = {}
    section_intros:    dict[str, str] = {}

# -- Theme colors and fonts for CRRA plots (used in plotly templates) ----------------------------------------------

CRRA_COLORS = {
    "off_white": "#eae9d8",
    "red": "#ff5f4d",
    "green_dark": "#298231",
    "green": "#55c95b",
    "green_light": "#92ef9b",
    "yellow": "#d9e210",
    "white": "#ffffff",
    "brown_grey": "#665d5b",
    "grey": "#a0a0a0",
    "black": "#000000",
}

CRRA_FONT = "Segoe UI, sans-serif"

PLOTLY_COLOR_SEQUENCE = [
    CRRA_COLORS["red"],
    CRRA_COLORS["green"],
    CRRA_COLORS["yellow"],
    CRRA_COLORS["green_dark"],
    CRRA_COLORS["brown_grey"],
    CRRA_COLORS["green_light"],
    CRRA_COLORS["grey"],
]

PLOTLY_HEATMAP_SCALE = [
    [0.0, CRRA_COLORS["white"]],
    [0.5, CRRA_COLORS["green_light"]],
    [1.0, CRRA_COLORS["green_dark"]],
]

PLOTLY_TEMPLATE = "plotly_white"