IPDxIRR_2F (Ionospheric plasma densities)#

Abstract: Access to the derived plasma characteristics at 1Hz (level 2 product).

%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.12.3
pandas     : 2.1.3
xarray     : 2023.12.0
matplotlib : 3.8.2
from viresclient import SwarmRequest
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter

request = SwarmRequest()

IPDxIRR_2F product information#

Derived plasma characteristics at 1Hz, for each Swarm spacecraft.

Documentation:

Check what “IPD” data variables are available#

request.available_collections("IPD", details=False)
{'IPD': ['SW_OPER_IPDAIRR_2F', 'SW_OPER_IPDBIRR_2F', 'SW_OPER_IPDCIRR_2F']}
request.available_measurements("IPD")
['Ne',
 'Te',
 'Background_Ne',
 'Foreground_Ne',
 'PCP_flag',
 'Grad_Ne_at_100km',
 'Grad_Ne_at_50km',
 'Grad_Ne_at_20km',
 'Grad_Ne_at_PCP_edge',
 'ROD',
 'RODI10s',
 'RODI20s',
 'delta_Ne10s',
 'delta_Ne20s',
 'delta_Ne40s',
 'Num_GPS_satellites',
 'mVTEC',
 'mROT',
 'mROTI10s',
 'mROTI20s',
 'IBI_flag',
 'Ionosphere_region_flag',
 'IPIR_index',
 'Ne_quality_flag',
 'TEC_STD']

Fetch three hours of IPD data#

request.set_collection("SW_OPER_IPDAIRR_2F")
request.set_products(measurements=request.available_measurements("IPD"))
data = request.get_between(
    dt.datetime(2014,12,21, 0),
    dt.datetime(2014,12,21, 3)
)

Load and plot using pandas/matplotlib#

df = data.as_dataframe()
df.head()
mVTEC mROTI10s ROD delta_Ne20s Te RODI10s Longitude IBI_flag TEC_STD mROT ... mROTI20s Latitude Spacecraft Background_Ne Grad_Ne_at_100km Radius delta_Ne40s RODI20s Grad_Ne_at_50km Grad_Ne_at_20km
Timestamp
2014-12-21 00:00:00.196999936 51.786934 0.001472 0.0 10266.500 2212.278353 10238.517220 -128.771412 -1 3.131451 -0.011013 ... 0.002676 -4.693533 A 1343599.375 -0.084919 6.840395e+06 3811.1 7764.002532 -0.403940 -1.047788
2014-12-21 00:00:01.196999936 51.768982 0.001386 0.0 2830.850 2165.194729 3263.138721 -128.772618 -1 3.122494 -0.011013 ... 0.002732 -4.757416 A 1343599.375 -0.144009 6.840404e+06 16343.3 7181.496228 0.144877 0.338403
2014-12-21 00:00:02.196999936 51.746898 0.001310 0.0 0.000 1544.874194 3263.138721 -128.773822 -1 3.113830 -0.008833 ... 0.002750 -4.821298 A 1343599.375 -0.058276 6.840413e+06 3246.4 7181.496228 -0.123734 0.133643
2014-12-21 00:00:03.196999936 51.728759 0.001930 0.0 2194.925 1228.501871 3263.138721 -128.775026 -1 3.104259 -0.008151 ... 0.003277 -4.885179 A 1343599.375 -0.144613 6.840422e+06 848.3 7390.308480 -0.131441 1.443077
2014-12-21 00:00:04.196999936 51.711313 0.002434 0.0 9491.525 2681.512355 3263.138721 -128.776229 -1 3.097484 -0.007051 ... 0.003744 -4.949060 A 1343599.375 -0.039358 6.840430e+06 6448.3 7554.331699 -0.403369 -1.948789

5 rows × 29 columns

df.columns
Index(['mVTEC', 'mROTI10s', 'ROD', 'delta_Ne20s', 'Te', 'RODI10s', 'Longitude',
       'IBI_flag', 'TEC_STD', 'mROT', 'Ne_quality_flag', 'IPIR_index',
       'Foreground_Ne', 'Ionosphere_region_flag', 'PCP_flag', 'delta_Ne10s',
       'Num_GPS_satellites', 'Ne', 'Grad_Ne_at_PCP_edge', 'mROTI20s',
       'Latitude', 'Spacecraft', 'Background_Ne', 'Grad_Ne_at_100km', 'Radius',
       'delta_Ne40s', 'RODI20s', 'Grad_Ne_at_50km', 'Grad_Ne_at_20km'],
      dtype='object')
fig, axes = plt.subplots(nrows=7, ncols=1, figsize=(20,18), sharex=True)
df.plot(ax=axes[0], y=['Background_Ne', 'Foreground_Ne', 'Ne'], alpha=0.8)
df.plot(ax=axes[1], y=['Grad_Ne_at_100km', 'Grad_Ne_at_50km', 'Grad_Ne_at_20km'])
df.plot(ax=axes[2], y=['RODI10s', 'RODI20s'])
df.plot(ax=axes[3], y=['ROD'])
df.plot(ax=axes[4], y=['mROT'])
df.plot(ax=axes[5], y=['delta_Ne10s', 'delta_Ne20s', 'delta_Ne40s'])
df.plot(ax=axes[6], y=['mROTI20s', 'mROTI10s'])
axes[0].set_ylabel("[cm$^{-3}$]")
axes[1].set_ylabel("[cm$^{-3}$m$^{-1}$]")
axes[2].set_ylabel("[cm$^{-3}$s$^{-1}$]")
axes[3].set_ylabel("[cm$^{-3}$m$^{-1}$]")
axes[4].set_ylabel("[TECU s$^{-1}$]")
axes[5].set_ylabel("[cm$^{-3}$m$^{-1}$]")
axes[6].set_ylabel("[TECU s$^{-1}$]")
axes[6].set_xlabel("Timestamp")

for ax in axes:
    # Reformat time axis
    # https://www.earthdatascience.org/courses/earth-analytics-python/use-time-series-data-in-python/customize-dates--matplotlib-plots-python/
    ax.xaxis.set_major_formatter(DateFormatter("%Y-%m-%d\n%H:%M:%S"))
    ax.legend(loc="upper right")
    ax.grid()
fig.subplots_adjust(hspace=0)
../_images/8e787033164cfb750130dce76a7f6fb60b24f750f731c99b28be3f4a1debdbb1.png

Load as xarray#

ds = data.as_xarray()
ds
<xarray.Dataset>
Dimensions:                 (Timestamp: 10800)
Coordinates:
  * Timestamp               (Timestamp) datetime64[ns] 2014-12-21T00:00:00.19...
Data variables: (12/29)
    Spacecraft              (Timestamp) object 'A' 'A' 'A' 'A' ... 'A' 'A' 'A'
    mVTEC                   (Timestamp) float64 51.79 51.77 ... 20.84 20.94
    mROTI10s                (Timestamp) float64 0.001472 0.001386 ... 0.005609
    ROD                     (Timestamp) float64 0.0 0.0 ... 7.28e+03 7.28e+03
    delta_Ne20s             (Timestamp) float64 1.027e+04 ... 1.702e+03
    Te                      (Timestamp) float64 2.212e+03 ... 1.723e+03
    ...                      ...
    Grad_Ne_at_100km        (Timestamp) float64 -0.08492 -0.144 ... 0.9621
    Radius                  (Timestamp) float64 6.84e+06 6.84e+06 ... 6.835e+06
    delta_Ne40s             (Timestamp) float64 3.811e+03 ... 1.702e+03
    RODI20s                 (Timestamp) float64 7.764e+03 7.181e+03 ... 907.9
    Grad_Ne_at_50km         (Timestamp) float64 -0.4039 0.1449 ... 0.9347 0.9775
    Grad_Ne_at_20km         (Timestamp) float64 -1.048 0.3384 ... 1.002 0.9148
Attributes:
    Sources:         ['SW_OPER_IPDAIRR_2F_20141221T000000_20141221T235959_0302']
    MagneticModels:  []
    AppliedFilters:  []

Alternative plot setup#

To plot the data from xarray, we need a different plotting setup. This does however give us more control over the plot. The units are extracted directly from the xarray object.

fig, axes = plt.subplots(nrows=7, ncols=1, figsize=(20,18), sharex=True)
def subplot(ax=None, y=None, **kwargs):
    """Plot combination of variables onto a given axis"""
    units = ds[y[0]].units
    for var in y:
        ax.plot(ds["Timestamp"], ds[var], label=var, **kwargs)
        if units != ds[var].units:
            raise ValueError(f"Units mismatch for {var}")
    ax.set_ylabel(f"[{units}]")
    # Reformat time axis
    # https://www.earthdatascience.org/courses/earth-analytics-python/use-time-series-data-in-python/customize-dates--matplotlib-plots-python/
    ax.xaxis.set_major_formatter(DateFormatter("%Y-%m-%d\n%H:%M:%S"))
    ax.legend(loc="upper right")
    ax.grid()
subplot(ax=axes[0], y=['Background_Ne', 'Foreground_Ne', 'Ne'])
subplot(ax=axes[1], y=['Grad_Ne_at_100km', 'Grad_Ne_at_50km', 'Grad_Ne_at_20km'])
subplot(ax=axes[2], y=['RODI10s', 'RODI20s'])
subplot(ax=axes[3], y=['ROD'])
subplot(ax=axes[4], y=['mROT'])
subplot(ax=axes[5], y=['delta_Ne10s', 'delta_Ne20s', 'delta_Ne40s'])
subplot(ax=axes[6], y=['mROTI20s', 'mROTI10s'])
fig.subplots_adjust(hspace=0)
../_images/38a33b938b18d5eabfd11f30bb71a72f6ed503d73905cb7ae8e2283b63aa6d15.png