Skip to content

Commit 879cb46

Browse files
wholmgrencwhanse
authored andcommitted
ModelChain 0.7 deprecations, remove times kwarg (#773)
* modelchain deprecations, remove times * tests * add requires_tables decorator * flake8 * remove ModelChain.singlediode * fix expected value * update whatsnew * uncovered line, whatsnew * feedback * more explicit docstrings
1 parent b98ec26 commit 879cb46

File tree

3 files changed

+137
-164
lines changed

3 files changed

+137
-164
lines changed

docs/sphinx/source/whatsnew/v0.7.0.rst

+14-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ API Changes
2121
old `pvsystem.sapm_celltemp` returned a `DataFrame` with both cell and module temperatures.
2222
- Created `temperature.sapm_module` to return module temperature using the SAPM temperature model.
2323
- Changed the order of arguments for`pvsystem.sapm_celltemp`,
24-
`pvsystem.pvsyst_celltemp` and `PVSystem.sapm_celltemp` to be consistent
24+
`pvsystem.pvsyst_celltemp` and `PVSystem.sapm_celltemp` to be consistent
2525
among cell temperature model functions.
2626
- Removed `model` as a kwarg from `temperature.sapm_cell` and
2727
`temperature.pvsyst_cell`. These functions now require model-specific parameters.
@@ -35,7 +35,7 @@ API Changes
3535
'open_rack_polymer_thinfilm_steel' and '22x_concentrator_tracker'
3636
are considered obsolete and have been removed.
3737
* Changes to `PVSystem` class
38-
- Changed the `model` kwarg in `PVSystem.sapm_celltemp` and
38+
- Changed the `model` kwarg in `PVSystem.sapm_celltemp` and
3939
`PVSystem.pvsyst_celltemp` to `parameter_set`. `parameter_set` expects
4040
a str which is a valid key for `temperature.TEMPERATURE_MODEL_PARAMETERS`
4141
for the corresponding temperature model.
@@ -71,6 +71,15 @@ API Changes
7171

7272
* Calling :py:func:`pvlib.pvsystem.retrieve_sam` with no parameters will raise
7373
an exception instead of displaying a dialog.
74+
* The `times` keyword argument has been deprecated in the
75+
:py:meth:`pvlib.modelchain.ModelChain.run_model`,
76+
:py:meth:`pvlib.modelchain.ModelChain.prepare_inputs`, and
77+
:py:meth:`pvlib.modelchain.ModelChain.complete_irradiance` methods.
78+
Model times are now determined by the input `weather`. `DataFrame`.
79+
Therefore, the `weather` DataFrame must have a `DatetimeIndex`.
80+
The `weather` argument of the above methods is now the first, required
81+
positional argument and the `times` argument is kept as the second keyword
82+
argument for capability during the deprecation period.
7483

7584
Enhancements
7685
~~~~~~~~~~~~
@@ -119,6 +128,9 @@ Removal of prior version deprecations
119128
* Removed `atmosphere.relativeairmass`.
120129
* Removed `solarposition.get_sun_rise_set_transit`.
121130
* Removed `tmy` module.
131+
* Removed `ModelChain.singlediode` method.
132+
* Removed `ModelChain.prepare_inputs` clearsky assumption when no irradiance
133+
data was provided.
122134

123135
Contributors
124136
~~~~~~~~~~~~

pvlib/modelchain.py

+64-88
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
from functools import partial
1010
import warnings
11-
import pandas as pd
1211

1312
from pvlib import (atmosphere, clearsky, pvsystem, solarposition, temperature,
1413
tools)
@@ -412,13 +411,6 @@ def dc_model(self, model):
412411
self._dc_model = self.pvsyst
413412
elif model == 'pvwatts':
414413
self._dc_model = self.pvwatts_dc
415-
elif model == 'singlediode':
416-
warnings.warn('DC model keyword singlediode used for '
417-
'ModelChain object. singlediode is '
418-
'ambiguous, use desoto instead. singlediode '
419-
'keyword will be removed in v0.7.0 and '
420-
'later', pvlibDeprecationWarning)
421-
self._dc_model = self.desoto
422414
else:
423415
raise ValueError(model + ' is not a valid DC power model')
424416
else:
@@ -480,24 +472,6 @@ def cec(self):
480472
def pvsyst(self):
481473
return self._singlediode(self.system.calcparams_pvsyst)
482474

483-
def singlediode(self):
484-
"""Deprecated"""
485-
(photocurrent, saturation_current, resistance_series,
486-
resistance_shunt, nNsVth) = (
487-
self.system.calcparams_desoto(self.effective_irradiance,
488-
self.cell_temperature))
489-
490-
self.desoto = (photocurrent, saturation_current, resistance_series,
491-
resistance_shunt, nNsVth)
492-
493-
self.dc = self.system.singlediode(
494-
photocurrent, saturation_current, resistance_series,
495-
resistance_shunt, nNsVth)
496-
497-
self.dc = self.system.scale_voltage_current_power(self.dc).fillna(0)
498-
499-
return self
500-
501475
def pvwatts_dc(self):
502476
self.dc = self.system.pvwatts_dc(self.effective_irradiance,
503477
self.cell_temperature)
@@ -746,7 +720,7 @@ def effective_irradiance_model(self):
746720
fd*self.total_irrad['poa_diffuse'])
747721
return self
748722

749-
def complete_irradiance(self, times=None, weather=None):
723+
def complete_irradiance(self, weather, times=None):
750724
"""
751725
Determine the missing irradiation columns. Only two of the
752726
following data columns (dni, ghi, dhi) are needed to calculate
@@ -758,19 +732,21 @@ def complete_irradiance(self, times=None, weather=None):
758732
759733
Parameters
760734
----------
761-
times : None or DatetimeIndex, default None
762-
Times at which to evaluate the model. Can be None if
763-
attribute `times` is already set.
764-
weather : None or pandas.DataFrame, default None
765-
Table with at least two columns containing one of the
766-
following data sets: dni, dhi, ghi. Can be None if attribute
767-
`weather` is already set.
735+
weather : DataFrame
736+
Column names must be ``'dni'``, ``'ghi'``, ``'dhi'``,
737+
``'wind_speed'``, ``'temp_air'``. All irradiance components
738+
are required. Air temperature of 20 C and wind speed
739+
of 0 m/s will be added to the DataFrame if not provided.
740+
times : None, deprecated
741+
Deprecated argument included for API compatibility, but not
742+
used internally. The index of the weather DataFrame is used
743+
for times.
768744
769745
Returns
770746
-------
771747
self
772748
773-
Assigns attributes: times, weather
749+
Assigns attributes: weather
774750
775751
Examples
776752
--------
@@ -782,19 +758,23 @@ def complete_irradiance(self, times=None, weather=None):
782758
783759
>>> # my_weather containing 'dhi' and 'ghi'.
784760
>>> mc = ModelChain(my_system, my_location) # doctest: +SKIP
785-
>>> mc.complete_irradiance(my_datetime, my_weather) # doctest: +SKIP
786-
>>> mc.run_model() # doctest: +SKIP
761+
>>> mc.complete_irradiance(my_weather) # doctest: +SKIP
762+
>>> mc.run_model(mc.weather) # doctest: +SKIP
787763
788764
>>> # my_weather containing 'dhi', 'ghi' and 'dni'.
789765
>>> mc = ModelChain(my_system, my_location) # doctest: +SKIP
790-
>>> mc.run_model(my_datetime, my_weather) # doctest: +SKIP
766+
>>> mc.run_model(my_weather) # doctest: +SKIP
791767
"""
792-
if weather is not None:
793-
self.weather = weather
768+
self.weather = weather
769+
794770
if times is not None:
795-
self.times = times
771+
warnings.warn('times keyword argument is deprecated and will be '
772+
'removed in 0.8. The index of the weather DataFrame '
773+
'is used for times.', pvlibDeprecationWarning)
774+
796775
self.solar_position = self.location.get_solarposition(
797-
self.times, method=self.solar_position_method)
776+
self.weather.index, method=self.solar_position_method)
777+
798778
icolumns = set(self.weather.columns)
799779
wrn_txt = ("This function is not safe at the moment.\n" +
800780
"Results can be too high or negative.\n" +
@@ -803,7 +783,7 @@ def complete_irradiance(self, times=None, weather=None):
803783

804784
if {'ghi', 'dhi'} <= icolumns and 'dni' not in icolumns:
805785
clearsky = self.location.get_clearsky(
806-
times, solar_position=self.solar_position)
786+
self.weather.index, solar_position=self.solar_position)
807787
self.weather.loc[:, 'dni'] = pvlib.irradiance.dni(
808788
self.weather.loc[:, 'ghi'], self.weather.loc[:, 'dhi'],
809789
self.solar_position.zenith,
@@ -822,62 +802,54 @@ def complete_irradiance(self, times=None, weather=None):
822802

823803
return self
824804

825-
def prepare_inputs(self, times=None, weather=None):
805+
def prepare_inputs(self, weather, times=None):
826806
"""
827807
Prepare the solar position, irradiance, and weather inputs to
828808
the model.
829809
830810
Parameters
831811
----------
832-
times : None or DatetimeIndex, default None
833-
Times at which to evaluate the model. Can be None if
834-
attribute `times` is already set.
835-
weather : None or DataFrame, default None
836-
If ``None``, the weather attribute is used. Column names
837-
must be ``'dni'``, ``'ghi'``, ``'dhi'``, ``'wind_speed'``,
838-
``'temp_air'``. All irradiance components are required.
839-
Assumes air temperature is 20 C and wind speed is 0 m/s if
840-
not provided.
812+
weather : DataFrame
813+
Column names must be ``'dni'``, ``'ghi'``, ``'dhi'``,
814+
``'wind_speed'``, ``'temp_air'``. All irradiance components
815+
are required. Air temperature of 20 C and wind speed
816+
of 0 m/s will be added to the DataFrame if not provided.
817+
times : None, deprecated
818+
Deprecated argument included for API compatibility, but not
819+
used internally. The index of the weather DataFrame is used
820+
for times.
841821
842822
Notes
843823
-----
844-
Assigns attributes: ``times``, ``solar_position``, ``airmass``,
824+
Assigns attributes: ``solar_position``, ``airmass``,
845825
``total_irrad``, `aoi`
846826
847827
See also
848828
--------
849829
ModelChain.complete_irradiance
850830
"""
851-
if weather is not None:
852-
self.weather = weather
853-
if self.weather is None:
854-
self.weather = pd.DataFrame(index=times)
831+
832+
if not {'ghi', 'dni', 'dhi'} <= set(weather.columns):
833+
raise ValueError(
834+
"Uncompleted irradiance data set. Please check your input "
835+
"data.\nData set needs to have 'dni', 'dhi' and 'ghi'.\n"
836+
"Detected data: {0}".format(list(weather.columns)))
837+
838+
self.weather = weather
855839

856840
if times is not None:
857-
self.times = times
841+
warnings.warn('times keyword argument is deprecated and will be '
842+
'removed in 0.8. The index of the weather DataFrame '
843+
'is used for times.', pvlibDeprecationWarning)
844+
845+
self.times = self.weather.index
858846

859847
self.solar_position = self.location.get_solarposition(
860-
self.times, method=self.solar_position_method)
848+
self.weather.index, method=self.solar_position_method)
861849

862850
self.airmass = self.location.get_airmass(
863851
solar_position=self.solar_position, model=self.airmass_model)
864852

865-
if not any([x in ['ghi', 'dni', 'dhi'] for x in self.weather.columns]):
866-
warnings.warn('Clear sky assumption for no input irradiance is '
867-
'deprecated and will be removed in v0.7.0. Use '
868-
'location.get_clearsky instead',
869-
pvlibDeprecationWarning)
870-
self.weather[['ghi', 'dni', 'dhi']] = self.location.get_clearsky(
871-
self.solar_position.index, self.clearsky_model,
872-
solar_position=self.solar_position,
873-
airmass_absolute=self.airmass['airmass_absolute'])
874-
875-
if not {'ghi', 'dni', 'dhi'} <= set(self.weather.columns):
876-
raise ValueError(
877-
"Uncompleted irradiance data set. Please check your input "
878-
"data.\nData set needs to have 'dni', 'dhi' and 'ghi'.\n"
879-
"Detected data: {0}".format(list(self.weather.columns)))
880-
881853
# PVSystem.get_irradiance and SingleAxisTracker.get_irradiance
882854
# and PVSystem.get_aoi and SingleAxisTracker.get_aoi
883855
# have different method signatures. Use partial to handle
@@ -921,32 +893,36 @@ def prepare_inputs(self, times=None, weather=None):
921893
self.weather['temp_air'] = 20
922894
return self
923895

924-
def run_model(self, times=None, weather=None):
896+
def run_model(self, weather, times=None):
925897
"""
926898
Run the model.
927899
928900
Parameters
929901
----------
930-
times : None or DatetimeIndex, default None
931-
Times at which to evaluate the model. Can be None if
932-
attribute `times` is already set.
933-
weather : None or DataFrame, default None
934-
If ``None``, the weather attribute is used. Column names
935-
must be ``'dni'``, ``'ghi'``, ``'dhi'``, ``'wind_speed'``,
936-
``'temp_air'``. All irradiance components are required.
937-
Assumes air temperature is 20 C and wind speed is 0 m/s if
938-
not provided.
902+
weather : DataFrame
903+
Column names must be ``'dni'``, ``'ghi'``, ``'dhi'``,
904+
``'wind_speed'``, ``'temp_air'``. All irradiance components
905+
are required. Air temperature of 20 C and wind speed
906+
of 0 m/s will be added to the DataFrame if not provided.
907+
times : None, deprecated
908+
Deprecated argument included for API compatibility, but not
909+
used internally. The index of the weather DataFrame is used
910+
for times.
939911
940912
Returns
941913
-------
942914
self
943915
944-
Assigns attributes: times, solar_position, airmass, irradiance,
916+
Assigns attributes: solar_position, airmass, irradiance,
945917
total_irrad, effective_irradiance, weather, cell_temperature, aoi,
946918
aoi_modifier, spectral_modifier, dc, ac, losses.
947919
"""
920+
if times is not None:
921+
warnings.warn('times keyword argument is deprecated and will be '
922+
'removed in 0.8. The index of the weather DataFrame '
923+
'is used for times.', pvlibDeprecationWarning)
948924

949-
self.prepare_inputs(times, weather)
925+
self.prepare_inputs(weather)
950926
self.aoi_model()
951927
self.spectral_model()
952928
self.effective_irradiance_model()

0 commit comments

Comments
 (0)