Skip to content

Commit 8416618

Browse files
committed
Add updated aluminum capacity calibration
1 parent 0331f1d commit 8416618

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(
@@ -733,3 +739,94 @@ def gen_data_alu_trade(scenario: message_ix.Scenario) -> dict[str, pd.DataFrame]
733739
results["bound_activity_lo"].append(bound_act_net_export_chn_2025)
734740

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

@@ -394,3 +395,36 @@ def path_fallback(context_or_regions: Union[Context, str], *parts) -> Path:
394395
return c
395396

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

0 commit comments

Comments
 (0)