-
Notifications
You must be signed in to change notification settings - Fork 154
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
Adjust calculation of PRICE_EMISSION #726
base: main
Are you sure you want to change the base?
Conversation
Note that there are 3 relevant failing tests (in |
I'm not so sure about that. # message_ix.Reporter can also be initialized
rep = Reporter.from_scenario(scen)
# Number of quantities available in a rudimentary MESSAGEix Scenario
> assert 268 == len(rep.graph["all"])
E assert 268 == 272
E + where 272 = len([<ACT:nl-t-yv-ya-m-h>, <ACTIVITY_BOUND_ALL_MODES_LO-margin:n-t-y-h>, <ACTIVITY_BOUND_ALL_MODES_LO:n-t-y-h>, <ACTIVITY_BOUND_ALL_MODES_UP-margin:n-t-y-h>, <ACTIVITY_BOUND_ALL_MODES_UP:n-t-y-h>, <ACTIVITY_BOUND_LO-margin:>, ...]) Here, we have a hardcoded number of quantities we expect in a MESSAGEix Scenario. However, this PR changes the number of quantities by adding these lines to par("df_year", "y")
par("df_period", "y")
par("levelized_cost", "n t y h")
var(
"PRICE_EMISSION_NEW",
"n type_emission type_tec y",
"TEMPORARY test for Emission price fix",
) Now, I can't see the whole output of what For nb_path = PosixPath('/home/runner/work/message_ix/message_ix/tutorial/westeros/westeros_report.ipynb')
checks = [('len-rep-graph', 13724)]
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/popen-gw1/test_tutorial_westeros_report_5')
tmp_env = environ({'_R_CHECK_SYSTEM_CLOCK_': 'FALSE', 'SELENIUM_JAR_PATH': '/usr/share/java/selenium-server.jar', 'CONDA': '/usr...FRAME_EVAL': 'NO', 'PYTEST_CURRENT_TEST': 'message_ix/tests/test_tutorials.py::test_tutorial[westeros_report] (call)'})
@pytest.mark.parametrize("nb_path,checks", TUTORIALS, ids=IDS, indirect=["nb_path"])
def test_tutorial(nb_path, checks, tmp_path, tmp_env):
"""Test tutorial in the IPython or IR notebook at `nb_path`.
If `checks` are given, values in the specified cells are tested.
"""
if nb_path.name == "westeros_baseline_using_xlsx_import_part2.ipynb":
# Copy data files used by this tutorial to `tmp_path`
for name in DATA_FILES:
copyfile(nb_path.parent / name, tmp_path / name)
# Determine arguments for run_notebook()
args = default_args()
if nb_path.name.startswith("R_"):
args.update(kernel_name="IR")
# The notebook can be run without errors
nb, errors = run_notebook(nb_path, tmp_path, tmp_env, **args)
assert errors == []
# Cell(s) identified by name or index have a particular value
for cell, value in checks:
> assert np.isclose(get_cell_output(nb, cell), value)
E assert False
E + where False = <function isclose at 0x7f36903354c0>(13775, 13724)
E + where <function isclose at 0x7f36903354c0> = np.isclose
E + and 13775 = get_cell_output({'cells': [{'attachments': {}, 'cell_type': 'markdown', 'metadata': {}, 'source': '# Westeros Tutorial - Introducing reporting\n\n‘Reporting’ is the term used in the MESSAGEix ecosystem to refer to any calculations performed _after_ the MESSAGE mathematical optimization problem has been solved.\n\nThis tutorial introduces the reporting features provided by the ``ixmp`` and ``message_ix`` packages.\nIt was developed by Paul Natsuo Kishimoto ([@khaeru](https://github.com/khaeru)) for a MESSAGEix training workshop held at IIASA in October 2019.\nParticipants in the MESSAGEix workshops of June and September 2020 contributed feedback.\n<!-- Add a line here if you revise the tutorial! -->\n\n**Pre-requisites**\n- You have the *MESSAGEix* framework installed and working\n In particular, you should have installed ``message_ix[report]``, which requires ``ixmp[report]``, ``genno[compat]``, and ``plotnine``\n- Complete tutorial Part 1 (``westeros_baseline.ipynb``)\n - Understand the following MESSAGEix terms: ‘variable’, ‘parameter’\n- Open the [‘Reporting’ page in the MESSAGEix documentation](https://docs.messageix.org/en/stable/reporting.html); bookmark it or keep it open in a tab.\n S...pe': 'stream', 'name': 'stdout', 'text': "'E':\n- <lambda>\n- 'A':\n - 1\n- 'C':\n - sum_calc\n - 'A' (above)\n - 'B':\n - 2\n- 'D':\n - 12\n"}, {'output_type': 'execute_result', 'metadata': {}, 'data': {'text/plain': '5.0'}, 'execution_count': 31}], 'source': 'rep.add("D", 12)\nrep.add("E", (lambda a, c, d: a + d * (a / c), "A", "C", "D"))\nprint(rep.describe("E"))\n\nrep.get("E")\n'}, {'cell_type': 'code', 'execution_count': 32, 'metadata': {'execution': {'iopub.status.busy': '2023-12-01T09:49:15.984386Z', 'iopub.execute_input': '2023-12-01T09:49:15.984888Z', 'iopub.status.idle': '2023-12-01T09:49:16.144007Z', 'shell.execute_reply': '2023-12-01T09:49:16.142901Z'}}, 'outputs': [], 'source': 'mp.close_db()\n'}], 'metadata': {'kernelspec': {'display_name': 'message_ix', 'language': 'python', 'name': 'python3'}, 'language_info': {'name': 'python', 'version': '3.8.18', 'mimetype': 'text/x-python', 'codemirror_mode': {'name': 'ipython', 'version': 3}, 'pygments_lexer': 'ipython3', 'nbconvert_exporter': 'python', 'file_extension': '.py'}, 'vscode': {'interpreter': {'hash': '29605b568787f5559ca1ba05da75d155c3dcfa15a1a63b1885b057c5465ade2e'}}}, 'nbformat': 4, 'nbformat_minor': 2}, 'len-rep-graph') As we can see, the error arises related to reporting again. It is comparing another expected hardcoded number to an actual number. Looking at our test setup, we are only checking the result of a single cell in this notebook; the cell len(rep.graph) So this seems related, too. My suggestion for this is very similar to the error above: clean up this PR and see what value comes out (e.g. by quickly running the tutorial), then use that to update the expected value. |
This will be postponed together with the originating issue since we don't have enough time for a proper cleanup right now. |
As discussed in the weekly meeting on February 15, @behnam-zakeri will continue this PR. Please let me know if I can assist with anything here. |
@glatterf42 thanks for following up on this in today's meeting. I went through the test and actually the tests are not using Westeros tutorials but building new models for testing this. I started to test the changes in this PR using Westeros tutorials. I followed the logic below:
I ran this setup for two types of emission bounds, cumulative and yearly, using Westeros tutorials. My observation is that:
So, my first reaction is that:
Maybe @OFR-IIASA and @gidden can help here. |
Hey @behnam-zakeri - thanks so much for looking into this so quickly. I have a comment and two questions:
|
Dear Behnam, As there were existing test, the idea was to leave those in place and extend the test examples covered, while also making sure that the results are the SAME as opposed to just "close". The test for "duality" was "close" before, but the allowed tolerance was too large, hence the error in the formulation wasnt caught. As you rightly point out, there are a few different cases to test, but I have made a few more adjustments below. TEST 1.: Equal length time periods // CUMULATIVE bound TEST 2.: Unequal length time periods // CUMULATIVE bound TEST 3.: Equal length time periods // PERIOD bound TEST 4.: Unequal length time periods // PERIOD bound TEST 5.: Test price duality
-> Scenario
In the end, we need to ensure that the carbon-price from a cumulative constraint, provides the same emission trajectory per period as the cumulative trajectory when applied as |
@gidden thanks for the reflection. |
@OFR-IIASA thanks for the updates and confirming the logic for the tests. I see your point, if we need varying model periods we need to develop a new test model. |
41c5dd1
to
99f6866
Compare
Thanks for continuing the work here, @behnam-zakeri! Any further improvements to reach our goal are much appreciated :) |
@glatterf42 I made the following changes and now this PR is ready for reviewing/improving the tests. Indeed, the existing tests are good enough, but a few of them, i.e., The changes made today are:
|
Still working on getting test case 5 to work. I've tried using This might speak to a problem in the conversion between emission bounds and emission prices. If anyone has any idea how to troubleshoot this further or even what specifically might cause this problem, I'm happy to take suggestions :) |
I'm sad to have to postpone this (and #723) beyond 3.9, but it doesn't look like this PR will be ready still this week. We could consider releasing 3.9.1 if this gets merged not too long after our 3.9 release. |
@behnam-zakeri suggested earlier today that it might be useful to take the |
ec88a76
to
968881a
Compare
I'm running various scenarios locally, trying out different combinations of technologies, formulations of Today, I have noticed the following: following @OFR-IIASA's description for TEST 5 is very similar to what we're doing in the emissions_taxes tutorial. There, @behnam-zakeri has written the following when comparing However, I asked the same in the MESSAGE meeting yesterday and the consensus was that the test should run if the model setup is right, i.e. if there are enough gradual options to shift from high to low emission-technologies and the model is not just using one until it can't, when it switches entirely to another technology. cumulative_bound = 40
> print(scenario_cumulative_bound.var("EMISS"))
node emission type_tec year lvl mrg
0 World CO2 all 2020 85.0 0.0
1 World CO2 all 2025 85.0 0.0
2 World CO2 all 2030 85.0 0.0
3 World CO2 all 2040 0.0 0.0
4 World CO2 all 2045 0.0 0.0
5 World CO2 all 2050 25.0 0.0
6 node CO2 all 2020 85.0 0.0
7 node CO2 all 2025 85.0 0.0
8 node CO2 all 2030 85.0 0.0
9 node CO2 all 2040 0.0 0.0
10 node CO2 all 2045 0.0 0.0
11 node CO2 all 2050 25.0 0.0
> print(scen_tax.var("EMISS"))
node emission type_tec year lvl mrg
0 World CO2 all 2020 500.0 0.0
1 World CO2 all 2025 500.0 0.0
2 World CO2 all 2030 500.0 0.0
3 World CO2 all 2040 0.0 0.0
4 World CO2 all 2045 0.0 0.0
5 World CO2 all 2050 25.0 0.0
6 node CO2 all 2020 500.0 0.0
7 node CO2 all 2025 500.0 0.0
8 node CO2 all 2030 500.0 0.0
9 node CO2 all 2040 0.0 0.0
10 node CO2 all 2045 0.0 0.0
11 node CO2 all 2050 25.0 0.0 This now makes me think: our current way of calculating |
This PR revises the calculation of the
PRICE_EMISSION
to correctly account for the period-duration when deriving the period-specificPRICE_EMISSION
from a single marginal value which covers multiple periods (cumulative constraint).How to review
developer (someone like the reviewer) will be able to understand what the code
does in the future.
PR checklist