EFIxTIE (Ion temperatures)

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.

Documentation:

# Display important package versions used
%load_ext watermark
%watermark -i -v -p viresclient,pandas,xarray,matplotlib
Python implementation: CPython
Python version       : 3.11.6
IPython version      : 8.18.0

viresclient: 0.15.2
pandas     : 2.1.3
xarray     : 2023.12.0
matplotlib : 3.8.2
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()

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()
request.get_times_for_orbits(3740, 3742, mission="Swarm", spacecraft="Alpha")
(datetime.datetime(2014, 7, 25, 1, 9, 37, 149985),
 datetime.datetime(2014, 7, 25, 5, 51, 25, 595024))

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()
request.set_collection("SW_OPER_EFIATIE_2_")
request.set_products(
    measurements=tie_vars, auxiliaries=["OrbitNumber", "OrbitDirection", "MLT"]
)
data = request.get_between(start, end)
2026-10-01T17:54:02.438543Z ERROR WPS10Service: asynchronous request failed. Retrying in 20 seconds. URLError: <urlopen error [Errno 104] Connection reset by peer>
2026-10-01T17:54:02.438543Z ERROR WPS10Service: asynchronous request failed. Retrying in 20 seconds. URLError: <urlopen error [Errno 104] Connection reset by peer>
2026-10-01T17:54:02.438543Z ERROR WPS10Service: asynchronous request failed. Retrying in 20 seconds. URLError: <urlopen error [Errno 104] Connection reset by peer>

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

df = data.as_dataframe()
df.head()
Radius_GC Tn_msis Longitude_GD Height_GD Flag_ti_model OrbitDirection OrbitNumber Latitude_GD Longitude Radius Latitude_QD Ti_meas_drift MLT Latitude Flag_ti_meas Ti_model_drift Spacecraft MLT_QD Te_adj_LP
Timestamp
2014-07-25 01:09:38.196999936 6.845324e+06 1048.83 -126.081803 467186.573954 3 1 3740 -0.012195 -126.081803 6.845324e+06 4.363832 1308.57 16.776039 -0.012119 3 1308.57 A 16.734770 1486.15
2014-07-25 01:09:38.696000000 6.845318e+06 1048.90 -126.082416 467180.926784 3 1 3740 0.019850 -126.082416 6.845318e+06 4.395916 1308.26 16.775776 0.019726 3 1308.26 A 16.734495 1485.50
2014-07-25 01:09:39.196992256 6.845312e+06 1048.98 -126.083031 467175.265855 3 1 3740 0.052023 -126.083031 6.845312e+06 4.428128 1308.20 16.775513 0.051698 3 1308.20 A 16.734220 1484.76
2014-07-25 01:09:39.696000000 6.845307e+06 1049.05 -126.083644 467169.641168 3 1 3740 0.084067 -126.083644 6.845307e+06 4.460213 1308.21 16.775248 0.083543 3 1308.21 A 16.733945 1484.88
2014-07-25 01:09:40.196999936 6.845301e+06 1049.14 -126.084259 467164.002862 3 1 3740 0.116240 -126.084259 6.845301e+06 4.492427 1309.25 16.774982 0.115515 3 1309.25 A 16.733669 1486.79
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'
    Radius_GC       (Timestamp) float64 6.845e+06 6.845e+06 ... 6.845e+06
    Tn_msis         (Timestamp) float64 1.049e+03 1.049e+03 ... 1.044e+03
    Longitude_GD    (Timestamp) float64 -126.1 -126.1 -126.1 ... 163.2 163.2
    Height_GD       (Timestamp) float64 4.672e+05 4.672e+05 ... 4.673e+05
    Flag_ti_model   (Timestamp) uint8 3 3 3 3 3 3 3 3 3 3 ... 1 1 1 1 1 1 1 1 1
    ...              ...
    MLT             (Timestamp) float64 16.78 16.78 16.78 ... 16.6 16.6 16.6
    Latitude        (Timestamp) float64 -0.01212 0.01973 ... -0.1681 -0.1362
    Flag_ti_meas    (Timestamp) uint8 3 3 3 3 3 3 3 3 3 3 ... 1 1 1 1 1 1 1 1 1
    Ti_model_drift  (Timestamp) float64 1.309e+03 1.308e+03 ... 1.279e+03
    MLT_QD          (Timestamp) float64 16.73 16.73 16.73 ... 16.63 16.63 16.63
    Te_adj_LP       (Timestamp) float64 1.486e+03 1.486e+03 ... 1.98e+03
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/5cff392e3358df542360ab3be3e1775b348b9fafea6ed7f16397a248dd5a7b41.png