Description
Is your feature request related to a problem? Please describe.
TEMPERATURE_MODEL_PARAMETERS
is mentioned several times in the docs, but it isn't published in the api
Describe the solution you'd like
add a docstring after the constant definition in temperature.py
like this (exact wording tbd):
TEMPERATURE_MODEL_PARAMETERS = {
'sapm': {
'open_rack_glass_glass': {'a': -3.47, 'b': -.0594, 'deltaT': 3},
'close_mount_glass_glass': {'a': -2.98, 'b': -.0471, 'deltaT': 1},
'open_rack_glass_polymer': {'a': -3.56, 'b': -.0750, 'deltaT': 3},
'insulated_back_glass_polymer': {'a': -2.81, 'b': -.0455, 'deltaT': 0},
},
'pvsyst': {'freestanding': {'u_c': 29.0, 'u_v': 0},
'insulated': {'u_c': 15.0, 'u_v': 0}}
}
"""Dictionary of temperature parameters organized by model.
There are keys for each model at the top level. Currently there are two models,
``sapm`` for the Sandia Array Performance Model, and ``pvsyst``. Each model has
a dictionary of configurations with a dictionary of the model parameters
associated with it. Retrieve a parameters by indexing the model and
configuration by name.
Example
-------
Retrieve the open rack glass-polymer configuration for SAPM::
from pvlib.temperature import TEMPERATURE_MODEL_PARAMS
temp_params = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer']
"""
Then somewhere in the docs add an autodata
directive to publish the constant data to the api, like this:
Temperature Model Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. currentmodule:: pvlib.temperature
.. autodata:: TEMPERATURE_MODEL_PARAMETERS
:annotation:
note: remove :annotation:
to show the value of the dictionary
depending on where it goes, you might have to return the module namespace to whatever it was before this entry using something like this:
.. currentmodule:: pvlib
to return it to pvlib
for example if this was in api.rst
and can be referenced everywhere in the docs using:
:data:`~pvlib.temperature.TEMPERATURE_MODEL_PARAMETERS`
Ideas for where to put it?
- in
api.rst
in the subsection called "PV Temperature Models" part of "PV Modeling" - in
pvsystem.rst
at the end after SAT, in a new section called "temperature" - huh?
Describe alternatives you've considered
- instead of using a dictionary, use a constant class and then add it to the temperature section of
api.rst
after the Faiman model, here's an example:
class _IndexAttrMeta(type):
"""private meta class to index class attributes like a dictionary"""
def __getitem__(self, item):
# retrieve items by index like a dictionary
return getattr(self, str(item).lower())
class TEMPERATURE_MODEL_PARAMETERS(metaclass=_IndexAttrMeta):
"""Dictionary of temperature parameters organized by model.
There are keys for each model at the top level. Currently there are two models,
``sapm`` for the Sandia Array Performance Model, and ``pvsyst``. Each model has
a dictionary of configurations with a dictionary of the model parameters
associated with it. Retrieve a parameters by indexing the model and
configuration by name.
Example
-------
Retrieve the open rack glass-polymer configuration for SAPM::
from pvlib.temperature import TEMPERATURE_MODEL_PARAMS
temp_params = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer']
"""
# NOTE: only Python-2 uses __metaclass__,
# Python-3 passes this to the class as an argument,
# see: https://docs.python.org/3/library/2to3.html#2to3fixer-metaclass
# __metaclass__ = _IndexAttrMeta
#: Sandia Array Performance Model
sapm = {
'open_rack_glass_glass': {'a': -3.47, 'b': -.0594, 'deltaT': 3},
'close_mount_glass_glass': {'a': -2.98, 'b': -.0471, 'deltaT': 1},
'open_rack_glass_polymer': {'a': -3.56, 'b': -.0750, 'deltaT': 3},
'insulated_back_glass_polymer': {'a': -2.81, 'b': -.0455, 'deltaT': 0}}
#: PVSyst model
pvsyst = {'freestanding': {'u_c': 29.0, 'u_v': 0},
'insulated': {'u_c': 15.0, 'u_v': 0}}
So this works just like it did before:
In [1]: from pvlib.temperature import TEMPERATURE_MODEL_PARAMETERS
In [2]: TEMPERATURE_MODEL_PARAMETERS['sapm']
Out[2]:
{'open_rack_glass_glass': {'a': -3.47, 'b': -0.0594, 'deltaT': 3},
'close_mount_glass_glass': {'a': -2.98, 'b': -0.0471, 'deltaT': 1},
'open_rack_glass_polymer': {'a': -3.56, 'b': -0.075, 'deltaT': 3},
'insulated_back_glass_polymer': {'a': -2.81, 'b': -0.0455, 'deltaT': 0}}
In [3]: TEMPERATURE_MODEL_PARAMETERS['pvsyst']
Out[3]: {'freestanding': {'u_c': 29.0, 'u_v': 0}, 'insulated': {'u_c': 15.0, 'u_v': 0}}
and all of the tests pass
$ pytest pvlib/tests/test_temperature.py
================================================= test session starts =================================================
platform win32 -- Python 3.6.8, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\mikm\Projects, inifile: pytest.ini
plugins: cov-2.8.1, mock-2.0.0, remotedata-0.3.2, rerunfailures-8.0, timeout-1.3.4
collected 14 items
pvlib\tests\test_temperature.py .............. [100%]
================================================== warnings summary ===================================================
pvlib\tests\test_temperature.py:5
C:\Users\mikm\Projects\pvlib-python\pvlib\tests\test_temperature.py:5: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
from pandas.util.testing import assert_series_equal
-- Docs: https://docs.pytest.org/en/latest/warnings.html
============================================ 14 passed, 1 warning in 0.07s ============================================
Now just add it to api.rst
PV temperature models
---------------------
.. autosummary::
:toctree: generated/
temperature.sapm_cell
temperature.sapm_module
temperature.pvsyst_cell
temperature.faiman
temperature.TEMPERATURE_MODEL_PARAMETERS
and it will be documented on it's own generated page like other functions
currently, I can't figure out how to remove the __init__
method which is not supposed to be documented, but this isn't my first choice anyway, so if this alternate is the way to go, perhaps someone else can figure out how to remove it?
- another option would be to just make it a class, but this would require changing
TEMPERATURE_MODEL_PARAMETERS
usage everywhere to use attributes instead of items, likeTEMPERATURE_MODEL_PARAMETERS.sapm
. This option is probably the easiest technically, and safest for readability, but requires some grunt work to find all useage and replace indexing with dot notation.
class TEMPERATURE_MODEL_PARAMETERS:
"""Dictionary of temperature parameters organized by model.
There are keys for each model at the top level. Currently there are two models,
``sapm`` for the Sandia Array Performance Model, and ``pvsyst``. Each model has
a dictionary of configurations with a dictionary of the model parameters
associated with it. Retrieve a parameters by indexing the model and
configuration by name.
Example
-------
Retrieve the open rack glass-polymer configuration for SAPM::
from pvlib.temperature import TEMPERATURE_MODEL_PARAMS
temp_params = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer']
"""
#: Sandia Array Performance Model
sapm = {
'open_rack_glass_glass': {'a': -3.47, 'b': -.0594, 'deltaT': 3},
'close_mount_glass_glass': {'a': -2.98, 'b': -.0471, 'deltaT': 1},
'open_rack_glass_polymer': {'a': -3.56, 'b': -.0750, 'deltaT': 3},
'insulated_back_glass_polymer': {'a': -2.81, 'b': -.0455, 'deltaT': 0}}
#: PVSyst model
pvsyst = {'freestanding': {'u_c': 29.0, 'u_v': 0},
'insulated': {'u_c': 15.0, 'u_v': 0}}
- even a more complicated option would be to figure out how use properties to make the models immutable, but just like
__getitem__
, the property decorator only acts on instances so you would have to figure out how to add it to a metaclass, which is really going too far now:
class Meta(type):
@staticmethod
def bind_geta(a):
# bind `a` so it doesn't change in the loop
def geta(self):
return getattr(self, a)
# return the bound function `geta`
return geta
def __getitem__(self, arg):
return getattr(self, arg)
def __new__(cls, name, bases, attrs):
for a in attrs:
if a.startswith('__'):
continue
if not a.startswith('_'):
# create the property as an attribute of Meta
setattr(cls, a[1:], property(Meta.bind_geta(a)))
return super().__new__(cls, name, bases, attrs)
class TEMPERATURE_MODEL_PARAMETERS(metaclass=Meta):
"""Dictionary of temperature parameters organized by model.
There are keys for each model at the top level. Currently there are two models,
``sapm`` for the Sandia Array Performance Model, and ``pvsyst``. Each model has
a dictionary of configurations with a dictionary of the model parameters
associated with it. Retrieve a parameters by indexing the model and
configuration by name.
Example
-------
Retrieve the open rack glass-polymer configuration for SAPM::
from pvlib.temperature import TEMPERATURE_MODEL_PARAMS
temp_params = TEMPERATURE_MODEL_PARAMETERS['sapm']['open_rack_glass_polymer']
"""
_sapm = {
'open_rack_glass_glass': {'a': -3.47, 'b': -.0594, 'deltaT': 3},
'close_mount_glass_glass': {'a': -2.98, 'b': -.0471, 'deltaT': 1},
'open_rack_glass_polymer': {'a': -3.56, 'b': -.0750, 'deltaT': 3},
'insulated_back_glass_polymer': {'a': -2.81, 'b': -.0455, 'deltaT': 0}}
_pvsyst = {'freestanding': {'u_c': 29.0, 'u_v': 0},
'insulated': {'u_c': 15.0, 'u_v': 0}}
Additional context
see #938