Skip to content

Commit 9acc71d

Browse files
macflo8khaeru
authored andcommitted
Add updated aluminum capacity calibration
1 parent 123ceec commit 9acc71d

File tree

5 files changed

+137
-3
lines changed

5 files changed

+137
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:e203bd3b535e8494767e6301fa87d11eb3d8d19de2139f27108a04bcd569f10c
3-
size 121450
2+
oid sha256:2144ce3f352e6bca67ed46467dd656615abdfb8bdba8548862e32bea119f4448
3+
size 58799
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:087e3fad92e1c9fcf292ea606e3d2ccf510e773bad478a9a650a2e48661267ca
3+
size 121353
Binary file not shown.

message_ix_models/model/material/data_aluminum.py

+98-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@
1515

1616
from .data_util import read_rel, read_timeseries
1717
from .material_demand import material_demand_calc
18-
from .util import combine_df_dictionaries, get_ssp_from_context, read_config
18+
from .util import (
19+
add_R12_column,
20+
combine_df_dictionaries,
21+
get_pycountry_iso,
22+
get_ssp_from_context,
23+
read_config,
24+
)
1925

2026

2127
def read_data_aluminum(
@@ -730,3 +736,94 @@ def gen_data_alu_trade(scenario: message_ix.Scenario) -> dict[str, pd.DataFrame]
730736
results["bound_activity_lo"].append(bound_act_net_export_chn_2025)
731737

732738
return {par_name: pd.concat(dfs) for par_name, dfs in results.items()}
739+
740+
741+
def gen_hist_new_cap():
742+
df_cap = pd.read_excel(
743+
package_data_path("material", "aluminum", "smelters-with 2022 projection.xls"),
744+
sheet_name="Sheet1",
745+
skipfooter=23,
746+
).rename(columns={"Unnamed: 0": "Country", "Unnamed: 1": "Region"})
747+
df_cap.Technology = df_cap.Technology.fillna("unknown")
748+
df_cap = df_cap[~df_cap[1995].isna()]
749+
df_cap.Country = df_cap["Country"].ffill()
750+
df_cap["ISO"] = df_cap.Country.apply(
751+
lambda c: get_pycountry_iso(
752+
c,
753+
{
754+
"Surinam": "SUR",
755+
"Trinidad": "TTO",
756+
"Quatar": "QAT",
757+
"Turkey": "TUR",
758+
"UAE": "ARE",
759+
"Gernamy": "DEU",
760+
"Azerbaydzhan": "AZE",
761+
"Russia": "RUS",
762+
"Tadzhikistan": "TJK",
763+
"UK": "GBR",
764+
"Total": "World",
765+
"Bosnia": "BIH",
766+
},
767+
)
768+
)
769+
df_cap = add_R12_column(
770+
df_cap, file_path=package_data_path("node", "R12.yaml"), iso_column="ISO"
771+
)
772+
773+
# generate historical_new_capacity for soderberg
774+
df_cap_ss = df_cap[
775+
(df_cap.Technology.str.contains("SS") & ~(df_cap.Technology.str.contains("PB")))
776+
& ~(df_cap.Technology.str.contains("HAL"))
777+
& ~(df_cap.Technology.str.contains("P"))
778+
]
779+
df_cap_ss_r12 = df_cap_ss.groupby("R12").sum(numeric_only=True)
780+
sample = df_cap_ss_r12[df_cap_ss_r12[df_cap_ss_r12.columns[-1]] != 0][
781+
[i for i in range(1995, 2020, 5)] + [2019]
782+
]
783+
hist_new_cap_ss = compute_differences(sample, 1995) / 10**6
784+
hist_new_cap_ss = hist_new_cap_ss.rename(columns={2019: 2020})
785+
hist_new_cap_ss = (
786+
hist_new_cap_ss.reset_index()
787+
.melt(id_vars="R12", var_name="year_vtg")
788+
.assign(unit="Mt", technology="soderberg_aluminum")
789+
.rename(columns={"R12": "node_loc"})
790+
)
791+
792+
# generate historical_new_capacity for prebake
793+
df_cap_pb = df_cap.loc[df_cap.index.difference(df_cap_ss.index)]
794+
df_cap_pb_r12 = df_cap_pb.groupby("R12").sum(numeric_only=True)
795+
sample = df_cap_pb_r12[[i for i in range(1995, 2020, 5)] + [2019]]
796+
hist_new_cap_pb = compute_differences(sample, 1995) / 10**6
797+
hist_new_cap_pb = hist_new_cap_pb.rename(columns={2019: 2020})
798+
hist_new_cap_pb = (
799+
hist_new_cap_pb.reset_index()
800+
.melt(id_vars="R12", var_name="year_vtg")
801+
.assign(unit="Mt", technology="prebake_aluminum")
802+
.rename(columns={"R12": "node_loc"})
803+
)
804+
805+
return {"historical_new_capacity": pd.concat([hist_new_cap_ss, hist_new_cap_pb])}
806+
807+
808+
def compute_differences(df, ref_col):
809+
# Initialize a DataFrame to store differences
810+
differences = df[ref_col].to_frame()
811+
812+
# Start with the reference column
813+
ref_values = df[ref_col].copy()
814+
815+
for col in df.columns:
816+
if col == ref_col:
817+
continue # Skip the reference column
818+
819+
# Compute differences
820+
diff = df[col] - ref_values
821+
diff[diff <= 0] = 0 # Keep only positive differences
822+
823+
# Store differences
824+
differences[col] = diff
825+
826+
# Update the reference column where the current column is greater
827+
ref_values = ref_values.where(df[col] <= ref_values, df[col])
828+
829+
return differences

message_ix_models/model/material/util.py

+34
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import message_ix
66
import openpyxl as pxl
77
import pandas as pd
8+
import pycountry
89
import yaml
910
from scipy.optimize import curve_fit
1011

@@ -389,3 +390,36 @@ def path_fallback(context_or_regions: Union[Context, str], *parts) -> Path:
389390
return c
390391

391392
raise FileNotFoundError(candidates)
393+
394+
395+
def get_pycountry_iso(row, mis_dict):
396+
try:
397+
row = pycountry.countries.lookup(row).alpha_3
398+
except LookupError:
399+
try:
400+
row = mis_dict[row]
401+
except KeyError:
402+
print(f"{row} is not mapped to an ISO")
403+
row = None
404+
return row
405+
406+
407+
def get_r12_reg(df, r12_map_inv, col_name):
408+
try:
409+
df = r12_map_inv[df[col_name]]
410+
except KeyError:
411+
df = None
412+
return df
413+
414+
415+
def add_R12_column(df, file_path, iso_column="COUNTRY"):
416+
# Replace 'your_file_path.yaml' with the path to your actual YAML file
417+
# file_path = private_data_path("node", "R12_SSP_V1.yaml")
418+
yaml_data = read_yaml_file(file_path)
419+
yaml_data.pop("World")
420+
421+
r12_map = {k: v["child"] for k, v in yaml_data.items()}
422+
r12_map_inv = {k: v[0] for k, v in invert_dictionary(r12_map).items()}
423+
424+
df["R12"] = df.apply(lambda x: get_r12_reg(x, r12_map_inv, iso_column), axis=1)
425+
return df

0 commit comments

Comments
 (0)