From 1147f8cc87af7f17c10668924d437e6cb3387678 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Thu, 21 Jan 2021 20:57:31 -0700 Subject: [PATCH 1/4] refactor ModelChain._prep_inputs_solar_pos for wx in poa solpos --- docs/sphinx/source/whatsnew/v0.9.0.rst | 3 +++ pvlib/modelchain.py | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.0.rst b/docs/sphinx/source/whatsnew/v0.9.0.rst index 91254807c8..887d4d50f3 100644 --- a/docs/sphinx/source/whatsnew/v0.9.0.rst +++ b/docs/sphinx/source/whatsnew/v0.9.0.rst @@ -90,6 +90,9 @@ Enhancements Bug fixes ~~~~~~~~~ +* Pass weather data to solar position calculations in + :ref:meth:`~pvlib.modelchain.ModelChain.prepare_inputs_from_poa`. + (:issue:`1065`, :pull:``) Testing ~~~~~~~ diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 9958b89a3b..c9c578bf96 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1210,10 +1210,19 @@ def _complete_irradiance(self, weather): weather.ghi - weather.dni * tools.cosd(self.results.solar_position.zenith)) - def _prep_inputs_solar_pos(self, kwargs={}): + def _prep_inputs_solar_pos(self, weather): """ Assign solar position """ + # build weather kwargs for solar position calculation + kwargs = _build_kwargs(['pressure', 'temp_air'], + weather[0] if isinstance(weather, tuple) + else weather) + try: + kwargs['temperature'] = kwargs.pop('temp_air') + except KeyError: + pass + self.results.solar_position = self.location.get_solarposition( self.times, method=self.solar_position_method, **kwargs) @@ -1363,16 +1372,7 @@ def prepare_inputs(self, weather): self._assign_weather(weather) self._assign_times() - # build kwargs for solar position calculation - try: - press_temp = _build_kwargs(['pressure', 'temp_air'], - weather[0] if isinstance(weather, tuple) - else weather) - press_temp['temperature'] = press_temp.pop('temp_air') - except KeyError: - pass - - self._prep_inputs_solar_pos(press_temp) + self._prep_inputs_solar_pos(weather) self._prep_inputs_airmass() # PVSystem.get_irradiance and SingleAxisTracker.get_irradiance @@ -1470,7 +1470,7 @@ def prepare_inputs_from_poa(self, data): 'poa_diffuse']) self._assign_total_irrad(data) - self._prep_inputs_solar_pos() + self._prep_inputs_solar_pos(data) self._prep_inputs_airmass() if isinstance(self.system, SingleAxisTracker): From da4f66ca1514008868eb1db4eba89a865d5e61b1 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Thu, 21 Jan 2021 20:59:11 -0700 Subject: [PATCH 2/4] pr number --- docs/sphinx/source/whatsnew/v0.9.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.0.rst b/docs/sphinx/source/whatsnew/v0.9.0.rst index 887d4d50f3..5b82f40d95 100644 --- a/docs/sphinx/source/whatsnew/v0.9.0.rst +++ b/docs/sphinx/source/whatsnew/v0.9.0.rst @@ -92,7 +92,7 @@ Bug fixes ~~~~~~~~~ * Pass weather data to solar position calculations in :ref:meth:`~pvlib.modelchain.ModelChain.prepare_inputs_from_poa`. - (:issue:`1065`, :pull:``) + (:issue:`1065`, :pull:`1140`) Testing ~~~~~~~ From 79c4ebc06fc60a316febe597df67e2c0aca5edc3 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 22 Jan 2021 08:37:19 -0700 Subject: [PATCH 3/4] add tests --- pvlib/tests/test_modelchain.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 62877e034a..8e711cce06 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -886,6 +886,20 @@ def test_temperature_models_arrays_multi_weather( != mc.results.cell_temperature[1]).all() +def test_run_model_solar_position_weather( + pvwatts_dc_pvwatts_ac_system, location, weather, mocker): + mc = ModelChain(pvwatts_dc_pvwatts_ac_system, location, + aoi_model='no_loss', spectral_model='no_loss') + weather['pressure'] = 90000 + weather['temp_air'] = 25 + m = mocker.spy(location, 'get_solarposition') + mc.run_model(weather) + # assert_called_once_with cannot be used with series, so need to use + # assert_series_equal on call_args + assert_series_equal(m.call_args.kwargs['temperature'], weather['temp_air']) + assert_series_equal(m.call_args.kwargs['pressure'], weather['pressure']) + + def test_run_model_from_poa(sapm_dc_snl_ac_system, location, total_irrad): mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', spectral_model='no_loss') @@ -909,6 +923,24 @@ def test_run_model_from_poa_arrays(sapm_dc_snl_ac_system_Array, location, assert_frame_equal(mc.results.dc[0], mc.results.dc[1]) +def test_run_model_from_poa_arrays_solar_position_weather( + sapm_dc_snl_ac_system_Array, location, weather, total_irrad, mocker): + data = weather.copy() + data[['poa_global', 'poa_diffuse', 'poa_direct']] = total_irrad + data['pressure'] = 90000 + data['temp_air'] = 25 + data2 = data.copy() + data2['pressure'] = 95000 + data2['temp_air'] = 30 + mc = ModelChain(sapm_dc_snl_ac_system_Array, location, aoi_model='no_loss', + spectral_model='no_loss') + m = mocker.spy(location, 'get_solarposition') + mc.run_model_from_poa((data, data2)) + # mc uses only the first weather data for solar position corrections + assert_series_equal(m.call_args.kwargs['temperature'], data['temp_air']) + assert_series_equal(m.call_args.kwargs['pressure'], data['pressure']) + + def test_run_model_from_poa_tracking(sapm_dc_snl_ac_system, location, total_irrad): system = SingleAxisTracker( From 07fe1e4468adb8537a9ce7d5d66c48e3de688c14 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 22 Jan 2021 08:42:29 -0700 Subject: [PATCH 4/4] compat with py 3.6 and 3.7 --- pvlib/tests/test_modelchain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 8e711cce06..9085b02b13 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -896,8 +896,8 @@ def test_run_model_solar_position_weather( mc.run_model(weather) # assert_called_once_with cannot be used with series, so need to use # assert_series_equal on call_args - assert_series_equal(m.call_args.kwargs['temperature'], weather['temp_air']) - assert_series_equal(m.call_args.kwargs['pressure'], weather['pressure']) + assert_series_equal(m.call_args[1]['temperature'], weather['temp_air']) + assert_series_equal(m.call_args[1]['pressure'], weather['pressure']) def test_run_model_from_poa(sapm_dc_snl_ac_system, location, total_irrad): @@ -937,8 +937,8 @@ def test_run_model_from_poa_arrays_solar_position_weather( m = mocker.spy(location, 'get_solarposition') mc.run_model_from_poa((data, data2)) # mc uses only the first weather data for solar position corrections - assert_series_equal(m.call_args.kwargs['temperature'], data['temp_air']) - assert_series_equal(m.call_args.kwargs['pressure'], data['pressure']) + assert_series_equal(m.call_args[1]['temperature'], data['temp_air']) + assert_series_equal(m.call_args[1]['pressure'], data['pressure']) def test_run_model_from_poa_tracking(sapm_dc_snl_ac_system, location,