@@ -1023,7 +1023,9 @@ def _set_celltemp(self, model):
10231023 -------
10241024 self
10251025 """
1026- poa = _tuple_from_dfs (self .results .total_irrad , 'poa_global' )
1026+
1027+ poa = _irrad_for_celltemp (self .results .total_irrad ,
1028+ self .results .effective_irradiance )
10271029 temp_air = _tuple_from_dfs (self .weather , 'temp_air' )
10281030 wind_speed = _tuple_from_dfs (self .weather , 'wind_speed' )
10291031 self .results .cell_temperature = model (poa , temp_air , wind_speed )
@@ -1464,13 +1466,22 @@ def prepare_inputs_from_poa(self, data):
14641466 return self
14651467
14661468 def _get_cell_temperature (self , data ,
1467- total_irrad , temperature_model_parameters ):
1469+ poa , temperature_model_parameters ):
14681470 """Extract the cell temperature data from a DataFrame.
14691471
1470- If 'cell_temperature' column exists then it is returned. If
1471- 'module_temperature' column exists then it is used to calculate
1472- the cell temperature. If neither column exists then None is
1472+ If 'cell_temperature' column exists in data then it is returned. If
1473+ 'module_temperature' column exists in data, then it is used with poa to
1474+ calculate the cell temperature. If neither column exists then None is
14731475 returned.
1476+
1477+ Parameters
1478+ ----------
1479+ data : DataFrame (not a tuple of DataFrame)
1480+ poa : Series (not a tuple of Series)
1481+
1482+ Returns
1483+ -------
1484+ Series
14741485 """
14751486 if 'cell_temperature' in data :
14761487 return data ['cell_temperature' ]
@@ -1483,14 +1494,14 @@ def _get_cell_temperature(self, data,
14831494 # use SAPM cell temperature model only
14841495 return pvlib .temperature .sapm_cell_from_module (
14851496 module_temperature = data ['module_temperature' ],
1486- poa_global = total_irrad [ 'poa_global' ] ,
1497+ poa_global = poa ,
14871498 deltaT = temperature_model_parameters ['deltaT' ])
14881499
1489- def _prepare_temperature_single_array (self , data ):
1490- """Set cell_temperature using a single weather data frame."""
1500+ def _prepare_temperature_single_array (self , data , poa ):
1501+ """Set cell_temperature using a single data frame."""
14911502 self .results .cell_temperature = self ._get_cell_temperature (
14921503 data ,
1493- self . results . total_irrad ,
1504+ poa ,
14941505 self .system .temperature_model_parameters
14951506 )
14961507 if self .results .cell_temperature is None :
@@ -1505,7 +1516,7 @@ def _prepare_temperature(self, data=None):
15051516 If 'data' contains 'cell_temperature', these values are assigned to
15061517 attribute ``cell_temperature``. If 'data' contains 'module_temperature`
15071518 and `temperature_model' is 'sapm', cell temperature is calculated using
1508- :py:func:`pvlib.temperature.sapm_celL_from_module `. Otherwise, cell
1519+ :py:func:`pvlib.temperature.sapm_cell_from_module `. Otherwise, cell
15091520 temperature is calculated by 'temperature_model'.
15101521
15111522 Parameters
@@ -1521,14 +1532,16 @@ def _prepare_temperature(self, data=None):
15211532 Assigns attribute ``results.cell_temperature``.
15221533
15231534 """
1535+ poa = _irrad_for_celltemp (self .results .total_irrad ,
1536+ self .results .effective_irradiance )
15241537 if not isinstance (data , tuple ) and self .system .num_arrays > 1 :
1538+ # broadcast data to all arrays
15251539 data = (data ,) * self .system .num_arrays
15261540 elif not isinstance (data , tuple ):
1527- return self ._prepare_temperature_single_array (data )
1541+ return self ._prepare_temperature_single_array (data , poa )
15281542 given_cell_temperature = tuple (itertools .starmap (
15291543 self ._get_cell_temperature ,
1530- zip (data , self .results .total_irrad ,
1531- self .system .temperature_model_parameters )
1544+ zip (data , poa , self .system .temperature_model_parameters )
15321545 ))
15331546 # If cell temperature has been specified for all arrays return
15341547 # immediately and do not try to compute it.
@@ -1716,10 +1729,8 @@ def run_model_from_effective_irradiance(self, data=None):
17161729 ----------
17171730 data : DataFrame, or list or tuple of DataFrame
17181731 Required column is ``'effective_irradiance'``.
1719- If optional column ``'cell_temperature'`` is provided, these values
1720- are used instead of `temperature_model`. If optional column
1721- ``'module_temperature'`` is provided, `temperature_model` must be
1722- ``'sapm'``.
1732+ Optional columns include ``'cell_temperature'``,
1733+ ``'module_temperature'`` and ``'poa_global'``.
17231734
17241735 If the ModelChain's PVSystem has multiple arrays, `data` must be a
17251736 list or tuple with the same length and order as the PVsystem's
@@ -1740,6 +1751,20 @@ def run_model_from_effective_irradiance(self, data=None):
17401751
17411752 Notes
17421753 -----
1754+ Optional ``data`` columns ``'cell_temperature'``,
1755+ ``'module_temperature'`` and ``'poa_global'`` are used for determining
1756+ cell temperature.
1757+
1758+ * If optional column ``'cell_temperature'`` is present, these values
1759+ are used and `temperature_model` is ignored.
1760+ * If optional column ``'module_temperature'`` is preset,
1761+ `temperature_model` must be ``'sapm'``.
1762+ * Otherwise, cell temperature is calculated using `temperature_model`.
1763+
1764+ The cell temperature models require plane-of-array irradiance as input.
1765+ If optional column ``'poa_global'`` is present, these data are used.
1766+ If ``'poa_global'`` is not present, ``'effective_irradiance'`` is used.
1767+
17431768 Assigns attributes: ``weather``, ``total_irrad``,
17441769 ``effective_irradiance``, ``cell_temperature``, ``dc``, ``ac``,
17451770 ``losses``, ``diode_params`` (if dc_model is a single diode model).
@@ -1760,6 +1785,29 @@ def run_model_from_effective_irradiance(self, data=None):
17601785 return self
17611786
17621787
1788+ def _irrad_for_celltemp (total_irrad , effective_irradiance ):
1789+ """
1790+ Determine irradiance to use for cell temperature models, in order
1791+ of preference 'poa_global' then 'effective_irradiance'
1792+
1793+ Returns
1794+ -------
1795+ Series or tuple of Series
1796+ tuple if total_irrad is a tuple of DataFrame
1797+
1798+ """
1799+ if isinstance (total_irrad , tuple ):
1800+ if all (['poa_global' in df for df in total_irrad ]):
1801+ return _tuple_from_dfs (total_irrad , 'poa_global' )
1802+ else :
1803+ return effective_irradiance
1804+ else :
1805+ if 'poa_global' in total_irrad :
1806+ return total_irrad ['poa_global' ]
1807+ else :
1808+ return effective_irradiance
1809+
1810+
17631811def _snl_params (inverter_params ):
17641812 """Return True if `inverter_params` includes parameters for the
17651813 Sandia inverter model."""
0 commit comments