Get countries in common-regions
@laurinks asked me about a model-specific common-region-to-country mapping, so I whipped together this code. Maybe useful going forward
dsd = nomenclature.DataStructureDefinition("definitions/")
rp = nomenclature.RegionProcessor.from_directory("mappings/", dsd)
def get_model_country_mapping(model):
model_mapping = rp.mappings[model]
model_country_mapping = dict()
for common_region in model_mapping.common_regions:
_list = list()
for constituent_region in common_region.constituent_regions:
_list.extend(dsd.region[model_mapping.rename_mapping[constituent_region]].countries)
model_country_mapping[common_region.name] = _list
return model_mapping
fyi @phackstock @SferraFab @dc-almeida
Very nice, I think this should become a property of the RegionAggregationMapping class.
This way, you could run:
dsd = nomenclature.DataStructureDefinition("definitions/")
rp = nomenclature.RegionProcessor.from_directory("mappings/", dsd)
model="Some Model"
rp.mappings[model].common_region_country_mapping
and would get the desired mapping.
In addition you could also add RegionAggregationMapping.native_region_country_mapping.
Or something along those lines with a less verbose name.
Might be easier to add it as a property of the CommonRegion class (which is implicltly model-dependent). https://github.com/IAMconsortium/nomenclature/blob/30fb5b14d34da4c8905f54df4d16f2a38a24abc3/nomenclature/processor/region.py#L64
And adding a "getter" would also be helpful, currently there are only lists.
rp.mappings[model].get["Asia (R5)"].countries
@danielhuppmann Thanks a lot. It is indeed very useful.
Based on the suggested function above (but returning model_country_mapping instead of model_mapping - I guess this was a typo), I am extracting Excel tables for each common region (R5 or R10) which contain information on the countries included in the region for each model (see attached files).
Maybe useful also for other teams when doing multi-model analysis on R10 or R5 levels. (I am not familiar with the nomenclature, so the code can certainly be improved.)
#List of models: As IMAGE complained about IND, I commented out the mapping for G20 members in common-definitions/mappings/IMAGE_v3.4.yaml
scenarioMIP_models = ["AIM 3.0", "COFFEE 1.5", "GCAM 7.1 scenarioMIP", "IMAGE 3.4", "MESSAGEix-GLOBIOM 2.1-M-R12", "REMIND-MAgPIE 3.4-4.8","WITCH 6.0"]
#List of common regions
common_regions = ["OECD & EU (R5)", "Reforming Economies (R5)", "Asia (R5)", "Middle East & Africa (R5)", "Latin America (R5)"]
# common_regions = ["Africa (R10)","Rest of Asia (R10)","Reforming Economies (R10)","Pacific OECD (R10)","North America (R10)","Middle East (R10)","Latin America (R10)","India+ (R10)","Europe (R10)","China+ (R10)"]
# List of all countries
all_countries = list()
for region in common_regions:
all_countries = all_countries + dsd.region[region].countries
# Function returning dataframe with -1/0/1 entries indicating if countries (rows) are incorrectly/not/correctly contained in region for models (columns)
def get_model_region_country_mapping(region):
model_region_country_mapping = dict()
# Add common region definition
model_region_country_mapping["Definition"] = dsd.region[region].countries
# Add model region definition
for model in scenarioMIP_models:
model_region_country_mapping[model] = get_model_country_mapping(model)[region]
# Initialize dataframe
df = pandas.DataFrame(index = all_countries, columns=model_region_country_mapping.keys())
# Add true/false to column Definition
# Add 1 if country correctly included, add -1 if country incorrectly included, add 0 if country not included
for model, country_list in model_region_country_mapping.items():
if model == "Definition":
df[model] = df.index.isin(country_list).astype(bool)
else:
df[model] = df.index.isin(country_list).astype(int)
df.iloc[:, 1:] = df.apply(lambda row: row[1:] * (1 if row['Definition'] else -1), axis=1)
df["TOTAL"] = df.drop(columns=["Definition"]).sum(axis=1)
df = df = df[(df["TOTAL"] != 0) | (df["Definition"] == True)]
df = df.sort_values(by="TOTAL", ascending=False)
return df
output_file = 'R5_model_comparison.xlsx'
# output_file = 'R10_model_comparison.xlsx'
with pandas.ExcelWriter(output_file, engine='openpyxl') as writer:
for region in common_regions:
df = get_model_region_country_mapping(region)
df.to_excel(writer, sheet_name=region, index=True)