Clear-day envelope model and TMY day classification tools for NSRDB, Solargis, and PVGIS Typical Meteorological Year files.
Given a supported TMY CSV, this project:
- Reads and normalizes TMY data from a provider-specific CSV format.
- Computes solar position (elevation/azimuth) using a C++ implementation wrapped with pybind11.
- Fits a clear-day DNI envelope using the ASHRAE log-linear formulation and iterative outlier rejection.
- Builds a clear-day DNI model for each timestamp.
- Computes daily ratios of measured DNI energy to clear-day DNI energy.
- Classifies each day into
extremely_clear,clear,cloudy, orextremely_cloudy. - Generates plots, daily classification CSVs, or sun-position/DNI exports.
Classification is based on fixed physical ratio thresholds, not tuned per location.
TMY ingestion is centralized in src/clear_day_analysis/tmy_reader.py.
- NSRDB TMY CSV:
read_nsrdb_tmy_csv - Solargis TMY60 P50 CSV:
read_solargis_tmy60_p50_csv - PVGIS 5.x TMY CSV:
read_pvgis_tmy_csv - Generic entry point:
read_tmy_csv(path, source=None)
Use the generic reader for new workflows:
from clear_day_analysis.tmy_reader import read_tmy_csv
df, md = read_tmy_csv("path/to/tmy.csv", source="auto")source may be "auto"/None, "nsrdb", "solargis", or "pvgis".
Readers expose two normalized TMY timestamps with different roles:
datetime: timezone-aware UTC, used for solar-position calculations, clear-day fitting, exports, and row ordering.tmy_datetime_local: timezone-naive local standard time in the fixed synthetic TMY calendar, used for daily DNI integration, day classification, and day-based plots.
TMY providers may preserve source years for selected months. For stable annual analysis, readers normalize timestamps onto a synthetic TMY calendar. Provider source timestamps are preserved where meaningful:
- NSRDB:
nsrdb_datetime_utc - Solargis:
solargis_datetime_utcwhen source-year information is available - PVGIS:
pvgis_datetime_utc
datetime is monotonic for normal non-leap 8760-row TMY files. For local-time providers, UTC timestamps can fall just outside the synthetic local year at the boundaries. tmy_datetime_local wraps those boundary rows onto the 2001 non-leap local TMY calendar so daily classification represents local-standard solar-resource days. Do not use source-specific timestamp columns for analysis unless the task is explicitly auditing source data.
- Python (see
pyproject.toml) - A C++ sun-position algorithm included as a git submodule:
external/Updated-PSA-sun-position-algorithm - Build toolchain, because the C++ extension is compiled during installation:
- Windows: Visual Studio Build Tools
- macOS: Xcode Command Line Tools
- Linux: a C++ compiler toolchain
Clone including submodules:
git clone --recurse-submodules <repo-url>
cd clear-day-analysisCreate an environment and install editable:
python -m venv .venv
# activate your venv
pip install -U pip
pip install -e .Generate the daily classification CSV plus clear-day fit and classification plots:
python make_plots.py path/to/tmy.csvOutputs are written next to the input TMY file, including <tmy_stem>_daily_classification.csv and PNG diagnostic/report plots.
Export canonical columns for normalized UTC time, normalized local TMY time, sun position, measured irradiance, and fitted clear-day DNI:
python export_tmy_sun_position_dni.py path/to/tmy.csvCreate a report-ready sun-position reference plot from that export:
python plot_sun_position_reference_days.py path/to/tmy_sun_position_dni_utc.csv --location-name "Site Name" --irradiance-col DNIThe reference plot shows daylight azimuth/elevation points for winter solstice, spring equinox, and summer solstice using local-standard TMY time. Marker shape identifies the reference day, marker color shows DNI by default, and --irradiance-col dni_clear_model can be used for the fitted clear-day reference. Add --connect-lines for faint solar-path guide lines.
Example with value labels and fixed color limits:
python plot_sun_position_reference_days.py path/to/tmy_sun_position_dni_utc.csv --irradiance-col dni_clear_model --label-values --vmin 0 --vmax 1100The analysis and export scripts use read_tmy_csv(..., source="auto").
Their shared TMY ingestion, solar-position, ASHRAE fitting, and clear-DNI model preparation path is clear_day_analysis.workflow.run_clear_day_workflow().
Install test dependencies and run:
pip install -e .[test]
pytestSee:
docs/METHOD.mdfor the clear-day envelope model, TMY ingestion convention, datetime policy, and day classification definition.docs/DEVELOPMENT.mdfor build and CI details.