From 138317917704016037693125e09bac810d9a126d Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Thu, 11 Mar 2021 20:53:35 -0700 Subject: [PATCH 1/5] fix modelchain with module temperature and arrays --- pvlib/modelchain.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 885353a230..4b2b53d72f 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1520,9 +1520,13 @@ def _prepare_temperature(self, data=None): # broadcast data to all arrays data = (data,) * self.system.num_arrays # find where cell or module temperature is specified in input data + if self.system.num_arrays == 1: + # GH 1192 + t_mod_params = (self.system.temperature_model_parameters, ) + else: + t_mod_params = self.system.temperature_model_parameters given_cell_temperature = tuple(itertools.starmap( - self._get_cell_temperature, - zip(data, poa, self.system.temperature_model_parameters) + self._get_cell_temperature, zip(data, poa, t_mod_params) )) # If cell temperature has been specified for all arrays return # immediately and do not try to compute it. From 0c5bbd9d9ef79e880c974a05dfab6e76c678fe15 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 12 Mar 2021 09:45:17 -0700 Subject: [PATCH 2/5] refactor to directly build from arrays --- pvlib/modelchain.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 4b2b53d72f..990598ae1e 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1519,12 +1519,12 @@ def _prepare_temperature(self, data=None): if not isinstance(data, tuple): # broadcast data to all arrays data = (data,) * self.system.num_arrays + # data is tuple, so temperature_model_parameters must also be + # tuple. system.temperature_model_parameters is reduced to a dict + # if system.num_arrays == 1, so manually access parameters. GH 1192 + t_mod_params = tuple(array.temperature_model_parameters + for array in self.system.arrays) # find where cell or module temperature is specified in input data - if self.system.num_arrays == 1: - # GH 1192 - t_mod_params = (self.system.temperature_model_parameters, ) - else: - t_mod_params = self.system.temperature_model_parameters given_cell_temperature = tuple(itertools.starmap( self._get_cell_temperature, zip(data, poa, t_mod_params) )) From fe95eff4adde0a958d684dd4f60de0da149a522c Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 12 Mar 2021 09:45:24 -0700 Subject: [PATCH 3/5] add test --- pvlib/tests/test_modelchain.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 7b96b409d7..a3e9384a8a 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -830,6 +830,24 @@ def test__prepare_temperature(sapm_dc_snl_ac_system, location, weather, assert_series_equal(mc.results.cell_temperature, data['cell_temperature']) +def test__prepare_temperature_len1_weather_tuple( + sapm_dc_snl_ac_system, location, weather, total_irrad): + # GH 1192 + data = weather.copy() + data[['poa_global', 'poa_diffuse', 'poa_direct']] = total_irrad + data_tuple = (data, ) + mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', + spectral_model='no_loss') + # prepare_temperature expects mc.total_irrad and mc.weather to be set + mc._assign_weather(data_tuple) + mc._assign_total_irrad(data_tuple) + mc._prepare_temperature(data_tuple) + expected = pd.Series([48.928025, 38.080016], index=data.index) + assert_series_equal(mc.results.cell_temperature[0], expected) + data['module_temperature'] = [40., 30.] + assert_series_equal(mc.results.cell_temperature[0], expected) + + def test__prepare_temperature_arrays_weather(sapm_dc_snl_ac_system_same_arrays, location, weather, total_irrad): From 708cefdfdcfcd317773824ac9baf4630236de867 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 12 Mar 2021 10:03:23 -0700 Subject: [PATCH 4/5] improve test --- pvlib/tests/test_modelchain.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index a3e9384a8a..8200b0555a 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -833,18 +833,32 @@ def test__prepare_temperature(sapm_dc_snl_ac_system, location, weather, def test__prepare_temperature_len1_weather_tuple( sapm_dc_snl_ac_system, location, weather, total_irrad): # GH 1192 + weather['module_temperature'] = [40., 30.] data = weather.copy() - data[['poa_global', 'poa_diffuse', 'poa_direct']] = total_irrad - data_tuple = (data, ) + mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', spectral_model='no_loss') - # prepare_temperature expects mc.total_irrad and mc.weather to be set - mc._assign_weather(data_tuple) - mc._assign_total_irrad(data_tuple) - mc._prepare_temperature(data_tuple) + mc.run_model([data]) expected = pd.Series([48.928025, 38.080016], index=data.index) assert_series_equal(mc.results.cell_temperature[0], expected) - data['module_temperature'] = [40., 30.] + + data = weather.copy().rename( + columns={ + "ghi": "poa_global", "dhi": "poa_diffuse", "dni": "poa_direct"} + ) + mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', + spectral_model='no_loss') + mc.run_model_from_poa([data]) + expected = pd.Series([48.928025, 38.080016], index=data.index) + assert_series_equal(mc.results.cell_temperature[0], expected) + + data = weather.copy()["module_temperature", "poa_global"].rename( + columns={"ghi": "effective_irradiance"} + ) + mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', + spectral_model='no_loss') + mc.run_model_from_effective_irradiance([data]) + expected = pd.Series([48.928025, 38.080016], index=data.index) assert_series_equal(mc.results.cell_temperature[0], expected) From 0a4e2f27863e7d143491e10343f2f57a4884bbaf Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Fri, 12 Mar 2021 10:06:34 -0700 Subject: [PATCH 5/5] fix test --- 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 8200b0555a..d4cb14814e 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -839,7 +839,7 @@ def test__prepare_temperature_len1_weather_tuple( mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', spectral_model='no_loss') mc.run_model([data]) - expected = pd.Series([48.928025, 38.080016], index=data.index) + expected = pd.Series([42.617244212941394, 30.0], index=data.index) assert_series_equal(mc.results.cell_temperature[0], expected) data = weather.copy().rename( @@ -849,16 +849,16 @@ def test__prepare_temperature_len1_weather_tuple( mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', spectral_model='no_loss') mc.run_model_from_poa([data]) - expected = pd.Series([48.928025, 38.080016], index=data.index) + expected = pd.Series([41.5, 30.0], index=data.index) assert_series_equal(mc.results.cell_temperature[0], expected) - data = weather.copy()["module_temperature", "poa_global"].rename( + data = weather.copy()[["module_temperature", "ghi"]].rename( columns={"ghi": "effective_irradiance"} ) mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', spectral_model='no_loss') mc.run_model_from_effective_irradiance([data]) - expected = pd.Series([48.928025, 38.080016], index=data.index) + expected = pd.Series([41.5, 30.0], index=data.index) assert_series_equal(mc.results.cell_temperature[0], expected)