CarlyneB commited on
Commit
64cc758
·
1 Parent(s): ca86b1a

[FEAT] Goal 1 almost achieved: two types of limits possible(percentage / absolute value), start of unit conversion, adapted export templates and a bug fix in the ‘Coefficients’ tab (some resources not displayed)

Browse files
app.py CHANGED
@@ -4,11 +4,22 @@ from streamlit_option_menu import option_menu
4
  from tabs import (tab0_welcome, tab1_inputs, tab2_constraints,
5
  tab3_coefficients, tab4_optimization, tab5_sensitivity,
6
  tab6_scenarios)
7
- from utils.data_utils import load_slider_data
8
  from config.config import method_order, secondary_resources
 
9
 
10
  st.set_page_config("Carbon Portfolio Optimizer", layout="wide")
11
- st.title("Toolkit: CDR Portfolio Optimization")
 
 
 
 
 
 
 
 
 
 
12
 
13
  with st.sidebar:
14
  selected = option_menu(
@@ -33,14 +44,14 @@ if "constraints" not in st.session_state:
33
  st.session_state.constraints = {}
34
  for m in method_order:
35
  if m not in st.session_state.constraints:
36
- st.session_state.constraints[m] = {"active": True, "max_share": 1.0}
37
 
38
  # Initialize cost_sliders
39
  cost_sliders = load_slider_data()
40
  if "costs" not in st.session_state or st.session_state.costs == {}:
41
  st.session_state.costs = {
42
  m: {
43
- r: (0.0 if (m, r) in secondary_resources else cost_sliders[m][r]["median"])
44
  for r in cost_sliders[m]
45
  }
46
  for m in cost_sliders
 
4
  from tabs import (tab0_welcome, tab1_inputs, tab2_constraints,
5
  tab3_coefficients, tab4_optimization, tab5_sensitivity,
6
  tab6_scenarios)
7
+ from utils.data_utils import load_slider_data, strip_unit_suffix
8
  from config.config import method_order, secondary_resources
9
+ import pathlib
10
 
11
  st.set_page_config("Carbon Portfolio Optimizer", layout="wide")
12
+
13
+ # Function to load CSS from the 'assets' folder
14
+ def load_css(file_path):
15
+ with open(file_path) as f:
16
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
17
+
18
+ # Load the external CSS
19
+ css_path = pathlib.Path("assets/styles.css")
20
+ load_css(css_path)
21
+
22
+ st.markdown('<h1 class="custom-title">CRRA Toolkit: CDR Portfolio Optimization</h1>', unsafe_allow_html=True)
23
 
24
  with st.sidebar:
25
  selected = option_menu(
 
44
  st.session_state.constraints = {}
45
  for m in method_order:
46
  if m not in st.session_state.constraints:
47
+ st.session_state.constraints[m] = {"active": True, "cap_type": "percent", "cap_value": 1.0}
48
 
49
  # Initialize cost_sliders
50
  cost_sliders = load_slider_data()
51
  if "costs" not in st.session_state or st.session_state.costs == {}:
52
  st.session_state.costs = {
53
  m: {
54
+ strip_unit_suffix(r): (0.0 if (m, strip_unit_suffix(r)) in secondary_resources else cost_sliders[m][r]["median"])
55
  for r in cost_sliders[m]
56
  }
57
  for m in cost_sliders
assets/styles.css ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .cdr-table, .cdr-table-res{
2
+ width: 100%;
3
+ border-collapse: separate;
4
+ border-spacing: 0;
5
+ border-radius: 10px;
6
+ overflow: hidden;
7
+ }
8
+
9
+ .cdr-table thead th, .cdr-table-res thead th{
10
+ background-color: #3d86e9;
11
+ color: white;
12
+ font-weight: bold;
13
+ padding: 8px 12px;
14
+ text-align: center;
15
+ }
16
+
17
+ .cdr-table tbody th, .cdr-table-res tbody th{
18
+ text-align: center;
19
+ color: #949393;
20
+ font-weight: 100;
21
+ }
22
+
23
+ .cdr-table tbody td:nth-child(3) {
24
+ text-align: right;
25
+ }
26
+
27
+ .cdr-table-res tbody {
28
+ text-align: center;
29
+ }
30
+
31
+ .cdr-table tbody tr:hover, .cdr-table-res tbody tr:hover {
32
+ background-color: #f5f5f5;
33
+ }
34
+
35
+ /* tab2 */
36
+ [class*="st-key-toggle_type_"] p {
37
+ font-weight: 600;
38
+ }
39
+
40
+ h1.custom-header {
41
+ font-family: "Segoe UI", sans-serif;
42
+ font-weight: bold;
43
+ font-style: italic;
44
+ font-size: 35px;
45
+ }
46
+
47
+ h1.custom-title {
48
+ font-family: "Segoe UI", sans-serif;
49
+ font-weight: bold;
50
+ font-size: 50px;
51
+ font-style: italic;
52
+ }
53
+
54
+ div.custom-corps {
55
+ font-family: "Segoe UI", sans-serif;
56
+ font-size: 18px;
57
+ }
config/config.py CHANGED
@@ -1,12 +1,14 @@
1
  import pandas as pd
2
 
 
 
3
  method_groups = {
4
  "Forestry": [
5
  "Afforestation", "Reforestation", "Forest management", "Agroforestry"],
6
  "Soil carbon sequestration (crop, grasslands)": [
7
  "Cropland management", "Pasture management"],
8
  "Blue carbon": [
9
- "Coastal revegetation (mangrove, seaweeds)"],
10
  "Durable biobased products": [
11
  "Durable biobased products"],
12
  "Bio-char": [
@@ -31,51 +33,34 @@ method_groups = {
31
  }
32
 
33
  resource_groups = {
34
- "Minerals": ["Basalt mineral (t/tCO2)", "Olivine mineral (t/tCO2)", "Wollastonite mineral (t/tCO2)", "Unspecified mineral (t/tCO2)"],
35
- "Biomass": ["Forest biomass (t/tCO2)", "Non-forest biomass (t/tCO2)", "Unspecified biomass (t/tCO2)"],
36
- "Land": ["Arable land (ha/tCO2)", "Non-arable land (ha/tCO2)", "Unspecified land (ha/tCO2)"],
37
- "Chemicals": ["Unspecified chemical (t/tCO2)"],
38
- "Energy": ["Electrical energy (MWh/tCO2)", "Thermal energy unspecified grade (MWh/tCO2)", "Thermal energy low grade (MWh/tCO2)", "Thermal energy high grade (MWh/tCO2)"],
39
- "Water": ["Salt water (Liters/tCO2)", "Unspecified water (Liters/tCO2)"],
40
- "Shoreline": ["Shoreline (km/tCO2)"],
41
- "Storage": ["Geologic storage (t/tCO2)"]
42
  }
43
 
44
- method_order = sum(method_groups.values(), [])
45
-
46
- resource_order = sum(resource_groups.values(), [])
47
-
48
- # names used for display
49
  resource_unit_map = {
50
- "Land": "ha",
51
- "Energy": "MWh",
52
- "Biomass": "t",
53
- "Minerals": "t",
54
- "Chemicals": "t",
55
  "Shoreline": "km",
56
- "Water": "L",
57
- "Storage": "t"
58
  }
59
 
60
  resource_units = {
61
- "ha/tCO2": ["Arable land (ha/tCO2)", "Non-arable land (ha/tCO2)", "Unspecified land (ha/tCO2)"],
62
- "MWh/tCO2": ["Electrical energy (MWh/tCO2)", "Thermal energy unspecified grade (MWh/tCO2)", "Thermal energy low grade (MWh/tCO2)", "Thermal energy high grade (MWh/tCO2)"],
63
- "t/tCO2": ["Forest biomass (t/tCO2)", "Non-forest biomass (t/tCO2)", "Unspecified biomass (t/tCO2)", "Basalt mineral (t/tCO2)", "Olivine mineral (t/tCO2)", "Wollastonite mineral (t/tCO2)", "Unspecified mineral (t/tCO2)", "Unspecified chemical (t/tCO2)", "Geologic storage (t/tCO2)"],
64
- "km/tCO2": ["Shoreline (km/tCO2)"],
65
- "Liters/tCO2": ["Salt water (Liters/tCO2)", "Unspecified water (Liters/tCO2)"]
66
  }
67
 
68
- resource_grouped = {
69
- "Land": ["Arable land (ha/tCO2)", "Non-arable land (ha/tCO2)", "Unspecified land (ha/tCO2)"],
70
- "Energy": ["Electrical energy (MWh/tCO2)", "Thermal energy unspecified grade (MWh/tCO2)", "Thermal energy low grade (MWh/tCO2)", "Thermal energy high grade (MWh/tCO2)"],
71
- "Biomass": ["Forest biomass (t/tCO2)", "Non-forest biomass (t/tCO2)", "Unspecified biomass (t/tCO2)"],
72
- "Minerals": ["Basalt mineral (t/tCO2)", "Olivine mineral (t/tCO2)", "Wollastonite mineral (t/tCO2)", "Unspecified mineral (t/tCO2)"],
73
- "Chemicals": ["Unspecified chemical (t/tCO2)"],
74
- "Shoreline": ["Shoreline (km/tCO2)"],
75
- "Water": ["Salt water (Liters/tCO2)", "Unspecified water (Liters/tCO2)"],
76
- "Storage": ["Geologic storage (t/tCO2)"]
77
-
78
- }
79
 
80
  # secondary resources
81
  secondary_df = pd.read_csv("data/secondary_resources.csv")
@@ -83,24 +68,24 @@ secondary_resources = set(zip(secondary_df["method"], secondary_df["resource"]))
83
 
84
  # tooltips
85
  resource_tooltips = {
86
- # "Arable land (ha/tCO2)": "Land used for growing crops.",
87
- # "Non-arable land (ha/tCO2)": "Land not suitable for crop production, e.g., pastures.",
88
- # "Unspecified land (ha/tCO2)": "General land use not specified.",
89
- # "Electrical energy (MWh/tCO2)": "Electricity consumption per ton of CO2 captured.",
90
- # "Thermal energy unspecified grade (MWh/tCO2)": "Heat energy consumption per ton of CO2 captured.",
91
- # "Thermal energy low grade (MWh/tCO2)": "Heat energy consumption per ton of CO2 captured.",
92
- # "Thermal energy high grade (MWh/tCO2)": "Heat energy consumption per ton of CO2 captured.",
93
- "Forest biomass (t/tCO2)": "Dry quantities of biomass sourced from forests.",
94
- "Non-forest biomass (t/tCO2)": "Dry quantities of biomass sourced from non-forest areas.",
95
- "Unspecified biomass (t/tCO2)": "Dry quantities of general biomass, not specified.",
96
- # "Basalt mineral (t/tCO2)": "Basalt mineral used in enhanced weathering.",
97
- # "Olivine mineral (t/tCO2)": "Olivine mineral used in enhanced weathering.",
98
- # "Wollastonite mineral (t/tCO2)": "Wollastonite mineral used in enhanced weathering.",
99
- # "Unspecified mineral (t/tCO2)": "General mineral not specified for enhanced weathering.",
100
- # "Unspecified chemical (t/tCO2)": "General chemical resource not specified.",
101
- # "Salt water (Liters/tCO2)": "Salt water used in ocean-based methods.",
102
- # "Unspecified water (Liters/tCO2)": "General water resource not specified.",
103
- # "Shoreline (km/tCO2)": "Length of shoreline affected by coastal methods."
104
  }
105
 
106
  method_tooltips = {
 
1
  import pandas as pd
2
 
3
+ CO2_UNIT = "MtCO₂"
4
+
5
  method_groups = {
6
  "Forestry": [
7
  "Afforestation", "Reforestation", "Forest management", "Agroforestry"],
8
  "Soil carbon sequestration (crop, grasslands)": [
9
  "Cropland management", "Pasture management"],
10
  "Blue carbon": [
11
+ "Coastal revegetation (mangrove, seaweeds, etc.)"],
12
  "Durable biobased products": [
13
  "Durable biobased products"],
14
  "Bio-char": [
 
33
  }
34
 
35
  resource_groups = {
36
+ "Minerals": ["Basalt mineral", "Olivine mineral", "Wollastonite mineral", "Unspecified mineral"],
37
+ "Biomass": ["Forest biomass", "Non-forest biomass", "Unspecified biomass"],
38
+ "Land": ["Arable land", "Non-arable land", "Unspecified land"],
39
+ "Chemicals": ["Unspecified chemical"],
40
+ "Energy": ["Electrical energy", "Thermal energy unspecified grade", "Thermal energy low grade", "Thermal energy high grade"],
41
+ "Water": ["Salt water", "Unspecified water"],
42
+ "Shoreline": ["Shoreline"],
43
+ "Storage": ["Geologic storage"]
44
  }
45
 
 
 
 
 
 
46
  resource_unit_map = {
47
+ "Land": "Mha",
48
+ "Energy": "TWh",
49
+ "Biomass": "Mt",
50
+ "Minerals": "Mt",
51
+ "Chemicals": "Mt",
52
  "Shoreline": "km",
53
+ "Water": "bcm",
54
+ "Storage": "Mt"
55
  }
56
 
57
  resource_units = {
58
+ f"{resource_unit_map[cat]}/MtCO2": resources
59
+ for cat, resources in resource_groups.items()
 
 
 
60
  }
61
 
62
+ resource_order = sum(resource_groups.values(), [])
63
+ method_order = sum(method_groups.values(), [])
 
 
 
 
 
 
 
 
 
64
 
65
  # secondary resources
66
  secondary_df = pd.read_csv("data/secondary_resources.csv")
 
68
 
69
  # tooltips
70
  resource_tooltips = {
71
+ # "Arable land": "Land used for growing crops.",
72
+ # "Non-arable land": "Land not suitable for crop production, e.g., pastures.",
73
+ # "Unspecified land": "General land use not specified.",
74
+ # "Electrical energy ": "Electricity consumption per ton of CO2 captured.",
75
+ # "Thermal energy unspecified grade": "Heat energy consumption per ton of CO2 captured.",
76
+ # "Thermal energy low grade": "Heat energy consumption per ton of CO2 captured.",
77
+ # "Thermal energy high grade": "Heat energy consumption per ton of CO2 captured.",
78
+ "Forest biomass": "Dry quantities of biomass sourced from forests.",
79
+ "Non-forest biomass": "Dry quantities of biomass sourced from non-forest areas.",
80
+ "Unspecified biomass": "Dry quantities of general biomass, not specified.",
81
+ # "Basalt mineral": "Basalt mineral used in enhanced weathering.",
82
+ # "Olivine mineral": "Olivine mineral used in enhanced weathering.",
83
+ # "Wollastonite mineral": "Wollastonite mineral used in enhanced weathering.",
84
+ # "Unspecified mineral": "General mineral not specified for enhanced weathering.",
85
+ # "Unspecified chemical": "General chemical resource not specified.",
86
+ # "Salt water": "Salt water used in ocean-based methods.",
87
+ # "Unspecified water": "General water resource not specified.",
88
+ # "Shoreline": "Length of shoreline affected by coastal methods."
89
  }
90
 
91
  method_tooltips = {
data/cost_sliders.json CHANGED
@@ -1,548 +1,553 @@
1
  {
2
  "Afforestation": {
3
- "Unspecified land (ha/tCO2)": {
4
  "min": 0.002,
5
  "median": 0.094926862556845,
6
  "max": 0.38461538
7
  },
8
- "Unspecified water (Liters/tCO2)": {
9
- "min": 46000.0,
10
- "median": 92000.0,
11
- "max": 92000.0
12
  }
13
  },
14
  "Agroforestry": {
15
- "Arable land (ha/tCO2)": {
16
  "min": 0.0025,
17
  "median": 0.06410128,
18
  "max": 3.03030303
19
  }
20
  },
21
  "BioCCS with anaerobic digestion/fermentation": {
22
- "Non-forest biomass (t/tCO2)": {
 
 
 
 
 
23
  "min": 1.315,
24
  "median": 1.5617433414042998,
25
  "max": 8.0
26
  },
27
- "Unspecified biomass (t/tCO2)": {
28
  "min": 0.99809364,
29
  "median": 1.14,
30
  "max": 2.0
31
  },
32
- "Unspecified water (Liters/tCO2)": {
33
- "min": 368182.0,
34
- "median": 565909.0,
35
- "max": 913636.0
36
  }
37
  },
38
  "BioCCS with combustion": {
39
- "Electrical energy (MWh/tCO2)": {
40
  "min": 0.0,
41
  "median": 0.101,
42
  "max": 0.5
43
  },
44
- "Forest biomass (t/tCO2)": {
45
  "min": 0.55555555,
46
  "median": 0.59375,
47
  "max": 0.8547
48
  },
49
- "Thermal energy unspecified grade (MWh/tCO2)": {
50
  "min": 0.0,
51
  "median": 0.9306111111111112,
52
  "max": 4.0
53
  },
54
- "Unspecified biomass (t/tCO2)": {
55
  "min": 0.66666667,
56
  "median": 1.14,
57
  "max": 2.0
58
  },
59
- "Unspecified chemical (t/tCO2)": {
60
  "min": 0.00013,
61
  "median": 0.00316,
62
  "max": 20.2
63
  },
64
- "Unspecified water (Liters/tCO2)": {
65
- "min": 630.0,
66
- "median": 201625.2165,
67
- "max": 1296342.17
68
  }
69
  },
70
- "Coastal revegetation (mangrove, seaweeds)": {
71
- "Non-arable land (ha/tCO2)": {
72
  "min": 0.0078,
73
  "median": 0.12056618,
74
  "max": 0.32828863
75
  }
76
  },
77
  "Cropland management": {
78
- "Arable land (ha/tCO2)": {
79
  "min": 0.08264463,
80
  "median": 0.4206349227777499,
81
  "max": 9.0
82
  }
83
  },
84
  "Durable biobased products": {
85
- "Electrical energy (MWh/tCO2)": {
86
  "min": 2.0,
87
  "median": 4.0,
88
  "max": 4.0
89
  },
90
- "Non-arable land (ha/tCO2)": {
91
  "min": 3.0,
92
  "median": 6.0,
93
  "max": 6.0
94
  },
95
- "Unspecified biomass (t/tCO2)": {
96
  "min": 0.0,
97
  "median": 3.57142857,
98
  "max": 4.0
99
  },
100
- "Unspecified water (Liters/tCO2)": {
101
- "min": 100.0,
102
- "median": 300.0,
103
- "max": 500.0
104
  }
105
  },
106
  "Electrochemical DACCS": {
107
- "Electrical energy (MWh/tCO2)": {
108
  "min": 0.252556,
109
  "median": 0.784125,
110
  "max": 6.2222222222
111
  },
112
- "Non-arable land (ha/tCO2)": {
113
  "min": 0.0002225771032,
114
  "median": 0.000323748514,
115
  "max": 0.016
116
  },
117
- "Unspecified water (Liters/tCO2)": {
118
- "min": 1000.0,
119
- "median": 5000.0,
120
- "max": 27000.0
121
  }
122
  },
123
  "Electrochemical OAE": {
124
- "Electrical energy (MWh/tCO2)": {
125
  "min": 0.83,
126
  "median": 2.15,
127
  "max": 5.0
128
  },
129
- "Non-arable land (ha/tCO2)": {
130
  "min": 0.00071,
131
  "median": 0.00101,
132
  "max": 0.00131
133
  },
134
- "Shoreline (km/tCO2)": {
135
- "min": 6e-09,
136
- "median": 1.2e-08,
137
- "max": 1.2e-08
138
  },
139
- "Unspecified mineral (t/tCO2)": {
140
  "min": 2.4,
141
  "median": 2.95,
142
  "max": 3.5
143
  }
144
  },
145
  "Forest management": {
146
- "Unspecified land (ha/tCO2)": {
147
  "min": 0.1087,
148
  "median": 0.76865,
149
  "max": 1.4286
150
  }
151
  },
152
  "High-temp DACCS (solid-sorbent/liquid-solvent)": {
153
- "Electrical energy (MWh/tCO2)": {
154
  "min": 0.077,
155
  "median": 0.46296111111111,
156
  "max": 0.77
157
  },
158
- "Non-arable land (ha/tCO2)": {
159
  "min": 1.5e-10,
160
  "median": 0.0002225771032,
161
  "max": 0.0009914798235
162
  },
163
- "Thermal energy high grade (MWh/tCO2)": {
164
  "min": 1.125,
165
  "median": 1.75,
166
  "max": 3.8
167
  },
168
- "Unspecified water (Liters/tCO2)": {
169
- "min": 0.005,
170
- "median": 4700.0,
171
- "max": 50000.0
172
  }
173
  },
174
  "Low-temp DACCS (solid-sorbent/liquid-solvent)": {
175
- "Electrical energy (MWh/tCO2)": {
176
  "min": 0.13,
177
  "median": 0.46296111111111,
178
  "max": 4.6111111111
179
  },
180
- "Non-arable land (ha/tCO2)": {
181
  "min": 1e-11,
182
  "median": 0.0002225771032,
183
  "max": 0.0009914798235
184
  },
185
- "Thermal energy low grade (MWh/tCO2)": {
186
  "min": 0.6388888889,
187
  "median": 1.5,
188
  "max": 2.7222222222
189
  },
190
- "Unspecified water (Liters/tCO2)": {
191
- "min": -2000.0,
192
- "median": 1008.17439,
193
- "max": 15000.0
194
  }
195
  },
196
  "Mineral OAE / Ocean liming": {
197
- "Electrical energy (MWh/tCO2)": {
198
  "min": 0.027,
199
  "median": 0.6065,
200
  "max": 4.0
201
  },
202
- "Non-arable land (ha/tCO2)": {
203
  "min": 0.0,
204
  "median": 0.000355,
205
  "max": 0.00131
206
  },
207
- "Thermal energy unspecified grade (MWh/tCO2)": {
208
  "min": 0.16,
209
  "median": 1.4589444444444444,
210
  "max": 1.55
211
  },
212
- "Unspecified mineral (t/tCO2)": {
213
  "min": 1.4,
214
  "median": 1.743,
215
  "max": 5.0
216
  },
217
- "Unspecified water (Liters/tCO2)": {
218
- "min": 339.1655,
219
- "median": 678.331,
220
- "max": 678.331
221
  }
222
  },
223
  "Mineral looping DACCS": {
224
- "Electrical energy (MWh/tCO2)": {
225
  "min": 0.0,
226
  "median": 0.0833333333333333,
227
  "max": 4.0
228
  },
229
- "Non-arable land (ha/tCO2)": {
230
  "min": 0.0002225771032,
231
  "median": 0.00063889,
232
  "max": 0.0033
233
  },
234
- "Thermal energy unspecified grade (MWh/tCO2)": {
235
  "min": 1.0,
236
  "median": 1.81944444445,
237
  "max": 2.2222222222
238
  },
239
- "Unspecified mineral (t/tCO2)": {
240
  "min": 0.0,
241
  "median": 0.2,
242
  "max": 0.5
243
  },
244
- "Unspecified water (Liters/tCO2)": {
245
  "min": 0.0,
246
- "median": 200.0,
247
- "max": 26714.00689
248
  }
249
  },
250
  "Mineralization ex-situ": {
251
- "Electrical energy (MWh/tCO2)": {
252
  "min": 0.0,
253
  "median": 0.75,
254
  "max": 3.0
255
  },
256
- "Non-arable land (ha/tCO2)": {
257
  "min": 0.0002225771032,
258
  "median": 0.00043604877962,
259
  "max": 0.0009914798235
260
  },
261
- "Olivine mineral (t/tCO2)": {
262
  "min": 0.4,
263
  "median": 0.8,
264
  "max": 0.8
265
  },
266
- "Thermal energy unspecified grade (MWh/tCO2)": {
267
  "min": 0.4,
268
  "median": 0.45,
269
  "max": 1.0
270
  },
271
- "Unspecified mineral (t/tCO2)": {
272
  "min": 0.04,
273
  "median": 3.0,
274
  "max": 10.0
275
  },
276
- "Unspecified water (Liters/tCO2)": {
277
  "min": 0.0,
278
- "median": 5450.0,
279
- "max": 300000.0
280
  }
281
  },
282
  "Moisture swing DACCS": {
283
- "Electrical energy (MWh/tCO2)": {
284
  "min": 0.316,
285
  "median": 0.32466666665,
286
  "max": 0.3333333333
287
  },
288
- "Non-arable land (ha/tCO2)": {
289
  "min": 8e-06,
290
  "median": 0.00027248,
291
  "max": 0.0009914798235
292
  },
293
- "Unspecified water (Liters/tCO2)": {
294
- "min": -146.0,
295
- "median": 427.0,
296
- "max": 1000.0
297
  }
298
  },
299
  "Pasture management": {
300
- "Arable land (ha/tCO2)": {
301
  "min": 0.07189434,
302
  "median": 0.25242204,
303
  "max": 2.28974424
304
  }
305
  },
306
  "Reforestation": {
307
- "Unspecified land (ha/tCO2)": {
308
  "min": 0.002,
309
  "median": 0.094926862556845,
310
  "max": 38.8
311
  },
312
- "Unspecified water (Liters/tCO2)": {
313
- "min": 46000.0,
314
- "median": 92000.0,
315
- "max": 92000.0
316
  }
317
  },
318
  "pH swing": {
319
- "Electrical energy (MWh/tCO2)": {
320
  "min": 0.66,
321
  "median": 1.768,
322
  "max": 4.67
323
  },
324
- "Salt water (Liters/tCO2)": {
325
- "min": 435000.0,
326
- "median": 4780000.0,
327
- "max": 9125000.0
328
  },
329
- "Unspecified water (Liters/tCO2)": {
330
- "min": 217391.304,
331
- "median": 6608695.652,
332
- "max": 13000000.0
333
  }
334
  },
335
  "Bio-char - Forest biomass": {
336
- "Electrical energy (MWh/tCO2)": {
337
  "min": 0.0,
338
  "median": 0.00035,
339
  "max": 0.5
340
  },
341
- "Forest biomass (t/tCO2)": {
342
  "min": 0.33,
343
  "median": 0.37,
344
  "max": 0.82
345
  },
346
- "Unspecified land (ha/tCO2)": {
347
  "min": 0.05640158,
348
  "median": 0.16320079,
349
  "max": 0.27
350
  },
351
- "Unspecified water (Liters/tCO2)": {
352
- "min": -500.0,
353
- "median": 100.0,
354
- "max": 3000.0
355
  }
356
  },
357
  "Bio-char - Non-forest biomass": {
358
- "Electrical energy (MWh/tCO2)": {
359
  "min": 0.0,
360
  "median": 0.00035,
361
  "max": 0.5
362
  },
363
- "Non-forest biomass (t/tCO2)": {
364
  "min": 0.818,
365
  "median": 1.3395,
366
  "max": 1.667
367
  },
368
- "Unspecified land (ha/tCO2)": {
369
  "min": 0.05640158,
370
  "median": 0.16320079,
371
  "max": 0.27
372
  },
373
- "Unspecified water (Liters/tCO2)": {
374
- "min": -500.0,
375
- "median": 100.0,
376
- "max": 3000.0
377
  }
378
  },
379
  "Bio-char - Unspecified biomass": {
380
- "Electrical energy (MWh/tCO2)": {
381
  "min": 0.0,
382
  "median": 0.00035,
383
  "max": 0.5
384
  },
385
- "Unspecified biomass (t/tCO2)": {
386
  "min": 0.5,
387
  "median": 1.20922073,
388
  "max": 12.86
389
  },
390
- "Unspecified land (ha/tCO2)": {
391
  "min": 0.05640158,
392
  "median": 0.16320079,
393
  "max": 0.27
394
  },
395
- "Unspecified water (Liters/tCO2)": {
396
- "min": -500.0,
397
- "median": 100.0,
398
- "max": 3000.0
399
  }
400
  },
401
  "Enhanced weathering - Basalt mineral": {
402
- "Arable land (ha/tCO2)": {
403
  "min": 1e-06,
404
  "median": 0.25,
405
  "max": 2.5
406
  },
407
- "Basalt mineral (t/tCO2)": {
408
  "min": 1.0,
409
  "median": 4.3,
410
  "max": 19.0
411
  },
412
- "Electrical energy (MWh/tCO2)": {
413
  "min": 0.00925,
414
  "median": 0.38875,
415
  "max": 2.775
416
  },
417
- "Non-arable land (ha/tCO2)": {
418
  "min": 0.0009,
419
  "median": 0.00906504,
420
  "max": 40.0
421
  },
422
- "Unspecified water (Liters/tCO2)": {
423
- "min": 100.0,
424
- "median": 866.0,
425
- "max": 50000.0
426
  }
427
  },
428
  "Enhanced weathering - Olivine mineral": {
429
- "Arable land (ha/tCO2)": {
430
  "min": 1e-06,
431
  "median": 0.25,
432
  "max": 2.5
433
  },
434
- "Electrical energy (MWh/tCO2)": {
435
  "min": 0.00925,
436
  "median": 0.38875,
437
  "max": 2.775
438
  },
439
- "Non-arable land (ha/tCO2)": {
440
  "min": 0.0009,
441
  "median": 0.00906504,
442
  "max": 40.0
443
  },
444
- "Olivine mineral (t/tCO2)": {
445
  "min": 0.27027027,
446
  "median": 1.25,
447
  "max": 3.7
448
  },
449
- "Unspecified water (Liters/tCO2)": {
450
- "min": 100.0,
451
- "median": 866.0,
452
- "max": 50000.0
453
  }
454
  },
455
  "Enhanced weathering - Wollastonite mineral": {
456
- "Arable land (ha/tCO2)": {
457
  "min": 1e-06,
458
  "median": 0.25,
459
  "max": 2.5
460
  },
461
- "Electrical energy (MWh/tCO2)": {
462
  "min": 0.00925,
463
  "median": 0.38875,
464
  "max": 2.775
465
  },
466
- "Non-arable land (ha/tCO2)": {
467
  "min": 0.0009,
468
  "median": 0.00906504,
469
  "max": 40.0
470
  },
471
- "Unspecified water (Liters/tCO2)": {
472
- "min": 100.0,
473
- "median": 866.0,
474
- "max": 50000.0
475
  },
476
- "Wollastonite mineral (t/tCO2)": {
477
  "min": 0.56,
478
  "median": 1.5642857142856998,
479
  "max": 3.0
480
  }
481
  },
482
  "Enhanced weathering - Unspecified mineral": {
483
- "Arable land (ha/tCO2)": {
484
  "min": 1e-06,
485
  "median": 0.25,
486
  "max": 2.5
487
  },
488
- "Electrical energy (MWh/tCO2)": {
489
  "min": 0.00925,
490
  "median": 0.38875,
491
  "max": 2.775
492
  },
493
- "Non-arable land (ha/tCO2)": {
494
  "min": 0.0009,
495
  "median": 0.00906504,
496
  "max": 40.0
497
  },
498
- "Unspecified mineral (t/tCO2)": {
499
  "min": 0.5,
500
  "median": 2.5,
501
  "max": 25.0
502
  },
503
- "Unspecified water (Liters/tCO2)": {
504
- "min": 100.0,
505
- "median": 866.0,
506
- "max": 50000.0
507
  }
508
  },
509
  "BioCCS with combustion & growing biomass": {
510
- "Arable land (ha/tCO2)": {
511
  "min": 0.022803284,
512
  "median": 0.058399844,
513
  "max": 1.9451
514
  },
515
- "Electrical energy (MWh/tCO2)": {
516
  "min": 0.0,
517
  "median": 0.101,
518
  "max": 0.5
519
  },
520
- "Thermal energy unspecified grade (MWh/tCO2)": {
521
  "min": 0.0,
522
  "median": 0.9306111111111112,
523
  "max": 4.0
524
  },
525
- "Unspecified chemical (t/tCO2)": {
526
  "min": 0.00013,
527
  "median": 0.00316,
528
  "max": 20.2
529
  },
530
- "Unspecified water (Liters/tCO2)": {
531
- "min": 630.0,
532
- "median": 201625.2165,
533
- "max": 1296342.17
534
  }
535
  },
536
  "BioCCS with anaerobic digestion/fermentation & growing biomass": {
537
- "Arable land (ha/tCO2)": {
538
  "min": 0.022803284,
539
  "median": 0.058844191,
540
  "max": 0.454545455
541
  },
542
- "Unspecified water (Liters/tCO2)": {
543
- "min": 368182.0,
544
- "median": 565909.0,
545
- "max": 913636.0
546
  }
547
  }
548
  }
 
1
  {
2
  "Afforestation": {
3
+ "Unspecified land (Mha/MtCO2)": {
4
  "min": 0.002,
5
  "median": 0.094926862556845,
6
  "max": 0.38461538
7
  },
8
+ "Unspecified water (bcm/MtCO2)": {
9
+ "min": 0.046,
10
+ "median": 0.092,
11
+ "max": 0.092
12
  }
13
  },
14
  "Agroforestry": {
15
+ "Arable land (Mha/MtCO2)": {
16
  "min": 0.0025,
17
  "median": 0.06410128,
18
  "max": 3.03030303
19
  }
20
  },
21
  "BioCCS with anaerobic digestion/fermentation": {
22
+ "Arable land (Mha/MtCO2)": {
23
+ "min": 0.022803284,
24
+ "median": 0.058844191,
25
+ "max": 0.454545455
26
+ },
27
+ "Non-forest biomass (Mt/MtCO2)": {
28
  "min": 1.315,
29
  "median": 1.5617433414042998,
30
  "max": 8.0
31
  },
32
+ "Unspecified biomass (Mt/MtCO2)": {
33
  "min": 0.99809364,
34
  "median": 1.14,
35
  "max": 2.0
36
  },
37
+ "Unspecified water (bcm/MtCO2)": {
38
+ "min": 0.368182,
39
+ "median": 0.565909,
40
+ "max": 0.913636
41
  }
42
  },
43
  "BioCCS with combustion": {
44
+ "Electrical energy (TWh/MtCO2)": {
45
  "min": 0.0,
46
  "median": 0.101,
47
  "max": 0.5
48
  },
49
+ "Forest biomass (Mt/MtCO2)": {
50
  "min": 0.55555555,
51
  "median": 0.59375,
52
  "max": 0.8547
53
  },
54
+ "Thermal energy unspecified grade (TWh/MtCO2)": {
55
  "min": 0.0,
56
  "median": 0.9306111111111112,
57
  "max": 4.0
58
  },
59
+ "Unspecified biomass (Mt/MtCO2)": {
60
  "min": 0.66666667,
61
  "median": 1.14,
62
  "max": 2.0
63
  },
64
+ "Unspecified chemical (Mt/MtCO2)": {
65
  "min": 0.00013,
66
  "median": 0.00316,
67
  "max": 20.2
68
  },
69
+ "Unspecified water (bcm/MtCO2)": {
70
+ "min": 0.00063,
71
+ "median": 0.2016252165,
72
+ "max": 1.29634217
73
  }
74
  },
75
+ "Coastal revegetation (mangrove, seaweeds, etc.)": {
76
+ "Non-arable land (Mha/MtCO2)": {
77
  "min": 0.0078,
78
  "median": 0.12056618,
79
  "max": 0.32828863
80
  }
81
  },
82
  "Cropland management": {
83
+ "Arable land (Mha/MtCO2)": {
84
  "min": 0.08264463,
85
  "median": 0.4206349227777499,
86
  "max": 9.0
87
  }
88
  },
89
  "Durable biobased products": {
90
+ "Electrical energy (TWh/MtCO2)": {
91
  "min": 2.0,
92
  "median": 4.0,
93
  "max": 4.0
94
  },
95
+ "Non-arable land (Mha/MtCO2)": {
96
  "min": 3.0,
97
  "median": 6.0,
98
  "max": 6.0
99
  },
100
+ "Unspecified biomass (Mt/MtCO2)": {
101
  "min": 0.0,
102
  "median": 3.57142857,
103
  "max": 4.0
104
  },
105
+ "Unspecified water (bcm/MtCO2)": {
106
+ "min": 0.0001,
107
+ "median": 0.0003,
108
+ "max": 0.0005
109
  }
110
  },
111
  "Electrochemical DACCS": {
112
+ "Electrical energy (TWh/MtCO2)": {
113
  "min": 0.252556,
114
  "median": 0.784125,
115
  "max": 6.2222222222
116
  },
117
+ "Non-arable land (Mha/MtCO2)": {
118
  "min": 0.0002225771032,
119
  "median": 0.000323748514,
120
  "max": 0.016
121
  },
122
+ "Unspecified water (bcm/MtCO2)": {
123
+ "min": 0.001,
124
+ "median": 0.005,
125
+ "max": 0.027
126
  }
127
  },
128
  "Electrochemical OAE": {
129
+ "Electrical energy (TWh/MtCO2)": {
130
  "min": 0.83,
131
  "median": 2.15,
132
  "max": 5.0
133
  },
134
+ "Non-arable land (Mha/MtCO2)": {
135
  "min": 0.00071,
136
  "median": 0.00101,
137
  "max": 0.00131
138
  },
139
+ "Shoreline (km/MtCO2)": {
140
+ "min": 0.006,
141
+ "median": 0.012,
142
+ "max": 0.012
143
  },
144
+ "Unspecified mineral (Mt/MtCO2)": {
145
  "min": 2.4,
146
  "median": 2.95,
147
  "max": 3.5
148
  }
149
  },
150
  "Forest management": {
151
+ "Unspecified land (Mha/MtCO2)": {
152
  "min": 0.1087,
153
  "median": 0.76865,
154
  "max": 1.4286
155
  }
156
  },
157
  "High-temp DACCS (solid-sorbent/liquid-solvent)": {
158
+ "Electrical energy (TWh/MtCO2)": {
159
  "min": 0.077,
160
  "median": 0.46296111111111,
161
  "max": 0.77
162
  },
163
+ "Non-arable land (Mha/MtCO2)": {
164
  "min": 1.5e-10,
165
  "median": 0.0002225771032,
166
  "max": 0.0009914798235
167
  },
168
+ "Thermal energy high grade (TWh/MtCO2)": {
169
  "min": 1.125,
170
  "median": 1.75,
171
  "max": 3.8
172
  },
173
+ "Unspecified water (bcm/MtCO2)": {
174
+ "min": 5e-09,
175
+ "median": 0.0047,
176
+ "max": 0.05
177
  }
178
  },
179
  "Low-temp DACCS (solid-sorbent/liquid-solvent)": {
180
+ "Electrical energy (TWh/MtCO2)": {
181
  "min": 0.13,
182
  "median": 0.46296111111111,
183
  "max": 4.6111111111
184
  },
185
+ "Non-arable land (Mha/MtCO2)": {
186
  "min": 1e-11,
187
  "median": 0.0002225771032,
188
  "max": 0.0009914798235
189
  },
190
+ "Thermal energy low grade (TWh/MtCO2)": {
191
  "min": 0.6388888889,
192
  "median": 1.5,
193
  "max": 2.7222222222
194
  },
195
+ "Unspecified water (bcm/MtCO2)": {
196
+ "min": -0.002,
197
+ "median": 0.00100817439,
198
+ "max": 0.015
199
  }
200
  },
201
  "Mineral OAE / Ocean liming": {
202
+ "Electrical energy (TWh/MtCO2)": {
203
  "min": 0.027,
204
  "median": 0.6065,
205
  "max": 4.0
206
  },
207
+ "Non-arable land (Mha/MtCO2)": {
208
  "min": 0.0,
209
  "median": 0.000355,
210
  "max": 0.00131
211
  },
212
+ "Thermal energy unspecified grade (TWh/MtCO2)": {
213
  "min": 0.16,
214
  "median": 1.4589444444444444,
215
  "max": 1.55
216
  },
217
+ "Unspecified mineral (Mt/MtCO2)": {
218
  "min": 1.4,
219
  "median": 1.743,
220
  "max": 5.0
221
  },
222
+ "Unspecified water (bcm/MtCO2)": {
223
+ "min": 0.0003391655,
224
+ "median": 0.000678331,
225
+ "max": 0.000678331
226
  }
227
  },
228
  "Mineral looping DACCS": {
229
+ "Electrical energy (TWh/MtCO2)": {
230
  "min": 0.0,
231
  "median": 0.0833333333333333,
232
  "max": 4.0
233
  },
234
+ "Non-arable land (Mha/MtCO2)": {
235
  "min": 0.0002225771032,
236
  "median": 0.00063889,
237
  "max": 0.0033
238
  },
239
+ "Thermal energy unspecified grade (TWh/MtCO2)": {
240
  "min": 1.0,
241
  "median": 1.81944444445,
242
  "max": 2.2222222222
243
  },
244
+ "Unspecified mineral (Mt/MtCO2)": {
245
  "min": 0.0,
246
  "median": 0.2,
247
  "max": 0.5
248
  },
249
+ "Unspecified water (bcm/MtCO2)": {
250
  "min": 0.0,
251
+ "median": 0.0002,
252
+ "max": 0.02671400689
253
  }
254
  },
255
  "Mineralization ex-situ": {
256
+ "Electrical energy (TWh/MtCO2)": {
257
  "min": 0.0,
258
  "median": 0.75,
259
  "max": 3.0
260
  },
261
+ "Non-arable land (Mha/MtCO2)": {
262
  "min": 0.0002225771032,
263
  "median": 0.00043604877962,
264
  "max": 0.0009914798235
265
  },
266
+ "Olivine mineral (Mt/MtCO2)": {
267
  "min": 0.4,
268
  "median": 0.8,
269
  "max": 0.8
270
  },
271
+ "Thermal energy unspecified grade (TWh/MtCO2)": {
272
  "min": 0.4,
273
  "median": 0.45,
274
  "max": 1.0
275
  },
276
+ "Unspecified mineral (Mt/MtCO2)": {
277
  "min": 0.04,
278
  "median": 3.0,
279
  "max": 10.0
280
  },
281
+ "Unspecified water (bcm/MtCO2)": {
282
  "min": 0.0,
283
+ "median": 0.00545,
284
+ "max": 0.3
285
  }
286
  },
287
  "Moisture swing DACCS": {
288
+ "Electrical energy (TWh/MtCO2)": {
289
  "min": 0.316,
290
  "median": 0.32466666665,
291
  "max": 0.3333333333
292
  },
293
+ "Non-arable land (Mha/MtCO2)": {
294
  "min": 8e-06,
295
  "median": 0.00027248,
296
  "max": 0.0009914798235
297
  },
298
+ "Unspecified water (bcm/MtCO2)": {
299
+ "min": -0.000146,
300
+ "median": 0.000427,
301
+ "max": 0.001
302
  }
303
  },
304
  "Pasture management": {
305
+ "Arable land (Mha/MtCO2)": {
306
  "min": 0.07189434,
307
  "median": 0.25242204,
308
  "max": 2.28974424
309
  }
310
  },
311
  "Reforestation": {
312
+ "Unspecified land (Mha/MtCO2)": {
313
  "min": 0.002,
314
  "median": 0.094926862556845,
315
  "max": 38.8
316
  },
317
+ "Unspecified water (bcm/MtCO2)": {
318
+ "min": 0.046,
319
+ "median": 0.092,
320
+ "max": 0.092
321
  }
322
  },
323
  "pH swing": {
324
+ "Electrical energy (TWh/MtCO2)": {
325
  "min": 0.66,
326
  "median": 1.768,
327
  "max": 4.67
328
  },
329
+ "Salt water (bcm/MtCO2)": {
330
+ "min": 0.435,
331
+ "median": 4.78,
332
+ "max": 9.125
333
  },
334
+ "Unspecified water (bcm/MtCO2)": {
335
+ "min": 0.217391304,
336
+ "median": 6.608695652,
337
+ "max": 13.0
338
  }
339
  },
340
  "Bio-char - Forest biomass": {
341
+ "Electrical energy (TWh/MtCO2)": {
342
  "min": 0.0,
343
  "median": 0.00035,
344
  "max": 0.5
345
  },
346
+ "Forest biomass (Mt/MtCO2)": {
347
  "min": 0.33,
348
  "median": 0.37,
349
  "max": 0.82
350
  },
351
+ "Unspecified land (Mha/MtCO2)": {
352
  "min": 0.05640158,
353
  "median": 0.16320079,
354
  "max": 0.27
355
  },
356
+ "Unspecified water (bcm/MtCO2)": {
357
+ "min": -0.0005,
358
+ "median": 0.0001,
359
+ "max": 0.003
360
  }
361
  },
362
  "Bio-char - Non-forest biomass": {
363
+ "Electrical energy (TWh/MtCO2)": {
364
  "min": 0.0,
365
  "median": 0.00035,
366
  "max": 0.5
367
  },
368
+ "Non-forest biomass (Mt/MtCO2)": {
369
  "min": 0.818,
370
  "median": 1.3395,
371
  "max": 1.667
372
  },
373
+ "Unspecified land (Mha/MtCO2)": {
374
  "min": 0.05640158,
375
  "median": 0.16320079,
376
  "max": 0.27
377
  },
378
+ "Unspecified water (bcm/MtCO2)": {
379
+ "min": -0.0005,
380
+ "median": 0.0001,
381
+ "max": 0.003
382
  }
383
  },
384
  "Bio-char - Unspecified biomass": {
385
+ "Electrical energy (TWh/MtCO2)": {
386
  "min": 0.0,
387
  "median": 0.00035,
388
  "max": 0.5
389
  },
390
+ "Unspecified biomass (Mt/MtCO2)": {
391
  "min": 0.5,
392
  "median": 1.20922073,
393
  "max": 12.86
394
  },
395
+ "Unspecified land (Mha/MtCO2)": {
396
  "min": 0.05640158,
397
  "median": 0.16320079,
398
  "max": 0.27
399
  },
400
+ "Unspecified water (bcm/MtCO2)": {
401
+ "min": -0.0005,
402
+ "median": 0.0001,
403
+ "max": 0.003
404
  }
405
  },
406
  "Enhanced weathering - Basalt mineral": {
407
+ "Arable land (Mha/MtCO2)": {
408
  "min": 1e-06,
409
  "median": 0.25,
410
  "max": 2.5
411
  },
412
+ "Basalt mineral (Mt/MtCO2)": {
413
  "min": 1.0,
414
  "median": 4.3,
415
  "max": 19.0
416
  },
417
+ "Electrical energy (TWh/MtCO2)": {
418
  "min": 0.00925,
419
  "median": 0.38875,
420
  "max": 2.775
421
  },
422
+ "Non-arable land (Mha/MtCO2)": {
423
  "min": 0.0009,
424
  "median": 0.00906504,
425
  "max": 40.0
426
  },
427
+ "Unspecified water (bcm/MtCO2)": {
428
+ "min": 0.0001,
429
+ "median": 0.000866,
430
+ "max": 0.05
431
  }
432
  },
433
  "Enhanced weathering - Olivine mineral": {
434
+ "Arable land (Mha/MtCO2)": {
435
  "min": 1e-06,
436
  "median": 0.25,
437
  "max": 2.5
438
  },
439
+ "Electrical energy (TWh/MtCO2)": {
440
  "min": 0.00925,
441
  "median": 0.38875,
442
  "max": 2.775
443
  },
444
+ "Non-arable land (Mha/MtCO2)": {
445
  "min": 0.0009,
446
  "median": 0.00906504,
447
  "max": 40.0
448
  },
449
+ "Olivine mineral (Mt/MtCO2)": {
450
  "min": 0.27027027,
451
  "median": 1.25,
452
  "max": 3.7
453
  },
454
+ "Unspecified water (bcm/MtCO2)": {
455
+ "min": 0.0001,
456
+ "median": 0.000866,
457
+ "max": 0.05
458
  }
459
  },
460
  "Enhanced weathering - Wollastonite mineral": {
461
+ "Arable land (Mha/MtCO2)": {
462
  "min": 1e-06,
463
  "median": 0.25,
464
  "max": 2.5
465
  },
466
+ "Electrical energy (TWh/MtCO2)": {
467
  "min": 0.00925,
468
  "median": 0.38875,
469
  "max": 2.775
470
  },
471
+ "Non-arable land (Mha/MtCO2)": {
472
  "min": 0.0009,
473
  "median": 0.00906504,
474
  "max": 40.0
475
  },
476
+ "Unspecified water (bcm/MtCO2)": {
477
+ "min": 0.0001,
478
+ "median": 0.000866,
479
+ "max": 0.05
480
  },
481
+ "Wollastonite mineral (Mt/MtCO2)": {
482
  "min": 0.56,
483
  "median": 1.5642857142856998,
484
  "max": 3.0
485
  }
486
  },
487
  "Enhanced weathering - Unspecified mineral": {
488
+ "Arable land (Mha/MtCO2)": {
489
  "min": 1e-06,
490
  "median": 0.25,
491
  "max": 2.5
492
  },
493
+ "Electrical energy (TWh/MtCO2)": {
494
  "min": 0.00925,
495
  "median": 0.38875,
496
  "max": 2.775
497
  },
498
+ "Non-arable land (Mha/MtCO2)": {
499
  "min": 0.0009,
500
  "median": 0.00906504,
501
  "max": 40.0
502
  },
503
+ "Unspecified mineral (Mt/MtCO2)": {
504
  "min": 0.5,
505
  "median": 2.5,
506
  "max": 25.0
507
  },
508
+ "Unspecified water (bcm/MtCO2)": {
509
+ "min": 0.0001,
510
+ "median": 0.000866,
511
+ "max": 0.05
512
  }
513
  },
514
  "BioCCS with combustion & growing biomass": {
515
+ "Arable land (Mha/MtCO2)": {
516
  "min": 0.022803284,
517
  "median": 0.058399844,
518
  "max": 1.9451
519
  },
520
+ "Electrical energy (TWh/MtCO2)": {
521
  "min": 0.0,
522
  "median": 0.101,
523
  "max": 0.5
524
  },
525
+ "Thermal energy unspecified grade (TWh/MtCO2)": {
526
  "min": 0.0,
527
  "median": 0.9306111111111112,
528
  "max": 4.0
529
  },
530
+ "Unspecified chemical (Mt/MtCO2)": {
531
  "min": 0.00013,
532
  "median": 0.00316,
533
  "max": 20.2
534
  },
535
+ "Unspecified water (bcm/MtCO2)": {
536
+ "min": 0.00063,
537
+ "median": 0.2016252165,
538
+ "max": 1.29634217
539
  }
540
  },
541
  "BioCCS with anaerobic digestion/fermentation & growing biomass": {
542
+ "Arable land (Mha/MtCO2)": {
543
  "min": 0.022803284,
544
  "median": 0.058844191,
545
  "max": 0.454545455
546
  },
547
+ "Unspecified water (bcm/MtCO2)": {
548
+ "min": 0.368182,
549
+ "median": 0.565909,
550
+ "max": 0.913636
551
  }
552
  }
553
  }
data/generate_cost_matrix.py CHANGED
@@ -1,8 +1,18 @@
1
  #%% uses the latest version of aggregated inputs to create the dictionary of costs
2
  import json
 
3
 
4
  import pandas as pd
5
 
 
 
 
 
 
 
 
 
 
6
 
7
  def create_sliders_inputs():
8
  df = pd.read_csv("data/inputs_aggregated.csv")
@@ -36,48 +46,48 @@ def create_sliders_inputs():
36
 
37
  # create the three cases for bio-char
38
  cost_sliders["Bio-char - Forest biomass"] = cost_sliders["Bio-char"].copy()
39
- cost_sliders["Bio-char - Forest biomass"].pop("Non-forest biomass (t/tCO2)")
40
- cost_sliders["Bio-char - Forest biomass"].pop("Unspecified biomass (t/tCO2)")
41
  cost_sliders["Bio-char - Non-forest biomass"] = cost_sliders["Bio-char"].copy()
42
- cost_sliders["Bio-char - Non-forest biomass"].pop("Forest biomass (t/tCO2)")
43
- cost_sliders["Bio-char - Non-forest biomass"].pop("Unspecified biomass (t/tCO2)")
44
  cost_sliders["Bio-char - Unspecified biomass"] = cost_sliders["Bio-char"].copy()
45
- cost_sliders["Bio-char - Unspecified biomass"].pop("Forest biomass (t/tCO2)")
46
- cost_sliders["Bio-char - Unspecified biomass"].pop("Non-forest biomass (t/tCO2)")
47
  # remove "Bio-char" from the dictionary
48
  if "Bio-char" in cost_sliders:
49
  del cost_sliders["Bio-char"]
50
 
51
  # create all cases for enhanced weathering
52
  cost_sliders["Enhanced weathering - Basalt mineral"] = cost_sliders["Enhanced weathering"].copy()
53
- cost_sliders["Enhanced weathering - Basalt mineral"].pop("Olivine mineral (t/tCO2)")
54
- cost_sliders["Enhanced weathering - Basalt mineral"].pop("Wollastonite mineral (t/tCO2)")
55
- cost_sliders["Enhanced weathering - Basalt mineral"].pop("Unspecified mineral (t/tCO2)")
56
  cost_sliders["Enhanced weathering - Olivine mineral"] = cost_sliders["Enhanced weathering"].copy()
57
- cost_sliders["Enhanced weathering - Olivine mineral"].pop("Basalt mineral (t/tCO2)")
58
- cost_sliders["Enhanced weathering - Olivine mineral"].pop("Wollastonite mineral (t/tCO2)")
59
- cost_sliders["Enhanced weathering - Olivine mineral"].pop("Unspecified mineral (t/tCO2)")
60
  cost_sliders["Enhanced weathering - Wollastonite mineral"] = cost_sliders["Enhanced weathering"].copy()
61
- cost_sliders["Enhanced weathering - Wollastonite mineral"].pop("Basalt mineral (t/tCO2)")
62
- cost_sliders["Enhanced weathering - Wollastonite mineral"].pop("Olivine mineral (t/tCO2)")
63
- cost_sliders["Enhanced weathering - Wollastonite mineral"].pop("Unspecified mineral (t/tCO2)")
64
  cost_sliders["Enhanced weathering - Unspecified mineral"] = cost_sliders["Enhanced weathering"].copy()
65
- cost_sliders["Enhanced weathering - Unspecified mineral"].pop("Basalt mineral (t/tCO2)")
66
- cost_sliders["Enhanced weathering - Unspecified mineral"].pop("Olivine mineral (t/tCO2)")
67
- cost_sliders["Enhanced weathering - Unspecified mineral"].pop("Wollastonite mineral (t/tCO2)")
68
  # remove "Enhanced weathering" from the dictionary
69
  if "Enhanced weathering" in cost_sliders:
70
  del cost_sliders["Enhanced weathering"]
71
  # create case for growing biomass in bioccs
72
  cost_sliders["BioCCS with combustion & growing biomass"] = cost_sliders["BioCCS with combustion"].copy()
73
- cost_sliders["BioCCS with combustion"].pop("Arable land (ha/tCO2)")
74
- cost_sliders["BioCCS with combustion & growing biomass"].pop("Forest biomass (t/tCO2)")
75
- cost_sliders["BioCCS with combustion & growing biomass"].pop("Unspecified biomass (t/tCO2)")
76
 
77
  cost_sliders["BioCCS with anaerobic digestion/fermentation & growing biomass"] = cost_sliders["BioCCS with anaerobic digestion/fermentation"].copy()
78
- cost_sliders["BioCCS with anaerobic digestion/fermentation"].pop("Arable land (ha/tCO2)")
79
- cost_sliders["BioCCS with anaerobic digestion/fermentation & growing biomass"].pop("Non-forest biomass (t/tCO2)")
80
- cost_sliders["BioCCS with anaerobic digestion/fermentation & growing biomass"].pop("Unspecified biomass (t/tCO2)")
81
 
82
 
83
 
 
1
  #%% uses the latest version of aggregated inputs to create the dictionary of costs
2
  import json
3
+ import sys
4
 
5
  import pandas as pd
6
 
7
+ from pathlib import Path
8
+ sys.path.insert(0, str(Path(__file__).parent.parent))
9
+ from utils.data_utils import strip_unit_suffix
10
+
11
+ def pop_by_name(d: dict, name: str):
12
+ """Pop a key from dict by resource name, ignoring the unit suffix."""
13
+ key = next((k for k in d if strip_unit_suffix(k) == name), None)
14
+ if key:
15
+ d.pop(key)
16
 
17
  def create_sliders_inputs():
18
  df = pd.read_csv("data/inputs_aggregated.csv")
 
46
 
47
  # create the three cases for bio-char
48
  cost_sliders["Bio-char - Forest biomass"] = cost_sliders["Bio-char"].copy()
49
+ pop_by_name(cost_sliders["Bio-char - Forest biomass"], "Non-forest biomass")
50
+ pop_by_name(cost_sliders["Bio-char - Forest biomass"], "Unspecified biomass")
51
  cost_sliders["Bio-char - Non-forest biomass"] = cost_sliders["Bio-char"].copy()
52
+ pop_by_name(cost_sliders["Bio-char - Non-forest biomass"], "Forest biomass")
53
+ pop_by_name(cost_sliders["Bio-char - Non-forest biomass"], "Unspecified biomass")
54
  cost_sliders["Bio-char - Unspecified biomass"] = cost_sliders["Bio-char"].copy()
55
+ pop_by_name(cost_sliders["Bio-char - Unspecified biomass"], "Forest biomass")
56
+ pop_by_name(cost_sliders["Bio-char - Unspecified biomass"], "Non-forest biomass")
57
  # remove "Bio-char" from the dictionary
58
  if "Bio-char" in cost_sliders:
59
  del cost_sliders["Bio-char"]
60
 
61
  # create all cases for enhanced weathering
62
  cost_sliders["Enhanced weathering - Basalt mineral"] = cost_sliders["Enhanced weathering"].copy()
63
+ pop_by_name(cost_sliders["Enhanced weathering - Basalt mineral"], "Olivine mineral")
64
+ pop_by_name(cost_sliders["Enhanced weathering - Basalt mineral"], "Wollastonite mineral")
65
+ pop_by_name(cost_sliders["Enhanced weathering - Basalt mineral"], "Unspecified mineral")
66
  cost_sliders["Enhanced weathering - Olivine mineral"] = cost_sliders["Enhanced weathering"].copy()
67
+ pop_by_name(cost_sliders["Enhanced weathering - Olivine mineral"], "Basalt mineral")
68
+ pop_by_name(cost_sliders["Enhanced weathering - Olivine mineral"], "Wollastonite mineral")
69
+ pop_by_name(cost_sliders["Enhanced weathering - Olivine mineral"], "Unspecified mineral")
70
  cost_sliders["Enhanced weathering - Wollastonite mineral"] = cost_sliders["Enhanced weathering"].copy()
71
+ pop_by_name(cost_sliders["Enhanced weathering - Wollastonite mineral"], "Basalt mineral")
72
+ pop_by_name(cost_sliders["Enhanced weathering - Wollastonite mineral"], "Olivine mineral")
73
+ pop_by_name(cost_sliders["Enhanced weathering - Wollastonite mineral"], "Unspecified mineral")
74
  cost_sliders["Enhanced weathering - Unspecified mineral"] = cost_sliders["Enhanced weathering"].copy()
75
+ pop_by_name(cost_sliders["Enhanced weathering - Unspecified mineral"], "Basalt mineral")
76
+ pop_by_name(cost_sliders["Enhanced weathering - Unspecified mineral"], "Olivine mineral")
77
+ pop_by_name(cost_sliders["Enhanced weathering - Unspecified mineral"], "Wollastonite mineral")
78
  # remove "Enhanced weathering" from the dictionary
79
  if "Enhanced weathering" in cost_sliders:
80
  del cost_sliders["Enhanced weathering"]
81
  # create case for growing biomass in bioccs
82
  cost_sliders["BioCCS with combustion & growing biomass"] = cost_sliders["BioCCS with combustion"].copy()
83
+ pop_by_name(cost_sliders["BioCCS with combustion"], "Arable land")
84
+ pop_by_name(cost_sliders["BioCCS with combustion & growing biomass"], "Forest biomass")
85
+ pop_by_name(cost_sliders["BioCCS with combustion & growing biomass"], "Unspecified biomass")
86
 
87
  cost_sliders["BioCCS with anaerobic digestion/fermentation & growing biomass"] = cost_sliders["BioCCS with anaerobic digestion/fermentation"].copy()
88
+ pop_by_name(cost_sliders["BioCCS with anaerobic digestion/fermentation"], "Arable land (ha/tCO2)")
89
+ pop_by_name(cost_sliders["BioCCS with anaerobic digestion/fermentation & growing biomass"], "Non-forest biomass")
90
+ pop_by_name(cost_sliders["BioCCS with anaerobic digestion/fermentation & growing biomass"], "Unspecified biomass")
91
 
92
 
93
 
data/generate_input_template.py CHANGED
@@ -6,7 +6,7 @@ from openpyxl.styles import Font
6
 
7
  from pathlib import Path
8
  sys.path.insert(0, str(Path(__file__).parent.parent))
9
- from config.config import (resource_order, method_order)
10
 
11
  # Data
12
  with open("data/cost_sliders.json") as f:
@@ -17,23 +17,31 @@ secondary_resources = set(zip(secondary_df["method"], secondary_df["resource"]))
17
 
18
  wb = openpyxl.Workbook()
19
 
 
 
 
 
 
 
20
  # resource_caps
21
  ws1 = wb.active
22
  ws1.title = "resource_caps"
23
- ws1.append(["Resource", "Available Amount"])
24
  ws1["A1"].font = Font(bold=True)
25
  ws1["B1"].font = Font(bold=True)
 
26
  for r in resource_order:
27
- ws1.append([r, float("nan")])
28
-
29
  # constraints
30
  ws2 = wb.create_sheet("constraints")
31
- ws2.append(["method", "active", "max_share"])
32
  ws2["A1"].font = Font(bold=True)
33
  ws2["B1"].font = Font(bold=True)
34
  ws2["C1"].font = Font(bold=True)
 
35
  for m in method_order:
36
- ws2.append([m, True, 1.0])
37
 
38
  ws3 = wb.create_sheet("coefficients")
39
  ws3.append(["method", "resource", "value", "secondary"])
 
6
 
7
  from pathlib import Path
8
  sys.path.insert(0, str(Path(__file__).parent.parent))
9
+ from config.config import (resource_order, method_order, resource_unit_map, resource_groups)
10
 
11
  # Data
12
  with open("data/cost_sliders.json") as f:
 
17
 
18
  wb = openpyxl.Workbook()
19
 
20
+ resource_to_unit = {
21
+ r: resource_unit_map[group]
22
+ for group, resources in resource_groups.items()
23
+ for r in resources
24
+ }
25
+
26
  # resource_caps
27
  ws1 = wb.active
28
  ws1.title = "resource_caps"
29
+ ws1.append(["Resource", "Unit", "Available Amount"])
30
  ws1["A1"].font = Font(bold=True)
31
  ws1["B1"].font = Font(bold=True)
32
+ ws1["C1"].font = Font(bold=True)
33
  for r in resource_order:
34
+ ws1.append([r, resource_to_unit.get(r, ""), float("nan")])
35
+
36
  # constraints
37
  ws2 = wb.create_sheet("constraints")
38
+ ws2.append(["method", "active", "cap_type (percent or absolute)", "cap_value"])
39
  ws2["A1"].font = Font(bold=True)
40
  ws2["B1"].font = Font(bold=True)
41
  ws2["C1"].font = Font(bold=True)
42
+ ws2["D1"].font = Font(bold=True)
43
  for m in method_order:
44
+ ws2.append([m, True, "percent", 1.0])
45
 
46
  ws3 = wb.create_sheet("coefficients")
47
  ws3.append(["method", "resource", "value", "secondary"])
data/generate_resource_template.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import sys
3
+ import pandas as pd
4
+ import openpyxl
5
+ from openpyxl.styles import Font
6
+
7
+ from pathlib import Path
8
+ sys.path.insert(0, str(Path(__file__).parent.parent))
9
+ from config.config import (resource_order, resource_unit_map, resource_groups)
10
+
11
+ wb = openpyxl.Workbook()
12
+
13
+ resource_to_unit = {
14
+ r: resource_unit_map[group]
15
+ for group, resources in resource_groups.items()
16
+ for r in resources
17
+ }
18
+
19
+ # resource_caps
20
+ ws1 = wb.active
21
+ ws1.title = "resource_caps"
22
+ ws1.append(["Resource", "Unit", "Available Amount"])
23
+ ws1["A1"].font = Font(bold=True)
24
+ ws1["B1"].font = Font(bold=True)
25
+ ws1["C1"].font = Font(bold=True)
26
+ for r in resource_order:
27
+ ws1.append([r, resource_to_unit.get(r, ""), float("nan")])
28
+
29
+ wb.save("data/resource_template.xlsx")
30
+ print("Template generated: data/resource_template.xlsx")
data/inputs_aggregated.csv CHANGED
@@ -1,76 +1,76 @@
1
- Implementation,Resource,Type,Unit,count,quantile_25,mean,median,quantile_75,std,min,max
2
- Afforestation,Unspecified land,Physical,ha/tCO2,36,0.024592505,0.11565221097503724,0.094926862556845,0.197075,0.11236779976444418,0.002,0.38461538
3
- Afforestation,Unspecified water,Physical,Liters/tCO2,2,92000.0,92000.0,92000.0,92000.0,0.0,92000.0,92000.0
4
- Agroforestry,Arable land,Physical,ha/tCO2,12,0.03995278725,0.4507674440833333,0.06410128000000001,0.2141,0.901140274110988,0.0025,3.03030303
5
- Bio-char,Electrical energy,Energy,MWh/tCO2,6,8.75e-05,0.1667833333333333,0.00035,0.3750875,0.2581085675964025,0.0,0.5
6
- Bio-char,Forest biomass,Physical,t/tCO2,6,0.34,0.47283333333333327,0.37,0.55525,0.20162382465042825,0.33,0.82
7
- Bio-char,Non-forest biomass,Physical,t/tCO2,8,1.142,1.291,1.3395000000000001,1.4885000000000002,0.332019792869556,0.818,1.667
8
- Bio-char,Unspecified biomass,Physical,t/tCO2,48,0.94339623,1.924254525942129,1.20922073,2.522177213052725,1.9378239910641315,0.5,12.86
9
- Bio-char,Unspecified land,Physical,ha/tCO2,4,0.05640158,0.16320079,0.16320079,0.27,0.12332110528547877,0.05640158,0.27
10
- Bio-char,Unspecified water,Physical,Liters/tCO2,9,0.0,633.3333333333334,100.0,500.0,1376.5899897936204,-500.0,3000.0
11
- BioCCS with anaerobic digestion/fermentation,Arable land,Physical,ha/tCO2,16,0.03793734775,0.100866767,0.058844191000000004,0.10303396649999999,0.11375772648817686,0.022803284,0.454545455
12
- BioCCS with anaerobic digestion/fermentation,Non-forest biomass,Physical,t/tCO2,6,1.4285714285714,2.689964230684533,1.5617433414042998,2.1282742681047,2.6242499596696813,1.315,8.0
13
- BioCCS with anaerobic digestion/fermentation,Unspecified biomass,Physical,t/tCO2,6,1.03357023,1.3793645466666666,1.14,1.785,0.4849128814150571,0.99809364,2.0
14
- BioCCS with anaerobic digestion/fermentation,Unspecified water,Physical,Liters/tCO2,14,395454.5,569805.1428571428,565909.0,654545.5,183277.283077123,368182.0,913636.0
15
- BioCCS with combustion,Arable land,Physical,ha/tCO2,32,0.038,0.20054008704125,0.058399844,0.09459459,0.4656596577374178,0.022803284,1.9451
16
- BioCCS with combustion,Electrical energy,Energy,MWh/tCO2,18,0.0277777777777777,0.13097530864197526,0.101,0.1111111111111111,0.16241025701586306,0.0,0.5
17
- BioCCS with combustion,Forest biomass,Physical,t/tCO2,8,0.5607638875000001,0.67548055375,0.59375,0.8386749975,0.14441914653695664,0.55555555,0.8547
18
- BioCCS with combustion,Thermal energy unspecified grade,Energy,MWh/tCO2,22,0.3472222222222222,1.0062424242424242,0.9306111111111111,1.025,1.0524401441735463,0.0,4.0
19
- BioCCS with combustion,Unspecified biomass,Physical,t/tCO2,8,0.9166666675,1.2641666675,1.14,1.625,0.5282247887342408,0.66666667,2.0
20
- BioCCS with combustion,Unspecified chemical,Physical,t/tCO2,20,0.00027,4.044119,0.00316,0.016,8.287794157908491,0.00013,20.2
21
- BioCCS with combustion,Unspecified water,Physical,Liters/tCO2,32,6475.0,312937.45634375,201625.2165,542045.5,343154.80918602005,630.0,1296342.17
22
- "Coastal revegetation (mangrove, seaweeds…)",Non-arable land,Physical,ha/tCO2,11,0.043295020000000004,0.13201796181818182,0.12056618,0.19744896,0.11706388563455744,0.0078,0.32828863
23
- Cropland management,Arable land,Physical,ha/tCO2,14,0.27061989000000003,1.2779463596825358,0.42063492277774994,1.05233487,2.3297794467976978,0.08264463,9.0
24
- Durable biobased products,Electrical energy,Energy,MWh/tCO2,2,4.0,4.0,4.0,4.0,0.0,4.0,4.0
25
- Durable biobased products,Non-arable land,Physical,ha/tCO2,2,6.0,6.0,6.0,6.0,0.0,6.0,6.0
26
- Durable biobased products,Unspecified biomass,Physical,t/tCO2,6,1.2678571425,2.6071428566666666,3.57142857,3.8928571425,1.8426633339173129,0.0,4.0
27
- Durable biobased products,Unspecified water,Physical,Liters/tCO2,2,200.0,300.0,300.0,400.0,282.842712474619,100.0,500.0
28
- Electrochemical DACCS,Electrical energy,Energy,MWh/tCO2,10,0.33333333335000004,2.0320806,0.784125,2.75,2.3788325030763033,0.252556,6.2222222222
29
- Electrochemical DACCS,Non-arable land,Physical,ha/tCO2,14,0.00027248,0.0026615877837057145,0.000323748514,0.000880697128935,0.005656829998005935,0.0002225771032,0.016
30
- Electrochemical DACCS,Unspecified water,Physical,Liters/tCO2,6,2000.0,11000.0,5000.0,21500.0,12521.980673998822,1000.0,27000.0
31
- Electrochemical OAE,Electrical energy,Energy,MWh/tCO2,8,1.6,2.24125,2.15,2.5,1.2835935883292655,0.83,5.0
32
- Electrochemical OAE,Non-arable land,Physical,ha/tCO2,2,0.00086,0.00101,0.00101,0.00116,0.00042426406871192844,0.00071,0.00131
33
- Electrochemical OAE,Shoreline,Physical,km/tCO2,2,1.2e-08,1.2e-08,1.2e-08,1.2e-08,0.0,1.2e-08,1.2e-08
34
- Electrochemical OAE,Unspecified mineral,Physical,t/tCO2,4,2.4,2.95,2.95,3.5,0.6350852961085884,2.4,3.5
35
- Enhanced weathering,Arable land,Physical,ha/tCO2,28,0.12875,0.548973515,0.25,0.5,0.7099161244217219,1e-06,2.5
36
- Enhanced weathering,Basalt mineral,Physical,t/tCO2,25,3.33,5.773041804595108,4.3,5.3,4.967901225163679,1.0,19.0
37
- Enhanced weathering,Electrical energy,Energy,MWh/tCO2,8,0.09285,0.59343125,0.38875000000000004,0.5,0.9045657102947644,0.00925,2.775
38
- Enhanced weathering,Non-arable land,Physical,ha/tCO2,12,0.004428795,11.432468628333334,0.00906504,28.5714286,17.226399848110834,0.0009,40.0
39
- Enhanced weathering,Olivine mineral,Physical,t/tCO2,26,0.9090909,1.4295112634615386,1.25,1.58,0.9412466256217807,0.27027027,3.7
40
- Enhanced weathering,Unspecified mineral,Physical,t/tCO2,19,1.31578947,6.356736418947368,2.5,8.625,7.726415037245945,0.5,25.0
41
- Enhanced weathering,Unspecified water,Physical,Liters/tCO2,5,500.0,10466.4,866.0,866.0,22102.21859452123,100.0,50000.0
42
- Enhanced weathering,Wollastonite mineral,Physical,t/tCO2,8,1.3214285714285499,1.62964285714285,1.5642857142856998,1.83,0.7423655162834324,0.56,3.0
43
- Forest management,Unspecified land,Physical,ha/tCO2,2,0.43867500000000004,0.76865,0.76865,1.0986250000000002,0.9333102404881242,0.1087,1.4286
44
- High-temp DACCS (solid-sorbent/liquid-solvent),Electrical energy,Energy,MWh/tCO2,32,0.3611111111,0.42378784722013874,0.46296111111111,0.5,0.16317834501458298,0.077,0.77
45
- High-temp DACCS (solid-sorbent/liquid-solvent),Non-arable land,Physical,ha/tCO2,23,2.2000000000000002e-08,0.00022929641616869565,0.0002225771032,0.000298114257,0.0002987803322061786,1.5e-10,0.0009914798235
46
- High-temp DACCS (solid-sorbent/liquid-solvent),Thermal energy high grade,Energy,MWh/tCO2,38,1.4722222222,1.954835008771642,1.75,2.3148148055556,0.6439376166933265,1.125,3.8
47
- High-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water,Physical,Liters/tCO2,16,2502.0435975,10221.02242375,4700.0,8180.0,15886.886921845426,0.005,50000.0
48
- Low-temp DACCS (solid-sorbent/liquid-solvent),Electrical energy,Energy,MWh/tCO2,44,0.218,0.8953202020237373,0.46296111111111,0.69,1.2556951906425198,0.13,4.6111111111
49
- Low-temp DACCS (solid-sorbent/liquid-solvent),Non-arable land,Physical,ha/tCO2,23,6.25e-08,0.00023824473964695653,0.0002225771032,0.000298114257,0.00029447829320152126,1e-11,0.0009914798235
50
- Low-temp DACCS (solid-sorbent/liquid-solvent),Thermal energy low grade,Energy,MWh/tCO2,30,1.4324999999999999,1.6782145666607466,1.5,2.062499999975,0.5167942816781624,0.6388888889,2.7222222222
51
- Low-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water,Physical,Liters/tCO2,14,0.00075,3186.8824842857143,1008.17439,4925.0,5237.922016339205,-2000.0,15000.0
52
- Mineral OAE / Ocean liming,Electrical energy,Energy,MWh/tCO2,12,0.323625,1.1535833333333334,0.6065,1.755,1.2860244737055733,0.027,4.0
53
- Mineral OAE / Ocean liming,Non-arable land,Physical,ha/tCO2,4,0.0,0.000505,0.000355,0.00086,0.0006324818837985268,0.0,0.00131
54
- Mineral OAE / Ocean liming,Thermal energy unspecified grade,Energy,MWh/tCO2,6,1.3888888888888888,1.2576296296296297,1.4589444444444444,1.529,0.5425887907843043,0.16,1.55
55
- Mineral OAE / Ocean liming,Unspecified mineral,Physical,t/tCO2,8,1.62,2.489,1.7429999999999999,2.5895,1.5545979728350534,1.4,5.0
56
- Mineral OAE / Ocean liming,Unspecified water,Physical,Liters/tCO2,2,678.331,678.331,678.331,678.331,0.0,678.331,678.331
57
- Mineral looping DACCS,Electrical energy,Energy,MWh/tCO2,8,0.0833333333,1.1041666666583332,0.0833333333333333,1.375,1.793811009144325,0.0,4.0
58
- Mineral looping DACCS,Non-arable land,Physical,ha/tCO2,12,0.0005870872613099999,0.001064587040495,0.00063889,0.0008728674558749999,0.0010640920465922832,0.0002225771032,0.0033
59
- Mineral looping DACCS,Thermal energy unspecified grade,Energy,MWh/tCO2,4,1.4791666666749999,1.715277777775,1.81944444445,2.05555555555,0.5340152854505239,1.0,2.2222222222
60
- Mineral looping DACCS,Unspecified mineral,Physical,t/tCO2,4,0.15000000000000002,0.225,0.2,0.275,0.20615528128088303,0.0,0.5
61
- Mineral looping DACCS,Unspecified water,Physical,Liters/tCO2,6,125.0,6761.8350550000005,200.0,10067.75258,11115.783599449733,0.0,26714.00689
62
- Mineralization ex-situ,Electrical energy,Energy,MWh/tCO2,8,0.5,1.0625,0.75,1.25,0.9797047660246574,0.0,3.0
63
- Mineralization ex-situ,Non-arable land,Physical,ha/tCO2,4,0.0002984556613,0.000521538621485,0.00043604877962,0.0006591317398049999,0.00034159549577798685,0.0002225771032,0.0009914798235
64
- Mineralization ex-situ,Olivine mineral,Physical,t/tCO2,2,0.8,0.8,0.8,0.8,0.0,0.8,0.8
65
- Mineralization ex-situ,Thermal energy unspecified grade,Energy,MWh/tCO2,4,0.4,0.575,0.45,0.625,0.2872281323269014,0.4,1.0
66
- Mineralization ex-situ,Unspecified mineral,Physical,t/tCO2,22,0.4375,3.9349999999999996,3.0,7.0,3.6477217286306,0.04,10.0
67
- Mineralization ex-situ,Unspecified water,Physical,Liters/tCO2,14,200.0,50004.28571428572,5450.0,14500.0,106907.99154947611,0.0,300000.0
68
- Moisture swing DACCS,Electrical energy,Energy,MWh/tCO2,4,0.316,0.32466666665,0.32466666665,0.3333333333,0.01000740464670849,0.316,0.3333333333
69
- Moisture swing DACCS,Non-arable land,Physical,ha/tCO2,8,0.00016893282740000002,0.0003308893107425,0.00027248,0.00037989864681,0.0003186555229397746,8e-06,0.0009914798235
70
- Moisture swing DACCS,Unspecified water,Physical,Liters/tCO2,4,-146.0,427.0,427.0,1000.0,661.6434084913111,-146.0,1000.0
71
- Pasture management,Arable land,Physical,ha/tCO2,24,0.10225284750000001,0.44236770317026247,0.25242204,0.522974429158825,0.522145451866414,0.07189434,2.28974424
72
- Reforestation,Unspecified land,Physical,ha/tCO2,34,0.044458695,1.5641017441794511,0.094926862556845,0.1887,6.8258032964187745,0.002,38.8
73
- Reforestation,Unspecified water,Physical,Liters/tCO2,2,92000.0,92000.0,92000.0,92000.0,0.0,92000.0,92000.0
74
- pH swing,Electrical energy,Energy,MWh/tCO2,28,0.98,2.2051124785714284,1.768,3.3024999999999998,1.3819088428118145,0.66,4.67
75
- pH swing,Salt water,Physical,Liters/tCO2,4,435000.0,4780000.0,4780000.0,9125000.0,5017173.8392578475,435000.0,9125000.0
76
- pH swing,Unspecified water,Physical,Liters/tCO2,4,217391.304,6608695.652,6608695.652,13000000.0,7380042.571581251,217391.304,13000000.0
 
1
+ Implementation,Resource,Type,Unit,count,quantile_25,mean,median,quantile_75,std,min,max
2
+ Afforestation,Unspecified land,Physical,Mha/MtCO2,36,0.024592505,0.1156522109750372,0.094926862556845,0.197075,0.1123677997644441,0.002,0.38461538
3
+ Afforestation,Unspecified water,Physical,bcm/MtCO2,2,0.092,0.092,0.092,0.092,0.0,0.092,0.092
4
+ Agroforestry,Arable land,Physical,Mha/MtCO2,12,0.03995278725,0.4507674440833333,0.06410128,0.2141,0.901140274110988,0.0025,3.03030303
5
+ Bio-char,Electrical energy,Energy,TWh/MtCO2,6,8.75e-05,0.1667833333333333,0.00035,0.3750875,0.2581085675964025,0.0,0.5
6
+ Bio-char,Forest biomass,Physical,Mt/MtCO2,6,0.34,0.4728333333333332,0.37,0.55525,0.2016238246504282,0.33,0.82
7
+ Bio-char,Non-forest biomass,Physical,Mt/MtCO2,8,1.142,1.291,1.3395,1.4885000000000002,0.332019792869556,0.818,1.667
8
+ Bio-char,Unspecified biomass,Physical,Mt/MtCO2,48,0.94339623,1.924254525942129,1.20922073,2.522177213052725,1.9378239910641315,0.5,12.86
9
+ Bio-char,Unspecified land,Physical,Mha/MtCO2,4,0.05640158,0.16320079,0.16320079,0.27,0.1233211052854787,0.05640158,0.27
10
+ Bio-char,Unspecified water,Physical,bcm/MtCO2,9,0.0,0.0006333333333333334,0.0001,0.0005,0.0013765899897936204,-0.0005,0.003
11
+ BioCCS with anaerobic digestion/fermentation,Arable land,Physical,Mha/MtCO2,16,0.03793734775,0.100866767,0.058844191,0.1030339664999999,0.1137577264881768,0.022803284,0.454545455
12
+ BioCCS with anaerobic digestion/fermentation,Non-forest biomass,Physical,Mt/MtCO2,6,1.4285714285714,2.689964230684533,1.5617433414042998,2.1282742681047,2.6242499596696813,1.315,8.0
13
+ BioCCS with anaerobic digestion/fermentation,Unspecified biomass,Physical,Mt/MtCO2,6,1.03357023,1.3793645466666666,1.14,1.785,0.4849128814150571,0.99809364,2.0
14
+ BioCCS with anaerobic digestion/fermentation,Unspecified water,Physical,bcm/MtCO2,14,0.3954545,0.5698051428571428,0.565909,0.6545455,0.183277283077123,0.368182,0.913636
15
+ BioCCS with combustion,Arable land,Physical,Mha/MtCO2,32,0.038,0.20054008704125,0.058399844,0.09459459,0.4656596577374178,0.022803284,1.9451
16
+ BioCCS with combustion,Electrical energy,Energy,TWh/MtCO2,18,0.0277777777777777,0.1309753086419752,0.101,0.1111111111111111,0.162410257015863,0.0,0.5
17
+ BioCCS with combustion,Forest biomass,Physical,Mt/MtCO2,8,0.5607638875000001,0.67548055375,0.59375,0.8386749975,0.1444191465369566,0.55555555,0.8547
18
+ BioCCS with combustion,Thermal energy unspecified grade,Energy,TWh/MtCO2,22,0.3472222222222222,1.0062424242424242,0.9306111111111112,1.025,1.0524401441735465,0.0,4.0
19
+ BioCCS with combustion,Unspecified biomass,Physical,Mt/MtCO2,8,0.9166666675,1.2641666675,1.14,1.625,0.5282247887342408,0.66666667,2.0
20
+ BioCCS with combustion,Unspecified chemical,Physical,Mt/MtCO2,20,0.00027,4.044119,0.00316,0.016,8.287794157908491,0.00013,20.2
21
+ BioCCS with combustion,Unspecified water,Physical,bcm/MtCO2,32,0.006475,0.31293745634375003,0.2016252165,0.5420455,0.34315480918602004,0.00063,1.29634217
22
+ "Coastal revegetation (mangrove, seaweeds, etc.)",Non-arable land,Physical,Mha/MtCO2,11,0.04329502,0.1320179618181818,0.12056618,0.19744896,0.1170638856345574,0.0078,0.32828863
23
+ Cropland management,Arable land,Physical,Mha/MtCO2,14,0.27061989,1.2779463596825358,0.4206349227777499,1.05233487,2.3297794467976978,0.08264463,9.0
24
+ Durable biobased products,Electrical energy,Energy,TWh/MtCO2,2,4.0,4.0,4.0,4.0,0.0,4.0,4.0
25
+ Durable biobased products,Non-arable land,Physical,Mha/MtCO2,2,6.0,6.0,6.0,6.0,0.0,6.0,6.0
26
+ Durable biobased products,Unspecified biomass,Physical,Mt/MtCO2,6,1.2678571425,2.6071428566666666,3.57142857,3.8928571425,1.8426633339173129,0.0,4.0
27
+ Durable biobased products,Unspecified water,Physical,bcm/MtCO2,2,0.0002,0.0003,0.0003,0.0004,0.000282842712474619,0.0001,0.0005
28
+ Electrochemical DACCS,Electrical energy,Energy,TWh/MtCO2,10,0.33333333335,2.0320806,0.784125,2.75,2.378832503076304,0.252556,6.2222222222
29
+ Electrochemical DACCS,Non-arable land,Physical,Mha/MtCO2,14,0.00027248,0.0026615877837057,0.000323748514,0.000880697128935,0.0056568299980059,0.0002225771032,0.016
30
+ Electrochemical DACCS,Unspecified water,Physical,bcm/MtCO2,6,0.002,0.011,0.005,0.0215,0.012521980673998822,0.001,0.027
31
+ Electrochemical OAE,Electrical energy,Energy,TWh/MtCO2,8,1.6,2.24125,2.15,2.5,1.2835935883292655,0.83,5.0
32
+ Electrochemical OAE,Non-arable land,Physical,Mha/MtCO2,2,0.00086,0.00101,0.00101,0.00116,0.0004242640687119,0.00071,0.00131
33
+ Electrochemical OAE,Shoreline,Physical,km/MtCO2,2,0.012,0.012,0.012,0.012,0.0,0.012,0.012
34
+ Electrochemical OAE,Unspecified mineral,Physical,Mt/MtCO2,4,2.4,2.95,2.95,3.5,0.6350852961085884,2.4,3.5
35
+ Enhanced weathering,Arable land,Physical,Mha/MtCO2,28,0.12875,0.548973515,0.25,0.5,0.7099161244217219,1e-06,2.5
36
+ Enhanced weathering,Basalt mineral,Physical,Mt/MtCO2,25,3.33,5.773041804595108,4.3,5.3,4.967901225163679,1.0,19.0
37
+ Enhanced weathering,Electrical energy,Energy,TWh/MtCO2,8,0.09285,0.59343125,0.38875,0.5,0.9045657102947644,0.00925,2.775
38
+ Enhanced weathering,Non-arable land,Physical,Mha/MtCO2,12,0.004428795,11.432468628333334,0.00906504,28.5714286,17.226399848110834,0.0009,40.0
39
+ Enhanced weathering,Olivine mineral,Physical,Mt/MtCO2,26,0.9090909,1.4295112634615386,1.25,1.58,0.9412466256217809,0.27027027,3.7
40
+ Enhanced weathering,Unspecified mineral,Physical,Mt/MtCO2,19,1.31578947,6.356736418947368,2.5,8.625,7.726415037245945,0.5,25.0
41
+ Enhanced weathering,Unspecified water,Physical,bcm/MtCO2,5,0.0005,0.010466399999999999,0.000866,0.000866,0.02210221859452123,0.0001,0.05
42
+ Enhanced weathering,Wollastonite mineral,Physical,Mt/MtCO2,8,1.32142857142855,1.62964285714285,1.5642857142856998,1.83,0.7423655162834324,0.56,3.0
43
+ Forest management,Unspecified land,Physical,Mha/MtCO2,2,0.438675,0.76865,0.76865,1.0986250000000002,0.9333102404881242,0.1087,1.4286
44
+ High-temp DACCS (solid-sorbent/liquid-solvent),Electrical energy,Energy,TWh/MtCO2,32,0.3611111111,0.4237878472201387,0.46296111111111,0.5,0.1631783450145829,0.077,0.77
45
+ High-temp DACCS (solid-sorbent/liquid-solvent),Non-arable land,Physical,Mha/MtCO2,23,2.2000000000000002e-08,0.0002292964161686,0.0002225771032,0.000298114257,0.0002987803322061,1.5e-10,0.0009914798235
46
+ High-temp DACCS (solid-sorbent/liquid-solvent),Thermal energy high grade,Energy,TWh/MtCO2,38,1.4722222222,1.954835008771642,1.75,2.3148148055556,0.6439376166933265,1.125,3.8
47
+ High-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water,Physical,bcm/MtCO2,16,0.0025020435975000002,0.01022102242375,0.0047,0.00818,0.015886886921845426,5e-09,0.05
48
+ Low-temp DACCS (solid-sorbent/liquid-solvent),Electrical energy,Energy,TWh/MtCO2,44,0.218,0.8953202020237373,0.46296111111111,0.69,1.2556951906425198,0.13,4.6111111111
49
+ Low-temp DACCS (solid-sorbent/liquid-solvent),Non-arable land,Physical,Mha/MtCO2,23,6.25e-08,0.0002382447396469,0.0002225771032,0.000298114257,0.0002944782932015,1e-11,0.0009914798235
50
+ Low-temp DACCS (solid-sorbent/liquid-solvent),Thermal energy low grade,Energy,TWh/MtCO2,30,1.4325,1.6782145666607466,1.5,2.062499999975,0.5167942816781624,0.6388888889,2.7222222222
51
+ Low-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water,Physical,bcm/MtCO2,14,7.5e-10,0.0031868824842857142,0.00100817439,0.004925,0.005237922016339205,-0.002,0.015
52
+ Mineral OAE / Ocean liming,Electrical energy,Energy,TWh/MtCO2,12,0.323625,1.1535833333333334,0.6065,1.755,1.2860244737055733,0.027,4.0
53
+ Mineral OAE / Ocean liming,Non-arable land,Physical,Mha/MtCO2,4,0.0,0.000505,0.000355,0.00086,0.0006324818837985,0.0,0.00131
54
+ Mineral OAE / Ocean liming,Thermal energy unspecified grade,Energy,TWh/MtCO2,6,1.3888888888888888,1.2576296296296297,1.4589444444444444,1.529,0.5425887907843043,0.16,1.55
55
+ Mineral OAE / Ocean liming,Unspecified mineral,Physical,Mt/MtCO2,8,1.62,2.489,1.743,2.5895,1.5545979728350534,1.4,5.0
56
+ Mineral OAE / Ocean liming,Unspecified water,Physical,bcm/MtCO2,2,0.000678331,0.000678331,0.000678331,0.000678331,0.0,0.000678331,0.000678331
57
+ Mineral looping DACCS,Electrical energy,Energy,TWh/MtCO2,8,0.0833333333,1.1041666666583332,0.0833333333333333,1.375,1.793811009144325,0.0,4.0
58
+ Mineral looping DACCS,Non-arable land,Physical,Mha/MtCO2,12,0.0005870872613099,0.001064587040495,0.00063889,0.0008728674558749,0.0010640920465922,0.0002225771032,0.0033
59
+ Mineral looping DACCS,Thermal energy unspecified grade,Energy,TWh/MtCO2,4,1.479166666675,1.715277777775,1.81944444445,2.05555555555,0.5340152854505239,1.0,2.2222222222
60
+ Mineral looping DACCS,Unspecified mineral,Physical,Mt/MtCO2,4,0.15,0.225,0.2,0.275,0.206155281280883,0.0,0.5
61
+ Mineral looping DACCS,Unspecified water,Physical,bcm/MtCO2,6,0.000125,0.006761835055,0.0002,0.01006775258,0.011115783599449734,0.0,0.02671400689
62
+ Mineralization ex-situ,Electrical energy,Energy,TWh/MtCO2,8,0.5,1.0625,0.75,1.25,0.9797047660246574,0.0,3.0
63
+ Mineralization ex-situ,Non-arable land,Physical,Mha/MtCO2,4,0.0002984556613,0.000521538621485,0.00043604877962,0.0006591317398049,0.0003415954957779,0.0002225771032,0.0009914798235
64
+ Mineralization ex-situ,Olivine mineral,Physical,Mt/MtCO2,2,0.8,0.8,0.8,0.8,0.0,0.8,0.8
65
+ Mineralization ex-situ,Thermal energy unspecified grade,Energy,TWh/MtCO2,4,0.4,0.575,0.45,0.625,0.2872281323269014,0.4,1.0
66
+ Mineralization ex-situ,Unspecified mineral,Physical,Mt/MtCO2,22,0.4375,3.935,3.0,7.0,3.6477217286306,0.04,10.0
67
+ Mineralization ex-situ,Unspecified water,Physical,bcm/MtCO2,14,0.0002,0.050004285714285716,0.00545,0.0145,0.10690799154947613,0.0,0.3
68
+ Moisture swing DACCS,Electrical energy,Energy,TWh/MtCO2,4,0.316,0.32466666665,0.32466666665,0.3333333333,0.0100074046467084,0.316,0.3333333333
69
+ Moisture swing DACCS,Non-arable land,Physical,Mha/MtCO2,8,0.0001689328274,0.0003308893107425,0.00027248,0.00037989864681,0.0003186555229397,8e-06,0.0009914798235
70
+ Moisture swing DACCS,Unspecified water,Physical,bcm/MtCO2,4,-0.000146,0.000427,0.000427,0.001,0.0006616434084913112,-0.000146,0.001
71
+ Pasture management,Arable land,Physical,Mha/MtCO2,24,0.1022528475,0.4423677031702624,0.25242204,0.522974429158825,0.522145451866414,0.07189434,2.28974424
72
+ Reforestation,Unspecified land,Physical,Mha/MtCO2,34,0.044458695,1.5641017441794511,0.094926862556845,0.1887,6.825803296418775,0.002,38.8
73
+ Reforestation,Unspecified water,Physical,bcm/MtCO2,2,0.092,0.092,0.092,0.092,0.0,0.092,0.092
74
+ pH swing,Electrical energy,Energy,TWh/MtCO2,28,0.98,2.2051124785714284,1.768,3.3025,1.3819088428118145,0.66,4.67
75
+ pH swing,Salt water,Physical,bcm/MtCO2,4,0.435,4.78,4.78,9.125,5.017173839257849,0.435,9.125
76
+ pH swing,Unspecified water,Physical,bcm/MtCO2,4,0.217391304,6.608695652,6.608695652,13.0,7.380042571581251,0.217391304,13.0
data/inputs_aggregated_old.csv CHANGED
@@ -1,74 +1,76 @@
1
  Implementation,Resource,Type,Unit,count,quantile_25,mean,median,quantile_75,std,min,max
2
- Agroforestry,Arable land,Physical,ha/tCO2,12,0.03995278725,0.4507674440833333,0.06410128000000001,0.2141,0.901140274110988,0.0025,3.03030303
3
- Bio-char,Electrical energy,Energy,MWh/tCO2,6,8.75e-05,0.1667833333333333,0.00035,0.3750875,0.2581085675964025,0.0,0.5
4
- Bio-char,Forest biomass,Physical,t/tCO2,6,0.34,0.47283333333333327,0.37,0.55525,0.20162382465042825,0.33,0.82
5
- Bio-char,Non-forest biomass,Physical,t/tCO2,8,1.142,1.291,1.3395000000000001,1.4885000000000002,0.332019792869556,0.818,1.667
6
- Bio-char,Unspecified biomass,Physical,t/tCO2,48,0.94339623,1.924254525942129,1.20922073,2.522177213052725,1.9378239910641315,0.5,12.86
7
- Bio-char,Unspecified land,Physical,ha/tCO2,4,0.05640158,0.16320079,0.16320079,0.27,0.12332110528547877,0.05640158,0.27
 
 
8
  Bio-char,Unspecified water,Physical,Liters/tCO2,9,0.0,633.3333333333334,100.0,500.0,1376.5899897936204,-500.0,3000.0
9
- BioCCS with anaerobic digestion/fermentation,Arable land,Physical,ha/tCO2,16,0.03793734775,0.100866767,0.058844191000000004,0.10303396649999999,0.11375772648817686,0.022803284,0.454545455
10
- BioCCS with anaerobic digestion/fermentation,Non-forest biomass,Physical,t/tCO2,6,1.4285714285714,2.689964230684533,1.5617433414042998,2.1282742681047,2.6242499596696813,1.315,8.0
11
- BioCCS with anaerobic digestion/fermentation,Unspecified biomass,Physical,t/tCO2,6,1.03357023,1.3793645466666666,1.14,1.785,0.4849128814150571,0.99809364,2.0
12
  BioCCS with anaerobic digestion/fermentation,Unspecified water,Physical,Liters/tCO2,14,395454.5,569805.1428571428,565909.0,654545.5,183277.283077123,368182.0,913636.0
13
- BioCCS with combustion,Arable land,Physical,ha/tCO2,32,0.038,0.20054008704125,0.058399844,0.09459459,0.4656596577374178,0.022803284,1.9451
14
- BioCCS with combustion,Electrical energy,Energy,MWh/tCO2,18,0.0277777777777777,0.13097530864197526,0.101,0.1111111111111111,0.16241025701586306,0.0,0.5
15
- BioCCS with combustion,Forest biomass,Physical,t/tCO2,8,0.5607638875000001,0.67548055375,0.59375,0.8386749975,0.14441914653695664,0.55555555,0.8547
16
- BioCCS with combustion,Thermal energy,Energy,MWh/tCO2,22,0.3472222222222222,1.0062424242424242,0.9306111111111111,1.025,1.0524401441735463,0.0,4.0
17
- BioCCS with combustion,Unspecified biomass,Physical,t/tCO2,8,0.9166666675,1.2641666675,1.14,1.625,0.5282247887342408,0.66666667,2.0
18
- BioCCS with combustion,Unspecified chemical,Physical,t/tCO2,20,0.00027,4.044119,0.00316,0.016,8.287794157908491,0.00013,20.2
19
  BioCCS with combustion,Unspecified water,Physical,Liters/tCO2,32,6475.0,312937.45634375,201625.2165,542045.5,343154.80918602005,630.0,1296342.17
20
- "Coastal revegetation (mangrove, seaweeds…)",Non-arable land,Physical,ha/tCO2,11,0.043295020000000004,0.13201796181818182,0.12056618,0.19744896,0.11706388563455744,0.0078,0.32828863
21
- Cropland management,Arable land,Physical,ha/tCO2,14,0.27061989000000003,1.2779463596825358,0.42063492277774994,1.05233487,2.3297794467976978,0.08264463,9.0
22
- Durable biobased products,Electrical energy,Energy,MWh/tCO2,2,4.0,4.0,4.0,4.0,0.0,4.0,4.0
23
- Durable biobased products,Non-arable land,Physical,ha/tCO2,2,6.0,6.0,6.0,6.0,0.0,6.0,6.0
24
- Durable biobased products,Unspecified biomass,Physical,t/tCO2,6,1.2678571425,2.6071428566666666,3.57142857,3.8928571425,1.8426633339173129,0.0,4.0
25
  Durable biobased products,Unspecified water,Physical,Liters/tCO2,2,200.0,300.0,300.0,400.0,282.842712474619,100.0,500.0
26
- Electrochemical DACCS,Electrical energy,Energy,MWh/tCO2,10,0.33333333335000004,2.0320806,0.784125,2.75,2.3788325030763033,0.252556,6.2222222222
27
- Electrochemical DACCS,Non-arable land,Physical,ha/tCO2,14,0.00027248,0.0026615877837057145,0.000323748514,0.000880697128935,0.005656829998005935,0.0002225771032,0.016
28
  Electrochemical DACCS,Unspecified water,Physical,Liters/tCO2,6,2000.0,11000.0,5000.0,21500.0,12521.980673998822,1000.0,27000.0
29
- Electrochemical OAE,Electrical energy,Energy,MWh/tCO2,8,1.6,2.24125,2.15,2.5,1.2835935883292655,0.83,5.0
30
- Electrochemical OAE,Non-arable land,Physical,ha/tCO2,2,0.00086,0.00101,0.00101,0.00116,0.00042426406871192844,0.00071,0.00131
31
- Electrochemical OAE,Shoreline,Physical,km/tCO2,2,1.2e-08,1.2e-08,1.2e-08,1.2e-08,0.0,1.2e-08,1.2e-08
32
- Electrochemical OAE,Unspecified mineral,Physical,t/tCO2,4,2.4,2.95,2.95,3.5,0.6350852961085884,2.4,3.5
33
- Enhanced weathering,Arable land,Physical,ha/tCO2,28,0.12875,0.548973515,0.25,0.5,0.7099161244217219,1e-06,2.5
34
- Enhanced weathering,Basalt mineral,Physical,t/tCO2,25,3.33,5.773041804595108,4.3,5.3,4.967901225163679,1.0,19.0
35
- Enhanced weathering,Electrical energy,Energy,MWh/tCO2,8,0.09285,0.59343125,0.38875000000000004,0.5,0.9045657102947644,0.00925,2.775
36
- Enhanced weathering,Non-arable land,Physical,ha/tCO2,12,0.004428795,11.432468628333334,0.00906504,28.5714286,17.226399848110834,0.0009,40.0
37
- Enhanced weathering,Olivine mineral,Physical,t/tCO2,26,0.9090909,1.4295112634615386,1.25,1.58,0.9412466256217807,0.27027027,3.7
38
- Enhanced weathering,Unspecified mineral,Physical,t/tCO2,19,1.31578947,6.356736418947368,2.5,8.625,7.726415037245945,0.5,25.0
39
  Enhanced weathering,Unspecified water,Physical,Liters/tCO2,5,500.0,10466.4,866.0,866.0,22102.21859452123,100.0,50000.0
40
- Enhanced weathering,Wollastonite mineral,Physical,t/tCO2,8,1.3214285714285499,1.62964285714285,1.5642857142856998,1.83,0.7423655162834324,0.56,3.0
41
- Forest management,Unspecified land,Physical,ha/tCO2,2,0.43867500000000004,0.76865,0.76865,1.0986250000000002,0.9333102404881242,0.1087,1.4286
42
- Forestry,Unspecified land,Physical,ha/tCO2,70,0.0264,0.8191848413886097,0.094926862556845,0.1887,4.777133871507938,0.002,38.8
43
- Forestry,Unspecified water,Physical,Liters/tCO2,4,92000.0,92000.0,92000.0,92000.0,0.0,92000.0,92000.0
44
- High-temp DACCS (solid-sorbent/liquid-solvent),Electrical energy,Energy,MWh/tCO2,32,0.3611111111,0.42378784722013874,0.46296111111111,0.5,0.16317834501458298,0.077,0.77
45
- High-temp DACCS (solid-sorbent/liquid-solvent),Non-arable land,Physical,ha/tCO2,23,2.2000000000000002e-08,0.00022929641616869565,0.0002225771032,0.000298114257,0.0002987803322061786,1.5e-10,0.0009914798235
46
- High-temp DACCS (solid-sorbent/liquid-solvent),Thermal energy,Energy,MWh/tCO2,38,1.4722222222,1.954835008771642,1.75,2.3148148055556,0.6439376166933265,1.125,3.8
47
- High-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water,Physical,Liters/tCO2,16,2502.0435975,10221.02242375,4700.0,8180.0,15886.886921845426,0.005,50000.0
48
- Low-temp DACCS (solid-sorbent/liquid-solvent),Electrical energy,Energy,MWh/tCO2,44,0.218,0.8953202020237373,0.46296111111111,0.69,1.2556951906425198,0.13,4.6111111111
49
- Low-temp DACCS (solid-sorbent/liquid-solvent),Non-arable land,Physical,ha/tCO2,23,6.25e-08,0.00023824473964695653,0.0002225771032,0.000298114257,0.00029447829320152126,1e-11,0.0009914798235
50
- Low-temp DACCS (solid-sorbent/liquid-solvent),Thermal energy,Energy,MWh/tCO2,30,1.4324999999999999,1.6782145666607466,1.5,2.062499999975,0.5167942816781624,0.6388888889,2.7222222222
51
- Low-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water,Physical,Liters/tCO2,14,0.00075,3186.8824842857143,1008.17439,4925.0,5237.922016339205,-2000.0,15000.0
52
- Mineral OAE / Ocean liming,Electrical energy,Energy,MWh/tCO2,12,0.323625,1.1535833333333334,0.6065,1.755,1.2860244737055733,0.027,4.0
53
- Mineral OAE / Ocean liming,Non-arable land,Physical,ha/tCO2,4,0.0,0.000505,0.000355,0.00086,0.0006324818837985268,0.0,0.00131
54
- Mineral OAE / Ocean liming,Thermal energy,Energy,MWh/tCO2,6,1.3888888888888888,1.2576296296296297,1.4589444444444444,1.529,0.5425887907843043,0.16,1.55
55
- Mineral OAE / Ocean liming,Unspecified mineral,Physical,t/tCO2,8,1.62,2.489,1.7429999999999999,2.5895,1.5545979728350534,1.4,5.0
56
  Mineral OAE / Ocean liming,Unspecified water,Physical,Liters/tCO2,2,678.331,678.331,678.331,678.331,0.0,678.331,678.331
57
- Mineral looping DACCS,Electrical energy,Energy,MWh/tCO2,8,0.0833333333,1.1041666666583332,0.0833333333333333,1.375,1.793811009144325,0.0,4.0
58
- Mineral looping DACCS,Non-arable land,Physical,ha/tCO2,12,0.0005870872613099999,0.001064587040495,0.00063889,0.0008728674558749999,0.0010640920465922832,0.0002225771032,0.0033
59
- Mineral looping DACCS,Thermal energy,Energy,MWh/tCO2,4,1.4791666666749999,1.715277777775,1.81944444445,2.05555555555,0.5340152854505239,1.0,2.2222222222
60
- Mineral looping DACCS,Unspecified mineral,Physical,t/tCO2,4,0.15000000000000002,0.225,0.2,0.275,0.20615528128088303,0.0,0.5
61
  Mineral looping DACCS,Unspecified water,Physical,Liters/tCO2,6,125.0,6761.8350550000005,200.0,10067.75258,11115.783599449733,0.0,26714.00689
62
- Mineralization ex-situ,Electrical energy,Energy,MWh/tCO2,8,0.5,1.0625,0.75,1.25,0.9797047660246574,0.0,3.0
63
- Mineralization ex-situ,Non-arable land,Physical,ha/tCO2,4,0.0002984556613,0.000521538621485,0.00043604877962,0.0006591317398049999,0.00034159549577798685,0.0002225771032,0.0009914798235
64
- Mineralization ex-situ,Olivine mineral,Physical,t/tCO2,2,0.8,0.8,0.8,0.8,0.0,0.8,0.8
65
- Mineralization ex-situ,Thermal energy,Energy,MWh/tCO2,4,0.4,0.575,0.45,0.625,0.2872281323269014,0.4,1.0
66
- Mineralization ex-situ,Unspecified mineral,Physical,t/tCO2,22,0.4375,3.9349999999999996,3.0,7.0,3.6477217286306,0.04,10.0
67
  Mineralization ex-situ,Unspecified water,Physical,Liters/tCO2,14,200.0,50004.28571428572,5450.0,14500.0,106907.99154947611,0.0,300000.0
68
- Moisture swing DACCS,Electrical energy,Energy,MWh/tCO2,4,0.316,0.32466666665,0.32466666665,0.3333333333,0.01000740464670849,0.316,0.3333333333
69
- Moisture swing DACCS,Non-arable land,Physical,ha/tCO2,8,0.00016893282740000002,0.0003308893107425,0.00027248,0.00037989864681,0.0003186555229397746,8e-06,0.0009914798235
70
  Moisture swing DACCS,Unspecified water,Physical,Liters/tCO2,4,-146.0,427.0,427.0,1000.0,661.6434084913111,-146.0,1000.0
71
- Pasture management,Arable land,Physical,ha/tCO2,24,0.10225284750000001,0.44236770317026247,0.25242204,0.522974429158825,0.522145451866414,0.07189434,2.28974424
72
- pH swing,Electrical energy,Energy,MWh/tCO2,28,0.98,2.2051124785714284,1.768,3.3024999999999998,1.3819088428118145,0.66,4.67
 
 
73
  pH swing,Salt water,Physical,Liters/tCO2,4,435000.0,4780000.0,4780000.0,9125000.0,5017173.8392578475,435000.0,9125000.0
74
  pH swing,Unspecified water,Physical,Liters/tCO2,4,217391.304,6608695.652,6608695.652,13000000.0,7380042.571581251,217391.304,13000000.0
 
1
  Implementation,Resource,Type,Unit,count,quantile_25,mean,median,quantile_75,std,min,max
2
+ Afforestation,Unspecified land,Physical,Mha/MtCO2,36,0.024592505,0.11565221097503724,0.094926862556845,0.197075,0.11236779976444418,0.002,0.38461538
3
+ Afforestation,Unspecified water,Physical,Liters/tCO2,2,92000.0,92000.0,92000.0,92000.0,0.0,92000.0,92000.0
4
+ Agroforestry,Arable land,Physical,Mha/MtCO2,12,0.03995278725,0.4507674440833333,0.06410128000000001,0.2141,0.901140274110988,0.0025,3.03030303
5
+ Bio-char,Electrical energy,Energy,TWh/MtCO2,6,8.75e-05,0.1667833333333333,0.00035,0.3750875,0.2581085675964025,0.0,0.5
6
+ Bio-char,Forest biomass,Physical,Mt/MtCO2,6,0.34,0.47283333333333327,0.37,0.55525,0.20162382465042825,0.33,0.82
7
+ Bio-char,Non-forest biomass,Physical,Mt/MtCO2,8,1.142,1.291,1.3395000000000001,1.4885000000000002,0.332019792869556,0.818,1.667
8
+ Bio-char,Unspecified biomass,Physical,Mt/MtCO2,48,0.94339623,1.924254525942129,1.20922073,2.522177213052725,1.9378239910641315,0.5,12.86
9
+ Bio-char,Unspecified land,Physical,Mha/MtCO2,4,0.05640158,0.16320079,0.16320079,0.27,0.12332110528547877,0.05640158,0.27
10
  Bio-char,Unspecified water,Physical,Liters/tCO2,9,0.0,633.3333333333334,100.0,500.0,1376.5899897936204,-500.0,3000.0
11
+ BioCCS with anaerobic digestion/fermentation,Arable land,Physical,Mha/MtCO2,16,0.03793734775,0.100866767,0.058844191000000004,0.10303396649999999,0.11375772648817686,0.022803284,0.454545455
12
+ BioCCS with anaerobic digestion/fermentation,Non-forest biomass,Physical,Mt/MtCO2,6,1.4285714285714,2.689964230684533,1.5617433414042998,2.1282742681047,2.6242499596696813,1.315,8.0
13
+ BioCCS with anaerobic digestion/fermentation,Unspecified biomass,Physical,Mt/MtCO2,6,1.03357023,1.3793645466666666,1.14,1.785,0.4849128814150571,0.99809364,2.0
14
  BioCCS with anaerobic digestion/fermentation,Unspecified water,Physical,Liters/tCO2,14,395454.5,569805.1428571428,565909.0,654545.5,183277.283077123,368182.0,913636.0
15
+ BioCCS with combustion,Arable land,Physical,Mha/MtCO2,32,0.038,0.20054008704125,0.058399844,0.09459459,0.4656596577374178,0.022803284,1.9451
16
+ BioCCS with combustion,Electrical energy,Energy,TWh/MtCO2,18,0.0277777777777777,0.13097530864197526,0.101,0.1111111111111111,0.16241025701586306,0.0,0.5
17
+ BioCCS with combustion,Forest biomass,Physical,Mt/MtCO2,8,0.5607638875000001,0.67548055375,0.59375,0.8386749975,0.14441914653695664,0.55555555,0.8547
18
+ BioCCS with combustion,Thermal energy unspecified grade,Energy,TWh/MtCO2,22,0.3472222222222222,1.0062424242424242,0.9306111111111111,1.025,1.0524401441735463,0.0,4.0
19
+ BioCCS with combustion,Unspecified biomass,Physical,Mt/MtCO2,8,0.9166666675,1.2641666675,1.14,1.625,0.5282247887342408,0.66666667,2.0
20
+ BioCCS with combustion,Unspecified chemical,Physical,Mt/MtCO2,20,0.00027,4.044119,0.00316,0.016,8.287794157908491,0.00013,20.2
21
  BioCCS with combustion,Unspecified water,Physical,Liters/tCO2,32,6475.0,312937.45634375,201625.2165,542045.5,343154.80918602005,630.0,1296342.17
22
+ "Coastal revegetation (mangrove, seaweeds…)",Non-arable land,Physical,Mha/MtCO2,11,0.043295020000000004,0.13201796181818182,0.12056618,0.19744896,0.11706388563455744,0.0078,0.32828863
23
+ Cropland management,Arable land,Physical,Mha/MtCO2,14,0.27061989000000003,1.2779463596825358,0.42063492277774994,1.05233487,2.3297794467976978,0.08264463,9.0
24
+ Durable biobased products,Electrical energy,Energy,TWh/MtCO2,2,4.0,4.0,4.0,4.0,0.0,4.0,4.0
25
+ Durable biobased products,Non-arable land,Physical,Mha/MtCO2,2,6.0,6.0,6.0,6.0,0.0,6.0,6.0
26
+ Durable biobased products,Unspecified biomass,Physical,Mt/MtCO2,6,1.2678571425,2.6071428566666666,3.57142857,3.8928571425,1.8426633339173129,0.0,4.0
27
  Durable biobased products,Unspecified water,Physical,Liters/tCO2,2,200.0,300.0,300.0,400.0,282.842712474619,100.0,500.0
28
+ Electrochemical DACCS,Electrical energy,Energy,TWh/MtCO2,10,0.33333333335000004,2.0320806,0.784125,2.75,2.3788325030763033,0.252556,6.2222222222
29
+ Electrochemical DACCS,Non-arable land,Physical,Mha/MtCO2,14,0.00027248,0.0026615877837057145,0.000323748514,0.000880697128935,0.005656829998005935,0.0002225771032,0.016
30
  Electrochemical DACCS,Unspecified water,Physical,Liters/tCO2,6,2000.0,11000.0,5000.0,21500.0,12521.980673998822,1000.0,27000.0
31
+ Electrochemical OAE,Electrical energy,Energy,TWh/MtCO2,8,1.6,2.24125,2.15,2.5,1.2835935883292655,0.83,5.0
32
+ Electrochemical OAE,Non-arable land,Physical,Mha/MtCO2,2,0.00086,0.00101,0.00101,0.00116,0.00042426406871192844,0.00071,0.00131
33
+ Electrochemical OAE,Shoreline,Physical,km/MtCO2,2,0.012,0.012,0.012,0.012,0.0,0.012,0.012
34
+ Electrochemical OAE,Unspecified mineral,Physical,Mt/MtCO2,4,2.4,2.95,2.95,3.5,0.6350852961085884,2.4,3.5
35
+ Enhanced weathering,Arable land,Physical,Mha/MtCO2,28,0.12875,0.548973515,0.25,0.5,0.7099161244217219,1e-06,2.5
36
+ Enhanced weathering,Basalt mineral,Physical,Mt/MtCO2,25,3.33,5.773041804595108,4.3,5.3,4.967901225163679,1.0,19.0
37
+ Enhanced weathering,Electrical energy,Energy,TWh/MtCO2,8,0.09285,0.59343125,0.38875000000000004,0.5,0.9045657102947644,0.00925,2.775
38
+ Enhanced weathering,Non-arable land,Physical,Mha/MtCO2,12,0.004428795,11.432468628333334,0.00906504,28.5714286,17.226399848110834,0.0009,40.0
39
+ Enhanced weathering,Olivine mineral,Physical,Mt/MtCO2,26,0.9090909,1.4295112634615386,1.25,1.58,0.9412466256217807,0.27027027,3.7
40
+ Enhanced weathering,Unspecified mineral,Physical,Mt/MtCO2,19,1.31578947,6.356736418947368,2.5,8.625,7.726415037245945,0.5,25.0
41
  Enhanced weathering,Unspecified water,Physical,Liters/tCO2,5,500.0,10466.4,866.0,866.0,22102.21859452123,100.0,50000.0
42
+ Enhanced weathering,Wollastonite mineral,Physical,Mt/MtCO2,8,1.3214285714285499,1.62964285714285,1.5642857142856998,1.83,0.7423655162834324,0.56,3.0
43
+ Forest management,Unspecified land,Physical,Mha/MtCO2,2,0.43867500000000004,0.76865,0.76865,1.0986250000000002,0.9333102404881242,0.1087,1.4286
44
+ High-temp DACCS (solid-sorbenMt/liquid-solvent),Electrical energy,Energy,TWh/MtCO2,32,0.3611111111,0.42378784722013874,0.46296111111111,0.5,0.16317834501458298,0.077,0.77
45
+ High-temp DACCS (solid-sorbenMt/liquid-solvent),Non-arable land,Physical,Mha/MtCO2,23,2.2000000000000002e-08,0.00022929641616869565,0.0002225771032,0.000298114257,0.0002987803322061786,1.5e-10,0.0009914798235
46
+ High-temp DACCS (solid-sorbenMt/liquid-solvent),Thermal energy high grade,Energy,TWh/MtCO2,38,1.4722222222,1.954835008771642,1.75,2.3148148055556,0.6439376166933265,1.125,3.8
47
+ High-temp DACCS (solid-sorbenMt/liquid-solvent),Unspecified water,Physical,Liters/tCO2,16,2502.0435975,10221.02242375,4700.0,8180.0,15886.886921845426,0.005,50000.0
48
+ Low-temp DACCS (solid-sorbenMt/liquid-solvent),Electrical energy,Energy,TWh/MtCO2,44,0.218,0.8953202020237373,0.46296111111111,0.69,1.2556951906425198,0.13,4.6111111111
49
+ Low-temp DACCS (solid-sorbenMt/liquid-solvent),Non-arable land,Physical,Mha/MtCO2,23,6.25e-08,0.00023824473964695653,0.0002225771032,0.000298114257,0.00029447829320152126,1e-11,0.0009914798235
50
+ Low-temp DACCS (solid-sorbenMt/liquid-solvent),Thermal energy low grade,Energy,TWh/MtCO2,30,1.4324999999999999,1.6782145666607466,1.5,2.062499999975,0.5167942816781624,0.6388888889,2.7222222222
51
+ Low-temp DACCS (solid-sorbenMt/liquid-solvent),Unspecified water,Physical,Liters/tCO2,14,0.00075,3186.8824842857143,1008.17439,4925.0,5237.922016339205,-2000.0,15000.0
52
+ Mineral OAE / Ocean liming,Electrical energy,Energy,TWh/MtCO2,12,0.323625,1.1535833333333334,0.6065,1.755,1.2860244737055733,0.027,4.0
53
+ Mineral OAE / Ocean liming,Non-arable land,Physical,Mha/MtCO2,4,0.0,0.000505,0.000355,0.00086,0.0006324818837985268,0.0,0.00131
54
+ Mineral OAE / Ocean liming,Thermal energy unspecified grade,Energy,TWh/MtCO2,6,1.3888888888888888,1.2576296296296297,1.4589444444444444,1.529,0.5425887907843043,0.16,1.55
55
+ Mineral OAE / Ocean liming,Unspecified mineral,Physical,Mt/MtCO2,8,1.62,2.489,1.7429999999999999,2.5895,1.5545979728350534,1.4,5.0
 
 
56
  Mineral OAE / Ocean liming,Unspecified water,Physical,Liters/tCO2,2,678.331,678.331,678.331,678.331,0.0,678.331,678.331
57
+ Mineral looping DACCS,Electrical energy,Energy,TWh/MtCO2,8,0.0833333333,1.1041666666583332,0.0833333333333333,1.375,1.793811009144325,0.0,4.0
58
+ Mineral looping DACCS,Non-arable land,Physical,Mha/MtCO2,12,0.0005870872613099999,0.001064587040495,0.00063889,0.0008728674558749999,0.0010640920465922832,0.0002225771032,0.0033
59
+ Mineral looping DACCS,Thermal energy unspecified grade,Energy,TWh/MtCO2,4,1.4791666666749999,1.715277777775,1.81944444445,2.05555555555,0.5340152854505239,1.0,2.2222222222
60
+ Mineral looping DACCS,Unspecified mineral,Physical,Mt/MtCO2,4,0.15000000000000002,0.225,0.2,0.275,0.20615528128088303,0.0,0.5
61
  Mineral looping DACCS,Unspecified water,Physical,Liters/tCO2,6,125.0,6761.8350550000005,200.0,10067.75258,11115.783599449733,0.0,26714.00689
62
+ Mineralization ex-situ,Electrical energy,Energy,TWh/MtCO2,8,0.5,1.0625,0.75,1.25,0.9797047660246574,0.0,3.0
63
+ Mineralization ex-situ,Non-arable land,Physical,Mha/MtCO2,4,0.0002984556613,0.000521538621485,0.00043604877962,0.0006591317398049999,0.00034159549577798685,0.0002225771032,0.0009914798235
64
+ Mineralization ex-situ,Olivine mineral,Physical,Mt/MtCO2,2,0.8,0.8,0.8,0.8,0.0,0.8,0.8
65
+ Mineralization ex-situ,Thermal energy unspecified grade,Energy,TWh/MtCO2,4,0.4,0.575,0.45,0.625,0.2872281323269014,0.4,1.0
66
+ Mineralization ex-situ,Unspecified mineral,Physical,Mt/MtCO2,22,0.4375,3.9349999999999996,3.0,7.0,3.6477217286306,0.04,10.0
67
  Mineralization ex-situ,Unspecified water,Physical,Liters/tCO2,14,200.0,50004.28571428572,5450.0,14500.0,106907.99154947611,0.0,300000.0
68
+ Moisture swing DACCS,Electrical energy,Energy,TWh/MtCO2,4,0.316,0.32466666665,0.32466666665,0.3333333333,0.01000740464670849,0.316,0.3333333333
69
+ Moisture swing DACCS,Non-arable land,Physical,Mha/MtCO2,8,0.00016893282740000002,0.0003308893107425,0.00027248,0.00037989864681,0.0003186555229397746,8e-06,0.0009914798235
70
  Moisture swing DACCS,Unspecified water,Physical,Liters/tCO2,4,-146.0,427.0,427.0,1000.0,661.6434084913111,-146.0,1000.0
71
+ Pasture management,Arable land,Physical,Mha/MtCO2,24,0.10225284750000001,0.44236770317026247,0.25242204,0.522974429158825,0.522145451866414,0.07189434,2.28974424
72
+ Reforestation,Unspecified land,Physical,Mha/MtCO2,34,0.044458695,1.5641017441794511,0.094926862556845,0.1887,6.8258032964187745,0.002,38.8
73
+ Reforestation,Unspecified water,Physical,Liters/tCO2,2,92000.0,92000.0,92000.0,92000.0,0.0,92000.0,92000.0
74
+ pH swing,Electrical energy,Energy,TWh/MtCO2,28,0.98,2.2051124785714284,1.768,3.3024999999999998,1.3819088428118145,0.66,4.67
75
  pH swing,Salt water,Physical,Liters/tCO2,4,435000.0,4780000.0,4780000.0,9125000.0,5017173.8392578475,435000.0,9125000.0
76
  pH swing,Unspecified water,Physical,Liters/tCO2,4,217391.304,6608695.652,6608695.652,13000000.0,7380042.571581251,217391.304,13000000.0
data/inputs_template.xlsx CHANGED
Binary files a/data/inputs_template.xlsx and b/data/inputs_template.xlsx differ
 
data/resource_template.xlsx CHANGED
Binary files a/data/resource_template.xlsx and b/data/resource_template.xlsx differ
 
data/secondary_resources.csv CHANGED
@@ -1,50 +1,50 @@
1
  method,resource
2
- Afforestation,Unspecified water (Liters/tCO2)
3
- Reforestation,Unspecified water (Liters/tCO2)
4
- Durable biobased products,Non-arable land (ha/tCO2)
5
- Durable biobased products,Electrical energy (MWh/tCO2)
6
- Durable biobased products,Unspecified water (Liters/tCO2)
7
- Bio-char - Forest biomass,Unspecified land (ha/tCO2)
8
- Bio-char - Forest biomass,Electrical energy (MWh/tCO2)
9
- Bio-char - Forest biomass,Unspecified water (Liters/tCO2)
10
- Bio-char - Non-forest biomass,Unspecified land (ha/tCO2)
11
- Bio-char - Non-forest biomass,Electrical energy (MWh/tCO2)
12
- Bio-char - Non-forest biomass,Unspecified water (Liters/tCO2)
13
- Bio-char - Unspecified biomass,Unspecified land (ha/tCO2)
14
- Bio-char - Unspecified biomass,Electrical energy (MWh/tCO2)
15
- Bio-char - Unspecified biomass,Unspecified water (Liters/tCO2)
16
- BioCCS with combustion,Unspecified chemical (t/tCO2)
17
- BioCCS with combustion,Electrical energy (MWh/tCO2)
18
- BioCCS with combustion,Thermal energy (MWh/tCO2)
19
- BioCCS with combustion,Unspecified water (Liters/tCO2)
20
- BioCCS with combustion & growing biomass,Unspecified chemical (t/tCO2)
21
- BioCCS with combustion & growing biomass,Electrical energy (MWh/tCO2)
22
- BioCCS with combustion & growing biomass,Thermal energy (MWh/tCO2)
23
- BioCCS with combustion & growing biomass,Unspecified water (Liters/tCO2)
24
- BioCCS with anaerobic digestion/fermentation,Unspecified water (Liters/tCO2)
25
- BioCCS with anaerobic digestion/fermentation & growing biomass,Unspecified water (Liters/tCO2)
26
- Enhanced weathering - Basalt mineral,Arable land (ha/tCO2)
27
- Enhanced weathering - Basalt mineral,Non-arable land (ha/tCO2)
28
- Enhanced weathering - Basalt mineral,Electrical energy (MWh/tCO2)
29
- Enhanced weathering - Basalt mineral,Unspecified water (Liters/tCO2)
30
- Enhanced weathering - Olivine mineral,Arable land (ha/tCO2)
31
- Enhanced weathering - Olivine mineral,Non-arable land (ha/tCO2)
32
- Enhanced weathering - Olivine mineral,Electrical energy (MWh/tCO2)
33
- Enhanced weathering - Olivine mineral,Unspecified water (Liters/tCO2)
34
- Enhanced weathering - Wollastonite mineral,Arable land (ha/tCO2)
35
- Enhanced weathering - Wollastonite mineral,Non-arable land (ha/tCO2)
36
- Enhanced weathering - Wollastonite mineral,Electrical energy (MWh/tCO2)
37
- Enhanced weathering - Wollastonite mineral,Unspecified water (Liters/tCO2)
38
- Enhanced weathering - Unspecified mineral,Arable land (ha/tCO2)
39
- Enhanced weathering - Unspecified mineral,Non-arable land (ha/tCO2)
40
- Enhanced weathering - Unspecified mineral,Electrical energy (MWh/tCO2)
41
- Enhanced weathering - Unspecified mineral,Unspecified water (Liters/tCO2)
42
- Mineral OAE / Ocean liming,Non-arable land (ha/tCO2)
43
- Mineral OAE / Ocean liming,Electrical energy (MWh/tCO2)
44
- Mineral OAE / Ocean liming,Thermal energy (MWh/tCO2)
45
- Mineral OAE / Ocean liming,Unspecified water (Liters/tCO2)
46
- Electrochemical OAE,Non-arable land (ha/tCO2)
47
- Electrochemical DACCS,Non-arable land (ha/tCO2)
48
- Low-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water (Liters/tCO2)
49
- High-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water (Liters/tCO2)
50
- Mineral looping DACCS,Unspecified water (Liters/tCO2)
 
1
  method,resource
2
+ Afforestation,Unspecified water
3
+ Reforestation,Unspecified water
4
+ Durable biobased products,Non-arable land
5
+ Durable biobased products,Electrical energy
6
+ Durable biobased products,Unspecified water
7
+ Bio-char - Forest biomass,Unspecified land
8
+ Bio-char - Forest biomass,Electrical energy
9
+ Bio-char - Forest biomass,Unspecified water
10
+ Bio-char - Non-forest biomass,Unspecified land
11
+ Bio-char - Non-forest biomass,Electrical energy
12
+ Bio-char - Non-forest biomass,Unspecified water
13
+ Bio-char - Unspecified biomass,Unspecified land
14
+ Bio-char - Unspecified biomass,Electrical energy
15
+ Bio-char - Unspecified biomass,Unspecified water
16
+ BioCCS with combustion,Unspecified chemical
17
+ BioCCS with combustion,Electrical energy
18
+ BioCCS with combustion,Thermal energy
19
+ BioCCS with combustion,Unspecified water
20
+ BioCCS with combustion & growing biomass,Unspecified chemical
21
+ BioCCS with combustion & growing biomass,Electrical energy
22
+ BioCCS with combustion & growing biomass,Thermal energy
23
+ BioCCS with combustion & growing biomass,Unspecified water
24
+ BioCCS with anaerobic digestion/fermentation,Unspecified water
25
+ BioCCS with anaerobic digestion/fermentation & growing biomass,Unspecified water
26
+ Enhanced weathering - Basalt mineral,Arable land
27
+ Enhanced weathering - Basalt mineral,Non-arable land
28
+ Enhanced weathering - Basalt mineral,Electrical energy
29
+ Enhanced weathering - Basalt mineral,Unspecified water
30
+ Enhanced weathering - Olivine mineral,Arable land
31
+ Enhanced weathering - Olivine mineral,Non-arable land
32
+ Enhanced weathering - Olivine mineral,Electrical energy
33
+ Enhanced weathering - Olivine mineral,Unspecified water
34
+ Enhanced weathering - Wollastonite mineral,Arable land
35
+ Enhanced weathering - Wollastonite mineral,Non-arable land
36
+ Enhanced weathering - Wollastonite mineral,Electrical energy
37
+ Enhanced weathering - Wollastonite mineral,Unspecified water
38
+ Enhanced weathering - Unspecified mineral,Arable land
39
+ Enhanced weathering - Unspecified mineral,Non-arable land
40
+ Enhanced weathering - Unspecified mineral,Electrical energy
41
+ Enhanced weathering - Unspecified mineral,Unspecified water
42
+ Mineral OAE / Ocean liming,Non-arable land
43
+ Mineral OAE / Ocean liming,Electrical energy
44
+ Mineral OAE / Ocean liming,Thermal energy
45
+ Mineral OAE / Ocean liming,Unspecified water
46
+ Electrochemical OAE,Non-arable land
47
+ Electrochemical DACCS,Non-arable land
48
+ Low-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water
49
+ High-temp DACCS (solid-sorbent/liquid-solvent),Unspecified water
50
+ Mineral looping DACCS,Unspecified water
optimization/optimization.py CHANGED
@@ -8,16 +8,22 @@ def run_optimization(resource_caps, method_constraints, method_costs):
8
 
9
  Args:
10
  resource_caps (dict): {resource: available_quantity}
11
- method_constraints (dict): {method: {"active": bool, "max_share": float}}
 
 
12
  method_costs (dict): {method: {resource: usage_per_tCO2}}
13
 
14
  Returns:
15
  (bool, dict): (success_flag, result_dict)
16
  result_dict includes "total_removed", "method_usage"
17
  """
18
- methods = list(method_costs.keys())
 
19
  resources = list(resource_caps.keys())
20
 
 
 
 
21
  # A matrix: each row is a resource, each column a method
22
  A_resource = np.array([
23
  [method_costs[m].get(r, 0.0) for m in methods]
@@ -25,15 +31,27 @@ def run_optimization(resource_caps, method_constraints, method_costs):
25
  ])
26
  b_resource = np.array([resource_caps[r] for r in resources])
27
 
28
- # Constraint: sum(x_i) * share_i ≤ x_i
29
  A_share = []
30
  b_share = []
31
  for i, m in enumerate(methods):
32
- row = np.zeros(len(methods))
33
- row += -method_constraints[m]["max_share"]
34
- row[i] += 1
35
- A_share.append(row)
36
- b_share.append(0)
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  # Combine constraints
39
  A_ub = np.vstack([A_resource, A_share])
 
8
 
9
  Args:
10
  resource_caps (dict): {resource: available_quantity}
11
+ method_constraints (dict): {method: {"active": bool, "cap_type": str, "cap_value": float}}
12
+ cap_type: "percent" → cap_value is a fraction of total (0 to 1)
13
+ cap_type: "absolute" → cap_value is a hard upper bound in CO₂ units
14
  method_costs (dict): {method: {resource: usage_per_tCO2}}
15
 
16
  Returns:
17
  (bool, dict): (success_flag, result_dict)
18
  result_dict includes "total_removed", "method_usage"
19
  """
20
+ # Only keep active methods
21
+ methods = [m for m in method_costs if method_constraints.get(m, {}).get("active", True)]
22
  resources = list(resource_caps.keys())
23
 
24
+ if not methods:
25
+ return False, {"message": "No active methods."}
26
+
27
  # A matrix: each row is a resource, each column a method
28
  A_resource = np.array([
29
  [method_costs[m].get(r, 0.0) for m in methods]
 
31
  ])
32
  b_resource = np.array([resource_caps[r] for r in resources])
33
 
34
+ # Cap constraints per method
35
  A_share = []
36
  b_share = []
37
  for i, m in enumerate(methods):
38
+ constraint = method_constraints.get(m, {})
39
+ cap_type = constraint.get("cap_type", "percent")
40
+ cap_value = constraint.get("cap_value", 1.0)
41
+
42
+ # x_i <= cap_value
43
+ if cap_type == "absolute":
44
+ row = np.zeros(len(methods))
45
+ row[i] = 1
46
+ A_share.append(row)
47
+ b_share.append(cap_value)
48
+ # x_i <= cap_value * sum(x) → x_i - cap_value * sum(x) <= 0
49
+ else:
50
+ row = np.zeros(len(methods))
51
+ row += -cap_value
52
+ row[i] += 1
53
+ A_share.append(row)
54
+ b_share.append(0)
55
 
56
  # Combine constraints
57
  A_ub = np.vstack([A_resource, A_share])
tabs/tab0_welcome.py CHANGED
@@ -1,29 +1,29 @@
1
  import streamlit as st
2
-
3
 
4
  def render_tab():
5
- st.header("Welcome!")
6
- st.markdown("""
 
7
  This tool helps you optimize your carbon direct removal portfolio by adjusting resource usage and constraints.
8
-
9
  **Required:**
10
  1. **Resource inputs**: provide the total available quantities of resources for 1 year.
11
-
12
- **Optionnal:**
13
-
14
- 2. **Method constraints**: select which carbon removal methods are active and set their maximum portfolio share.
15
  3. **Resource efficiency coefficients**: adjust the resource usage for each method.
16
-
17
  **Outputs:**
18
-
19
- 4. **Portfolio generation**: run the optimization to find the best portfolio: how much CO2 removed, what methods are used, and in what proportions.
20
-
21
  **Explore:**
22
-
23
- 5. **Sensitivity analysis**: analyze how changes in method shares or resource availability affect the portfolio.
24
- 6. **Scenario comparison**: compare different scenarios based on the optimization results.
25
-
26
- Let's get started! Use the side tabs to navigate through the sections.
27
- """)
28
 
 
 
29
 
 
 
 
 
1
  import streamlit as st
2
+ from config.config import CO2_UNIT
3
 
4
  def render_tab():
5
+ st.markdown('<h1 class="custom-header">Welcome!</h1>', unsafe_allow_html=True)
6
+ st.markdown(f"""
7
+ <div class='custom-corps'>
8
  This tool helps you optimize your carbon direct removal portfolio by adjusting resource usage and constraints.
9
+
10
  **Required:**
11
  1. **Resource inputs**: provide the total available quantities of resources for 1 year.
12
+
13
+ **Optional:**
14
+
15
+ 2. **Method constraints**: select which carbon removal methods are active and set their **maximum deployment cap** (as % of total potential or absolute value in {CO2_UNIT}/yr).
16
  3. **Resource efficiency coefficients**: adjust the resource usage for each method.
17
+
18
  **Outputs:**
19
+
20
+ 4. **Portfolio generation**: run the optimization to find the best portfolio: how much CO₂ is removed, what methods are used, and in what proportions.
21
+
22
  **Explore:**
 
 
 
 
 
 
23
 
24
+ 5. **Sensitivity analysis**: analyze how changes in method caps or resource availability affect the portfolio.
25
+ 6. **Scenario comparison**: compare different scenarios based on the optimization results.
26
 
27
+ Let's get started! Use the side tabs to navigate through the sections.
28
+ </div>
29
+ """, unsafe_allow_html=True)
tabs/tab1_inputs.py CHANGED
@@ -14,7 +14,7 @@ def render_tab():
14
  for r in resource_order:
15
  if r not in st.session_state.resource_caps:
16
  st.session_state.resource_caps[r] = 0.0
17
- st.header("Resource inputs")
18
 
19
  st.info("""
20
  **Objective:**
@@ -22,7 +22,7 @@ def render_tab():
22
  This section lets you define the **total available quantities of each resource** for the optimization model.
23
  """)
24
 
25
- st.warning("⚠️ Resources with zero availability will block portfolio feasibility if required by active methods.")
26
 
27
  # Reset button
28
  st.markdown("### Controls")
@@ -40,6 +40,7 @@ def render_tab():
40
  col_template, col_upload = st.columns([1, 1])
41
  with col_template:
42
  st.markdown("Use the template below to fill in your resource availability values and import them directly into the tool.")
 
43
  with open("data/resource_template.xlsx", "rb") as f:
44
  st.download_button(
45
  label="Download Excel Template",
@@ -58,7 +59,7 @@ def render_tab():
58
  if uploaded_file is not None and uploaded_file.name != st.session_state.get("resource_last_loaded_file"):
59
  try:
60
  df = pd.read_excel(uploaded_file)
61
- required_cols = {"Resource", "Available Amount"}
62
  if not required_cols.issubset(df.columns):
63
  raise ValueError(f"Missing columns: {required_cols - set(df.columns)}")
64
 
 
14
  for r in resource_order:
15
  if r not in st.session_state.resource_caps:
16
  st.session_state.resource_caps[r] = 0.0
17
+ st.markdown('<h1 class="custom-header">Resource inputs</h1>', unsafe_allow_html=True)
18
 
19
  st.info("""
20
  **Objective:**
 
22
  This section lets you define the **total available quantities of each resource** for the optimization model.
23
  """)
24
 
25
+ st.warning("Resources with zero availability will block portfolio feasibility if required by active methods.", icon=":material/warning:")
26
 
27
  # Reset button
28
  st.markdown("### Controls")
 
40
  col_template, col_upload = st.columns([1, 1])
41
  with col_template:
42
  st.markdown("Use the template below to fill in your resource availability values and import them directly into the tool.")
43
+ st.warning("The change of unit in the template will not be taken into account.", icon=":material/warning:")
44
  with open("data/resource_template.xlsx", "rb") as f:
45
  st.download_button(
46
  label="Download Excel Template",
 
59
  if uploaded_file is not None and uploaded_file.name != st.session_state.get("resource_last_loaded_file"):
60
  try:
61
  df = pd.read_excel(uploaded_file)
62
+ required_cols = {"Resource", "Unit", "Available Amount"}
63
  if not required_cols.issubset(df.columns):
64
  raise ValueError(f"Missing columns: {required_cols - set(df.columns)}")
65
 
tabs/tab2_constraints.py CHANGED
@@ -3,95 +3,136 @@
3
  import pandas as pd
4
  import streamlit as st
5
 
6
- from config.config import method_groups, method_order, method_tooltips
7
- from utils.ui_helpers import format_method_summary
8
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  def render_tab():
11
- st.header("Method constraints")
12
-
13
  st.info("""
14
  **Objective:**
15
 
16
  This section lets you control which CDR methods are included in the optimization
17
- and assign their **maximum portfolio share**.
18
-
19
- - Activate or deactivate individual methods
20
- - Set each method's **max share** (as % of the total portfolio)
21
- """)
22
 
23
- # UI controls
24
- with st.expander("⚙️ Manage methods (Open/Close)", expanded=False):
25
- st.subheader("Activate/deactivate methods and set max allocation")
26
 
 
27
  for group, method_list in method_groups.items():
28
  st.markdown(f"#### {group}")
29
  cols = st.columns(3)
30
-
31
  for i, m in enumerate(method_list):
32
- with cols[i % 3]:
33
- toggle_key = f"toggle_{m}"
34
- slider_key = f"slider_{m}_widget"
35
- tooltip = method_tooltips.get(m, None)
36
-
37
- # Set default slider value only on first render
38
- if slider_key not in st.session_state:
39
- st.session_state[slider_key] = int(st.session_state.constraints[m]["max_share"] * 100)
40
-
41
- # Toggle
42
- is_active = st.toggle(
43
- m,
44
- value=st.session_state.constraints[m]["active"],
45
- key=toggle_key,
46
- help=tooltip
47
- )
48
-
49
- if is_active:
50
- share_val = st.slider(
51
- "Max share (%)",
52
- min_value=0,
53
- max_value=100,
54
- step=5,
55
- key=slider_key
56
- )
57
- st.session_state.constraints[m] = {
58
- "active": True,
59
- "max_share": share_val / 100
60
- }
61
-
62
- if share_val == 0:
63
- st.warning("Max share is 0% but method is active", icon="⚠️")
64
- else:
65
- st.session_state.constraints[m] = {
66
- "active": False,
67
- "max_share": 0.0
68
- }
69
-
70
- # Reset all constraints
71
  st.divider()
72
  if st.button("🔄 Reset All Method Constraints"):
73
- for m in method_order:
74
- st.session_state.constraints[m] = {"active": True, "max_share": 1.0}
75
- slider_key = f"slider_{m}_widget"
76
- if slider_key in st.session_state:
77
- del st.session_state[slider_key]
78
- st.success("All method constraints reset to default.")
79
- st.rerun()
80
-
81
- # Summary table
82
- st.subheader("Summary table: Active methods in the model")
83
-
84
- active_methods_summary = {
85
- m: int(st.session_state.constraints[m]["max_share"] * 100)
86
- for m in method_order if st.session_state.constraints[m]["active"]
87
- }
88
-
89
- if active_methods_summary:
90
- df_methods = pd.DataFrame.from_dict(
91
- active_methods_summary, orient="index", columns=["Max allocation (%)"]
92
- ).reindex(method_order).dropna()
93
-
94
- styled = format_method_summary(df_methods)
95
- st.table(styled)
96
  else:
97
- st.warning("No active methods selected.")
 
3
  import pandas as pd
4
  import streamlit as st
5
 
6
+ from config.config import CO2_UNIT, method_groups, method_order, method_tooltips
7
+ from utils.ui_helpers import format_table_summary
8
+
9
+
10
+ # ─── Helpers ─────────────────────────────────────────────────────────────────
11
+
12
+ def default_constraint():
13
+ return {"active": True, "cap_type": "percent", "cap_value": 1.0}
14
+
15
+
16
+ def render_method(m, cols, i):
17
+ with cols[i % 3]:
18
+ tooltip = method_tooltips.get(m, None)
19
+ constraint = st.session_state.constraints[m]
20
+
21
+ if f"toggle_type_{m}" not in st.session_state:
22
+ st.session_state[f"toggle_type_{m}"] = constraint.get("active", True)
23
+
24
+ is_active = st.toggle(m, key=f"toggle_type_{m}", help=tooltip)
25
+
26
+ if not is_active:
27
+ st.session_state.constraints[m] = {
28
+ "active": False,
29
+ "cap_type": constraint.get("cap_type", "percent"),
30
+ "cap_value": constraint.get("cap_value", 1.0),
31
+ }
32
+ return
33
+
34
+ cap_type_index = 0 if constraint.get("cap_type", "percent") == "percent" else 1
35
+ cap_type = st.radio(
36
+ "Cap value type",
37
+ label_visibility="collapsed",
38
+ options=["percent", "absolute"],
39
+ index=cap_type_index,
40
+ horizontal=True,
41
+ key=f"cap_type_{m}",
42
+ format_func=lambda x: "% of total potential" if x == "percent" else f"Absolute ({CO2_UNIT}/yr)",
43
+ )
44
+
45
+ if cap_type == "percent":
46
+ if constraint.get("cap_type") == "percent" and constraint.get("cap_value", 0) > 0:
47
+ current_pct = int(constraint["cap_value"] * 100)
48
+ else:
49
+ current_pct = 100
50
+
51
+ share_val = st.slider(
52
+ "Max share (%)", min_value=0, max_value=100, step=5,
53
+ value=current_pct,
54
+ key=f"slider_{m}_widget",
55
+ )
56
+ st.session_state.constraints[m] = {
57
+ "active": True,
58
+ "cap_type": "percent",
59
+ "cap_value": share_val / 100,
60
+ }
61
+ if share_val == 0:
62
+ st.warning("Cap is 0% but method is active.", icon="⚠️")
63
+
64
+ else:
65
+ if constraint.get("cap_type") == "absolute":
66
+ current_abs = float(constraint.get("cap_value") or 0.0)
67
+ else:
68
+ current_abs = 0.0
69
+
70
+ abs_val = st.number_input(
71
+ f"Max cap ({CO2_UNIT}/yr)",
72
+ min_value=0.0,
73
+ format="%.2f",
74
+ value=current_abs,
75
+ key=f"manual_{m}_widget",
76
+ )
77
+ st.session_state.constraints[m] = {
78
+ "active": True,
79
+ "cap_type": "absolute",
80
+ "cap_value": abs_val,
81
+ }
82
+ if abs_val == 0:
83
+ st.warning(f"Cap is 0 {CO2_UNIT}/yr but method is active.", icon="⚠️")
84
+
85
+ def reset_all_constraints():
86
+ for m in method_order:
87
+ st.session_state.constraints[m] = default_constraint()
88
+ for key in [f"toggle_type_{m}", f"cap_type_{m}", f"slider_{m}_widget", f"manual_{m}_widget"]:
89
+ st.session_state.pop(key, None)
90
+ st.success("All method constraints reset to default.")
91
+ st.rerun()
92
+
93
+
94
+ def build_summary_df():
95
+ """Build summary dataframe for active methods."""
96
+ rows = {}
97
+ for m in method_order:
98
+ c = st.session_state.constraints[m]
99
+ if not c["active"]:
100
+ continue
101
+ if c["cap_type"] == "percent":
102
+ rows[m] = {"Cap value": f"{int(c['cap_value'] * 100)}", "Unit": "%"}
103
+ else:
104
+ rows[m] = {"Cap value": f"{c['cap_value']:,.2f}", "Unit": f"{CO2_UNIT}/yr"}
105
+ return pd.DataFrame.from_dict(rows, orient="index") if rows else None
106
+
107
+
108
+ # ─── Main render ─────────────────────────────────────────────────────────────
109
 
110
  def render_tab():
111
+ st.markdown('<h1 class="custom-header">Method constraints</h1>', unsafe_allow_html=True)
 
112
  st.info("""
113
  **Objective:**
114
 
115
  This section lets you control which CDR methods are included in the optimization
116
+ and set a **maximum deployment cap** per method.
 
 
 
 
117
 
118
+ - Activate or deactivate individual methods
119
+ - Cap each method by **% of its total potential** or by an **absolute value** in {CO2_UNIT}/yr
120
+ """.format(CO2_UNIT=CO2_UNIT))
121
 
122
+ with st.expander("⚙️ Manage methods", expanded=False):
123
  for group, method_list in method_groups.items():
124
  st.markdown(f"#### {group}")
125
  cols = st.columns(3)
 
126
  for i, m in enumerate(method_list):
127
+ render_method(m, cols, i)
128
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  st.divider()
130
  if st.button("🔄 Reset All Method Constraints"):
131
+ reset_all_constraints()
132
+
133
+ st.subheader("Summary — Active methods and caps")
134
+ df = build_summary_df()
135
+ if df is not None:
136
+ st.markdown(format_table_summary(df,"cdr-table"), unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  else:
138
+ st.warning("No active methods selected.")
tabs/tab3_coefficients.py CHANGED
@@ -2,14 +2,32 @@ import pandas as pd
2
  import streamlit as st
3
 
4
  from config.config import (method_groups, method_order, resource_groups,
5
- resource_order, secondary_resources)
6
  from utils.ui_helpers import format_efficiency_summary
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
 
9
  def render_tab(cost_sliders):
10
  st.header("Resource efficiency coefficients")
11
 
12
- # === Info ===
13
  st.info("""
14
  **Objective:**
15
 
@@ -21,7 +39,21 @@ def render_tab(cost_sliders):
21
  """)
22
  st.warning("Blue cells in the table highlight coefficients modified from their **default median values**.")
23
 
24
- # === Method selector ===
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  method_choices = []
26
  method_lookup = {}
27
  for group, methods in method_groups.items():
@@ -31,66 +63,56 @@ def render_tab(cost_sliders):
31
  method_lookup[label] = method
32
 
33
  selected_label = st.selectbox("Select a method:", method_choices)
34
- method_selected = method_lookup[selected_label]
 
 
 
 
 
35
 
36
- # === Resource sliders ===
37
- with st.expander(f"Manage resources for the {method_selected} method", expanded=True):
38
  for group_name, rlist in resource_groups.items():
39
- used = [r for r in rlist if r in cost_sliders[method_selected]]
40
  if not used:
41
  continue
42
 
43
  st.markdown(f"### {group_name}")
 
44
  for r in used:
45
- conf = cost_sliders[method_selected][r]
46
- default_val = conf["median"]
47
- min_val = conf["min"]
48
- max_val = conf["max"]
49
-
50
- if min_val < 0.01:
51
- step = 0.0001
52
- fmt = "%.4f"
53
- elif min_val < 1:
54
- step = 0.001
55
- fmt = "%.3f"
56
- elif min_val < 100:
57
- step = 0.01
58
- fmt = "%.2f"
59
- else:
60
- step = 1.0
61
- fmt = "%.0f"
62
-
63
- is_secondary = (method_selected, r) in secondary_resources
64
- toggle_key = f"toggle_{method_selected}_{r}".replace(" ", "_").lower()
65
 
66
  if is_secondary:
67
  if toggle_key not in st.session_state:
68
- st.session_state[toggle_key] = st.session_state.costs[method_selected][r] != 0.0
69
- enabled = st.checkbox(f"Use {r}", key=toggle_key)
70
-
71
  if not enabled:
72
- st.session_state.costs[method_selected][r] = 0.0
73
  st.markdown("**DISABLED**")
74
  continue
75
- elif st.session_state.costs[method_selected][r] == 0.0:
76
- st.session_state.costs[method_selected][r] = default_val
77
-
78
- # Sliders and inputs
79
- slider_key = f"slider_{method_selected}_{r}".replace(" ", "_").lower()
80
- manual_key = f"manual_{method_selected}_{r}".replace(" ", "_").lower()
81
 
82
  if slider_key not in st.session_state:
83
- st.session_state[slider_key] = st.session_state.costs[method_selected][r]
84
 
85
  col1, col2 = st.columns([3, 1])
86
  with col1:
87
  slider_val = st.slider(
88
- label=r,
89
- min_value=min_val,
90
- max_value=max_val,
91
  step=step,
92
  format=fmt,
93
- key=slider_key
94
  )
95
  with col2:
96
  manual_val = st.number_input(
@@ -99,60 +121,60 @@ def render_tab(cost_sliders):
99
  value=slider_val,
100
  key=manual_key,
101
  help="Manual override (optional, any value)",
102
- format=fmt
103
  )
104
 
105
- final_val = manual_val if manual_val != slider_val else slider_val
106
- st.session_state.costs[method_selected][r] = final_val
107
 
108
- # === Reset buttons ===
109
  col1, col2 = st.columns(2)
110
  with col1:
111
  if st.button("🔄 Reset selected method"):
112
- for r in cost_sliders[method_selected]:
113
- is_secondary = (method_selected, r) in secondary_resources
114
- st.session_state.costs[method_selected][r] = 0.0 if is_secondary else cost_sliders[method_selected][r]["median"]
115
- for suffix in ["slider", "manual", "toggle"]:
116
- key = f"{suffix}_{method_selected}_{r}".replace(" ", "_").lower()
117
- if key in st.session_state:
118
- del st.session_state[key]
119
- st.success(f"{method_selected} reset to default values.")
120
  st.rerun()
121
 
122
  with col2:
123
  if st.button("🔄 Reset all methods"):
124
- for m in method_order:
125
- for r in cost_sliders.get(m, {}):
126
  is_secondary = (m, r) in secondary_resources
127
- st.session_state.costs[m][r] = 0.0 if is_secondary else cost_sliders[m][r]["median"]
128
- for suffix in ["slider", "manual", "toggle"]:
129
- key = f"{suffix}_{m}_{r}".replace(" ", "_").lower()
130
- if key in st.session_state:
131
- del st.session_state[key]
132
  st.success("All methods reset to default values.")
133
  st.rerun()
134
 
135
- # === Summary table ===
136
  st.subheader("Summary table: resource usage coefficients in the model")
137
 
138
  df_default = pd.DataFrame(index=method_order, columns=resource_order)
139
  df_current = pd.DataFrame(index=method_order, columns=resource_order)
140
 
141
  for m in method_order:
 
 
 
142
  for r in resource_order:
143
  is_secondary = (m, r) in secondary_resources
144
- current_val = st.session_state.costs.get(m, {}).get(r, 0.0)
145
-
146
- if is_secondary:
147
- default_val = cost_sliders.get(m, {}).get(r, {}).get("median", 0.0) if current_val != 0.0 else 0.0
148
- else:
149
- default_val = cost_sliders.get(m, {}).get(r, {}).get("median", 0.0)
150
-
151
  df_default.at[m, r] = default_val
152
  df_current.at[m, r] = current_val
153
 
154
  df_default = df_default.astype(float)
155
  df_current = df_current.astype(float)
156
 
 
 
 
157
  styled = format_efficiency_summary(df_current, df_default)
158
- st.table(styled)
 
2
  import streamlit as st
3
 
4
  from config.config import (method_groups, method_order, resource_groups,
5
+ resource_order, secondary_resources, resource_unit_map, CO2_UNIT)
6
  from utils.ui_helpers import format_efficiency_summary
7
+ from utils.data_utils import strip_unit_suffix
8
+
9
+
10
+ def _normalize_costs(costs_dict: dict) -> dict:
11
+ """Strip unit suffixes from resource keys for legacy scenario compatibility."""
12
+ return {strip_unit_suffix(r): v for r, v in costs_dict.items()}
13
+
14
+
15
+ def _get_slider_params(conf: dict) -> tuple:
16
+ """Return (step, fmt) based on the min value of a slider config."""
17
+ min_val = conf["min"]
18
+ if min_val < 0.01:
19
+ return 0.0001, "%.4f"
20
+ elif min_val < 1:
21
+ return 0.001, "%.3f"
22
+ elif min_val < 100:
23
+ return 0.01, "%.2f"
24
+ else:
25
+ return 1.0, "%.0f"
26
 
27
 
28
  def render_tab(cost_sliders):
29
  st.header("Resource efficiency coefficients")
30
 
 
31
  st.info("""
32
  **Objective:**
33
 
 
39
  """)
40
  st.warning("Blue cells in the table highlight coefficients modified from their **default median values**.")
41
 
42
+ # Normalize cost_sliders once: strip unit suffixes from resource keys
43
+ # cost_sliders_norm[method][resource_name] = {min, median, max}
44
+ cost_sliders_norm = {
45
+ m: _normalize_costs(resources)
46
+ for m, resources in cost_sliders.items()
47
+ }
48
+
49
+ # Build resource display labels: "Arable land" -> "Arable land (Mha/MtCO2)"
50
+ resource_display = {
51
+ r: f"{r} ({resource_unit_map[cat]}/{CO2_UNIT})"
52
+ for cat, resources in resource_groups.items()
53
+ for r in resources
54
+ }
55
+
56
+ # ── Method selector ──────────────────────────────────────────────────────
57
  method_choices = []
58
  method_lookup = {}
59
  for group, methods in method_groups.items():
 
63
  method_lookup[label] = method
64
 
65
  selected_label = st.selectbox("Select a method:", method_choices)
66
+ method = method_lookup[selected_label]
67
+
68
+ # ── Resource sliders ─────────────────────────────────────────────────────
69
+ with st.expander(f"Manage resources for **{method}**", expanded=True):
70
+ method_sliders = cost_sliders_norm.get(method, {})
71
+ method_costs_norm = _normalize_costs(st.session_state.costs.get(method, {}))
72
 
 
 
73
  for group_name, rlist in resource_groups.items():
74
+ used = [r for r in rlist if r in method_sliders]
75
  if not used:
76
  continue
77
 
78
  st.markdown(f"### {group_name}")
79
+
80
  for r in used:
81
+ conf = method_sliders[r]
82
+ display_label = resource_display.get(r, r)
83
+ step, fmt = _get_slider_params(conf)
84
+ is_secondary = (method, r) in secondary_resources
85
+
86
+ toggle_key = f"toggle_{method}_{r}".replace(" ", "_").lower()
87
+ slider_key = f"slider_{method}_{r}".replace(" ", "_").lower()
88
+ manual_key = f"manual_{method}_{r}".replace(" ", "_").lower()
89
+
90
+ current_val = method_costs_norm.get(r, 0.0)
 
 
 
 
 
 
 
 
 
 
91
 
92
  if is_secondary:
93
  if toggle_key not in st.session_state:
94
+ st.session_state[toggle_key] = current_val != 0.0
95
+ enabled = st.checkbox(f"Use {display_label}", key=toggle_key)
 
96
  if not enabled:
97
+ st.session_state.costs[method][r] = 0.0
98
  st.markdown("**DISABLED**")
99
  continue
100
+ elif current_val == 0.0:
101
+ st.session_state.costs[method][r] = conf["median"]
102
+ current_val = conf["median"]
 
 
 
103
 
104
  if slider_key not in st.session_state:
105
+ st.session_state[slider_key] = current_val
106
 
107
  col1, col2 = st.columns([3, 1])
108
  with col1:
109
  slider_val = st.slider(
110
+ label=display_label,
111
+ min_value=conf["min"],
112
+ max_value=conf["max"],
113
  step=step,
114
  format=fmt,
115
+ key=slider_key,
116
  )
117
  with col2:
118
  manual_val = st.number_input(
 
121
  value=slider_val,
122
  key=manual_key,
123
  help="Manual override (optional, any value)",
124
+ format=fmt,
125
  )
126
 
127
+ st.session_state.costs[method][r] = manual_val if manual_val != slider_val else slider_val
 
128
 
129
+ # ── Reset buttons ────────────────────────────────────────────────────
130
  col1, col2 = st.columns(2)
131
  with col1:
132
  if st.button("🔄 Reset selected method"):
133
+ for r, conf in cost_sliders_norm.get(method, {}).items():
134
+ is_secondary = (method, r) in secondary_resources
135
+ st.session_state.costs[method][r] = 0.0 if is_secondary else conf["median"]
136
+ for prefix in ["slider", "manual", "toggle"]:
137
+ st.session_state.pop(f"{prefix}_{method}_{r}".replace(" ", "_").lower(), None)
138
+ st.success(f"{method} reset to default values.")
 
 
139
  st.rerun()
140
 
141
  with col2:
142
  if st.button("🔄 Reset all methods"):
143
+ for m, sliders in cost_sliders_norm.items():
144
+ for r, conf in sliders.items():
145
  is_secondary = (m, r) in secondary_resources
146
+ st.session_state.costs[m][r] = 0.0 if is_secondary else conf["median"]
147
+ for prefix in ["slider", "manual", "toggle"]:
148
+ st.session_state.pop(f"{prefix}_{m}_{r}".replace(" ", "_").lower(), None)
 
 
149
  st.success("All methods reset to default values.")
150
  st.rerun()
151
 
152
+ # ── Summary table ─────────────────────────────────────────────────────────
153
  st.subheader("Summary table: resource usage coefficients in the model")
154
 
155
  df_default = pd.DataFrame(index=method_order, columns=resource_order)
156
  df_current = pd.DataFrame(index=method_order, columns=resource_order)
157
 
158
  for m in method_order:
159
+ current_costs = _normalize_costs(st.session_state.costs.get(m, {}))
160
+ sliders = cost_sliders_norm.get(m, {})
161
+
162
  for r in resource_order:
163
  is_secondary = (m, r) in secondary_resources
164
+ current_val = current_costs.get(r, 0.0)
165
+ default_val = sliders.get(r, {}).get("median", 0.0)
166
+
167
+ if is_secondary and current_val == 0.0:
168
+ default_val = 0.0
169
+
 
170
  df_default.at[m, r] = default_val
171
  df_current.at[m, r] = current_val
172
 
173
  df_default = df_default.astype(float)
174
  df_current = df_current.astype(float)
175
 
176
+ df_default = df_default.rename(columns=resource_display)
177
+ df_current = df_current.rename(columns=resource_display)
178
+
179
  styled = format_efficiency_summary(df_current, df_default)
180
+ st.table(styled)
tabs/tab4_optimization.py CHANGED
@@ -1,5 +1,7 @@
 
1
  import io
2
  import json
 
3
  import unicodedata
4
  import zipfile
5
  import openpyxl
@@ -10,10 +12,10 @@ import seaborn as sns
10
  import streamlit as st
11
  import plotly.graph_objects as go
12
 
13
- from config.config import method_order, resource_order, resource_units, secondary_resources
14
  from optimization.optimization import run_optimization
15
- from utils.ui_helpers import format_results_summary
16
- from utils.data_utils import is_valid_scenario, load_inputs_from_excel
17
 
18
 
19
  # ─── Input panels ────────────────────────────────────────────────────────────
@@ -35,7 +37,7 @@ def panel_load_from_excel():
35
  with col_upload:
36
  with open("data/inputs_template.xlsx", "rb") as f:
37
  st.download_button(
38
- label="Download Excel Template",
39
  data=f,
40
  file_name="crra_input_template.xlsx",
41
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@@ -76,10 +78,11 @@ def panel_load_from_excel():
76
 
77
  def parse_zip_scenario(uploaded) -> dict | None:
78
  """Reconstruct a scenario dict from a ZIP containing the 4 CSVs."""
 
79
  try:
80
  with zipfile.ZipFile(io.BytesIO(uploaded.read())) as zf:
81
  names = zf.namelist()
82
-
83
  def _read(fname):
84
  return pd.read_csv(io.BytesIO(zf.read(fname)), index_col=0)
85
 
@@ -88,20 +91,48 @@ def parse_zip_scenario(uploaded) -> dict | None:
88
  if not required.issubset(names):
89
  return None
90
 
91
- resource_caps = _read("resource_caps.csv")["Available Amount"].to_dict()
92
-
 
93
  df_c = _read("method_constraints.csv")
94
- constraints = {
95
- m: {"active": bool(row["active"]), "max_share": float(row["max_share"])}
96
- for m, row in df_c.iterrows()
97
- }
98
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  df_costs = _read("method_costs.csv") # index=method, columns=resources
 
100
  costs = {m: row.dropna().to_dict() for m, row in df_costs.iterrows()}
101
-
102
- allocations = _read("allocations.csv")["tCO₂ removed"].to_dict()
 
 
 
 
 
 
 
 
 
 
103
  total = sum(allocations.values())
104
-
105
  return {
106
  "summary": {"total_co2_removed": total, "total_cost": 0},
107
  "allocations": allocations,
@@ -193,7 +224,7 @@ def run_and_store_result():
193
  total_removed = result["total_removed"]
194
 
195
  if total_removed <= 0:
196
- st.warning("❌ Optimization removed 0 tCO₂. Relax constraints or increase resources.")
197
  return
198
 
199
  total_cost = sum(
@@ -207,30 +238,42 @@ def run_and_store_result():
207
  "method_constraints": st.session_state.constraints,
208
  "method_costs": st.session_state.costs,
209
  }
210
- st.success(f"✅ {total_removed:,.0f} tCO₂ removed")
211
 
212
 
213
  # ─── Results display ─────────────────────────────────────────────────────────
214
 
215
  def show_metrics(latest):
216
  col1, col2 = st.columns(2)
217
- col1.metric("Total CO₂ Removed", f"{latest['summary']['total_co2_removed']:,.0f} t")
218
  col2.metric("Methods Used", len(latest["allocations"]))
219
 
220
 
221
- def build_results_df(allocations):
222
- df = pd.DataFrame.from_dict(allocations, orient="index", columns=["tCO₂ removed"])
223
- df["tCO₂ removed"] = pd.to_numeric(df["tCO₂ removed"], errors="coerce")
224
- total = df["tCO₂ removed"].sum()
225
  if total > 0:
226
- df["Share (%)"] = (df["tCO₂ removed"] / total * 100).round(2)
227
- return df.sort_values("tCO₂ removed", ascending=False)
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
 
230
  def show_donut(df_result):
231
  fig = go.Figure(data=[go.Pie(
232
  labels=df_result.index.tolist(),
233
- values=df_result["tCO₂ removed"].tolist(),
234
  hole=0.4,
235
  textinfo="label+percent",
236
  textposition="outside",
@@ -242,11 +285,17 @@ def show_donut(df_result):
242
 
243
 
244
  def show_heatmap(df_result, resource_caps, method_costs):
 
 
 
 
 
 
245
  available = [r for r in resource_order if resource_caps.get(r, 0) > 0]
246
  matrix, y_labels = [], []
247
  for method in df_result.index:
248
  row = [
249
- (method_costs.get(method, {}).get(r, 0.0) * df_result.at[method, "tCO₂ removed"]
250
  / resource_caps[r] * 100) if resource_caps[r] > 0 else 0
251
  for r in available
252
  ]
@@ -264,15 +313,27 @@ def show_heatmap(df_result, resource_caps, method_costs):
264
  )
265
  st.plotly_chart(fig, use_container_width=True)
266
 
267
-
268
  def show_absolute_usage(allocations, method_costs):
269
- rows = [
270
- {"Method": m, "Resource": r, "Used": method_costs[m][r] * co2, "Unit": unit}
271
- for m, co2 in allocations.items()
272
- for unit, resources in resource_units.items()
273
- for r in resources
274
- if r in method_costs.get(m, {}) and method_costs[m][r] * co2 > 0
275
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  if not rows:
277
  return
278
 
@@ -295,15 +356,18 @@ def save_scenario(latest):
295
  st.caption("Save the current scenario with inputs and outputs for comparison and/or export.")
296
 
297
  suggested = st.session_state.get("scenario_loaded_file", "").rsplit(".", 1)[0]
298
- current = st.session_state.get("scenario_name", "").strip()
 
 
 
299
 
300
  col_name, col_btn = st.columns([3, 1])
301
  with col_name:
302
  st.text_input(
303
- "Scenario name", key="scenario_name",
304
- value=current or suggested,
305
  label_visibility="collapsed",
306
- placeholder="Enter a scenario name"
307
  )
308
  with col_btn:
309
  if st.button("Save", use_container_width=True, icon=":material/save:"):
@@ -323,8 +387,9 @@ def export_scenario():
323
 
324
  scenario = st.session_state.scenarios[name]
325
  st.markdown(f"#### Scenario: {name}")
326
- df_saved = build_results_df(scenario["allocations"])
327
- st.table(format_results_summary(df_saved))
 
328
 
329
  safe = unicodedata.normalize("NFKD", name).encode("ascii", "ignore").decode("ascii")
330
  col_json, col_csv = st.columns(2)
@@ -343,13 +408,12 @@ def export_scenario():
343
  pd.DataFrame.from_dict(scenario["resource_caps"], orient="index",
344
  columns=["Available Amount"]).to_csv())
345
  zf.writestr("method_constraints.csv",
346
- pd.DataFrame.from_dict(scenario["method_constraints"], orient="index",
347
- columns=["active", "max_share"]).to_csv())
348
- zf.writestr("method_costs.csv", # ← nouveau
349
  pd.DataFrame.from_dict(scenario["method_costs"], orient="index").to_csv())
350
  zf.writestr("allocations.csv",
351
  pd.DataFrame.from_dict(scenario["allocations"], orient="index",
352
- columns=["tCO₂ removed"]).to_csv())
353
  with col_csv:
354
  st.download_button(
355
  "Export CSV (zip)", data=buf.getvalue(),
@@ -359,50 +423,66 @@ def export_scenario():
359
  )
360
 
361
  def export_inputs_only():
 
 
 
 
 
362
  st.markdown("### Export inputs")
363
  st.caption("Export only the resource capabilities, method constraints and coefficients — without results.")
364
 
365
  suggested = st.session_state.get("excel_loaded_file", "").rsplit(".", 1)[0]
366
-
367
- col_text, col_button = st.columns([3,1])
 
 
 
 
368
  with col_text:
369
  st.text_input(
370
- "File name", label_visibility="collapsed", key="input_file_name",
371
- value=suggested,
 
372
  placeholder="Enter a file name",
373
  )
 
 
374
 
375
- wb = openpyxl.Workbook()
376
- ws1 = wb.active
377
- ws1.title = "resource_caps"
378
- ws1.append(["Resource", "Available Amount"])
379
- for r, v in st.session_state.resource_caps.items():
380
- ws1.append([r, v])
381
 
382
- ws2 = wb.create_sheet("constraints")
383
- ws2.append(["method", "active", "max_share"])
384
- for m, c in st.session_state.constraints.items():
385
- ws2.append([m, c.get("active", True), c.get("max_share", 1.0)])
 
 
386
 
387
- ws3 = wb.create_sheet("coefficients")
388
- ws3.append(["method", "resource", "value", "secondary"])
389
- for m, resources in st.session_state.costs.items():
390
- for r, v in resources.items():
391
- ws3.append([m, r, v, (m, r) in secondary_resources])
392
 
393
- buf = io.BytesIO()
394
- wb.save(buf)
395
- buf.seek(0)
 
 
396
 
397
- safe = st.session_state.get("input_file_name", "").strip() or suggested or "crra_inputs"
398
- with col_button:
 
 
 
 
 
399
  st.download_button(
400
- f"Export Excel",
401
- data=buf,
402
- file_name=f"{safe}.xlsx",
403
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
404
- icon=":material/download:",
405
- use_container_width=True
406
  )
407
 
408
  def clear_all_data():
@@ -485,10 +565,11 @@ def render_tab():
485
 
486
  # ── Results ────────────────────────────────────────────────────────────
487
  show_metrics(latest)
488
- df_result = build_results_df(allocations)
489
 
490
  st.subheader("Optimization Summary")
491
- st.table(format_results_summary(df_result))
 
492
 
493
  st.markdown("### Method allocation breakdown")
494
  show_donut(df_result)
 
1
+ from collections import defaultdict
2
  import io
3
  import json
4
+ import re
5
  import unicodedata
6
  import zipfile
7
  import openpyxl
 
12
  import streamlit as st
13
  import plotly.graph_objects as go
14
 
15
+ from config.config import method_order, resource_order, resource_unit_map, resource_groups, secondary_resources, CO2_UNIT
16
  from optimization.optimization import run_optimization
17
+ from utils.ui_helpers import format_table_summary
18
+ from utils.data_utils import is_valid_scenario, load_inputs_from_excel, strip_unit_suffix
19
 
20
 
21
  # ─── Input panels ────────────────────────────────────────────────────────────
 
37
  with col_upload:
38
  with open("data/inputs_template.xlsx", "rb") as f:
39
  st.download_button(
40
+ label="Excel Template",
41
  data=f,
42
  file_name="crra_input_template.xlsx",
43
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
 
78
 
79
  def parse_zip_scenario(uploaded) -> dict | None:
80
  """Reconstruct a scenario dict from a ZIP containing the 4 CSVs."""
81
+
82
  try:
83
  with zipfile.ZipFile(io.BytesIO(uploaded.read())) as zf:
84
  names = zf.namelist()
85
+
86
  def _read(fname):
87
  return pd.read_csv(io.BytesIO(zf.read(fname)), index_col=0)
88
 
 
91
  if not required.issubset(names):
92
  return None
93
 
94
+ resource_caps_raw = _read("resource_caps.csv")["Available Amount"].to_dict()
95
+ resource_caps = {strip_unit_suffix(k): v for k, v in resource_caps_raw.items()}
96
+
97
  df_c = _read("method_constraints.csv")
98
+
99
+ # Compatibility with older files that used `max_share`
100
+ if "cap_type (percent or absolute)" in df_c.columns:
101
+ constraints = {
102
+ m: {
103
+ "active": bool(row["active"]),
104
+ "cap_type": str(row["cap_type (percent or absolute)"]),
105
+ "cap_value": float(row["cap_value"])
106
+ }
107
+ for m, row in df_c.iterrows()
108
+ }
109
+ else:
110
+ constraints = {
111
+ m: {
112
+ "active": bool(row["active"]),
113
+ "cap_type": "percent",
114
+ "cap_value": float(row["max_share"])
115
+ }
116
+ for m, row in df_c.iterrows()
117
+ }
118
+
119
  df_costs = _read("method_costs.csv") # index=method, columns=resources
120
+
121
  costs = {m: row.dropna().to_dict() for m, row in df_costs.iterrows()}
122
+
123
+ df = _read("allocations.csv")
124
+ col = f"{CO2_UNIT} removed"
125
+ if col not in df.columns:
126
+ old_col = "tCO₂ removed"
127
+ if old_col in df.columns:
128
+ df[col] = df[old_col] / 1_000_000 # convert tCO2 → MtCO2
129
+ else:
130
+ raise ValueError(f"Column '{col}' not found. Available: {list(df.columns)}")
131
+
132
+ allocations = df[col].to_dict()
133
+
134
  total = sum(allocations.values())
135
+
136
  return {
137
  "summary": {"total_co2_removed": total, "total_cost": 0},
138
  "allocations": allocations,
 
224
  total_removed = result["total_removed"]
225
 
226
  if total_removed <= 0:
227
+ st.warning(f"❌ Optimization removed 0 {CO2_UNIT}. Relax constraints or increase resources.")
228
  return
229
 
230
  total_cost = sum(
 
238
  "method_constraints": st.session_state.constraints,
239
  "method_costs": st.session_state.costs,
240
  }
241
+ st.success(f"✅ {total_removed:,.0f} {CO2_UNIT} removed")
242
 
243
 
244
  # ─── Results display ─────────────────────────────────────────────────────────
245
 
246
  def show_metrics(latest):
247
  col1, col2 = st.columns(2)
248
+ col1.metric("Total CO₂ Removed", f"{latest['summary']['total_co2_removed']:,.0f} {CO2_UNIT}")
249
  col2.metric("Methods Used", len(latest["allocations"]))
250
 
251
 
252
+ def build_results_df(allocations, method_constraints=None):
253
+ df = pd.DataFrame.from_dict(allocations, orient="index", columns=[f"{CO2_UNIT} removed"])
254
+ df[f"{CO2_UNIT} removed"] = pd.to_numeric(df[f"{CO2_UNIT} removed"], errors="coerce")
255
+ total = df[f"{CO2_UNIT} removed"].sum()
256
  if total > 0:
257
+ df["Share (%)"] = (df[f"{CO2_UNIT} removed"] / total * 100).round(2)
258
+
259
+ if method_constraints:
260
+ caps = {}
261
+ for m in df.index:
262
+ c = method_constraints.get(m, {})
263
+
264
+ if c.get("cap_type") == "absolute":
265
+ caps[m] = f"{c['cap_value']:,.2f} {CO2_UNIT}/yr"
266
+ else:
267
+ caps[m] = f"{int(c.get('cap_value', 1.0) * 100)}% of potential"
268
+ df["Cap"] = pd.Series(caps)
269
+
270
+ return df.sort_values(f"{CO2_UNIT} removed", ascending=False)
271
 
272
 
273
  def show_donut(df_result):
274
  fig = go.Figure(data=[go.Pie(
275
  labels=df_result.index.tolist(),
276
+ values=df_result[f"{CO2_UNIT} removed"].tolist(),
277
  hole=0.4,
278
  textinfo="label+percent",
279
  textposition="outside",
 
285
 
286
 
287
  def show_heatmap(df_result, resource_caps, method_costs):
288
+ # Normalize method_costs keys for legacy scenarios
289
+ normalized_costs = {
290
+ m: {strip_unit_suffix(r): v for r, v in resources.items()}
291
+ for m, resources in method_costs.items()
292
+ }
293
+
294
  available = [r for r in resource_order if resource_caps.get(r, 0) > 0]
295
  matrix, y_labels = [], []
296
  for method in df_result.index:
297
  row = [
298
+ (normalized_costs.get(method, {}).get(r, 0.0) * df_result.at[method, f"{CO2_UNIT} removed"]
299
  / resource_caps[r] * 100) if resource_caps[r] > 0 else 0
300
  for r in available
301
  ]
 
313
  )
314
  st.plotly_chart(fig, use_container_width=True)
315
 
 
316
  def show_absolute_usage(allocations, method_costs):
317
+ # Normalize method_costs keys: strip legacy unit suffixes
318
+ normalized_costs = {
319
+ m: {strip_unit_suffix(r): v for r, v in resources.items()}
320
+ for m, resources in method_costs.items()
321
+ }
322
+
323
+ # Build resource_units locally to avoid the overwrite bug when multiple categories share the same unit
324
+ _resource_units = defaultdict(list)
325
+ for cat, resources in resource_groups.items():
326
+ unit_key = f"{resource_unit_map[cat]}/MtCO2"
327
+ _resource_units[unit_key].extend(resources)
328
+ local_resource_units = dict(_resource_units)
329
+
330
+ rows = []
331
+ for m, co2 in allocations.items():
332
+ for unit, resources in local_resource_units.items():
333
+ for r in resources:
334
+ cost = normalized_costs.get(m, {}).get(r)
335
+ if cost is not None and cost * co2 > 0:
336
+ rows.append({"Method": m, "Resource": r, "Used": cost * co2, "Unit": unit})
337
  if not rows:
338
  return
339
 
 
356
  st.caption("Save the current scenario with inputs and outputs for comparison and/or export.")
357
 
358
  suggested = st.session_state.get("scenario_loaded_file", "").rsplit(".", 1)[0]
359
+
360
+ # Initialize only if not already set
361
+ if "scenario_name" not in st.session_state:
362
+ st.session_state["scenario_name"] = suggested
363
 
364
  col_name, col_btn = st.columns([3, 1])
365
  with col_name:
366
  st.text_input(
367
+ "Scenario name",
368
+ key="scenario_name",
369
  label_visibility="collapsed",
370
+ placeholder="Enter a scenario name",
371
  )
372
  with col_btn:
373
  if st.button("Save", use_container_width=True, icon=":material/save:"):
 
387
 
388
  scenario = st.session_state.scenarios[name]
389
  st.markdown(f"#### Scenario: {name}")
390
+ df_saved = build_results_df(scenario["allocations"], method_constraints=scenario.get("method_constraints"))
391
+
392
+ st.markdown(format_table_summary(df_saved,"cdr-table-res"), unsafe_allow_html=True)
393
 
394
  safe = unicodedata.normalize("NFKD", name).encode("ascii", "ignore").decode("ascii")
395
  col_json, col_csv = st.columns(2)
 
408
  pd.DataFrame.from_dict(scenario["resource_caps"], orient="index",
409
  columns=["Available Amount"]).to_csv())
410
  zf.writestr("method_constraints.csv",
411
+ pd.DataFrame.from_dict(scenario["method_constraints"], orient="index", columns=["active", "cap_type (percent or absolute)", "cap_value"]).to_csv())
412
+ zf.writestr("method_costs.csv",
 
413
  pd.DataFrame.from_dict(scenario["method_costs"], orient="index").to_csv())
414
  zf.writestr("allocations.csv",
415
  pd.DataFrame.from_dict(scenario["allocations"], orient="index",
416
+ columns=[f"{CO2_UNIT} removed"]).to_csv())
417
  with col_csv:
418
  st.download_button(
419
  "Export CSV (zip)", data=buf.getvalue(),
 
423
  )
424
 
425
  def export_inputs_only():
426
+ resource_to_unit = {
427
+ r: resource_unit_map[group]
428
+ for group, resources in resource_groups.items()
429
+ for r in resources
430
+ }
431
  st.markdown("### Export inputs")
432
  st.caption("Export only the resource capabilities, method constraints and coefficients — without results.")
433
 
434
  suggested = st.session_state.get("excel_loaded_file", "").rsplit(".", 1)[0]
435
+ # Update when a new file is loaded
436
+ if st.session_state.get("_input_file_name_source") != suggested:
437
+ st.session_state["input_file_name"] = suggested
438
+ st.session_state["_input_file_name_source"] = suggested
439
+
440
+ col_text, col_btn = st.columns([3, 1])
441
  with col_text:
442
  st.text_input(
443
+ "File name",
444
+ label_visibility="collapsed",
445
+ key="input_file_name",
446
  placeholder="Enter a file name",
447
  )
448
+ with col_btn:
449
+ prepare = st.button("Prepare export", use_container_width=True, icon=":material/file_export:")
450
 
451
+ if prepare:
452
+ safe = st.session_state.get("input_file_name", "").strip() or suggested or "crra_inputs"
 
 
 
 
453
 
454
+ wb = openpyxl.Workbook()
455
+ ws1 = wb.active
456
+ ws1.title = "resource_caps"
457
+ ws1.append(["Resource", "Unit", "Available Amount"])
458
+ for r, v in st.session_state.resource_caps.items():
459
+ ws1.append([r, resource_to_unit.get(r, ""), v])
460
 
461
+ ws2 = wb.create_sheet("constraints")
462
+ ws2.append(["method", "active", "cap_type (percent or absolute)", "cap_value"])
463
+ for m, c in st.session_state.constraints.items():
464
+ ws2.append([m, c.get("active", True), c.get("cap_type", "percent"), c.get("cap_value", 1.0)])
 
465
 
466
+ ws3 = wb.create_sheet("coefficients")
467
+ ws3.append(["method", "resource", "value", "secondary"])
468
+ for m, resources in st.session_state.costs.items():
469
+ for r, v in resources.items():
470
+ ws3.append([m, r, v, (m, r) in secondary_resources])
471
 
472
+ buf = io.BytesIO()
473
+ wb.save(buf)
474
+
475
+ st.session_state["_input_export_buf"] = buf.getvalue()
476
+ st.session_state["_input_export_name"] = safe
477
+
478
+ if "_input_export_buf" in st.session_state:
479
  st.download_button(
480
+ f"Download **{st.session_state['_input_export_name']}.xlsx**",
481
+ data=st.session_state["_input_export_buf"],
482
+ file_name=f"{st.session_state['_input_export_name']}.xlsx",
483
  mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
484
+ use_container_width=True,
485
+ icon=":material/download:"
486
  )
487
 
488
  def clear_all_data():
 
565
 
566
  # ── Results ────────────────────────────────────────────────────────────
567
  show_metrics(latest)
568
+ df_result = build_results_df(allocations, method_constraints=latest.get("method_constraints"))
569
 
570
  st.subheader("Optimization Summary")
571
+ # st.table(format_results_summary(df_result))
572
+ st.markdown(format_table_summary(df_result,"cdr-table-res"), unsafe_allow_html=True)
573
 
574
  st.markdown("### Method allocation breakdown")
575
  show_donut(df_result)
tabs/tab5_sensitivity.py CHANGED
@@ -3,7 +3,7 @@ import pandas as pd
3
  import seaborn as sns
4
  import streamlit as st
5
 
6
- from config.config import method_order, resource_order
7
  from optimization.optimization import run_optimization
8
 
9
 
@@ -55,14 +55,14 @@ def render_tab():
55
  all_data.append({
56
  "Input": resource,
57
  "% of cap": pct,
58
- "CO₂ removed (t)": co2_removed
59
  })
60
 
61
  df = pd.DataFrame(all_data)
62
  st.markdown("#### Sensitivity to resource availability")
63
  fig, ax = plt.subplots(figsize=(8, 5))
64
- sns.lineplot(data=df, x="% of cap", y="CO₂ removed (t)", hue="Input", ax=ax)
65
- ax.axhline(y=baseline_removed, linestyle="--", color="gray", label=f"Baseline: {baseline_removed:,} tCO₂")
66
  ax.legend()
67
  st.pyplot(fig)
68
 
@@ -73,32 +73,73 @@ def render_tab():
73
  if not selected_methods:
74
  st.warning("Please select at least one method to run the sensitivity analysis.")
75
  else:
76
- percentages = list(range(0, 110, 10))
77
- all_data = []
78
-
79
- for method in selected_methods:
80
- for pct in percentages:
81
- temp_constraints = st.session_state.constraints.copy()
82
- temp_constraints[method] = temp_constraints.get(method, {}).copy()
83
- temp_constraints[method]["max_share"] = pct / 100
84
-
85
- success, result = run_optimization(
86
- resource_caps=st.session_state.resource_caps,
87
- method_constraints=temp_constraints,
88
- method_costs=st.session_state.costs,
89
- )
90
-
91
- co2_removed = result["total_removed"] if success else 0
92
- all_data.append({
93
- "Input": method,
94
- "% max allocation": pct,
95
- "CO₂ removed (t)": co2_removed
96
- })
97
-
98
- df = pd.DataFrame(all_data)
99
- st.markdown("#### Sensitivity to method max allocation in the portfolio")
100
- fig, ax = plt.subplots(figsize=(8, 5))
101
- sns.lineplot(data=df, x="% max allocation", y="CO₂ removed (t)", hue="Input", ax=ax)
102
- ax.axhline(y=baseline_removed, linestyle="--", color="gray", label=f"Baseline: {baseline_removed:,} tCO₂")
103
- ax.legend()
104
- st.pyplot(fig)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  import seaborn as sns
4
  import streamlit as st
5
 
6
+ from config.config import CO2_UNIT, method_order, resource_order
7
  from optimization.optimization import run_optimization
8
 
9
 
 
55
  all_data.append({
56
  "Input": resource,
57
  "% of cap": pct,
58
+ f"CO₂ removed ({CO2_UNIT})": co2_removed
59
  })
60
 
61
  df = pd.DataFrame(all_data)
62
  st.markdown("#### Sensitivity to resource availability")
63
  fig, ax = plt.subplots(figsize=(8, 5))
64
+ sns.lineplot(data=df, x="% of cap", y=f"CO₂ removed ({CO2_UNIT})", hue="Input", ax=ax)
65
+ ax.axhline(y=baseline_removed, linestyle="--", color="gray", label=f"Baseline: {baseline_removed:,} {CO2_UNIT}")
66
  ax.legend()
67
  st.pyplot(fig)
68
 
 
73
  if not selected_methods:
74
  st.warning("Please select at least one method to run the sensitivity analysis.")
75
  else:
76
+ percent_methods = [m for m in selected_methods if st.session_state.constraints[m].get("cap_type", "percent") == "percent"]
77
+ absolute_methods = [m for m in selected_methods if st.session_state.constraints[m].get("cap_type") == "absolute"]
78
+
79
+ if percent_methods:
80
+ st.markdown("#### Sensitivity to % cap")
81
+ percentages = list(range(0, 110, 10))
82
+ all_data = []
83
+
84
+ for method in percent_methods:
85
+ for pct in percentages:
86
+ temp_constraints = st.session_state.constraints.copy()
87
+ temp_constraints[method]["cap_type"] = "percent"
88
+ temp_constraints[method]["cap_value"] = pct / 100
89
+
90
+ success, result = run_optimization(
91
+ resource_caps=st.session_state.resource_caps,
92
+ method_constraints=temp_constraints,
93
+ method_costs=st.session_state.costs,
94
+ )
95
+ co2_removed = result["total_removed"] if success else 0
96
+ all_data.append({
97
+ "Input": method,
98
+ "% max allocation": pct,
99
+ f"CO₂ removed ({CO2_UNIT})": co2_removed
100
+ })
101
+
102
+ df = pd.DataFrame(all_data)
103
+ fig, ax = plt.subplots(figsize=(8, 5))
104
+ sns.lineplot(data=df, x="% max allocation", y=f"CO₂ removed ({CO2_UNIT})", hue="Input", ax=ax)
105
+ ax.axhline(y=baseline_removed, linestyle="--", color="gray", label=f"Baseline: {baseline_removed:,} {CO2_UNIT}")
106
+ ax.legend()
107
+ st.pyplot(fig)
108
+
109
+ if absolute_methods:
110
+ st.markdown(f"#### Sensitivity to absolute cap ({CO2_UNIT}/yr)")
111
+ all_data = []
112
+
113
+ for method in absolute_methods:
114
+ current_cap = st.session_state.constraints[method].get("cap_value", 0.0)
115
+ # Varier de 0 à 200% de la valeur actuelle en 11 points
116
+ if current_cap > 0:
117
+ values = [current_cap * pct / 100 for pct in range(0, 210, 20)]
118
+ else:
119
+ st.warning(f"Method **{method}** has an absolute cap of 0 — set a value first.", icon="⚠️")
120
+ continue
121
+
122
+ for val in values:
123
+ temp_constraints = st.session_state.constraints.copy()
124
+ temp_constraints[method]["cap_type"] = "absolute"
125
+ temp_constraints[method]["cap_value"] = val
126
+
127
+ success, result = run_optimization(
128
+ resource_caps=st.session_state.resource_caps,
129
+ method_constraints=temp_constraints,
130
+ method_costs=st.session_state.costs,
131
+ )
132
+ co2_removed = result["total_removed"] if success else 0
133
+ all_data.append({
134
+ "Input": method,
135
+ f"Cap ({CO2_UNIT}/yr)": val,
136
+ f"CO₂ removed ({CO2_UNIT})": co2_removed
137
+ })
138
+
139
+ if all_data:
140
+ df = pd.DataFrame(all_data)
141
+ fig, ax = plt.subplots(figsize=(8, 5))
142
+ sns.lineplot(data=df, x=f"Cap ({CO2_UNIT}/yr)", y=f"CO₂ removed ({CO2_UNIT})", hue="Input", ax=ax)
143
+ ax.axhline(y=baseline_removed, linestyle="--", color="gray", label=f"Baseline: {baseline_removed:,} {CO2_UNIT}")
144
+ ax.legend()
145
+ st.pyplot(fig)
tabs/tab6_scenarios.py CHANGED
@@ -4,6 +4,7 @@ import matplotlib.pyplot as plt
4
  import pandas as pd
5
  import seaborn as sns
6
  import streamlit as st
 
7
  from utils.data_utils import is_valid_scenario
8
  from tabs.tab4_optimization import parse_zip_scenario
9
 
@@ -55,13 +56,13 @@ def _prepare_comparison_data(selected):
55
 
56
  row = {
57
  "Scenario": name,
58
- "CO₂ Removed (t)": scenario.get("summary", {}).get("total_co2_removed", 0),
59
  }
60
 
61
  for method in all_methods:
62
  val = allocations.get(method, 0)
63
- row[f"{method} (tCO₂)"] = val
64
- method_alloc_rows.append({"Scenario": name, "Method": method, "tCO₂": val})
65
 
66
  for resource in all_resources:
67
  total_used = 0
@@ -91,9 +92,9 @@ def _show_method_allocations(df):
91
  return
92
  st.subheader("Method Allocations")
93
  fig, ax = plt.subplots(figsize=(10, 4))
94
- sns.barplot(data=df, x="Method", y="tCO₂", hue="Scenario", ax=ax)
95
  ax.set_xlabel("Method")
96
- ax.set_ylabel("tCO₂")
97
  plt.xticks(rotation=45, ha="right")
98
  st.pyplot(fig)
99
 
 
4
  import pandas as pd
5
  import seaborn as sns
6
  import streamlit as st
7
+ from config.config import CO2_UNIT
8
  from utils.data_utils import is_valid_scenario
9
  from tabs.tab4_optimization import parse_zip_scenario
10
 
 
56
 
57
  row = {
58
  "Scenario": name,
59
+ f"CO₂ Removed ({CO2_UNIT})": scenario.get("summary", {}).get("total_co2_removed", 0),
60
  }
61
 
62
  for method in all_methods:
63
  val = allocations.get(method, 0)
64
+ row[f"{method} ({CO2_UNIT})"] = val
65
+ method_alloc_rows.append({"Scenario": name, "Method": method, f"{CO2_UNIT}": val})
66
 
67
  for resource in all_resources:
68
  total_used = 0
 
92
  return
93
  st.subheader("Method Allocations")
94
  fig, ax = plt.subplots(figsize=(10, 4))
95
+ sns.barplot(data=df, x="Method", y=f"{CO2_UNIT}", hue="Scenario", ax=ax)
96
  ax.set_xlabel("Method")
97
+ ax.set_ylabel(f"{CO2_UNIT}")
98
  plt.xticks(rotation=45, ha="right")
99
  st.pyplot(fig)
100
 
utils/data_utils.py CHANGED
@@ -1,5 +1,6 @@
1
  import io
2
  import json
 
3
  import pandas as pd
4
  import streamlit as st
5
  import openpyxl
@@ -58,10 +59,19 @@ def load_inputs_from_excel(file):
58
  constraints = {}
59
  if "constraints" in xl:
60
  for _, row in xl["constraints"].iterrows():
61
- constraints[row["method"]] = {
62
- "active": bool(row["active"]),
63
- "max_share": float(row["max_share"])
64
- }
 
 
 
 
 
 
 
 
 
65
 
66
  costs = {}
67
  if "coefficients" in xl:
@@ -71,3 +81,6 @@ def load_inputs_from_excel(file):
71
 
72
  return resource_caps, constraints, costs
73
 
 
 
 
 
1
  import io
2
  import json
3
+ import re
4
  import pandas as pd
5
  import streamlit as st
6
  import openpyxl
 
59
  constraints = {}
60
  if "constraints" in xl:
61
  for _, row in xl["constraints"].iterrows():
62
+ # Compatibility with older files that used `max_share`
63
+ if "cap_type (percent or absolute)" in xl["constraints"].columns:
64
+ constraints[row["method"]] = {
65
+ "active": bool(row["active"]),
66
+ "cap_type": str(row["cap_type (percent or absolute)"]),
67
+ "cap_value": float(row["cap_value"])
68
+ }
69
+ else:
70
+ constraints[row["method"]] = {
71
+ "active": bool(row["active"]),
72
+ "cap_type": "percent",
73
+ "cap_value": float(row["max_share"])
74
+ }
75
 
76
  costs = {}
77
  if "coefficients" in xl:
 
81
 
82
  return resource_caps, constraints, costs
83
 
84
+ def strip_unit_suffix(resource_name: str) -> str:
85
+ """Remove legacy unit suffix from resource name, e.g. 'Unspecified land (ha/tCO2)' -> 'Unspecified land'"""
86
+ return re.sub(r"\s*\(.*?\)\s*$", "", resource_name).strip()
utils/ui_helpers.py CHANGED
@@ -1,6 +1,7 @@
1
  import numpy as np
2
  import pandas as pd
3
  import streamlit as st
 
4
 
5
  # params
6
  background_color = "#3d86e9"
@@ -33,40 +34,34 @@ def inputs_table_style(df):
33
  .set_table_styles([{"selector": "th", "props": [("background-color", background_color), ("font-weight", "bold")]}])
34
  )
35
 
36
- def format_method_summary(df: pd.DataFrame):
37
  df = df.copy()
38
  df.index.name = "CDR Method"
39
- df.reset_index(inplace=True)
40
-
41
- return (
42
- df.style
43
- .set_table_styles([
44
- {"selector": "thead th", "props": [("background-color", background_color), ("color", "white"), ("font-weight", "bold")]},
45
- {"selector": "td.col0", "props": [("text-align", "left"), ("font-weight", "bold")]},
46
- {"selector": "td.col1", "props": [("text-align", "center")]}
47
- ])
48
- )
49
-
50
- def format_results_summary(df: pd.DataFrame):
51
- df = df.copy()
52
- df.index.name = "CDR Method"
53
- df.reset_index(inplace=True)
54
-
55
- return (
56
- df.style
57
- .format({
58
- "tCO₂ removed": "{:,.0f}",
59
- "Share (%)": "{:.2f}"
60
- })
61
- .set_table_styles([
62
- {"selector": "thead th", "props": [("background-color", background_color), ("color", "white"), ("font-weight", "bold")]},
63
- {"selector": "td.col0", "props": [("text-align", "left"), ("font-weight", "bold")]},
64
- {"selector": "td.col1", "props": [("text-align", "center")]}
65
- ])
66
- )
67
 
68
  def format_efficiency_summary(df: pd.DataFrame, df_default: pd.DataFrame):
69
  df_numeric = df.copy()
 
70
  df_numeric.index.name = "Method"
71
 
72
  df_display = df_numeric.map(smart_display_format)
 
1
  import numpy as np
2
  import pandas as pd
3
  import streamlit as st
4
+ from config.config import CO2_UNIT
5
 
6
  # params
7
  background_color = "#3d86e9"
 
34
  .set_table_styles([{"selector": "th", "props": [("background-color", background_color), ("font-weight", "bold")]}])
35
  )
36
 
37
+ def format_table_summary(df: pd.DataFrame, class_name: str):
38
  df = df.copy()
39
  df.index.name = "CDR Method"
40
+ df = df.reset_index()
41
+
42
+ html = df.to_html(index=True, classes=class_name, border=0)
43
+ return html
44
+
45
+ # df = df.copy()
46
+ # df.index.name = "CDR Method"
47
+ # df.reset_index(inplace=True)
48
+
49
+ # return (
50
+ # df.style
51
+ # .format({
52
+ # f"{CO2_UNIT} removed": "{:,.0f}",
53
+ # "Share (%)": "{:.2f}"
54
+ # })
55
+ # .set_table_styles([
56
+ # {"selector": "thead th", "props": [("background-color", background_color), ("color", "white"), ("font-weight", "bold")]},
57
+ # {"selector": "td.col0", "props": [("text-align", "left"), ("font-weight", "bold")]},
58
+ # {"selector": "td.col1", "props": [("text-align", "center")]}
59
+ # ])
60
+ # )
 
 
 
 
 
 
 
61
 
62
  def format_efficiency_summary(df: pd.DataFrame, df_default: pd.DataFrame):
63
  df_numeric = df.copy()
64
+
65
  df_numeric.index.name = "Method"
66
 
67
  df_display = df_numeric.map(smart_display_format)