def _check_irrad_ratio(ratio, ghi, sza, bounds): # unpack bounds dict ghi_lb, ghi_ub, sza_lb, sza_ub, ratio_lb, ratio_ub = _get_bounds(bounds) # for zenith set inclusive_lower to handle edge cases, e.g., zenith=0 return ( util.check_limits( sza, lower_bound=sza_lb, upper_bound=sza_ub, inclusive_lower=True) & util.check_limits(ghi, lower_bound=ghi_lb, upper_bound=ghi_ub) & util.check_limits(ratio, lower_bound=ratio_lb, upper_bound=ratio_ub))
def wind_limits(wind_speed, limits=(0.0, 50.0)): """Identify wind speed values that are within limits. Parameters ---------- wind_speed : Series Wind speed in :math:`m/s` wind_limits : tuple, default (0, 50) (lower bound, upper bound) for wind speed. Returns ------- Series True if `wind_speed` >= lower bound and `wind_speed` < upper bound. Notes ----- Copyright (c) 2019 SolarArbiter. See the file LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory of this distribution and at `<https://github.com/pvlib/ pvanalytics/blob/master/LICENSES/SOLARFORECASTARBITER_LICENSE>`_ for more information. """ return util.check_limits(wind_speed, lower_bound=limits[0], upper_bound=limits[1], inclusive_lower=True)
def temperature_limits(air_temperature, limits=(-35.0, 50.0)): """Identify temperature values that are within limits. Parameters ---------- air_temperature : Series Air temperature [C]. temp_limits : tuple, default (-35, 50) (lower bound, upper bound) for temperature. Returns ------- Series True if `air_temperature` > lower bound and `air_temperature` < upper bound. Notes ----- Copyright (c) 2019 SolarArbiter. See the file LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory of this distribution and at `<https://github.com/pvlib/ pvanalytics/blob/master/LICENSES/SOLARFORECASTARBITER_LICENSE>`_ for more information. """ return util.check_limits(air_temperature, lower_bound=limits[0], upper_bound=limits[1])
def relative_humidity_limits(relative_humidity, limits=(0, 100)): """Identify relative humidity values that are within limits. Parameters ---------- relative_humidity : Series Relative humidity in %. limits : tuple, default (0, 100) (lower bound, upper bound) for relative humidity. Returns ------- Series True if `relative_humidity` >= lower bound and `relative_humidity` <= upper_bound. Notes ----- Copyright (c) 2019 SolarArbiter. See the file LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory of this distribution and at `<https://github.com/pvlib/ pvanalytics/blob/master/LICENSES/SOLARFORECASTARBITER_LICENSE>`_ for more information. """ return util.check_limits(relative_humidity, lower_bound=limits[0], upper_bound=limits[1], inclusive_lower=True, inclusive_upper=True)
def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits=None): r"""Test for physical limits on DHI using the QCRad criteria. Test is applied to each DHI value. A DHI value passes if value > lower bound and value < upper bound. Lower bounds are constant for all tests. Upper bounds are calculated as .. math:: ub = min + mult * dni\_extra * cos( solar\_zenith)^{exp} Parameters ---------- dhi : Series Diffuse horizontal irradiance in :math:`W/m^2` solar_zenith : Series Solar zenith angle in degrees dni_extra : Series Extraterrestrial normal irradiance in :math:`W/m^2` limits : dict, default QCRAD_LIMITS Must have keys 'dhi_ub' and 'dhi_lb'. For 'dhi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float values. For 'dhi_lb' value is a float. Returns ------- Series True where value passes limit test. Notes ----- Copyright (c) 2019 SolarArbiter. See the file LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory of this distribution and at `<https://github.com/pvlib/ pvanalytics/blob/master/LICENSES/SOLARFORECASTARBITER_LICENSE>`_ for more information. """ if not limits: limits = QCRAD_LIMITS dhi_ub = _qcrad_ub(dni_extra, solar_zenith, limits['dhi_ub']) dhi_limit_flag = util.check_limits(dhi, limits['dhi_lb'], dhi_ub) return dhi_limit_flag
def daily_insolation_limits(irrad, clearsky, daily_min=0.4, daily_max=1.25): """Check that daily insolation lies between minimum and maximum values. Irradiance measurements and clear-sky irradiance on each day are integrated with the trapezoid rule to calculate daily insolation. Parameters ---------- irrad : Series Irradiance measurements (GHI or POA). clearsky : Series Clearsky irradiance. daily_min : float, default 0.4 Minimum ratio of daily insolation to daily clearsky insolation. daily_max : float, default 1.25 Maximum ratio of daily insolation to daily clearsky insolation. Returns ------- Series True for values on days where the ratio of daily insolation to daily clearsky insolation is between `daily_min` and `daily_max`. Notes ----- The default limits (`daily_max` and `daily_min`) have been set for GHI and POA irradiance for systems with *fixed* azimuth and tilt. If you pass POA irradiance for a tracking system it is recommended that you increase `daily_max` to 1.35. The default values for `daily_min` and `daily_max` were taken from the PVFleets QA Analysis project. """ daily_irradiance = _daily_total(irrad) daily_clearsky = _daily_total(clearsky) good_days = util.check_limits( daily_irradiance/daily_clearsky, upper_bound=daily_max, lower_bound=daily_min ) return good_days.reindex(irrad.index, method='pad', fill_value=False)
def test_check_limits(): """Test the private check limits function. Notes ----- Copyright (c) 2019 SolarArbiter. See the file LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory of this distribution and at `<https://github.com/pvlib/ pvanalytics/blob/master/LICENSES/SOLARFORECASTARBITER_LICENSE>`_ for more information. """ expected = pd.Series(data=[True, False]) data = pd.Series(data=[3, 2]) result = util.check_limits(val=data, lower_bound=2.5) assert_series_equal(expected, result, check_names=False) result = util.check_limits(val=data, lower_bound=3, inclusive_lower=True) assert_series_equal(expected, result, check_names=False) data = pd.Series(data=[3, 4]) result = util.check_limits(val=data, upper_bound=3.5) assert_series_equal(expected, result, check_names=False) result = util.check_limits(val=data, upper_bound=3, inclusive_upper=True) assert_series_equal(expected, result, check_names=False) result = util.check_limits(val=data, lower_bound=3, upper_bound=4, inclusive_lower=True, inclusive_upper=True) assert all(result) result = util.check_limits(val=data, lower_bound=3, upper_bound=4) assert not any(result) with pytest.raises(ValueError): util.check_limits(val=data)
def clearsky_limits(measured, clearsky, csi_max=1.1): """Identify irradiance values which do not exceed clearsky values. Uses :py:func:`pvlib.irradiance.clearsky_index` to compute the clearsky index as the ratio of `measured` to `clearsky`. Compares the clearsky index to `csi_max` to identify values in `measured` that are less than or equal to `csi_max`. Parameters ---------- measured : Series Measured irradiance in :math:`W/m^2`. clearsky : Series Expected clearsky irradiance in :math:`W/m^2`. csi_max : float, default 1.1 Maximum ratio of `measured` to `clearsky` (clearsky index). Returns ------- Series True for each value where the clearsky index is less than or equal to `csi_max`. Notes ----- Copyright (c) 2019 SolarArbiter. See the file LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory of this distribution and at `<https://github.com/pvlib/ pvanalytics/blob/master/LICENSES/SOLARFORECASTARBITER_LICENSE>`_ for more information. """ csi = pvlib.irradiance.clearsky_index( measured, clearsky, max_clearsky_index=np.Inf ) return util.check_limits(csi, upper_bound=csi_max, inclusive_upper=True)