AeroViz is a Python toolkit for reading, processing, and visualizing aerosol measurement data. It supports 18+ atmospheric instruments with built-in quality control, data processing, and publication-ready visualizations.
pip install AeroVizfrom AeroViz import RawDataReader
# Read AE33 Aethalometer data (black carbon)
df = RawDataReader(
instrument='AE33',
path='/path/to/data',
start='2024-01-01',
end='2024-12-31',
mean_freq='1h', # Hourly averages
qc=True # Apply quality control
)
# Output: DataFrame with columns like BC1-BC7, abs_370-abs_950, AAE, eBC
print(df[['eBC', 'AAE']].describe())| Instrument | Description | Output Columns |
|---|---|---|
| AE33 | Magee Aethalometer (7-wavelength) | BC1-BC7, abs_370-abs_950, AAE, eBC |
| AE43 | Magee Aethalometer (7-wavelength) | BC1-BC7, abs_370-abs_950, AAE, eBC |
| BC1054 | Met One Black Carbon Monitor | BC, abs_880 |
| MA350 | AethLabs microAeth (5-wavelength) | BC1-BC5, abs_375-abs_880 |
# Example: Read black carbon data
bc = RawDataReader('AE33', '/data/AE33', '2024-01-01', '2024-06-30')
print(f"Mean eBC: {bc['eBC'].mean():.2f} ng/m³")
print(f"Mean AAE: {-bc['AAE'].mean():.2f}") # AAE stored as negative| Instrument | Description | Size Range | Output Columns |
|---|---|---|---|
| SMPS | Scanning Mobility Particle Sizer | 10-1000 nm | Size bins, total_num, GMD_num, GSD_num |
| APS | Aerodynamic Particle Sizer | 0.5-20 μm | Size bins, total_num, GMD_num, GSD_num |
| GRIMM | Optical Particle Counter | 0.25-32 μm | Size bins, number concentrations |
# Example: Read SMPS size distribution
smps = RawDataReader(
'SMPS', '/data/SMPS', '2024-01-01', '2024-06-30',
size_range=(10, 500) # Filter to 10-500 nm
)
print(f"Total number: {smps['total_num'].mean():.0f} #/cm³")
print(f"GMD: {smps['GMD_num'].mean():.1f} nm")| Instrument | Description | Output Columns |
|---|---|---|
| TEOM | Tapered Element Oscillating Microbalance | PM_NV, PM_Total, Volatile_Fraction |
| BAM1020 | Beta Attenuation Monitor | PM2.5, PM10 |
# Example: Read TEOM PM mass data
teom = RawDataReader('TEOM', '/data/TEOM', '2024-01-01', '2024-06-30')
print(f"PM2.5 (non-volatile): {teom['PM_NV'].mean():.1f} μg/m³")
print(f"PM2.5 (total): {teom['PM_Total'].mean():.1f} μg/m³")| Instrument | Description | Output Columns |
|---|---|---|
| NEPH | TSI Nephelometer | scattering_B, scattering_G, scattering_R, SAE |
| Aurora | Ecotech Aurora 3000 | scattering_B, scattering_G, scattering_R, SAE |
# Example: Read nephelometer scattering data
neph = RawDataReader('Aurora', '/data/Aurora', '2024-01-01', '2024-06-30')
print(f"Scattering (550nm): {neph['scattering_G'].mean():.1f} Mm⁻¹")| Instrument | Description | Output Columns |
|---|---|---|
| Xact | Cooper XRF Heavy Metals | Fe, Zn, Pb, Cu, Mn, Cr, Ni, As, Cd, ... |
| OCEC | Sunset OC/EC Analyzer | OC, EC, TC, OC1-OC4, EC1-EC3 |
| IGAC | Ion Chromatograph | SO4²⁻, NO3⁻, Cl⁻, NH4⁺, Na⁺, K⁺, ... |
| Q-ACSM | Aerosol Chemical Speciation Monitor | Org, SO4, NO3, NH4, Chl |
# Example: Read XRF heavy metals data
xrf = RawDataReader('Xact', '/data/Xact', '2024-01-01', '2024-06-30')
print(f"Fe: {xrf['Fe'].mean():.1f} ng/m³")
print(f"Pb: {xrf['Pb'].mean():.2f} ng/m³")| Instrument | Description |
|---|---|
| VOC | Volatile Organic Compounds Analyzer |
| EPA | Taiwan EPA Air Quality Data |
| Minion | Low-cost Sensor Network |
| Parameter | Type | Description | Default |
|---|---|---|---|
instrument |
str | Instrument name (see tables above) | Required |
path |
str/Path | Directory containing raw data files | Required |
start |
str/datetime | Start date ('2024-01-01' or datetime) |
Required |
end |
str/datetime | End date | Required |
mean_freq |
str | Output frequency: '1h', '30min', '1D' |
'1h' |
qc |
bool/str | Quality control: True, False, or 'MS' for monthly stats |
True |
reset |
bool/str | True to reprocess, 'append' to add new data |
False |
size_range |
tuple | Size range in nm for SMPS/APS: (min, max) |
None |
AeroViz applies automatic QC based on instrument-specific rules. The QC_Flag column indicates data quality:
| Flag | Description |
|---|---|
Valid |
Data passed all QC checks |
Insufficient |
Not enough raw data points in period |
Status Error |
Instrument reported error status |
Invalid BC |
Black carbon outside valid range |
Invalid Number Conc |
Particle count outside valid range |
Spike |
Detected sudden unrealistic change |
# Check data quality
df = RawDataReader('AE33', '/data/AE33', '2024-01-01', '2024-06-30')
print(df['QC_Flag'].value_counts())
# Valid 8000
# Insufficient 300
# Status Error 60Advanced analysis with specialized modules:
from AeroViz import DataProcess
from pathlib import Path
# Optical property calculations
optical = DataProcess(method='Optical', path_out=Path('./results'))
# Available methods:
# - 'Chemistry': Mass reconstruction, volume calculation, kappa
# - 'Optical': Mie theory, IMPROVE extinction, RI retrieval
# - 'SizeDistr': SMPS-APS merge, mode fitting, lung deposition
# - 'VOC': OFP, SOAP, MIR calculationsPublication-ready plots:
from AeroViz import plot
# Time series, diurnal patterns, wind rose, polar plots, etc.AeroViz expects data organized by station and instrument:
/data/
├── Station_Instrument/
│ ├── raw_file_001.dat
│ ├── raw_file_002.dat
│ └── instrument_outputs/ # Auto-generated
│ ├── output_instrument.csv
│ ├── _read_instrument_qc.csv
│ └── report.json
Contributions are welcome! Please see our GitHub Issues for bug reports and feature requests.
MIT License - see LICENSE for details.
If you use AeroViz in your research, please cite:
AeroViz: Aerosol Data Processing and Visualization Toolkit
https://github.com/Alex870521/AeroViz