Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get countries in common-regions #403

Open
danielhuppmann opened this issue Oct 1, 2024 · 3 comments
Open

Get countries in common-regions #403

danielhuppmann opened this issue Oct 1, 2024 · 3 comments

Comments

@danielhuppmann
Copy link
Member

@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

@phackstock
Copy link
Contributor

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.

@danielhuppmann
Copy link
Member Author

Might be easier to add it as a property of the CommonRegion class (which is implicltly model-dependent).

class CommonRegion(BaseModel):

And adding a "getter" would also be helpful, currently there are only lists.

rp.mappings[model].get["Asia (R5)"].countries

@laurinks
Copy link

laurinks commented Oct 25, 2024

@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)

R10_model_comparison.xlsx
R5_model_comparison.xlsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants