diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/6-ACT-TRACER-Dust.ipynb b/Tutorials/2024_PNNL_Atmospheric_Course/6-ACT-TRACER-Dust.ipynb new file mode 100644 index 00000000..faea7c43 --- /dev/null +++ b/Tutorials/2024_PNNL_Atmospheric_Course/6-ACT-TRACER-Dust.ipynb @@ -0,0 +1,731 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "950099de-bfc3-4e1d-85a4-0184030e85a8", + "metadata": {}, + "source": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \"TRACER\n", + " \n", + "

Atmospheric Radiation Measurement user facility (ARM)

\n", + "

TRacking Aerosol Convection interations ExpeRiment (TRACER)

\n", + "

July 16-19, 2022 Dust Event

\n", + " Notebook for data exploration of ARM aerosol and lidar data.
\n", + " Corresponding Author: Adam Theisen (atheisen@anl.gov)\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "830e2e64-3205-41cd-8247-2fa3905f6106", + "metadata": {}, + "source": [ + "## Overview\n", + "The first notebook in this series was an introduction to some of the features in ACT. In this notebook, we will be exploring different types and data and bringing it all together to get a view of this dust event.\n", + "\n", + "1. Micropulse Lidar (MPL) Data\n", + "1. Aerodynamic Particle Sizer (APS) Data\n", + "1. Putting it All Together\n", + "1. Questions for the User to Explore" + ] + }, + { + "cell_type": "markdown", + "id": "74e672b9-ef14-4f01-be19-a222f5ea1573", + "metadata": { + "tags": [] + }, + "source": [ + "## Prerequisites\n", + "This notebook will rely heavily on Python and the [Atmospheric data Community Toolkit (ACT)](https://github.com/ARM-DOE/ACT). Don't worry if you don't have experience with either, this notebook will walk you though what you need to know.\n", + "\n", + "You will also need an account and token to download data using the ARM Live webservice. Navigate to the [webserive information page](https://adc.arm.gov/armlive/) and log in to get your token. Your account username will be your ARM username.\n", + "\n", + "| Concepts | Importance | Notes |\n", + "| --- | --- | --- |\n", + "| [ACT](https://github.com/ARM-DOE/ACT) | Helpful | |\n", + "\n", + "- **Time to learn**: 60 Minutes\n", + "- **System requirements**:\n", + " - Python 3.11 or latest\n", + " - ACT v1.5.0 or latest\n", + " - numpy\n", + " - xarray\n", + " - matplotlib" + ] + }, + { + "cell_type": "markdown", + "id": "f89921ee-514a-4e11-859a-4858ed7354ab", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "0de3c05a-6e49-4859-850b-32c989f2cc33", + "metadata": {}, + "source": [ + "## Imports\n", + "Let's get started with some data! But first, we need to import some libraries." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5b00201-8c78-4ef5-b02f-57e55021f5d6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import act\n", + "import numpy as np\n", + "import xarray as xr\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "id": "3647028a-cf78-436a-be33-6a0148474bf6", + "metadata": {}, + "source": [ + "## Micropulse Lidar (MPL) Data\n", + "ARM has many value-added products (VAPs) that apply corrections, additional quality control, retrievals, and more. These are a great way to get the data if you don't want to do the added processing yourself. In this case, there is a VAP for the MPL with the datastream hou30smplcmask1zwangM1.c1 that you could utilize. For this case though, let's download the instrument data and correct it ourselves using ACT." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dc01deb-8e97-4e45-9efb-196b37ca7386", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Set your username and token here!\n", + "username = 'YourUserName'\n", + "token = 'YourToken'\n", + "\n", + "# Set the datastream and start/enddates\n", + "datastream = 'houmplpolfsM1.b1'\n", + "startdate = '2022-07-16'\n", + "enddate = '2022-07-16'\n", + "\n", + "# Use ACT to easily download the data. Watch for the data citation! Show some support\n", + "# for ARM's instrument experts and cite their data if you use it in a publication\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "acdaa696-ebb5-4bbe-8d1e-a4c66f524964", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's read in the data using ACT and check out the data\n", + "ds_mpl = act.io.read_arm_netcdf(result)\n", + "\n", + "# Now we can correct the data\n", + "ds_mpl = act.corrections.correct_mpl(ds_mpl)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cd2407a-7f6c-4e86-b677-e1da101f1786", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's plot up the data to see what it looks like. But first,\n", + "# if you look at the variables, you would see the the variable\n", + "# we're going to plot has range_bins as it's 2nd dimension.\n", + "# We want it to be height so we have to swap some coordinates around\n", + "ds_mpl.coords['height'] = ds_mpl.height\n", + "ds_mpl = ds_mpl.swap_dims({'range_bins': 'height'})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "477de074-9465-47eb-a658-decf6768b077", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# It's a lot of data, so it will take some time!\n", + "display = act.plotting.TimeSeriesDisplay(ds_mpl, figsize=(10, 6))\n", + "display.plot('signal_return_co_pol', cb_friendly=True, vmin=-20, vmax=20)\n", + "\n", + "# This instrument collects data over 30 km so let's constrain\n", + "# this to just the lower 5 km\n", + "display.set_yrng([0, 5])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73c9bcfd-7330-4126-b50d-50556c8c8532", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's look at the cross polarization to get some more information\n", + "# It's a lot of data, so it will take some time!\n", + "display = act.plotting.TimeSeriesDisplay(ds_mpl, figsize=(10, 6))\n", + "display.plot('signal_return_cross_pol', cb_friendly=True, vmin=-20, vmax=20)\n", + "\n", + "# This instrument collects data over 30 km so let's constrain\n", + "# this to just the lower 5 km\n", + "display.set_yrng([0, 5])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "a93b725a-3216-4eca-8ad0-d9e9e31b1372", + "metadata": {}, + "source": [ + "## Aerosol Particle Size Data\n", + "Dust particles are generally under 10 µm or 10,000 nm and ARM has a variety of instruments that measure across different ranges. The chart below shows the ranges for each instrument and where we can expect to see the dust particles.\n", + "\n", + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2991b44-a831-4879-b655-e2d7e5fef28b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Download the data as before\n", + "datastream = 'houaosapsM1.b1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "\n", + "# and read it in\n", + "ds_aps = act.io.arm.read_arm_netcdf(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f2c2c57-09c9-44d6-8098-8a414ba0fb0d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's plot up the size distribution and number concentration\n", + "# These data are taken every second so it will take a little bit\n", + "display = act.plotting.TimeSeriesDisplay(ds_aps, subplot_shape=(2,), figsize=(10,8))\n", + "display.plot('total_N_conc', subplot_index=(0,))\n", + "display.day_night_background(subplot_index=(0,))\n", + "display.plot('dN_dlogDp', subplot_index=(1,), vmax=40)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "fc59f297-718c-4157-9acc-a44a4b801a91", + "metadata": {}, + "source": [ + "## Putting it All Together\n", + "Let's start pulling these data together into the same plots so we can see what's going on." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20da29fc-2009-4c7d-9490-301d99eb2f20", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's start fresh and get all the data and maybe expand the dates\n", + "startdate = '2022-07-10'\n", + "enddate = '2022-07-20'\n", + "\n", + "# MPL - Let's try the VAP this time\n", + "datastream = 'hou30smplcmask1zwangM1.c1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_mpl = act.io.arm.read_arm_netcdf(result)\n", + "\n", + "# APS\n", + "datastream = 'houaosapsM1.b1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_aps = act.io.arm.read_arm_netcdf(result)\n", + "\n", + "# SMPS\n", + "datastream = 'houaossmpsM1.b1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_smps = act.io.arm.read_arm_netcdf(result)\n", + "\n", + "#ACSM\n", + "datastream = 'houaosacsmM1.b2'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_acsm = act.io.arm.read_arm_netcdf(result)\n", + "\n", + "#PSAP\n", + "datastream = 'houaospsap3w1mM1.b1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_psap = act.io.arm.read_arm_netcdf(result)\n", + "\n", + "#SP2\n", + "datastream = 'houaossp2bc60sM1.b1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_sp2 = act.io.arm.read_arm_netcdf(result)\n", + "\n", + "# AOSMET\n", + "datastream = 'houmetM1.b1'\n", + "result = act.discovery.download_arm_data(username, token, datastream, startdate, enddate)\n", + "ds_met = act.io.arm.read_arm_netcdf(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b2770c8-f40f-4847-b426-02d69bd9529b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Before we proceed to plotting, let's reduce the MPL data down a little bit\n", + "# This will remove all data where heights are greater than 5\n", + "ds_mpl = ds_mpl.where(ds_mpl.height <= 5, drop=True)\n", + "\n", + "# This will resample to 1 minute\n", + "ds_mpl = ds_mpl.resample(time='1min').nearest()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db93b1f6-a836-4c28-b7a9-87053d5f9963", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's not forget about QCing the data!\n", + "# We can remove all the bad data from each aerosol dataset\n", + "ds_aps.clean.cleanup()\n", + "ds_aps = act.qc.arm.add_dqr_to_qc(ds_aps)\n", + "ds_aps.qcfilter.datafilter(rm_assessments=['Bad'], del_qc_var=False)\n", + "\n", + "ds_smps.clean.cleanup()\n", + "ds_smps = act.qc.arm.add_dqr_to_qc(ds_smps)\n", + "ds_smps.qcfilter.datafilter(rm_assessments=['Bad'], del_qc_var=False)\n", + "\n", + "ds_acsm.clean.cleanup()\n", + "ds_acsm = act.qc.arm.add_dqr_to_qc(ds_acsm)\n", + "ds_acsm.qcfilter.datafilter(rm_assessments=['Bad'], del_qc_var=False)\n", + "\n", + "ds_sp2.clean.cleanup()\n", + "ds_sp2 = act.qc.arm.add_dqr_to_qc(ds_sp2)\n", + "ds_sp2.qcfilter.datafilter(rm_assessments=['Bad'], del_qc_var=False)\n", + "\n", + "ds_psap.clean.cleanup()\n", + "ds_psap = act.qc.arm.add_dqr_to_qc(ds_psap)\n", + "ds_psap.qcfilter.datafilter(rm_assessments=['Bad'], del_qc_var=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "af7d3e43-1607-4037-961b-8c09ea308f55", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# We can pass a dictionary to the display objects with multiple datasets\n", + "# So let's plot all this up!\n", + "display = act.plotting.TimeSeriesDisplay({'aps': ds_aps, 'mpl': ds_mpl, 'smps': ds_smps, 'acsm': ds_acsm, 'psap': ds_psap, 'sp2': ds_sp2, 'met': ds_met},\n", + " subplot_shape=(7,), figsize=(10,18))\n", + "\n", + "# MPL Plot\n", + "# Variable names of interest linear_depol_ratio, linear_depol_snr, backscatter_snr\n", + "display.plot('linear_depol_ratio', dsname='mpl', subplot_index=(0,), cb_friendly=True)\n", + "display.set_yrng([0, 3], subplot_index=(0,))\n", + "\n", + "# APS Plot\n", + "display.plot('total_N_conc', dsname='aps', subplot_index=(1,))\n", + "display.day_night_background(dsname='aps', subplot_index=(1,))\n", + "\n", + "# SMPS Plot\n", + "display.plot('total_N_conc', dsname='smps', subplot_index=(2,))\n", + "display.day_night_background(dsname='smps', subplot_index=(2,))\n", + "\n", + "# ACSM plot\n", + "display.plot('sulfate', dsname='acsm', subplot_index=(3,), label='sulfate')\n", + "display.plot('nitrate', dsname='acsm', subplot_index=(3,), label='nitrate')\n", + "display.plot('ammonium', dsname='acsm', subplot_index=(3,), label='ammonium')\n", + "display.plot('chloride', dsname='acsm', subplot_index=(3,), label='chloride')\n", + "display.plot('total_organics', dsname='acsm', subplot_index=(3,), label='total_organics')\n", + "\n", + "display.day_night_background(dsname='acsm', subplot_index=(3,))\n", + "\n", + "# SP2 Plot\n", + "display.plot('sp2_rbc_conc', dsname='sp2', subplot_index=(4,))\n", + "display.day_night_background(dsname='sp2', subplot_index=(4,))\n", + "\n", + "# PSAP Plot\n", + "display.plot('Ba_B_Weiss', dsname='psap', subplot_index=(5,))\n", + "display.day_night_background(dsname='psap', subplot_index=(5,))\n", + "\n", + "# MET Wind Plot\n", + "display.plot('wdir_vec_mean', dsname='met', subplot_index=(6,), linestyle='', marker='.')\n", + "#display.plot('wspd_vec_mean', dsname='met', subplot_index=(6,), marker=None, secondary_y=True, color='orange', label='Wind Speed')\n", + "display.day_night_background(dsname='met', subplot_index=(6,))\n", + "\n", + "plt.subplots_adjust(hspace=0.3)\n", + "plt.legend()\n", + "plt.savefig('./images/output.png')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c1b979c8-f9c5-4420-8845-9b73b70fbf1b", + "metadata": {}, + "source": [ + "#### Check this out\n", + "[Floutsi et al 2023](https://amt.copernicus.org/articles/16/2353/2023/) has a great paper that shows how different aerosols can have different ratios. In [Figure 3](https://amt.copernicus.org/articles/16/2353/2023/amt-16-2353-2023-f03-web.png), you can see that Sharan dust has a slightly different signal than Central Asian dust." + ] + }, + { + "cell_type": "markdown", + "id": "81e99004-3e0b-474e-b016-8e5e79a161d0", + "metadata": {}, + "source": [ + "### Try more data!\n", + "\n", + "Go back and adjust the start/end date around this period and see how things change! You can also try adding in some of the other instruments like the OPC (houaosopcM1.b1: calc_dust_weight or total_N_conc) or the NEPHDRY (houaosnephdry1mM1.b1: Bs_B_Dry_Neph3W). You can find a full list of data products on the ARM TRACER [website](https://www.arm.gov/research/campaigns/amf2021tracer#:~:text=Order%20Data-,HOU%20DATA%20SOURCES,-NAME)" + ] + }, + { + "cell_type": "markdown", + "id": "dcef61c0-becf-4f59-a92a-7707997877ae", + "metadata": {}, + "source": [ + "## Advanced Visualizations and Processing\n", + "Let's try and dive into the data a little more and see if there are any patterns in the data based on the direction of the wind." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "53326c0d-df46-4ce6-b0a1-a87e6bd90641", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# We already should have the data loaded up so let's explore with some data roses\n", + "# First we need to combine data and to do that, we need to get it on the same time grid\n", + "ds_combined = xr.merge([ds_met.resample(time='30min').nearest(), ds_acsm.resample(time='30min').nearest()], compat='override')\n", + "\n", + "# Plot out the data rose using the WindRose display object\n", + "display = act.plotting.WindRoseDisplay(ds_combined)\n", + "display.plot_data('wdir_vec_mean', 'wspd_vec_mean', 'sulfate', num_dirs=15, plot_type='line', line_plot_calc='mean')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8fe0eb42-34d3-4e58-ac3b-49ac6c0453d8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# First we need to combine data and to do that, we need to get it on the same time grid\n", + "ds_combined = xr.merge([ds_met.resample(time='1min').nearest(), ds_sp2.resample(time='1min').nearest()], compat='override')\n", + "\n", + "# Plot out the data rose using the WindRose display object\n", + "display = act.plotting.WindRoseDisplay(ds_combined)\n", + "# Let's try a different type of data rose that will show the mean Black Carbon Concentration\n", + "# depending on wind direction and speed\n", + "display.plot_data('wdir_vec_mean', 'wspd_vec_mean', 'sp2_rbc_conc', num_dirs=15, plot_type='contour', contour_type='mean')\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "fa7ae058-c48d-48da-bbe9-fb2ce1c6c26f", + "metadata": {}, + "source": [ + "### Checkout the area\n", + "The AMF was deployed at [La Porte Municipal Airport](https://www.google.com/maps/place/Airport+Blvd/@29.6652378,-95.0466689,9165m/data=!3m1!1e3!4m7!3m6!1s0x863f6020e5e0ea21:0x792ee34f8eaac3e8!4b1!8m2!3d29.6663473!4d-95.0578571!16s%2Fg%2F1wbf_smp?entry=ttu). Check out the google map and see if this mapes sense!\n", + "\n", + "### Now back to the dust event!\n", + "Let's see if we can look at the lowest layers in the MPL data and see how they compare to the APS data. For this, we can use simple matplotlib plots to investigate as well." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1560e9f0-a398-4a05-a438-9e0216ca52b1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's take a slice of the data to figure out where the signal\n", + "# may be showing up in the profile\n", + "data = ds_mpl['linear_depol_ratio'].values[:, 0:10]\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.plot(ds_mpl['time'], data)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dadae53c-a37d-424b-9bb2-5c2def73ec86", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's do it again and add in the APS data\n", + "# Other variables to try: backscatter_snr, linear_depol_snr, linear_depol_ratio\n", + "data = ds_mpl['linear_depol_ratio'].values[:, 4]\n", + "\n", + "fig, ax = plt.subplots(figsize=(12,6))\n", + "ax.plot(ds_mpl['time'], data, label='MPL LDR')\n", + "\n", + "ax2 = ax.twinx()\n", + "ax2.plot(ds_aps['time'], ds_aps['total_N_conc'], color='purple', label='APS')\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e2d172c-c383-4d4f-917a-59338a82d00d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Let's try a scatter plot using matplotlib\n", + "# First we need the data on the same time scale\n", + "ds_mpl2 = ds_mpl.resample(time='30s').nearest()\n", + "ds_aps2 = ds_aps.resample(time='30s').nearest()\n", + "\n", + "ds = xr.merge([ds_mpl2, ds_aps2], compat='override')\n", + "\n", + "# Other variables to try: backscatter_snr, linear_depol_snr, linear_depol_ratio\n", + "data = ds['linear_depol_snr'].values[:, 4]\n", + "\n", + "fig, ax = plt.subplots(figsize=(10, 8))\n", + "ax.scatter(data, ds['total_N_conc']) # , c=ds['linear_depol_snr'].values[:, 4])\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "4178c3dd-4a15-4e05-839c-b5fdf96c0efd", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "ec6021b0", + "metadata": {}, + "source": [ + "### Excercises\n", + "Here are a couple additional excercises that users can work through on their own time." + ] + }, + { + "cell_type": "markdown", + "id": "cbc5bd72", + "metadata": {}, + "source": [ + "#### Time series of ratios of fine particles vs. coarse particles using SMPS and APS data\n", + "Using the SMPS (ds_smps) and APS (ds_aps) data, can you calculate a ratio of fine to coarse particles? Remember, that this data would need to be on the same timestep." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "830f729b", + "metadata": {}, + "outputs": [], + "source": [ + "# First, let's resample to 1-minute averages. Note, that this may take some time with this much data.\n", + "# The other option is to grab the nearest value\n", + "ds_smps_1m = ds_smps.resample(time='1min').nearest()\n", + "ds_aps_1m = ds_aps.resample(time='1min').nearest()\n", + "\n", + "# But wait, the concentration variables have the same name! We need to rename\n", + "ds_aps_1m = ds_aps_1m.rename_vars({'total_N_conc': 'total_N_conc_aps'})\n", + "ds_merge = xr.merge([ds_smps_1m, ds_aps_1m], compat='override')\n", + "\n", + "# Next, let's calculate the ratio\n", + "ratio = ds_merge['total_N_conc'].values / ds_merge['total_N_conc_aps'].values\n", + "\n", + "# Then we can add it back to the Dataset as a variable\n", + "atts = {'units': '1', 'long_name': 'Ration of SMPS to APS total_N_conc'}\n", + "da = xr.DataArray(ratio, coords=ds_merge['total_N_conc'].coords, dims=ds_merge['total_N_conc'].dims, attrs=atts)\n", + "ds_merge['smps_aps_ratio'] = da\n", + "\n", + "# And then plot it wil ACT!\n", + "display = act.plotting.TimeSeriesDisplay(ds_merge, figsize=(12, 10), subplot_shape=(3,))\n", + "display.plot('smps_aps_ratio', subplot_index=(0,))\n", + "display.plot('total_N_conc', subplot_index=(1,))\n", + "display.plot('total_N_conc_aps', subplot_index=(2,))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "1dea39c3", + "metadata": {}, + "source": [ + "#### Compare Chemical Composition Between Events\n", + "\n", + "Make a chart of aerosol composition on July 12, 13, and compare it to that from 17-18. This will require subsetting the ds_acsm data and plotting it using Matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9c2181f", + "metadata": {}, + "outputs": [], + "source": [ + "# First subset the data for both sets\n", + "ds_acsm_12 = ds_acsm.sel(time=slice('2022-07-12', '2022-07-13'))\n", + "ds_acsm_17 = ds_acsm.sel(time=slice('2022-07-17', '2022-07-18'))\n", + "\n", + "# Run through and get data\n", + "labels = ['total_organics', 'sulfate', 'nitrate', 'ammonium', 'chloride']\n", + "data12 = []\n", + "data17 = []\n", + "for label in labels:\n", + " data12.append(float(ds_acsm_12[label].mean().values.tolist()))\n", + " data17.append(float(ds_acsm_17[label].mean().values.tolist()))\n", + " \n", + "# Pie charts use values that add up to 100% so we have to adjust the data\n", + "#data12 = data12 / np.sum(data12)\n", + "#data17 = data17 / np.sum(data17)\n", + "\n", + "fig, ax = plt.subplots(1,1, figsize=(12,6))\n", + "ax.bar(range(len(labels)), data12, label='July 12-13')\n", + "plt.xticks(range(len(labels)), labels)\n", + "\n", + "ax.bar(range(len(labels)), data17, label='July 17-18')\n", + "plt.xticks(range(len(labels)), labels)\n", + "plt.legend()\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "id": "dd37d2fc", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "1160da20-2f54-43c0-aeea-d7a306d37f6d", + "metadata": {}, + "source": [ + "## Additional Questions for the User to Explore\n", + "1. Can you improve these matplotlib plots to make them more readable?\n", + "1. Are there other variables that you would be interested in for the data roses?\n", + "1. We looked at relationships between the MPL and APS, are there other sets of instruments that might have relationships? (SP2 and PSAP?)\n", + "\n", + "#### More Advanced\n", + "1. Can we use a machine learning toolkit like scikit-learn to cluster the MPL/APS data?\n", + "1. Could we get relationships between those clusters or a classification of what it is (smoke, dust, pollution)?" + ] + }, + { + "cell_type": "markdown", + "id": "a810279c-09ba-49e7-b517-e791c350883b", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "0eaee516-805e-46ed-94e9-1d115bcebb6c", + "metadata": {}, + "source": [ + "## Next Steps\n", + "This notebook showed users how they can explore multiple different datasets using ACT. The next steps are for the users to continue exploring and diving into the data and the questions posed at the end!\n", + "\n", + "### Data Used in this Notebook\n", + "Ermold, B., & Flynn, C. Particle Soot Absorption Photometer (AOSPSAP3W1M). Atmospheric Radiation Measurement (ARM) User Facility. https://doi.org/10.5439/1225037\n", + "\n", + "Jackson, R., & Sedlacek, A. Single Particle Soot Photometer (AOSSP2BC60S). Atmospheric Radiation Measurement (ARM) User Facility. https://doi.org/10.5439/1807910\n", + "\n", + "Kuang, C., & Singh, A. Aerodynamic Particle Sizer (AOSAPS). Atmospheric Radiation Measurement (ARM) User Facility. https://doi.org/10.5439/1407135\n", + "\n", + "Kyrouac, J., & Shi, Y. Surface Meteorological Instrumentation (MET). Atmospheric Radiation Measurement (ARM) User Facility. https://doi.org/10.5439/1786358\n", + "\n", + "Muradyan, P., Cromwell, E., Koontz, A., & Coulter, R. Micropulse Lidar (MPLPOLFS). Atmospheric Radiation Measurement (ARM) User Facility. https://doi.org/10.5439/1320657\n", + "\n", + "Sivaraman, C., Flynn, D., Riihimaki, L., & Comstock, J. Cloud mask from Micropulse Lidar (30SMPLCMASK1ZWANG). Atmospheric Radiation Measurement (ARM)\n", + "User Facility. https://doi.org/10.5439/1508389\n", + "\n", + "Zawadowicz, M., & Howie, J. Aerosol Chemical Speciation Monitor (AOSACSM). Atmospheric Radiation Measurement (ARM) User Facility. https://doi.org/10.5439/1762267" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/GitHub-logo.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/GitHub-logo.png new file mode 100644 index 00000000..c9904ee8 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/GitHub-logo.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/GitHubJoin.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/GitHubJoin.png new file mode 100644 index 00000000..b92b9473 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/GitHubJoin.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_Fork.jpeg b/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_Fork.jpeg new file mode 100644 index 00000000..a2722961 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_Fork.jpeg differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_ForkDest.jpeg b/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_ForkDest.jpeg new file mode 100644 index 00000000..43067050 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_ForkDest.jpeg differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_ForkPost.jpeg b/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_ForkPost.jpeg new file mode 100644 index 00000000..7683b472 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/Github_ForkPost.jpeg differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/add-analysis-script.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/add-analysis-script.png new file mode 100644 index 00000000..4514ccc1 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/add-analysis-script.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/aerosol-mentors-repo-screenshot.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/aerosol-mentors-repo-screenshot.png new file mode 100644 index 00000000..0fbd22fd Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/aerosol-mentors-repo-screenshot.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/aerosol_sizing.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/aerosol_sizing.png new file mode 100644 index 00000000..d17ab375 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/aerosol_sizing.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/arm_resources.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/arm_resources.png new file mode 100644 index 00000000..31943906 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/arm_resources.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/binder-highlight.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/binder-highlight.png new file mode 100644 index 00000000..77fde66d Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/binder-highlight.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/codecells.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/codecells.png new file mode 100644 index 00000000..f6cd8774 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/codecells.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/commit-python-script-github-ui.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/commit-python-script-github-ui.png new file mode 100644 index 00000000..b0ac422e Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/commit-python-script-github-ui.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/console.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/console.png new file mode 100644 index 00000000..41d7e88d Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/console.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/create-new-branch-github-ui.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/create-new-branch-github-ui.png new file mode 100644 index 00000000..50a68edc Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/create-new-branch-github-ui.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/extensions.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/extensions.png new file mode 100644 index 00000000..e0bdca19 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/extensions.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/fetch-upstream-github.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/fetch-upstream-github.png new file mode 100644 index 00000000..bdba9fe9 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/fetch-upstream-github.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/git_clone_notebooks.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/git_clone_notebooks.png new file mode 100644 index 00000000..7f47c5a8 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/git_clone_notebooks.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/interface_labeled.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/interface_labeled.png new file mode 100644 index 00000000..59deea74 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/interface_labeled.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/locate-github-branches-web.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/locate-github-branches-web.png new file mode 100644 index 00000000..cb46130e Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/locate-github-branches-web.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/magics.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/magics.png new file mode 100644 index 00000000..65b74c5e Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/magics.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown.png new file mode 100644 index 00000000..12ad4b4a Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown_eq.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown_eq.png new file mode 100644 index 00000000..9314fb2b Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown_eq.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown_eq_inline.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown_eq_inline.png new file mode 100644 index 00000000..810e931b Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/markdown_eq_inline.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/move-to-co-directory.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/move-to-co-directory.png new file mode 100644 index 00000000..c074c613 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/move-to-co-directory.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/move-to-python-directory.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/move-to-python-directory.png new file mode 100644 index 00000000..ecfd23b8 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/move-to-python-directory.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/notebook-interface_labeled.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/notebook-interface_labeled.png new file mode 100644 index 00000000..0525c649 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/notebook-interface_labeled.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/on-new-branch-github-ui.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/on-new-branch-github-ui.png new file mode 100644 index 00000000..9815dd23 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/on-new-branch-github-ui.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/open-pull-request-github-ui.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/open-pull-request-github-ui.png new file mode 100644 index 00000000..57f9301d Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/open-pull-request-github-ui.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/output.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/output.png new file mode 100644 index 00000000..f11538bb Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/output.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/raw.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/raw.png new file mode 100644 index 00000000..9d50a34a Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/raw.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/running-tabs-kernels.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/running-tabs-kernels.png new file mode 100644 index 00000000..f3c63f93 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/running-tabs-kernels.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/special_vars.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/special_vars.png new file mode 100644 index 00000000..72812f4d Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/special_vars.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/submit-pull-request-github-ui.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/submit-pull-request-github-ui.png new file mode 100644 index 00000000..7f1d9250 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/submit-pull-request-github-ui.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/submit-pull-request.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/submit-pull-request.png new file mode 100644 index 00000000..615edf47 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/submit-pull-request.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/table-contents.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/table-contents.png new file mode 100644 index 00000000..24dbd675 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/table-contents.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/terminal.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/terminal.png new file mode 100644 index 00000000..30693eae Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/terminal.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/txt-editor.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/txt-editor.png new file mode 100644 index 00000000..07ff3d66 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/txt-editor.png differ diff --git a/Tutorials/2024_PNNL_Atmospheric_Course/images/view-compare-pull-request-github-ui.png b/Tutorials/2024_PNNL_Atmospheric_Course/images/view-compare-pull-request-github-ui.png new file mode 100644 index 00000000..d207e107 Binary files /dev/null and b/Tutorials/2024_PNNL_Atmospheric_Course/images/view-compare-pull-request-github-ui.png differ