From 566ed69fbb00943163cf9ce8df539f819b4676aa Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:01:45 -0400 Subject: [PATCH 1/8] remove SingleAxisTracker --- pvlib/modelchain.py | 32 +--- pvlib/tests/test_modelchain.py | 66 -------- pvlib/tests/test_tracking.py | 149 ------------------ pvlib/tracking.py | 270 +-------------------------------- 4 files changed, 7 insertions(+), 510 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index f6fad98975..c82cf2d148 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -14,8 +14,7 @@ from typing import Union, Tuple, Optional, TypeVar from pvlib import (atmosphere, clearsky, inverter, pvsystem, solarposition, - temperature, tools) -from pvlib.tracking import SingleAxisTracker + temperature) import pvlib.irradiance # avoid name conflict with full import from pvlib.pvsystem import _DC_MODEL_PARAMS from pvlib._deprecation import pvlibDeprecationWarning @@ -1535,27 +1534,11 @@ def prepare_inputs(self, weather): self._prep_inputs_solar_pos(weather) self._prep_inputs_airmass() self._prep_inputs_albedo(weather) + self._prep_inputs_fixed() - # PVSystem.get_irradiance and SingleAxisTracker.get_irradiance - # and PVSystem.get_aoi and SingleAxisTracker.get_aoi - # have different method signatures. Use partial to handle - # the differences. - if isinstance(self.system, SingleAxisTracker): - self._prep_inputs_tracking() - get_irradiance = partial( - self.system.get_irradiance, - self.results.tracking['surface_tilt'], - self.results.tracking['surface_azimuth'], - self.results.solar_position['apparent_zenith'], - self.results.solar_position['azimuth']) - else: - self._prep_inputs_fixed() - get_irradiance = partial( - self.system.get_irradiance, - self.results.solar_position['apparent_zenith'], - self.results.solar_position['azimuth']) - - self.results.total_irrad = get_irradiance( + self.results.total_irrad = self.system.get_irradiance( + self.results.solar_position['apparent_zenith'], + self.results.solar_position['azimuth'], _tuple_from_dfs(self.results.weather, 'dni'), _tuple_from_dfs(self.results.weather, 'ghi'), _tuple_from_dfs(self.results.weather, 'dhi'), @@ -1636,10 +1619,7 @@ def prepare_inputs_from_poa(self, data): self._prep_inputs_solar_pos(data) self._prep_inputs_airmass() - if isinstance(self.system, SingleAxisTracker): - self._prep_inputs_tracking() - else: - self._prep_inputs_fixed() + self._prep_inputs_fixed() return self diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index 62b71f2042..a2d295c747 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -6,7 +6,6 @@ from pvlib import iam, modelchain, pvsystem, temperature, inverter from pvlib.modelchain import ModelChain from pvlib.pvsystem import PVSystem -from pvlib.tracking import SingleAxisTracker from pvlib.location import Location from pvlib._deprecation import pvlibDeprecationWarning @@ -753,50 +752,6 @@ def test_run_model_with_weather_noct_sam_temp(sapm_dc_snl_ac_system, location, 'model': 'noct_sam'} -def test_run_model_tracker(sapm_dc_snl_ac_system, location, weather, mocker): - with pytest.warns(pvlibDeprecationWarning): - system = SingleAxisTracker( - module_parameters=sapm_dc_snl_ac_system.arrays[0].module_parameters, # noqa: E501 - temperature_model_parameters=( - sapm_dc_snl_ac_system.arrays[0].temperature_model_parameters - ), - inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters) - mocker.spy(system, 'singleaxis') - mc = ModelChain(system, location) - mc.run_model(weather) - assert system.singleaxis.call_count == 1 - assert (mc.results.tracking.columns == ['tracker_theta', - 'aoi', - 'surface_azimuth', - 'surface_tilt']).all() - assert mc.results.ac[0] > 0 - assert np.isnan(mc.results.ac[1]) - assert isinstance(mc.results.dc, pd.DataFrame) - - -def test_run_model_tracker_list( - sapm_dc_snl_ac_system, location, weather, mocker): - with pytest.warns(pvlibDeprecationWarning): - system = SingleAxisTracker( - module_parameters=sapm_dc_snl_ac_system.arrays[0].module_parameters, # noqa: E501 - temperature_model_parameters=( - sapm_dc_snl_ac_system.arrays[0].temperature_model_parameters - ), - inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters) - mocker.spy(system, 'singleaxis') - mc = ModelChain(system, location) - mc.run_model([weather]) - assert system.singleaxis.call_count == 1 - assert (mc.results.tracking.columns == ['tracker_theta', - 'aoi', - 'surface_azimuth', - 'surface_tilt']).all() - assert mc.results.ac[0] > 0 - assert np.isnan(mc.results.ac[1]) - assert isinstance(mc.results.dc, tuple) - assert len(mc.results.dc) == 1 - - def test__assign_total_irrad(sapm_dc_snl_ac_system, location, weather, total_irrad): data = pd.concat([weather, total_irrad], axis=1) @@ -1047,27 +1002,6 @@ def test_run_model_from_poa_arrays_solar_position_weather( assert_series_equal(m.call_args[1]['pressure'], data['pressure']) -def test_run_model_from_poa_tracking(sapm_dc_snl_ac_system, location, - total_irrad): - with pytest.warns(pvlibDeprecationWarning): - system = SingleAxisTracker( - module_parameters=sapm_dc_snl_ac_system.arrays[0].module_parameters, # noqa: E501 - temperature_model_parameters=( - sapm_dc_snl_ac_system.arrays[0].temperature_model_parameters - ), - inverter_parameters=sapm_dc_snl_ac_system.inverter_parameters) - mc = ModelChain(system, location, aoi_model='no_loss', - spectral_model='no_loss') - ac = mc.run_model_from_poa(total_irrad).results.ac - assert (mc.results.tracking.columns == ['tracker_theta', - 'aoi', - 'surface_azimuth', - 'surface_tilt']).all() - expected = pd.Series(np.array([149.280238, 96.678385]), - index=total_irrad.index) - assert_series_equal(ac, expected) - - @pytest.mark.parametrize("input_type", [lambda x: x[0], tuple, list]) def test_run_model_from_effective_irradiance(sapm_dc_snl_ac_system, location, weather, total_irrad, input_type): diff --git a/pvlib/tests/test_tracking.py b/pvlib/tests/test_tracking.py index 87452939f5..95c05c8df7 100644 --- a/pvlib/tests/test_tracking.py +++ b/pvlib/tests/test_tracking.py @@ -290,155 +290,6 @@ def test_low_sun_angles(): assert_allclose(expected[k], v) -def test_SingleAxisTracker_tracking(): - with pytest.warns(pvlibDeprecationWarning): - system = tracking.SingleAxisTracker(max_angle=90, axis_tilt=30, - axis_azimuth=180, gcr=2.0/7.0, - backtrack=True) - - apparent_zenith = pd.Series([30]) - apparent_azimuth = pd.Series([135]) - - tracker_data = system.singleaxis(apparent_zenith, apparent_azimuth) - - expect = pd.DataFrame({'aoi': 7.286245, 'surface_azimuth': 142.65730, - 'surface_tilt': 35.98741, - 'tracker_theta': -20.88121}, - index=[0], dtype=np.float64) - expect = expect[SINGLEAXIS_COL_ORDER] - - assert_frame_equal(expect, tracker_data) - - # results calculated using PVsyst - pvsyst_solar_azimuth = 7.1609 - pvsyst_solar_height = 27.315 - pvsyst_axis_tilt = 20. - pvsyst_axis_azimuth = 20. - with pytest.warns(pvlibDeprecationWarning): - pvsyst_system = tracking.SingleAxisTracker( - max_angle=60., axis_tilt=pvsyst_axis_tilt, - axis_azimuth=180+pvsyst_axis_azimuth, backtrack=False) - # the definition of azimuth is different from PYsyst - apparent_azimuth = pd.Series([180+pvsyst_solar_azimuth]) - apparent_zenith = pd.Series([90-pvsyst_solar_height]) - tracker_data = pvsyst_system.singleaxis(apparent_zenith, apparent_azimuth) - expect = pd.DataFrame({'aoi': 41.07852, 'surface_azimuth': 180-18.432, - 'surface_tilt': 24.92122, - 'tracker_theta': -15.18391}, - index=[0], dtype=np.float64) - expect = expect[SINGLEAXIS_COL_ORDER] - - assert_frame_equal(expect, tracker_data) - - -# see test_irradiance for more thorough testing -def test_get_aoi(): - with pytest.warns(pvlibDeprecationWarning): - system = tracking.SingleAxisTracker(max_angle=90, axis_tilt=30, - axis_azimuth=180, gcr=2.0/7.0, - backtrack=True) - surface_tilt = np.array([30, 0]) - surface_azimuth = np.array([90, 270]) - solar_zenith = np.array([70, 10]) - solar_azimuth = np.array([100, 180]) - out = system.get_aoi(surface_tilt, surface_azimuth, - solar_zenith, solar_azimuth) - expected = np.array([40.632115, 10.]) - assert_allclose(out, expected, atol=0.000001) - - -def test_get_irradiance(): - with pytest.warns(pvlibDeprecationWarning): - system = tracking.SingleAxisTracker(max_angle=90, axis_tilt=30, - axis_azimuth=180, gcr=2.0/7.0, - backtrack=True) - times = pd.date_range(start='20160101 1200-0700', - end='20160101 1800-0700', freq='6H') - # latitude=32, longitude=-111 - solar_position = pd.DataFrame(np.array( - [[55.36421554, 55.38851771, 34.63578446, 34.61148229, - 172.32003763, -3.44516534], - [96.50000401, 96.50000401, -6.50000401, -6.50000401, - 246.91581654, -3.56292888]]), - columns=['apparent_zenith', 'zenith', 'apparent_elevation', - 'elevation', 'azimuth', 'equation_of_time'], - index=times) - irrads = pd.DataFrame({'dni': [900, 0], 'ghi': [600, 0], 'dhi': [100, 0]}, - index=times) - solar_zenith = solar_position['apparent_zenith'] - solar_azimuth = solar_position['azimuth'] - - # invalid warnings already generated in horizon test above, - # no need to clutter test output here - with np.errstate(invalid='ignore'): - tracker_data = system.singleaxis(solar_zenith, solar_azimuth) - - # some invalid values in irradiance.py. not our problem here - with np.errstate(invalid='ignore'): - irradiance = system.get_irradiance(tracker_data['surface_tilt'], - tracker_data['surface_azimuth'], - solar_zenith, - solar_azimuth, - irrads['dni'], - irrads['ghi'], - irrads['dhi']) - - expected = pd.DataFrame(data=np.array( - [[961.80070, 815.94490, 145.85580, 135.32820, 10.52757492], - [nan, nan, nan, nan, nan]]), - columns=['poa_global', 'poa_direct', - 'poa_diffuse', 'poa_sky_diffuse', - 'poa_ground_diffuse'], - index=times) - - assert_frame_equal(irradiance, expected, check_less_precise=2) - - # test with albedo as a Series - irrads['albedo'] = [0.5, 0.5] - with np.errstate(invalid='ignore'): - irradiance = system.get_irradiance(tracker_data['surface_tilt'], - tracker_data['surface_azimuth'], - solar_zenith, - solar_azimuth, - irrads['dni'], - irrads['ghi'], - irrads['dhi'], - albedo=irrads['albedo']) - - expected = pd.Series(data=[21.05514984, nan], index=times, - name='poa_ground_diffuse') - - assert_series_equal(irradiance['poa_ground_diffuse'], expected, - check_less_precise=2) - - - -def test_SingleAxisTracker___repr__(): - with pytest.warns(pvlibDeprecationWarning): - system = tracking.SingleAxisTracker( - max_angle=45, gcr=.25, module='blah', inverter='blarg', - temperature_model_parameters={'a': -3.56}) - expected = """SingleAxisTracker: - axis_tilt: 0 - axis_azimuth: 0 - max_angle: 45 - backtrack: True - gcr: 0.25 - cross_axis_tilt: 0.0 - name: None - Array: - name: None - mount: SingleAxisTrackerMount(axis_tilt=0, axis_azimuth=0, max_angle=45, backtrack=True, gcr=0.25, cross_axis_tilt=0.0, racking_model=None, module_height=None) - module: blah - albedo: 0.25 - module_type: None - temperature_model_parameters: {'a': -3.56} - strings: 1 - modules_per_string: 1 - inverter: blarg""" # noqa: E501 - assert system.__repr__() == expected - - def test_calc_axis_tilt(): # expected values expected_axis_tilt = 2.239 # [degrees] diff --git a/pvlib/tracking.py b/pvlib/tracking.py index 9ae148447f..4e027665ed 100644 --- a/pvlib/tracking.py +++ b/pvlib/tracking.py @@ -2,275 +2,7 @@ import pandas as pd from pvlib.tools import cosd, sind, tand, acosd, asind -from pvlib.pvsystem import ( - PVSystem, Array, SingleAxisTrackerMount, _unwrap_single_value -) -from pvlib import irradiance, atmosphere -from pvlib._deprecation import deprecated - - -@deprecated('0.9.0', alternative='PVSystem with SingleAxisTrackerMount') -class SingleAxisTracker(PVSystem): - """ - A class for single-axis trackers that inherits the PV modeling methods from - :py:class:`~pvlib.pvsystem.PVSystem`. For details on calculating tracker - rotation see :py:func:`pvlib.tracking.singleaxis`. - - Parameters - ---------- - axis_tilt : float, default 0 - The tilt of the axis of rotation (i.e, the y-axis defined by - ``axis_azimuth``) with respect to horizontal. - ``axis_tilt`` must be >= 0 and <= 90. [degree] - - axis_azimuth : float, default 0 - A value denoting the compass direction along which the axis of - rotation lies. Measured in decimal degrees east of north. - - max_angle : float, default 90 - A value denoting the maximum rotation angle, in decimal degrees, - of the one-axis tracker from its horizontal position (horizontal - if axis_tilt = 0). A max_angle of 90 degrees allows the tracker - to rotate to a vertical position to point the panel towards a - horizon. max_angle of 180 degrees allows for full rotation. - - backtrack : bool, default True - Controls whether the tracker has the capability to "backtrack" - to avoid row-to-row shading. False denotes no backtrack - capability. True denotes backtrack capability. - - gcr : float, default 2.0/7.0 - A value denoting the ground coverage ratio of a tracker system - which utilizes backtracking; i.e. the ratio between the PV array - surface area to total ground area. A tracker system with modules - 2 meters wide, centered on the tracking axis, with 6 meters - between the tracking axes has a gcr of 2/6=0.333. If gcr is not - provided, a gcr of 2/7 is default. gcr must be <=1. - - cross_axis_tilt : float, default 0.0 - The angle, relative to horizontal, of the line formed by the - intersection between the slope containing the tracker axes and a plane - perpendicular to the tracker axes. Cross-axis tilt should be specified - using a right-handed convention. For example, trackers with axis - azimuth of 180 degrees (heading south) will have a negative cross-axis - tilt if the tracker axes plane slopes down to the east and positive - cross-axis tilt if the tracker axes plane slopes down to the west. Use - :func:`~pvlib.tracking.calc_cross_axis_tilt` to calculate - `cross_axis_tilt`. [degrees] - - **kwargs - Passed to :py:class:`~pvlib.pvsystem.PVSystem`. If the `arrays` - parameter is specified it must have only a single Array. Furthermore - if a :py:class:`~pvlib.pvsystem.Array` is provided it must have - ``surface_tilt`` and ``surface_azimuth`` equal to None. - - Raises - ------ - ValueError - If more than one Array is specified. - ValueError - If an Array is provided with a surface tilt or azimuth not None. - - See also - -------- - pvlib.tracking.singleaxis - pvlib.tracking.calc_axis_tilt - pvlib.tracking.calc_cross_axis_tilt - """ - - def __init__(self, axis_tilt=0, axis_azimuth=0, max_angle=90, - backtrack=True, gcr=2.0/7.0, cross_axis_tilt=0.0, **kwargs): - - mount_kwargs = { - k: kwargs.pop(k) for k in ['racking_model', 'module_height'] - if k in kwargs - } - mount = SingleAxisTrackerMount(axis_tilt, axis_azimuth, max_angle, - backtrack, gcr, cross_axis_tilt, - **mount_kwargs) - - array_defaults = { - 'albedo': None, 'surface_type': None, 'module': None, - 'module_type': None, 'module_parameters': None, - 'temperature_model_parameters': None, - 'modules_per_string': 1, - } - array_kwargs = { - key: kwargs.get(key, array_defaults[key]) for key in array_defaults - } - # strings/strings_per_inverter is a special case - array_kwargs['strings'] = kwargs.get('strings_per_inverter', 1) - - array = Array(mount=mount, **array_kwargs) - pass_through_kwargs = { # other args to pass to PVSystem() - k: v for k, v in kwargs.items() if k not in array_defaults - } - # leave these in case someone is using them - self.axis_tilt = axis_tilt - self.axis_azimuth = axis_azimuth - self.max_angle = max_angle - self.backtrack = backtrack - self.gcr = gcr - self.cross_axis_tilt = cross_axis_tilt - - pass_through_kwargs['surface_tilt'] = None - pass_through_kwargs['surface_azimuth'] = None - - super().__init__(arrays=[array], **pass_through_kwargs) - - def __repr__(self): - attrs = ['axis_tilt', 'axis_azimuth', 'max_angle', 'backtrack', 'gcr', - 'cross_axis_tilt'] - sat_repr = ('SingleAxisTracker:\n ' + '\n '.join( - f'{attr}: {getattr(self, attr)}' for attr in attrs)) - # get the parent PVSystem info - pvsystem_repr = super().__repr__() - # remove the first line (contains 'PVSystem: \n') - pvsystem_repr = '\n'.join(pvsystem_repr.split('\n')[1:]) - return sat_repr + '\n' + pvsystem_repr - - def singleaxis(self, apparent_zenith, apparent_azimuth): - """ - Get tracking data. See :py:func:`pvlib.tracking.singleaxis` more - detail. - - Parameters - ---------- - apparent_zenith : float, 1d array, or Series - Solar apparent zenith angles in decimal degrees. - - apparent_azimuth : float, 1d array, or Series - Solar apparent azimuth angles in decimal degrees. - - Returns - ------- - tracking data - """ - tracking_data = singleaxis(apparent_zenith, apparent_azimuth, - self.axis_tilt, self.axis_azimuth, - self.max_angle, self.backtrack, - self.gcr, self.cross_axis_tilt) - - return tracking_data - - def get_aoi(self, surface_tilt, surface_azimuth, solar_zenith, - solar_azimuth): - """Get the angle of incidence on the system. - - For a given set of solar zenith and azimuth angles, the - surface tilt and azimuth parameters are typically determined - by :py:meth:`~SingleAxisTracker.singleaxis`. The - :py:meth:`~SingleAxisTracker.singleaxis` method also returns - the angle of incidence, so this method is only needed - if using a different tracking algorithm. - - Parameters - ---------- - surface_tilt : numeric - Panel tilt from horizontal. - surface_azimuth : numeric - Panel azimuth from north - solar_zenith : float or Series. - Solar zenith angle. - solar_azimuth : float or Series. - Solar azimuth angle. - - Returns - ------- - aoi : Series - The angle of incidence in degrees from normal. - """ - - aoi = irradiance.aoi(surface_tilt, surface_azimuth, - solar_zenith, solar_azimuth) - return aoi - - @_unwrap_single_value - def get_irradiance(self, surface_tilt, surface_azimuth, - solar_zenith, solar_azimuth, dni, ghi, dhi, - albedo=None, dni_extra=None, airmass=None, - model='haydavies', - **kwargs): - """ - Uses the :func:`irradiance.get_total_irradiance` function to - calculate the plane of array irradiance components on a tilted - surface defined by the input data and ``self.albedo``. - - For a given set of solar zenith and azimuth angles, the - surface tilt and azimuth parameters are typically determined - by :py:meth:`~SingleAxisTracker.singleaxis`. - - Parameters - ---------- - surface_tilt : numeric - Panel tilt from horizontal. - surface_azimuth : numeric - Panel azimuth from north - solar_zenith : numeric - Solar zenith angle. - solar_azimuth : numeric - Solar azimuth angle. - dni : float or Series - Direct Normal Irradiance - ghi : float or Series - Global horizontal irradiance - dhi : float or Series - Diffuse horizontal irradiance - albedo : None, float or Series, default None - Ground surface albedo. [unitless] - dni_extra : float or Series, default None - Extraterrestrial direct normal irradiance - airmass : float or Series, default None - Airmass - model : String, default 'haydavies' - Irradiance model. - - **kwargs - Passed to :func:`irradiance.get_total_irradiance`. - - Returns - ------- - poa_irradiance : DataFrame - Column names are: ``total, beam, sky, ground``. - """ - - # not needed for all models, but this is easier - if dni_extra is None: - dni_extra = irradiance.get_extra_radiation(solar_zenith.index) - - if airmass is None: - airmass = atmosphere.get_relative_airmass(solar_zenith) - - # SingleAxisTracker only supports a single Array, but we need the - # validate/iterate machinery so that single length tuple input/output - # is handled the same as PVSystem.get_irradiance. GH 1159 - dni = self._validate_per_array(dni, system_wide=True) - ghi = self._validate_per_array(ghi, system_wide=True) - dhi = self._validate_per_array(dhi, system_wide=True) - - if albedo is None: - # assign default albedo here because SingleAxisTracker - # initializes albedo to None - albedo = 0.25 - - albedo = self._validate_per_array(albedo, system_wide=True) - - return tuple( - irradiance.get_total_irradiance( - surface_tilt, - surface_azimuth, - solar_zenith, - solar_azimuth, - dni, ghi, dhi, - dni_extra=dni_extra, - airmass=airmass, - model=model, - albedo=albedo, - **kwargs) - for array, dni, ghi, dhi, albedo in zip( - self.arrays, dni, ghi, dhi, albedo - ) - ) +from pvlib import irradiance def singleaxis(apparent_zenith, apparent_azimuth, From 762e900fd852888823648b5a6cfe041d6e3da52f Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:04:13 -0400 Subject: [PATCH 2/8] remove pvsyst_cell's `eta_m` --- pvlib/pvsystem.py | 4 +--- pvlib/temperature.py | 9 +-------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index bdab5d604d..b335361683 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -1601,9 +1601,7 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model, func = temperature.pvsyst_cell required = tuple() optional = { - # TODO remove 'eta_m' after deprecation of this parameter - **_build_kwargs(['eta_m', 'module_efficiency', - 'alpha_absorption'], + **_build_kwargs(['module_efficiency', 'alpha_absorption'], self.module_parameters), **_build_kwargs(['u_c', 'u_v'], self.temperature_model_parameters) diff --git a/pvlib/temperature.py b/pvlib/temperature.py index 9748965ccd..70692d2cd2 100644 --- a/pvlib/temperature.py +++ b/pvlib/temperature.py @@ -291,7 +291,7 @@ def sapm_cell_from_module(module_temperature, poa_global, deltaT, def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0, - eta_m=None, module_efficiency=0.1, alpha_absorption=0.9): + module_efficiency=0.1, alpha_absorption=0.9): r""" Calculate cell temperature using an empirical heat loss factor model as implemented in PVsyst. @@ -321,8 +321,6 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0, in :eq:`pvsyst`. :math:`\left[ \frac{\text{W}/\text{m}^2}{\text{C}\ \left( \text{m/s} \right)} \right]` - eta_m : numeric, default None (deprecated, use module_efficiency instead) - module_efficiency : numeric, default 0.1 Module external efficiency as a fraction. Parameter :math:`\eta_{m}` in :eq:`pvsyst`. Calculate as @@ -378,11 +376,6 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0, 37.93103448275862 """ # noQA: E501 - if eta_m: - warn_deprecated( - since='v0.9', message='eta_m overwriting module_efficiency', - name='eta_m', alternative='module_efficiency', removal='v0.10') - module_efficiency = eta_m total_loss_factor = u_c + u_v * wind_speed heat_input = poa_global * alpha_absorption * (1 - module_efficiency) temp_difference = heat_input / total_loss_factor From 04f1983798eb4a7792169d38ace8c186a6ce4226 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:05:25 -0400 Subject: [PATCH 3/8] Remove deprecated PVSystem inverter and temperature methods --- pvlib/pvsystem.py | 218 ----------------------------------- pvlib/tests/test_pvsystem.py | 56 --------- 2 files changed, 274 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index b335361683..8a7c4f69c9 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -636,39 +636,6 @@ def sapm(self, effective_irradiance, temp_cell): in zip(self.arrays, effective_irradiance, temp_cell) ) - @deprecated('0.9', alternative='PVSystem.get_cell_temperature', - removal='0.10.0') - def sapm_celltemp(self, poa_global, temp_air, wind_speed): - """Uses :py:func:`pvlib.temperature.sapm_cell` to calculate cell - temperatures. - - Parameters - ---------- - poa_global : numeric or tuple of numeric - Total incident irradiance in W/m^2. - - temp_air : numeric or tuple of numeric - Ambient dry bulb temperature in degrees C. - - wind_speed : numeric or tuple of numeric - Wind speed in m/s at a height of 10 meters. - - Returns - ------- - numeric or tuple of numeric - values in degrees C. - - Notes - ----- - The `temp_air` and `wind_speed` parameters may be passed as tuples - to provide different values for each Array in the system. If not - passed as a tuple then the same value is used for input to each Array. - If passed as a tuple the length must be the same as the number of - Arrays. - """ - return self.get_cell_temperature(poa_global, temp_air, wind_speed, - model='sapm') - @_unwrap_single_value def sapm_spectral_loss(self, airmass_absolute): """ @@ -730,158 +697,6 @@ def sapm_effective_irradiance(self, poa_direct, poa_diffuse, in zip(self.arrays, poa_direct, poa_diffuse, aoi) ) - @deprecated('0.9', alternative='PVSystem.get_cell_temperature', - removal='0.10.0') - def pvsyst_celltemp(self, poa_global, temp_air, wind_speed=1.0): - """Uses :py:func:`pvlib.temperature.pvsyst_cell` to calculate cell - temperature. - - Parameters - ---------- - poa_global : numeric or tuple of numeric - Total incident irradiance in W/m^2. - - temp_air : numeric or tuple of numeric - Ambient dry bulb temperature in degrees C. - - wind_speed : numeric or tuple of numeric, default 1.0 - Wind speed in m/s measured at the same height for which the wind - loss factor was determined. The default value is 1.0, which is - the wind speed at module height used to determine NOCT. - - Returns - ------- - numeric or tuple of numeric - values in degrees C. - - Notes - ----- - The `temp_air` and `wind_speed` parameters may be passed as tuples - to provide different values for each Array in the system. If not - passed as a tuple then the same value is used for input to each Array. - If passed as a tuple the length must be the same as the number of - Arrays. - """ - return self.get_cell_temperature(poa_global, temp_air, wind_speed, - model='pvsyst') - - @deprecated('0.9', alternative='PVSystem.get_cell_temperature', - removal='0.10.0') - def faiman_celltemp(self, poa_global, temp_air, wind_speed=1.0): - """ - Use :py:func:`pvlib.temperature.faiman` to calculate cell temperature. - - Parameters - ---------- - poa_global : numeric or tuple of numeric - Total incident irradiance [W/m^2]. - - temp_air : numeric or tuple of numeric - Ambient dry bulb temperature [C]. - - wind_speed : numeric or tuple of numeric, default 1.0 - Wind speed in m/s measured at the same height for which the wind - loss factor was determined. The default value 1.0 m/s is the wind - speed at module height used to determine NOCT. [m/s] - - Returns - ------- - numeric or tuple of numeric - values in degrees C. - - Notes - ----- - The `temp_air` and `wind_speed` parameters may be passed as tuples - to provide different values for each Array in the system. If not - passed as a tuple then the same value is used for input to each Array. - If passed as a tuple the length must be the same as the number of - Arrays. - """ - return self.get_cell_temperature(poa_global, temp_air, wind_speed, - model='faiman') - - @deprecated('0.9', alternative='PVSystem.get_cell_temperature', - removal='0.10.0') - def fuentes_celltemp(self, poa_global, temp_air, wind_speed): - """ - Use :py:func:`pvlib.temperature.fuentes` to calculate cell temperature. - - Parameters - ---------- - poa_global : pandas Series or tuple of Series - Total incident irradiance [W/m^2] - - temp_air : pandas Series or tuple of Series - Ambient dry bulb temperature [C] - - wind_speed : pandas Series or tuple of Series - Wind speed [m/s] - - Returns - ------- - temperature_cell : Series or tuple of Series - The modeled cell temperature [C] - - Notes - ----- - The Fuentes thermal model uses the module surface tilt for convection - modeling. The SAM implementation of PVWatts hardcodes the surface tilt - value at 30 degrees, ignoring whatever value is used for irradiance - transposition. If you want to match the PVWatts behavior you can - either leave ``surface_tilt`` unspecified to use the PVWatts default - of 30, or specify a ``surface_tilt`` value in the Array's - ``temperature_model_parameters``. - - The `temp_air`, `wind_speed`, and `surface_tilt` parameters may be - passed as tuples - to provide different values for each Array in the system. If not - passed as a tuple then the same value is used for input to each Array. - If passed as a tuple the length must be the same as the number of - Arrays. - """ - return self.get_cell_temperature(poa_global, temp_air, wind_speed, - model='fuentes') - - @deprecated('0.9', alternative='PVSystem.get_cell_temperature', - removal='0.10.0') - def noct_sam_celltemp(self, poa_global, temp_air, wind_speed, - effective_irradiance=None): - """ - Use :py:func:`pvlib.temperature.noct_sam` to calculate cell - temperature. - - Parameters - ---------- - poa_global : numeric or tuple of numeric - Total incident irradiance in W/m^2. - - temp_air : numeric or tuple of numeric - Ambient dry bulb temperature in degrees C. - - wind_speed : numeric or tuple of numeric - Wind speed in m/s at a height of 10 meters. - - effective_irradiance : numeric, tuple of numeric, or None. - The irradiance that is converted to photocurrent. If None, - assumed equal to ``poa_global``. [W/m^2] - - Returns - ------- - temperature_cell : numeric or tuple of numeric - The modeled cell temperature [C] - - Notes - ----- - The `temp_air` and `wind_speed` parameters may be passed as tuples - to provide different values for each Array in the system. If not - passed as a tuple then the same value is used for input to each Array. - If passed as a tuple the length must be the same as the number of - Arrays. - """ - return self.get_cell_temperature( - poa_global, temp_air, wind_speed, model='noct_sam', - effective_irradiance=effective_irradiance) - @_unwrap_single_value def first_solar_spectral_loss(self, pw, airmass_absolute): """ @@ -1027,24 +842,6 @@ def get_ac(self, model, p_dc, v_dc=None): model + ' is not a valid AC power model.', ' model must be one of "sandia", "adr" or "pvwatts"') - @deprecated('0.9', alternative='PVSystem.get_ac', removal='0.10') - def snlinverter(self, v_dc, p_dc): - """Uses :py:func:`pvlib.inverter.sandia` to calculate AC power based on - ``self.inverter_parameters`` and the input voltage and power. - - See :py:func:`pvlib.inverter.sandia` for details - """ - return inverter.sandia(v_dc, p_dc, self.inverter_parameters) - - @deprecated('0.9', alternative='PVSystem.get_ac', removal='0.10') - def adrinverter(self, v_dc, p_dc): - """Uses :py:func:`pvlib.inverter.adr` to calculate AC power based on - ``self.inverter_parameters`` and the input voltage and power. - - See :py:func:`pvlib.inverter.adr` for details - """ - return inverter.adr(v_dc, p_dc, self.inverter_parameters) - @_unwrap_single_value def scale_voltage_current_power(self, data): """ @@ -1104,21 +901,6 @@ def pvwatts_losses(self): self.losses_parameters) return pvwatts_losses(**kwargs) - @deprecated('0.9', alternative='PVSystem.get_ac', removal='0.10') - def pvwatts_ac(self, pdc): - """ - Calculates AC power according to the PVWatts model using - :py:func:`pvlib.inverter.pvwatts`, `self.module_parameters["pdc0"]`, - and `eta_inv_nom=self.inverter_parameters["eta_inv_nom"]`. - - See :py:func:`pvlib.inverter.pvwatts` for details. - """ - kwargs = _build_kwargs(['eta_inv_nom', 'eta_inv_ref'], - self.inverter_parameters) - - return inverter.pvwatts(pdc, self.inverter_parameters['pdc0'], - **kwargs) - @_unwrap_single_value def dc_ohms_from_percent(self): """ diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index d5dcfc1420..2a0dd14f43 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -1515,20 +1515,6 @@ def test_PVSystem_get_ac_sandia(cec_inverter_parameters, mocker): assert_series_equal(pacs, pd.Series([-0.020000, 132.004308, 250.000000])) -@fail_on_pvlib_version('0.10') -def test_PVSystem_snlinverter(cec_inverter_parameters): - system = pvsystem.PVSystem( - inverter=cec_inverter_parameters['Name'], - inverter_parameters=cec_inverter_parameters, - ) - vdcs = pd.Series(np.linspace(0,50,3)) - idcs = pd.Series(np.linspace(0,11,3)) - pdcs = idcs * vdcs - with pytest.warns(pvlibDeprecationWarning): - pacs = system.snlinverter(vdcs, pdcs) - assert_series_equal(pacs, pd.Series([-0.020000, 132.004308, 250.000000])) - - def test_PVSystem_get_ac_sandia_multi(cec_inverter_parameters, mocker): inv_fun = mocker.spy(inverter, 'sandia_multi') system = pvsystem.PVSystem( @@ -2169,28 +2155,6 @@ def test_PVSystem_pvwatts_losses(pvwatts_system_defaults, mocker): assert out < expected -@fail_on_pvlib_version('0.10') -def test_PVSystem_pvwatts_ac(pvwatts_system_defaults, mocker): - mocker.spy(inverter, 'pvwatts') - pdc = 50 - with pytest.warns(pvlibDeprecationWarning): - out = pvwatts_system_defaults.pvwatts_ac(pdc) - inverter.pvwatts.assert_called_once_with( - pdc, **pvwatts_system_defaults.inverter_parameters) - assert out < pdc - - -@fail_on_pvlib_version('0.10') -def test_PVSystem_pvwatts_ac_kwargs(pvwatts_system_kwargs, mocker): - mocker.spy(inverter, 'pvwatts') - pdc = 50 - with pytest.warns(pvlibDeprecationWarning): - out = pvwatts_system_kwargs.pvwatts_ac(pdc) - inverter.pvwatts.assert_called_once_with( - pdc, **pvwatts_system_kwargs.inverter_parameters) - assert out < pdc - - def test_PVSystem_num_arrays(): system_one = pvsystem.PVSystem() system_two = pvsystem.PVSystem(arrays=[ @@ -2358,26 +2322,6 @@ def test_Array_dc_ohms_from_percent(mocker): out = array.dc_ohms_from_percent() -@pytest.mark.parametrize('funcname', ['sapm_celltemp', 'pvsyst_celltemp', - 'faiman_celltemp', 'fuentes_celltemp', - 'noct_sam_celltemp']) -def test_PVSystem_temperature_deprecated(funcname): - temp_model_params = { - 'a': -3.47, 'b': -0.0594, 'deltaT': 3, # sapm - 'noct_installed': 45, # fuentes - 'module_efficiency': 0.2, 'noct': 45, # noct_sam - } - system = pvsystem.PVSystem(temperature_model_parameters=temp_model_params) - func = getattr(system, funcname) - index = pd.date_range('2019-01-01', freq='h', periods=5) - temps = pd.Series(25, index) - irrads = pd.Series(1000, index) - winds = pd.Series(1, index) - - with pytest.warns(pvlibDeprecationWarning): - func(irrads, temps, winds) - - @pytest.mark.parametrize('model,keys', [ ('sapm', ('a', 'b', 'deltaT')), ('fuentes', ('noct_installed',)), From 4b505924a977226fdb42a8c658cd73e66a025f87 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:13:10 -0400 Subject: [PATCH 4/8] remove deprecated PVSystem attribute passthrough --- pvlib/pvsystem.py | 152 ----------------------------------- pvlib/tests/test_pvsystem.py | 27 ------- 2 files changed, 179 deletions(-) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 8a7c4f69c9..d42f96e27f 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -68,37 +68,6 @@ def f(*args, **kwargs): return f -def _check_deprecated_passthrough(func): - """ - Decorator to warn or error when getting and setting the "pass-through" - PVSystem properties that have been moved to Array. Emits a warning for - PVSystems with only one Array and raises an error for PVSystems with - more than one Array. - """ - - @functools.wraps(func) - def wrapper(self, *args, **kwargs): - pvsystem_attr = func.__name__ - class_name = self.__class__.__name__ # PVSystem or SingleAxisTracker - overrides = { # some Array attrs aren't the same as PVSystem - 'strings_per_inverter': 'strings', - } - array_attr = overrides.get(pvsystem_attr, pvsystem_attr) - alternative = f'{class_name}.arrays[i].{array_attr}' - - if len(self.arrays) > 1: - raise AttributeError( - f'{class_name}.{pvsystem_attr} not supported for multi-array ' - f'systems. Set {array_attr} for each Array in ' - f'{class_name}.arrays instead.') - - wrapped = deprecated('0.9', alternative=alternative, removal='0.10', - name=f"{class_name}.{pvsystem_attr}")(func) - return wrapped(self, *args, **kwargs) - - return wrapper - - # not sure if this belongs in the pvsystem module. # maybe something more like core.py? It may eventually grow to # import a lot more functionality from other modules. @@ -912,127 +881,6 @@ def dc_ohms_from_percent(self): return tuple(array.dc_ohms_from_percent() for array in self.arrays) - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def module_parameters(self): - return tuple(array.module_parameters for array in self.arrays) - - @module_parameters.setter - @_check_deprecated_passthrough - def module_parameters(self, value): - for array in self.arrays: - array.module_parameters = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def module(self): - return tuple(array.module for array in self.arrays) - - @module.setter - @_check_deprecated_passthrough - def module(self, value): - for array in self.arrays: - array.module = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def module_type(self): - return tuple(array.module_type for array in self.arrays) - - @module_type.setter - @_check_deprecated_passthrough - def module_type(self, value): - for array in self.arrays: - array.module_type = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def temperature_model_parameters(self): - return tuple(array.temperature_model_parameters - for array in self.arrays) - - @temperature_model_parameters.setter - @_check_deprecated_passthrough - def temperature_model_parameters(self, value): - for array in self.arrays: - array.temperature_model_parameters = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def surface_tilt(self): - return tuple(array.mount.surface_tilt for array in self.arrays) - - @surface_tilt.setter - @_check_deprecated_passthrough - def surface_tilt(self, value): - for array in self.arrays: - array.mount.surface_tilt = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def surface_azimuth(self): - return tuple(array.mount.surface_azimuth for array in self.arrays) - - @surface_azimuth.setter - @_check_deprecated_passthrough - def surface_azimuth(self, value): - for array in self.arrays: - array.mount.surface_azimuth = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def albedo(self): - return tuple(array.albedo for array in self.arrays) - - @albedo.setter - @_check_deprecated_passthrough - def albedo(self, value): - for array in self.arrays: - array.albedo = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def racking_model(self): - return tuple(array.mount.racking_model for array in self.arrays) - - @racking_model.setter - @_check_deprecated_passthrough - def racking_model(self, value): - for array in self.arrays: - array.mount.racking_model = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def modules_per_string(self): - return tuple(array.modules_per_string for array in self.arrays) - - @modules_per_string.setter - @_check_deprecated_passthrough - def modules_per_string(self, value): - for array in self.arrays: - array.modules_per_string = value - - @property - @_unwrap_single_value - @_check_deprecated_passthrough - def strings_per_inverter(self): - return tuple(array.strings for array in self.arrays) - - @strings_per_inverter.setter - @_check_deprecated_passthrough - def strings_per_inverter(self, value): - for array in self.arrays: - array.strings = value - @property def num_arrays(self): """The number of Arrays in the system.""" diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 2a0dd14f43..552142bfe8 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -1657,9 +1657,6 @@ def test_PVSystem_get_ac_invalid(cec_inverter_parameters): def test_PVSystem_creation(): pv_system = pvsystem.PVSystem(module='blah', inverter='blarg') # ensure that parameter attributes are dict-like. GH 294 - with pytest.warns(pvlibDeprecationWarning): - pv_system.module_parameters['pdc0'] = 1 - pv_system.inverter_parameters['Paco'] = 1 @@ -1901,30 +1898,6 @@ def test_Array_get_irradiance(solar_pos): assert_series_equal(expected, expected, check_less_precise=5) -@fail_on_pvlib_version('0.10') -@pytest.mark.parametrize('attr', ['module_parameters', 'module', 'module_type', - 'temperature_model_parameters', 'albedo', - 'surface_tilt', 'surface_azimuth', - 'racking_model', 'modules_per_string', - 'strings_per_inverter']) -def test_PVSystem_multi_array_attributes(attr): - array_one = pvsystem.Array(pvsystem.FixedMount()) - array_two = pvsystem.Array(pvsystem.FixedMount()) - system = pvsystem.PVSystem(arrays=[array_one, array_two]) - with pytest.raises(AttributeError): - getattr(system, attr) - - with pytest.raises(AttributeError): - setattr(system, attr, 'dummy') - - system = pvsystem.PVSystem() - with pytest.warns(pvlibDeprecationWarning): - getattr(system, attr) - - with pytest.warns(pvlibDeprecationWarning): - setattr(system, attr, 'dummy') - - def test_PVSystem___repr__(): system = pvsystem.PVSystem( module='blah', inverter='blarg', name='pv ftw', From 4bc02e90b268f9aa24058dee98a9e9273a1fa6b3 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:15:34 -0400 Subject: [PATCH 5/8] remove overlooked eta_m test --- pvlib/tests/test_temperature.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pvlib/tests/test_temperature.py b/pvlib/tests/test_temperature.py index bd6831fd0a..6ab4b4730b 100644 --- a/pvlib/tests/test_temperature.py +++ b/pvlib/tests/test_temperature.py @@ -99,13 +99,6 @@ def test_pvsyst_cell_series(): assert_series_equal(expected, result) -def test_pvsyst_cell_eta_m_deprecated(): - with pytest.warns(pvlibDeprecationWarning): - result = temperature.pvsyst_cell(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) - - def test_faiman_default(): result = temperature.faiman(900, 20, 5) assert_allclose(result, 35.203, atol=0.001) From 383cb77bbc6ffd201d7ea1206b05158401455a20 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:26:57 -0400 Subject: [PATCH 6/8] remove deprecated ModelChain attribute passthrough --- pvlib/modelchain.py | 27 --------------------------- pvlib/tests/test_modelchain.py | 10 ---------- 2 files changed, 37 deletions(-) diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index c82cf2d148..78cace3736 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -464,13 +464,6 @@ class ModelChain: Name of ModelChain instance. """ - # list of deprecated attributes - _deprecated_attrs = ['solar_position', 'airmass', 'total_irrad', - 'aoi', 'aoi_modifier', 'spectral_modifier', - 'cell_temperature', 'effective_irradiance', - 'dc', 'ac', 'diode_params', 'tracking', - 'weather', 'times', 'losses'] - def __init__(self, system, location, clearsky_model='ineichen', transposition_model='haydavies', @@ -502,26 +495,6 @@ def __init__(self, system, location, self.results = ModelChainResult() - def __getattr__(self, key): - if key in ModelChain._deprecated_attrs: - msg = f'ModelChain.{key} is deprecated and will' \ - f' be removed in v0.10. Use' \ - f' ModelChain.results.{key} instead' - warnings.warn(msg, pvlibDeprecationWarning) - return getattr(self.results, key) - # __getattr__ is only called if __getattribute__ fails. - # In that case we should check if key is a deprecated attribute, - # and fail with an AttributeError if it is not. - raise AttributeError - - def __setattr__(self, key, value): - if key in ModelChain._deprecated_attrs: - msg = f'ModelChain.{key} is deprecated from v0.9. Use' \ - f' ModelChain.results.{key} instead' - warnings.warn(msg, pvlibDeprecationWarning) - setattr(self.results, key, value) - else: - super().__setattr__(key, value) @classmethod def with_pvwatts(cls, system, location, diff --git a/pvlib/tests/test_modelchain.py b/pvlib/tests/test_modelchain.py index a2d295c747..9a130c9569 100644 --- a/pvlib/tests/test_modelchain.py +++ b/pvlib/tests/test_modelchain.py @@ -1732,16 +1732,6 @@ def test_ModelChain_no_extra_kwargs(sapm_dc_snl_ac_system, location): ModelChain(sapm_dc_snl_ac_system, location, arbitrary_kwarg='value') -@fail_on_pvlib_version('0.10') -def test_ModelChain_attributes_deprecated_10(sapm_dc_snl_ac_system, location): - match = 'Use ModelChain.results' - mc = ModelChain(sapm_dc_snl_ac_system, location) - with pytest.warns(pvlibDeprecationWarning, match=match): - mc.aoi - with pytest.warns(pvlibDeprecationWarning, match=match): - mc.aoi = 5 - - def test_basic_chain_alt_az(sam_data, cec_inverter_parameters, sapm_temperature_cs5p_220m): times = pd.date_range(start='20160101 1200-0700', From e125f7cb833a95f1b93987f2753bfe9f1125156e Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:37:38 -0400 Subject: [PATCH 7/8] whatsnew --- docs/sphinx/source/whatsnew/v0.9.6.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/sphinx/source/whatsnew/v0.9.6.rst b/docs/sphinx/source/whatsnew/v0.9.6.rst index 889f456e0c..4658949e54 100644 --- a/docs/sphinx/source/whatsnew/v0.9.6.rst +++ b/docs/sphinx/source/whatsnew/v0.9.6.rst @@ -12,6 +12,17 @@ Breaking Changes (:issue:`1724`, :pull:`1739`) * For consistency with the rest of pvlib, the ``tilt`` parameter is renamed to ``surface_tilt`` in :py:func:`pvlib.soiling.hsu`. (:issue:`1717`, :pull:`1738`) +* The following, originally deprecated in :ref:`whatsnew_0900`, is now removed: (:pull:`1770`) + + - The :py:class:`pvlib.tracking.SingleAxisTracker` class + - The various model-specific :py:class:`~pvlib.pvsystem.PVSystem` inverter + and cell temperature methods + - Attribute "pass-through" from :py:class:`~pvlib.modelchain.ModelChain` + to :py:class:`~pvlib.modelchain.ModelChainResult` + - Attribute "pass-through" from :py:class:`~pvlib.pvsystem.PVSystem` + to :py:class:`~pvlib.pvsystem.Array` + - The ``eta_m`` parameter in :py:func:`pvlib.temperature.pvsyst_cell` + Deprecations ~~~~~~~~~~~~ From afc407d179b83b73b57e75521c08af2c30075b1e Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 12 Jun 2023 21:50:25 -0400 Subject: [PATCH 8/8] scrub sphinx docs --- docs/sphinx/source/reference/classes.rst | 1 - .../source/reference/irradiance/class-methods.rst | 1 - docs/sphinx/source/reference/tracking.rst | 13 ------------- .../source/user_guide/comparison_pvlib_matlab.rst | 1 - docs/sphinx/source/user_guide/pvsystem.rst | 13 ------------- pvlib/pvsystem.py | 1 - 6 files changed, 30 deletions(-) diff --git a/docs/sphinx/source/reference/classes.rst b/docs/sphinx/source/reference/classes.rst index d96db6422d..213b0c6870 100644 --- a/docs/sphinx/source/reference/classes.rst +++ b/docs/sphinx/source/reference/classes.rst @@ -19,6 +19,5 @@ the :ref:`pvsystemdoc` and :ref:`modelchaindoc` pages. pvsystem.Array pvsystem.FixedMount pvsystem.SingleAxisTrackerMount - tracking.SingleAxisTracker modelchain.ModelChain modelchain.ModelChainResult diff --git a/docs/sphinx/source/reference/irradiance/class-methods.rst b/docs/sphinx/source/reference/irradiance/class-methods.rst index 67c16736dc..f7fa25663b 100644 --- a/docs/sphinx/source/reference/irradiance/class-methods.rst +++ b/docs/sphinx/source/reference/irradiance/class-methods.rst @@ -9,4 +9,3 @@ Methods for irradiance calculations pvsystem.PVSystem.get_irradiance pvsystem.PVSystem.get_aoi pvsystem.PVSystem.get_iam - tracking.SingleAxisTracker.get_irradiance diff --git a/docs/sphinx/source/reference/tracking.rst b/docs/sphinx/source/reference/tracking.rst index f4bbcc9aa9..6d3f7fc4eb 100644 --- a/docs/sphinx/source/reference/tracking.rst +++ b/docs/sphinx/source/reference/tracking.rst @@ -3,19 +3,6 @@ Tracking ======== -SingleAxisTracker ------------------ - -The :py:class:`~tracking.SingleAxisTracker` inherits from -:py:class:`~pvsystem.PVSystem`. - -.. autosummary:: - :toctree: generated/ - - tracking.SingleAxisTracker - tracking.SingleAxisTracker.singleaxis - tracking.SingleAxisTracker.get_irradiance - Functions --------- diff --git a/docs/sphinx/source/user_guide/comparison_pvlib_matlab.rst b/docs/sphinx/source/user_guide/comparison_pvlib_matlab.rst index 5822e261c2..30f7d36dca 100644 --- a/docs/sphinx/source/user_guide/comparison_pvlib_matlab.rst +++ b/docs/sphinx/source/user_guide/comparison_pvlib_matlab.rst @@ -54,7 +54,6 @@ Major differences * pvlib-python implements a handful of class designed to simplify the PV modeling process. These include :py:class:`~pvlib.location.Location`, :py:class:`~pvlib.pvsystem.PVSystem`, - :py:class:`~pvlib.tracking.SingleAxisTracker`, and :py:class:`~pvlib.modelchain.ModelChain`. diff --git a/docs/sphinx/source/user_guide/pvsystem.rst b/docs/sphinx/source/user_guide/pvsystem.rst index ae9344483c..c3d666fbfe 100644 --- a/docs/sphinx/source/user_guide/pvsystem.rst +++ b/docs/sphinx/source/user_guide/pvsystem.rst @@ -323,16 +323,3 @@ methods that calculate system losses. At present, these methods include only :py:meth:`pvlib.pvsystem.PVSystem.pvwatts_losses` and :py:func:`pvlib.pvsystem.pvwatts_losses`, but we hope to add more related functions and methods in the future. - - -.. _sat: - -SingleAxisTracker ------------------ - -The :py:class:`~pvlib.tracking.SingleAxisTracker` is a subclass of -:py:class:`~pvlib.pvsystem.PVSystem`. The SingleAxisTracker class -includes a few more keyword arguments and attributes that are specific -to trackers, plus the -:py:meth:`~pvlib.tracking.SingleAxisTracker.singleaxis` method. It also -overrides the `get_aoi` and `get_irradiance` methods. diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index d42f96e27f..c48da38ebe 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -187,7 +187,6 @@ class PVSystem: See also -------- pvlib.location.Location - pvlib.tracking.SingleAxisTracker """ def __init__(self,