Skip to content

Commit 10f1ffa

Browse files
measrainseykhaeru
authored andcommitted
Implement using Config
1 parent 8530d11 commit 10f1ffa

File tree

7 files changed

+292
-222
lines changed

7 files changed

+292
-222
lines changed

message_ix_models/tools/costs/config.py

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
class Config:
2121
"""Configuration for :mod:`.costs`."""
2222

23+
test_val: int = 2
24+
2325
#: Base year for projections.
2426
base_year: int = BASE_YEAR
2527

message_ix_models/tools/costs/demo.py

+72-27
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,88 @@
1+
from message_ix_models.tools.costs.config import Config
12
from message_ix_models.tools.costs.projections import create_cost_projections
23

3-
# By default, the create_cost_projections() function will run for R12
4+
# Example 1: By default, the Config fill will run for:
5+
# R12
46
# for the base suite of technologies,
57
# with NAM as reference region,
68
# using GDP as the cost driver,
7-
# and the updated data version.
9+
# and the updated data version
10+
# and outputs in MESSAGE format.
811
# The function will also run for all SSP scenarios,
912
# for all years from 2021 to 2100.
10-
inv, fix = create_cost_projections()
13+
default = Config()
14+
out_default = create_cost_projections(
15+
node=default.node,
16+
ref_region=default.ref_region,
17+
base_year=default.base_year,
18+
module=default.module,
19+
method=default.method,
20+
scenario_version=default.scenario_version,
21+
scenario=default.scenario,
22+
convergence_year=default.convergence_year,
23+
fom_rate=default.fom_rate,
24+
format=default.format,
25+
)
1126

12-
# Example 1: Get cost projections for SSP2 scenario in R12,
27+
# Example 2: Get cost projections for SSP2 scenario in R12,
28+
# using WEU as the reference region,
29+
# with convergence as the method,
1330
# for materials technologies,
1431
# using GDP (updated data)
15-
inv2, fix2 = create_cost_projections(
16-
sel_node="r12",
17-
sel_ref_region="R12_NAM",
18-
sel_base_year=2021,
19-
sel_module="materials",
20-
sel_scenario_version="updated",
21-
sel_scenario="ssp2",
22-
sel_method="gdp",
32+
# You can either put the inputs directly into the create_cost_projections function,
33+
# or you can create a Config object and pass that in.
34+
default = Config()
35+
36+
# Option 1: Directly input the parameters
37+
out_materials_ssp2 = create_cost_projections(
38+
node=default.node,
39+
ref_region="R12_WEU",
40+
base_year=default.base_year,
41+
module="materials",
42+
method="convergence",
43+
scenario_version=default.scenario_version,
44+
scenario="SSP2",
45+
convergence_year=default.convergence_year,
46+
fom_rate=default.fom_rate,
47+
format=default.format,
2348
)
2449

25-
# Example 2: Get cost projections in R11 (with WEU as reference region), using learning
26-
# (this will run for all SSP scenarios)
27-
inv, fix = create_cost_projections(
28-
sel_node="r11",
29-
sel_ref_region="R11_WEU",
30-
sel_base_year=2021,
31-
sel_method="learning",
32-
sel_scenario_version="updated",
50+
# Option 2: Create a Config object and pass that in
51+
config = Config(
52+
module="materials", scenario="SSP2", ref_region="R12_WEU", method="convergence"
3353
)
3454

35-
# Example 3: Get cost projections in R12, using convergence
36-
inv, fix = create_cost_projections(
37-
sel_node="r12",
38-
sel_base_year=2021,
39-
sel_method="convergence",
55+
out_materials_ssp2 = create_cost_projections(
56+
node=config.node,
57+
ref_region=config.ref_region,
58+
base_year=config.base_year,
59+
module=config.module,
60+
method=config.method,
61+
scenario_version=config.scenario_version,
62+
scenario=config.scenario,
63+
convergence_year=config.convergence_year,
64+
fom_rate=config.fom_rate,
65+
format=config.format,
4066
)
4167

42-
# Example 4: Get cost projections in R11 using previous/original SSP scenarios
43-
inv, fix = create_cost_projections(sel_node="r11", sel_scenario_version="original")
68+
# Example 3: Get cost projections for SSP5 scenario in R12,
69+
# using LAM as the reference region,
70+
# with learning as the method,
71+
# for materials technologies,
72+
73+
config = Config(
74+
module="materials", scenario="SSP5", ref_region="R12_LAM", method="learning"
75+
)
76+
77+
out_materials_ssp5 = create_cost_projections(
78+
node=config.node,
79+
ref_region=config.ref_region,
80+
base_year=config.base_year,
81+
module=config.module,
82+
method=config.method,
83+
scenario_version=config.scenario_version,
84+
scenario=config.scenario,
85+
convergence_year=config.convergence_year,
86+
fom_rate=config.fom_rate,
87+
format=config.format,
88+
)

message_ix_models/tools/costs/gdp.py

+20-20
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
# Function to read in (under-review) SSP data
11-
def process_raw_ssp_data(input_node, input_ref_region) -> pd.DataFrame:
11+
def process_raw_ssp_data(node, ref_region) -> pd.DataFrame:
1212
"""Read in raw SSP data and process it
1313
1414
This function takes in the raw SSP data (in IAMC format), aggregates \
@@ -38,22 +38,22 @@ def process_raw_ssp_data(input_node, input_ref_region) -> pd.DataFrame:
3838
(in units of billion US$2005/yr / million)
3939
"""
4040
# Change node selection to upper case
41-
node_up = input_node.upper()
41+
node_up = node.upper()
4242

4343
# Check if node selection is valid
4444
if node_up not in ["R11", "R12", "R20"]:
4545
print("Please select a valid region: R11, R12, or R20")
4646

4747
# Set default reference region
48-
if input_ref_region is None:
49-
if input_node.upper() == "R11":
50-
input_ref_region = "R11_NAM"
51-
if input_node.upper() == "R12":
52-
input_ref_region = "R12_NAM"
53-
if input_node.upper() == "R20":
54-
input_ref_region = "R20_NAM"
48+
if ref_region is None:
49+
if node.upper() == "R11":
50+
ref_region = "R11_NAM"
51+
if node.upper() == "R12":
52+
ref_region = "R12_NAM"
53+
if node.upper() == "R20":
54+
ref_region = "R20_NAM"
5555
else:
56-
input_ref_region = input_ref_region
56+
ref_region = ref_region
5757

5858
# Set data path for node file
5959
node_file = package_data_path("node", node_up + ".yaml")
@@ -162,7 +162,7 @@ def process_raw_ssp_data(input_node, input_ref_region) -> pd.DataFrame:
162162
)
163163

164164
# If reference region is not in the list of regions, print error message
165-
reference_region = input_ref_region.upper()
165+
reference_region = ref_region.upper()
166166
if reference_region not in df.region.unique():
167167
print("Please select a valid reference region: " + str(df.region.unique()))
168168
# If reference region is in the list of regions, calculate GDP ratios
@@ -212,22 +212,22 @@ def process_raw_ssp_data(input_node, input_ref_region) -> pd.DataFrame:
212212

213213
# Function to calculate adjusted region-differentiated cost ratios
214214
def calculate_indiv_adjusted_region_cost_ratios(
215-
region_diff_df, input_node, input_ref_region, input_base_year
215+
region_diff_df, node, ref_region, base_year
216216
):
217217
df_gdp = (
218-
process_raw_ssp_data(input_node=input_node, input_ref_region=input_ref_region)
218+
process_raw_ssp_data(node=node, ref_region=ref_region)
219219
.query("year >= 2020")
220220
.drop(columns=["total_gdp", "total_population"])
221221
)
222222
df_cost_ratios = region_diff_df.copy()
223223

224224
# If base year does not exist in GDP data, then use earliest year in GDP data
225225
# and give warning
226-
base_year = int(input_base_year)
226+
base_year = int(base_year)
227227
if int(base_year) not in df_gdp.year.unique():
228228
base_year = int(min(df_gdp.year.unique()))
229229
print(
230-
f"Base year {input_base_year} not found in GDP data. \
230+
f"Base year {base_year} not found in GDP data. \
231231
Using {base_year} for GDP data instead."
232232
)
233233

@@ -236,15 +236,15 @@ def calculate_indiv_adjusted_region_cost_ratios(
236236
# If specified node is R12, then use R12_NAM as the reference region
237237
# If specified node is R20, then use R20_NAM as the reference region
238238
# However, if a reference region is specified, then use that instead
239-
if input_ref_region is None:
240-
if input_node.upper() == "R11":
239+
if ref_region is None:
240+
if node.upper() == "R11":
241241
reference_region = "R11_NAM"
242-
if input_node.upper() == "R12":
242+
if node.upper() == "R12":
243243
reference_region = "R12_NAM"
244-
if input_node.upper() == "R20":
244+
if node.upper() == "R20":
245245
reference_region = "R20_NAM"
246246
else:
247-
reference_region = input_ref_region
247+
reference_region = ref_region
248248

249249
gdp_base_year = df_gdp.query("year == @base_year").reindex(
250250
["scenario_version", "scenario", "region", "gdp_ratio_reg_to_reference"], axis=1

message_ix_models/tools/costs/learning.py

+24-26
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
# Function to get GEA based cost reduction data
14-
def get_cost_reduction_data(input_module) -> pd.DataFrame:
14+
def get_cost_reduction_data(module) -> pd.DataFrame:
1515
"""Get cost reduction data
1616
1717
Raw data on cost reduction in 2100 for technologies are read from \
@@ -45,10 +45,10 @@ def get_cost_reduction_data(input_module) -> pd.DataFrame:
4545
.reset_index(drop=1)
4646
)
4747

48-
if input_module == "base":
48+
if module == "base":
4949
return base_rates
5050

51-
elif input_module == "materials":
51+
elif module == "materials":
5252
# Read in materials technology mapping file
5353
materials_file_path = package_data_path("costs", "technology_materials_map.csv")
5454
df_materials_tech = pd.read_csv(materials_file_path)
@@ -78,9 +78,7 @@ def get_cost_reduction_data(input_module) -> pd.DataFrame:
7878

7979

8080
# Function to get technology learning scenarios data
81-
def get_technology_learning_scenarios_data(
82-
input_base_year, input_module
83-
) -> pd.DataFrame:
81+
def get_technology_learning_scenarios_data(base_year, module) -> pd.DataFrame:
8482
"""Read in technology first year and learning scenarios data
8583
8684
Raw data on technology first year and learning scenarios are read from \
@@ -90,7 +88,7 @@ def get_technology_learning_scenarios_data(
9088
9189
Parameters
9290
----------
93-
input_base_year : int, optional
91+
base_year : int, optional
9492
The base year, by default set to global BASE_YEAR
9593
9694
Returns
@@ -109,9 +107,9 @@ def get_technology_learning_scenarios_data(
109107
pd.read_csv(file)
110108
.assign(
111109
first_technology_year=lambda x: np.where(
112-
x.first_year_original > input_base_year,
110+
x.first_year_original > base_year,
113111
x.first_year_original,
114-
input_base_year,
112+
base_year,
115113
),
116114
)
117115
.drop(columns=["first_year_original"])
@@ -122,10 +120,10 @@ def get_technology_learning_scenarios_data(
122120
)
123121
)
124122

125-
if input_module == "base":
123+
if module == "base":
126124
return base_learn
127125

128-
elif input_module == "materials":
126+
elif module == "materials":
129127
# Read in materials technology mapping file
130128
materials_file_path = package_data_path("costs", "technology_materials_map.csv")
131129
df_materials_tech = pd.read_csv(materials_file_path)
@@ -157,10 +155,10 @@ def get_technology_learning_scenarios_data(
157155
# Function to project reference region investment cost using learning rates
158156
def project_ref_region_inv_costs_using_learning_rates(
159157
regional_diff_df: pd.DataFrame,
160-
input_node,
161-
input_ref_region,
162-
input_base_year,
163-
input_module,
158+
node,
159+
ref_region,
160+
base_year,
161+
module,
164162
) -> pd.DataFrame:
165163
"""Project investment costs using learning rates for reference region
166164
@@ -172,11 +170,11 @@ def project_ref_region_inv_costs_using_learning_rates(
172170
----------
173171
regional_diff_df : pandas.DataFrame
174172
Dataframe output from :func:`get_weo_region_differentiated_costs`
175-
input_node : str, optional
173+
node : str, optional
176174
The reference node, by default "r12"
177-
input_ref_region : str, optional
175+
ref_region : str, optional
178176
The reference region, by default None (defaults set in function)
179-
input_base_year : int, optional
177+
base_year : int, optional
180178
The base year, by default set to global BASE_YEAR
181179
182180
Returns
@@ -191,21 +189,21 @@ def project_ref_region_inv_costs_using_learning_rates(
191189
"""
192190

193191
# Set default reference region
194-
if input_ref_region is None:
195-
if input_node.upper() == "R11":
192+
if ref_region is None:
193+
if node.upper() == "R11":
196194
reference_region = "R11_NAM"
197-
if input_node.upper() == "R12":
195+
if node.upper() == "R12":
198196
reference_region = "R12_NAM"
199-
if input_node.upper() == "R20":
197+
if node.upper() == "R20":
200198
reference_region = "R20_NAM"
201199
else:
202-
reference_region = input_ref_region
200+
reference_region = ref_region
203201

204202
# Get cost reduction data
205-
df_cost_reduction = get_cost_reduction_data(input_module)
203+
df_cost_reduction = get_cost_reduction_data(module)
206204

207205
# Get learning rates data
208-
df_learning = get_technology_learning_scenarios_data(input_base_year, input_module)
206+
df_learning = get_technology_learning_scenarios_data(base_year, module)
209207

210208
# Merge cost reduction data with learning rates data
211209
df_learning_reduction = df_learning.merge(
@@ -221,7 +219,7 @@ def project_ref_region_inv_costs_using_learning_rates(
221219
cost_region_2100=lambda x: x.reg_cost_base_year
222220
- (x.reg_cost_base_year * x.cost_reduction),
223221
b=lambda x: (1 - PRE_LAST_YEAR_RATE) * x.cost_region_2100,
224-
r=lambda x: (1 / (LAST_MODEL_YEAR - input_base_year))
222+
r=lambda x: (1 / (LAST_MODEL_YEAR - base_year))
225223
* np.log((x.cost_region_2100 - x.b) / (x.reg_cost_base_year - x.b)),
226224
reference_region=reference_region,
227225
)

0 commit comments

Comments
 (0)