Utilities for working with hourly air quality monitoring data with a focus on small particulates (PM2.5). This package is designed for scientific analysis with a focus on robust and performant algorithms.
This package provides a compact data model and transformation utilities for working with air quality monitor deployments, including:
- Spatial metadata (e.g., location, timezone, ID)
- Hourly time-series measurements (e.g., PM2.5)
- Integration with GeoJSON
- Timezone-aware trimming and aggregation
- Methods to summarize, filter, and export subsets of the data
All functionality is encapsulated in a Monitor class designed for ES module
environments and data-driven workflows. It is also useful in Svelte and Vue applications.
The compact data model for a monitor object consists of two aligned Arquero tables:
meta: A metadata table describing each monitoring device deploymentdata: A time-series table with hourly observations and adatetimecolumn (UTC)
Both tables are linked by a shared identifier:
meta.deviceDeploymentID <---> data columns (besides datetime)
npm install air-monitor
import Monitor from 'air-monitor';
// Load AirNow monitor data
const monitor = new Monitor();
await monitor.loadLatest("airnow");
console.log(`airnow has ${monitor.count()} monitors`);
// Filter to a single state
const wa = monitor.filterByValue('stateCode', 'WA');
console.log(`washington has ${wa.count()} monitors`);
// Get pm25 array and metadata for Entiat, WA
const id = wa
.filterByValue('locationName', 'Entiat')
.getIDs();
const pm25 = wa.getPM25(id);
const meta = wa.getMetaObject(id);
console.log(pm25);
console.log(JSON.stringify(meta, null, 2));
- ✅ Clean parsing of time-series CSVs (with
'NA', negative, and NaN handling) - ✅ Accurate trimming to full local-time days with DST support
- ✅ Chaining API for filtering, summarizing, and reshaping
- ✅ GeoJSON export with per-site metadata and recent status
- ✅ UVU-based test suite with 100% transformation coverage
Creates a new monitor instance from parsed tables.
Loads {baseName}.meta.csv and {baseName}.data.csv from a file URL.
Returns a new Monitor filtered by a metadata column.
Aggregates time series by day or hour using mean, max, etc.
Merges another monitor instance into the current one.
Removes device series that contain no valid observations.
Trims incomplete or fully missing days from the edges of the time range.
Appends most recent valid timestamp and value to each metadata row.
Converts metadata + status into a valid GeoJSON FeatureCollection.
data.datetimeis a regular hourly time axis with no gaps- All non-datetime values are either finite numbers or
null - Time-series columns match exactly with
meta.deviceDeploymentID datetimevalues are stored in UTC (not local time)
GPL-3.0-or-later © 2024–2025 Jonathan Callahan / USFS AirFire