Skip to content

fix run_model_from_effective_irradiance with iterable weather and excluding cell temperature #1165

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

Merged
merged 8 commits into from
Feb 8, 2021

Conversation

cwhanse
Copy link
Member

@cwhanse cwhanse commented Feb 6, 2021

Moves check for complete POA for cell temperature calculations to ModelChain._set_celltemp.
Adds testing for weather/data input type (tuple, list) to tests for ModelChain.run_from_effective_irradiance

@cwhanse
Copy link
Member Author

cwhanse commented Feb 6, 2021

@wholmgren @wfvining one test is failing. I actually think the ModelChain should run with that that test setup, since effective_irradiance is provided for every array. The cell temperature model can use effective_irradiance since #1129. PTAL and let me know if you agree.

@wfvining
Copy link
Contributor

wfvining commented Feb 8, 2021

That does seem reasonable to me. If we remove that test, we should make sure that there is still a test that covers the case where one array does not have enough information to calculate cell temperature.

@wholmgren
Copy link
Member

I agree.

@cwhanse
Copy link
Member Author

cwhanse commented Feb 8, 2021

That does seem reasonable to me. If we remove that test, we should make sure that there is still a test that covers the case where one array does not have enough information to calculate cell temperature.

I had to call _set_celltemp directly to get a case that raises the ValueError. Missing 'poa_global' is covered by the new test__set_celltemp_missing_poa. Missing 'poa_global' or effective_irradiance are caught upstream by the _check_multiple_input steps of run_from_poa and run_from_effective_irradiance.

@wholmgren
Copy link
Member

wholmgren commented Feb 8, 2021

I had to call _set_celltemp directly to get a case that raises the ValueError

This suggests to me that the ValueError is only accessible from private calls and cannot be hit through run_* method calls. Am I misunderstanding?

@cwhanse
Copy link
Member Author

cwhanse commented Feb 8, 2021

I had to call _set_celltemp directly to get a case that raises the ValueError

This suggests to me that the ValueError is only accessible from private calls and cannot be hit through run_* method calls. Am I misunderstanding?

I believe that to be the case, but could be wrong.

@wholmgren
Copy link
Member

Why keep it if we can't hit it through the run method calls?

@cwhanse
Copy link
Member Author

cwhanse commented Feb 8, 2021

I had to call _set_celltemp directly to get a case that raises the ValueError

This suggests to me that the ValueError is only accessible from private calls and cannot be hit through run_* method calls. Am I misunderstanding?

  • With ModelChain.run_model, prepare_inputs calls _check_multiple_input to verify that weather has the same dimension as num_arrays, and calls _verify_df to verify that 'ghi', 'dhi' and 'dni' are present in weather.
  • With ModelChain.run_model_from_poa, prepare_inputs_from_poa calls _check_multiple_input to verify that data has the same dimension as num_arrays, and _verify_df to verify that data contains 'poa_global', 'poa_direct' and 'poa_diffuse'.
  • With ModelChain.run_model_from_effective_irradiance, there is no prepare_inputs method. _check_multiple_input is called to verify that data has the same dimension as num_arrays. There is no use of _verify_df to check for effective_irradiance in data. Seems like an oversight here.

All three public run_model methods end up at _run_from_effective_irrad, which calls _prepare_temperature and that's how execution gets to _set_celltemp.

@cwhanse
Copy link
Member Author

cwhanse commented Feb 8, 2021

Why keep it if we can't hit it through the run method calls?

Good question. I'm OK removing that check. @wfvining ?

@wholmgren
Copy link
Member

wholmgren commented Feb 8, 2021

There is no use of _verify_df to check for effective_irradiance in data. Seems like an oversight here.

I agree.

Maybe out of scope for this PR, but I think we could refactor _prepare_temperature to use _verify_df in try/except blocks that parallel the logic in run_model_from_effective_irradiance docstring. I still struggle to understand _prepare_temperature every time I come back to it. We also now have the benefit of a ModelChainResults setter that will ensure the output type is correct.

@wholmgren
Copy link
Member

wholmgren commented Feb 8, 2021

We also need to add or change a test to cover the specific case in #1163. All of the test_run_model_from_effective_irradiance_* functions include POA data, while #1163 only has effective irradiance. That might be why we're not hitting the error from the run method calls - not confident in that.

@wholmgren
Copy link
Member

#1163 is test_run_model_from_effective_irradiance_no_poa_global but with an iterable input.

@wfvining
Copy link
Contributor

wfvining commented Feb 8, 2021

Why keep it if we can't hit it through the run method calls?

Good question. I'm OK removing that check. @wfvining ?

I'm okay removing it or just making it catch any generic exception as opposed to a specific ValueError. I think given the amount of state maintained inside ModelChain, once missing data is allowed inside of modelchain it can be very difficult to notice or debug problems, so these kinds of tests are pretty valuable.

Maybe out of scope for this PR, but I think we could refactor _prepare_temperature to use _verify_df in try/except blocks that parallel the logic in run_model_from_effective_irradiance docstring. I still struggle to understand _prepare_temperature every time I come back to it

I would support refactoring this. My guess is that the bulk of the technical debt in ModelChain is related to _prepare_temperature.

@wholmgren
Copy link
Member

wholmgren commented Feb 8, 2021

I think this should do it:

@pytest.mark.parametrize("input_type", [lambda x: x[0], tuple, list])
def test_run_model_from_effective_irradiance_no_poa_global(
        sapm_dc_snl_ac_system, location, weather, total_irrad, input_type):
    data = weather.copy()
    data['effective_irradiance'] = total_irrad['poa_global']
    mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss',
                    spectral_model='no_loss')
    ac = mc.run_model_from_effective_irradiance(input_type((data,))).results.ac
    expected = pd.Series(np.array([149.280238, 96.678385]),
                         index=data.index)
    # if isinstance(ac, (tuple, list)):
    #     ac = ac[0]
    assert_series_equal(ac, expected)

edit: I commented out the if isinstance(ac, (tuple, list)) check because ac is always a Series.

@wholmgren wholmgren added this to the 0.9.0 milestone Feb 8, 2021
@wholmgren wholmgren added the bug label Feb 8, 2021
@cwhanse
Copy link
Member Author

cwhanse commented Feb 8, 2021

I would support refactoring this.

As would I. New issue though.

I would also propose that we consider combining _check_multiple_inputs and _verify_df to hopefully make these checks more easily understood in the future. The only separate use of this pair of methods is in complete_irradiance which doesn't use _verify_df and instead explicitly looks for 2 of 'ghi', 'dhi' and 'dni'. Maybe that check could be built into _verify_df.

Copy link
Member

@wholmgren wholmgren left a comment

Choose a reason for hiding this comment

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

minor suggestions below. I confirmed this resolves the example in #1163.

Comment on lines 1000 to 1001
# check with data as an iterable of length 1
mc.run_model_from_effective_irradiance(input_type((data,)))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# check with data as an iterable of length 1
mc.run_model_from_effective_irradiance(input_type((data,)))



@pytest.mark.parametrize("input_type", [tuple, list])
def test_run_model_from_effective_irradiance_input_type(
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def test_run_model_from_effective_irradiance_input_type(
def test_run_model_from_effective_irradiance_multi_array(

"only a subset of Arrays you must provide "
"'poa_global' for all Arrays, including those "
"that have a known 'cell_temperature'.")
# ModelChain.temperature_model().
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# ModelChain.temperature_model().

@wholmgren wholmgren changed the title Add completeness check to ModelChain._set_celltemp fix run_model_from_effective_irradiance with iterable weather and excluding cell temperature Feb 8, 2021
@wholmgren wholmgren merged commit b666520 into pvlib:master Feb 8, 2021
@cwhanse
Copy link
Member Author

cwhanse commented Feb 8, 2021

Ok to merge

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

Successfully merging this pull request may close these issues.

ValueError: ModelChain.run_from_effective_irradiance([weather]) when only providing temp_air and wind_speed
3 participants