From 9317efbe3d40d186d135ffe66abc4a6d92a336a9 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Mon, 11 Jan 2021 11:08:45 -0700 Subject: [PATCH 1/9] add switch between poa_global and effective_irradiance for cell temperature models --- pvlib/modelchain.py | 24 +++++++++++++++++++++--- pvlib/tests/test_modelchain.py | 12 ++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index c5414fdc12..b215f4f29a 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1023,7 +1023,8 @@ def _set_celltemp(self, model): ------- self """ - poa = _tuple_from_dfs(self.results.total_irrad, 'poa_global') + + poa = self._irrad_for_celltemp() temp_air = _tuple_from_dfs(self.weather, 'temp_air') wind_speed = _tuple_from_dfs(self.weather, 'wind_speed') self.results.cell_temperature = model(poa, temp_air, wind_speed) @@ -1041,6 +1042,21 @@ def faiman_temp(self): def fuentes_temp(self): return self._set_celltemp(self.system.fuentes_celltemp) + def _irrad_for_celltemp(self): + """ + Determine irradiance to use for cell temperature models, in order + of preference 'poa_global' or 'effective_irradiance' + + Returns + ------- + None. + + """ + if all(['poa_global' in df for df in self.results.total_irrad]): + return _tuple_from_dfs(self.results.total_irrad, 'poa_global') + else: + return self.results.effective_irradiance + @property def losses_model(self): return self._losses_model @@ -1481,9 +1497,10 @@ def _get_cell_temperature(self, data, if (('module_temperature' in data) and (self.temperature_model == self.sapm_temp)): # use SAPM cell temperature model only + poa = self._irrad_for_celltemp() return pvlib.temperature.sapm_cell_from_module( module_temperature=data['module_temperature'], - poa_global=total_irrad['poa_global'], + poa_global=poa, deltaT=temperature_model_parameters['deltaT']) def _prepare_temperature_single_array(self, data): @@ -1505,7 +1522,7 @@ def _prepare_temperature(self, data=None): If 'data' contains 'cell_temperature', these values are assigned to attribute ``cell_temperature``. If 'data' contains 'module_temperature` and `temperature_model' is 'sapm', cell temperature is calculated using - :py:func:`pvlib.temperature.sapm_celL_from_module`. Otherwise, cell + :py:func:`pvlib.temperature.sapm_cell_from_module`. Otherwise, cell temperature is calculated by 'temperature_model'. Parameters @@ -1522,6 +1539,7 @@ def _prepare_temperature(self, data=None): """ if not isinstance(data, tuple) and self.system.num_arrays > 1: + # broadcast data to all arrays data = (data,) * self.system.num_arrays elif not isinstance(data, tuple): return self._prepare_temperature_single_array(data) diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 4e09f77f84..9288d62715 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -918,6 +918,18 @@ def test_run_model_from_effective_irradiance(sapm_dc_snl_ac_system, location, assert_series_equal(ac, expected) +def test_run_model_from_effective_irradiance_no_poa_global( + sapm_dc_snl_ac_system, location, weather, total_irrad): + data = weather.copy() + data['effective_irradiance'] = data['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(data).results.ac + expected = pd.Series(np.array([149.280238, 96.678385]), + index=data.index) + assert_series_equal(ac, expected) + + @pytest.mark.parametrize("input_type", [tuple, list]) def test_run_model_from_effective_irradiance_arrays_error( sapm_dc_snl_ac_system_Array, location, weather, total_irrad, From 68b7cf768f6df4ed52e18a14abcc75557461d2ad Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 12 Jan 2021 14:55:28 -0700 Subject: [PATCH 2/9] handle tuple and single DF --- pvlib/modelchain.py | 12 +++++++++--- pvlib/tests/test_modelchain.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index b215f4f29a..dba3fb4b26 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1052,10 +1052,16 @@ def _irrad_for_celltemp(self): None. """ - if all(['poa_global' in df for df in self.results.total_irrad]): - return _tuple_from_dfs(self.results.total_irrad, 'poa_global') + if isinstance(self.results.total_irrad, tuple): + if all(['poa_global' in df for df in self.results.total_irrad]): + return _tuple_from_dfs(self.results.total_irrad, 'poa_global') + else: + return self.results.effective_irradiance else: - return self.results.effective_irradiance + if 'poa_global' in self.results.total_irrad: + return self.results.total_irrad['poa_global'] + else: + return self.results.effective_irradiance @property def losses_model(self): diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 9288d62715..9de1fafab1 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -921,7 +921,7 @@ def test_run_model_from_effective_irradiance(sapm_dc_snl_ac_system, location, def test_run_model_from_effective_irradiance_no_poa_global( sapm_dc_snl_ac_system, location, weather, total_irrad): data = weather.copy() - data['effective_irradiance'] = data['poa_global'] + 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(data).results.ac From 8166cf6de91a03f285f9bdfd2617b00b2281ffb8 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 12 Jan 2021 15:42:11 -0700 Subject: [PATCH 3/9] handle tuples etc., improve some docstrings --- pvlib/modelchain.py | 32 ++++++++++++++++++++++---------- pvlib/temperature.py | 4 ++-- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index dba3fb4b26..6fa163e83b 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1024,7 +1024,8 @@ def _set_celltemp(self, model): self """ - poa = self._irrad_for_celltemp() + poa = self._irrad_for_celltemp(self.results.total_irrad, + self.results.effective_irradiance) temp_air = _tuple_from_dfs(self.weather, 'temp_air') wind_speed = _tuple_from_dfs(self.weather, 'wind_speed') self.results.cell_temperature = model(poa, temp_air, wind_speed) @@ -1042,7 +1043,8 @@ def faiman_temp(self): def fuentes_temp(self): return self._set_celltemp(self.system.fuentes_celltemp) - def _irrad_for_celltemp(self): + @staticmethod + def _irrad_for_celltemp(total_irrad, effective_irradiance): """ Determine irradiance to use for cell temperature models, in order of preference 'poa_global' or 'effective_irradiance' @@ -1052,16 +1054,16 @@ def _irrad_for_celltemp(self): None. """ - if isinstance(self.results.total_irrad, tuple): - if all(['poa_global' in df for df in self.results.total_irrad]): - return _tuple_from_dfs(self.results.total_irrad, 'poa_global') + if isinstance(total_irrad, tuple): + if all(['poa_global' in df for df in total_irrad]): + return _tuple_from_dfs(total_irrad, 'poa_global') else: - return self.results.effective_irradiance + return effective_irradiance else: - if 'poa_global' in self.results.total_irrad: - return self.results.total_irrad['poa_global'] + if 'poa_global' in total_irrad: + return total_irrad['poa_global'] else: - return self.results.effective_irradiance + return effective_irradiance @property def losses_model(self): @@ -1493,6 +1495,15 @@ def _get_cell_temperature(self, data, 'module_temperature' column exists then it is used to calculate the cell temperature. If neither column exists then None is returned. + + Parameters + ---------- + data : DataFrame (not a tuple of DataFrame) + total_irrad : DataFrame (not a tuple of DataFrame) + + Returns + ------- + Series """ if 'cell_temperature' in data: return data['cell_temperature'] @@ -1503,7 +1514,8 @@ def _get_cell_temperature(self, data, if (('module_temperature' in data) and (self.temperature_model == self.sapm_temp)): # use SAPM cell temperature model only - poa = self._irrad_for_celltemp() + poa = self._irrad_for_celltemp(self.results.total_irrad, + self.results.effective_irradiance) return pvlib.temperature.sapm_cell_from_module( module_temperature=data['module_temperature'], poa_global=poa, diff --git a/pvlib/temperature.py b/pvlib/temperature.py index 1f27180a9a..03871143e8 100644 --- a/pvlib/temperature.py +++ b/pvlib/temperature.py @@ -49,7 +49,7 @@ def _temperature_model_params(model, parameter_set): def sapm_cell(poa_global, temp_air, wind_speed, a, b, deltaT, - irrad_ref=1000): + irrad_ref=1000.): r''' Calculate cell temperature per the Sandia Array Performance Model. @@ -215,7 +215,7 @@ def sapm_module(poa_global, temp_air, wind_speed, a, b): def sapm_cell_from_module(module_temperature, poa_global, deltaT, - irrad_ref=1000): + irrad_ref=1000.): r''' Calculate cell temperature from module temperature using the Sandia Array Performance Model. From 7e54534b62af0b99cb95eba54d8c1e850c63f2f2 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 12 Jan 2021 16:24:03 -0700 Subject: [PATCH 4/9] more handle tuples --- pvlib/modelchain.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 6fa163e83b..16b46b2747 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1488,18 +1488,18 @@ def prepare_inputs_from_poa(self, data): return self def _get_cell_temperature(self, data, - total_irrad, temperature_model_parameters): + poa, temperature_model_parameters): """Extract the cell temperature data from a DataFrame. - If 'cell_temperature' column exists then it is returned. If - 'module_temperature' column exists then it is used to calculate - the cell temperature. If neither column exists then None is + If 'cell_temperature' column exists in data then it is returned. If + 'module_temperature' column exists in data, then it is used with poa to + calculate the cell temperature. If neither column exists then None is returned. Parameters ---------- data : DataFrame (not a tuple of DataFrame) - total_irrad : DataFrame (not a tuple of DataFrame) + poa : Series (not a tuple of Series) Returns ------- @@ -1514,18 +1514,16 @@ def _get_cell_temperature(self, data, if (('module_temperature' in data) and (self.temperature_model == self.sapm_temp)): # use SAPM cell temperature model only - poa = self._irrad_for_celltemp(self.results.total_irrad, - self.results.effective_irradiance) return pvlib.temperature.sapm_cell_from_module( module_temperature=data['module_temperature'], poa_global=poa, deltaT=temperature_model_parameters['deltaT']) - def _prepare_temperature_single_array(self, data): - """Set cell_temperature using a single weather data frame.""" + def _prepare_temperature_single_array(self, data, poa): + """Set cell_temperature using a single data frame.""" self.results.cell_temperature = self._get_cell_temperature( data, - self.results.total_irrad, + poa, self.system.temperature_model_parameters ) if self.results.cell_temperature is None: @@ -1556,6 +1554,8 @@ def _prepare_temperature(self, data=None): Assigns attribute ``results.cell_temperature``. """ + poa = self._irrad_for_celltemp(self.results.total_irrad, + self.results.effective_irradiance) if not isinstance(data, tuple) and self.system.num_arrays > 1: # broadcast data to all arrays data = (data,) * self.system.num_arrays @@ -1563,8 +1563,7 @@ def _prepare_temperature(self, data=None): return self._prepare_temperature_single_array(data) given_cell_temperature = tuple(itertools.starmap( self._get_cell_temperature, - zip(data, self.results.total_irrad, - self.system.temperature_model_parameters) + zip(data, poa, self.system.temperature_model_parameters) )) # If cell temperature has been specified for all arrays return # immediately and do not try to compute it. From 40d87346726e7b6624dfe818bfd781baa7452a3a Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 12 Jan 2021 16:29:25 -0700 Subject: [PATCH 5/9] add missing argument --- pvlib/modelchain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 16b46b2747..1e979ac951 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1560,7 +1560,7 @@ def _prepare_temperature(self, data=None): # broadcast data to all arrays data = (data,) * self.system.num_arrays elif not isinstance(data, tuple): - return self._prepare_temperature_single_array(data) + return self._prepare_temperature_single_array(data, poa) given_cell_temperature = tuple(itertools.starmap( self._get_cell_temperature, zip(data, poa, self.system.temperature_model_parameters) From c720a759711a777b5d5e8d2133845bfd555e8a75 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 13 Jan 2021 11:42:36 -0700 Subject: [PATCH 6/9] whatsnew --- docs/sphinx/source/whatsnew/v0.9.0.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/sphinx/source/whatsnew/v0.9.0.rst b/docs/sphinx/source/whatsnew/v0.9.0.rst index f06b1d8140..cb8b6dbdfd 100644 --- a/docs/sphinx/source/whatsnew/v0.9.0.rst +++ b/docs/sphinx/source/whatsnew/v0.9.0.rst @@ -46,6 +46,10 @@ Enhancements :py:class:`~pvlib.pvsystem.PVSystem` and :py:class:`~pvlib.modelchain.ModelChain` (as ``ac_model='sandia_multi'``). (:pull:`1076`, :issue:`1067`) +* :py:class:`~pvlib.modelchain.ModelChain` 'run_model' methods now + automatically switch to using 'effective_irradiance' (if available) for + cell temperature models, when 'poa_global' is not provided in input weather + or calculated from input weather data. Bug fixes ~~~~~~~~~ From 2211fed4b521d3e21820d789c87746fcf0966b6e Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 13 Jan 2021 15:51:11 -0700 Subject: [PATCH 7/9] edits from review, add test for different poa_global and effective_irradiance --- docs/sphinx/source/whatsnew/v0.9.0.rst | 6 +++--- pvlib/modelchain.py | 24 ++++++++++++++++++------ pvlib/tests/test_modelchain.py | 15 ++++++++++++++- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.0.rst b/docs/sphinx/source/whatsnew/v0.9.0.rst index cb8b6dbdfd..1094973bd5 100644 --- a/docs/sphinx/source/whatsnew/v0.9.0.rst +++ b/docs/sphinx/source/whatsnew/v0.9.0.rst @@ -47,9 +47,9 @@ Enhancements :py:class:`~pvlib.modelchain.ModelChain` (as ``ac_model='sandia_multi'``). (:pull:`1076`, :issue:`1067`) * :py:class:`~pvlib.modelchain.ModelChain` 'run_model' methods now - automatically switch to using 'effective_irradiance' (if available) for - cell temperature models, when 'poa_global' is not provided in input weather - or calculated from input weather data. + automatically switch to using ``'effective_irradiance'`` (if available) for + cell temperature models, when ``'poa_global'`` is not provided in input + weather or calculated from input weather data. Bug fixes ~~~~~~~~~ diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 1e979ac951..f0536aa514 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1047,11 +1047,12 @@ def fuentes_temp(self): def _irrad_for_celltemp(total_irrad, effective_irradiance): """ Determine irradiance to use for cell temperature models, in order - of preference 'poa_global' or 'effective_irradiance' + of preference 'poa_global' then 'effective_irradiance' Returns ------- - None. + Series of tuple of Series + tuple if total_irrad is a tuple of DataFrame """ if isinstance(total_irrad, tuple): @@ -1751,10 +1752,8 @@ def run_model_from_effective_irradiance(self, data=None): ---------- data : DataFrame, or list or tuple of DataFrame Required column is ``'effective_irradiance'``. - If optional column ``'cell_temperature'`` is provided, these values - are used instead of `temperature_model`. If optional column - ``'module_temperature'`` is provided, `temperature_model` must be - ``'sapm'``. + Optional columns include ``'cell_temperature'``, + ``'module_temperature'`` and ``'poa_global'``. If the ModelChain's PVSystem has multiple arrays, `data` must be a list or tuple with the same length and order as the PVsystem's @@ -1775,6 +1774,19 @@ def run_model_from_effective_irradiance(self, data=None): Notes ----- + Optional `data` columns ``'cell_temperature'``, + ``'module_temperature'`` and ``'poa_global'`` are used for determining + cell temperature. + * If optional column ``'cell_temperature'`` is present, these values + are used and `temperature_model` is ignored. + * If optional column ``'module_temperature'`` is preset, + `temperature_model` must be ``'sapm'``. + * Otherwise, cell temperature is calculated using `temperature_model`. + + The cell temperature models require plane-of-array irradiance as input. + If optional column ``'poa_global'`` is present, these data are used. + If ``'poa_global'`` is not present, ``'effective_irradiance'`` is used. + Assigns attributes: ``weather``, ``total_irrad``, ``effective_irradiance``, ``cell_temperature``, ``dc``, ``ac``, ``losses``, ``diode_params`` (if dc_model is a single diode model). diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 9de1fafab1..a45430e7b7 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -802,7 +802,7 @@ def test__prepare_temperature_arrays_weather(sapm_dc_snl_ac_system_same_arrays, location, weather, total_irrad): data = weather.copy() - data[['poa_global', 'poa_diffuse', 'poa_direct']] = total_irrad + data[['poa_global', 'poa_direct', 'poa_diffuse']] = total_irrad data_two = data.copy() mc = ModelChain(sapm_dc_snl_ac_system_same_arrays, location, aoi_model='no_loss', spectral_model='no_loss') @@ -930,6 +930,19 @@ def test_run_model_from_effective_irradiance_no_poa_global( assert_series_equal(ac, expected) +def test_run_model_from_effective_irradiance_poa_global_differs( + sapm_dc_snl_ac_system, location, weather, total_irrad): + data = weather.copy() + data[['poa_global', 'poa_diffuse', 'poa_direct']] = total_irrad + data['effective_irradiance'] = data['poa_global'] * 0.8 + mc = ModelChain(sapm_dc_snl_ac_system, location, aoi_model='no_loss', + spectral_model='no_loss') + ac = mc.run_model_from_effective_irradiance(data).results.ac + expected = pd.Series(np.array([118.302801, 76.099841]), + index=data.index) + assert_series_equal(ac, expected) + + @pytest.mark.parametrize("input_type", [tuple, list]) def test_run_model_from_effective_irradiance_arrays_error( sapm_dc_snl_ac_system_Array, location, weather, total_irrad, From 9174fe323fa2ddacb7ff88da343e7aebfabff515 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 13 Jan 2021 15:51:30 -0700 Subject: [PATCH 8/9] move to helper function, add test --- pvlib/modelchain.py | 54 +++++++++++++++++----------------- pvlib/tests/test_modelchain.py | 23 +++++++++++++++ 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index f0536aa514..ead487814a 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1024,8 +1024,8 @@ def _set_celltemp(self, model): self """ - poa = self._irrad_for_celltemp(self.results.total_irrad, - self.results.effective_irradiance) + poa = _irrad_for_celltemp(self.results.total_irrad, + self.results.effective_irradiance) temp_air = _tuple_from_dfs(self.weather, 'temp_air') wind_speed = _tuple_from_dfs(self.weather, 'wind_speed') self.results.cell_temperature = model(poa, temp_air, wind_speed) @@ -1043,29 +1043,6 @@ def faiman_temp(self): def fuentes_temp(self): return self._set_celltemp(self.system.fuentes_celltemp) - @staticmethod - def _irrad_for_celltemp(total_irrad, effective_irradiance): - """ - Determine irradiance to use for cell temperature models, in order - of preference 'poa_global' then 'effective_irradiance' - - Returns - ------- - Series of tuple of Series - tuple if total_irrad is a tuple of DataFrame - - """ - if isinstance(total_irrad, tuple): - if all(['poa_global' in df for df in total_irrad]): - return _tuple_from_dfs(total_irrad, 'poa_global') - else: - return effective_irradiance - else: - if 'poa_global' in total_irrad: - return total_irrad['poa_global'] - else: - return effective_irradiance - @property def losses_model(self): return self._losses_model @@ -1555,8 +1532,8 @@ def _prepare_temperature(self, data=None): Assigns attribute ``results.cell_temperature``. """ - poa = self._irrad_for_celltemp(self.results.total_irrad, - self.results.effective_irradiance) + poa = _irrad_for_celltemp(self.results.total_irrad, + self.results.effective_irradiance) if not isinstance(data, tuple) and self.system.num_arrays > 1: # broadcast data to all arrays data = (data,) * self.system.num_arrays @@ -1807,6 +1784,29 @@ def run_model_from_effective_irradiance(self, data=None): return self +def _irrad_for_celltemp(total_irrad, effective_irradiance): + """ + Determine irradiance to use for cell temperature models, in order + of preference 'poa_global' then 'effective_irradiance' + + Returns + ------- + Series of tuple of Series + tuple if total_irrad is a tuple of DataFrame + + """ + if isinstance(total_irrad, tuple): + if all(['poa_global' in df for df in total_irrad]): + return _tuple_from_dfs(total_irrad, 'poa_global') + else: + return effective_irradiance + else: + if 'poa_global' in total_irrad: + return total_irrad['poa_global'] + else: + return effective_irradiance + + def _snl_params(inverter_params): """Return True if `inverter_params` includes parameters for the Sandia inverter model.""" diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index a45430e7b7..2987ae563f 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -1770,3 +1770,26 @@ def test_modelchain__common_keys(): assert {'b'} == modelchain._common_keys( (series, no_a) ) + + +def test__irrad_for_celltemp(): + total_irrad = pd.DataFrame(index=[0, 1], columns=['poa_global'], + data=[10., 20.]) + empty = total_irrad.drop('poa_global', axis=1) + effect_irrad = pd.Series(index=total_irrad.index, data=[5., 8.]) + # test with single array inputs + poa = modelchain._irrad_for_celltemp(total_irrad, effect_irrad) + assert_series_equal(poa, total_irrad['poa_global']) + poa = modelchain._irrad_for_celltemp(empty, effect_irrad) + assert_series_equal(poa, effect_irrad) + # test with tuples + poa = modelchain._irrad_for_celltemp( + (total_irrad, total_irrad), (effect_irrad, effect_irrad)) + assert len(poa) == 2 + assert_series_equal(poa[0], total_irrad['poa_global']) + assert_series_equal(poa[1], total_irrad['poa_global']) + poa = modelchain._irrad_for_celltemp( + (empty, empty), (effect_irrad, effect_irrad)) + assert len(poa) == 2 + assert_series_equal(poa[0], effect_irrad) + assert_series_equal(poa[1], effect_irrad) From 8c3e643720e187596da7cd280824400706e2f6bb Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Thu, 14 Jan 2021 10:28:14 -0700 Subject: [PATCH 9/9] edits --- pvlib/modelchain.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index ead487814a..4c67e835f4 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -1751,9 +1751,10 @@ def run_model_from_effective_irradiance(self, data=None): Notes ----- - Optional `data` columns ``'cell_temperature'``, + Optional ``data`` columns ``'cell_temperature'``, ``'module_temperature'`` and ``'poa_global'`` are used for determining cell temperature. + * If optional column ``'cell_temperature'`` is present, these values are used and `temperature_model` is ignored. * If optional column ``'module_temperature'`` is preset, @@ -1791,7 +1792,7 @@ def _irrad_for_celltemp(total_irrad, effective_irradiance): Returns ------- - Series of tuple of Series + Series or tuple of Series tuple if total_irrad is a tuple of DataFrame """