Refine climate metrics and data pipeline

This commit is contained in:
2026-07-24 22:55:14 -04:00
parent 016f7386d8
commit 4e2d878e5b
32 changed files with 3557 additions and 3347 deletions
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
Fetch NSRDB representative-point inputs for a county cloud-cover metric.
Fetch NSRDB representative-point inputs for a county clear-sky GHI reduction metric.
This uses the direct single-point NSRDB CSV endpoint rather than polygon archive
requests. It is faster for first-pass cloud metrics because it downloads one CSV
@@ -12,10 +12,10 @@ ghi,clearsky_ghi,cloud_type
The summary metric is based on daylight rows with valid GHI and Clearsky GHI:
cloudinessIndexPct = 1 - mean(clamped(GHI / Clearsky GHI))
clearSkyGhiReductionIndex = 1 - mean(clamped(GHI / Clearsky GHI))
where the ratio is clamped to [0, 1] so occasional above-clear-sky modeled GHI
does not create negative cloudiness.
does not create negative reduction values.
"""
from __future__ import annotations
@@ -33,7 +33,6 @@ import urllib.parse
import urllib.request
from pathlib import Path
DEFAULT_POINTS_CSV = Path("data/nrel/county_representative_points.csv")
DEFAULT_OUTPUT_CSV = Path("data/nrel/county_representative_point_cloud_summary.csv")
DEFAULT_ERROR_CSV = Path("data/nrel/county_representative_point_cloud_error_log.csv")
@@ -73,7 +72,7 @@ CLOUD_SUMMARY_FIELDS = [
"state_abbr",
"lat",
"lon",
"cloudinessIndexPct",
"clearSkyGhiReductionIndex",
"avgObservedToClearskyRatio",
"daylightRows",
"allRows",
@@ -442,7 +441,7 @@ def summarize_cloud_metrics(
raise ValueError("No daylight rows with valid GHI and Clearsky GHI were found.")
avg_ratio = ratio_sum / daylight_rows
cloudiness_pct = 1 - avg_ratio
clear_sky_ghi_reduction = 1 - avg_ratio
clear_or_probably_clear = daylight_cloud_type_counts.get("0", 0) + daylight_cloud_type_counts.get("1", 0)
cloudy_or_obscured = sum(
daylight_cloud_type_counts.get(code, 0)
@@ -467,7 +466,7 @@ def summarize_cloud_metrics(
"state_abbr": point["state_abbr"],
"lat": point["lat"],
"lon": point["lon"],
"cloudinessIndexPct": fmt(cloudiness_pct, 4),
"clearSkyGhiReductionIndex": fmt(clear_sky_ghi_reduction, 4),
"avgObservedToClearskyRatio": fmt(avg_ratio, 4),
"daylightRows": str(daylight_rows),
"allRows": str(all_rows),
@@ -675,7 +674,7 @@ def log_county_result(
if summary is not None:
print(
" "
f"cloudiness={summary['cloudinessIndexPct']}, "
f"clear_sky_ghi_reduction={summary['clearSkyGhiReductionIndex']}, "
f"clear_ratio={summary['avgObservedToClearskyRatio']}, "
f"daylight_rows={summary['daylightRows']}"
)
@@ -783,7 +782,7 @@ def parse_args() -> argparse.Namespace:
"--min-clearsky-ghi",
type=float,
default=DEFAULT_MIN_CLEARSKY_GHI,
help="Minimum Clearsky GHI W/m2 for daylight cloudiness ratio rows.",
help="Minimum Clearsky GHI W/m2 for daylight GHI ratio rows.",
)
parser.add_argument(
"--no-polar-fallback",