Smoke document
The smoke document is the contract’s wildfire-smoke document family. It is a time series of wildfire smoke for one site and one run of an air-quality model, which today is ECCC’s RAQDPS (GEM-MACH).
It is a separate document because the wind-profile models published for
Canada carry no smoke, and putting another model’s smoke into their profiles
would break the rule of one model per document. Consumers join a smoke
document to a profile by site and validAt, and label the result with both
models’ runs.
The live sample dataset has no smoke documents. The datasets this document kind was built against stayed with their operator when the engine went public, and they are private. Nothing on this page can be fetched from the sample. The JSON below is still real: it is quoted from a committed history-archive fixture.
On the wire
| Fact | Value |
|---|---|
| Published at | raqdps/sites/<site-slug>.json |
| Parse | parseSmokeDocument(Json) from @azohra/meteo.briefing/contract |
| Zod authority | smokeDocumentSchema |
| JSON Schema | smoke.schema.json |
| Discovery | the catalogue’s smokeModels array, kept separate from models so consumers written before smoke existed still parse the catalogue unchanged |
Shape and units
{ "schemaVersion": 1, "model": "raqdps", "run": { "referenceTime": "2026-08-10T00:00:00Z", "generatedAt": "2026-08-10T09:57:54Z" }, "site": { "id": "erie", "name": "Erie", "latitude": 49.204789, "longitude": -117.406951, "timeZone": "America/Vancouver" }, "hours": [ { "validAt": "2026-08-10T01:00:00Z", "pm25Ugm3": 46.1, "smokePlumeSurfaceUgm3": 46.1, "smokePlumeColumnMgm2": 5.9 }, … ]}Quoted from the committed fixture
briefing/test/fixtures/raqdps-erie-2026-08.jsonl.gz. It is the first
archived run of a real, smoky August 2026, with its 72 hours cut to one.
| Field | Unit | Meaning |
|---|---|---|
pm25Ugm3 | µg/m³ | Total near-surface PM2.5 from all sources. This is the air-quality number. |
smokePlumeSurfaceUgm3 | µg/m³ | The part of that surface PM2.5 that comes from wildfire smoke. |
smokePlumeColumnMgm2 | mg/m² | Vertically integrated wildfire-smoke PM2.5, as published. It is currently kept out of derived optics. |
The site block carries only the site’s identity and its timezone. It has no elevations, because terrain matters to a profile and not to air quality. The hours are all forecast hours, in time order, as in a profile.
RAQDPS publishes no optical-depth field. On 2026-08-09 the live Datamart
tree held only concentration and column-mass files. Optical thickness would
therefore be derived downstream from the column, using a cited
mass-extinction efficiency; see
smokeAotFromColumn in @azohra/meteo.briefing/derive
and the account in Smoke and thermals.
Read the next section before applying that derivation to this document’s
column.
The column field carries a provider defect
This was checked on 2026-08-10 against the raw provider GRIBs, HRRR, and GOES-18. The provider declares a column integrated over the entire atmosphere. The values behave instead like the surface concentration multiplied by a near-surface layer about 50–250 m deep. They track RAQDPS’s own surface field rather than a real column, and in heavy smoke they run about 15–26× below columns consistent with the satellite. The builder reads and converts the published GRIB faithfully, so the defect is upstream. It was reported to ECCC on 2026-08-10.
The field is therefore kept out of all derived optics. The analyze
smokeImpact kind republishes it raw as a fact of
the document and gives no AOT for joined days. The decision will be
revisited when a named trigger arrives: GOES AOD once ECCC responds, or
around September. The contract’s
smokePlumeColumnMgm2 JSDoc
carries the same warning next to the type, so the warning travels with the
code. The surface field does not have this problem.
Provider facts, verified 2026-08-09
- The Datamart keeps the wildfire products in the plain
model_raqdpstree. There is nomodel_raqdps-fw/directory, whatever older MSC documentation suggests. Files live underhttps://dd.weather.gc.ca/YYYYMMDD/WXO-DD/model_raqdps/10km/grib2/HH/hhh/with the usual MSC one-message-per-file naming (…_MSC_RAQDPS_PM2.5-WildfireSmokePlume_Sfc_RLatLon0.09_PThhhH.grib2). - Grid
RLatLon0.09(~10 km), runs 00Z and 12Z, hourly steps to 72 h; thehpfx.collab.science.gc.camirror serves identical paths. A PM10 wildfire-plume pair exists alongside the PM2.5 one (not currently published here), plus NO2, NO, O3, SO2, and plain PM10/PM2.5. - The GRIB messages carry no units metadata. The SI base units were worked out from live field statistics: surface concentrations arrive in kg/m³ and the column in kg/m². That day’s national maxima, 1.4×10⁻⁶ and 1.2×10⁻⁴, are physically plausible only in kg-based units. The builder converts to µg/m³ and mg/m² when it fetches.
- Fetch cost: three whole-domain files per forecast hour, about 0.6 MB together, or roughly 43 MB per run and 86 MB per day.
Joining a smoke document to a profile
The two models run on different schedules: RAQDPS twice a day and HRDPS
four times. A joined pair therefore usually mixes runs. RAQDPS’s 72 h horizon
covers HRDPS’s 48 h even at the worst offset (12 + 48 = 60 < 72), so the join
never runs out of smoke hours. Any view built on it must still show the smoke
run’s referenceTime next to the profile’s, so it does not imply both came
from the same run. smokeHoursByValidAt in
@azohra/meteo.briefing/derive aligns the hours, and
the scene graph’s smokeSource carries the label. Models that publish their
own smoke, such as HRRR, never need the join. Their profiles carry a
same-run smoke block, and when both
exist, the profile’s own block is used.