Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add P3 examples #52

Merged
merged 30 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2f39e0e
A first comparison with P3 humidity data
RobertPincus Apr 27, 2021
2e7e5e3
Further explanations about the P3 humidity comparison
RobertPincus Apr 27, 2021
3dbbe35
Update Python requirements. Add P3 description and photo
RobertPincus Apr 27, 2021
503f696
Add P-3 W-band radar example
RobertPincus Apr 27, 2021
12701c1
jpg -> jpeg. Having a local stack that worked would be helpful.
RobertPincus Apr 27, 2021
dee00e6
Adding figures showing AXBT and SWIFT measurements of ocean temperature
RobertPincus Apr 27, 2021
acac4cc
Adding cartopy for static maps
RobertPincus Apr 27, 2021
fd1a8cc
install cartopy via conda using an environment.yml file. Switch book-…
RobertPincus Apr 27, 2021
2b2e333
Code bug fix and more complete text for AXBTs
RobertPincus Apr 27, 2021
76a3936
Shorten titles
RobertPincus Apr 27, 2021
aa5e288
Add P3 WSRA example, update copyright year
RobertPincus Apr 27, 2021
145679d
Hide cells showing how to set up maps
RobertPincus Apr 27, 2021
31aa0e5
Get conda info to help debug CI
RobertPincus Apr 27, 2021
e3eb9c5
Explicitly activate conda environment
RobertPincus Apr 27, 2021
becf006
conda activate -> source activate
RobertPincus Apr 27, 2021
4830c7b
Need to specify bash perhaps
RobertPincus Apr 27, 2021
eb51a13
pylab inline -> matplotlib inline
RobertPincus Apr 28, 2021
1343992
Updating modules imported in P-3 examples. Not clear how this was wor…
RobertPincus Apr 28, 2021
b4df2c1
Add flight tracks
RobertPincus Apr 28, 2021
6bac1bb
Remove unneeded imports
RobertPincus Apr 30, 2021
9a1f4f7
Add cartopy to requirements.txt
RobertPincus Apr 30, 2021
869045c
Merge branch 'add-citations' into add-p3-examples
RobertPincus May 3, 2021
9bfaa05
Update P-3 page to use citations
RobertPincus May 3, 2021
1a6facc
Update local running info to describe conda use.
RobertPincus May 3, 2021
6d1dc76
Merge pull request #2 from eurec4a/master
RobertPincus May 3, 2021
82c3bee
Use book-wide style where possible
RobertPincus May 4, 2021
b58687c
Limit line lengths to 100 char (from review)
RobertPincus May 4, 2021
d82bef7
More graceful treatment of dates for P-3 flights,
RobertPincus May 4, 2021
c15adb9
Cleanup and one excellent efficiency suggestion from code review, tha…
RobertPincus May 5, 2021
c2d9e62
Merge remote-tracking branch 'upstream/master' into add-p3-examples
RobertPincus May 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .github/workflows/buildbook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,31 @@ on: [push, pull_request]

jobs:
build:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8]
defaults:
run:
shell: bash -l {0}

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Set up Python modules with conda
uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: how_to_eurec4a
environment-file: environment.yml
python-version: ${{ matrix.python-version }}
auto-activate-base: false
- name: build book
run: |
jupyter-book build -W -n --keep-going how_to_eurec4a
conda info
jupyter-book build -W -n --keep-going how_to_eurec4a
- name: Archive build artifacts
if: always()
uses: actions/upload-artifact@v2
Expand Down
8 changes: 8 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: how_to_eurec4a
dependencies:
- python>=3.7
- anaconda
- pip
- pip:
- -r file:requirements.txt
- cartopy
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
Binary file added how_to_eurec4a/Miss-Piggy.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions how_to_eurec4a/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

#######################################################################################
# Book settings
title : How to EUREC4A # The title of the book. Will be placed in the left navbar.
author : EUREC4A community # The author of the book
copyright : "2020" # Copyright year to be placed in the footer
title : How to EUREC4A # The title of the book. Will be placed in the left navbar.
author : EUREC4A community # The author of the book
copyright : "2021" # Copyright year to be placed in the footer
logo : logo_pyeurec4a.png # A path to the book logo
repository:
url : https://github.com/eurec4a/how_to_eurec4a
Expand Down
7 changes: 7 additions & 0 deletions how_to_eurec4a/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
- file: bacardi
- file: wales
- file: hamp_comparison
- file: pthree
sections:
- file: p3_flight_tracks
- file: p3_humidity_comparison
- file: p3_wband_radar
- file: p3_AXBTs
- file: p3_wsra
- file: meteor
sections:
- file: meteor_cloudradar
Expand Down
205 changes: 205 additions & 0 deletions how_to_eurec4a/p3_AXBTs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.12
jupytext_version: 1.7.1
kernelspec:
display_name: Python 3
language: python
name: python3
---

# Ocean temperatures: AXBTs and SWIFT buoys

During EUREC4A/ATOMIC the P-3 deployed 165 Airborne eXpendable BathyThermographs (AXBTs)
to measure profiles of ocean temperature. (These are kind of the oceanic equivalent of
dropsondes but they don't measure salinity.) Often these were dropped around
other ocean temperature measurements - for example the autonomous
Surface Wave Instrument Floats with Tracking (SWIFT) buoys deployed from the
Ron Brown by Elizabeth Thompson of NOAA and her colleagues.

Let's take a look at some of the AXBT measurements and how they compare to the
SWIFTs.

```{code-cell} ipython3
import xarray as xr
import numpy as np
import datetime

import matplotlib.pyplot as plt
import seaborn as sns
import colorcet as cc
%matplotlib inline

import eurec4a
cat = eurec4a.get_intake_catalog()
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
```
Mapping takes quite some setup. Maybe this should become part of the `eurec4a` Python module.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably. However I am yet undecided if the eurec4a module should grow larger than accessing EUREC4A data and metadata. I think functions like those should either be in a generic campaign data analysis package or we should make chapters of the book importable (#28).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the best way forward. All the mapping stuff in my contributions comes from Bjorn in any case. It does seem strange to have to repeat code in every document independently.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to go towards importable book chapters, but I am afraid that I won't be able to do that right now... Thus for now, we probably need to stick a little with repeated code.


```{code-cell} ipython3
---
tags: [hide-cell]
---
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib.offsetbox import AnchoredText

import cartopy as cp
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.feature import LAND
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from mpl_toolkits.axes_grid1 import make_axes_locatable
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
def set_up_map(plt, lon_w = -60.5, lon_e = -49, lat_s = 10, lat_n = 16.5):
ax = plt.axes(projection=ccrs.PlateCarree())
# Defining boundaries of the plot
ax.set_extent([lon_w,lon_e,lat_s,lat_n]) # lon west, lon east, lat south, lat north
ax.coastlines(resolution='10m',linewidth=1.5,zorder=1);
ax.add_feature(LAND,facecolor='0.9')
return(ax)

def ax_to_map(ax, lon_w = -60.5, lon_e = -49, lat_s = 10, lat_n = 16.5):
# Defining boundaries of the plot
ax.set_extent([lon_w,lon_e,lat_s,lat_n]) # lon west, lon east, lat south, lat north
ax.coastlines(resolution='10m',linewidth=1.5,zorder=1);
ax.add_feature(LAND,facecolor='0.9')
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved

def add_gridlines(ax):
# Assigning axes ticks
xticks = np.arange(-65,0,2.5)
yticks = np.arange(0,25,2.5)
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,linewidth=1, color='black', alpha=0.5, linestyle='dotted')
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
gl.xlocator = mticker.FixedLocator(xticks)
gl.ylocator = mticker.FixedLocator(yticks)
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 10, 'color': 'k'}
gl.ylabel_style = {'size': 10, 'color': 'k'}
gl.right_labels = False
gl.bottom_labels = False
gl.xlabel = {'Latitude'}
```
Now set up colors to code each flight date during the experiment. One could choose
a categorical palette so the colors were as different from each other as possible.
Here we'll choose from a continuous set that spans the experiment so days that are
close in time are also close in color.

```{code-cell} ipython3
---
tags: [hide-cell]
---
# On what days did the P-3 fly? These are UTC.
flight_dates = [datetime.date(2020, 1, 17),
datetime.date(2020, 1, 19),
datetime.date(2020, 1, 23),
datetime.date(2020, 1, 24),
datetime.date(2020, 1, 31),
datetime.date(2020, 2, 3),
datetime.date(2020, 2, 4),
datetime.date(2020, 2, 5),
datetime.date(2020, 2, 9),
datetime.date(2020, 2, 10),
datetime.date(2020, 2, 11)]
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved

# color map for things coded by flight date
# Sample from a 255 color map running from start to end of experiment
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
norm = mpl.colors.Normalize(vmin=datetime.date(2020, 1, 15).toordinal(),
vmax=datetime.date(2020, 2, 15).toordinal())
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
flight_cols = [cc.m_bmy(norm(d.toordinal()), alpha=0.9) for d in flight_dates]
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
flight_cols = [mpl.cm.viridis(norm(d.toordinal()), alpha=0.9) for d in flight_dates]
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
```
The P-3 only deployed AXBTs on some flights, and the SWIFT buoys were only deployed
on a subset of those dates.

```{code-cell} ipython3
axbts = cat.P3.AXBT.Level_3.to_dask()
axbt_dates = [d for d in flight_dates if d.strftime("%Y-%m-%d") in np.datetime_as_string(axbts.time, unit="D")]

swifts = [cat[s].all.to_dask() for s in list(cat) if "SWIFT" in s]
#
# Dates with potential SWIFT/P-3 overlap
#
swift_dates = [d for d in
[datetime.date(2020, 1, 19),
datetime.date(2020, 1, 31),
datetime.date(2020, 2, 3),
datetime.date(2020, 2, 4),
datetime.date(2020, 2, 5),
datetime.date(2020, 2, 9),
datetime.date(2020, 2, 10)]
if d in axbt_dates]
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
```
Now we can make a map that shows where the AXBTs were deployed and where the SWIFTs
were on days there the two platforms overlapped

RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
```{code-cell} ipython3
fig = plt.figure(figsize = (8.3, 9.4))
ax = set_up_map(plt)
add_gridlines(ax)

RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
#
# AXBT locations
#
for d in axbt_dates:
flight = axbts.sel(time=d.strftime("%Y-%m-%d"))
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
ax.scatter(flight.lon,flight.lat,
alpha=0.5,color=flight_cols[flight_dates.index(d)],
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
transform=ccrs.PlateCarree(),zorder=7,
label="{:02d}-{:02d}".format(d.month, d.day))
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
#
# SWIFT locations on selected dates (where there's overlap)
#
for d in swift_dates:
flight = axbts.sel(time=d.strftime("%Y-%m-%d"))
for swift in swifts:
drift = swift.sel(time = flight.time.mean(), method = "nearest")
ax.scatter(drift.lon,drift.lat,
alpha=1,color=flight_cols[flight_dates.index(d)],
transform=ccrs.PlateCarree(),zorder=7, marker = "p")
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved

plt.legend(ncol=2,loc=(0.0,0.0),fontsize=12,framealpha=0.8,markerscale=1, title="Flight date (MM-DD-2020)")
plt.tight_layout()
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved
```
On 19 Jan and 3 Feb the AXBTs bracket the SWIFTs; on 23 Jan the SWIFTs are at
the southern end of the AXBT pattern.

The next plot will focus on 19 Jan.
Let's look at the profile of ocean temperature in the first 150 m from the AXBTs
and compare the near-surface temperatures to the SWIFTs they are surrounding.

```{code-cell} ipython3
fig, ax = plt.subplots(figsize=[8.3, 9.4])
axbt_1day = axbts.sel(time="2020-01-19")
# Swift data at mean of AXBT times
swifts_1day = [s.sel(time = axbt_1day.time.mean(), method = "nearest") for s in swifts]

axbt_1day.temperature.where(axbt_1day.depth < 150).plot.line(y="depth",
add_legend=False, yincrease=False)
ax.set_xlabel("Sea water temperature (K)")
ax.set_ylabel("Depth (m)")
sns.despine()
RobertPincus marked this conversation as resolved.
Show resolved Hide resolved

#
# Inset plot! https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/zoom_inset_axes.html
#
axin = ax.inset_axes([0.06, 0.84, 0.6, 0.12])
axin.scatter([s.sea_water_temperature.values + 273.15 for s in swifts_1day],
# SWIFTs 16 and 17 report water temperature at 0.5 m depth; SWIFTs 23-25 report at 0.3 m
# See the variable long_name or Tables 8 and 9 of Quinn et al.
[0.5 if '0.5' in s.sea_water_temperature.long_name else 0.3 for s in swifts_1day],
color="0.25",
s = 1.5 * plt.rcParams['lines.markersize'] ** 2)
axbt_1day.temperature.where(axbt_1day.depth < 3).plot.line(y="depth",
add_legend=False, yincrease=False, ax = axin)
axin.set_xlabel("Sea water temperature (K)")
axin.set_ylabel("Depth (m)")
sns.despine(ax=axin)
ax.indicate_inset_zoom(axin)

plt.tight_layout()
```
Loading