Home

Awesome

NAPS Data Analysis Toolbox

<p align="center"> <img src="https://github.com/dbeaudoinfortin/NAPSDataAnalysis/assets/15943629/bc1f2673-05fd-4713-8be7-57119d038358"/> </p> <p align="center"><b>Download NAPS air quality data <a href="https://dbeaudoinfortin.github.io/NAPSDataAnalysis/">here</a></b></p>

Contents

Overview

Welcome to the Canada National Air Pollution Surveillance Program (NAPS) data downloader, extractor, importer, analysis, and visualization toolbox.

This project will eventually contain a collection of tools to assist in the analysis of Canadian air quality data. The data is provided by the National Air Pollution Surveillance (NAPS) program, which is part of Environment and Climate Change Canada. You can view the original data here.

I started this project because, despite the wealth of data that NAPS provides, analysing it is challenging, time consuming and error prone. The data from the NAPS portal is spread out in hundreds of XLS/XLSX/CSV files, with dozens of formats, different units of measure, different naming conventions, etc. With this toolbox, anyone can use the downloader tools to download all of the data they need in one command. I then provide the tools needed to parse all this data, clean it up and import it into a single simple, clean database schema. After that, you can analyse the data using whatever tool works best for you. I provide a powerful dynamic query tool, a CSV exporter tool, a heat map visualization tool to generate pretty graphs, and a couple example BI dashboards to get you started with BI tools. And if all of that is too complicated, you might still be interested in either the data download web page or the clean data exports that republish the NAPS data in a consistent format.

All usage is for non-commercial research purposes. I am not affiliated with the Government of Canada.

Data Download Web Page

If you are simply looking to download NAPS air quality data, I have created a simple web page that makes it quick and easy to download CSV files. This web page is hosted on GitHub Pages and delivers static content from the /docs directory of this project.

Clean Data Exports

Last Updated October 2024

The NAPS data is messy; the data files contain many inconsistencies in structure, formatting, labelling, etc. In order to load all this data into a clean database, I needed to implement many clean-up rules and handle many exceptional cases. I believe this work could be of benefit to others.

If you are curious about the data issues I have encountered, I have started keeping track of some of the non-trivial issues here.

In the /exports directory you will find many CSV files that re-publish the same NAPS data but cleaned-up and grouped. These files were generated using the NAPSContinuousDataExporter and NAPSIntegratedDataExporter.

Integrated Data

All of the integrated data exports have been zipped to compress them. I have exported the data 3 different ways:

Continuous Data

All of the continuous data exports have been zipped to compress them. There is significantly more continuous data than integrated data. The zip files will expand to about 15GB in total. I have exported the data 3 different ways:

To work around GitHub's file size limit of 100MB, some of the zip files have been created as multi-part archives. You will need to download all of the parts of the archive before you can extract the main zip file.

Even More Granular Data

If you are looking for even more granular data, have a look at the /docs/data directory which contains nearly 300,000 CSV files. I have created a simple web page with simple dropdowns that make it quick and easy to download these CSV files.

Data Analysis

Dynamic Queries

The NAPS Data Analysis Toolbox provides powerful tools for the analysis of Canadian air quality data. The dynamic query tools for both the continuous and integrated data allow you to run highly customized queries to aggregate or simply retrieve the data in the way that you need it, in a single command.

The dynamic query tools have support for several types of aggregation functions, multiple levels of grouping, filtering on many dimensions (site IDs, site name, pollutants, hour, days of the week, days of the month, months, years, provinces/territories, city name, site type, site urbanization), standard deviation functions, sample counts, minimum sample counts (to optionally ensure a statistically significant number of data points), lower and upper bounds for data points (to optionally exclude outliers) and post-aggregation lower and upper bounds (to eliminate results outside the scope of interest). I'm planning to add even more functionality in the future.

Say, for example, you want to know how many times the hourly reading for carbon monoxide exceeded the national standard of 13ppm across all of Canada for the years between 1974 and 2022. You can produce the following table by running the following command:

-pollutants CO
-group1 year
-yearStart 1974
-yearEnd 2022
-aggregateFunction count
-valueLowerBound 13

The table output will look something like this:

<p align="center"> <img src="https://github.com/user-attachments/assets/b5d1d43a-8c7c-4424-aee9-596111532065" height="600" /> </p>

For more details on how to run these query tools, see the continuous and integrated data query sections below.

Heat Map Diagrams

The NAPS Data Analysis Toolbox provides tools for generating heat map diagrams for both the continuous and integrated data. These heat maps are highly customizable and can be generated in a single command. They make it much easier to spot trends in the data. For example, here is the entire history carbon monoxide readings for all NAPS sites, for all of Canada, aggregated into a single heat map diagram.

Avg_CO_By Day of the Year and Year

From this diagram alone there are some trends that immediately stand out, such as:

We can change the x-axis to get a view of what is happening on the weekends compared to the weekdays:

<p align="center"> <img src="https://github.com/user-attachments/assets/25024f6e-e70f-43b2-9926-006a93ec4be6" height="600" /> </p>

(Note that this second heat map uses a different colour palette that better suits the data.)

Focusing on a single year (2002) makes it easy to see the difference between summer and winter months:

<p align="center"> <img src="https://github.com/user-attachments/assets/9224b0b7-d57a-447f-ab1c-324bd36fd991" width="400" /> </p>

Similarly, we can look at any pollutant, or all pollutants. Here is SO2, for all years, using a third colour palette:

Avg_SO2_By Day of the Year and Year

And here are two heat maps for lead, showing the average and maximum concentrations, respectively. This makes it easy to see the large reduction in air pollution starting with the ban on leaded gasoline in 1990:

<p align="center"> <img src="https://github.com/user-attachments/assets/9660ba50-52bf-4b9b-ba17-7fcde5766e34" width="400" /> <img src="https://github.com/user-attachments/assets/a7b8b1ce-dfcf-4778-b158-fabde5fb27f3" width="400" /> </p>

(The provinces of Ontario & Quebec were only chosen to demonstrate the ability to filter by province/territory.)

We can limit the results to only large and medium urban areas, and focus in around the year 1990 to better see the large effect of the ban on leaded gasoline:

Integrated_Avg By Week of the Year and Year

Here is a breakdown by province/territory of PM2.5 concentrations. The upper and lower bounds of the colour scales have been fixed to be consistent between all 13 graphs. The seasonal trends by province become apparent when averaging the data over many years.

<p align="center"> <img src="https://github.com/user-attachments/assets/4cd0131e-955a-4943-bb16-f861090f64c6" width="400" /> <img src="https://github.com/user-attachments/assets/2effe67d-7dd0-4336-b1f1-0f025076e115" width="400" /> <img src="https://github.com/user-attachments/assets/33d54e35-bea0-4c18-b2fa-09732a52452b" width="400" /> <img src="https://github.com/user-attachments/assets/8b2d4df2-9f58-467c-83ae-b2eea672859a" width="400" /> <img src="https://github.com/user-attachments/assets/11b91e0f-8633-48d7-990c-ab2cf6297a1a" width="400" /> <img src="https://github.com/user-attachments/assets/918b3147-e795-4014-b1d2-86cf703599b5" width="400" /> <img src="https://github.com/user-attachments/assets/36725f0d-1295-4acd-a238-8aa510a63f90" width="400" /> <img src="https://github.com/user-attachments/assets/492b226e-3a79-44e4-9354-e1cd3b282b0f" width="400" /> <img src="https://github.com/user-attachments/assets/fc3b572a-0049-41cd-8549-e0b507ca8bc8" width="400" /> <img src="https://github.com/user-attachments/assets/9850b8c2-9904-4ac5-ae65-81284f8e573e" width="400" /> <img src="https://github.com/user-attachments/assets/f759dc62-0e62-492a-a671-d55092ac1157" width="400" /> <img src="https://github.com/user-attachments/assets/5430a222-5192-4fa0-b890-6ff99f97214d" width="400" /> <img src="https://github.com/user-attachments/assets/4c3a4def-4755-4d05-8bd0-586cc7e5b8b7" width="400" /> </p>

The seasonal differences between Ontario and Quebec become more apparent when looking at just the large and medium urban zones. Here is a comparison of both the average and maximum PM2.5 concentrations:

<p align="center"> <img src="https://github.com/user-attachments/assets/22d829c6-05c3-4059-b4a1-befeede455e7" width="400" /> <img src="https://github.com/user-attachments/assets/e0c27530-fa35-4e24-b780-e0e4c148cbb8" width="400" /> <img src="https://github.com/user-attachments/assets/a4b07961-e5a8-4f87-a77a-a03e956f40b2" width="400" /> <img src="https://github.com/user-attachments/assets/14f63809-3ea6-42d7-bcc5-7e79a3ee40d1" width="400" /> </p>

The queries used to generate these heat maps are fully dynamic and there are several colour palettes to choose from. The minimum and maximum values that determine the colour scale are calculated automatically, but there are also options to clamp/limit the values to a lower and an upper bound to prevent outliers from shifting the entire scale. The titles, axis labels, legends and file names are all automatically generated. There is also an option to produce an accompanying CSV table containing all of the data used to render the heat map.

For more details on how to generate custom heat maps, see the continuous and integrated heat map sections below.

Dashboards

In the /reports directory you will find a sample Microsoft Power BI report. This report is example of how a BI tool can be used for visualizing the NAPS data. This report is designed to be used in conjunction with the database schema built and populated by the tools in this tool box. For information on how to set-up your database and connect to it using Power BI, check out the Getting Started section below.

Report 2

Report 1

Report 3

I plan to eventually add sample reports for other BI/Data Visualization software that are open source, free, and available on more platforms than just Windows x86-64.

Getting Started

The following steps will guide you in building a database from scratch, populating it with NAPS data, and querying/analysing the NAPS data.

Installing PostgreSQL

The tools in this toolbox are designed to be used with a PostgreSQL database. PostgreSQL was chosen because it is feature-rich, highly performant, open-source, free, and widely available on multiple platforms.

You can download an installer of PostgreSQL for every major desktop/server OS here. The installer will walk you through the process of creating an initial database with a user and password.

Installing Java

The tools in this toolbox are written in Java. You will need the Java 21 or later in order to run any of the tools. The Java JDK is free, multi-platform (supporting Windows, Linux, MacOS, etc.), multi-architecture (supporting x86 and ARM), and can be downloaded directly from Oracle.

Downloading the Data

There are three separate tools included in this tool box that will automatically download that data files from the NAPS website and save them to a local directory. These tools were created to eliminate the tedious clicking of manually downloading and extracting all the data files. You can download any of the files in any order. The sites definition data file is only required if you will be downloading the integrated data.

NAPSSitesDownloader

This tool will download all of the NAPS site definitions from the NAPS website and save them to disk in the specified directory. You can run the tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.download.sites.NAPSSitesDownloader -p C:\temp\NAPSData\RawFiles -t 10

For more information about the possible command line arguments, see the NAPSSitesDownloader section below.

NAPSContinuousDataDownloader

This tool will download all of the NAPS continuous air quality data from the NAPS website and save it to disk in the specified directory. This is optional and only needs to be run if you want to analyze the continuous air quality data. A sub-directory named ContinuousData will be automatically created. You can run the tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.download.continuous.NAPSContinuousDataDownloader -p C:\temp\NAPSData\RawFiles -t 10

For more information about the possible command line arguments, see the NAPSContinuousDataDownloader section below.

NAPSIntegratedDataDownloader

This tool will download all of the NAPS integrated air quality data from the NAPS website and save it to disk in the specified directory. This is optional and only needs to be run if you want to analyze the integrated air quality data. A sub-directory named IntegratedData will be automatically created. You can run the tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.download.integrated.NAPSIntegratedDataDownloader -p C:\temp\NAPSData\RawFiles -t 10

For more information about the possible command line arguments, see the NAPSIntegratedDataDownloader section below.

Loading the Data

There are three separate tools included in this tool box that are used to parse the data from the files downloaded in the previous step and insert that data in that database. Any of the three tools will automatically create the database schema, if needed. The sites definition data must be loaded first and is required if you will be loading the integrated data into the database. Ensure that the PostgreSQL database previously created is running.

NAPSSitesLoader

This tool will load all of the NAPS site definitions into the database. This must be run before running the NAPSIntegratedDataLoader. Assuming you are using all default database connection parameters, you can run the tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.loader.sites.NAPSSitesLoader -p C:\temp\NAPSData\RawFiles -t 10

For more information about the possible command line arguments, see the NAPSSitesLoader section below.

NAPSContinuousDataLoader

This tool will load all of the NAPS continuous air quality data into the database. This is optional and only needs to be run if you want to analyze the continuous air quality data. Assuming you are using all default database connection parameters, you can run the tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.loader.continuous.NAPSContinuousDataLoader -p C:\temp\NAPSData\RawFiles\ContinuousData -t 10

For more information about the possible command line arguments, see the NAPSContinuousDataLoader section below.

NAPSIntegratedDataLoader

This tool will load all of the NAPS integrated air quality data into the database. This is optional and only needs to be run if you want to analyze the integrated air quality data. This must be run after all of the NAPS site definitions have been loaded into the database using NAPSSitesLoader (see above). Assuming you are using all default database connection parameters, you can run the tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.loader.integrated.NAPSIntegratedDataLoader -p C:\temp\NAPSData\RawFiles\IntegratedData -t 10

For more information about the possible command line arguments, see the NAPSIntegratedDataLoader section below.

Querying the Data

By now, all the data you wish to analyse should have been loaded into your database using either the NAPSContinuousDataLoader, the NAPSIntegratedDataLoader, or both. You may now want to query the data to retrieve what you need for your own analysis.

Assuming you are using all default database connection parameters, you can run the continuous query tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.analysis.query.continuous.NAPSContinuousDataQuery -p C:\temp\NAPSData\queries\continuous -pollutants CO -group1 year -yearStart 1974 -yearEnd 2022 -aggregateFunction count -valueLowerBound 13

Likewise, you can run the integrated query tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.analysis.query.integrated.NAPSIntegratedDataQuery -p C:\temp\NAPSData\queries\integrated -pollutants 3-Methyloctane -group1 day_of_week -aggregateFunction avg -showSampleCount

These are just example queries; you will need to craft a command that works for your scenario. For more information about the possible command line arguments, see either the NAPSContinuousDataQuery section or the NAPSIntegratedDataQuery section below.

Generating Heat Maps

By now, all the data you wish to analyse should have been loaded into your database using either the NAPSContinuousDataLoader, the NAPSIntegratedDataLoader, or both. You may now want to generate heat map diagrams to visualize the data as part of your own analysis.

Assuming you are using all default database connection parameters, you can run the continuous heat map tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.analysis.heatmap.continuous.NAPSContinuousDataHeatMap -p C:\temp\NAPSData\heatmaps\continuous -aggregateFunction avg -group1 day_of_year -group2 year -pollutants SO2 -generateCSV -colourGradient 3

Likewise, you can run the integrated query tool using the following command line command, on Windows, in the directory of the naps_data.jar:

java -cp naps_data.jar com.dbf.naps.data.analysis.heatmap.integrated.NAPSIntegratedDataHeatMap -p C:\temp\NAPSData\heatmaps\integrated -aggregateFunction max -group1 month -group2 year -pollutants Lead -provTerr ON,QC -generateCSV -colourGradient 2

These are just example heat maps; you will need to craft a command that works for your scenario. For more information about the possible command line arguments, see either the NAPSContinuousHeatMap section or the NAPSIntegratedHeatMap section below.

Installing Microsoft Power BI

If you are interested, I have created an example Power BI report to demonstrate how dashboards can make use of the database that you previously created and populated with NAPS data in the previous steps above.

The desktop version of Microsoft Power BI is a free tool for exploring and visualizing data. You can find it here. Unfortunately, it only supports Windows x86-64 systems. I do plan to eventually make sample reports for other BI/Data Visualization software.

Creating a Report

After starting Microsoft Power BI and creating a new blank report, you will need connect to your database, previously populated with NAPS data (see steps above). Provided your database is installed locally and you have used all default database settings, connecting should be as easy as selecting the PostgreSQL database option in the Get Data menu, and entering localhost as the Server and postgres as the User. get data Connect to DB

If you previously chose to load the entire NAPS dataset into your database, then I would highly suggest using the DirectQuery Data Connectivity mode, since there is likely too much database for Power BI to import. After successfully connecting to the database, Power BI will ask what tables you want to use. You should select all of them.

Screenshot 2024-06-19 231428

It will then connect to each of the tables and build a model. image

If all goes well, the model view of your report should look like the following:

image

You can now drag-and-drop columns onto the visualization to start building your report/dashboard. If you would like to view the sample report to see how it was made, you can simply download it from here and open it in Power BI.

NAPS Site Tools

The following tools are used for downloading a list of NAPS sites and loading the site definitions into a database.

NAPSSitesDownloader

A Java tool that downloads a single file containing all of the sites (sampling stations) for the NAPS program. This is the simplest tool in the toolbox and is only included for sake of completeness. The file is downloaded from here to the specified directory.

You can invoke this tool by running the class com.dbf.naps.data.download.sites.NAPSSitesDownloader. Note that the threadCount argument is meaningless since there is only one file to download.

Command line usage:

 -o,  --overwriteFiles       Replace the existing file.
 -p,  --downloadPath <arg>   Local path for downloaded files.
 -t,  --threadCount <arg>    Maximum number of parallel threads.
 -v,  --verbose              Make logging more verbose.

NAPSSitesLoader

A Java tool that loads all of the sites (sampling stations) for the NAPS program (downloaded by the NAPSContinuousDataDownloader) from the provided directory into a PostgreSQL database, as specified. This tool looks for a single file named "sites.csv" in the provided directory. The database schema is automatically created when the tool runs. Once all the data is loaded, there should be 789 rows of data (as of October 2024) in the sites table of your database.

You can invoke this tool by running the class com.dbf.naps.data.loader.sites.NAPSSitesLoader. Note that the threadCount argument is meaningless since there is only one file to process.

Command line usage:

 -p,   --dataPath <arg>       Local path for the raw data file previously downloaded (sites.csv).
 -dbh, --dbHost <arg>         Hostname for the PostgreSQL database. Default: localhost
 -dbt, --dbPort <arg>         Port for the PostgreSQL database. Default: 5432
 -dbn, --dbName <arg>         Database name for the PostgreSQL database. Default: naps
 -dbu, --dbUser <arg>         Database user name for the PostgreSQL database. Default: postgres
 -dbp, --dbPass <arg>         Database password for the PostgreSQL database. Default: password
 -t,   --threadCount <arg>    Maximum number of parallel threads.
 -v,   --verbose              Make logging more verbose.

Continuous Data Tools

The following tools are used for downloading continuous air quality data, loading the data into a database and exporting the data to CSV files. The continuous data represents instantaneous air quality measurements collected on a continuous bases and reported hourly.

NAPSContinuousDataDownloader

A Java tool that will download all of the hourly continuous data for the provided years into the provided directory. All file names are unique and all files are downloaded into a single directory. Files are downloaded from here.

You can invoke this tool by running the class com.dbf.naps.data.download.continuous.NAPSContinuousDataDownloader.

Command line usage:

 -o,  --overwriteFiles       Replace existing files.
 -p,  --downloadPath <arg>   Local path for downloaded files.
 -t,  --threadCount <arg>    Maximum number of parallel threads.
 -v,  --verbose                    Make logging more verbose.
 -ye, --yearEnd <arg>        End year (inclusive).
 -ys, --yearStart <arg>      Start year (inclusive).

NAPSContinuousDataLoader

A Java tool that loads all of the raw continuous data, previously downloaded by the NAPSContinuousDataDownloader, from the provided directory into a PostgreSQL database, as specified. The database schema is automatically created when the tool runs. This tool automatically cleans-up and fixes data inconsistencies as it finds them. Once all the data is loaded, there should be about 275 million rows of data (as of October 2024) in the continuous_data table of your database.

You can invoke this tool by running the class com.dbf.naps.data.loader.continuous.NAPSContinuousDataLoader.

Command line usage:

 -p,   --dataPath <arg>       Local path for raw data files previously downloaded.
 -dbh, --dbHost <arg>         Hostname for the PostgreSQL database. Default: localhost
 -dbt, --dbPort <arg>         Port for the PostgreSQL database. Default: 5432
 -dbn, --dbName <arg>         Database name for the PostgreSQL database. Default: naps
 -dbu, --dbUser <arg>         Database user name for the PostgreSQL database. Default: postgres
 -dbp, --dbPass <arg>         Database password for the PostgreSQL database. Default: password
 -t,   --threadCount <arg>    Maximum number of parallel threads.
 -v,   --verbose              Make logging more verbose.

NAPSContinuousDataQuery

This powerful Java tool allows you to dynamically query the NAPS continuous data that was loaded into a PostgreSQL database using the NAPSContinuousDataLoader. It will output a CSV file containing a table of data based on the query rules that you provide. This tool is intended to be used for aggregating data (i.e. average, sum, minimum, maximum, etc.) that is grouped by one or more fields (e.g. pollutant, site, year, month, day, etc.). If you need to generate large tables of data that do not involve grouping functions, have a look at the NAPSContinuousDataExporter.

You can invoke this tool by running the class com.dbf.naps.data.analysis.query.continuous.NAPSContinuousDataQuery.

Command line usage:

 -a,   --aggregateFunction <arg>  Data aggregation function (AVG, MIN, MAX, COUNT, SUM, NONE).
 -cn,  --cityName <arg>           City name, partial match.
 -ct,  --title <arg>              Chart title. Will be automatically generated if not defined.
 -d,   --days <arg>               Comma-separated list of days of the month.
 -dbh, --dbHost <arg>             Hostname for the PostgreSQL database. Default: localhost
 -dbn, --dbName <arg>             Database name for the PostgreSQL database. Default: naps
 -dbp, --dbPass <arg>             Database password for the PostgreSQL database. Default: password
 -dbt, --dbPort <arg>             Port for the PostgreSQL database. Default: 5432
 -dbu, --dbUser <arg>             Database user name for the PostgreSQL database. Default: postgres
 -dow, --daysOfWeek <arg>         Comma-separated list of days of the week, starting at 1 for Sunday.
 -fn,  --fileName <arg>           Custom file name without the extension. Will be automatically generated if not defined.
 -fp,  --filePerPollutant         Create a separate file for each pollutant.
 -fs,  --filePerSite              Create a separate file for each site.
 -fy,  --filePerYear              Create a separate file for each year.
 -g1,  --group1 <arg>             Data field for level 1 grouping.
 -g2,  --group2 <arg>             Data field for optional level 2 grouping.
 -g3,  --group3 <arg>             Data field for optional level 3 grouping
 -g4,  --group4 <arg>             Data field for optional level 4 grouping
 -g5,  --group5 <arg>             Data field for optional level 5 grouping
 -m,   --months <arg>             Comma-separated list of months of the year, starting at 1 for January.
 -o,   --overwriteFiles           Replace existing files.
 -p,   --dataPath <arg>           Local path to save the data.
 -pn,  --pollutants <arg>         Comma-separated list of pollutant names.
 -pt,  --provTerr <arg>           Comma-separated list of 2-digit province & territory codes.
 -rlb, --resultLowerBound <arg>   Lower bound (inclusive) of post-aggregated results to include. Results less than this
                                     threshold will be filtered out of the result set after aggregation.
 -rub, --resultUpperBound <arg>   Upper bound (inclusive) of post-aggregated results to include. Results greater than
                                     this threshold will be filtered out of the result set after aggregation.
 -sc,  --showSampleCount          Include the sample count (number of samples or data points) in the result set.
 -scm, --minSampleCount <arg>     Minimum sample count (number of samples or data points) in order to be included in the
                                     result set.
 -sid, --sites <arg>              Comma-separated list of site IDs.
 -sn,  --siteName <arg>           NAPS site (station) name, partial match.
 -st, --siteType <arg>            NAPS site type classification (PE, RB, T, PS).
 -stdDevPop, --showStdDevPop      Include the population standard deviation in the result set.
 -stdDevSmp, --showStdDevSamp     Include the sample standard deviation in the result set.
 -t,   --threadCount <arg>        Maximum number of parallel threads.
 -u,   --urbanization <arg>       NAPS site urbanization classification (LU, MU, SU, NU).
 -v,   --verbose                  Make logging more verbose.
 -vlb, --valueLowerBound <arg>    Lower bound (inclusive) of pre-aggregated raw values to include. Values less than this
                                     threshold will be filtered out before aggregation.
 -vub, --valueUpperBound <arg>    Upper bound (inclusive) of pre-aggregated raw values to include. Values greater than
                                     this threshold will be filtered out before aggregation.
 -ye,  --yearEnd <arg>            End year (inclusive).
 -ys,  --yearStart <arg>          Start year (inclusive).

Aggregation Rules:

Filtering Rules:

Other Notes:

Example Query:

Say, for example, you are studying the effects of wildfires on air quality in Canada and you want generate a unique table of data for each site and each year. You want those tables to contain each day of summer months between 2018 and 2022 where the average PM2.5 measurement for that day exceeded a threshold of 20, in all sites in Alberta.

In addition to the obligatory -dataPath option, you can add the following command line options:

-provTerr AB
-months 5,6,7,8,9
-pollutants PM2.5
-yearStart 2018
-yearEnd 2022
-group1 month
-group2 day
-aggregateFunction avg
-minSampleCount 4
-valueUpperBound 1000
-resultLowerBound 20
-showSampleCount
-showStdDevSamp
-filePerSite
-filePerYear

Here is an explanation of what each option does:

With these options, the results will include the average of the 24 PM2.5 measurements that were taken each day. It will only include results for days that had at least 4 data points, ensuring the results are statistically significant. Any data point with a value greater than 1000 is considered outliers and will be excluded because, in our hypothetical scenario, they exceed the maximum possible range for PM2.5 for the air quality sensors. A column indicating the number of samples (data points) will be included in the results. Also included is a column indicating the standard deviation, which shows how much the measurements for each day vary. Since a lower bound is specified, all the days where the average PM2.5 measurement was below the threshold of 20 (considered 'Poor' in terms of air quality) will be excluded; only poor air quality days will be included in the results. A separate table of results will be generated for each combination of naps site and year, provided data is available for that combination.

The complete command line command is the following:

 java -cp naps_data.jar com.dbf.naps.data.analysis.query.continuous.NAPSContinuousDataQuery -p C:\temp\NAPSData\Queries -t 5 -provTerr AB -months 5,6,7,8,9 -pollutants PM2.5 -yearStart 2018 -yearEnd 2022 -group1 month -group2 day -aggregateFunction avg -minSampleCount 4 -valueUpperBound 1000 -resultLowerBound 20 -showSampleCount -showStdDevSamp -filePerSite -filePerYear

The above example generated 224 tables of data, each saved in its own CSV file. The table for Redwater, Alberta contains only the poor air quality days and shows that nearly the entire month of August 2018 had poor air quality due to smoke from B.C. wildfires.

image

NAPSContinuousHeatMap

A Java tool that generates highly customizable heat map diagrams for the visualization of NAPS continuous data. These heat maps are saved in high resolution PNG format.

You can invoke this tool by running the class com.dbf.naps.data.analysis.heatmap.continuous.NAPSContinuousDataHeatMap.

Command line usage:

 -a,   --aggregateFunction <arg>  Data aggregation function (AVG, MIN, MAX, COUNT, SUM).
 -cg,  --colourGradient <arg>     Heat map colour gradient choice. Values are 1-9 (inclusive).
 -clb, --colourLowerBound <arg>   Heat map colour lower bound (inclusive).
 -cn,  --cityName <arg>           City name, partial match.
 -csv, --generateCSV              Generate a corresponding CSV file containing the raw data for each heat map.
 -ct,  --title <arg>              Chart title. Will be automatically generated if not defined.
 -cub, --colourUpperBound <arg>   Heat map colour upper bound (inclusive).
 -d,   --days <arg>               Comma-separated list of days of the month.
 -dbh, --dbHost <arg>             Hostname for the PostgreSQL database. Default: localhost
 -dbn, --dbName <arg>             Database name for the PostgreSQL database. Default: naps
 -dbp, --dbPass <arg>             Database password for the PostgreSQL database. Default: password
 -dbt, --dbPort <arg>             Port for the PostgreSQL database. Default: 5432
 -dbu, --dbUser <arg>             Database user name for the PostgreSQL database. Default: postgres
 -dow, --daysOfWeek <arg>         Comma-separated list of days of the week, starting at 1 for Sunday.
 -fn,  --fileName <arg>           Custom file name without the extension. Will be automatically generated if not defined.
 -fp,  --filePerPollutant         Create a separate file for each pollutant.
 -fs,  --filePerSite              Create a separate file for each site.
 -fy,  --filePerYear              Create a separate file for each year.
 -g1,  --group1 <arg>             Data field for the heat map X-axis.
 -g2,  --group2 <arg>             Data field for the heat map Y-axis.
 -m,   --months <arg>             Comma-separated list of months of the year, starting at 1 for January.
 -o,   --overwriteFiles           Replace existing files.
 -p,   --dataPath <arg>           Local path to save the data.
 -pn,  --pollutants <arg>         Comma-separated list of pollutant names.
 -pt,  --provTerr <arg>           Comma-separated list of 2-digit province & territory codes.
 -rlb, --resultLowerBound <arg>   Lower bound (inclusive) of post-aggregated results to include. Results less than this
                                     threshold will be filtered out of the result set after aggregation.
 -rub, --resultUpperBound <arg>   Upper bound (inclusive) of post-aggregated results to include. Results greater than
                                     this threshold will be filtered out of the result set after aggregation.
 -scm, --minSampleCount <arg>     Minimum sample count (number of samples or data points) in order to be included in the
                                     result set.
 -sid, --sites <arg>              Comma-separated list of site IDs.
 -sn,  --siteName <arg>           NAPS site (station) name, partial match.
 -st,  --siteType <arg>           NAPS site type classification (PE, RB, T, PS).
 -t,   --threadCount <arg>        Maximum number of parallel threads.
 -u,   --urbanization <arg>       NAPS site urbanization classification (LU, MU, SU, NU).
 -v,   --verbose                  Make logging more verbose.
 -vlb, --valueLowerBound <arg>    Lower bound (inclusive) of pre-aggregated raw values to include. Values less than this
                                     threshold will be filtered out before aggregation.
 -vub, --valueUpperBound <arg>    Upper bound (inclusive) of pre-aggregated raw values to include. Values greater than
                                     this threshold will be filtered out before aggregation.
 -ye,  --yearEnd <arg>            End year (inclusive).
 -ys,  --yearStart <arg>          Start year (inclusive).

Colour Palettes:

9 different colour palettes are currently offered. I plan to eventually add more in the future. The current palettes are the following:

  1. A smooth gradient based on the colour wheel from blue to red. All the of the colours are fully saturated.
  2. A 12 step gradient from blue to red with less saturation than the first colour palette.
  3. A simplified 5 step gradient from blue to red.
  4. A two colour gradient from blue to red, with purple mixed in-between.
  5. A 5 step colour blind friendly gradient of greenish-yellow to dark orange.
  6. A 3 step black-red-orange gradient, similar to black-body radiation, up to approximately 1300 degrees kelvin.
  7. Same as number 6 but two more steps are added to extend the scale up to approximately 6500k degrees kelvin.
  8. A 50 step colour gradient based on Dave Green's ‘cubehelix’ colour scheme
  9. A 2 step grey-scale gradient that should be used for non-colour screen/print-outs.

The default colour palette, if not specified, is number 1. Here are examples of what the colour palette look like, in order:

Continuous_By Day of the Month and Month_C1 Continuous_By Day of the Month and Month_C2 Continuous_By Day of the Month and Month_C3 Continuous_By Day of the Month and Month_C4 Continuous_By Day of the Month and Month_C5 Continuous_By Day of the Month and Month_C6 Continuous_By Day of the Month and Month_C7 Continuous_By Day of the Month and Month_C8 Continuous_By Day of the Month and Month_C9

Aggregation Rules:

Filtering Rules:

Notes:

NAPSContinuousDataExporter

A Java tool that exports the continuous data, previously loaded by the NAPSContinuousDataLoader, from a PostgreSQL database to one or more CSV files at the directory location specified. The data is in a flat, denormalized, CSV format and is encoded in UTF-8 with a BOM. This format is compatible with all modern versions of Excel. The tool allows you to specify what years, pollutants, and sites you want to export. It also lets you specify if you want the data grouped into a single file by any combination of per year, per pollutant and per site.

You can invoke this tool by running the class com.dbf.naps.data.exporter.continuous.NAPSContinuousDataExporter.

Command line usage:

 -t,   --threadCount <arg> Maximum number of parallel threads.
 -dbh, --dbHost <arg>      Hostname for the PostgreSQL database. Default: localhost
 -dbn, --dbName <arg>      Database name for the PostgreSQL database. Default: naps
 -dbp, --dbPass <arg>      Database password for the PostgreSQL database. Default: password
 -dbt, --dbPort <arg>      Port for the PostgreSQL database. Default: 5432
 -dbu, --dbUser <arg>      Database user name for the PostgreSQL database. Default: postgres
 -fn,  --fileName <arg>    Custom file name without the extension. Will be automatically generated if not defined.
 -fp,  --filePerPollutant  Create a separate file for each pollutant.
 -fs,  --filePerSite       Create a separate file for each site.
 -fy,  --filePerYear       Create a separate file for each year.
 -o,   --overwriteFiles    Replace existing files.
 -p,   --dataPath <arg>    Local path to save the exported data.
 -pn,  --pollutants <arg>  Comma-separated list of pollutant names.
 -sid, --sites <arg>       Comma-separated list of site IDs.
 -v,   --verbose           Make logging more verbose.
 -ye,  --yearEnd <arg>     End year (inclusive).
 -ys,  --yearStart <arg>   Start year (inclusive).

Integrated Data Tools

The following tools are used for downloading integrated air quality data, loading the data into a database and exporting the data to CSV files. The integrated data represents air quality measurements that are sampled over a longer duration (typically 24 hours) and collected on a regular basis (every few days).

NAPSIntegratedDataDownloader

A Java tool that will download all of the integrated data for the provided years into the provided directory. Since many of the file names of the files conflict, each year will be downloaded into its own sub-directory. Files are downloaded from here.

You can invoke this tool by running the class com.dbf.naps.data.download.integrated.NAPSIntegratedDataDownloader.

Command line usage:

 -o,  --overwriteFiles       Replace existing files.
 -p,  --downloadPath <arg>   Local path for downloaded files.
 -t,  --threadCount <arg>    Maximum number of parallel threads.
 -v,  --verbose              Make logging more verbose.
 -ye, --yearEnd <arg>        End year (inclusive).
 -ys, --yearStart <arg>      Start year (inclusive).

NAPSIntegratedDataLoader

A Java tool that loads all of the raw integrated data, previously downloaded by the NAPSIntegratedDataDownloader, from the provided directory into a PostgreSQL database, as specified. The database schema is automatically created when the tool runs. This tool automatically cleans-up and fixes data inconsistencies as it finds them. Once all the data is loaded, there should be about 14 million rows of data (as of October 2024) in the integrated_data table of your database.

You can invoke this tool by running the class com.dbf.naps.data.loader.integrated.NAPSIntegratedDataLoader.

NOTE: The NAPSSitesLoader must be run first in order to populate the naps.sites table with site (station) definitions prior to loading the integrated data!

Command line usage:

 -p,   --dataPath <arg>       Local path for raw data files previously downloaded.
 -dbh, --dbHost <arg>         Hostname for the PostgreSQL database. Default: localhost
 -dbt, --dbPort <arg>         Port for the PostgreSQL database. Default: 5432
 -dbn, --dbName <arg>         Database name for the PostgreSQL database. Default: naps
 -dbu, --dbUser <arg>         Database user name for the PostgreSQL database. Default: postgres
 -dbp, --dbPass <arg>         Database password for the PostgreSQL database. Default: password
 -t,   --threadCount <arg>    Maximum number of parallel threads.
 -v,   --verbose              Make logging more verbose.

NAPSIntegratedDataQuery

This powerful Java tool allows you to dynamically query the NAPS integrated data that was loaded into a PostgreSQL database using the NAPSIntegratedDataLoader. It will output a CSV file containing a table of data based on the query rules that you provide. It functions the same as the NAPSContinuousDataQuery and accepts all of the same command line arguments, with the exception that the data fields used for grouping cannot include HOUR, since hour attribute only applies to continuous data, not integrated data.

You can invoke this tool by running the class com.dbf.naps.data.analysis.query.integrated.NAPSIntegratedDataQuery.

Command line usage:

 -a,   --aggregateFunction <arg>  Data aggregation function (AVG, MIN, MAX, COUNT, SUM, NONE).
 -cn,  --cityName <arg>           City name, partial match.
 -d,   --days <arg>               Comma-separated list of days of the month.
 -dbh, --dbHost <arg>             Hostname for the PostgreSQL database. Default: localhost
 -dbn, --dbName <arg>             Database name for the PostgreSQL database. Default: naps
 -dbp, --dbPass <arg>             Database password for the PostgreSQL database. Default: password
 -dbt, --dbPort <arg>             Port for the PostgreSQL database. Default: 5432
 -dbu, --dbUser <arg>             Database user name for the PostgreSQL database. Default: postgres
 -dow, --daysOfWeek <arg>         Comma-separated list of days of the week, starting at 1 for Sunday.
 -fn,  --fileName <arg>           Custom file name without the extension. Will be automatically generated if not defined.
 -fp,  --filePerPollutant         Create a separate file for each pollutant.
 -fs,  --filePerSite              Create a separate file for each site.
 -fy,  --filePerYear              Create a separate file for each year.
 -g1,  --group1 <arg>             Data field for level 1 grouping.
 -g2,  --group2 <arg>             Data field for optional level 2 grouping.
 -g3,  --group3 <arg>             Data field for optional level 3 grouping
 -g4,  --group4 <arg>             Data field for optional level 4 grouping
 -g5,  --group5 <arg>             Data field for optional level 5 grouping
 -m,   --months <arg>             Comma-separated list of months of the year, starting at 1 for January.
 -o,   --overwriteFiles           Replace existing files.
 -p,   --dataPath <arg>           Local path to save the data.
 -pn,  --pollutants <arg>         Comma-separated list of pollutant names.
 -pt,  --provTerr <arg>           Comma-separated list of 2-digit province & territory codes.
 -rlb, --resultLowerBound <arg>   Lower bound (inclusive) of post-aggregated results to include. Results less than this
                                     threshold will be filtered out of the result set after aggregation.
 -rub, --resultUpperBound <arg>   Upper bound (inclusive) of post-aggregated results to include. Results greater than
                                     this threshold will be filtered out of the result set after aggregation.
 -sc,  --showSampleCount          Include the sample count (number of samples or data points) in the result set.
 -scm, --minSampleCount <arg>     Minimum sample count (number of samples or data points) in order to be included in the
                                     result set.
 -sid, --sites <arg>              Comma-separated list of site IDs.
 -sn,  --siteName <arg>           NAPS site (station) name, partial match.
 -st,  --siteType <arg>           NAPS site type classification (PE, RB, T, PS).
 -stdDevPop, --showStdDevPop      Include the population standard deviation in the result set.
 -stdDevSmp, --showStdDevSamp     Include the sample standard deviation in the result set.
 -t,   --threadCount <arg>        Maximum number of parallel threads.
 -u,   --urbanization <arg>       NAPS site urbanization classification (LU, MU, SU, NU).
 -v,   --verbose                  Make logging more verbose.
 -vlb, --valueLowerBound <arg>    Lower bound (inclusive) of pre-aggregated raw values to include. Values less than this
                                     threshold will be filtered out before aggregation.
 -vub, --valueUpperBound <arg>    Upper bound (inclusive) of pre-aggregated raw values to include. Values greater than
                                     this threshold will be filtered out before aggregation.
 -ye,  --yearEnd <arg>            End year (inclusive).
 -ys,  --yearStart <arg>          Start year (inclusive).

Possible values for group1 through group5 are YEAR,MONTH, DAY, DAY_OF_WEEK, DAY_OF_YEAR, WEEK_OF_YEAR, NAPS_ID, POLLUTANT, PROVINCE_TERRITORY, SITE_TYPE, URBANIZATION.

All of the same rules and restrictions of the NAPSContinuousDataQuery apply.

NAPSIntegratedHeatMap

A Java tool that generates highly customizable heat map diagrams for the visualization of NAPS integrated data. It functions the same as the NAPSContinuousHeatMap and accepts all of the same command line arguments, with the exception that the data fields used for the x and y axes (group1 and group2) cannot include HOUR, since hour attribute only applies to continuous data, not integrated data.

You can invoke this tool by running the class com.dbf.naps.data.analysis.heatmap.integrated.NAPSIntegratedDataHeatMap.

Command line usage:

 -a,   --aggregateFunction <arg>  Data aggregation function (AVG, MIN, MAX, COUNT, SUM).
 -cg,  --colourGradient <arg>     Heat map colour gradient choice. Values are 1-8 (inclusive).
 -clb, --colourLowerBound <arg>   Heat map colour lower bound (inclusive).
 -cn,  --cityName <arg>           City name, partial match.
 -csv, --generateCSV              Generate a corresponding CSV file containing the raw data for each heat map.
 -cub, --colourUpperBound <arg>   Heat map colour upper bound (inclusive).
 -d,   --days <arg>               Comma-separated list of days of the month.
 -dbh, --dbHost <arg>             Hostname for the PostgreSQL database. Default: localhost
 -dbn, --dbName <arg>             Database name for the PostgreSQL database. Default: naps
 -dbp, --dbPass <arg>             Database password for the PostgreSQL database. Default: password
 -dbt, --dbPort <arg>             Port for the PostgreSQL database. Default: 5432
 -dbu, --dbUser <arg>             Database user name for the PostgreSQL database. Default: postgres
 -dow, --daysOfWeek <arg>         Comma-separated list of days of the week, starting at 1 for Sunday.
 -fn,  --fileName <arg>           Custom file name without the extension. Will be automatically generated if not defined.
 -fp,  --filePerPollutant         Create a separate file for each pollutant.
 -fs,  --filePerSite              Create a separate file for each site.
 -fy,  --filePerYear              Create a separate file for each year.
 -g1,  --group1 <arg>             Data field for the heat map X-axis.
 -g2,  --group2 <arg>             Data field for the heat map Y-axis.
 -m,   --months <arg>             Comma-separated list of months of the year, starting at 1 for January.
 -o,   --overwriteFiles           Replace existing files.
 -p,   --dataPath <arg>           Local path to save the data.
 -pn,  --pollutants <arg>         Comma-separated list of pollutant names.
 -pt,  --provTerr <arg>           Comma-separated list of 2-digit province & territory codes.
 -rlb, --resultLowerBound <arg>   Lower bound (inclusive) of post-aggregated results to include. Results less than this
                                     threshold will be filtered out of the result set after aggregation.
 -rub, --resultUpperBound <arg>   Upper bound (inclusive) of post-aggregated results to include. Results greater than
                                     this threshold will be filtered out of the result set after aggregation.
 -scm, --minSampleCount <arg>     Minimum sample count (number of samples or data points) in order to be included in the
                                     result set.
 -sid, --sites <arg>              Comma-separated list of site IDs.
 -sn,  --siteName <arg>           NAPS site (station) name, partial match.
 -st,  --siteType <arg>           NAPS site type classification (PE, RB, T, PS).
 -t,   --threadCount <arg>        Maximum number of parallel threads.
 -u,   --urbanization <arg>       NAPS site urbanization classification (LU, MU, SU, NU).
 -v,   --verbose                  Make logging more verbose.
 -vlb, --valueLowerBound <arg>    Lower bound (inclusive) of pre-aggregated raw values to include. Values less than this
                                     threshold will be filtered out before aggregation.
 -vub, --valueUpperBound <arg>    Upper bound (inclusive) of pre-aggregated raw values to include. Values greater than
                                     this threshold will be filtered out before aggregation.
 -ye,  --yearEnd <arg>            End year (inclusive).
 -ys,  --yearStart <arg>          Start year (inclusive).

Possible values for group1 and group2 are YEAR,MONTH, DAY, DAY_OF_WEEK, DAY_OF_YEAR, WEEK_OF_YEAR, NAPS_ID, POLLUTANT, PROVINCE_TERRITORY, SITE_TYPE, URBANIZATION.

All of the same rules and restrictions of the NAPSContinuousHeatMap apply.

NAPSIntegratedDataExporter

A Java tool that exports the integrated data, previously loaded by the NAPSIntegratedDataLoader, from a PostgreSQL database to one or more CSV files at the directory location specified. The data is in a flat, denormalized, CSV format and is encoded in UTF-8 with a BOM. This format is compatible with all modern versions of Excel. The tool allows you to specify what years, pollutants, and sites you want to export. It also lets you specify if you want the data grouped into a single file by any combination of per year, per pollutant and per site.

You can invoke this tool by running the class com.dbf.naps.data.exporter.integrated.NAPSIntegratedDataExporter.

Command line usage:

 -t,--threadCount <arg>    Maximum number of parallel threads.
 -dbh, --dbHost <arg>      Hostname for the PostgreSQL database. Default: localhost
 -dbn, --dbName <arg>      Database name for the PostgreSQL database. Default: naps
 -dbp, --dbPass <arg>      Database password for the PostgreSQL database. Default: password
 -dbt, --dbPort <arg>      Port for the PostgreSQL database. Default: 5432
 -dbu, --dbUser <arg>      Database user name for the PostgreSQL database. Default: postgres
 -fn,  --fileName <arg>    Custom file name without the extension. Will be automatically generated if not defined.
 -fp,  --filePerPollutant  Create a separate file for each pollutant.
 -fs,  --filePerSite       Create a separate file for each site.
 -fy,  --filePerYear       Create a separate file for each year.
 -o,   --overwriteFiles    Replace existing files.
 -p,   --dataPath <arg>    Local path to save the exported data.
 -pn,  --pollutants <arg>  Comma-separated list of pollutant names.
 -sid, --sites <arg>       Comma-separated list of site IDs.
 -v,   --verbose           Make logging more verbose.
 -ye,  --yearEnd <arg>     End year (inclusive).
 -ys,  --yearStart <arg>   Start year (inclusive).

How To Run Individual Tools

You can find the latest package here. Alternatively, in the /target directory you can find the pre-compiled jar file naps_data.jar. This is a shaded jar file which means that it contains all of the 3rd party dependencies inside of it. Assuming you have Java 17 installed and part of your system path you can simply invoke the class by running the following:

 java -cp naps_data.jar com.dbf.naps.data.loader.continuous.NAPSContinuousDataLoader -p C:\temp\NAPSData\RawFiles -t 24

In the above example, the data will be loaded from the C:\temp\NAPSData\RawFiles directory into the database using a thread pool size of 24, and all default database connection options (see above for details).

Pollutants

In order to analyse the data using tools such as the NAPSContinuousHeatMap or the NAPSContinuousDataQuery, you will need to know the correct names of the pollutants. The data from the NAPS portal contains many inconsistencies and I have taken the time to resolve them as I find them. For example, there is a mix of chemical symbols and names (Pb vs. Lead, Ti vs Titanium), inconsistent capitalization (AMMONIUM vs. Ammonium, a-Pinene vs. A-Pinene), inconsistent spacing (Chrysene&Triphenylene vs. Chrysene & Triphenylene, Freon114 vs. Freon 114) and the inconsistent naming of PM 2.5 (PM25 vs. PM2.5).

The following table lists all of the compounds (pollutants) and how many data points are present in both the continuous data set and the integrated data set.

<details> <summary>Table of Compounds</summary>

As of October 2024

CompoundContinuous Data PointsIntegrated Data Points
CO22,515,492
NO38,711,270
NO241,663,301
NOX30,910,885
O357,283,903
PM109,785,097
PM2.535,593,88139120
SO237,398,0185354
1-Bromopropane1209
1-Butene/Isobutene76502
1-Butyne54678
1-Decene31484
1-Heptene30900
1-Hexene56593
1-Hexene/2-Methyl-1-Pentene15836
1-Me-Pyrene6532
1-Methylcyclohexene34763
1-Methylcyclopentene34771
1-Methylpyrene3357
1-Nonene31173
1-Octene32108
1-Pentene77107
1-Propyne48033
1-Undecene23655
1,1-Dichloroethane50692
1,1-Dichloroethylene52542
1,1,1-Trichloroethane75177
1,1,2-Trichloroethane69481
1,1,2,2-Tetrachloroethane52405
1,2-Dichlorobenzene52550
1,2-Dichloroethane70470
1,2-Dichloropropane52561
1,2-Diethylbenzene39184
1,2,3-Trimethylbenzene76829
1,2,4-Trichlorobenzene52097
1,2,4-Trimethylbenzene77070
1,3-Butadiene77121
1,3-Dichlorobenzene52576
1,3-Diethylbenzene76850
1,3,5-Trimethylbenzene77072
1,4-Dichlorobenzene77075
1,4-Dichlorobutane37265
1,4-Diethylbenzene75956
1234678-H7CDD3076
1234678-H7CDF3076
123478-H6CDD3076
123478-H6CDF3076
1234789-H7CDF3076
123678-H6CDD3076
123678-H6CDF3076
12378-P5CDD3076
12378-P5CDF3076
123789-H6CDD3076
123789-H6CDF3076
13C12-H6CDD3076
13C12-H6CDF3049
13C12-H7CDD3076
13C12-H7CDF3049
13C12-OCDD3076
13C12-P5CDD3076
13C12-P5CDF3049
13C12-TCDD3076
13C12-TCDF3076
13C6-HCB1609
13C6-PCP1602
2-Ethyl-1-Butene21807
2-Ethyltoluene77108
2-Me-Fluorene6534
2-Methyl-1-butene73846
2-Methyl-1-Pentene5574
2-Methyl-2-butene73822
2-methyl-2-Pentene993
2-Methylfluorene3355
2-Methylheptane77014
2-Methylhexane77075
2-Methylpentane76936
2-Pentanone864
2-Pentanone/Isovaleraldehyde7091
2,2-Dimethylbutane76968
2,2-Dimethylhexane46134
2,2-Dimethylpentane59357
2,2-Dimethylpropane54681
2,2,3-Trimethylbutane35097
2,2,4-Trimethylpentane77106
2,2,5-Trimethylhexane58259
2,3-Dimethylbutane77118
2,3-Dimethylpentane77110
2,3,4-Trimethylpentane77114
2,4-Dimethylhexane77088
2,4-Dimethylpentane77110
2,5-Dimethylbenzaldehyde7237
2,5-Dimethylheptane1304
2,5-Dimethylhexane77078
234678-H6CDF3076
23478-P5CDF3076
2378-TCDD3076
2378-TCDF3076
3-Ethyltoluene77111
3-Me-Cholanthrene6525
3-Methyl-1-Butene37045
3-Methyl-1-pentene54388
3-Methylcholanthrene3357
3-Methylheptane77062
3-Methylhexane77113
3-Methyloctane1281
3-Methylpentane76733
3,6-Dimethyloctane37365
4-Ethyltoluene77109
4-Methyl-1-pentene53818
4-Methylheptane77079
4-Methyloctane1294
7-Me-Benz(a)Anthracene6527
7-Methylbenz(a)Anthracene3357
A-Pinene51592
Acenaphthene9886
Acenaphthylene9877
Acetaldehyde13399
Acetate34557
Acetone13374
Acetylene75905
Acrolein9442
Aluminum111612
Ammonia30530
Ammonium45360
Anthanthrene9886
Anthracene9869
Antimony114301
Arabitol12662
Arsenic34532
B-Pinene51096
Barium140508
Benz(a)Anthracene9888
Benzaldehyde10294
Benzene77064
Benzo(a)Fluorene9889
Benzo(a)Pyrene9861
Benzo(b)&(k)Fluoranthene1981
Benzo(b)Chrysene9891
Benzo(b)Fluoranthene7965
Benzo(b)Fluorene9886
Benzo(e)Pyrene9890
Benzo(g,h,i)Fluoranthene9889
Benzo(g,h,i)Perylene9886
Benzo(k)Fluoranthene7969
Benzylchloride41318
Beryllium29991
Bismuth3138
Bromide40544
Bromine87462
Bromodichloromethane38568
Bromoform70330
Bromomethane68617
Bromotrichloromethane10550
Butane77109
Butyraldehyde/Iso-Butyraldehyde1790
Cadmium119962
Calcium119604
Camphene51214
Carbontetrachloride77085
Cerium36931
Cesium54465
Chloride39433
Chlorobenzene69924
Chloroethane68614
Chloroform76803
Chloromethane75181
Chromium119568
Chrysene7965
Chrysene & Triphenylene2000
cis-1,2-Dichloroethylene36928
cis-1,2-Dimethylcyclohexane64142
cis-1,3-Dichloropropene39194
cis-1,3-Dimethylcyclohexane61191
cis-1,4/t-1,3-Dimethylcyclohexane57679
cis-2-Butene77119
cis-2-Heptene35862
cis-2-Hexene76758
cis-2-Octene9755
cis-2-Pentene77094
cis-3-Heptene8941
cis-3-Methyl-2-Pentene74116
cis-4-Methyl-2-pentene65305
Cl-29562
Cobalt34532
Copper40297
Crotonaldehyde10294
Cyclohexane77119
Cyclohexene34678
Cyclopentane76972
Cyclopentene56770
D-Limonene51242
Decane77086
Dibenz(a,c)&(a,h)Anthracene9819
Dibromochloromethane39061
Dibromomethane39198
Dodecane75811
EC5871
EC(A)12298
EC(B)6305
EC_R11781
EC_T11783
EC111783
EC1(A)12298
EC1(B)6305
EC211783
EC2(A)12298
EC2(B)6305
EC311783
EC3(A)12298
EC3(B)6305
EDB38570
Ethane76167
Ethylbenzene77078
Ethylbromide37371
Ethylene74819
Fluoranthene9891
Fluorene9887
Fluoride42340
Formaldehyde13402
Formate34559
Freon 1176991
Freon 11342474
Freon 11470298
Freon 1264825
Freon 2276867
Galactosan12663
Gallium3138
H6CDD3076
H6CDF3076
H7CDD3076
H7CDF3076
HCB1566
Heptane77020
Hexachlorobutadiene52067
Hexanal10291
Hexane76090
Hexylbenzene35788
Indane76685
Indeno(1,2,3-cd)Fluoranthene5899
Indeno(1,2,3-cd)Pyrene9877
Iron119582
iso-Butylbenzene54583
iso-Propylbenzene77093
Isobutane77086
Isopentane77015
Isoprene76826
Isovaleraldehyde2654
Lanthanum11662
Lead121968
Levoglucosan12662
Lithium42260
m-Tolualdehyde9080
m and p-Xylene77086
Magnesium42385
Manganese126621
Mannitol11798
Mannosan12662
MEK12501
MEK/Butyraidehyde864
Methylcyclohexane77097
Methylcyclopentane77119
MIBK10234
Molybdenum34532
MSA34567
MTBE34606
n-Butylbenzene61104
n-Propylbenzene77108
N_NO35986
Na+29470
Naphthalene71450
NH4+29562
Nickel120129
Nitrate63095
Nitric Acid17728
Nitrite58221
Nitrous Acid12318
NO339241
Nonane76954
o-Tolualdehyde7290
o-Xylene77082
OC5871
OC(A)12298
OC(B)12298
OC(corr)12297
OC_R11783
OC_RA5872
OC_RB5871
OC_T11783
OC111783
OC1(A)12298
OC1(B)12298
OC211783
OC2(A)12298
OC2(B)12298
OC311783
OC3(A)12298
OC3(B)12298
OC411783
OC4(A)12298
OC4(B)12298
OCDD3076
OCDF3075
OCS1614
Octane77112
Oxalate42383
p-Cymene76878
p-Tolualdehyde9080
P5CDD3076
P5CDF3076
PCB-105302
PCB-114302
PCB-118302
PCB-123302
PCB-126302
PCB-156302
PCB-157302
PCB-167302
PCB-169302
PCB-189302
PCB-77302
PCB-81302
PCP1598
Pentane77097
Perylene9877
Phenanthrene9889
Phosphate39032
PM2.5-1014424
POC(A)12298
POC(B)6305
POC_R11783
POC_T11783
Potassium119604
Propane77034
Propionaldehyde13399
Propionate34567
Propylene77061
Pyrene9891
Retene6779
Rubidium82705
sec-Butylbenzene54663
Selenium119549
Silicon85595
Silver34470
SO439246
Sodium33456
Strontium140551
Styrene74513
Sulfur47350
Sulphate50837
Sulphur38250
Sulphur Dioxide24502
T_NO35993
TC11783
TC(A)12298
TC(B)6305
TC(corr)12297
TCDD3076
TCDF3076
TEQ3076
tert-Butylbenzene37364
Tetrachloroethylene70497
Thallium29991
Tin114287
Titanium111408
Toluene77097
trans-1,2-Dichloroethylene39208
trans-1,2-Dimethylcyclohexane54626
trans-1,3-Dichloropropene39022
trans-1,4-Dimethylcyclohexane56374
trans-2-Butene77114
trans-2-Heptene36398
trans-2-Hexene76863
trans-2-Octene44719
trans-2-Pentene77090
trans-3-Heptene34355
trans-3-Methyl-2-Pentene74810
trans-4-Methyl-2-Pentene45767
Trichloroethylene76930
Triphenylene7965
Tungsten3138
Undecane77077
Uranium20905
Valeraldehyde10292
Vanadium120111
Vinylchloride70498
Zinc120132
</details>

Database Design

I am using a normalized relational PostgreSQL database to store the data. I have chosen to hold the continuous data and the integrated data in separate tables to improve performance. I don't think there is a frequent need to query the data in both tables at the same time. The following diagram illustrates the schema design.

schema diagram

Known Issues

This repository makes use of GitHub's built-in issue tracker. You can view all open issues here. Most of the issues are problems with the data files that are distributed from the NAPS website.

Developer Notes

Legal Stuff

Copyright (c) 2024 David Fortin

This software (NAPS Data Analysis Toolbox) is provided by David Fortin under the MIT License, meaning you are free to use it however you want, as long as you include the original copyright notice (above) and license notice in any copy you make. You just can't hold me liable in case something goes wrong. License details can be read here

The data itself is provided by the National Air Pollution Surveillance (NAPS) program, which is run by the Analysis and Air Quality Section of Environment and Climate Change Canada. The data is licensed under the terms of the Canadian Open Government Licence and can be freely re-published under those terms.