EFIxTIE (Ion temperatures)

Abstract: Access to the EFIxTIE data product containing estimates of the O+ ion temperature in the upper F region along Swarm orbits.

For more information about this product, see the SITE project.

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.10.3
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?

There are three collections available, one for each Swarm spacecraft.

request.available_collections("EFI_TIE", details=False)
{'EFI_TIE': ['SW_OPER_EFIATIE_2_', 'SW_OPER_EFIBTIE_2_', 'SW_OPER_EFICTIE_2_']}
print(request.available_measurements("EFI_TIE"))
['Latitude_GD', 'Longitude_GD', 'Height_GD', 'Radius_GC', 'Latitude_QD', 'MLT_QD', 'Tn_msis', 'Te_adj_LP', 'Ti_meas_drift', 'Ti_model_drift', 'Flag_ti_meas', 'Flag_ti_model']

Notes for the listed available variables:

tie_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",
    # Neutral temperature from NRLMSISE-00 model
    "Tn_msis",
    # Corrected Swarm LP electron temperature
    "Te_adj_LP",
    # Estimated ion temperature from TII drift at high latitudes
    "Ti_meas_drift",
    # Estimated Ion temperature from Weimer 2005 model drifts at high latitudes
    "Ti_model_drift",
    # Bitwise flags with process information
    #  See the Product definition document for details
    "Flag_ti_meas", "Flag_ti_model"
]

Fetching and plotting data

Hint: you can identify start/end times of specific orbit numbers using .get_times_for_orbits:

request = SwarmRequest(SERVER_URL)
request.get_times_for_orbits(3740, 3742, mission="Swarm", spacecraft="Alpha")
(datetime.datetime(2014, 7, 25, 1, 9, 37, 149742),
 datetime.datetime(2014, 7, 25, 5, 51, 25, 594702))

For demonstration, we will fetch some data from Swarm Alpha (SW_OPER_EFIATIE_2_). We also ask for magnetic local time, MLT, and orbital information: OrbitNumber, OrbitDirection which can be useful for some plots.

start = dt.datetime(2014, 7, 25, 1, 9, 38)
end = dt.datetime(2014, 7, 25, 5, 51, 25)

request = SwarmRequest(SERVER_URL)
request.set_collection("SW_OPER_EFIATIE_2_")
request.set_products(
    measurements=tie_vars,
    auxiliaries=["OrbitNumber", "OrbitDirection", "MLT"]
)
data = request.get_between(start, end)

Data can be loaded as either a pandas datframe or a xarray dataset.

df = data.as_dataframe()
df.head()
Height_GD Tn_msis MLT Te_adj_LP Latitude Spacecraft Radius Radius_GC Longitude_GD Latitude_QD MLT_QD Flag_ti_model Flag_ti_meas Ti_meas_drift Latitude_GD Ti_model_drift OrbitNumber Longitude OrbitDirection
Timestamp
2014-07-25 01:09:38.196999936 467186.573954 1048.83 16.776039 1486.15 -0.012119 A 6.845324e+06 6.845324e+06 -126.081803 4.363832 16.734770 3 3 1308.57 -0.012195 1308.57 3740 -126.081803 1
2014-07-25 01:09:38.696000000 467180.926784 1048.90 16.775776 1485.50 0.019726 A 6.845318e+06 6.845318e+06 -126.082416 4.395916 16.734495 3 3 1308.26 0.019850 1308.26 3740 -126.082416 1
2014-07-25 01:09:39.196992256 467175.265855 1048.98 16.775513 1484.76 0.051698 A 6.845312e+06 6.845312e+06 -126.083031 4.428128 16.734220 3 3 1308.20 0.052023 1308.20 3740 -126.083031 1
2014-07-25 01:09:39.696000000 467169.641168 1049.05 16.775248 1484.88 0.083543 A 6.845307e+06 6.845307e+06 -126.083644 4.460213 16.733945 3 3 1308.21 0.084067 1308.21 3740 -126.083644 1
2014-07-25 01:09:40.196999936 467164.002862 1049.14 16.774982 1486.79 0.115515 A 6.845301e+06 6.845301e+06 -126.084259 4.492427 16.733669 3 3 1309.25 0.116240 1309.25 3740 -126.084259 1
ds = data.as_xarray()
ds
<xarray.Dataset>
Dimensions:         (Timestamp: 33808)
Coordinates:
  * Timestamp       (Timestamp) datetime64[ns] 2014-07-25T01:09:38.196999936 ...
Data variables: (12/19)
    Spacecraft      (Timestamp) object 'A' 'A' 'A' 'A' 'A' ... 'A' 'A' 'A' 'A'
    Height_GD       (Timestamp) float64 4.672e+05 4.672e+05 ... 4.673e+05
    Tn_msis         (Timestamp) float64 1.049e+03 1.049e+03 ... 1.044e+03
    MLT             (Timestamp) float64 16.78 16.78 16.78 ... 16.6 16.6 16.6
    Te_adj_LP       (Timestamp) float64 1.486e+03 1.486e+03 ... 1.98e+03
    Latitude        (Timestamp) float64 -0.01212 0.01973 ... -0.1681 -0.1362
    ...              ...
    Ti_meas_drift   (Timestamp) float64 1.309e+03 1.308e+03 ... 1.279e+03
    Latitude_GD     (Timestamp) float64 -0.01219 0.01985 ... -0.1691 -0.1371
    Ti_model_drift  (Timestamp) float64 1.309e+03 1.308e+03 ... 1.279e+03
    OrbitNumber     (Timestamp) int32 3740 3740 3740 3740 ... 3742 3742 3742
    Longitude       (Timestamp) float64 -126.1 -126.1 -126.1 ... 163.2 163.2
    OrbitDirection  (Timestamp) int8 1 1 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1 1 1 1
Attributes: (3)
# Set up a time series plot where each row is an orbit
nrows = len(np.unique(ds["OrbitNumber"]))
fig, axes = plt.subplots(nrows=nrows, ncols=1, figsize=(10, 7))
axes_r = [ax.twinx() for ax in axes]
for i, (orbitnumber, ds_orbit) in enumerate(ds.groupby("OrbitNumber")):
    # Plot electron & ion temperatures, measured and modelled
    ds_orbit.plot.scatter(x="Timestamp", y="Ti_meas_drift", s=0.1, ax=axes[i], color="tab:red")
    ds_orbit.plot.scatter(x="Timestamp", y="Te_adj_LP", s=0.1, ax=axes[i], color="tab:purple")
    ds_orbit.plot.scatter(x="Timestamp", y="Tn_msis", s=0.1, ax=axes[i], color="tab:green")
    ds_orbit.plot.scatter(x="Timestamp", y="MLT", s=0.05, ax=axes_r[i], color="tab:gray", alpha=0.5)
    # Identify times closest to North and South pole
    t_NP = ds_orbit["Timestamp"].isel(Timestamp=ds_orbit["Latitude"].argmax()).values
    t_SP = ds_orbit["Timestamp"].isel(Timestamp=ds_orbit["Latitude"].argmin()).values
    axes[i].axvline(mpl.dates.date2num(t_NP), color="gray")
    axes[i].axvline(mpl.dates.date2num(t_SP), color="gray")
    # Tidy up labelling
    axes[i].xaxis.set_major_formatter(mpl.dates.DateFormatter("%H:%M"))
    axes[i].set_xlabel("")
# Add legend manually
red = mpl.patches.Patch(color="tab:red", label="Ti_meas_drift")
purple = mpl.patches.Patch(color="tab:purple", label="Te_adj_LP")
green = mpl.patches.Patch(color="tab:green", label="Tn_msis")
gray = mpl.patches.Patch(color="tab:gray", label="MLT / Poles")
axes[0].legend(handles=[red, purple, green, gray])
# Tidy up axes and labelling
for ax in axes:
    ax.set_ylim(500, 4000)
axes[-1].set_xlabel("Time")
title = "".join([
    f"Swarm {ds['Spacecraft'].data[0]} ion temperatures, ",
    ds["Timestamp"].dt.date.data[0].isoformat(),
    f"\n{[s for s in ds.attrs['Sources'] if 'TIE' in s]}"
])
fig.suptitle(title);
../_images/03k1_Demo-EFIxTIE_20_0.png