From 359a8dca8de88acf4d42122a5fafc97319fe6e95 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 30 May 2023 11:30:52 +0200 Subject: [PATCH 01/14] Add extreme BSRN limits --- pvanalytics/quality/irradiance.py | 89 +++++++++++++++++++------------ 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index 508ff459..d7ca8fb8 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -10,10 +10,17 @@ from pvanalytics import util -QCRAD_LIMITS = {'ghi_ub': {'mult': 1.5, 'exp': 1.2, 'min': 100}, - 'dhi_ub': {'mult': 0.95, 'exp': 1.2, 'min': 50}, - 'dni_ub': {'mult': 1.0, 'exp': 0.0, 'min': 0}, - 'ghi_lb': -4, 'dhi_lb': -4, 'dni_lb': -4} +BSRN_LIMITS_PHYSICAL = { # Physically Possible Limits (also used by QCRad) + 'ghi_ub': {'mult': 1.5, 'exp': 1.2, 'min': 100}, + 'dhi_ub': {'mult': 0.95, 'exp': 1.2, 'min': 50}, + 'dni_ub': {'mult': 1.0, 'exp': 0.0, 'min': 0}, + 'ghi_lb': -4, 'dhi_lb': -4, 'dni_lb': -4} + +BSRN_LIMITS_EXTREME = { # Extremely Rare Limis + 'ghi_ub': {'mult': 1.2, 'exp': 1.2, 'min': 50}, + 'dhi_ub': {'mult': 0.75, 'exp': 1.2, 'min': 30}, + 'dni_ub': {'mult': 0.95, 'exp': 0.2, 'min': 10}, + 'ghi_lb': -2, 'dhi_lb': -2, 'dni_lb': -2} QCRAD_CONSISTENCY = { 'ghi_ratio': { @@ -42,8 +49,8 @@ def _qcrad_ub(dni_extra, sza, lim): return lim['mult'] * dni_extra * cosd_sza**lim['exp'] + lim['min'] -def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits=None): - r"""Test for physical limits on GHI using the QCRad criteria. +def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits='physical'): + r"""Test for lower and upper limits on GHI using the QCRad criteria. Test is applied to each GHI value. A GHI value passes if value > lower bound and value < upper bound. Lower bounds are constant for @@ -60,10 +67,11 @@ def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits=None): Solar zenith angle in degrees dni_extra : Series Extraterrestrial normal irradiance in :math:`W/m^2` - limits : dict, default QCRAD_LIMITS - Must have keys 'ghi_ub' and 'ghi_lb'. For 'ghi_ub' value is a - dict with keys {'mult', 'exp', 'min'} and float values. For - 'ghi_lb' value is a float. + limits : {'physical', 'extreme'} or dict, default 'physical' + If string, must be either 'physical' or 'extreme', corresponding to the + BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float + values. For 'ghi_lb' value is a float. Returns ------- @@ -79,8 +87,10 @@ def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits=None): for more information. """ - if not limits: - limits = QCRAD_LIMITS + if limits == 'physical': + limits = BSRN_LIMITS_PHYSICAL + elif limits == 'extreme': + limits = BSRN_LIMITS_EXTREME ghi_ub = _qcrad_ub(dni_extra, solar_zenith, limits['ghi_ub']) ghi_limit_flag = quality.util.check_limits(ghi, limits['ghi_lb'], ghi_ub) @@ -88,8 +98,8 @@ def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits=None): return ghi_limit_flag -def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits=None): - r"""Test for physical limits on DHI using the QCRad criteria. +def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits='physical'): + r"""Test for lower and upper 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 @@ -106,10 +116,11 @@ def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits=None): 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. + limits : {'physical', 'extreme'} or dict, default 'physical' + If string, must be either 'physical' or 'extreme', corresponding to the + BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float + values. For 'ghi_lb' value is a float. Returns ------- @@ -125,8 +136,10 @@ def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits=None): for more information. """ - if not limits: - limits = QCRAD_LIMITS + if limits == 'physical': + limits = BSRN_LIMITS_PHYSICAL + elif limits == 'extreme': + limits = BSRN_LIMITS_EXTREME dhi_ub = _qcrad_ub(dni_extra, solar_zenith, limits['dhi_ub']) @@ -135,8 +148,8 @@ def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits=None): return dhi_limit_flag -def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits=None): - r"""Test for physical limits on DNI using the QCRad criteria. +def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits='physical'): + r"""Test for lower and upper limits on DNI using the QCRad criteria. Test is applied to each DNI value. A DNI value passes if value > lower bound and value < upper bound. Lower bounds are constant for @@ -153,10 +166,11 @@ def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits=None): Solar zenith angle in degrees dni_extra : Series Extraterrestrial normal irradiance in :math:`W/m^2` - limits : dict, default QCRAD_LIMITS - Must have keys 'dni_ub' and 'dni_lb'. For 'dni_ub' value is a - dict with keys {'mult', 'exp', 'min'} and float values. For - 'dni_lb' value is a float. + limits : {'physical', 'extreme'} or dict, default 'physical' + If string, must be either 'physical' or 'extreme', corresponding to the + BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float + values. For 'ghi_lb' value is a float. Returns ------- @@ -172,8 +186,10 @@ def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits=None): for more information. """ - if not limits: - limits = QCRAD_LIMITS + if limits == 'physical': + limits = BSRN_LIMITS_PHYSICAL + elif limits == 'extreme': + limits = BSRN_LIMITS_EXTREME dni_ub = _qcrad_ub(dni_extra, solar_zenith, limits['dni_ub']) @@ -183,7 +199,7 @@ def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits=None): def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, - dni=None, limits=None): + dni=None, limits='physical'): r"""Test for physical limits on GHI, DHI or DNI using the QCRad criteria. Criteria from [1]_ are used to determine physically plausible @@ -209,10 +225,11 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, Diffuse horizontal irradiance in :math:`W/m^2` dni : Series or None, default None Direct normal irradiance in :math:`W/m^2` - limits : dict, default QCRAD_LIMITS - for keys 'ghi_ub', 'dhi_ub', 'dni_ub', value is a dict with - keys {'mult', 'exp', 'min'} and float values. For keys - 'ghi_lb', 'dhi_lb', 'dni_lb', value is a float. + limits : {'physical', 'extreme'} or dict, default 'physical' + If string, must be either 'physical' or 'extreme', corresponding to the + BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float + values. For 'ghi_lb' value is a float. Returns ------- @@ -238,8 +255,10 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, Science Journal 2, pp. 23-37, 2008. """ - if not limits: - limits = QCRAD_LIMITS + if limits == 'physical': + limits = BSRN_LIMITS_PHYSICAL + elif limits == 'extreme': + limits = BSRN_LIMITS_EXTREME if ghi is not None: ghi_limit_flag = check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, From a290f045610ce8605884a62cd14e223fa5960340 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 30 May 2023 13:55:59 +0200 Subject: [PATCH 02/14] Add test --- pvanalytics/tests/quality/test_irradiance.py | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pvanalytics/tests/quality/test_irradiance.py b/pvanalytics/tests/quality/test_irradiance.py index d5f36295..3c1a71d7 100644 --- a/pvanalytics/tests/quality/test_irradiance.py +++ b/pvanalytics/tests/quality/test_irradiance.py @@ -157,6 +157,37 @@ def test_check_irradiance_limits_qcrad(irradiance_qcrad): assert_series_equal(dni_out, dni_out_expected, check_names=False) +def test_check_irradiance_limits_qcrad_extreme(irradiance_qcrad): + """Test different input combinations to check_irradiance_limits_qcrad. + + Notes + ----- + Copyright (c) 2019 SolarArbiter. See the file + LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory + of this distribution and at ``_ + for more information. + + """ + expected = irradiance_qcrad + + # Update flagging for extreme limits + expected['ghi_limit_flag_extreme'] = \ + pd.Series([0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1]).astype(bool) + expected['dhi_limit_flag_extreme'] = \ + pd.Series([1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1]).astype(bool) + expected['dni_limit_flag_extreme'] = \ + pd.Series([1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1]).astype(bool) + + ghi_out, dhi_out, dni_out = irradiance.check_irradiance_limits_qcrad( + expected['solar_zenith'], expected['dni_extra'], ghi=expected['ghi'], + dhi=expected['dhi'], dni=expected['dni'], limits='extreme') + + assert_series_equal(ghi_out, expected['ghi_limit_flag_extreme'], check_names=False) # noqa: E501 + assert_series_equal(dhi_out, expected['dhi_limit_flag_extreme'], check_names=False) # noqa: E501 + assert_series_equal(dni_out, expected['dni_limit_flag_extreme'], check_names=False) # noqa: E501 + + def test_check_irradiance_consistency_qcrad(irradiance_qcrad): """Test that QCRad identifies consistent irradiance measurements. From 030d132b9f3c59176ab846ea9a815aa31fb85e9a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Oct 2024 01:18:09 +0200 Subject: [PATCH 03/14] Change BSRN to QCRAD --- pvanalytics/quality/irradiance.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index d7ca8fb8..408230a4 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -10,13 +10,13 @@ from pvanalytics import util -BSRN_LIMITS_PHYSICAL = { # Physically Possible Limits (also used by QCRad) +QCRAD_LIMITS_PHYSICAL = { # Physically Possible Limits (also called BSRN) 'ghi_ub': {'mult': 1.5, 'exp': 1.2, 'min': 100}, 'dhi_ub': {'mult': 0.95, 'exp': 1.2, 'min': 50}, 'dni_ub': {'mult': 1.0, 'exp': 0.0, 'min': 0}, 'ghi_lb': -4, 'dhi_lb': -4, 'dni_lb': -4} -BSRN_LIMITS_EXTREME = { # Extremely Rare Limis +QCRAD_LIMITS_EXTREME = { # Extremely Rare Limis 'ghi_ub': {'mult': 1.2, 'exp': 1.2, 'min': 50}, 'dhi_ub': {'mult': 0.75, 'exp': 1.2, 'min': 30}, 'dni_ub': {'mult': 0.95, 'exp': 0.2, 'min': 10}, @@ -69,7 +69,7 @@ def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits='physical'): Extraterrestrial normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float values. For 'ghi_lb' value is a float. @@ -88,9 +88,9 @@ def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits='physical'): """ if limits == 'physical': - limits = BSRN_LIMITS_PHYSICAL + limits = QCRAD_LIMITS_PHYSICAL elif limits == 'extreme': - limits = BSRN_LIMITS_EXTREME + limits = QCRAD_LIMITS_EXTREME ghi_ub = _qcrad_ub(dni_extra, solar_zenith, limits['ghi_ub']) ghi_limit_flag = quality.util.check_limits(ghi, limits['ghi_lb'], ghi_ub) @@ -118,7 +118,7 @@ def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits='physical'): Extraterrestrial normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float values. For 'ghi_lb' value is a float. @@ -137,9 +137,9 @@ def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits='physical'): """ if limits == 'physical': - limits = BSRN_LIMITS_PHYSICAL + limits = QCRAD_LIMITS_PHYSICAL elif limits == 'extreme': - limits = BSRN_LIMITS_EXTREME + limits = QCRAD_LIMITS_EXTREME dhi_ub = _qcrad_ub(dni_extra, solar_zenith, limits['dhi_ub']) @@ -168,7 +168,7 @@ def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits='physical'): Extraterrestrial normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float values. For 'ghi_lb' value is a float. @@ -187,9 +187,9 @@ def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits='physical'): """ if limits == 'physical': - limits = BSRN_LIMITS_PHYSICAL + limits = QCRAD_LIMITS_PHYSICAL elif limits == 'extreme': - limits = BSRN_LIMITS_EXTREME + limits = QCRAD_LIMITS_EXTREME dni_ub = _qcrad_ub(dni_extra, solar_zenith, limits['dni_ub']) @@ -227,7 +227,7 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, Direct normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - BSRN QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For + QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float values. For 'ghi_lb' value is a float. @@ -256,9 +256,9 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, """ if limits == 'physical': - limits = BSRN_LIMITS_PHYSICAL + limits = QCRAD_LIMITS_PHYSICAL elif limits == 'extreme': - limits = BSRN_LIMITS_EXTREME + limits = QCRAD_LIMITS_EXTREME if ghi is not None: ghi_limit_flag = check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, From a72fea2eec53f469f907351b064dff629ce2dab7 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 22 Oct 2024 03:01:51 +0200 Subject: [PATCH 04/14] Update tests --- pvanalytics/quality/irradiance.py | 4 +- pvanalytics/tests/quality/test_irradiance.py | 76 +++++++++++--------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index 408230a4..f314ce98 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -10,7 +10,8 @@ from pvanalytics import util -QCRAD_LIMITS_PHYSICAL = { # Physically Possible Limits (also called BSRN) +# QCRAD limits are often also referred to as BSRN limits +QCRAD_LIMITS_PHYSICAL = { # Physically Possible Limits 'ghi_ub': {'mult': 1.5, 'exp': 1.2, 'min': 100}, 'dhi_ub': {'mult': 0.95, 'exp': 1.2, 'min': 50}, 'dni_ub': {'mult': 1.0, 'exp': 0.0, 'min': 0}, @@ -91,6 +92,7 @@ def check_ghi_limits_qcrad(ghi, solar_zenith, dni_extra, limits='physical'): limits = QCRAD_LIMITS_PHYSICAL elif limits == 'extreme': limits = QCRAD_LIMITS_EXTREME + ghi_ub = _qcrad_ub(dni_extra, solar_zenith, limits['ghi_ub']) ghi_limit_flag = quality.util.check_limits(ghi, limits['ghi_lb'], ghi_ub) diff --git a/pvanalytics/tests/quality/test_irradiance.py b/pvanalytics/tests/quality/test_irradiance.py index 3c1a71d7..8d669a0f 100644 --- a/pvanalytics/tests/quality/test_irradiance.py +++ b/pvanalytics/tests/quality/test_irradiance.py @@ -42,23 +42,25 @@ def irradiance_qcrad(): output = pd.DataFrame( columns=['ghi', 'dhi', 'dni', 'solar_zenith', 'dni_extra', 'ghi_limit_flag', 'dhi_limit_flag', 'dni_limit_flag', + 'ghi_extreme_limit_flag', 'dhi_extreme_limit_flag', + 'dni_extreme_limit_flag', 'consistent_components', 'diffuse_ratio_limit'], - data=np.array([[-100, 100, 100, 30, 1370, 0, 1, 1, 0, 0], - [100, -100, 100, 30, 1370, 1, 0, 1, 0, 0], - [100, 100, -100, 30, 1370, 1, 1, 0, 0, 1], - [1000, 100, 900, 0, 1370, 1, 1, 1, 1, 1], - [1000, 200, 800, 15, 1370, 1, 1, 1, 1, 1], - [1000, 200, 800, 60, 1370, 0, 1, 1, 0, 1], - [1000, 300, 850, 80, 1370, 0, 0, 1, 0, 1], - [1000, 500, 800, 90, 1370, 0, 0, 1, 0, 1], - [500, 100, 1100, 0, 1370, 1, 1, 1, 0, 1], - [1000, 300, 1200, 0, 1370, 1, 1, 1, 0, 1], - [500, 600, 100, 60, 1370, 1, 1, 1, 0, 0], - [500, 600, 400, 80, 1370, 0, 0, 1, 0, 0], - [500, 500, 300, 80, 1370, 0, 0, 1, 1, 1], - [0, 0, 0, 93, 1370, 1, 1, 1, 0, 0]])) + data=np.array([[-100, 100, 100, 30, 1370, 0, 1, 1, 0, 1, 1, 0, 0], + [100, -100, 100, 30, 1370, 1, 0, 1, 1, 0, 1, 0, 0], + [100, 100, -100, 30, 1370, 1, 1, 0, 1, 1, 0, 0, 1], + [1000, 100, 900, 0, 1370, 1, 1, 1, 1, 1, 1, 1, 1], + [1000, 200, 800, 15, 1370, 1, 1, 1, 1, 1, 1, 1, 1], + [1000, 200, 800, 60, 1370, 0, 1, 1, 0, 1, 1, 0, 1], + [1000, 300, 850, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 1], + [1000, 500, 800, 90, 1370, 0, 0, 1, 0, 0, 0, 0, 1], + [500, 100, 1100, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1], + [1000, 300, 1200, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1], + [500, 600, 100, 60, 1370, 1, 1, 1, 1, 0, 1, 0, 0], + [500, 600, 400, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 0], + [500, 500, 300, 80, 1370, 0, 0, 1, 0, 0, 1, 1, 1], + [0, 0, 0, 93, 1370, 1, 1, 1, 1, 1, 1, 0, 0]])) dtypes = ['float64', 'float64', 'float64', 'float64', 'float64', - 'bool', 'bool', 'bool', 'bool', 'bool'] + 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool'] for (col, typ) in zip(output.columns, dtypes): output[col] = output[col].astype(typ) return output @@ -83,6 +85,13 @@ def test_check_ghi_limits_qcrad(irradiance_qcrad): expected['dni_extra']) assert_series_equal(ghi_out, ghi_out_expected, check_names=False) + ghi_out_extreme = irradiance.check_ghi_limits_qcrad( + expected['ghi'], expected['solar_zenith'], expected['dni_extra'], + limits='extreme') + ghi_extreme_out_expected = expected['ghi_extreme_limit_flag'] + assert_series_equal( + ghi_out_extreme, ghi_extreme_out_expected, check_names=False) + def test_check_dhi_limits_qcrad(irradiance_qcrad): """Test that QCRad identifies out of bounds DHI values. @@ -103,6 +112,13 @@ def test_check_dhi_limits_qcrad(irradiance_qcrad): expected['dni_extra']) assert_series_equal(dhi_out, dhi_out_expected, check_names=False) + dhi_out_extreme = irradiance.check_dhi_limits_qcrad( + expected['dhi'], expected['solar_zenith'], expected['dni_extra'], + limits='extreme') + dhi_extreme_out_expected = expected['dhi_extreme_limit_flag'] + assert_series_equal( + dhi_out_extreme, dhi_extreme_out_expected, check_names=False) + def test_check_dni_limits_qcrad(irradiance_qcrad): """Test that QCRad identifies out of bounds DNI values. @@ -123,6 +139,13 @@ def test_check_dni_limits_qcrad(irradiance_qcrad): expected['dni_extra']) assert_series_equal(dni_out, dni_out_expected, check_names=False) + dni_out_extreme = irradiance.check_dni_limits_qcrad( + expected['dni'], expected['solar_zenith'], expected['dni_extra'], + limits='extreme') + dni_extreme_out_expected = expected['dni_extreme_limit_flag'] + assert_series_equal( + dni_out_extreme, dni_extreme_out_expected, check_names=False) + def test_check_irradiance_limits_qcrad(irradiance_qcrad): """Test different input combinations to check_irradiance_limits_qcrad. @@ -159,33 +182,16 @@ def test_check_irradiance_limits_qcrad(irradiance_qcrad): def test_check_irradiance_limits_qcrad_extreme(irradiance_qcrad): """Test different input combinations to check_irradiance_limits_qcrad. - - Notes - ----- - Copyright (c) 2019 SolarArbiter. See the file - LICENSES/SOLARFORECASTARBITER_LICENSE at the top level directory - of this distribution and at ``_ - for more information. - """ expected = irradiance_qcrad - # Update flagging for extreme limits - expected['ghi_limit_flag_extreme'] = \ - pd.Series([0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1]).astype(bool) - expected['dhi_limit_flag_extreme'] = \ - pd.Series([1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1]).astype(bool) - expected['dni_limit_flag_extreme'] = \ - pd.Series([1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1]).astype(bool) - ghi_out, dhi_out, dni_out = irradiance.check_irradiance_limits_qcrad( expected['solar_zenith'], expected['dni_extra'], ghi=expected['ghi'], dhi=expected['dhi'], dni=expected['dni'], limits='extreme') - assert_series_equal(ghi_out, expected['ghi_limit_flag_extreme'], check_names=False) # noqa: E501 - assert_series_equal(dhi_out, expected['dhi_limit_flag_extreme'], check_names=False) # noqa: E501 - assert_series_equal(dni_out, expected['dni_limit_flag_extreme'], check_names=False) # noqa: E501 + assert_series_equal(ghi_out, expected['ghi_extreme_limit_flag'], check_names=False) # noqa: E501 + assert_series_equal(dhi_out, expected['dhi_extreme_limit_flag'], check_names=False) # noqa: E501 + assert_series_equal(dni_out, expected['dni_extreme_limit_flag'], check_names=False) # noqa: E501 def test_check_irradiance_consistency_qcrad(irradiance_qcrad): From 01bf6c7984c65b76cc50d1d36631437d18f87275 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 24 Oct 2024 04:30:31 +0200 Subject: [PATCH 05/14] Update citations --- pvanalytics/quality/irradiance.py | 32 +++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index a9a96dfa..f1cb2b9b 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -204,7 +204,7 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, dni=None, limits='physical'): r"""Test for physical limits on GHI, DHI or DNI using the QCRad criteria. - Criteria from [1]_ are used to determine physically plausible + Criteria from [1]_ and [2]_ are used to determine physically plausible lower and upper bounds. Each value is tested and a value passes if value > lower bound and value < upper bound. Lower bounds are constant for all tests. Upper bounds are calculated as @@ -252,11 +252,15 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, References ---------- - .. [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. - - """ + .. [1] C. N. Long and Y. Shi, "An Automated Quality Assessment and Control + Algorithm for Surface Radiation Measurements," The Open Atmospheric + Science Journal, vol. 2, no. 1. Bentham Science Publishers Ltd., + pp. 23–37, Apr. 18, 2008. :doi:`10.2174/1874282300802010023`. + .. [2] C. N. Long and E. G. Dutton, "BSRN Global Network recommended QC + tests, V2.0," Baseline Surface Radiation Network (BSRN), + Accessed: Oct. 24, 2024. [Online.] Available: + _ + """ # noqa: E501 if limits == 'physical': limits = QCRAD_LIMITS_PHYSICAL elif limits == 'extreme': @@ -307,7 +311,7 @@ def check_irradiance_consistency_qcrad(solar_zenith, ghi, dhi, dni, param=None): """Check consistency of GHI, DHI and DNI using QCRad criteria. - Uses criteria given in [1]_ to validate the ratio of irradiance + Uses criteria given in [1]_, [2]_ to validate the ratio of irradiance components. .. warning:: Not valid for night time. While you can pass data @@ -348,11 +352,15 @@ def check_irradiance_consistency_qcrad(solar_zenith, ghi, dhi, dni, References ---------- - .. [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. - - """ + .. [1] C. N. Long and Y. Shi, "An Automated Quality Assessment and Control + Algorithm for Surface Radiation Measurements," The Open Atmospheric + Science Journal, vol. 2, no. 1. Bentham Science Publishers Ltd., + pp. 23–37, Apr. 18, 2008. :doi:`10.2174/1874282300802010023`. + .. [2] C. N. Long and E. G. Dutton, "BSRN Global Network recommended QC + tests, V2.0," Baseline Surface Radiation Network (BSRN), + Accessed: Oct. 24, 2024. [Online.] Available: + _ + """ # noqa: E501 if not param: param = QCRAD_CONSISTENCY From b7702e8f78dc55e393f29640462c4d12e0b22038 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 24 Oct 2024 04:37:17 +0200 Subject: [PATCH 06/14] Add whatsnew --- docs/whatsnew/0.2.2.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/whatsnew/0.2.2.rst b/docs/whatsnew/0.2.2.rst index 82983d6d..5aa5d3e4 100644 --- a/docs/whatsnew/0.2.2.rst +++ b/docs/whatsnew/0.2.2.rst @@ -6,7 +6,12 @@ Enhancements ~~~~~~~~~~~~ - +* Added extreme limits option to + :py:func:`~pvanalytics.quality.irradiance.check_ghi_limits_qcrad`, + :py:func:`~pvanalytics.quality.irradiance.check_dhi_limits_qcrad`, + :py:func:`~pvanalytics.quality.irradiance.check_dni_limits_qcrad`, and + :py:func:`~pvanalytics.quality.irradiance.check_irradiance_limits_qcrad`. + (:pull:`190`) Bug Fixes ~~~~~~~~~ From 26e4312357ec5627ab6d46b7b1cbcc4a453841c1 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Oct 2024 19:31:35 +0100 Subject: [PATCH 07/14] Fix linter --- pvanalytics/tests/quality/test_irradiance.py | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pvanalytics/tests/quality/test_irradiance.py b/pvanalytics/tests/quality/test_irradiance.py index 59af7fee..7a03fa61 100644 --- a/pvanalytics/tests/quality/test_irradiance.py +++ b/pvanalytics/tests/quality/test_irradiance.py @@ -48,20 +48,20 @@ def irradiance_qcrad(): 'consistent_components_outside_domain', 'diffuse_ratio_limit_outside_domain', ], - data=np.array([[-100, 100, 100, 30, 1370, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], - [100, -100, 100, 30, 1370, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0], - [100, 100, -100, 30, 1370, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1], - [1000, 100, 900, 0, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [1000, 200, 800, 15, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [1000, 200, 800, 60, 1370, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1], - [1000, 300, 850, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1], - [1000, 500, 800, 90, 1370, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1], - [500, 100, 1100, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], - [1000, 300, 1200, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], - [500, 600, 100, 60, 1370, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0], - [500, 600, 400, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], - [500, 500, 300, 80, 1370, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], - [0, 0, 0, 93, 1370, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1]])) + data=np.array([[-100, 100, 100, 30, 1370, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], # noqa: E501 + [100, -100, 100, 30, 1370, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0], # noqa: E501 + [100, 100, -100, 30, 1370, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1], # noqa: E501 + [1000, 100, 900, 0, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], # noqa: E501 + [1000, 200, 800, 15, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], # noqa: E501 + [1000, 200, 800, 60, 1370, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1], # noqa: E501 + [1000, 300, 850, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1], # noqa: E501 + [1000, 500, 800, 90, 1370, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1], # noqa: E501 + [500, 100, 1100, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], # noqa: E501 + [1000, 300, 1200, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], # noqa: E501 + [500, 600, 100, 60, 1370, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0], # noqa: E501 + [500, 600, 400, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], # noqa: E501 + [500, 500, 300, 80, 1370, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], # noqa: E501 + [0, 0, 0, 93, 1370, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1]])) # noqa: E501 dtypes = ['float64', 'float64', 'float64', 'float64', 'float64', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'boo'] From 93cea93825e466a30ba8bc99be5322ee06624ee7 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 27 Oct 2024 19:37:53 +0100 Subject: [PATCH 08/14] Fix typo --- pvanalytics/tests/quality/test_irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvanalytics/tests/quality/test_irradiance.py b/pvanalytics/tests/quality/test_irradiance.py index 7a03fa61..e6203d98 100644 --- a/pvanalytics/tests/quality/test_irradiance.py +++ b/pvanalytics/tests/quality/test_irradiance.py @@ -64,7 +64,7 @@ def irradiance_qcrad(): [0, 0, 0, 93, 1370, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1]])) # noqa: E501 dtypes = ['float64', 'float64', 'float64', 'float64', 'float64', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', - 'bool', 'boo'] + 'bool', 'bool'] for (col, typ) in zip(output.columns, dtypes): output[col] = output[col].astype(typ) return output From 6a479392aee81f7c7f7496e499f9f18bfb7b8eeb Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:23:44 +0100 Subject: [PATCH 09/14] Update docs/whatsnew/0.2.2.rst --- docs/whatsnew/0.2.2.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/whatsnew/0.2.2.rst b/docs/whatsnew/0.2.2.rst index cfd82eb7..4097791f 100644 --- a/docs/whatsnew/0.2.2.rst +++ b/docs/whatsnew/0.2.2.rst @@ -6,6 +6,7 @@ Enhancements ~~~~~~~~~~~~ +* Added extreme limits option to :py:func:`~pvanalytics.quality.irradiance.check_ghi_limits_qcrad`, :py:func:`~pvanalytics.quality.irradiance.check_dhi_limits_qcrad`, :py:func:`~pvanalytics.quality.irradiance.check_dni_limits_qcrad`, and From 8eef26e6f2d800efb788632c759b635e03ace457 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:00:59 +0100 Subject: [PATCH 10/14] Fix typo Co-authored-by: Cliff Hansen --- pvanalytics/quality/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index f0632ac4..fee3533d 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -17,7 +17,7 @@ 'dni_ub': {'mult': 1.0, 'exp': 0.0, 'min': 0}, 'ghi_lb': -4, 'dhi_lb': -4, 'dni_lb': -4} -QCRAD_LIMITS_EXTREME = { # Extremely Rare Limis +QCRAD_LIMITS_EXTREME = { # Extremely Rare Limits 'ghi_ub': {'mult': 1.2, 'exp': 1.2, 'min': 50}, 'dhi_ub': {'mult': 0.75, 'exp': 1.2, 'min': 30}, 'dni_ub': {'mult': 0.95, 'exp': 0.2, 'min': 10}, From 5b8391bf059974215ba9579d5c2bf9198d9c0f3c Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Oct 2024 21:04:38 +0100 Subject: [PATCH 11/14] Update limits docstring from review Co-authored-by: Kevin Anderson --- pvanalytics/quality/irradiance.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index fee3533d..3d796766 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -120,9 +120,9 @@ def check_dhi_limits_qcrad(dhi, solar_zenith, dni_extra, limits='physical'): Extraterrestrial normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For - 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float - values. For 'ghi_lb' value is a float. + QCRAD QC limits. If dict, 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 ------- @@ -170,9 +170,9 @@ def check_dni_limits_qcrad(dni, solar_zenith, dni_extra, limits='physical'): Extraterrestrial normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For - 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float - values. For 'ghi_lb' value is a float. + QCRAD QC limits. If dict, must have keys 'dni_ub' and 'dni_lb'. For + 'dni_ub' value is a dict with keys {'mult', 'exp', 'min'} and float + values. For 'dni_lb' value is a float. Returns ------- @@ -229,9 +229,11 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, Direct normal irradiance in :math:`W/m^2` limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the - QCRAD QC limits. If dict, must have keys 'ghi_ub' and 'ghi_lb'. For - 'ghi_ub' value is a dict with keys {'mult', 'exp', 'min'} and float - values. For 'ghi_lb' value is a float. + QCRAD QC limits. If dict, must have keys: + + * 'ghi_ub', 'dhi_ub', 'dni_ub': dicts with keys + {'mult', 'exp', 'min'} and float values. + * 'ghi_lb', 'dhi_lb', 'dni_lb': float values. Returns ------- From 8a20782bd8d7728e7179727cd3d1da83d8d422af Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Oct 2024 21:39:16 +0100 Subject: [PATCH 12/14] Implement review feedback --- pvanalytics/quality/irradiance.py | 7 +++---- pvanalytics/tests/quality/test_irradiance.py | 14 ++++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index 3d796766..9f2a198b 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -230,7 +230,7 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, limits : {'physical', 'extreme'} or dict, default 'physical' If string, must be either 'physical' or 'extreme', corresponding to the QCRAD QC limits. If dict, must have keys: - + * 'ghi_ub', 'dhi_ub', 'dni_ub': dicts with keys {'mult', 'exp', 'min'} and float values. * 'ghi_lb', 'dhi_lb', 'dni_lb': float values. @@ -261,7 +261,7 @@ def check_irradiance_limits_qcrad(solar_zenith, dni_extra, ghi=None, dhi=None, .. [2] C. N. Long and E. G. Dutton, "BSRN Global Network recommended QC tests, V2.0," Baseline Surface Radiation Network (BSRN), Accessed: Oct. 24, 2024. [Online.] Available: - _ + ``_ """ # noqa: E501 if limits == 'physical': limits = QCRAD_LIMITS_PHYSICAL @@ -316,8 +316,7 @@ def check_irradiance_consistency_qcrad(solar_zenith, ghi, dhi, dni, param=None, outside_domain=False): r"""Check consistency of GHI, DHI and DNI using QCRad criteria. - Uses criteria given in [1]_, [2]_ to validate the ratio of irradiance - components. + Uses criteria given in [1]_ to validate the ratio of irradiance components. .. warning:: Not valid for night time or low irradiance. When the input data fall outside the test domain, the returned value is set by the diff --git a/pvanalytics/tests/quality/test_irradiance.py b/pvanalytics/tests/quality/test_irradiance.py index e6203d98..8d3ba212 100644 --- a/pvanalytics/tests/quality/test_irradiance.py +++ b/pvanalytics/tests/quality/test_irradiance.py @@ -51,17 +51,19 @@ def irradiance_qcrad(): data=np.array([[-100, 100, 100, 30, 1370, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1], # noqa: E501 [100, -100, 100, 30, 1370, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0], # noqa: E501 [100, 100, -100, 30, 1370, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1], # noqa: E501 - [1000, 100, 900, 0, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], # noqa: E501 + [1000, 100, 900, 0, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1000, 200, 800, 15, 1370, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], # noqa: E501 [1000, 200, 800, 60, 1370, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1], # noqa: E501 [1000, 300, 850, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1], # noqa: E501 [1000, 500, 800, 90, 1370, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1], # noqa: E501 - [500, 100, 1100, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], # noqa: E501 + [500, 100, 1100, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], [1000, 300, 1200, 0, 1370, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1], # noqa: E501 - [500, 600, 100, 60, 1370, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0], # noqa: E501 - [500, 600, 400, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], # noqa: E501 - [500, 500, 300, 80, 1370, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], # noqa: E501 - [0, 0, 0, 93, 1370, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1]])) # noqa: E501 + [500, 600, 100, 60, 1370, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0], + [500, 600, 400, 80, 1370, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], + [500, 500, 300, 80, 1370, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], + [0, 0, 0, 93, 1370, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1], + [100, 100, 0, 95, 1370, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1] + ])) dtypes = ['float64', 'float64', 'float64', 'float64', 'float64', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool', 'bool'] From b99582968a5bfbef135553130d5bef124ccd9bb5 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Mon, 28 Oct 2024 21:41:29 +0100 Subject: [PATCH 13/14] Remove <>_ from link --- pvanalytics/quality/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index 9f2a198b..71bc134a 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -375,7 +375,7 @@ def check_irradiance_consistency_qcrad(solar_zenith, ghi, dhi, dni, .. [2] C. N. Long and E. G. Dutton, "BSRN Global Network recommended QC tests, V2.0," Baseline Surface Radiation Network (BSRN), Accessed: Oct. 24, 2024. [Online.] Available: - _ + https://bsrn.awi.de/fileadmin/user_upload/bsrn.awi.de/Publications/BSRN_recommended_QC_tests_V2.pdf """ # noqa: E501 if not param: param = QCRAD_CONSISTENCY From 48c0e156884b025bc44ab4fce05735760de870a1 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 29 Oct 2024 21:14:08 +0100 Subject: [PATCH 14/14] Add bsrn comment to consistency tests --- pvanalytics/quality/irradiance.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pvanalytics/quality/irradiance.py b/pvanalytics/quality/irradiance.py index 71bc134a..2c70ccc8 100644 --- a/pvanalytics/quality/irradiance.py +++ b/pvanalytics/quality/irradiance.py @@ -317,6 +317,7 @@ def check_irradiance_consistency_qcrad(solar_zenith, ghi, dhi, dni, r"""Check consistency of GHI, DHI and DNI using QCRad criteria. Uses criteria given in [1]_ to validate the ratio of irradiance components. + These tests are equivalent to the BSRN comparison tests [2]_. .. warning:: Not valid for night time or low irradiance. When the input data fall outside the test domain, the returned value is set by the