Source code for message_ix_models.tests.tools.costs.test_projections

import pytest
from message_ix import make_df

from message_ix_models import testing
from message_ix_models.model.structure import get_codelist
from message_ix_models.tools.costs import Config, create_cost_projections
from message_ix_models.util import add_par_data


[docs]@pytest.mark.parametrize( "config, exp_fix, exp_inv", ( ( Config(node="R11", scenario="SSP2"), {"technology": {"coal_ppl", "gas_ppl", "wind_res1", "solar_res1"}}, {"technology": {"coal_ppl", "gas_ppl", "wind_res1", "solar_res1"}}, ), ( Config( module="materials", method="convergence", scenario="SSP2", format="iamc" ), { "Variable": { "OM Cost|Electricity|MTO_petro|Vintage=2020", "OM Cost|Electricity|biomass_NH3|Vintage=2050", "OM Cost|Electricity|furnace_foil_steel|Vintage=2090", } }, { "Variable": { "Capital Cost|Electricity|MTO_petro", "Capital Cost|Electricity|biomass_NH3", "Capital Cost|Electricity|furnace_foil_steel", } }, ), ( Config(module="cooling", method="gdp", node="R12", scenario="SSP5"), {"technology": {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}}, {"technology": {"coal_ppl__cl_fresh", "gas_cc__air", "nuc_lc__ot_fresh"}}, ), pytest.param( Config(node="R20"), set(), set(), marks=pytest.mark.xfail(raises=NotImplementedError), ), ), ) def test_create_cost_projections(config, exp_fix, exp_inv) -> None: # Function runs without error result = create_cost_projections(config) inv_cost = result["inv_cost"] fix_cost = result["fix_cost"] if config.format == "message": # Columns needed for MESSAGE input are present extra_cols = {"scenario", "scenario_version"} assert set(make_df("fix_cost").columns) | extra_cols == set(fix_cost.columns) assert set(make_df("inv_cost").columns) | extra_cols == set(inv_cost.columns) # Retrieve list of node IDs for children of the "World" node; convert to string nodes = set(map(str, get_codelist(f"node/{config.node}")["World"].child)) # All regions are present in both data frames column = {"message": "node_loc", "iamc": "Region"}[config.format] assert nodes <= set(inv_cost[column].unique()) assert nodes <= set(fix_cost[column].unique()) # Expected values are in fix_cost columns for column, values in exp_fix.items(): assert values <= set(fix_cost[column].unique()) # Expected values are in inv_cost columns for column, values in exp_inv.items(): assert values <= set(inv_cost[column].unique())
[docs]@pytest.mark.parametrize( "node", ( "R11", "R12", pytest.param("R20", marks=pytest.mark.xfail(raises=NotImplementedError)), ), ) def test_bare_res(request, test_context, node): """Costs data can be added to the bare RES and solved.""" # Set the regions on the Context test_context.model.regions = node # Matching setting on .costs.Config config = Config(node=node, scenario="SSP2") # Create the bare RES scenario = testing.bare_res(request, test_context) test_context.set_scenario(scenario) # Data can be created data = create_cost_projections(config) # The extra "scenario" and "scenario_version" columns are ignored by # message_ix/ixmp. If they contain multiple values, these are treated as duplicate # rows, and only the last value for the combination of other dimensions is applied. # # Check that there are no duplicates when calling create_cost_projections() with a # single scenario. for df in data.values(): assert 1 == len(df.scenario.unique()) == len(df.scenario_version.unique()) # Data can be added to the scenario with scenario.transact("Add technoeconomic cost data"): add_par_data(scenario, data) # Scenario solves with the added data scenario.solve()