Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/maxiricalde/ProfeLedesma/llms.txt

Use this file to discover all available pages before exploring further.

The QC class (in helpers/QualityControl.py) modifies a GHI DataFrame in place, appending flag columns and a final Acepted boolean column. Three physical plausibility filters are applied sequentially — one upper-bound check during daytime, one nighttime polynomial check, and one clearness-index range check. Only rows passing all three are marked as accepted.

Constructor

QC(df)

Parameters

df
pd.DataFrame
required
A pandas DataFrame that must already contain the following columns:
ColumnSourceDescription
ghiraw dataMeasured global horizontal irradiance (W/m²)
SZAGeo.dfSolar zenith angle in degrees
CTZGeo.dfCosine of the solar zenith angle
TZGeo.dfSolar zenith angle in radians
TOAGeo.dfTop-of-atmosphere irradiance (W/m²)
Typically built by merging raw GHI measurements with the output of Geo(...).df on the date column.

Side effects — columns added to df

The constructor returns no value; it modifies df in place by appending the columns below.
Column addedTypeDescription
filtro1boolUpper bound (daytime): when SZA < 90°, True if ghi < 1.5 × 1361.7 × CTZ^1.2 + 100; always True when SZA ≥ 90°.
filtro2boolNighttime polynomial check: when SZA > 90°, True if ghi > (6.5331 − 0.065502×TZ + 1.8312×10⁻⁴×TZ²) / (1 + 0.01113×TZ); always True when SZA ≤ 90°.
ktfloatClearness index: ghi / TOA when TOA > 0; 0 otherwise.
filtro3boolClearness index bound: True when 0 < kt < 1.4.
AceptedboolTrue when filtro1 AND filtro2 AND filtro3 all hold simultaneously.

Filter Logic Detail

Filter 1 — Physically Possible Upper Limit (BSRN)

When SZA < 90°:  True if  ghi < 1.5 × 1361.7 × CTZ^1.2 + 100
When SZA ≥ 90°:  always True
Rejects daytime readings that exceed the theoretical upper bound for GHI at a given solar angle, following the BSRN (Baseline Surface Radiation Network) quality-control convention.

Filter 2 — Nighttime Polynomial Check

When SZA > 90°:  True if  ghi > f(TZ)
  where f(TZ) = (6.5331 − 0.065502×TZ + 1.8312×10⁻⁴×TZ²) / (1 + 0.01113×TZ)
When SZA ≤ 90°:  always True
At nighttime (SZA > 90°), a row passes (filtro2 = True) only when the measured GHI exceeds the polynomial threshold in TZ (radians). Rows that fall below this threshold at night are flagged False and will be excluded by Acepted.

Filter 3 — Clearness Index Range

kt = ghi / TOA    (0 when TOA = 0)
True when 0 < kt < 1.4
A clearness index outside the physically meaningful range (0, 1.4) indicates either a negative reading, a zero reading during daytime, or an unrealistically high value.

Usage Example

import numpy as np
import pandas as pd
from helpers.Geo import Geo
from helpers.QualityControl import QC

# --- Build solar geometry ---
ranges = pd.date_range(
    start='2022/01/01 00:00',
    end='2022/12/31 23:59',
    freq='1min'
)

dfGeo = Geo(
    range_dates=ranges,
    lat=-24.7288,
    long=-65.4095,
    gmt=0,
    alt=1233,
    beta=0
).df

# --- Merge with your measured GHI ---
# df_raw must have 'date' and 'ghi' columns
df = df_raw.merge(dfGeo[['date', 'SZA', 'CTZ', 'TZ', 'TOA']], on='date')

# --- Apply quality control ---
QC(df)

# --- Replace rejected readings with NaN ---
df['ghi'] = np.where(df.Acepted, df.ghi, np.nan)

print(f"Accepted: {df.Acepted.sum()} / {len(df)}")
print(df[['date', 'ghi', 'kt', 'filtro1', 'filtro2', 'filtro3', 'Acepted']].head(10))

The QC class uses the TZ column from Geo.df, which contains the solar zenith angle in radians. Do not pass the SZA column (degrees) in place of TZ — the nighttime filter formula (filtro2) will produce incorrect thresholds.
The column name Acepted uses the single-c spelling as defined in the source code. Use df['Acepted'] — not df['Accepted'] — when accessing the column programmatically.

Build docs developers (and LLMs) love