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
@@ -4,7 +4,7 @@ Summarize downloaded NSRDB county polygon GHI archives.
Each downloaded polygon archive contains one CSV per NSRDB site that intersects
the county polygon or tile. This script computes area-weighted county-level
average daily GHI values across those site CSVs, combining multiple tile
mean daily GHI values across those site CSVs, combining multiple tile
archives back into one county summary when present.
"""
@@ -18,7 +18,6 @@ import statistics
import zipfile
from pathlib import Path
DEFAULT_ARCHIVE_DIR = Path("data/nrel/polygon_archives")
DEFAULT_COUNTIES_GEOJSON = Path("data/geojson-counties-fips.json")
DEFAULT_REQUESTS_CSV = Path("data/nrel/county_polygon_ghi_request_manifest.csv")
@@ -37,7 +36,7 @@ SUMMARY_FIELDS = [
"request_site_count",
"ghi_rows_per_site_min",
"ghi_rows_per_site_max",
"avgSolarGhiKwhM2Day",
"meanDailyGlobalHorizontalRadiationKwhM2Day",
"areaWeightedAvgSolarGhiKwhM2Day",
"areaWeightedSites",
"weightedCellAreaKm2",
@@ -144,7 +143,10 @@ def extract_site_lon_lat(csv_text: str) -> tuple[float, float]:
if len(rows) < 2:
raise ValueError("Could not read NSRDB metadata rows.")
metadata = {key.strip().lower(): value.strip() for key, value in zip(rows[0], rows[1])}
metadata = {
key.strip().lower(): value.strip()
for key, value in zip(rows[0], rows[1], strict=True)
}
try:
lon = float(metadata["longitude"])
lat = float(metadata["latitude"])
@@ -185,7 +187,7 @@ def extract_ghi_values(csv_text: str) -> list[float]:
def site_average_daily_ghi(csv_text: str) -> tuple[float, int]:
"""Return average daily GHI in kWh/m2/day and number of GHI rows."""
"""Return mean daily GHI in kWh/m2/day and number of GHI rows."""
ghi_values = extract_ghi_values(csv_text)
return sum(ghi_values) / 1000 / 365, len(ghi_values)
@@ -353,7 +355,7 @@ def area_weighted_average(
weighted_sites = 0
county_area = sum(projected_polygon_area(polygon) for polygon in projected_county)
for site_average, (lon, lat) in zip(site_averages, site_lon_lats):
for site_average, (lon, lat) in zip(site_averages, site_lon_lats, strict=True):
x, y = project_lon_lat(lon, lat, reference_lat)
min_x = x - half_cell
min_y = y - half_cell
@@ -408,7 +410,7 @@ def summarize_archives(
"polygon_sites": len(site_averages),
"ghi_rows_per_site_min": min(row_counts),
"ghi_rows_per_site_max": max(row_counts),
"avgSolarGhiKwhM2Day": weighted["area_weighted_avg"],
"meanDailyGlobalHorizontalRadiationKwhM2Day": weighted["area_weighted_avg"],
"area_weighted_avg": weighted["area_weighted_avg"],
"area_weighted_sites": weighted["area_weighted_sites"],
"weighted_cell_area_km2": weighted["weighted_cell_area_km2"],
@@ -450,11 +452,11 @@ def build_summary_row(
if str(row.get("site_count", "")).strip().isdigit()
]
archive_zip = ";".join(str(path) for path in archive_paths)
final_avg = float(polygon_summary["avgSolarGhiKwhM2Day"])
final_avg = float(polygon_summary["meanDailyGlobalHorizontalRadiationKwhM2Day"])
area_weighted_avg = float(polygon_summary["area_weighted_avg"])
representative_point_avg = (
float(representative_point_row["avgSolarGhiKwhM2Day"])
if representative_point_row.get("avgSolarGhiKwhM2Day")
float(representative_point_row["meanDailyGlobalHorizontalRadiationKwhM2Day"])
if representative_point_row.get("meanDailyGlobalHorizontalRadiationKwhM2Day")
else None
)
weighted_minus_representative_point = (
@@ -475,7 +477,7 @@ def build_summary_row(
"request_site_count": str(sum(request_site_counts)) if request_site_counts else request_row.get("site_count", ""),
"ghi_rows_per_site_min": str(polygon_summary["ghi_rows_per_site_min"]),
"ghi_rows_per_site_max": str(polygon_summary["ghi_rows_per_site_max"]),
"avgSolarGhiKwhM2Day": format_float(final_avg),
"meanDailyGlobalHorizontalRadiationKwhM2Day": format_float(final_avg),
"areaWeightedAvgSolarGhiKwhM2Day": format_float(area_weighted_avg),
"areaWeightedSites": str(polygon_summary["area_weighted_sites"]),
"weightedCellAreaKm2": format_float(float(polygon_summary["weighted_cell_area_km2"]), 1),