EFIxIDM (Ion drifts & effective masses)
Contents
EFIxIDM (Ion drifts & effective masses)¶
Abstract: Access to the
EFIxIDM
products from the SLIDEM project.
See also:
More notebooks: https://nbviewer.org/github/pacesm/jupyter_notebooks/tree/master/EFI_TII/EFIxIDM_00_data_access.ipynb
Product documentation: https://earth.esa.int/eogateway/documents/20142/2860886/SLIDEM_Product_Definition.pdf
SERVER_URL = 'https://vires.services/ows'
# Display important package versions used
%load_ext watermark
%watermark -i -v -p viresclient,pandas,xarray,matplotlib
Python implementation: CPython
Python version : 3.9.7
IPython version : 8.0.1
viresclient: 0.11.0
pandas : 1.4.1
xarray : 0.21.1
matplotlib : 3.5.1
import datetime as dt
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr
# Control the HTML display of the datasets
xr.set_options(display_expand_attrs=False, display_expand_coords=True, display_expand_data=True)
from viresclient import SwarmRequest
request = SwarmRequest(SERVER_URL)
What data is available?¶
request.available_collections("EFI_IDM", details=False)
{'EFI_IDM': ['SW_PREL_EFIAIDM_2_', 'SW_PREL_EFIBIDM_2_', 'SW_PREL_EFICIDM_2_']}
print(request.available_measurements("EFI_IDM"))
['Latitude_GD', 'Longitude_GD', 'Height_GD', 'Radius_GC', 'Latitude_QD', 'MLT_QD', 'V_sat_nec', 'M_i_eff', 'M_i_eff_err', 'M_i_eff_Flags', 'M_i_eff_tbt_model', 'V_i', 'V_i_err', 'V_i_Flags', 'V_i_raw', 'N_i', 'N_i_err', 'N_i_Flags', 'A_fp', 'R_p', 'T_e', 'Phi_sc']
Notes for the listed available variables:
idm_vars = [
# Positional information in geodetic (GD) and geocentric (GC) frames
# redundant with VirES variables Latitude, Longitude, Radius (in geocentric frame)
"Latitude_GD", "Longitude_GD", "Height_GD", "Radius_GC",
# Quasi-dipole magnetic latitude and local time
# redundant with VirES auxiliaries, QDLat & MLT
"Latitude_QD", "MLT_QD",
# Satellite velocity in NEC frame
"V_sat_nec",
# Estimated ion effective mass, uncertainty, and validity flags
"M_i_eff", "M_i_eff_err", "M_i_eff_Flags",
# Effective masses from ruhlik et al. (2015) topside empirical model
"M_i_eff_tbt_model",
# Along-track ion drift velocity, uncertainty, validity flags, and velocity without detrending
"V_i", "V_i_err", "V_i_Flags", "V_i_raw",
# Ion density, uncertainty, and validity flags
"N_i", "N_i_err", "N_i_Flags",
# Modified-OML faceplate area, and Langmuir spherical probe radius
"A_fp", "R_p",
# Electron temperature, and spacecraft floating potential
"T_e", "Phi_sc",
]
Fetching and plotting data¶
start = dt.datetime(2016, 1, 2)
end = dt.datetime(2016, 1, 3)
request = SwarmRequest(SERVER_URL)
request.set_collection("SW_PREL_EFIAIDM_2_")
request.set_products(
measurements=idm_vars,
auxiliaries=["OrbitNumber", "OrbitDirection", "MLT"]
)
data = request.get_between(start, end)
Data can be loaded as either a pandas dataframe or a xarray dataset.
df = data.as_dataframe()
df.head()
Latitude_GD | N_i_Flags | Longitude | V_i_raw | V_sat_nec | Spacecraft | Height_GD | Latitude | A_fp | M_i_eff_Flags | ... | Phi_sc | V_i_err | M_i_eff | N_i_err | Latitude_QD | V_i | V_i_Flags | M_i_eff_tbt_model | M_i_eff_err | Radius | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Timestamp | |||||||||||||||||||||
2016-01-02 00:00:00.196999936 | 31.912074 | 1 | -95.369735 | -100000.0 | [7634.07808447415, -16.61654501845976, 11.9861... | A | 450611.243327 | 31.751028 | -1.0 | 1 | ... | -1.269281 | -1.0 | -1.0 | -1.0 | 41.461172 | -100000.0 | 65537 | -1.0 | -1.0 | 6.822807e+06 |
2016-01-02 00:00:00.696000000 | 31.944152 | 1 | -95.369768 | -100000.0 | [7634.07208768917, -16.337781619210624, 11.985... | A | 450615.988781 | 31.783018 | -1.0 | 1 | ... | -1.271026 | -1.0 | -1.0 | -1.0 | 41.492919 | -100000.0 | 65537 | -1.0 | -1.0 | 6.822801e+06 |
2016-01-02 00:00:01.196999936 | 31.976359 | 1 | -95.369800 | -100000.0 | [7634.066052693255, -16.057622242909282, 11.98... | A | 450620.758249 | 31.815135 | -1.0 | 1 | ... | -1.273090 | -1.0 | -1.0 | -1.0 | 41.524792 | -100000.0 | 65537 | -1.0 | -1.0 | 6.822795e+06 |
2016-01-02 00:00:01.696000000 | 32.008436 | 1 | -95.369831 | -100000.0 | [7634.060020001237, -15.778152926144662, 11.98... | A | 450625.516353 | 31.847124 | -1.0 | 1 | ... | -1.275790 | -1.0 | -1.0 | -1.0 | 41.556536 | -100000.0 | 65537 | -1.0 | -1.0 | 6.822789e+06 |
2016-01-02 00:00:02.196999936 | 32.040643 | 1 | -95.369860 | -100000.0 | [7634.053948932672, -15.497284583987861, 11.98... | A | 450630.298553 | 31.879242 | -1.0 | 1 | ... | -1.270579 | -1.0 | -1.0 | -1.0 | 41.588407 | -100000.0 | 65537 | -1.0 | -1.0 | 6.822783e+06 |
5 rows × 29 columns
ds = data.as_xarray()
ds
<xarray.Dataset> Dimensions: (Timestamp: 172776, V_sat_nec_dim1: 3) Coordinates: * Timestamp (Timestamp) datetime64[ns] 2016-01-02T00:00:00.1969999... Dimensions without coordinates: V_sat_nec_dim1 Data variables: (12/29) Spacecraft (Timestamp) object 'A' 'A' 'A' 'A' ... 'A' 'A' 'A' 'A' Latitude_GD (Timestamp) float64 31.91 31.94 31.98 ... 8.765 8.733 N_i_Flags (Timestamp) uint32 1 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1 Longitude (Timestamp) float64 -95.37 -95.37 -95.37 ... 81.23 81.23 V_i_raw (Timestamp) float64 -1e+05 -1e+05 ... -1e+05 -1e+05 V_sat_nec (Timestamp, V_sat_nec_dim1) float64 7.634e+03 ... -11.15 ... ... Latitude_QD (Timestamp) float64 41.46 41.49 41.52 ... 1.424 1.389 V_i (Timestamp) float64 -1e+05 -1e+05 ... -1e+05 -1e+05 V_i_Flags (Timestamp) uint32 65537 65537 65537 ... 65537 65537 M_i_eff_tbt_model (Timestamp) float64 -1.0 -1.0 -1.0 ... -1.0 -1.0 -1.0 M_i_eff_err (Timestamp) float64 -1.0 -1.0 -1.0 ... -1.0 -1.0 -1.0 Radius (Timestamp) float64 6.823e+06 6.823e+06 ... 6.826e+06 Attributes: (3)
An initial preview of the data:
fig, axes = plt.subplots(nrows=4, sharex=True, figsize=(10, 7))
axes_r = [ax.twinx() for ax in axes]
# Plot quantity (left axis) and error (right axis) for each quantity
ds.plot.scatter(x="Timestamp", y="M_i_eff", ax=axes[0], s=0.1)
ds.plot.scatter(x="Timestamp", y="M_i_eff_err", ax=axes_r[0], s=0.1, color="tab:orange")
ds.plot.scatter(x="Timestamp", y="V_i", ax=axes[1], s=0.1)
ds.plot.scatter(x="Timestamp", y="V_i_err", ax=axes_r[1], s=0.1, color="tab:orange")
ds.plot.scatter(x="Timestamp", y="N_i", ax=axes[2], s=0.1)
ds.plot.scatter(x="Timestamp", y="N_i_err", ax=axes_r[2], s=0.1, color="tab:orange")
ds.plot.scatter(x="Timestamp", y="T_e", ax=axes[3], s=0.1)
fig.subplots_adjust(hspace=0)
# Add legend to identify each side
blue = mpl.patches.Patch(color="tab:blue", label="Quantities")
orange = mpl.patches.Patch(color="tab:orange", label="Errors")
axes[0].legend(handles=[blue, orange])
# # Generate additional ticklabels for x-axis
# Use time xticks to get dataset vars at those xticks
locx = axes[-1].get_xticks()
times = mpl.dates.num2date(locx)
times = [t.replace(tzinfo=None) for t in times]
_ds_xticks = ds.reindex({"Timestamp": times}, method="nearest")
# Build ticklabels from dataset vars
xticklabels = np.stack([
_ds_xticks["Timestamp"].dt.strftime("%H:%M").values,
np.round(_ds_xticks["Latitude"].values, 2).astype(str),
np.round(_ds_xticks["Longitude"].values, 2).astype(str),
])
xticklabels = ["\n".join(row) for row in xticklabels.T]
# Add labels to first xtick
_xt0 = xticklabels[0].split("\n")
xticklabels[0] = f"Time: {_xt0[0]}\nLat: {_xt0[1]}\nLon: {_xt0[2]}"
axes[-1].set_xticks(axes[-1].get_xticks())
axes[-1].set_xticklabels(xticklabels)
axes[-1].set_xlabel("")
# Adjust title
sources = "\n".join([i for i in ds.attrs["Sources"] if "IDM" in i])
title = "".join([
f"Swarm {ds['Spacecraft'].data[0]} ion effective mass and drift, ",
ds["Timestamp"].dt.date.data[0].isoformat(),
f"\n{sources}"
])
fig.suptitle(title);
