Smoke and thermals
Wildfire smoke is the biggest unmodelled factor in a British Columbia summer forecast: from July to September it routinely caps thermal strength and visibility while the wind-profile models carry on as if the sun were clean. meteo treats smoke the way it treats everything else — published raw with its provenance, derived openly, and never silently blended into another model’s numbers.
Where smoke comes from
Two independent models supply it, and they disagree in useful ways:
- HRRR carries its own smoke. The operational HRRRv4 runs a
prognostic smoke tracer, and its profiles publish a per-hour
smokeblock — near-surface concentration, column mass, and optical thickness — from the same run as every other value. - The ECCC models are smoke-blind. HRDPS, RDPS, and GDPS see no smoke at all. For their sites, smoke arrives as a separate smoke document from ECCC’s RAQDPS air-quality model, joined to a profile hour by hour at read time — never folded into the profile itself, because one document carries one model’s values.
On a rendered Meteogram, smoke is a strip: the line is near-surface concentration (the breathe-it number), and the haze tint behind it deepens with optical depth (the sun-dimming number). The tint appears only when the model publishes its own optical depth (HRRR); a joined smoke document draws the line without a tint, because the only optical depth it could offer would derive from the quarantined RAQDPS column — a too-faint haze under heavy smoke is the worst direction to be wrong in. A joined strip is labelled with the smoke model and run it came from, so borrowed smoke never passes as the profile’s own.
The physics of the correction, in one chain
Thermals run on surface heating. Smoke of optical depth τ cuts the irradiance reaching the ground by a factor f, the heat fluxes scale with the irradiance, and Deardorff’s w* — the thermal-strength scale the Meteogram draws — is the cube root of the heat flux. So the whole correction collapses to one line:
adjusted w* = published w* × ∛f
Two facts make this correction far gentler than intuition suggests, and both are worth internalizing before a smoky-day flight decision:
Smoke dims the sun far less than intuition says — and thermals even less
Line chart of the fraction of surface irradiance and of thermal strength retained as smoke optical depth grows from 0 to 5. The measured transmittance curve exp(−0.16·τ) falls gently, the naive exp(−τ) plunges, and the w* curve — the cube root of the transmittance — stays highest: at optical depth 2, irradiance keeps 73 percent and thermal strength 90 percent.
First, smoke scatters far more than it absorbs (single-scattering albedo around 0.95), so most of the “blocked” light still arrives as diffuse sky — measured dimming follows exp(−0.16·τ), not the Beer–Lambert exp(−τ). Second, the cube root compresses whatever remains. A severe plume at τ = 2 removes about a quarter of the sun’s power but only about a tenth of w*. If a smoked-out day feels far worse than that, the missing effects are real but different: a shallower boundary layer, visibility, and air quality — which is why the correction is labelled a partial one, and why the raw smoke numbers are always published beside it.
The constants in that chain are versioned physics claims with citations,
not tuning knobs: the 4.7 m²/g mass-extinction efficiency converting a
smoke column to optical depth is Reid et al. 2005’s aged temperate/boreal
value, and the transmittance coefficient comes from three independent
datasets — California 2020 solar-generation data (Donaldson et al. 2021),
pyranometers under extreme Russian smoke (Chubarova et al. 2012), and the
July 2015 British Columbia episode itself (McKendry et al. 2019). They
live in @azohra/meteo.briefing/derive next to the
functions that use them.
One asterisk on the RAQDPS side of that chain: the column-mass field the conversion starts from currently carries a verified provider defect — it measures a thin near-surface slab rather than the whole atmosphere it declares, so RAQDPS-derived optical depth runs low in exactly the heavy-smoke situations where it matters most. Read it with that note in hand; the surface concentration does not share the problem.
The adjusted view
Because every input is published, the correction never has to happen in the forecast engine: the stored document keeps the model’s own derivation, and the smoke-adjusted view is re-derived in the renderer, hour by hour — w* derated by the slant-path transmittance for that hour’s actual sun angle, and the usable-lift envelope recomputed from the derated value.
The same afternoon, before and after the smoke correction
Smoke optical depth climbs through a convective afternoon while the smoke-blind model keeps its heat fluxes and w* strong — the gap a smoke-adjusted reading corrects.
Wildfire smoke thickens over strong thermals. This Meteogram shows one atmospheric profile in America/Vancouver. Smoke optical depth climbs through a convective afternoon while the smoke-blind model keeps its heat fluxes and w* strong — the gap a smoke-adjusted reading corrects.
Base view — the smoke-blind read: no plume drawn, full-strength thermals
Smoke-adjusted view — smoke-over-thermals 2000-08-01T12:00:00Z, w* × ∛f
The adjusted view always declares itself: the scene graph carries the smoke model and run that derated it, and the reference key renders that label. An adjusted Meteogram that looks like a base forecast is the failure mode the declaration exists to prevent.
One absence to state plainly: no catalogued pairing reaches this view on live data today. The only model that publishes its own optical depth is HRRR, which refuses the derate (next section), and a joined smoke document withholds optical depth because of the quarantined column. The figures on this page exercise the adjusted view through synthetic scenarios; the machinery waits for a smoke-carrying model whose radiation has not already felt its own plume.
Feel the relationship directly — drag a plume of any thickness over the same afternoon:
Drag a plume over the day
Change only smoke optical depth while the column, fluxes, and winds stay fixed: thermals fade far more gently than the sky darkens.
An interactive Meteogram applying the package's smoke-adjusted derivation to the smoke scenario at a uniform optical depth chosen by a slider.
Conclusion. Even at a severe τ of 2, the derived thermals keep roughly nine tenths of their strength — the cube root is doing the compressing. What the slider cannot show is what the correction deliberately leaves out: a real plume also shallows the boundary layer and cuts visibility, which is why the adjusted view is labeled a partial correction.
When the correction must NOT apply
HRRR’s smoke is radiatively coupled: its forecast smoke attenuates its
own shortwave radiation, so its published heat fluxes — and the w*
derived from them — are already smoke-aware. Derating an HRRR
Meteogram again would double-count the smoke. The catalogue declares this
per model (capabilities.smoke: "radiativelyCoupled"), every HRRR
document echoes it (semantics.smoke), and the adjusted view quietly
refuses on such profiles. The declaration cuts the other way too: on an
HRRR Meteogram, weak afternoon thermals under a thick haze strip are not
a contradiction — the model already did the arithmetic this page
describes.
One caveat rides along: evaluation of the 2023 season found HRRR underpredicts optical depth for aged, long-range smoke, so even a smoke-aware base picture can run optimistic in dense imported-smoke events.
Two models, one sky
When both sources cover a site, their disagreement is signal, not noise. On the first live day of this feature, HRRR put five times more smoke over a Fraser Valley site than RAQDPS did — two independent emission and transport models reading the same fires differently. A reader who can see both, each labelled with its model and run, knows more than a reader shown one blended number: that is the provenance thesis, applied to smoke.
Measured against the sky
The constants in the correction chain are cited claims, and cited claims
should answer to measurement: the engine’s catalogue carries
GOES-18’s satellite-measured downward shortwave as an observation model
(goes18-dsr), publishing ten-minute
observation documents for
whatever sites an operator serves. On the capability’s first live day —
the same BC smoke event — the reference deployment’s four founding sites
read 554–623 W/m², all quality-good, in one smoky late morning
[observed 2026-08-10]: consistent
with a cloudless sky delivering ~650–700 W/m² attenuated by the plume
overhead. Measured irradiance beside a smoke document’s optical depth is
exactly the comparison exp(−0.16·τ) was fitted from — a comparison any
operator publishing both datasets keeps running.
The third opinion: measured smoke
The optical depth itself is measured too: GOES-18’s aerosol optical
depth is the catalogue’s second observation model (goes18-aod), so a
Meteogram can hold three
independent statements about the same smoke side by side — RAQDPS’s
forecast AOT, HRRR’s physics-felt smoke, and GOES-18’s measured
AOT. Same quantity, same 550 nm wavelength, same field name, drawn as
neighbouring strips with one haze encoding — the measured strip’s tint
is the forecast smoke strip’s own, so one key chip explains both and the
eye compares them directly. Like every measurement, the strip renders
below the provenance divider, and its gaps carry meaning: it is a daytime
product, and an absent instant means no accepted retrieval — never
clear air.
Agreement between the forecast smoke strip and the measured strip is earned trust: the plume the smoke-adjusted view derates w* with is really overhead, at about the stated thickness. Disagreement is the more valuable signal — the forecast plume is misplaced, mistimed, or mis-sized, and the adjusted view inherits that error, so read its derated thermals with the same skepticism. The measurement wins on what the sky is doing right now; the forecast is still the only voice with anything to say about the hours ahead. On the measured strip’s first live afternoon — the same BC event — it tracked the plume over Dundee thinning from AOT 3.0 to 1.4 in under two hours [observed 2026-08-10]: the number every forecast strip beside it could finally be held to.
The stamped observations re-ran from the reference deployment’s
append-only observation history — the goes18-dsr/history/<site>/2026-08.jsonl.gz
month archive and its goes18-aod twin. That dataset went private with
the engine/instance split and can no longer be fetched; the
sample dataset
publishes the same month-archive convention, though its archives hold
forecast profiles — no observation documents ship in the sample.