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

Resolve the issue of zero capacity factor #561

Merged
merged 16 commits into from
Apr 26, 2022

Conversation

behnam-zakeri
Copy link
Contributor

@behnam-zakeri behnam-zakeri commented Feb 16, 2022

This PR adds tests for parameter "capacity_factor" to address the requirements mentioned in #515.

How to review

Please make a copy of this branch, run the test with the existing code, and the tests should pass.

PR checklist

  • Reduce duplication, i.e. don't have identical model_generator() methods in test_feature_temporal_level.py and test_feature_capacity_factor.py (@khaeru)
  • Continuous integration checks all ✅
  • Add or expand tests; coverage checks both ✅
  • Release notes added.

@codecov
Copy link

codecov bot commented Feb 16, 2022

Codecov Report

Merging #561 (53641ea) into main (27bdc65) will increase coverage by 0.1%.
The diff coverage is n/a.

@@           Coverage Diff           @@
##            main    #561     +/-   ##
=======================================
+ Coverage   92.7%   92.8%   +0.1%     
=======================================
  Files         41      42      +1     
  Lines       3236    3287     +51     
=======================================
+ Hits        3001    3052     +51     
  Misses       235     235             
Impacted Files Coverage Δ
message_ix/message_ix/models.py 100.0% <0.0%> (ø)
...ix/message_ix/tests/test_feature_temporal_level.py 100.0% <0.0%> (ø)
...x/message_ix/tests/test_feature_capacity_factor.py 100.0% <0.0%> (ø)
message_ix/message_ix/testing/__init__.py 99.6% <0.0%> (+<0.1%) ⬆️

@behnam-zakeri behnam-zakeri changed the title Add test for capacity factor Resolve the issue of zero capacity factor Feb 16, 2022
@behnam-zakeri
Copy link
Contributor Author

@khaeru, I went further and resolved the issue in the GAMS formulation, by adding a new masking set ("is_capacity_factor"). For populating this set on the python side, I copied the code you suggested in #514 (the part related to the enforce() method). I wanted to make sure that the tests designed here will work if we correct the formulation. Now, you can decide if we should add enforce() workflow here, or in a separate PR.

@khaeru
Copy link
Member

khaeru commented Feb 21, 2022

Will jump in here once #559 is addressed.

khaeru pushed a commit to behnam-zakeri/message_ix that referenced this pull request Apr 25, 2022
@khaeru
Copy link
Member

khaeru commented Apr 25, 2022

Reduce duplication, i.e. don't have identical model_generator() methods in test_feature_temporal_level.py and test_feature_capacity_factor.py (@khaeru)

@behnam-zakeri I've now done this (about 2.5 hours), saving us about 400 lines of code in the test files while still doing all the same tests. To me, at least, they are now easier to read & distinguish from one another. However, one question came up in the process, so I hope you can help:

Two of the tests (test_two_seasons_to_year_relative and test_linked_three_temporal_levels_relative) had the following pattern of code:

def test_func():
    try:
        do_stuff()
    except AssertionError:
        pass

This test will pass if do_stuff() raises an AssertionError. But it will also pass if do_stuff() doesn't raise any error at all. So the expected behaviour is ambiguous.

I changed these to the standard way of using pytest:

def test_func():
    with pytest.raises(AssertionError):
        do_stuff()

This is more explicit: it will pass if do_stuff() raises an AssertionError as expected, but the test will fail if the error is not raised.

I find these tests now fail. From the docstrings/comments:

  • test_two_seasons_to_year_relative says "Model should not solve," meaning we expect some kind of failure?
  • test_linked_three_temporal_levels_relative says "Model solves" in the docstring but, in contrast, "Shouldn't pass with a relative time duration" in the comments.

Can you identify what's going on in each case? What do we actually expect—maybe that the model actually should solve in each case, but the assertions in check_solution(scen) should fail?

@khaeru
Copy link
Member

khaeru commented Apr 25, 2022

maybe that the model actually should solve in each case, but the assertions in check_solution(scen) should fail?

The last commit makes this change, and the tests now pass, so I assume that was the case.

@khaeru khaeru requested a review from a team April 25, 2022 11:31
khaeru pushed a commit to behnam-zakeri/message_ix that referenced this pull request Apr 25, 2022
@behnam-zakeri
Copy link
Contributor Author

Thanks a lot @khaeru for reformatting and improvements. Related to your question
“ … that the model actually should solve in each case, but the assertions in check_solution(scen) should fail? that the model actually should solve in each case, but the assertions in check_solution(scen) should fail?”
As you identified in these cases the model should solve but Assersion checks must not pass. These checks ensure commodity balances wok as expected across different temporal levels.

@khaeru khaeru added this to the 3.5 milestone Apr 25, 2022
@LauWien LauWien requested review from LauWien and removed request for a team April 26, 2022 06:31
behnam-zakeri and others added 10 commits April 26, 2022 09:22
- Adapted from .test_feature_capacity_factor.model_generator() with the
  following improvements:

  - Don't generate and assert in the same function; split assertions to
    a separate function, check_solution() that remains with test code.
  - Use the pytest `request` fixture to access `test_mp` instead of
    passing it separately.
  - Use `request.node.name` instead of defining and passing a `comment`
    argument.
  - Remove the `year` argument, since calls to the function never
    override the default.
  - Collapse separate function add_cap_par() into the function body,
    since this is the only place it is used.
  - Use make_df() instead of assuming dimension order.

- Use PEP 257-compliant docstrings, i.e. initial line is a single line.
Copy link
Contributor

@LauWien LauWien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you! Just some, suggestions in line.

if existing.equals(expected):
continue # Contents are as expected; do nothing
# else:
# scenario.add_set(set_name, expected)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure, both lines above are commented.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm not sure why; they're not on #514 from which this was cherry-picked. That PR will need to be deconflicted when it is rebased, so we can clean up/remove then.

message_ix/tests/test_feature_temporal_level.py Outdated Show resolved Hide resolved
tec_dict["gas_ppl"]["time_origin"] = ["year"]

scen = make_subannual(
request,
tec_dict,
time_steps=[("summer", 1, "season", "year")],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also think about moving this up and create e.g. TS_0 to reduce duplication (this line and line 75).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, true. I skipped this one because it doesn't save on # of lines.

message_ix/tests/test_feature_capacity_factor.py Outdated Show resolved Hide resolved
message_ix/tests/test_feature_capacity_factor.py Outdated Show resolved Hide resolved
Co-authored-by: Laura Wienpahl <57132039+LauWien@users.noreply.github.com>
@khaeru
Copy link
Member

khaeru commented Apr 26, 2022

Thanks for the review! Will merge once checks again pass.

@khaeru
Copy link
Member

khaeru commented Apr 26, 2022

Thanks @behnam-zakeri for the contributions! 🎉

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

Successfully merging this pull request may close these issues.

Zero values for capacity_factor are changed to 1 in GAMS
3 participants