From 18797ea8aaec375ef0f21f0e231be5b900b3a642 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Sun, 9 May 2021 14:24:31 -0600 Subject: [PATCH 01/27] revise for new run_model methods, .results attribute, multiple arrays --- docs/sphinx/source/modelchain.rst | 181 +++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 51 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 716e37b396..d87ee5a79d 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -24,8 +24,8 @@ Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: 1. Creating the :py:class:`~.ModelChain`. 2. Executing the :py:meth:`ModelChain.run_model() <.ModelChain.run_model>` method with prepared weather data. -3. Examining the model results that :py:meth:`~.ModelChain.run_model` - stored in attributes of the :py:class:`~.ModelChain`. +3. Examining the model results that are stored in the ModelChain attribute + ``results`` as an instance of :py:class:`~.ModelChainResults`. A simple ModelChain example --------------------------- @@ -81,26 +81,27 @@ Next, we run a model with some simple weather data. columns=['ghi', 'dni', 'dhi', 'temp_air', 'wind_speed'], index=[pd.Timestamp('20170401 1200', tz='US/Arizona')]) - mc.run_model(weather); + mc.run_model(weather) -ModelChain stores the modeling results on a series of attributes. A few -examples are shown below. +ModelChain stores the modeling results in the ``results`` attribute. The +``results`` attribute is an instance of :py:class:`~ModelChainResult`. A few +examples of attributes of :py:class:`~ModelChainResult` are shown below. .. ipython:: python - mc.aoi + mc.results.aoi .. ipython:: python - mc.cell_temperature + mc.result.cell_temperature .. ipython:: python - mc.dc + mc.result.dc .. ipython:: python - mc.ac + mc.result.ac The remainder of this guide examines the ModelChain functionality and explores common pitfalls. @@ -161,9 +162,9 @@ model, AC model, AOI loss model, and spectral loss model. mc.ac Alternatively, we could have specified single diode or PVWatts related -information in the PVSystem construction. Here we pass PVWatts data to -the PVSystem. ModelChain will automatically determine that it should -choose PVWatts DC and AC models. ModelChain still needs us to specify +information in the PVSystem construction. Here we assign parameters for +PVWatts models to the PVSystem. ModelChain will automatically determine that +it should choose PVWatts DC and AC models. ModelChain still needs us to specify ``aoi_model`` and ``spectral_model`` keyword arguments because the ``system.module_parameters`` dictionary does not contain enough information to determine which of those models to choose. @@ -218,12 +219,21 @@ The key parts of ModelChain are: 3. A set of methods that inspect user-supplied objects to determine the appropriate default models. -run_model -~~~~~~~~~ +run_model methods +~~~~~~~~~~~~~~~~~ + +ModelChain provides three methods for executing the chain of models. The +methods allow for simulating the output of the PVSystem with different +input irradiance data: -Most users will only interact with the -:py:meth:`~pvlib.modelchain.ModelChain.run_model` method. The -:py:meth:`~pvlib.modelchain.ModelChain.run_model` method, shown below, +| ModelChain method | Input data | +| :--------------------------| :------------------------------| +| :py:meth:`~pvlib.modelchain.ModelChain.run_model` | GHI, DHI and DNI | +| :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_poa` | Broadband direct, diffuse and total irradiance in plane of array | +| :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_effective_irradiance poa` | Spectrally- and reflection-adjusted total irradiance in plane of array | + +To illustrate the use of a `run_model` method, assume that a user has GHI, DHI +and DNI. The :py:meth:`~pvlib.modelchain.ModelChain.run_model` method, shown below, calls a series of methods to complete the modeling steps. The first method, :py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs`, computes parameters such as solar position, airmass, angle of incidence, and @@ -232,30 +242,31 @@ plane of array irradiance. The assigns default values for temperature (20 C) and wind speed (0 m/s) if these inputs are not provided. :py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` requires all irradiance -components (GHI, DNI, and DHI). See -:py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` and +components (GHI, DNI, and DHI). The +:py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` +method is available for calculating the full set of GHI, DNI, or DHI if +only two of these three series are provided. See also :ref:`dniestmodels` for methods and functions that can help fully define the irradiance inputs. Next, :py:meth:`~pvlib.modelchain.ModelChain.run_model` calls the wrapper methods for AOI loss, spectral loss, effective irradiance, cell temperature, DC power, AC power, and other losses. These methods are -assigned to standard names, as described in the next section. +assigned to generic names, as described in the next section. The methods called by :py:meth:`~pvlib.modelchain.ModelChain.run_model` -store their results in a series of ModelChain attributes: ``times``, -``solar_position``, ``airmass``, ``irradiance``, ``total_irrad``, -``effective_irradiance``, ``weather``, ``temps``, ``aoi``, -``aoi_modifier``, ``spectral_modifier``, ``dc``, ``ac``, ``losses``. +store their results in the ``results`` attribute, which is an instance of +:py:class:`~ModelChainResult`. :py:class:`~ModelChainResult` has the following +attributes: +``weather``, ``times``, ``solar_position``, ``airmass``, ``total_irrad``, +``aoi``, ``aoi_modifier``, ``spectral_modifier``,``effective_irradiance``, +``cell_temperature``, ``dc``, ``ac``, ``losses``, ``tracking``, +``diode_params``. .. ipython:: python mc.run_model?? -Finally, the :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` -method is available for calculating the full set of GHI, DNI, or DHI if -only two of these three series are provided. The completed dataset can -then be passed to :py:meth:`~pvlib.modelchain.ModelChain.run_model`. Wrapping methods into a unified API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -263,7 +274,7 @@ Wrapping methods into a unified API Readers may notice that the source code of the ModelChain.run_model method is model-agnostic. ModelChain.run_model calls generic methods such as ``self.dc_model`` rather than a specific model such as -``singlediode``. So how does the ModelChain.run_model know what models +``pvwatts_dc``. So how does the ModelChain.run_model know what models it’s supposed to run? The answer comes in two parts, and allows us to explore more of the ModelChain API along the way. @@ -279,10 +290,11 @@ the ModelChain.pvwatts_dc method is shown below. Its only argument is mc.pvwatts_dc?? The ModelChain.pvwatts_dc method calls the pvwatts_dc method of the -PVSystem object that we supplied using data that is stored in its own -``effective_irradiance`` and ``cell_temperature`` attributes. Then it assigns the -result to the ``dc`` attribute of the ModelChain object. The code below -shows a simple example of this. +PVSystem object that we supplied when we created the ModelChain instance, +using data that is stored in the ModelChain ``effective_irradiance`` and +``cell_temperature`` attributes. The ModelChain.pvwatts_dc method assigns its +result to the ``dc`` attribute of the ModelChain's results object. The code +below shows a simple example of this. .. ipython:: python @@ -301,20 +313,22 @@ shows a simple example of this. # run ModelChain.pvwatts_dc and look at the result mc.pvwatts_dc(); - mc.dc + mc.results.dc The ModelChain.sapm method works similarly to the ModelChain.pvwatts_dc method. It calls the PVSystem.sapm method using stored data, then -assigns the result to the ``dc`` attribute. The ModelChain.sapm method -differs from the ModelChain.pvwatts_dc method in three notable ways. -First, the PVSystem.sapm method expects different units for effective -irradiance, so ModelChain handles the conversion for us. Second, the -PVSystem.sapm method (and the PVSystem.singlediode method) returns a -DataFrame with current, voltage, and power parameters rather than a -simple Series of power. Finally, this current and voltage information -allows the SAPM and single diode model paths to support the concept of -modules in series and parallel, which is handled by the -PVSystem.scale_voltage_current_power method. +assigns the result to the ``dc`` attribute of ModelChain.results. +The ModelChain.sapm method differs from the ModelChain.pvwatts_dc method in +a notable way: the PVSystem.sapm method returns a DataFrame with current, +voltage, and power results, rather than a simple Series +of power. The ModelChain methods for single diode models (e.g., +:py:meth:`~pvlib.modelchain.ModelChain.desoto` also return a DataFrame with +current, voltage and power, and a second DataFrame with the single diode +equation parameter values. + +All ModelChain methods for DC output use the +:py:meth`~pvlib.pvsystem.PVSystem.scale_voltage_current_power` method to scale +DC quantities to the output of the full PVSystem. .. ipython:: python @@ -336,7 +350,7 @@ PVSystem.scale_voltage_current_power method. # run ModelChain.sapm and look at the result mc.sapm(); - mc.dc + mc.results.dc We’ve established that the ``ModelChain.pvwatts_dc`` and ``ModelChain.sapm`` have the same API: they take the same arugments @@ -375,11 +389,11 @@ Inferring models ~~~~~~~~~~~~~~~~ How does ModelChain infer the appropriate model types? ModelChain uses a -series of methods (ModelChain.infer_dc_model, ModelChain.infer_ac_model, -etc.) that examine the user-supplied PVSystem object. The inference -methods use set logic to assign one of the model-specific methods, such -as ModelChain.sapm or ModelChain.snlinverter, to the universal method -names ModelChain.dc_model and ModelChain.ac_model. A few examples are +set of methods (ModelChain.infer_dc_model, ModelChain.infer_ac_model, +etc.) that examine the parameters assigned to the user-supplied PVSystem +object. The inference methods use set logic to assign one of the model-specific +methods, such as ModelChain.sapm or ModelChain.snlinverter, to the universal +method names ModelChain.dc_model and ModelChain.ac_model. A few examples are shown below. .. ipython:: python @@ -390,6 +404,71 @@ shown below. mc.infer_ac_model?? + +ModelChain for a PVSystem with multiple Arrays +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The PVSystem can represent a PV system with a single array of modules, or +with [multiple arrays](#PVSystem and Arrays). The same models are applied to +all PVSystem.array objects, so each Array must contain the appropriate model +parameters. For example, if ``ModelChain.dc_model='pvwatts'``, then each +``Array.module_parameters`` must contain 'pdc0'. + +When the PVSystem contains multiple arrays, ModelChain.results attributes +are tuples with length equal to the number of Arrays. Each tuple's elements +are in the same order as the PVSystem.arrays. + +.. ipython:: python + + location = Location(latitude=32.2, longitude=-110.9) + inverter_parameters = {'pdc0': 10000, 'eta_inv_nom': 0.96} + module_parameters = {'pdc0': 250, 'gamma_pdc': -0.004} + array_one = pvsystem.Array(surface_tilt=20, surface_azimuth=200, + module_parameters=module_parameters, + temperature_model_parameters=temperature_model_parameters, + modules_per_string=10, strings_per_inverter=2) + array_two = pvsystem.Array(surface_tilt=20, surface_azimuth=160, + module_parameters=module_parameters, + temperature_model_parameters=temperature_model_parameters, + modules_per_string=10, strings_per_inverter=2) + system_two_arrays = PVSystem(arrays=[array_one, array_two], + inverter_parameters=cec_inverter, + aoi_model='no_loss', spectral_model='no_loss') + mc = ModelChain(system, location) + + mc.run_model(weather) + + mc.results.dc + +When ``weather`` is a single DataFrame, these data are broadcast and used +for all arrays. To specify data separately for each array, provide a tuple +for ``weather`` where each element is a DataFrame containing the required data. + +Air, module and cell temperatures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The different run_model methods allow the ModelChain to be run starting with +different irradiance data. Similarly, ModelChain run_model methods can be used +with different temperature data as long as cell temperature can be determined: + +* ambient air temperature (``'temp_air'``) +* module temperature, typically measured on the rear surface (``'module_temperature'``) +* cell temperature (``'cell_temperature'``) + +If ``'cell_temperature'`` is provided in the input ``weather``, these data +are used directly. If ``module_temperature`` is provided and +``ModelChain.temperature model='sapm'`` (either set directly or inferred), the +:py:meth:`~pvlib.modelchain.ModelChain.sapm_temp` method calculates cell +temperature. Otherwise, `ModelChain.temperature_model` is used, in which case +air temperature is used, if provided. + +Cell temperature models also can use irradiance as input. All cell +temperature models expect POA irradiance (``'poa_global'``) as input. When +``weather`` contains ``'effectiveand effective'`` irradiance but not +``'poa_global'``, ``'effective_irradiance'`` is substituted for calculating +cell temperature. + + User-defined models ------------------- @@ -465,4 +544,4 @@ The end result is that ModelChain.run_model works as expected! .. ipython:: python mc.run_model(weather); - mc.dc + mc.results.dc From cf20167dc112abe8499d8243fabfff60c280a744 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Sun, 9 May 2021 14:51:34 -0600 Subject: [PATCH 02/27] fix typos, use bullets instead of table --- docs/sphinx/source/modelchain.rst | 60 ++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index d87ee5a79d..68fc66477f 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -93,15 +93,15 @@ examples of attributes of :py:class:`~ModelChainResult` are shown below. .. ipython:: python - mc.result.cell_temperature + mc.results.cell_temperature .. ipython:: python - mc.result.dc + mc.results.dc .. ipython:: python - mc.result.ac + mc.results.ac The remainder of this guide examines the ModelChain functionality and explores common pitfalls. @@ -226,11 +226,14 @@ ModelChain provides three methods for executing the chain of models. The methods allow for simulating the output of the PVSystem with different input irradiance data: -| ModelChain method | Input data | -| :--------------------------| :------------------------------| -| :py:meth:`~pvlib.modelchain.ModelChain.run_model` | GHI, DHI and DNI | -| :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_poa` | Broadband direct, diffuse and total irradiance in plane of array | -| :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_effective_irradiance poa` | Spectrally- and reflection-adjusted total irradiance in plane of array | +* :py:meth:`~pvlib.modelchain.ModelChain.run_model`, use when ``weather`` + contains global horizontal, direct and diffuse horizontal irradiance ('ghi', 'dni' and 'dhi') +* :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_poa`, use when + ``weather`` broadband direct, diffuse and total irradiance in the plane of array + ('poa_global', 'poa_direct', 'poa_diffuse') +* :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_effective_irradiance poa`, + use when ``weather`` contains spectrally- and reflection-adjusted total + irradiance in the plane of array ('effective_irradiance') To illustrate the use of a `run_model` method, assume that a user has GHI, DHI and DNI. The :py:meth:`~pvlib.modelchain.ModelChain.run_model` method, shown below, @@ -420,17 +423,18 @@ are in the same order as the PVSystem.arrays. .. ipython:: python + from pvlib.pvsystem import Array location = Location(latitude=32.2, longitude=-110.9) inverter_parameters = {'pdc0': 10000, 'eta_inv_nom': 0.96} module_parameters = {'pdc0': 250, 'gamma_pdc': -0.004} - array_one = pvsystem.Array(surface_tilt=20, surface_azimuth=200, - module_parameters=module_parameters, - temperature_model_parameters=temperature_model_parameters, - modules_per_string=10, strings_per_inverter=2) - array_two = pvsystem.Array(surface_tilt=20, surface_azimuth=160, - module_parameters=module_parameters, - temperature_model_parameters=temperature_model_parameters, - modules_per_string=10, strings_per_inverter=2) + array_one = Array(surface_tilt=20, surface_azimuth=200, + module_parameters=module_parameters, + temperature_model_parameters=temperature_model_parameters, + modules_per_string=10, strings_per_inverter=2) + array_two = Array(surface_tilt=20, surface_azimuth=160, + module_parameters=module_parameters, + temperature_model_parameters=temperature_model_parameters, + modules_per_string=10, strings_per_inverter=2) system_two_arrays = PVSystem(arrays=[array_one, array_two], inverter_parameters=cec_inverter, aoi_model='no_loss', spectral_model='no_loss') @@ -439,6 +443,7 @@ are in the same order as the PVSystem.arrays. mc.run_model(weather) mc.results.dc + mc.results.dc[0] When ``weather`` is a single DataFrame, these data are broadcast and used for all arrays. To specify data separately for each array, provide a tuple @@ -449,18 +454,17 @@ Air, module and cell temperatures The different run_model methods allow the ModelChain to be run starting with different irradiance data. Similarly, ModelChain run_model methods can be used -with different temperature data as long as cell temperature can be determined: - -* ambient air temperature (``'temp_air'``) -* module temperature, typically measured on the rear surface (``'module_temperature'``) -* cell temperature (``'cell_temperature'``) - -If ``'cell_temperature'`` is provided in the input ``weather``, these data -are used directly. If ``module_temperature`` is provided and -``ModelChain.temperature model='sapm'`` (either set directly or inferred), the -:py:meth:`~pvlib.modelchain.ModelChain.sapm_temp` method calculates cell -temperature. Otherwise, `ModelChain.temperature_model` is used, in which case -air temperature is used, if provided. +with different temperature data as long as cell temperature can be determined. +Temperatuer data are passed in the ``weather`` DataFrame and can include: + +* cell temperature (``'cell_temperature'``). If passed in ``weather`` no + cell temperature model is run. +* module temperature, typically measured on the rear surface (``'module_temperature'``). + If found in ``weather`` and ``ModelChain.temperature model='sapm'`` + (either set directly or inferred), the :py:meth:`~pvlib.modelchain.ModelChain.sapm_temp` + method is used to calculate cell temperature. +* ambient air temperature (``'temp_air'``). In this case `ModelChain.temperature_model` + is used to calcualte cell temeprature. Cell temperature models also can use irradiance as input. All cell temperature models expect POA irradiance (``'poa_global'``) as input. When From 586c77735bbfa9b469f7cfc56f1dde565916071f Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Sun, 9 May 2021 15:22:18 -0600 Subject: [PATCH 03/27] improvements, add with_ class methods --- docs/sphinx/source/modelchain.rst | 50 +++++++++++++++++-------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 68fc66477f..e630a3c990 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -4,28 +4,25 @@ ModelChain The :py:class:`~.modelchain.ModelChain` class provides a high-level interface for standardized PV modeling. The class aims to automate much -of the modeling process while providing user-control and remaining +of the modeling process while providing flexibility and remaining extensible. This guide aims to build users' understanding of the ModelChain class. It assumes some familiarity with object-oriented code in Python, but most information should be understandable even without a solid understanding of classes. -A :py:class:`~.modelchain.ModelChain` is composed of a -:py:class:`~.pvsystem.PVSystem` object and a -:py:class:`~.location.Location` object. A PVSystem object represents an -assembled collection of modules, inverters, etc., a Location object -represents a particular place on the planet, and a ModelChain object -describes the modeling chain used to calculate a system's output at that -location. The PVSystem and Location objects will be described in detail -in another guide. +A :py:class:`~.modelchain.ModelChain` has three components: + +* a :py:class:`~.pvsystem.PVSystem` object, representin a collection of modules and inverters +* a :py:class:`~.location.Location` object, representing a location on the planet +* values for attributes that specify the model to be used for for each step in the PV modeling + process. Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: -1. Creating the :py:class:`~.ModelChain`. -2. Executing the :py:meth:`ModelChain.run_model() <.ModelChain.run_model>` - method with prepared weather data. -3. Examining the model results that are stored in the ModelChain attribute - ``results`` as an instance of :py:class:`~.ModelChainResults`. +1. Creating an instance of :py:class:`~pvlib.modelchain.ModelChain`. +2. Executing a ModelChain.run_model method with weather data as input. +3. Examining the model results that are stored in the ModelChain's ``results`` + attribute. A simple ModelChain example --------------------------- @@ -204,7 +201,14 @@ functions for a PVSystem that contains SAPM-specific parameters. Of course, these choices can also lead to failure when executing :py:meth:`~pvlib.modelchain.ModelChain.run_model` if your system objects -do not contain the required parameters for running the model. +do not contain the required parameters for running the model chain. + +As a convenience, ModelChain includes two class methods that return a ModelChain +with models selected to be consistent with named PV system models: + +* :py:meth:`~pvlib.modelchain.ModelChain.with_pvwatts` +* :py:meth:`~pvlib.modelchain.ModelChain.with_sapm` + Demystifying ModelChain internals --------------------------------- @@ -214,10 +218,10 @@ users' code as simple as possible. The key parts of ModelChain are: - 1. The :py:meth:`ModelChain.run_model() <.ModelChain.run_model>` method + 1. The ModelChain.run_model methods. 2. A set of methods that wrap and call the PVSystem methods. - 3. A set of methods that inspect user-supplied objects to determine - the appropriate default models. + 3. A set of methods that can inspect user-supplied objects to infer + the appropriate model when a models isn't specified by the user. run_model methods ~~~~~~~~~~~~~~~~~ @@ -318,19 +322,19 @@ below shows a simple example of this. mc.pvwatts_dc(); mc.results.dc -The ModelChain.sapm method works similarly to the ModelChain.pvwatts_dc +The ModelChain.sapm method works in a manner similar to the ModelChain.pvwatts_dc method. It calls the PVSystem.sapm method using stored data, then assigns the result to the ``dc`` attribute of ModelChain.results. The ModelChain.sapm method differs from the ModelChain.pvwatts_dc method in a notable way: the PVSystem.sapm method returns a DataFrame with current, voltage, and power results, rather than a simple Series of power. The ModelChain methods for single diode models (e.g., -:py:meth:`~pvlib.modelchain.ModelChain.desoto` also return a DataFrame with +:py:meth:`~pvlib.modelchain.ModelChain.desoto`) also return a DataFrame with current, voltage and power, and a second DataFrame with the single diode equation parameter values. All ModelChain methods for DC output use the -:py:meth`~pvlib.pvsystem.PVSystem.scale_voltage_current_power` method to scale +:py:meth:`~pvlib.pvsystem.PVSystem.scale_voltage_current_power` method to scale DC quantities to the output of the full PVSystem. .. ipython:: python @@ -430,11 +434,11 @@ are in the same order as the PVSystem.arrays. array_one = Array(surface_tilt=20, surface_azimuth=200, module_parameters=module_parameters, temperature_model_parameters=temperature_model_parameters, - modules_per_string=10, strings_per_inverter=2) + modules_per_string=10, strings=2) array_two = Array(surface_tilt=20, surface_azimuth=160, module_parameters=module_parameters, temperature_model_parameters=temperature_model_parameters, - modules_per_string=10, strings_per_inverter=2) + modules_per_string=10, strings=2) system_two_arrays = PVSystem(arrays=[array_one, array_two], inverter_parameters=cec_inverter, aoi_model='no_loss', spectral_model='no_loss') From 011bfa8875218b84f2a3b5498e453332dc694538 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Sun, 9 May 2021 17:13:48 -0600 Subject: [PATCH 04/27] fix mistake --- docs/sphinx/source/modelchain.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index e630a3c990..e53183f60e 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -440,9 +440,9 @@ are in the same order as the PVSystem.arrays. temperature_model_parameters=temperature_model_parameters, modules_per_string=10, strings=2) system_two_arrays = PVSystem(arrays=[array_one, array_two], - inverter_parameters=cec_inverter, - aoi_model='no_loss', spectral_model='no_loss') - mc = ModelChain(system, location) + inverter_parameters=cec_inverter) + mc = ModelChain(system, location, aoi_model='no_loss', + spectral_model='no_loss') mc.run_model(weather) From 11f55780e9a2d18d2f6594131a95455bef408ffb Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Sun, 9 May 2021 17:30:56 -0600 Subject: [PATCH 05/27] fix another mistake --- docs/sphinx/source/modelchain.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index e53183f60e..829a36ea96 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -440,8 +440,8 @@ are in the same order as the PVSystem.arrays. temperature_model_parameters=temperature_model_parameters, modules_per_string=10, strings=2) system_two_arrays = PVSystem(arrays=[array_one, array_two], - inverter_parameters=cec_inverter) - mc = ModelChain(system, location, aoi_model='no_loss', + inverter_parameters={'pdc0': 8000}) + mc = ModelChain(system_two_arrays, location, aoi_model='no_loss', spectral_model='no_loss') mc.run_model(weather) From 12547a484023580b2a4c406407db975a319d6b6e Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Mon, 10 May 2021 07:59:55 -0600 Subject: [PATCH 06/27] fix cross reference --- docs/sphinx/source/modelchain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 829a36ea96..809e5c07ca 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -416,7 +416,7 @@ ModelChain for a PVSystem with multiple Arrays ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The PVSystem can represent a PV system with a single array of modules, or -with [multiple arrays](#PVSystem and Arrays). The same models are applied to +with multiple arrays (see :ref:`_multiarray`). The same models are applied to all PVSystem.array objects, so each Array must contain the appropriate model parameters. For example, if ``ModelChain.dc_model='pvwatts'``, then each ``Array.module_parameters`` must contain 'pdc0'. From a3efba1370ad1f2792d1b719fe8b89cc27540bc1 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Mon, 10 May 2021 10:46:16 -0600 Subject: [PATCH 07/27] updates from review --- docs/sphinx/source/api.rst | 2 ++ docs/sphinx/source/modelchain.rst | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/sphinx/source/api.rst b/docs/sphinx/source/api.rst index 633a9d8cc0..d62782bfdf 100644 --- a/docs/sphinx/source/api.rst +++ b/docs/sphinx/source/api.rst @@ -572,6 +572,8 @@ Creating a ModelChain object. modelchain.ModelChain.with_pvwatts modelchain.ModelChain.with_sapm +.. _modelchain_runmodel: + Running ------- diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 809e5c07ca..bd031d156a 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -12,7 +12,7 @@ without a solid understanding of classes. A :py:class:`~.modelchain.ModelChain` has three components: -* a :py:class:`~.pvsystem.PVSystem` object, representin a collection of modules and inverters +* a :py:class:`~.pvsystem.PVSystem` object, representing a collection of modules and inverters * a :py:class:`~.location.Location` object, representing a location on the planet * values for attributes that specify the model to be used for for each step in the PV modeling process. @@ -20,9 +20,10 @@ A :py:class:`~.modelchain.ModelChain` has three components: Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: 1. Creating an instance of :py:class:`~pvlib.modelchain.ModelChain`. -2. Executing a ModelChain.run_model method with weather data as input. -3. Examining the model results that are stored in the ModelChain's ``results`` - attribute. +2. Executing a ModelChain.run_model method with weather data as input. See + :ref:`_modelchain_runmodel` for a list of run_model methods. +3. Examining the model results that are stored in the ModelChain's + :py:class:`ModelChain.results <.ModelChain.ModelChainResult>` attribute. A simple ModelChain example --------------------------- @@ -159,7 +160,7 @@ model, AC model, AOI loss model, and spectral loss model. mc.ac Alternatively, we could have specified single diode or PVWatts related -information in the PVSystem construction. Here we assign parameters for +information in the PVSystem construction. Here we pass parameters for PVWatts models to the PVSystem. ModelChain will automatically determine that it should choose PVWatts DC and AC models. ModelChain still needs us to specify ``aoi_model`` and ``spectral_model`` keyword arguments because the @@ -263,8 +264,8 @@ assigned to generic names, as described in the next section. The methods called by :py:meth:`~pvlib.modelchain.ModelChain.run_model` store their results in the ``results`` attribute, which is an instance of -:py:class:`~ModelChainResult`. :py:class:`~ModelChainResult` has the following -attributes: +:py:class:`~.ModelChainResult`. :py:class:`~.ModelChainResult` has the +following attributes: ``weather``, ``times``, ``solar_position``, ``airmass``, ``total_irrad``, ``aoi``, ``aoi_modifier``, ``spectral_modifier``,``effective_irradiance``, ``cell_temperature``, ``dc``, ``ac``, ``losses``, ``tracking``, @@ -413,7 +414,7 @@ shown below. ModelChain for a PVSystem with multiple Arrays -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The PVSystem can represent a PV system with a single array of modules, or with multiple arrays (see :ref:`_multiarray`). The same models are applied to From 4e7cf88b5a92d8851bf84b820e31b9e61be4e02c Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Mon, 10 May 2021 13:39:09 -0600 Subject: [PATCH 08/27] more use of formatting --- docs/sphinx/source/modelchain.rst | 63 +++++++++++++++++-------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index bd031d156a..0e8a573279 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -236,7 +236,7 @@ input irradiance data: * :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_poa`, use when ``weather`` broadband direct, diffuse and total irradiance in the plane of array ('poa_global', 'poa_direct', 'poa_diffuse') -* :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_effective_irradiance poa`, +* :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_effective_irradiance`, use when ``weather`` contains spectrally- and reflection-adjusted total irradiance in the plane of array ('effective_irradiance') @@ -267,7 +267,7 @@ store their results in the ``results`` attribute, which is an instance of :py:class:`~.ModelChainResult`. :py:class:`~.ModelChainResult` has the following attributes: ``weather``, ``times``, ``solar_position``, ``airmass``, ``total_irrad``, -``aoi``, ``aoi_modifier``, ``spectral_modifier``,``effective_irradiance``, +``aoi``, ``aoi_modifier``, ``spectral_modifier``, ``effective_irradiance``, ``cell_temperature``, ``dc``, ``ac``, ``losses``, ``tracking``, ``diode_params``. @@ -279,10 +279,10 @@ following attributes: Wrapping methods into a unified API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Readers may notice that the source code of the ModelChain.run_model -method is model-agnostic. ModelChain.run_model calls generic methods +Readers may notice that the source code of the :py:meth:`~pvlib.modelchain.ModelChain.run_model` +method is model-agnostic. :py:meth:`~pvlib.modelchain.`ModelChain.run_model` calls generic methods such as ``self.dc_model`` rather than a specific model such as -``pvwatts_dc``. So how does the ModelChain.run_model know what models +``pvwatts_dc``. So how does :py:meth:`~pvlib.modelchain.ModelChain.run_model` know what models it’s supposed to run? The answer comes in two parts, and allows us to explore more of the ModelChain API along the way. @@ -290,18 +290,18 @@ First, ModelChain has a set of methods that wrap the PVSystem methods that perform the calculations (or further wrap the pvsystem.py module’s functions). Each of these methods takes the same arguments (``self``) and sets the same attributes, thus creating a uniform API. For example, -the ModelChain.pvwatts_dc method is shown below. Its only argument is +the :py:meth:`~pvlib.modelchain.ModelChain.pvwatts_dc` method is shown below. Its only argument is ``self``, and it sets the ``dc`` attribute. .. ipython:: python mc.pvwatts_dc?? -The ModelChain.pvwatts_dc method calls the pvwatts_dc method of the +The :py:meth:`~pvlib.modelchain.ModelChain.pvwatts_dc` method calls the pvwatts_dc method of the PVSystem object that we supplied when we created the ModelChain instance, using data that is stored in the ModelChain ``effective_irradiance`` and -``cell_temperature`` attributes. The ModelChain.pvwatts_dc method assigns its -result to the ``dc`` attribute of the ModelChain's results object. The code +``cell_temperature`` attributes. The :py:meth:`~pvlib.modelchain.ModelChain.pvwatts_dc` method assigns its +result to the ``dc`` attribute of the ModelChain's ``results`` object. The code below shows a simple example of this. .. ipython:: python @@ -323,10 +323,12 @@ below shows a simple example of this. mc.pvwatts_dc(); mc.results.dc -The ModelChain.sapm method works in a manner similar to the ModelChain.pvwatts_dc -method. It calls the PVSystem.sapm method using stored data, then -assigns the result to the ``dc`` attribute of ModelChain.results. -The ModelChain.sapm method differs from the ModelChain.pvwatts_dc method in +The :py:meth:`~pvlib.modelchain.ModelChain.sapm` method works in a manner similar +to the :py:meth:`~pvlib.modelchain.ModelChain.pvwatts_dc` +method. It calls the :py:meth:`~pvlib.pvsystem.PVSystem.sapm` method using stored data, then +assigns the result to the ``dc`` attribute of ``ModelChain.results``. +The :py:meth:`~pvlib.modelchain.ModelChain.sapm` method differs from the +:py:meth:`~pvlib.modelchain.ModelChain.pvwatts_dc` method in a notable way: the PVSystem.sapm method returns a DataFrame with current, voltage, and power results, rather than a simple Series of power. The ModelChain methods for single diode models (e.g., @@ -367,12 +369,13 @@ have the same API, we can call them in the same way. ModelChain includes a large number of methods that perform the same API-unification roles for each modeling step. -Again, so how does the ModelChain.run_model know which models it’s +Again, so how does :py:meth:`~pvlib.modelchain. ModelChain.run_model` know which models it’s supposed to run? At object construction, ModelChain assigns the desired model’s method (e.g. ``ModelChain.pvwatts_dc``) to the corresponding generic attribute -(e.g. ``ModelChain.dc_model``) using a method described in the next +(e.g. ``ModelChain.dc_model``) either with the value assigned to the ``dc_model`` +parameter at construction, or by inference as described in the next section. .. ipython:: python @@ -396,13 +399,17 @@ vs. DataFrame)! Inferring models ~~~~~~~~~~~~~~~~ -How does ModelChain infer the appropriate model types? ModelChain uses a -set of methods (ModelChain.infer_dc_model, ModelChain.infer_ac_model, -etc.) that examine the parameters assigned to the user-supplied PVSystem -object. The inference methods use set logic to assign one of the model-specific -methods, such as ModelChain.sapm or ModelChain.snlinverter, to the universal -method names ModelChain.dc_model and ModelChain.ac_model. A few examples are -shown below. +When ModelChain's attributes are not assigned when the instance is created, +ModelChain can infer the appropriate model from data stored on the ``PVSystem`` +object. ModelChain uses a set of methods (e.g., :py:meth:`~pvlib.modelchain.ModelChain.infer_dc_model`, +:py:meth:`~pvlib.modelchain.ModelChain.infer_ac_model`, etc.) that examine the +parameters on the user-supplied PVSystem object. The inference methods use set +logic to assign one of the model-specific methods, such as +:py:meth:`~pvlib.modelchain.ModelChain.sapm` or :py:meth:`~pvlib.modelchain.ModelChain.snlinverter`, +to the universal method names ``ModelChain.dc_model`` and ``ModelChain.ac_model``, +respectively. A few examples are shown below. Inferrence methods generally work +by inspecting the parameters for all required parameters for a corresponding +method. .. ipython:: python @@ -417,14 +424,14 @@ ModelChain for a PVSystem with multiple Arrays ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The PVSystem can represent a PV system with a single array of modules, or -with multiple arrays (see :ref:`_multiarray`). The same models are applied to -all PVSystem.array objects, so each Array must contain the appropriate model +with multiple arrays (see :ref:`multiarray`). The same models are applied to +all ``PVSystem.array`` objects, so each ``Array`` must contain the appropriate model parameters. For example, if ``ModelChain.dc_model='pvwatts'``, then each -``Array.module_parameters`` must contain 'pdc0'. +``Array.module_parameters`` must contain ``'pdc0'``. -When the PVSystem contains multiple arrays, ModelChain.results attributes +When the PVSystem contains multiple arrays, ``ModelChain.results`` attributes are tuples with length equal to the number of Arrays. Each tuple's elements -are in the same order as the PVSystem.arrays. +are in the same order as in ``PVSystem.arrays``. .. ipython:: python @@ -468,7 +475,7 @@ Temperatuer data are passed in the ``weather`` DataFrame and can include: If found in ``weather`` and ``ModelChain.temperature model='sapm'`` (either set directly or inferred), the :py:meth:`~pvlib.modelchain.ModelChain.sapm_temp` method is used to calculate cell temperature. -* ambient air temperature (``'temp_air'``). In this case `ModelChain.temperature_model` +* ambient air temperature (``'temp_air'``). In this case ``ModelChain.temperature_model`` is used to calcualte cell temeprature. Cell temperature models also can use irradiance as input. All cell From fe54d66d91a07b1a701f002670712729b0d1de43 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Mon, 10 May 2021 14:13:53 -0600 Subject: [PATCH 09/27] fix link --- docs/sphinx/source/modelchain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 0e8a573279..62debe71e7 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -23,7 +23,7 @@ Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: 2. Executing a ModelChain.run_model method with weather data as input. See :ref:`_modelchain_runmodel` for a list of run_model methods. 3. Examining the model results that are stored in the ModelChain's - :py:class:`ModelChain.results <.ModelChain.ModelChainResult>` attribute. + :py:class:`ModelChain.results ` attribute. A simple ModelChain example --------------------------- From 999c3d015b11c1d653ac70b4e34a695a12872657 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Mon, 10 May 2021 14:34:13 -0600 Subject: [PATCH 10/27] refix link --- docs/sphinx/source/modelchain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 62debe71e7..195af3b1a2 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -23,7 +23,7 @@ Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: 2. Executing a ModelChain.run_model method with weather data as input. See :ref:`_modelchain_runmodel` for a list of run_model methods. 3. Examining the model results that are stored in the ModelChain's - :py:class:`ModelChain.results ` attribute. + :py:class:`ModelChain.results ` attribute. A simple ModelChain example --------------------------- From 67580d093dba308aaf44020f50bf4e0a0b887f0f Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 11 May 2021 08:43:07 -0600 Subject: [PATCH 11/27] clear up deprecations --- docs/sphinx/source/introtutorial.rst | 4 ++-- docs/sphinx/source/modelchain.rst | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/sphinx/source/introtutorial.rst b/docs/sphinx/source/introtutorial.rst index 495b0c6e40..b3a9b9a7b6 100644 --- a/docs/sphinx/source/introtutorial.rst +++ b/docs/sphinx/source/introtutorial.rst @@ -209,8 +209,8 @@ by examining the parameters defined for the module. ) mc = ModelChain(system, location) - results = mc.run_model(weather) - annual_energy = results.ac.sum() + mc.run_model(weather) + annual_energy = mc.results.ac.sum() energies[name] = annual_energy energies = pd.Series(energies) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 195af3b1a2..fa89502a35 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -157,7 +157,7 @@ model, AC model, AOI loss model, and spectral loss model. .. ipython:: python mc.run_model(weather); - mc.ac + mc.results.ac Alternatively, we could have specified single diode or PVWatts related information in the PVSystem construction. Here we pass parameters for @@ -180,7 +180,7 @@ information to determine which of those models to choose. .. ipython:: python mc.run_model(weather); - mc.ac + mc.results.ac User-supplied keyword arguments override ModelChain’s inspection methods. For example, we can tell ModelChain to use different loss @@ -198,7 +198,7 @@ functions for a PVSystem that contains SAPM-specific parameters. .. ipython:: python mc.run_model(weather); - mc.ac + mc.results.ac Of course, these choices can also lead to failure when executing :py:meth:`~pvlib.modelchain.ModelChain.run_model` if your system objects @@ -528,13 +528,13 @@ function if you wanted to. def pvusa_ac_mc(mc): # keep it simple - mc.ac = mc.dc + mc.results.ac = mc.results.dc return mc def no_loss_temperature(mc): # keep it simple - mc.cell_temperature = mc.results.weather['temp_air'] + mc.results.cell_temperature = mc.results.weather['temp_air'] return mc From f86d7e3f4eb336f5e2c347d7469196ac668681bc Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 11 May 2021 09:47:07 -0600 Subject: [PATCH 12/27] a few more, print inverter model inference helpers --- docs/sphinx/source/modelchain.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index fa89502a35..e401252ba5 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -316,8 +316,8 @@ below shows a simple example of this. # manually assign data to the attributes that ModelChain.pvwatts_dc will need. # for standard workflows, run_model would assign these attributes. - mc.effective_irradiance = pd.Series(1000, index=[pd.Timestamp('20170401 1200-0700')]) - mc.cell_temperature = pd.Series(50, index=[pd.Timestamp('20170401 1200-0700')]) + mc.results.effective_irradiance = pd.Series(1000, index=[pd.Timestamp('20170401 1200-0700')]) + mc.results.cell_temperature = pd.Series(50, index=[pd.Timestamp('20170401 1200-0700')]) # run ModelChain.pvwatts_dc and look at the result mc.pvwatts_dc(); @@ -418,7 +418,9 @@ method. .. ipython:: python mc.infer_ac_model?? - + mc._snl_params?? + mc._adr_params?? + mc._pvwatts_params?? ModelChain for a PVSystem with multiple Arrays ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 1153904c4273c9c83bbcd4a47f18cdff0ae01e65 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 11 May 2021 10:06:30 -0600 Subject: [PATCH 13/27] correct references --- docs/sphinx/source/modelchain.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index e401252ba5..42b136a3a8 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -418,9 +418,9 @@ method. .. ipython:: python mc.infer_ac_model?? - mc._snl_params?? - mc._adr_params?? - mc._pvwatts_params?? + pvlib.modelchain._snl_params?? + pvlib.modelchain._adr_params?? + pvlib.modelchain._pvwatts_params?? ModelChain for a PVSystem with multiple Arrays ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 9f8911e1c34a61924879113e6cb72ef9ffe9bc12 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Tue, 11 May 2021 22:09:33 -0600 Subject: [PATCH 14/27] revisions from review --- docs/sphinx/source/modelchain.rst | 44 +++++++++++++++++-------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 42b136a3a8..46900fd4c7 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -21,7 +21,7 @@ Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: 1. Creating an instance of :py:class:`~pvlib.modelchain.ModelChain`. 2. Executing a ModelChain.run_model method with weather data as input. See - :ref:`_modelchain_runmodel` for a list of run_model methods. + :ref:`modelchain_runmodel` for a list of run_model methods. 3. Examining the model results that are stored in the ModelChain's :py:class:`ModelChain.results ` attribute. @@ -82,8 +82,9 @@ Next, we run a model with some simple weather data. mc.run_model(weather) ModelChain stores the modeling results in the ``results`` attribute. The -``results`` attribute is an instance of :py:class:`~ModelChainResult`. A few -examples of attributes of :py:class:`~ModelChainResult` are shown below. +``results`` attribute is an instance of :py:class:`~pvlib.modelchain.ModelChainResult`. +A few examples of attributes of :py:class:`~pvlib.modelchain.ModelChainResult` +are shown below. .. ipython:: python @@ -280,7 +281,7 @@ Wrapping methods into a unified API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Readers may notice that the source code of the :py:meth:`~pvlib.modelchain.ModelChain.run_model` -method is model-agnostic. :py:meth:`~pvlib.modelchain.`ModelChain.run_model` calls generic methods +method is model-agnostic. :py:meth:`~pvlib.modelchain.ModelChain.run_model` calls generic methods such as ``self.dc_model`` rather than a specific model such as ``pvwatts_dc``. So how does :py:meth:`~pvlib.modelchain.ModelChain.run_model` know what models it’s supposed to run? The answer comes in two parts, and allows us to @@ -355,8 +356,8 @@ DC quantities to the output of the full PVSystem. # manually assign data to the attributes that ModelChain.sapm will need. # for standard workflows, run_model would assign these attributes. - mc.effective_irradiance = pd.Series(1000, index=[pd.Timestamp('20170401 1200-0700')]) - mc.cell_temperature = pd.Series(50, index=[pd.Timestamp('20170401 1200-0700')]) + mc.results.effective_irradiance = pd.Series(1000, index=[pd.Timestamp('20170401 1200-0700')]) + mc.results.cell_temperature = pd.Series(50, index=[pd.Timestamp('20170401 1200-0700')]) # run ModelChain.sapm and look at the result mc.sapm(); @@ -369,8 +370,8 @@ have the same API, we can call them in the same way. ModelChain includes a large number of methods that perform the same API-unification roles for each modeling step. -Again, so how does :py:meth:`~pvlib.modelchain. ModelChain.run_model` know which models it’s -supposed to run? +Again, so how does :py:meth:`~pvlib.modelchain.ModelChain.run_model` know which +models it’s supposed to run? At object construction, ModelChain assigns the desired model’s method (e.g. ``ModelChain.pvwatts_dc``) to the corresponding generic attribute @@ -405,7 +406,7 @@ object. ModelChain uses a set of methods (e.g., :py:meth:`~pvlib.modelchain.Mode :py:meth:`~pvlib.modelchain.ModelChain.infer_ac_model`, etc.) that examine the parameters on the user-supplied PVSystem object. The inference methods use set logic to assign one of the model-specific methods, such as -:py:meth:`~pvlib.modelchain.ModelChain.sapm` or :py:meth:`~pvlib.modelchain.ModelChain.snlinverter`, +:py:meth:`~pvlib.modelchain.ModelChain.sapm` or :py:meth:`~pvlib.modelchain.ModelChain.sandia_inverter`, to the universal method names ``ModelChain.dc_model`` and ``ModelChain.ac_model``, respectively. A few examples are shown below. Inferrence methods generally work by inspecting the parameters for all required parameters for a corresponding @@ -469,20 +470,20 @@ Air, module and cell temperatures The different run_model methods allow the ModelChain to be run starting with different irradiance data. Similarly, ModelChain run_model methods can be used with different temperature data as long as cell temperature can be determined. -Temperatuer data are passed in the ``weather`` DataFrame and can include: +Temperature data are passed in the ``weather`` DataFrame and can include: * cell temperature (``'cell_temperature'``). If passed in ``weather`` no cell temperature model is run. * module temperature, typically measured on the rear surface (``'module_temperature'``). - If found in ``weather`` and ``ModelChain.temperature model='sapm'`` + If found in ``weather`` and ``ModelChain.temperature_model='sapm'`` (either set directly or inferred), the :py:meth:`~pvlib.modelchain.ModelChain.sapm_temp` method is used to calculate cell temperature. * ambient air temperature (``'temp_air'``). In this case ``ModelChain.temperature_model`` - is used to calcualte cell temeprature. + is used to calculate cell temeprature. Cell temperature models also can use irradiance as input. All cell temperature models expect POA irradiance (``'poa_global'``) as input. When -``weather`` contains ``'effectiveand effective'`` irradiance but not +``weather`` contains ``'effective_irradiance'`` but not ``'poa_global'``, ``'effective_irradiance'`` is substituted for calculating cell temperature. @@ -516,14 +517,17 @@ function if you wanted to. def pvusa_mc_wrapper(mc): - # calculate the dc power and assign it to mc.dc - # in the future, need to explicitly iterate over system.arrays + # calculate the dc power and assign it to mc.results.dc + # The wrapper should iterate over system.arrays # https://github.com/pvlib/pvlib-python/issues/1115 - mc.dc = pvusa(mc.results.total_irrad['poa_global'], - mc.results.weather['wind_speed'], mc.results.weather['temp_air'], - mc.system.module_parameters['a'], mc.system.module_parameters['b'], - mc.system.module_parameters['c'], mc.system.module_parameters['d']) - + mc.results.dc = tuple( + pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], + mc.results.weather['temp_air'], array.module_parameters['a'], + array.module_parameters['b'], array.module_parameters['c'], + array.module_parameters['d']) + for total_irrad, array + in zip(mc.results.total_irrad, mc.system.arrays) + ) # returning mc is optional, but enables method chaining return mc From 10f117c4810a7b732f579e6e14f84e7dc7721534 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 07:24:58 -0600 Subject: [PATCH 15/27] fix up loop in pvusa_mc_wrapper --- docs/sphinx/source/modelchain.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 46900fd4c7..c8f0e98f24 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -518,8 +518,16 @@ function if you wanted to. def pvusa_mc_wrapper(mc): # calculate the dc power and assign it to mc.results.dc - # The wrapper should iterate over system.arrays + # The wrapper should iterate over system.arrays if num_arrays > 1 # https://github.com/pvlib/pvlib-python/issues/1115 + if mc.system.num_arrays == 1: + mc.results.dc = pvusa( + total_irrad['poa_global'], mc.results.weather['wind_speed'], + mc.results.weather['temp_air'], mc.system.array.module_parameters['a'], + mc.system.array.module_parameters['b'], mc.system.array.module_parameters['c'], + mc.system.array.module_parameters['d']) + ) + else: mc.results.dc = tuple( pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], mc.results.weather['temp_air'], array.module_parameters['a'], From 23abfa659d290bdbc071744c1d9e199e403b905d Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 08:57:47 -0600 Subject: [PATCH 16/27] indents --- docs/sphinx/source/modelchain.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index c8f0e98f24..3d85ce51d8 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -526,7 +526,6 @@ function if you wanted to. mc.results.weather['temp_air'], mc.system.array.module_parameters['a'], mc.system.array.module_parameters['b'], mc.system.array.module_parameters['c'], mc.system.array.module_parameters['d']) - ) else: mc.results.dc = tuple( pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], @@ -535,7 +534,7 @@ function if you wanted to. array.module_parameters['d']) for total_irrad, array in zip(mc.results.total_irrad, mc.system.arrays) - ) + ) # returning mc is optional, but enables method chaining return mc From a04e3f95379c7f774e9b50a5e3b2731c155f238e Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 10:19:11 -0600 Subject: [PATCH 17/27] correct references --- docs/sphinx/source/modelchain.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 3d85ce51d8..5f2f179339 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -522,7 +522,7 @@ function if you wanted to. # https://github.com/pvlib/pvlib-python/issues/1115 if mc.system.num_arrays == 1: mc.results.dc = pvusa( - total_irrad['poa_global'], mc.results.weather['wind_speed'], + mc.results.total_irrad['poa_global'], mc.results.weather['wind_speed'], mc.results.weather['temp_air'], mc.system.array.module_parameters['a'], mc.system.array.module_parameters['b'], mc.system.array.module_parameters['c'], mc.system.array.module_parameters['d']) @@ -572,5 +572,5 @@ The end result is that ModelChain.run_model works as expected! .. ipython:: python - mc.run_model(weather); + mc.run_model(weather) mc.results.dc From 394f72db0c3b3cadb1acf53a43059311d1c97e7b Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 10:31:25 -0600 Subject: [PATCH 18/27] thrash some more --- docs/sphinx/source/modelchain.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 5f2f179339..b1f0b399f2 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -523,9 +523,9 @@ function if you wanted to. if mc.system.num_arrays == 1: mc.results.dc = pvusa( mc.results.total_irrad['poa_global'], mc.results.weather['wind_speed'], - mc.results.weather['temp_air'], mc.system.array.module_parameters['a'], - mc.system.array.module_parameters['b'], mc.system.array.module_parameters['c'], - mc.system.array.module_parameters['d']) + mc.results.weather['temp_air'], mc.system.arrays[0].module_parameters['a'], + mc.system.arrays[0].module_parameters['b'], mc.system.arrays[0].module_parameters['c'], + mc.system.arrays[0].module_parameters['d']) else: mc.results.dc = tuple( pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], From 0e45c01484412f32a363f5e9900e8a1a0c3d6a2f Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 10:41:07 -0600 Subject: [PATCH 19/27] suppress long output --- docs/sphinx/source/modelchain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index b1f0b399f2..04a5911235 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -572,5 +572,5 @@ The end result is that ModelChain.run_model works as expected! .. ipython:: python - mc.run_model(weather) + mc = mc.run_model(weather) mc.results.dc From 4e620ba860a824c66cc90420142ab4b0117701c9 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 12:18:46 -0600 Subject: [PATCH 20/27] add comments to user function example --- docs/sphinx/source/modelchain.rst | 42 +++++++++++++++++++------------ 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 04a5911235..f0a53ef76e 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -518,23 +518,33 @@ function if you wanted to. def pvusa_mc_wrapper(mc): # calculate the dc power and assign it to mc.results.dc - # The wrapper should iterate over system.arrays if num_arrays > 1 - # https://github.com/pvlib/pvlib-python/issues/1115 + # Set up to iterate over arrays and total_irrad. mc.system.arrays is + # always a tuple. However, when there is a single array + # mc.results.total_irrad will be a Series (if multiple arrays, + # total_irrad will be a tuple). In this case we put total_irrad + # in a list so that we can iterate. If we didn't put total_irrad + # in a list, iteration will access each value of the Series, one + # at a time. if mc.system.num_arrays == 1: - mc.results.dc = pvusa( - mc.results.total_irrad['poa_global'], mc.results.weather['wind_speed'], - mc.results.weather['temp_air'], mc.system.arrays[0].module_parameters['a'], - mc.system.arrays[0].module_parameters['b'], mc.system.arrays[0].module_parameters['c'], - mc.system.arrays[0].module_parameters['d']) - else: - mc.results.dc = tuple( - pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], - mc.results.weather['temp_air'], array.module_parameters['a'], - array.module_parameters['b'], array.module_parameters['c'], - array.module_parameters['d']) - for total_irrad, array - in zip(mc.results.total_irrad, mc.system.arrays) - ) + total_irrads = [mc.results.total_irrad] + else + total_irrads = mc.results.total_irrad + + mc.results.dc = tuple( + pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], + mc.results.weather['temp_air'], array.module_parameters['a'], + array.module_parameters['b'], array.module_parameters['c'], + array.module_parameters['d']) + for total_irrad, array + in zip(total_irrads, mc.system.arrays) + ) + + # The iteration returns a tuple. If there is a single array, pvlib + # unwraps the tuple of length 1. Unwrap here for consistency with the + # rest of pvlib. + if mc.system.num_arrays == 1: + mc.results.dc = mc.results.dc[0] + # returning mc is optional, but enables method chaining return mc From 46c614d65172d22e1bcd970d53ee237268bbabdb Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 13:20:11 -0600 Subject: [PATCH 21/27] add : --- docs/sphinx/source/modelchain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index f0a53ef76e..96cf3c84d9 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -527,7 +527,7 @@ function if you wanted to. # at a time. if mc.system.num_arrays == 1: total_irrads = [mc.results.total_irrad] - else + else: total_irrads = mc.results.total_irrad mc.results.dc = tuple( From 2fc389918211fbf86012c28f39309fc55c527709 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 13:27:19 -0600 Subject: [PATCH 22/27] spacing --- docs/sphinx/source/modelchain.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 96cf3c84d9..e8d0f5ba2d 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -529,16 +529,13 @@ function if you wanted to. total_irrads = [mc.results.total_irrad] else: total_irrads = mc.results.total_irrad - mc.results.dc = tuple( pvusa(total_irrad['poa_global'], mc.results.weather['wind_speed'], mc.results.weather['temp_air'], array.module_parameters['a'], array.module_parameters['b'], array.module_parameters['c'], array.module_parameters['d']) for total_irrad, array - in zip(total_irrads, mc.system.arrays) - ) - + in zip(total_irrads, mc.system.arrays)) # The iteration returns a tuple. If there is a single array, pvlib # unwraps the tuple of length 1. Unwrap here for consistency with the # rest of pvlib. From 48ca84b8783f6b46e7176c5d994dd96180224980 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Wed, 12 May 2021 13:36:56 -0600 Subject: [PATCH 23/27] move comments to docstring so they appear in rtd --- docs/sphinx/source/modelchain.rst | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index e8d0f5ba2d..5c64043d61 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -517,14 +517,20 @@ function if you wanted to. def pvusa_mc_wrapper(mc): - # calculate the dc power and assign it to mc.results.dc - # Set up to iterate over arrays and total_irrad. mc.system.arrays is - # always a tuple. However, when there is a single array - # mc.results.total_irrad will be a Series (if multiple arrays, - # total_irrad will be a tuple). In this case we put total_irrad - # in a list so that we can iterate. If we didn't put total_irrad - # in a list, iteration will access each value of the Series, one - # at a time. + """ + Calculate the dc power and assign it to mc.results.dc + Set up to iterate over arrays and total_irrad. mc.system.arrays is + always a tuple. However, when there is a single array + mc.results.total_irrad will be a Series (if multiple arrays, + total_irrad will be a tuple). In this case we put total_irrad + in a list so that we can iterate. If we didn't put total_irrad + in a list, iteration will access each value of the Series, one + at a time. + The iteration returns a tuple. If there is a single array, pvlib + unwraps the tuple of length 1. Unwrap the tuple here for consistency + with the rest of pvlib. + Returning mc is optional, but enables method chaining. + """ if mc.system.num_arrays == 1: total_irrads = [mc.results.total_irrad] else: @@ -536,13 +542,8 @@ function if you wanted to. array.module_parameters['d']) for total_irrad, array in zip(total_irrads, mc.system.arrays)) - # The iteration returns a tuple. If there is a single array, pvlib - # unwraps the tuple of length 1. Unwrap here for consistency with the - # rest of pvlib. if mc.system.num_arrays == 1: mc.results.dc = mc.results.dc[0] - - # returning mc is optional, but enables method chaining return mc From 6813c8ed49e94b61c2d744c3f6202073133dede7 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Thu, 13 May 2021 09:19:50 -0600 Subject: [PATCH 24/27] improvements from review --- docs/sphinx/source/modelchain.rst | 74 +++++++++++++++++-------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 5c64043d61..db437b32eb 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -211,6 +211,18 @@ with models selected to be consistent with named PV system models: * :py:meth:`~pvlib.modelchain.ModelChain.with_pvwatts` * :py:meth:`~pvlib.modelchain.ModelChain.with_sapm` +Each "with" method returns a ModelChain using a location and system. Parameters +used to define the system need to be consistent with the models specified by +the "with" method. Using location and system defined above: + +.. ipython:: python + + mc = mc.with_sapm(sapm_system, location) + print(mc) + + mc.run_model(weather) + mc.results.dc + Demystifying ModelChain internals --------------------------------- @@ -223,59 +235,53 @@ The key parts of ModelChain are: 1. The ModelChain.run_model methods. 2. A set of methods that wrap and call the PVSystem methods. 3. A set of methods that can inspect user-supplied objects to infer - the appropriate model when a models isn't specified by the user. + the appropriate model when a model isn't specified by the user. run_model methods ~~~~~~~~~~~~~~~~~ ModelChain provides three methods for executing the chain of models. The methods allow for simulating the output of the PVSystem with different -input irradiance data: +input data: * :py:meth:`~pvlib.modelchain.ModelChain.run_model`, use when ``weather`` - contains global horizontal, direct and diffuse horizontal irradiance ('ghi', 'dni' and 'dhi') + contains global horizontal, direct and diffuse horizontal irradiance + (``'ghi'``, ``'dni'`` and ``'dhi'``). * :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_poa`, use when ``weather`` broadband direct, diffuse and total irradiance in the plane of array - ('poa_global', 'poa_direct', 'poa_diffuse') + (``'poa_global'``, ``'poa_direct'``, ``'poa_diffuse'``). * :py:meth:`~pvlib.modelchain.ModelChain.run_model_from_effective_irradiance`, use when ``weather`` contains spectrally- and reflection-adjusted total - irradiance in the plane of array ('effective_irradiance') + irradiance in the plane of array ('effective_irradiance'). + +To illustrate the use of the `run_model` method, assume that a user has GHI and DHI. +:py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` + requires all three irradiance components (GHI, DNI, and DHI). The user needs to +calculate DNI before using `run_model`. The :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` +method is available for calculating the full set of GHI, DNI, or DHI if +only two of these three series are provided. See also :ref:`dniestmodels` +for methods and functions that can help fully define the irradiance inputs. -To illustrate the use of a `run_model` method, assume that a user has GHI, DHI -and DNI. The :py:meth:`~pvlib.modelchain.ModelChain.run_model` method, shown below, +The :py:meth:`~pvlib.modelchain.ModelChain.run_model` method, shown below, calls a series of methods to complete the modeling steps. The first method, :py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs`, computes parameters such as solar position, airmass, angle of incidence, and -plane of array irradiance. The -:py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` method also -assigns default values for temperature (20 C) -and wind speed (0 m/s) if these inputs are not provided. -:py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` requires all irradiance -components (GHI, DNI, and DHI). The -:py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` -method is available for calculating the full set of GHI, DNI, or DHI if -only two of these three series are provided. See also -:ref:`dniestmodels` for methods and functions that can help fully define -the irradiance inputs. - -Next, :py:meth:`~pvlib.modelchain.ModelChain.run_model` calls the +plane of array irradiance. Next, :py:meth:`~pvlib.modelchain.ModelChain.run_model` calls the wrapper methods for AOI loss, spectral loss, effective irradiance, cell temperature, DC power, AC power, and other losses. These methods are assigned to generic names, as described in the next section. -The methods called by :py:meth:`~pvlib.modelchain.ModelChain.run_model` -store their results in the ``results`` attribute, which is an instance of -:py:class:`~.ModelChainResult`. :py:class:`~.ModelChainResult` has the -following attributes: -``weather``, ``times``, ``solar_position``, ``airmass``, ``total_irrad``, -``aoi``, ``aoi_modifier``, ``spectral_modifier``, ``effective_irradiance``, -``cell_temperature``, ``dc``, ``ac``, ``losses``, ``tracking``, -``diode_params``. - .. ipython:: python mc.run_model?? +The methods called by :py:meth:`~pvlib.modelchain.ModelChain.run_model` +store their results in the ``results`` attribute, which is an instance of +:py:class:`~pvlib.modelchain.ModelChainResult`. For example, :py:class:`~.ModelChainResult` +includes the following attributes: ``solar_position``, ``effective_irradiance``, +``cell_temperature``, ``dc``, ``ac``. See :py:class:`~pvlib.modelchain.ModelChainResult` +for a full list of results attributes. + Wrapping methods into a unified API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -461,7 +467,9 @@ are in the same order as in ``PVSystem.arrays``. mc.results.dc[0] When ``weather`` is a single DataFrame, these data are broadcast and used -for all arrays. To specify data separately for each array, provide a tuple +for all arrays. Weather data can be specified for each array, in which case +``weather`` needs to be a tuple or list of DataFrames in the same order as +the arrays of the PVSystem. To specify data separately for each array, provide a tuple for ``weather`` where each element is a DataFrame containing the required data. Air, module and cell temperatures @@ -526,9 +534,9 @@ function if you wanted to. in a list so that we can iterate. If we didn't put total_irrad in a list, iteration will access each value of the Series, one at a time. - The iteration returns a tuple. If there is a single array, pvlib - unwraps the tuple of length 1. Unwrap the tuple here for consistency - with the rest of pvlib. + The iteration returns a tuple. If there is a single array, the + tuple is of length 1. As a convenience, pvlib unwraps tuples of length 1 + that are assigned to ModelChain.results attributes. Returning mc is optional, but enables method chaining. """ if mc.system.num_arrays == 1: From 6548592cb97a36d3aefc59f049c0fead87b93ceb Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Thu, 13 May 2021 09:49:34 -0600 Subject: [PATCH 25/27] last edits --- docs/sphinx/source/modelchain.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index db437b32eb..408588a41a 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -211,9 +211,9 @@ with models selected to be consistent with named PV system models: * :py:meth:`~pvlib.modelchain.ModelChain.with_pvwatts` * :py:meth:`~pvlib.modelchain.ModelChain.with_sapm` -Each "with" method returns a ModelChain using a location and system. Parameters -used to define the system need to be consistent with the models specified by -the "with" method. Using location and system defined above: +Each "with" method returns a ModelChain using a Location and PVSystem. Parameters +used to define the PVSystem need to be consistent with the models specified by +the "with" method. Using location and sapm_system defined above: .. ipython:: python @@ -255,9 +255,9 @@ input data: irradiance in the plane of array ('effective_irradiance'). To illustrate the use of the `run_model` method, assume that a user has GHI and DHI. -:py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` - requires all three irradiance components (GHI, DNI, and DHI). The user needs to -calculate DNI before using `run_model`. The :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` +:py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` requires all three +irradiance components (GHI, DNI, and DHI). In this case, the user needs +to calculate DNI before using `run_model`. The :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` method is available for calculating the full set of GHI, DNI, or DHI if only two of these three series are provided. See also :ref:`dniestmodels` for methods and functions that can help fully define the irradiance inputs. @@ -482,10 +482,11 @@ Temperature data are passed in the ``weather`` DataFrame and can include: * cell temperature (``'cell_temperature'``). If passed in ``weather`` no cell temperature model is run. -* module temperature, typically measured on the rear surface (``'module_temperature'``). +* module temperature (``'module_temperature'``), typically measured on the rear surface. If found in ``weather`` and ``ModelChain.temperature_model='sapm'`` (either set directly or inferred), the :py:meth:`~pvlib.modelchain.ModelChain.sapm_temp` - method is used to calculate cell temperature. + method is used to calculate cell temperature. If ``ModelChain.temperature_model`` + is set to any other model, ``'module_temperature'`` is ignored. * ambient air temperature (``'temp_air'``). In this case ``ModelChain.temperature_model`` is used to calculate cell temeprature. From 404e1cc53dd66373b00b4f0ebf3275f35794eb5f Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Thu, 13 May 2021 09:51:20 -0600 Subject: [PATCH 26/27] spelling --- docs/sphinx/source/modelchain.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index 408588a41a..dd3606632d 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -414,7 +414,7 @@ parameters on the user-supplied PVSystem object. The inference methods use set logic to assign one of the model-specific methods, such as :py:meth:`~pvlib.modelchain.ModelChain.sapm` or :py:meth:`~pvlib.modelchain.ModelChain.sandia_inverter`, to the universal method names ``ModelChain.dc_model`` and ``ModelChain.ac_model``, -respectively. A few examples are shown below. Inferrence methods generally work +respectively. A few examples are shown below. Inference methods generally work by inspecting the parameters for all required parameters for a corresponding method. From 53e392a215a7eb35bc005624dbf4da3b15bdae56 Mon Sep 17 00:00:00 2001 From: Cliff Hansen Date: Thu, 13 May 2021 11:11:17 -0600 Subject: [PATCH 27/27] remove unneeded unwrap in example function --- docs/sphinx/source/modelchain.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index dd3606632d..00b1d2c6fd 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -551,8 +551,6 @@ function if you wanted to. array.module_parameters['d']) for total_irrad, array in zip(total_irrads, mc.system.arrays)) - if mc.system.num_arrays == 1: - mc.results.dc = mc.results.dc[0] return mc