iiasa / message_ix

The integrated assessment and energy systems model MESSAGEix
https://docs.messageix.org
Apache License 2.0
119 stars 153 forks source link

How could I reflect 'commodity' set in the 'emission_factor' parameter? (for specific model) #749

Closed MESSAGEix-SK-Woo closed 11 months ago

MESSAGEix-SK-Woo commented 11 months ago

Hi, I'm currently building an Industry sector model in korea using MESSAGEix.

It's more specific model than global model, as a result, many of the technologies have multi inputs.

ex) kiln tec has various input such as "raw_material, coalB, biomass, waste, elec, .... ". but output is only 'clinker'

but some sets('var_cost' or 'emission_factor', ....) don't have 'commodity' set in their code.

I would like to reflect a 'commodity' set in these parameters.

and, To revise GAMS code is not to difficult. 'cuz I know how use it.

Although revising the GAMS code is not difficult for me, as I know how to use it, I found that even after adding a 'commodity' in the 'emission_factor' parameter, the python code did not reflect this change.

Here's what I did:

  1. I changed the GAMS code (emission_factor, added commodity).
  2. However, it did not reflect in the Python code. When I checked using "scenario.par('emission_factor')" in Python, I noticed that there wasn't a 'commodity' set in the 'emission_factor' parameter.

I suspect that this may be a Python issue. Can you please help me to reflect the 'commodity' in the 'emission_factor' parameter? I would really appreciate your help.

Thank you for your time, and I look forward to hearing back from you soon.

glatterf42 commented 11 months ago

Hi @MESSAGEix-SK-Woo, thanks for your question! I think there is a fundamental misunderstanding here: message_ix uses ixmp in the background, with which you can connect to a database (via the ixmp.Platform()). This database contains the data for different scenarios, accessible via message_ix.Scenario(). You are probably working on one of them in your code! Scenarios are used to handle different kind of model data, among them parameters. Following the baseline westeros tutorial, if you set up your scenario as

import pandas as pd
import ixmp
import message_ix

mp = ixmp.Platform()
scenario = message_ix.Scenario(
    mp, model="Westeros Electrified", scenario="baseline", version="new"
)

you can add parameters to the scenario like this:

# Define the time frame of the model
history = [690]
model_horizon = [700, 710, 720]
scenario.add_horizon(year=history + model_horizon, firstmodelyear=model_horizon[0])

# Define the locations of the model
country = "Westeros"
scenario.add_spatial_sets({"country": country}) 

# Define possible values of some categories used to define parameters
scenario.add_set("commodity", ["electricity", "light"])
scenario.add_set("level", ["secondary", "final", "useful"])

# Assume a GDP profile
gdp_profile = pd.Series([1.0, 1.5, 1.9], index=pd.Index(model_horizon, name="Time"))

# Estimate baseline demand
demand_per_year = 40 * 12 * 1000 / 8760
light_demand = pd.DataFrame(
    {
        "node": country,
        "commodity": "light",
        "level": "useful",
        "year": model_horizon,
        "time": "year",
        "value": (demand_per_year * gdp_profile).round(),
        "unit": "GWa",
    }
)

# Use `add_par` for adding data to a MESSAGEix parameter
scenario.add_par("demand", light_demand)

The interesting part is that you can use scenario.add_par() to change existing parameter data as well. So if you were to define a new commodity for the light_demand and want to overwrite the existing light_demand, you would also define a new pd.DataFrame (e.g. called new_light_demand and store that in the scenario using scenario.add_par("demand", new_light_demand). Afterwards, scenario.par("demand") should return the updated parameter data.