-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add Array.get_cell_temperature, PVSystem.get_cell_temperature #1211
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
Conversation
PSM3 test failures presumably related to NREL/developer.nrel.gov#208 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks really good to me. The dancing around effective_irradiance
is a little awkward, but I don't have a good recommendation for an alternative.
@@ -1009,26 +1009,26 @@ def _set_celltemp(self, model): | |||
temp_air = _tuple_from_dfs(self.results.weather, 'temp_air') | |||
wind_speed = _tuple_from_dfs(self.results.weather, 'wind_speed') | |||
kwargs = {} | |||
if model == self.system.noct_sam_celltemp: | |||
if model == 'noct_sam': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring says that model
is a function, it's changed to be a string here and elsewhere.
With this change, is ModelChain.temperature_model
needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change, is ModelChain.temperature_model needed?
I think this question remains, but it should be explored in a separate issue.
pvlib/pvsystem.py
Outdated
params = _build_kwargs(['transmittance_absorptance', 'eta_m_ref', | ||
'noct', 'array_height', 'mount_standoff'], | ||
self.temperature_model_parameters) | ||
if not {'noct', 'eta_m_ref'}.issubset(params): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be a good idea to parallel this error message for the other temperature models.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how I feel about this. Without a check like this, the error message isn't as helpful as it could be -- TypeError: noct_sam() missing 1 required positional argument: 'noct'
makes no mention of temperature_model_parameters
. But I'm not really a fan of having all these lists of pvlib.temperature
parameter names in pvlib.pvsystem
.
What do you think about letting python raise the TypeError
and we add a hint to the error message like this:
try:
temperature_cell = func(poa_global, temp_air, wind_speed, **params)
except TypeError as e:
msg = e.args[0] + (
". Check temperature_model_parameters to make sure "
"all required parameters are specified."
)
raise TypeError(msg)
Downside is that it adds irrelevant noise to TypeErrors caused by other problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't stand in the way of this PR over error messaging. If we want to verify parameters at this stage, as a kindness to users, maybe a dict in pvlib.temperature
akin to pvlib.pvsystem._DC_MODEL_PARAMS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is that we're using _build_kwargs
to build all of the arguments instead of just the optional keyword arguments. I suggest a pattern that performs explicit look ups instead of deferred checks. Fine with me to use the standard python KeyError or break into the kinder message template.
args = (self.temperature_model_par[arg] for arg in required_args)
kwargs = _build_kwargs(optional_args, self.temperature_model_parameters)
required_args and optional_args could come from a private dict like @cwhanse suggests. I'm also ok with hard coding it here (sounds easy). And I'm ok with using inspect
(I vaguely recall considering this previously and thinking it was too complicated for pvlib, but I currently like it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added something along these lines, let me know what you think.
pvlib/pvsystem.py
Outdated
params = _build_kwargs(['transmittance_absorptance', 'eta_m_ref', | ||
'noct', 'array_height', 'mount_standoff'], | ||
self.temperature_model_parameters) | ||
if not {'noct', 'eta_m_ref'}.issubset(params): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the problem is that we're using _build_kwargs
to build all of the arguments instead of just the optional keyword arguments. I suggest a pattern that performs explicit look ups instead of deferred checks. Fine with me to use the standard python KeyError or break into the kinder message template.
args = (self.temperature_model_par[arg] for arg in required_args)
kwargs = _build_kwargs(optional_args, self.temperature_model_parameters)
required_args and optional_args could come from a private dict like @cwhanse suggests. I'm also ok with hard coding it here (sounds easy). And I'm ok with using inspect
(I vaguely recall considering this previously and thinking it was too complicated for pvlib, but I currently like it).
pvlib/pvsystem.py
Outdated
|
||
# allow kwargs to override | ||
params.update(kwargs) | ||
temperature_cell = func(poa_global, temp_air, wind_speed, **params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here I would use *args
and **kwargs
Co-authored-by: Cliff Hansen <[email protected]>
Checks are green. Anything left on this one? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Close. A few minor things and a larger question about if we can replace **kwargs
with effective_irradiance=None
.
mc.run_model(weather) | ||
assert m_sapm.call_count == 1 | ||
# assert_called_once_with cannot be used with series, so need to use | ||
# assert_series_equal on call_args | ||
assert_series_equal(m_sapm.call_args[0][1], weather['temp_air']) # temp | ||
assert_series_equal(m_sapm.call_args[0][2], weather['wind_speed']) # wind | ||
assert m_sapm.call_args[1]['model'] == 'sapm' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No objection to this. An alternative is modifying the spy line to mocker.spy(temperature, 'sapm_cell')
and dropping this line.
pvlib/pvsystem.py
Outdated
# additional model-specific (and array-specific) inputs | ||
extra_inputs = [{}] * self.num_arrays | ||
|
||
if 'effective_irradiance' in kwargs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we cannot add effective_irradiance=None
to the method signature and drop kwargs
? I don't see one, but I feel like I might be forgetting something from a previous discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I was anticipating new models with new weather inputs, but better to cross that bridge if we come to it. The code is much simpler now without this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kanderso-nrel. @cwhanse can you take another look, especially double checking the handling of effective_irradiance
? Ok with me to merge if you approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks to me that ModelChain.temperature_model
becomes obsolete with addition of these methods. I could be mistaken. Separate issue, in either case.
Closes #xxxxdocs/sphinx/source/api.rst
for API changes.docs/sphinx/source/whatsnew
for all changes. Includes link to the GitHub Issue with:issue:`num`
or this Pull Request with:pull:`num`
. Includes contributor name and/or GitHub username (link with:ghuser:`user`
).Trying out the idea from #1176 (comment). If merged, I'd then update #1176 to have
Array.get_cell_temperature
grab the model parameters from theArray
'sMount
.