CHECK_DNI_QCRAD

This function tests for lower and upper limits on Direct Normal Irradiance (DNI) using the QCRad criteria.

The test is applied to each DNI value. A reading passes if it is strictly greater than the lower bound and less than the upper bound. The bounds can be either ‘physical’ or ‘extreme’ criteria.

Excel Usage

=CHECK_DNI_QCRAD(dni, solar_zenith, dni_extra, limits)
  • dni (list[list], required): Direct normal irradiance (W/m^2).
  • solar_zenith (list[list], required): Solar zenith angle (degrees).
  • dni_extra (list[list], required): Extraterrestrial normal irradiance (W/m^2).
  • limits (str, optional, default: “physical”): QCRAD QC limits.

Returns (list[list]): 2D list of booleans (True if passed limits), or an error string.

Example 1: Check DNI physical limits pass and fail cases

Inputs:

dni solar_zenith dni_extra limits
800 30 1367 physical
-10 30 1367
1500 30 1367

Excel formula:

=CHECK_DNI_QCRAD({800;-10;1500}, {30;30;30}, {1367;1367;1367}, "physical")

Expected output:

Result
true
false
false
Example 2: Evaluate DNI values with extreme limits setting

Inputs:

dni solar_zenith dni_extra limits
500 15 1367 extreme
900 30 1367
1200 55 1367

Excel formula:

=CHECK_DNI_QCRAD({500;900;1200}, {15;30;55}, {1367;1367;1367}, "extreme")

Expected output:

Result
true
true
false
Example 3: Handle scalar DNI inputs as single observations

Inputs:

dni solar_zenith dni_extra limits
700 25 1367 physical

Excel formula:

=CHECK_DNI_QCRAD(700, 25, 1367, "physical")

Expected output:

true

Example 4: Process a row vector of DNI observations

Inputs:

dni solar_zenith dni_extra limits
300 600 900 10 20 40 1367 1367 1367 physical

Excel formula:

=CHECK_DNI_QCRAD({300,600,900}, {10,20,40}, {1367,1367,1367}, "physical")

Expected output:

Result
true
true
true

Python Code

Show Code
import pandas as pd
from pvanalytics.quality.irradiance import check_dni_limits_qcrad as result_func

def check_dni_qcrad(dni, solar_zenith, dni_extra, limits='physical'):
    """
    Return a pass/fail QC flag array for each DNI reading against QCRad physical or extreme limits.

    See: https://pvanalytics.readthedocs.io/en/stable/generated/pvanalytics.quality.irradiance.check_dni_limits_qcrad.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        dni (list[list]): Direct normal irradiance (W/m^2).
        solar_zenith (list[list]): Solar zenith angle (degrees).
        dni_extra (list[list]): Extraterrestrial normal irradiance (W/m^2).
        limits (str, optional): QCRAD QC limits. Valid options: Physical, Extreme. Default is 'physical'.

    Returns:
        list[list]: 2D list of booleans (True if passed limits), or an error string.
    """
    try:
        def flatten(data):
            if not isinstance(data, list):
                return [float(data)]
            flat = []
            for row in data:
                if isinstance(row, list):
                    for val in row:
                        if val != "":
                            flat.append(float(val))
                elif row != "":
                    flat.append(float(row))
            return flat

        dni_s = pd.Series(flatten(dni))
        zenith_s = pd.Series(flatten(solar_zenith))
        dni_extra_s = pd.Series(flatten(dni_extra))

        n = len(dni_s)
        if not (len(zenith_s) == n and len(dni_extra_s) == n):
            return "Error: All input arrays must have the same length"
        if n == 0:
            return "Error: Arrays cannot be empty"

        lim = str(limits) if limits is not None else "physical"
        if lim not in ["physical", "extreme"]:
            return "Error: limits must be either 'physical' or 'extreme'"

        res = result_func(dni_s, zenith_s, dni_extra_s, limits=lim)

        return [[bool(v)] for v in res]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Direct normal irradiance (W/m^2).
Solar zenith angle (degrees).
Extraterrestrial normal irradiance (W/m^2).
QCRAD QC limits.