AMALi cloud top height#
This example presents the cloud top height derived from Airborne Mobile Aerosol Lidar for Arctic research (AMALi) measurements. The dataset is available on the PANGAEA database.
If you have questions or if you would like to use the data for a publication, please don’t hesitate to get in contact with the dataset authors as stated in the dataset attributes contact
or author
.
import os
# local caching
try:
from dotenv import load_dotenv
load_dotenv()
local_storage = os.environ['INTAKE_CACHE']
except ImportError:
local_storage = '/tmp/'
kwds = {'simplecache': dict(
cache_storage=local_storage,
same_names=True
)}
To analyse the data they first have to be loaded by importing the (AC)3 airborne meta data catalogue. To do so the ac3airborne package has to be installed. More information on how to do that and about the catalog can be found here.
import ac3airborne
cat = ac3airborne.get_intake_catalog()
datasets = []
for campaign in ['ACLOUD', 'AFLUX', 'MOSAiC-ACA','HALO-AC3']:
datasets.extend(list(cat[campaign]['P5']['AMALi_CTH']))
datasets
['ACLOUD_P5_RF04',
'ACLOUD_P5_RF05',
'ACLOUD_P5_RF06',
'ACLOUD_P5_RF07',
'ACLOUD_P5_RF08',
'ACLOUD_P5_RF10',
'ACLOUD_P5_RF11',
'ACLOUD_P5_RF13',
'ACLOUD_P5_RF14',
'ACLOUD_P5_RF16',
'ACLOUD_P5_RF17',
'ACLOUD_P5_RF18',
'ACLOUD_P5_RF19',
'ACLOUD_P5_RF20',
'ACLOUD_P5_RF21',
'ACLOUD_P5_RF22',
'ACLOUD_P5_RF23',
'ACLOUD_P5_RF25',
'AFLUX_P5_RF03',
'AFLUX_P5_RF04',
'AFLUX_P5_RF05',
'AFLUX_P5_RF06',
'AFLUX_P5_RF07',
'AFLUX_P5_RF08',
'AFLUX_P5_RF09',
'AFLUX_P5_RF10',
'AFLUX_P5_RF11',
'AFLUX_P5_RF12',
'AFLUX_P5_RF13',
'AFLUX_P5_RF14',
'AFLUX_P5_RF15',
'MOSAiC-ACA_P5_RF04',
'MOSAiC-ACA_P5_RF05',
'MOSAiC-ACA_P5_RF06',
'MOSAiC-ACA_P5_RF07',
'MOSAiC-ACA_P5_RF08',
'MOSAiC-ACA_P5_RF09',
'MOSAiC-ACA_P5_RF10',
'MOSAiC-ACA_P5_RF11',
'HALO-AC3_P5_RF01',
'HALO-AC3_P5_RF03',
'HALO-AC3_P5_RF04',
'HALO-AC3_P5_RF05',
'HALO-AC3_P5_RF07',
'HALO-AC3_P5_RF08',
'HALO-AC3_P5_RF09',
'HALO-AC3_P5_RF10',
'HALO-AC3_P5_RF11',
'HALO-AC3_P5_RF12',
'HALO-AC3_P5_RF13']
Note
Have a look at the attributes of the xarray dataset ds_cloud_top_height
for all relevant information on the dataset, such as author, contact, or citation information.
ds_cloud_top_height = cat['ACLOUD']['P5']['AMALi_CTH']['ACLOUD_P5_RF07'](storage_options=kwds).to_dask()
ds_cloud_top_height
/net/sever/mech/miniconda3/envs/howtoac3/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
'dims': dict(self._ds.dims),
<xarray.Dataset> Size: 2MB Dimensions: (time: 10078, boundary: 2, cloud_layer: 10) Coordinates: * time (time) datetime64[ns] 81kB 2017-05-27T13:17:33 ... 2... * boundary (boundary) <U5 40B 'lower' 'upper' * cloud_layer (cloud_layer) int64 80B 1 2 3 4 5 6 7 8 9 10 Data variables: surf_alt (time) float64 81kB ... ac_zen (time) float64 81kB ... alt (time) float64 81kB ... lat (time) float64 81kB ... lon (time) float64 81kB ... roll (time) float64 81kB ... pitch (time) float64 81kB ... heading (time) float64 81kB ... lowest_laser_height (time) float64 81kB ... laser_range_flag (time) int8 10kB ... valid_height (time, boundary) float64 161kB ... cth (time, cloud_layer) float64 806kB ... Attributes: (12/13) institution: Institute of Geophysics and Meteorology (IGM), University o... source: airborne observation author: Nils Risse (n.risse@uni-koeln.de) convention: CF-1.8 featureType: trajectory mission: ACLOUD ... ... flight_id: RF07 title: cloud top height derived from AMALi observations onboard Po... instrument: AMALi (Airborne Mobile Aerosol Lidar for Arctic research) history: derived from l1 product contact: n.risse@uni-koeln.de created: 2023-01-27T13:37:46
ds_cloud_mask = cat['ACLOUD']['P5']['AMALi_CM']['ACLOUD_P5_RF07'](storage_options=kwds).to_dask()
ds_cloud_mask
/net/sever/mech/miniconda3/envs/howtoac3/lib/python3.11/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
'dims': dict(self._ds.dims),
<xarray.Dataset> Size: 1MB Dimensions: (time: 10078, boundary: 2) Coordinates: * time (time) datetime64[ns] 81kB 2017-05-27T13:17:33 ... 2... * boundary (boundary) <U5 40B 'lower' 'upper' Data variables: surf_alt (time) float64 81kB ... ac_zen (time) float64 81kB ... alt (time) float64 81kB ... lat (time) float64 81kB ... lon (time) float64 81kB ... roll (time) float64 81kB ... pitch (time) float64 81kB ... heading (time) float64 81kB ... lowest_laser_height (time) float64 81kB ... laser_range_flag (time) int8 10kB ... valid_height (time, boundary) float64 161kB ... cloud_mask (time) int64 81kB ... Attributes: (12/13) institution: Institute of Geophysics and Meteorology (IGM), University o... source: airborne observation author: Nils Risse (n.risse@uni-koeln.de) convention: CF-1.8 featureType: trajectory mission: ACLOUD ... ... flight_id: RF07 title: cloud mask derived from AMALi observations onboard Polar 5 ... instrument: AMALi (Airborne Mobile Aerosol Lidar for Arctic research) history: derived from l1 product contact: n.risse@uni-koeln.de created: 2023-01-27T13:37:31
The dataset includes the cloud top height (cloud_top_height
), the number of cloud layers (n_cloud_layer
) and a cloud mask derived from the optical depth (cloud_mask
). Additionally, the instrument status is provided and positional data of the aircraft (lat
, lon
, alt
).
Load Polar 5 flight phase information#
Polar 5 flights are divided into segments to easily access start and end times of flight patterns. For more information have a look at the respective github repository.
At first we want to load the flight segments of (AC)³airborne
meta = ac3airborne.get_flight_segments()
The following command lists all flight segments into the dictionary segments
segments = {s.get("segment_id"): {**s, "flight_id": flight["flight_id"]}
for campaign in meta.values()
for platform in campaign.values()
for flight in platform.values()
for s in flight["segments"]
}
In this example we want to look at a high-level segment during ACLOUD RF07
seg = segments["ACLOUD_P5_RF07_hl03"]
Using the start and end times of the segment ACLOUD_P5_RF07_hl03
stored in seg
, we slice the MiRAC data to this flight section.
ds_cloud_top_height_sel = ds_cloud_top_height.sel(time=slice(seg["start"], seg["end"]))
ds_cloud_mask_sel = ds_cloud_mask.sel(time=slice(seg["start"], seg["end"]))
Plots#
The flight section during ACLOUD RF05 is flown at about 3 km altitude in west-east direction during a cold-air outbreak event perpendicular to the wind field. Clearly one can identify the roll-cloud structure in the radar reflectivity and the 89 GHz brightness temperature.
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
plt.style.use("../../mplstyle/book")
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, gridspec_kw=dict(height_ratios=[1, 0.25]))
# 1st: plot flight altitude and cloud top height with seperate colors for each layer
ax1.plot(ds_cloud_top_height_sel.time, ds_cloud_top_height_sel.alt*1e-3, color='k', label='Flight altitude')
stack = ds_cloud_top_height_sel.cth.stack({'tl': ['time', 'cloud_layer']})
im = ax1.scatter(x=stack.time, y=stack*1e-3, c=stack.cloud_layer, s=2, vmin=1, vmax=9, cmap='Set1')
fig.colorbar(im, ax=ax1, label='cloud layer (1 = highest cloud top)')
ax1.set_ylim(0, 4)
ax1.set_ylabel('Cloud top height [km]')
ax1.legend(frameon=False, loc='upper left')
# 3rd: plot cloud mask in lower part of the figure
ax2.scatter(ds_cloud_mask_sel.time, ds_cloud_mask_sel.cloud_mask, s=2, color='k')
ax2.set_yticks([int(x) for x in ds_cloud_mask_sel.cloud_mask.attrs['flag_values']])
ax2.set_yticklabels([x for x in ds_cloud_mask_sel.cloud_mask.attrs['flag_meanings'].split(' ')])
ax2.set_xlabel('Time (hh:mm) [UTC]')
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
plt.show()
