PWW I/O
Read, crop, and write PowerWorld .pww weather files. See Working with PWW Files
for a walkthrough; this page is the function-level reference.
from TeamOverbyeWeather import pww_io, localcrop
Conventions
Arrays are
uint8, shaped(time, variable, latitude, longitude)Latitude ascends; longitude descends (index 0 is
lon_max)255marks missing dataBounding boxes are
(lat_max, lon_min, lat_min, lon_max)date_min/date_maxare OLE Automation days;crop_to_timerangetakes Unix epoch seconds
pww_io
PWW VERSION 1/2 binary I/O — read, bbox crop, and write.
- Ported from extract_region_pww.py. Two entry points:
read_pww(data: bytes) — in-memory (SDK / tests) read_pww_file(path: str) — mmap-backed; file never fully loaded into RAM
- TeamOverbyeWeather.pww_io.read_pww(data)[source]
Parse a PWW binary from bytes (VERSION 1 or 2).
VERSION 1 files (HRRR, NOAA) have a station block whose records are grid metadata, not real lat/lon stations. We skip that block entirely and return stations=[] to avoid corrupting outputs with garbage coordinates.
- TeamOverbyeWeather.pww_io.read_pww_file(path)[source]
Parse a PWW file using mmap — the file is never fully loaded into RAM.
VERSION 1 station block is skipped (see read_pww docstring).
- TeamOverbyeWeather.pww_io.crop_to_bbox(header, stations, arr, region)[source]
Crop a full-grid PWW array to a bounding box.
region : (lat_max, lon_min, lat_min, lon_max) tuple — CDS convention (N, W, S, E).
- TeamOverbyeWeather.pww_io.concat_time(pieces)[source]
Concatenate several (header, stations, arr) PWW pieces along the time axis.
Used to reassemble the four 6-hour quarter PWWs inside a HRRR-history daily zip into one full-day array. Pieces must share grid shape, varcount, var_codes and sample_sec, and be supplied in ascending time order. The returned header spans date_min..date_max of all pieces;
write_pwwrecomputes VERSION 2 valid-counts from the concatenated array, so no per-timestep bookkeeping is carried here.
- TeamOverbyeWeather.pww_io.write_pww(header, stations, arr)[source]
Write a PWW binary to bytes, preserving the original version and magic numbers.
- TeamOverbyeWeather.pww_io.crop_to_timerange(header, arr, t_start, t_end)[source]
Crop the time axis of a PWW array to [t_start, t_end] (Unix epoch seconds).
PWW stores date_min/date_max as OLE Automation days (days since Dec 30 1899). t_start/t_end are converted to OLE days before indexing. Either bound may be None to leave that side open — passing header[“date_min”]/[“date_max”] instead would feed OLE days into a parameter expecting epoch seconds. Returns (new_header, cropped_arr). Raises ValueError if no time steps fall within the range.
localcrop
Client-side crop for files the server refuses to crop (CONUS-scale archives).
Mirrors fetch_and_crop in backend/download.py, but reads from a file on
disk instead of Drive. Handles every on-disk shape by content, not by source
name:
bare
.pww— ERA5, NOAA, hourly HRRR historyzip with one
.pww— HRRR forecastzip with four quarter
.pww— HRRR history 15-min daily (stitched)zip of daily zips — HRRR history 15-min monthly (recursed)
Members are cropped one at a time and concatenated along the time axis, so peak memory is one cropped member rather than a whole month.
- TeamOverbyeWeather.localcrop.crop_file(src_path, dest_path, bbox=None, t_start=None, t_end=None)[source]
Crop a downloaded PWW/ZIP to bbox and/or a Unix-epoch time range.
- Parameters:
- Returns:
Path to the written
.pww.- Return type: