UNPKG

air-monitor

Version:

Utilities for working with air quality monitoring data.

112 lines (75 loc) 3.58 kB
# air-monitor 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. ## Overview 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. ## Data Model The compact data model for a _monitor_ object consists of two aligned **Arquero** tables: - `meta`: A metadata table describing each monitoring device deployment - `data`: A time-series table with hourly observations and a `datetime` column (UTC) Both tables are linked by a shared identifier: meta.deviceDeploymentID <---> data columns (besides datetime) ## Install npm install air-monitor ## Example Usage 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)); ## Key Features - ✅ 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 ## API Highlights ### `new Monitor(metaTable, dataTable)` Creates a new monitor instance from parsed tables. ### `loadCustom(baseName, baseUrl)` Loads `{baseName}.meta.csv` and `{baseName}.data.csv` from a file URL. ### `filterByValue(column, value)` Returns a new `Monitor` filtered by a metadata column. ### `collapse(granularity, method)` Aggregates time series by day or hour using `mean`, `max`, etc. ### `combine(otherMonitor)` Merges another monitor instance into the current one. ### `dropEmpty()` Removes device series that contain no valid observations. ### `trimDate(timezone, trimEmptyDays = true)` Trims incomplete or fully missing days from the edges of the time range. ### `getCurrentStatus()` Appends most recent valid timestamp and value to each metadata row. ### `createGeoJSON()` Converts metadata + status into a valid GeoJSON `FeatureCollection`. ## Assumptions - `data.datetime` is 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` - `datetime` values are stored in UTC (not local time) ## Related Packages - [air-monitor-algorithms](https://www.npmjs.com/package/air-monitor-algorithms) - [air-monitor-plots](https://www.npmjs.com/package/air-monitor-plots) ## License GPL-3.0-or-later © 2024–2025 Jonathan Callahan / USFS AirFire