diff --git a/.stickler.yml b/.stickler.yml index 41aa301c06..dc360a6a7b 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -2,7 +2,7 @@ linters: flake8: python: 3 max-line-length: 79 - ignore: E201,E241,E226 + ignore: E201,E241,E226,W503,W504 files: ignore: - 'pvlib/_version.py' diff --git a/docs/sphinx/source/whatsnew/v0.8.0.rst b/docs/sphinx/source/whatsnew/v0.8.0.rst index b87f79067b..98df53001b 100644 --- a/docs/sphinx/source/whatsnew/v0.8.0.rst +++ b/docs/sphinx/source/whatsnew/v0.8.0.rst @@ -12,6 +12,15 @@ API Changes with Deprecations - :py:func:`pvlib.pvsystem.adrinverter` is now :py:func:`pvlib.inverter.adr` * Argument ``ac_model`` for :py:class:`pvlib.modelchain.ModelChain` now accepts ``'sandia'``, ``'pvwatts'`` and ``'adr'`` for the inverter models. (:pull:`886`) +* :py:class:`pvlib.pvsystem.PVSystem` ``module_type`` and ``racking_model`` now + default to ``None``. This continues a deprecation of assuming SAPM values + for cell temperature modeling. In this v0.8 release series, calling + :py:meth:`pvlib.pvsystem.PVSystem.sapm_celltemp` without setting ``PVSystem.temperature model parameters``, + or a valid combination of ``PVsystem.module_type`` and ``PVsystem.racking_model``, will cause + ``PVSystem.temperature_model_parameters`` to be set to SAPM values for a + glass/glass module in open racking and emit a warning. In v0.9, users must + provide ``temperature_model_parameters`` or a valid combination of + ``module_type`` and ``racking_model``. (:issue:`1030`, :pull:`1033`) API Changes ~~~~~~~~~~~ @@ -31,6 +40,23 @@ API Changes :py:func:`pvlib.iotools.read_tmy3`, :py:meth:`pvlib.location.Location.from_tmy`, and :py:class:`pvlib.pvsystem.LocalizedPVSystem` for alternatives. (:issue:`965`) (:pull:`1008`) +* The following functions, methods, and arguments were deprecated in a previous + release and have now been removed (:issue:`966`, :pull:`1033`): + * ``pvsystem.PVSystem.ashraeiam``. Use :py:meth:`pvlib.pvsystem.PVSystem.get_iam`. + * ``pvsystem.PVSystem.physicaliam``. Use :py:meth:`pvlib.pvsystem.PVSystem.get_iam`. + * ``pvsystem.PVSystem.sapm_aoi_loss``. Use :py:meth:`pvlib.pvsystem.PVSystem.get_iam`. + * ``pvsystem.ashraeiam``. Use :py:func:`pvlib.iam.ashrae`. + * ``pvsystem.physicaliam``. Use :py:func:`pvlib.iam.physical`. + * ``pvsystem.sapm_aoi_loss``. Use :py:func:`pvlib.iam.sapm`. + * ``pvsystem.sapm_celltemp``. Use :py:func:`pvlib.temperature.sapm_cell`. + * ``pvsystem.pvsyst_celltemp``. Use :py:func:`pvlib.temperature.pvsyst_cell`. + * ``times`` keyword argument of + :py:meth:`pvlib.modelchain.ModelChain.run_model`, + :py:meth:`pvlib.modelchain.ModelChain.complete_irradiance`, and + :py:meth:`pvlib.modelchain.ModelChain.prepare_inputs`. + The index of the input DataFrame is used instead. + * ``temp_model`` keyword argument of + :py:meth:`pvlib.modelchain.ModelChain`. Use ``temperature_model`` instead. Enhancements ~~~~~~~~~~~~ diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 2479f16118..9e6e3f0fcd 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -179,7 +179,7 @@ def basic_chain(times, latitude, longitude, linke_turbidity, altitude=altitude, dni_extra=dni_extra - ) + ) total_irrad = pvlib.irradiance.get_total_irradiance( surface_tilt, @@ -346,24 +346,6 @@ def __init__(self, system, location, self.ac_model = ac_model self.aoi_model = aoi_model self.spectral_model = spectral_model - - # TODO: deprecated kwarg temp_model. Remove use of temp_model in v0.8 - temp_model = kwargs.pop('temp_model', None) - if temp_model is not None: - if temperature_model is None: - warnings.warn('The temp_model keyword argument is deprecated.' - ' Use temperature_model instead', - pvlibDeprecationWarning) - temperature_model = temp_model - elif temp_model == temperature_model: - warnings.warn('Provide only one of temperature_model or ' - 'temp_model (deprecated).', - pvlibDeprecationWarning) - else: - raise ValueError( - 'Conflicting temperature_model {} and temp_model {}. ' - 'temp_model is deprecated. Specify only temperature_model.' - .format(temperature_model, temp_model)) self.temperature_model = temperature_model self.losses_model = losses_model @@ -544,7 +526,7 @@ def __repr__(self): 'transposition_model', 'solar_position_method', 'airmass_model', 'dc_model', 'ac_model', 'aoi_model', 'spectral_model', 'temperature_model', 'losses_model' - ] + ] def getmcattr(self, attr): """needed to avoid recursion in property lookups""" @@ -588,8 +570,8 @@ def dc_model(self, model): model = model.lower() if model in _DC_MODEL_PARAMS.keys(): # validate module parameters - missing_params = _DC_MODEL_PARAMS[model] - \ - set(self.system.module_parameters.keys()) + missing_params = (_DC_MODEL_PARAMS[model] + - set(self.system.module_parameters.keys())) if missing_params: # some parameters are not in module.keys() raise ValueError(model + ' selected for the DC model but ' 'one or more required parameters are ' @@ -834,8 +816,8 @@ def infer_spectral_model(self): def first_solar_spectral_loss(self): self.spectral_modifier = self.system.first_solar_spectral_loss( - self.weather['precipitable_water'], - self.airmass['airmass_absolute']) + self.weather['precipitable_water'], + self.airmass['airmass_absolute']) return self def sapm_spectral_loss(self): @@ -878,7 +860,10 @@ def temperature_model(self, model): def infer_temperature_model(self): params = set(self.system.temperature_model_parameters.keys()) - if set(['a', 'b', 'deltaT']) <= params: + # remove or statement in v0.9 + if set(['a', 'b', 'deltaT']) <= params or ( + not params and self.system.racking_model is None + and self.system.module_type is None): return self.sapm_temp elif set(['u_c', 'u_v']) <= params: return self.pvsyst_temp @@ -945,7 +930,7 @@ def effective_irradiance_model(self): fd*self.total_irrad['poa_diffuse']) return self - def complete_irradiance(self, weather, times=None): + def complete_irradiance(self, weather): """ Determine the missing irradiation columns. Only two of the following data columns (dni, ghi, dhi) are needed to calculate @@ -962,10 +947,6 @@ def complete_irradiance(self, weather, times=None): ``'wind_speed'``, ``'temp_air'``. All irradiance components are required. Air temperature of 20 C and wind speed of 0 m/s will be added to the DataFrame if not provided. - times : None, deprecated - Deprecated argument included for API compatibility, but not - used internally. The index of the weather DataFrame is used - for times. Returns ------- @@ -994,11 +975,6 @@ def complete_irradiance(self, weather, times=None): """ self.weather = weather - if times is not None: - warnings.warn('times keyword argument is deprecated and will be ' - 'removed in 0.8. The index of the weather DataFrame ' - 'is used for times.', pvlibDeprecationWarning) - self.solar_position = self.location.get_solarposition( self.weather.index, method=self.solar_position_method) @@ -1029,7 +1005,7 @@ def complete_irradiance(self, weather, times=None): return self - def prepare_inputs(self, weather, times=None): + def prepare_inputs(self, weather): """ Prepare the solar position, irradiance, and weather inputs to the model. @@ -1041,10 +1017,6 @@ def prepare_inputs(self, weather, times=None): ``'wind_speed'``, ``'temp_air'``. All irradiance components are required. Air temperature of 20 C and wind speed of 0 m/s will be added to the DataFrame if not provided. - times : None, deprecated - Deprecated argument included for API compatibility, but not - used internally. The index of the weather DataFrame is used - for times. Notes ----- @@ -1064,11 +1036,6 @@ def prepare_inputs(self, weather, times=None): self.weather = weather - if times is not None: - warnings.warn('times keyword argument is deprecated and will be ' - 'removed in 0.8. The index of the weather DataFrame ' - 'is used for times.', pvlibDeprecationWarning) - self.times = self.weather.index try: kwargs = _build_kwargs(['pressure', 'temp_air'], weather) @@ -1126,7 +1093,7 @@ def prepare_inputs(self, weather, times=None): self.weather['temp_air'] = 20 return self - def run_model(self, weather, times=None): + def run_model(self, weather): """ Run the model. @@ -1137,10 +1104,6 @@ def run_model(self, weather, times=None): ``'wind_speed'``, ``'temp_air'``. All irradiance components are required. Air temperature of 20 C and wind speed of 0 m/s will be added to the DataFrame if not provided. - times : None, deprecated - Deprecated argument included for API compatibility, but not - used internally. The index of the weather DataFrame is used - for times. Returns ------- @@ -1152,11 +1115,6 @@ def run_model(self, weather, times=None): ``dc``, ``ac``, ``losses``, ``diode_params`` (if dc_model is a single diode model) """ - if times is not None: - warnings.warn('times keyword argument is deprecated and will be ' - 'removed in 0.8. The index of the weather DataFrame ' - 'is used for times.', pvlibDeprecationWarning) - self.prepare_inputs(weather) self.aoi_model() self.spectral_model() diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 8232d9dc73..bf1b3bab06 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -170,12 +170,12 @@ class PVSystem(object): def __init__(self, surface_tilt=0, surface_azimuth=180, albedo=None, surface_type=None, - module=None, module_type='glass_polymer', + module=None, module_type=None, module_parameters=None, temperature_model_parameters=None, modules_per_string=1, strings_per_inverter=1, inverter=None, inverter_parameters=None, - racking_model='open_rack', losses_parameters=None, name=None, + racking_model=None, losses_parameters=None, name=None, **kwargs): self.surface_tilt = surface_tilt @@ -201,25 +201,9 @@ def __init__(self, if temperature_model_parameters is None: self.temperature_model_parameters = \ self._infer_temperature_model_params() - # TODO: in v0.8 check if an empty dict is returned and raise error else: self.temperature_model_parameters = temperature_model_parameters - # TODO: deprecated behavior if PVSystem.temperature_model_parameters - # are not specified. Remove in v0.8 - if not any(self.temperature_model_parameters): - warnings.warn( - 'Required temperature_model_parameters is not specified ' - 'and parameters are not inferred from racking_model and ' - 'module_type. Reverting to deprecated default: SAPM cell ' - 'temperature model parameters for a glass/glass module in ' - 'open racking. In the future ' - 'PVSystem.temperature_model_parameters will be required', - pvlibDeprecationWarning) - params = temperature._temperature_model_params( - 'sapm', 'open_rack_glass_glass') - self.temperature_model_parameters = params - self.modules_per_string = modules_per_string self.strings_per_inverter = strings_per_inverter @@ -358,26 +342,6 @@ def get_iam(self, aoi, iam_model='physical'): else: raise ValueError(model + ' is not a valid IAM model') - def ashraeiam(self, aoi): - """ - Deprecated. Use ``PVSystem.get_iam`` instead. - """ - import warnings - warnings.warn('PVSystem.ashraeiam is deprecated and will be removed in' - 'v0.8, use PVSystem.get_iam instead', - pvlibDeprecationWarning) - return PVSystem.get_iam(self, aoi, iam_model='ashrae') - - def physicaliam(self, aoi): - """ - Deprecated. Use ``PVSystem.get_iam`` instead. - """ - import warnings - warnings.warn('PVSystem.physicaliam is deprecated and will be removed' - ' in v0.8, use PVSystem.get_iam instead', - pvlibDeprecationWarning) - return PVSystem.get_iam(self, aoi, iam_model='physical') - def calcparams_desoto(self, effective_irradiance, temp_cell, **kwargs): """ Use the :py:func:`calcparams_desoto` function, the input @@ -506,6 +470,21 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed): ------- numeric, values in degrees C. """ + # warn user about change in default behavior in 0.9. + if (self.temperature_model_parameters == {} and self.module_type + is None and self.racking_model is None): + warnings.warn( + 'temperature_model_parameters, racking_model, and module_type ' + 'are not specified. Reverting to deprecated default: SAPM ' + 'cell temperature model parameters for a glass/glass module ' + 'in open racking. In v0.9, temperature_model_parameters or a ' + 'valid combination of racking_model and module_type will be ' + 'required.', + pvlibDeprecationWarning) + params = temperature._temperature_model_params( + 'sapm', 'open_rack_glass_glass') + self.temperature_model_parameters = params + kwargs = _build_kwargs(['a', 'b', 'deltaT'], self.temperature_model_parameters) return temperature.sapm_cell(poa_global, temp_air, wind_speed, @@ -514,7 +493,7 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed): def _infer_temperature_model_params(self): # try to infer temperature model parameters from from racking_model # and module_type - param_set = self.racking_model + '_' + self.module_type + param_set = '{}_{}'.format(self.racking_model, self.module_type) if param_set in temperature.TEMPERATURE_MODEL_PARAMETERS['sapm']: return temperature._temperature_model_params('sapm', param_set) elif 'freestanding' in param_set: @@ -543,16 +522,6 @@ def sapm_spectral_loss(self, airmass_absolute): """ return sapm_spectral_loss(airmass_absolute, self.module_parameters) - def sapm_aoi_loss(self, aoi): - """ - Deprecated. Use ``PVSystem.get_iam`` instead. - """ - import warnings - warnings.warn('PVSystem.sapm_aoi_loss is deprecated and will be' - ' removed in v0.8, use PVSystem.get_iam instead', - pvlibDeprecationWarning) - return PVSystem.get_iam(self, aoi, iam_model='sapm') - def sapm_effective_irradiance(self, poa_direct, poa_diffuse, airmass_absolute, aoi, reference_irradiance=1000): @@ -671,7 +640,7 @@ def first_solar_spectral_loss(self, pw, airmass_absolute): if 'first_solar_spectral_coefficients' in \ self.module_parameters.keys(): coefficients = \ - self.module_parameters['first_solar_spectral_coefficients'] + self.module_parameters['first_solar_spectral_coefficients'] module_type = None else: module_type = self._infer_cell_type() @@ -1071,27 +1040,6 @@ def calcparams_desoto(effective_irradiance, temp_cell, Source: [4] ''' - # test for use of function pre-v0.6.0 API change - if isinstance(a_ref, dict) or \ - (isinstance(a_ref, pd.Series) and ('a_ref' in a_ref.keys())): - import warnings - warnings.warn('module_parameters detected as fourth positional' - + ' argument of calcparams_desoto. calcparams_desoto' - + ' will require one argument for each module model' - + ' parameter in v0.7.0 and later', DeprecationWarning) - try: - module_parameters = a_ref - a_ref = module_parameters['a_ref'] - I_L_ref = module_parameters['I_L_ref'] - I_o_ref = module_parameters['I_o_ref'] - R_sh_ref = module_parameters['R_sh_ref'] - R_s = module_parameters['R_s'] - except Exception as e: - raise e('Module parameters could not be extracted from fourth' - + ' positional argument of calcparams_desoto. Check that' - + ' parameters are from the CEC database and/or update' - + ' your code for the new API for calcparams_desoto') - # Boltzmann constant in eV/K k = 8.617332478e-05 @@ -1624,16 +1572,6 @@ def sapm(effective_irradiance, temp_cell, module): # reference_irradiance and expose temp_ref = 25 irrad_ref = 1000 - # TODO: remove this warning in v0.8 after deprecation period for change in - # effective irradiance units, made in v0.7 - with np.errstate(invalid='ignore'): # turn off warning for NaN - ee = np.asarray(effective_irradiance) - ee_gt0 = ee[ee > 0.0] - if ee_gt0.size > 0 and np.all(ee_gt0 < 2.0): - import warnings - msg = 'effective_irradiance inputs appear to be in suns. Units ' \ - 'changed in v0.7 from suns to W/m2' - warnings.warn(msg, RuntimeWarning) q = 1.60218e-19 # Elementary charge in units of coulombs kb = 1.38066e-23 # Boltzmann's constant in units of J/K @@ -1695,85 +1633,6 @@ def sapm(effective_irradiance, temp_cell, module): return out -def _sapm_celltemp_translator(*args, **kwargs): - # TODO: remove this function after deprecation period for sapm_celltemp - new_kwargs = {} - # convert position arguments to kwargs - old_arg_list = ['poa_global', 'wind_speed', 'temp_air', 'model'] - for pos in range(len(args)): - new_kwargs[old_arg_list[pos]] = args[pos] - # determine value for new kwarg 'model' - try: - param_set = new_kwargs['model'] - new_kwargs.pop('model') # model is not a new kwarg - except KeyError: - # 'model' not in positional arguments, check kwargs - try: - param_set = kwargs['model'] - kwargs.pop('model') - except KeyError: - # 'model' not in kwargs, use old default value - param_set = 'open_rack_glass_glass' - if type(param_set) is list: - new_kwargs.update({'a': param_set[0], - 'b': param_set[1], - 'deltaT': param_set[2]}) - elif type(param_set) is dict: - new_kwargs.update(param_set) - else: # string - params = temperature._temperature_model_params('sapm', param_set) - new_kwargs.update(params) - new_kwargs.update(kwargs) # kwargs with unchanged names - new_kwargs['irrad_ref'] = 1000 # default for new kwarg - # convert old positional arguments to named kwargs - return temperature.sapm_cell(**new_kwargs) - - -sapm_celltemp = deprecated('0.7', alternative='temperature.sapm_cell', - name='sapm_celltemp', removal='0.8', - addendum='Note that the arguments and argument ' - 'order for temperature.sapm_cell are different ' - 'than for sapm_celltemp')(_sapm_celltemp_translator) - - -def _pvsyst_celltemp_translator(*args, **kwargs): - # TODO: remove this function after deprecation period for pvsyst_celltemp - new_kwargs = {} - # convert position arguments to kwargs - old_arg_list = ['poa_global', 'temp_air', 'wind_speed', 'eta_m', - 'alpha_absorption', 'model_params'] - for pos in range(len(args)): - new_kwargs[old_arg_list[pos]] = args[pos] - # determine value for new kwarg 'model' - try: - param_set = new_kwargs['model_params'] - new_kwargs.pop('model_params') # model_params is not a new kwarg - except KeyError: - # 'model_params' not in positional arguments, check kwargs - try: - param_set = kwargs['model_params'] - kwargs.pop('model_params') - except KeyError: - # 'model_params' not in kwargs, use old default value - param_set = 'freestanding' - if type(param_set) in (list, tuple): - new_kwargs.update({'u_c': param_set[0], - 'u_v': param_set[1]}) - else: # string - params = temperature._temperature_model_params('pvsyst', param_set) - new_kwargs.update(params) - new_kwargs.update(kwargs) # kwargs with unchanged names - # convert old positional arguments to named kwargs - return temperature.pvsyst_cell(**new_kwargs) - - -pvsyst_celltemp = deprecated( - '0.7', alternative='temperature.pvsyst_cell', name='pvsyst_celltemp', - removal='0.8', addendum='Note that the argument names for ' - 'temperature.pvsyst_cell are different than ' - 'for pvsyst_celltemp')(_pvsyst_celltemp_translator) - - def sapm_spectral_loss(airmass_absolute, module): """ Calculates the SAPM spectral loss coefficient, F1. @@ -2051,8 +1910,7 @@ def singlediode(photocurrent, saturation_current, resistance_series, # calculate the IV curve if requested using bishop88 if ivcurve_pnts: vd = v_oc * ( - (11.0 - np.logspace(np.log10(11.0), 0.0, - ivcurve_pnts)) / 10.0 + (11.0 - np.logspace(np.log10(11.0), 0.0, ivcurve_pnts)) / 10.0 ) ivcurve_i, ivcurve_v, _ = _singlediode.bishop88(vd, *args) @@ -2301,17 +2159,17 @@ def i_from_v(resistance_shunt, resistance_series, nNsVth, voltage, # equation for the diode voltage V_d then backing out voltage args = (voltage, photocurrent, saturation_current, resistance_series, resistance_shunt, nNsVth) - I = _singlediode.bishop88_i_from_v(*args, method=method.lower()) + current = _singlediode.bishop88_i_from_v(*args, method=method.lower()) # find the right size and shape for returns size, shape = _singlediode._get_size_and_shape(args) if size <= 1: if shape is not None: - I = np.tile(I, shape) - if np.isnan(I).any() and size <= 1: - I = np.repeat(I, size) + current = np.tile(current, shape) + if np.isnan(current).any() and size <= 1: + current = np.repeat(current, size) if shape is not None: - I = I.reshape(shape) - return I + current = current.reshape(shape) + return current def scale_voltage_current_power(data, voltage=1, current=1): @@ -2390,7 +2248,7 @@ def pvwatts_dc(g_poa_effective, temp_cell, pdc0, gamma_pdc, temp_ref=25.): .. [1] A. P. Dobos, "PVWatts Version 5 Manual" http://pvwatts.nrel.gov/downloads/pvwattsv5.pdf (2014). - """ + """ # noqa: E501 pdc = (g_poa_effective * 0.001 * pdc0 * (1 + gamma_pdc * (temp_cell - temp_ref))) @@ -2452,18 +2310,6 @@ def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2, return losses -ashraeiam = deprecated('0.7', alternative='iam.ashrae', name='ashraeiam', - removal='0.8')(iam.ashrae) - - -physicaliam = deprecated('0.7', alternative='iam.physical', name='physicaliam', - removal='0.8')(iam.physical) - - -sapm_aoi_loss = deprecated('0.7', alternative='iam.sapm', name='sapm_aoi_loss', - removal='0.8')(iam.sapm) - - snlinverter = deprecated('0.8', alternative='inverter.sandia', name='snlinverter', removal='0.9')(inverter.sandia) diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index e6d8f70083..af7d631dc9 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -13,7 +13,7 @@ from conftest import assert_series_equal import pytest -from conftest import fail_on_pvlib_version, requires_scipy, requires_tables +from conftest import fail_on_pvlib_version, requires_scipy @pytest.fixture(scope='function') @@ -153,6 +153,18 @@ def system_no_aoi(cec_module_cs5p_220m, sapm_temperature_cs5p_220m, return system +@pytest.fixture +def system_no_temp(cec_module_cs5p_220m, cec_inverter_parameters): + module_parameters = cec_module_cs5p_220m.copy() + module_parameters['EgRef'] = 1.121 + module_parameters['dEgdT'] = -0.0002677 + inverter_parameters = cec_inverter_parameters.copy() + system = PVSystem(surface_tilt=32.2, surface_azimuth=180, + module_parameters=module_parameters, + inverter_parameters=inverter_parameters) + return system + + @pytest.fixture def location(): return Location(32.2, -111, altitude=700) @@ -211,24 +223,6 @@ def test_run_model_with_irradiance(sapm_dc_snl_ac_system, location): assert_series_equal(ac, expected) -def test_run_model_times(sapm_dc_snl_ac_system, location): - mc = ModelChain(sapm_dc_snl_ac_system, location) - times = pd.date_range('20160101 1200-0700', periods=2, freq='6H') - irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150}, - index=times) - with pytest.warns(pvlibDeprecationWarning): - mc.run_model(irradiance, times=times) - - -def test_prepare_inputs_times(sapm_dc_snl_ac_system, location): - mc = ModelChain(sapm_dc_snl_ac_system, location) - times = pd.date_range('20160101 1200-0700', periods=2, freq='6H') - irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150}, - index=times) - with pytest.warns(pvlibDeprecationWarning): - mc.prepare_inputs(irradiance, times=times) - - def test_prepare_inputs_no_irradiance(sapm_dc_snl_ac_system, location): mc = ModelChain(sapm_dc_snl_ac_system, location) weather = pd.DataFrame() @@ -236,15 +230,6 @@ def test_prepare_inputs_no_irradiance(sapm_dc_snl_ac_system, location): mc.prepare_inputs(weather) -@requires_tables -def test_complete_irradiance_times(sapm_dc_snl_ac_system, location): - mc = ModelChain(sapm_dc_snl_ac_system, location) - times = pd.date_range('20160101 1200-0700', periods=2, freq='6H') - irradiance = pd.DataFrame({'ghi': 600., 'dhi': 150.}, index=times) - with pytest.warns(pvlibDeprecationWarning): - mc.complete_irradiance(irradiance, times=times) - - def test_run_model_perez(sapm_dc_snl_ac_system, location): mc = ModelChain(sapm_dc_snl_ac_system, location, transposition_model='perez') @@ -277,8 +262,6 @@ def test_run_model_with_weather_sapm_temp(sapm_dc_snl_ac_system, location, # test with sapm cell temperature model weather['wind_speed'] = 5 weather['temp_air'] = 10 - sapm_dc_snl_ac_system.racking_model = 'open_rack' - sapm_dc_snl_ac_system.module_type = 'glass_glass' mc = ModelChain(sapm_dc_snl_ac_system, location) mc.temperature_model = 'sapm' m_sapm = mocker.spy(sapm_dc_snl_ac_system, 'sapm_celltemp') @@ -437,6 +420,17 @@ def test_infer_temp_model_invalid(location, sapm_dc_snl_ac_system): spectral_model='no_loss') +# ModelChain.infer_temperature_model. remove or statement in v0.9 +@requires_scipy +@fail_on_pvlib_version('0.9') +def test_infer_temp_model_no_params(location, system_no_temp, weather): + mc = ModelChain(system_no_temp, location, aoi_model='physical', + spectral_model='no_loss') + match = "Reverting to deprecated default: SAPM cell temperature" + with pytest.warns(pvlibDeprecationWarning, match=match): + mc.run_model(weather) + + @requires_scipy def test_temperature_model_inconsistent(location, sapm_dc_snl_ac_system): with pytest.raises(ValueError): @@ -688,36 +682,6 @@ def test_bad_get_orientation(): modelchain.get_orientation('bad value') -@fail_on_pvlib_version('0.8') -def test_deprecated_08(): - # explicit system creation call because fail_on_pvlib_version - # does not support decorators. - # does not matter what the parameters are, just fake it until we make it - module_parameters = {'R_sh_ref': 1, 'a_ref': 1, 'I_o_ref': 1, - 'alpha_sc': 1, 'I_L_ref': 1, 'R_s': 1} - # do not assign PVSystem.temperature_model_parameters - # leave out PVSystem.racking_model and PVSystem.module_type - system = PVSystem(module_parameters=module_parameters) - # deprecated temp_model kwarg - warn_txt = 'temp_model keyword argument is deprecated' - with pytest.warns(pvlibDeprecationWarning, match=warn_txt): - ModelChain(system, location, dc_model='desoto', aoi_model='no_loss', - spectral_model='no_loss', ac_model='sandia', - temp_model='sapm') - # provide both temp_model and temperature_model kwargs - warn_txt = 'Provide only one of temperature_model' - with pytest.warns(pvlibDeprecationWarning, match=warn_txt): - ModelChain(system, location, dc_model='desoto', aoi_model='no_loss', - spectral_model='no_loss', ac_model='sandia', - temperature_model='sapm', temp_model='sapm') - # conflicting temp_model and temperature_model kwargs - exc_text = 'Conflicting temperature_model' - with pytest.raises(ValueError, match=exc_text): - ModelChain(system, location, dc_model='desoto', aoi_model='no_loss', - spectral_model='no_loss', ac_model='sandia', - temperature_model='pvsyst', temp_model='sapm') - - @fail_on_pvlib_version('0.9') @pytest.mark.parametrize('ac_model', ['snlinverter', 'adrinverter']) def test_deprecated_09(sapm_dc_snl_ac_system, cec_dc_adr_ac_system, diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 280c6d6d55..4febb71f43 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -198,17 +198,6 @@ def test_sapm(sapm_module_params): pd.Series(sapm_module_params)) -def test_pvsystem_sapm_warning(sapm_module_params): - # deprecation warning for change in effective_irradiance units in - # pvsystem.sapm - # TODO: remove after deprecation period (v0.8) - effective_irradiance = np.array([0.1, 0.2, 1.3]) - temp_cell = np.array([25, 25, 50]) - warn_txt = 'effective_irradiance inputs appear to be in suns' - with pytest.warns(RuntimeWarning, match=warn_txt): - pvsystem.sapm(effective_irradiance, temp_cell, sapm_module_params) - - def test_PVSystem_sapm(sapm_module_params, mocker): mocker.spy(pvsystem, 'sapm') system = pvsystem.PVSystem(module_parameters=sapm_module_params) @@ -386,14 +375,6 @@ def test__infer_temperature_model_params(): assert expected == system._infer_temperature_model_params() -def test__infer_temperature_model_params_deprec_warning(): - warn_txt = "Reverting to deprecated default" - with pytest.warns(pvlibDeprecationWarning, match=warn_txt): - pvsystem.PVSystem(module_parameters={}, - racking_model='not_a_rack_model', - module_type='glass_polymer') - - def test_calcparams_desoto(cec_module_params): times = pd.date_range(start='2015-01-01', periods=3, freq='12H') effective_irradiance = pd.Series([0.0, 800.0, 800.0], index=times) @@ -1130,8 +1111,8 @@ def test_PVSystem___repr__(): module: blah inverter: blarg albedo: 0.25 - racking_model: open_rack - module_type: glass_polymer + racking_model: None + module_type: None temperature_model_parameters: {'a': -3.56}""" assert system.__repr__() == expected @@ -1153,8 +1134,8 @@ def test_PVSystem_localize___repr__(): module: blah inverter: blarg albedo: 0.25 - racking_model: open_rack - module_type: glass_polymer + racking_model: None + module_type: None temperature_model_parameters: {'a': -3.56}""" assert localized_system.__repr__() == expected @@ -1193,8 +1174,8 @@ def test_LocalizedPVSystem___repr__(): module: blah inverter: blarg albedo: 0.25 - racking_model: open_rack - module_type: glass_polymer + racking_model: None + module_type: None temperature_model_parameters: {'a': -3.56}""" assert localized_system.__repr__() == expected @@ -1318,94 +1299,6 @@ def test_PVSystem_pvwatts_ac_kwargs(mocker): assert out < pdc -@fail_on_pvlib_version('0.8') -def test_deprecated_08(): - # deprecated function pvsystem.sapm_celltemp - with pytest.warns(pvlibDeprecationWarning): - pvsystem.sapm_celltemp(1000, 25, 1) - # deprecated function pvsystem.pvsyst_celltemp - with pytest.warns(pvlibDeprecationWarning): - pvsystem.pvsyst_celltemp(1000, 25) - module_parameters = {'R_sh_ref': 1, 'a_ref': 1, 'I_o_ref': 1, - 'alpha_sc': 1, 'I_L_ref': 1, 'R_s': 1, - 'B5': 0.0, 'B4': 0.0, 'B3': 0.0, 'B2': 0.0, - 'B1': 0.0, 'B0': 1.0, - 'b': 0.05, 'K': 4, 'L': 0.002, 'n': 1.526, - 'a_r': 0.16} - temp_model_params = temperature.TEMPERATURE_MODEL_PARAMETERS['sapm'][ - 'open_rack_glass_glass'] - # for missing temperature_model_parameters - with pytest.warns(pvlibDeprecationWarning): - pvsystem.PVSystem(module_parameters=module_parameters, - racking_model='open', module_type='glass_glass') - pv = pvsystem.PVSystem(module_parameters=module_parameters, - temperature_model_parameters=temp_model_params, - racking_model='open', module_type='glass_glass') - # deprecated method PVSystem.ashraeiam - with pytest.warns(pvlibDeprecationWarning): - pv.ashraeiam(45) - # deprecated function ashraeiam - with pytest.warns(pvlibDeprecationWarning): - pvsystem.ashraeiam(45) - # deprecated method PVSystem.physicaliam - with pytest.warns(pvlibDeprecationWarning): - pv.physicaliam(45) - # deprecated function physicaliam - with pytest.warns(pvlibDeprecationWarning): - pvsystem.physicaliam(45) - # deprecated method PVSystem.sapm_aoi_loss - with pytest.warns(pvlibDeprecationWarning): - pv.sapm_aoi_loss(45) - # deprecated function sapm_aoi_loss - with pytest.warns(pvlibDeprecationWarning): - pvsystem.sapm_aoi_loss(45, {'B5': 0.0, 'B4': 0.0, 'B3': 0.0, 'B2': 0.0, - 'B1': 0.0, 'B0': 1.0}) - - -@fail_on_pvlib_version('0.8') -def test__pvsyst_celltemp_translator(): - result = pvsystem._pvsyst_celltemp_translator(900, 20, 5) - assert_allclose(result, 45.137, 0.001) - result = pvsystem._pvsyst_celltemp_translator(900, 20, 5, 0.1, 0.9, - [29.0, 0.0]) - assert_allclose(result, 45.137, 0.001) - result = pvsystem._pvsyst_celltemp_translator(poa_global=900, temp_air=20, - wind_speed=5) - assert_allclose(result, 45.137, 0.001) - result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5) - assert_allclose(result, 45.137, 0.001) - result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5.0, - u_c=23.5, u_v=6.25, - eta_m=0.1) - assert_allclose(result, 33.315, 0.001) - result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5.0, - eta_m=0.1, - model_params=[23.5, 6.25]) - assert_allclose(result, 33.315, 0.001) - result = pvsystem._pvsyst_celltemp_translator(900, 20, wind_speed=5.0, - eta_m=0.1, - model_params=(23.5, 6.25)) - assert_allclose(result, 33.315, 0.001) - - -@fail_on_pvlib_version('0.8') -def test__sapm_celltemp_translator(): - result = pvsystem._sapm_celltemp_translator(900, 5, 20, - 'open_rack_glass_glass') - assert_allclose(result, 43.509, 3) - result = pvsystem._sapm_celltemp_translator(900, 5, temp_air=20, - model='open_rack_glass_glass') - assert_allclose(result, 43.509, 3) - params = temperature.TEMPERATURE_MODEL_PARAMETERS['sapm'][ - 'open_rack_glass_glass'] - result = pvsystem._sapm_celltemp_translator(900, 5, 20, params) - assert_allclose(result, 43.509, 3) - result = pvsystem._sapm_celltemp_translator(900, 5, 20, - [params['a'], params['b'], - params['deltaT']]) - assert_allclose(result, 43.509, 3) - - @fail_on_pvlib_version('0.9') def test_deprecated_09(cec_inverter_parameters, adr_inverter_parameters): # deprecated function pvsystem.snlinverter @@ -1417,3 +1310,8 @@ def test_deprecated_09(cec_inverter_parameters, adr_inverter_parameters): # deprecated function pvsystem.spvwatts_ac with pytest.warns(pvlibDeprecationWarning): pvsystem.pvwatts_ac(90, 100, 0.95) + # for missing temperature_model_parameters + match = "Reverting to deprecated default: SAPM cell temperature" + system = pvsystem.PVSystem() + with pytest.warns(pvlibDeprecationWarning, match=match): + system.sapm_celltemp(1, 2, 3) diff --git a/pvlib/tests/test_tracking.py b/pvlib/tests/test_tracking.py index a2dbb6e732..350a108f81 100644 --- a/pvlib/tests/test_tracking.py +++ b/pvlib/tests/test_tracking.py @@ -453,8 +453,8 @@ def test_SingleAxisTracker___repr__(): module: blah inverter: blarg albedo: 0.25 - racking_model: open_rack - module_type: glass_polymer + racking_model: None + module_type: None temperature_model_parameters: {'a': -3.56}""" assert system.__repr__() == expected @@ -477,8 +477,8 @@ def test_LocalizedSingleAxisTracker___repr__(): module: blah inverter: blarg albedo: 0.25 - racking_model: open_rack - module_type: glass_polymer + racking_model: None + module_type: None temperature_model_parameters: {'a': -3.56} latitude: 32 longitude: -111 diff --git a/setup.cfg b/setup.cfg index 631934553f..bc56ff3090 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,3 +13,8 @@ parentdir_prefix = pvlib-python- [aliases] test=pytest + +[flake8] +max-line-length = 79 +ignore = E201, E241, E226, W503, W504 +exclude = pvlib/_version.py docs dist \ No newline at end of file