Guides
Climate gaps
Identify the date ranges where GHCNh climate data is missing for a station. Useful for backtest setup — decide whether to interpolate, drop, or fail-loudly. Wired in Python; deferred in TypeScript v1.x behind a typed error.
Python (wired)
Section titled “Python (wired)”from mostlyright.discover import climate_gaps
gaps = climate_gaps("KNYC", "2020-01-01", "2025-01-01")# [{"start": "2020-03-14", "end": "2020-04-01"}, ...]Returns a sorted list of contiguous gap intervals. Empty list means full coverage in the window.
TypeScript (deferred v1.x)
Section titled “TypeScript (deferred v1.x)”import { climateGaps } from "@mostlyrightmd/core/discovery";import { DataAvailabilityError } from "@mostlyrightmd/core";
try { const gaps = await climateGaps("KNYC", "2020-01-01", "2025-01-01");} catch (e) { if (e instanceof DataAvailabilityError && e.reason === "model_unavailable") { console.warn(e.hint); // operator-actionable }}A subclass of DataAvailabilityError (ClimateGapsNotImplementedError) is raised on every call. The hint points here.
Why TypeScript v1.x defers it
Section titled “Why TypeScript v1.x defers it”Three architectural constraints make the browser/Node path impractical for v1.x — all three would need to change before a parity port becomes feasible:
-
GHCNh CSVs are 10+ MB per station-year. A 5-year backfill is 50+ MB per station; multi-station portfolio queries hit hundreds of MB. The payload is too big to ship over a bare browser fetch on every call.
-
Browser fetch doesn’t slice. GHCNh’s CSV endpoint has no HTTP
Rangesupport; the whole file pulls per call. Mobile and low-bandwidth users exit the SDK as bad-citizen behavior. Server-side ingest could pre-slice, but that means we’d be running a hosted service — explicitly out of scope for the local-first SDK in v1.x. -
Cache layer doesn’t scale. IndexedDB has per-origin storage quotas (typically ≤2 GB before browser eviction); the working set for a quant backtest commonly exceeds that. The Node FS cache works for bandwidth savings but doesn’t solve the per-call download problem the first time a station-year is touched.
One future option is a hosted climate-gap-precompute API that serves small JSON responses keyed by (station, window). This ships post-v1.x as part of the broader hosted-cache initiative. Until then, climateGaps() raises with a typed exception so consumers can branch on reason === "model_unavailable" instead of string-matching the message.
Workarounds (TypeScript v1.x)
Section titled “Workarounds (TypeScript v1.x)”For a hot backtest path: run the Python SDK ahead-of-time, serialize the gap list to JSON, and ship it alongside your TS bundle.
import jsonfrom mostlyright.discover import climate_gaps
gaps = climate_gaps("KNYC", "2020-01-01", "2025-01-01")with open("gaps-KNYC.json", "w") as f: json.dump(gaps, f)// In your TS appimport gaps from "./gaps-KNYC.json";console.log(gaps); // [{"start": "...", "end": "..."}, ...]For exploratory work: use research() directly. If you see cli_high_f === null for a date, that’s a climate gap signal — but it’s per-row, not pre-computed as a range list.
See also
Section titled “See also”- NWP forecasts in TypeScript — the parallel deferral on
forecastNwp() - Weather observations — how GHCNh fits into the dedup tiebreak
- API reference:
mostlyright.discover.climate_gaps·climateGaps(TS stub)