Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimum GHI limit check from Nollas et al. (2023) #174

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ Irradiance measurements can also be checked for consistency.

quality.irradiance.check_irradiance_consistency_qcrad

The validity of daytime GHI and DHI measurements can also be checked using
a more restrictive lower limit provided in [2]_.

.. autosummary::
:toctree: generated/

quality.irradiance.check_ghi_lower_limit_nollas

GHI and POA irradiance can be validated against clearsky values to
eliminate data that is unrealistically high.

Expand Down Expand Up @@ -196,6 +204,12 @@ the quality check.
.. [1] C. N. Long and Y. Shi, An Automated Quality Assessment and Control
Algorithm for Surface Radiation Measurements, The Open Atmospheric
Science Journal 2, pp. 23-37, 2008.
:doi:`10.2174/1874282300802010023`
.. [2] F. M. Nollas, G. A. Salazar, and C. A. Gueymard, Quality control
procedure for 1-minute pyranometric measurements of global and
shadowband-based diffuse solar irradiance, Renewable Energy, 202,
pp. 40-55, 2023.
:doi:`10.1016/j.renene.2022.11.056`

Features
========
Expand Down
4 changes: 3 additions & 1 deletion docs/whatsnew/0.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Breaking Changes

Enhancements
~~~~~~~~~~~~

* Add QC function for checking GHI lower limit according to Nollas et al. (2023).
:py:func:`~pvanalytics.quality.irradiance.check_ghi_lower_limit_nollas` (:pull:`174`)

Bug Fixes
~~~~~~~~~
Expand Down Expand Up @@ -44,3 +45,4 @@ Contributors
* Kevin Anderson (:ghuser:`kanderso-nrel`)
* Cliff Hansen (:ghuser:`cwhanse`)
* Abhishek Parikh (:ghuser:`abhisheksparikh`)
* Adam R. Jensen (:ghuser:`AdamRJensen`)
77 changes: 77 additions & 0 deletions pvanalytics/quality/irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,83 @@ def check_irradiance_consistency_qcrad(solar_zenith, ghi, dhi, dni,
return consistent_components, diffuse_ratio_limit


def _ghi_lower_limit_nollas(solar_zenith):
r"""Calculate lower limit for GHI according to Nollas et al.

See [1]_ for further information.

.. math::
ghi_min = (6.5331 - 0.065502 * solar\_zenith + 0.00018312 * solar\_zenith^{2}) /
(1 + 0.01113*solar\_zenith)

Parameters
----------
solar_zenith : Series
Solar zenith angle in degrees

Returns
-------
Series
Minimum possible GHI in :math:`W/m^2`

References
----------
.. [1] F. M. Nollas, G. A. Salazar, and C. A. Gueymard, Quality control
procedure for 1-minute pyranometric measurements of global and
shadowband-based diffuse solar irradiance, Renewable Energy, 202,
pp. 40-55, 2023.
:doi:`10.1016/j.renene.2022.11.056`
""" # noqa: E501
ghi_min = ((6.5331-0.065502*solar_zenith + 0.00018312*solar_zenith**2) /
(1 + 0.01113*solar_zenith))

# Set limit to nan when the sun is below the horizon
ghi_min[solar_zenith >= 90] = np.nan

return ghi_min


def check_ghi_lower_limit_nollas(ghi, solar_zenith):
r"""Test for lower limit on GHI using empirical limit from Nollas (2023).

Test is applied to each GHI value. A GHI value passes if value >
lower bound. The lower bound is from [1]_ and calculated as:

.. math::
lb = (6.5331 - 0.065502 * solar\_zenith + 0.00018312 * solar\_zenith^{2}) /
(1 + 0.01113*solar\_zenith)

Parameters
----------
ghi : Series
Global horizontal irradiance in :math:`W/m^2`
solar_zenith : Series
Solar zenith angle in degrees

Returns
-------
Series
False where valuez are below the minimum limit.

References
----------
.. [1] F. M. Nollas, G. A. Salazar, and C. A. Gueymard, Quality control
procedure for 1-minute pyranometric measurements of global and
shadowband-based diffuse solar irradiance, Renewable Energy, 202,
pp. 40-55, 2023.
:doi:`10.1016/j.renene.2022.11.056`
""" # noqa: E501
ghi_lb = _ghi_lower_limit_nollas(solar_zenith)

ghi_lower_limit_flag = quality.util.check_limits(
ghi, lower_bound=ghi_lb, inclusive_lower=False)

# Set flags to True when ghi_lb is nan (e.g., when solar_zenith>=90)
ghi_lower_limit_flag[np.isnan(ghi_lb)] = True

return ghi_lower_limit_flag


def clearsky_limits(measured, clearsky, csi_max=1.1):
"""Identify irradiance values which do not exceed clearsky values.

Expand Down
20 changes: 20 additions & 0 deletions pvanalytics/tests/quality/test_irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,26 @@ def test_check_irradiance_consistency_qcrad(irradiance_qcrad):
check_names=False)


def test_ghi_lower_limit_nollas(irradiance_qcrad):
"""Test thet minimum GHI is correctly calculated using Nollas equation."""
data = irradiance_qcrad
actual_ghi = irradiance._ghi_lower_limit_nollas(data['solar_zenith'])
expected_ghi = pd.Series([3.548128, 3.548128, 3.548128, 6.5331, 4.7917837,
1.9559971, 1.3039082, np.nan, 6.5331, 6.5331,
1.9559971, 1.3039082, 1.3039082, np.nan])
assert_series_equal(actual_ghi, expected_ghi, check_names=False)


def test_check_ghi_lower_limit_nollas(irradiance_qcrad):
"""Test that min GHI is checked correctly."""
data = irradiance_qcrad
actual_flags = irradiance.check_ghi_lower_limit_nollas(
data['ghi'], data['solar_zenith'])
expected_flags = pd.Series([0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
dtype=bool)
assert_series_equal(actual_flags, expected_flags, check_names=False)


@pytest.fixture
def times():
"""One hour of times at 10 minute frequency.
Expand Down