!pip install matplotlib s3fs "xarray[io]"

Hide code cell output

Requirement already satisfied: matplotlib in /usr/lib/python3/dist-packages (3.1.2)
Requirement already satisfied: s3fs in /home/deploy/.local/lib/python3.8/site-packages (2024.10.0)
Requirement already satisfied: xarray[io] in /home/deploy/.local/lib/python3.8/site-packages (2023.1.0)
Requirement already satisfied: aiohttp!=4.0.0a0,!=4.0.0a1 in /home/deploy/.local/lib/python3.8/site-packages (from s3fs) (3.10.11)
Requirement already satisfied: fsspec==2024.10.0.* in /home/deploy/.local/lib/python3.8/site-packages (from s3fs) (2024.10.0)
Requirement already satisfied: aiobotocore<3.0.0,>=2.5.4 in /home/deploy/.local/lib/python3.8/site-packages (from s3fs) (2.22.0)
Requirement already satisfied: pandas>=1.3 in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (2.0.3)
Requirement already satisfied: packaging>=21.3 in /usr/local/lib/python3.8/dist-packages (from xarray[io]) (24.1)
Requirement already satisfied: numpy>=1.20 in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.24.4)
Requirement already satisfied: scipy; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.10.1)
Requirement already satisfied: zarr; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (2.16.1)
Requirement already satisfied: cfgrib; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (0.9.15.0)
Requirement already satisfied: h5netcdf; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.1.0)
Requirement already satisfied: rasterio; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.3.11)
Requirement already satisfied: netCDF4; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.7.2)
Requirement already satisfied: cftime; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.6.4.post1)
Requirement already satisfied: pooch; extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (1.8.2)
Requirement already satisfied: pydap; python_version < "3.10" and extra == "io" in /home/deploy/.local/lib/python3.8/site-packages (from xarray[io]) (3.4.1)
Requirement already satisfied: multidict<7.0,>=4.5 in /home/deploy/.local/lib/python3.8/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (6.1.0)
Requirement already satisfied: aiosignal>=1.1.2 in /home/deploy/.local/lib/python3.8/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (1.3.1)
Requirement already satisfied: yarl<2.0,>=1.12.0 in /home/deploy/.local/lib/python3.8/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (1.15.2)
Requirement already satisfied: frozenlist>=1.1.1 in /home/deploy/.local/lib/python3.8/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (1.5.0)
Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /home/deploy/.local/lib/python3.8/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (2.4.4)
Requirement already satisfied: async-timeout<6.0,>=4.0; python_version < "3.11" in /home/deploy/.local/lib/python3.8/site-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (5.0.1)
Requirement already satisfied: attrs>=17.3.0 in /usr/lib/python3/dist-packages (from aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (19.3.0)
Requirement already satisfied: wrapt<2.0.0,>=1.10.10 in /home/deploy/.local/lib/python3.8/site-packages (from aiobotocore<3.0.0,>=2.5.4->s3fs) (1.17.2)
Requirement already satisfied: botocore<1.37.4,>=1.37.2 in /home/deploy/.local/lib/python3.8/site-packages (from aiobotocore<3.0.0,>=2.5.4->s3fs) (1.37.3)
Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /usr/lib/python3/dist-packages (from aiobotocore<3.0.0,>=2.5.4->s3fs) (0.9.4)
Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /home/deploy/.local/lib/python3.8/site-packages (from aiobotocore<3.0.0,>=2.5.4->s3fs) (2.9.0.post0)
Requirement already satisfied: aioitertools<1.0.0,>=0.5.1 in /home/deploy/.local/lib/python3.8/site-packages (from aiobotocore<3.0.0,>=2.5.4->s3fs) (0.12.0)
Requirement already satisfied: tzdata>=2022.1 in /home/deploy/.local/lib/python3.8/site-packages (from pandas>=1.3->xarray[io]) (2025.2)
Requirement already satisfied: pytz>=2020.1 in /home/deploy/.local/lib/python3.8/site-packages (from pandas>=1.3->xarray[io]) (2025.2)
Requirement already satisfied: asciitree in /home/deploy/.local/lib/python3.8/site-packages (from zarr; extra == "io"->xarray[io]) (0.3.3)
Requirement already satisfied: fasteners in /home/deploy/.local/lib/python3.8/site-packages (from zarr; extra == "io"->xarray[io]) (0.19)
Requirement already satisfied: numcodecs>=0.10.0 in /home/deploy/.local/lib/python3.8/site-packages (from zarr; extra == "io"->xarray[io]) (0.12.1)
Requirement already satisfied: click in /usr/lib/python3/dist-packages (from cfgrib; extra == "io"->xarray[io]) (7.0)
Requirement already satisfied: eccodes>=0.9.8 in /home/deploy/.local/lib/python3.8/site-packages (from cfgrib; extra == "io"->xarray[io]) (2.42.0)
Requirement already satisfied: h5py in /home/deploy/.local/lib/python3.8/site-packages (from h5netcdf; extra == "io"->xarray[io]) (3.11.0)
Requirement already satisfied: affine in /home/deploy/.local/lib/python3.8/site-packages (from rasterio; extra == "io"->xarray[io]) (2.4.0)
Requirement already satisfied: snuggs>=1.4.1 in /home/deploy/.local/lib/python3.8/site-packages (from rasterio; extra == "io"->xarray[io]) (1.4.7)
Requirement already satisfied: setuptools in /usr/lib/python3/dist-packages (from rasterio; extra == "io"->xarray[io]) (45.2.0)
Requirement already satisfied: certifi in /usr/lib/python3/dist-packages (from rasterio; extra == "io"->xarray[io]) (2019.11.28)
Requirement already satisfied: cligj>=0.5 in /home/deploy/.local/lib/python3.8/site-packages (from rasterio; extra == "io"->xarray[io]) (0.7.2)
Requirement already satisfied: click-plugins in /home/deploy/.local/lib/python3.8/site-packages (from rasterio; extra == "io"->xarray[io]) (1.1.1.2)
Requirement already satisfied: importlib-metadata; python_version < "3.10" in /usr/lib/python3/dist-packages (from rasterio; extra == "io"->xarray[io]) (1.5.0)
Requirement already satisfied: requests>=2.19.0 in /usr/lib/python3/dist-packages (from pooch; extra == "io"->xarray[io]) (2.22.0)
Requirement already satisfied: platformdirs>=2.5.0 in /home/deploy/.local/lib/python3.8/site-packages (from pooch; extra == "io"->xarray[io]) (4.3.6)
Requirement already satisfied: six>=1.4.0 in /usr/lib/python3/dist-packages (from pydap; python_version < "3.10" and extra == "io"->xarray[io]) (1.14.0)
Requirement already satisfied: beautifulsoup4 in /home/deploy/.local/lib/python3.8/site-packages (from pydap; python_version < "3.10" and extra == "io"->xarray[io]) (4.13.4)
Requirement already satisfied: Webob in /home/deploy/.local/lib/python3.8/site-packages (from pydap; python_version < "3.10" and extra == "io"->xarray[io]) (1.8.9)
Requirement already satisfied: docopt in /usr/lib/python3/dist-packages (from pydap; python_version < "3.10" and extra == "io"->xarray[io]) (0.6.2)
Requirement already satisfied: Jinja2 in /usr/local/lib/python3.8/dist-packages (from pydap; python_version < "3.10" and extra == "io"->xarray[io]) (3.1.4)
Requirement already satisfied: typing-extensions>=4.1.0; python_version < "3.11" in /home/deploy/.local/lib/python3.8/site-packages (from multidict<7.0,>=4.5->aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (4.13.2)
Requirement already satisfied: idna>=2.0 in /usr/lib/python3/dist-packages (from yarl<2.0,>=1.12.0->aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (2.8)
Requirement already satisfied: propcache>=0.2.0 in /home/deploy/.local/lib/python3.8/site-packages (from yarl<2.0,>=1.12.0->aiohttp!=4.0.0a0,!=4.0.0a1->s3fs) (0.2.0)
Requirement already satisfied: urllib3<1.27,>=1.25.4; python_version < "3.10" in /usr/lib/python3/dist-packages (from botocore<1.37.4,>=1.37.2->aiobotocore<3.0.0,>=2.5.4->s3fs) (1.25.8)
Requirement already satisfied: cffi in /home/deploy/.local/lib/python3.8/site-packages (from eccodes>=0.9.8->cfgrib; extra == "io"->xarray[io]) (1.17.1)
Requirement already satisfied: findlibs in /home/deploy/.local/lib/python3.8/site-packages (from eccodes>=0.9.8->cfgrib; extra == "io"->xarray[io]) (0.1.1)
Requirement already satisfied: pyparsing>=2.1.6 in /usr/lib/python3/dist-packages (from snuggs>=1.4.1->rasterio; extra == "io"->xarray[io]) (2.4.6)
Requirement already satisfied: soupsieve>1.2 in /home/deploy/.local/lib/python3.8/site-packages (from beautifulsoup4->pydap; python_version < "3.10" and extra == "io"->xarray[io]) (2.7)
Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.8/dist-packages (from Jinja2->pydap; python_version < "3.10" and extra == "io"->xarray[io]) (2.1.5)
Requirement already satisfied: pycparser in /home/deploy/.local/lib/python3.8/site-packages (from cffi->eccodes>=0.9.8->cfgrib; extra == "io"->xarray[io]) (2.22)
import zarr
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from scipy.signal import stft

Level 2 Data#

In this notebook we demonstrate the variety of different data available in the FAIR MAST dataset. In this example we are using level 2 MAST data, which includes cropping, interpolation, calibration, etc. of each signal, as well as mapping each diagnostic group try and follow IMAS naming convetions. The level 2 data is well-indexed data and follows the FAIR principles. Shots are also filtered using the plasma current to remove shots which were only used for testing, comissioning, machine calibration etc.

First we need to connect to the remote S3 storage bucket to access the data. Each shot from MAST is stored as a seperate Zarr file.

Using fsspec and xarray we can remotely read data directly over the web. In the example below we also turn on local file caching, allowing us to avoid reading over the network multiple times.

shot_id = 30421

endpoint_url = 'https://s3.echo.stfc.ac.uk'
url = f's3://mast/level2/shots/{shot_id}.zarr'

# Get a handle to the remote file
store = zarr.storage.FsspecStore.from_url(
    url,
    storage_options=dict(
        protocol='simplecache',
        target_protocol="s3",
        cache_storage='.cache',
        target_options=dict(
            anon=True, endpoint_url=endpoint_url, asynchronous=True
        )
    )
)

Summary Profiles#

The summary group provides a collection of general physics quantities for an experiment.

Hide code cell source

def plot_1d_profiles(profiles: xr.Dataset):
    """Helper function for plotting 1D profiles"""
    n = int(np.ceil(len(profiles.data_vars) / 2))
    fig, axes = plt.subplots(n, 2, figsize=(10, 2*n))
    axes = axes.flatten()

    for i, name in enumerate(profiles.data_vars.keys()):
        profiles[name].plot(x='time', ax=axes[i])

    for ax in axes:
        ax.grid('on', alpha=0.5)
        ax.set_xlim(profiles.time.min(), profiles.time.max())

    plt.tight_layout()
profiles = xr.open_zarr(store, group='summary')

plot_1d_profiles(profiles)
profiles
<xarray.Dataset> Size: 163kB
Dimensions:              (time: 2906)
Coordinates:
  * time                 (time) float64 23kB -0.0612 -0.06095 ... 0.6648 0.665
Data variables:
    greenwald_density    (time) float64 23kB ...
    ip                   (time) float64 23kB ...
    line_average_n_e     (time) float64 23kB ...
    neutron_rates_total  (time) float64 23kB ...
    power_nbi            (time) float64 23kB ...
    power_radiated       (time) float64 23kB ...
Attributes:
    name:          summary
    description:   Summary of physics quantities from a simulation or an expe...
    imas:          summary
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/5cffe610fef6ee6e9e72b966d58d46ae08c0a35ee6cfb481421a01375621532d.png

Pulse Schedule#

profiles = xr.open_zarr(store, group='pulse_schedule')

fig, axes = plt.subplots(2, 1, figsize=(10, 5))
axes = axes.flatten()
profiles['i_plasma'].plot(x='time', ax=axes[0])
profiles['n_e_line'].plot(x='time', ax=axes[1])


for ax in axes:
    ax.grid('on', alpha=0.5)
plt.tight_layout()

profiles
<xarray.Dataset> Size: 70kB
Dimensions:   (time: 2906)
Coordinates:
  * time      (time) float64 23kB -0.0612 -0.06095 -0.0607 ... 0.6648 0.665
Data variables:
    i_plasma  (time) float64 23kB ...
    n_e_line  (time) float64 23kB ...
Attributes:
    name:          pulse_schedule
    description:   Description of Pulse Schedule, described by subsystems wav...
    imas:          pulse_schedule
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/95eba18577d67e5b2b48ae88c82edcb66a2b0ea6b82659afe2029d3ba9422b09.png

Magnetics#

Magnetic diagnostics for equilibrium identification and plasma shape control.

profiles = xr.open_zarr(store, group='magnetics')

fig, axes = plt.subplots(4, 3, figsize=(8, 10))
axes = axes.flatten()

profiles['b_field_pol_probe_ccbv_field'].plot.line(x='time', ax=axes[0], add_legend=False)
profiles['b_field_pol_probe_obv_field'].plot.line(x='time', ax=axes[1], add_legend=False)
profiles['b_field_pol_probe_obr_field'].plot.line(x='time', ax=axes[2], add_legend=False)


profiles['b_field_pol_probe_omv_voltage'].plot.line(x='time_mirnov', ax=axes[3], add_legend=False)
profiles['b_field_pol_probe_cc_field'].plot.line(x='time_mirnov', ax=axes[4], add_legend=False)
profiles['b_field_tor_probe_cc_field'].plot.line(x='time_mirnov', ax=axes[5], add_legend=False)

profiles['b_field_tor_probe_saddle_field'].plot.line(x='time_saddle', ax=axes[6], add_legend=False)
profiles['b_field_tor_probe_saddle_voltage'].plot.line(x='time_saddle', ax=axes[7], add_legend=False)
profiles['b_field_tor_probe_omaha_voltage'].plot.line(x='time_omaha', ax=axes[8], add_legend=False)

profiles['flux_loop_flux'].plot.line(x='time', ax=axes[9], add_legend=False)
profiles['ip'].plot.line(x='time', ax=axes[10], add_legend=False)

for ax in axes:
    ax.grid('on', alpha=0.5)
plt.tight_layout()

profiles
<xarray.Dataset> Size: 335MB
Dimensions:                                      (
                                                  b_field_pol_probe_cc_channel: 5,
                                                  time_mirnov: 363201,
                                                  b_field_pol_probe_cc_geometry_channel: 40,
                                                  b_field_pol_probe_ccbv_channel: 40,
                                                  time: 3633,
                                                  ...
                                                  coordinate: 28,
                                                  b_field_tor_probe_saddle_m_geometry_channel: 12,
                                                  b_field_tor_probe_saddle_u_geometry_channel: 12,
                                                  b_field_tor_probe_saddle_voltage_channel: 12,
                                                  flux_loop_channel: 15,
                                                  flux_loop_geometry_channel: 44)
Coordinates: (12/25)
  * b_field_pol_probe_cc_channel                 (b_field_pol_probe_cc_channel) <U13 260B ...
  * b_field_pol_probe_cc_geometry_channel        (b_field_pol_probe_cc_geometry_channel) object 320B ...
  * b_field_pol_probe_ccbv_channel               (b_field_pol_probe_ccbv_channel) <U10 2kB ...
  * b_field_pol_probe_ccbv_geometry_channel      (b_field_pol_probe_ccbv_geometry_channel) object 320B ...
  * b_field_pol_probe_obr_channel                (b_field_pol_probe_obr_channel) <U9 684B ...
  * b_field_pol_probe_obr_geometry_channel       (b_field_pol_probe_obr_geometry_channel) object 152B ...
    ...                                           ...
  * flux_loop_channel                            (flux_loop_channel) <U12 720B ...
  * flux_loop_geometry_channel                   (flux_loop_geometry_channel) object 352B ...
  * time                                         (time) float64 29kB -0.0612 ...
  * time_mirnov                                  (time_mirnov) float64 3MB -0...
  * time_omaha                                   (time_omaha) float64 58MB -0...
  * time_saddle                                  (time_saddle) float64 291kB ...
Data variables: (12/46)
    b_field_pol_probe_cc_field                   (b_field_pol_probe_cc_channel, time_mirnov) float64 15MB ...
    b_field_pol_probe_cc_phi                     (b_field_pol_probe_cc_geometry_channel) float64 320B ...
    b_field_pol_probe_cc_r                       (b_field_pol_probe_cc_geometry_channel) float64 320B ...
    b_field_pol_probe_cc_z                       (b_field_pol_probe_cc_geometry_channel) float64 320B ...
    b_field_pol_probe_ccbv_field                 (b_field_pol_probe_ccbv_channel, time) float64 1MB ...
    b_field_pol_probe_ccbv_length                (b_field_pol_probe_ccbv_geometry_channel) float64 320B ...
    ...                                           ...
    b_field_tor_probe_saddle_u_z                 (b_field_tor_probe_saddle_u_geometry_channel, coordinate) float64 3kB ...
    b_field_tor_probe_saddle_voltage             (b_field_tor_probe_saddle_voltage_channel, time_saddle) float64 3MB ...
    flux_loop_flux                               (flux_loop_channel, time) float64 436kB ...
    flux_loop_r                                  (flux_loop_geometry_channel) float64 352B ...
    flux_loop_z                                  (flux_loop_geometry_channel) float64 352B ...
    ip                                           (time) float64 29kB -6.039e+...
Attributes:
    name:          magnetics
    description:   Magnetic diagnostics for equilibrium identification and pl...
    imas:          magnetics
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/007955984f760dc955133db59e74f9b611b52b2b3277d6af8b9942da2e0ccfa4.png

Looking at the spectrogram of one of the mirnov coils can show us information about the MHD modes. Here we see several mode instabilities occuring before the plasma is lost.

ds = profiles['b_field_pol_probe_omv_voltage'].isel(b_field_pol_probe_omv_channel=1)
# Parameters to limit the number of frequencies
nperseg = 2000  # Number of points per segment
nfft = 2000  # Number of FFT points

# Compute the Short-Time Fourier Transform (STFT)
sample_rate = 1/(ds.time_mirnov[1] - ds.time_mirnov[0])
f, t, Zxx = stft(ds, fs=int(sample_rate), nperseg=nperseg, nfft=nfft)

fig, ax = plt.subplots(figsize=(15, 5))
cax = ax.pcolormesh(t, f/1000, np.abs(Zxx), shading='nearest', cmap='jet', norm=LogNorm(vmin=1e-5))
ax.set_ylim(0, 50)
ax.set_title(f'Shot {shot_id}')
ax.set_ylabel('Frequency [Hz]')
ax.set_xlabel('Time [sec]')
plt.colorbar(cax, ax=ax)
plt.show()
_images/9ab9ab7f9ca0e54ac67cc66b0e755abdb5fc754df6b02e9ee56a5a9b040b37a4.png

Spectrometer Visible#

Spectrometer in visible light range diagnostic

profiles = xr.open_zarr(store, group='spectrometer_visible')
profiles['filter_spectrometer_dalpha_voltage'].plot.line(x='time')
profiles['filter_spectrometer_bes_voltage'].isel(bes_channel=0).plot.line(x='time_bes')
profiles
<xarray.Dataset> Size: 385MB
Dimensions:                             (time: 36321, bes_channel: 32,
                                         time_bes: 1452801, dalpha_channel: 3)
Coordinates:
  * bes_channel                         (bes_channel) <U13 2kB 'xbt/channel01...
  * dalpha_channel                      (dalpha_channel) <U13 156B 'XIM_DA/HM...
  * time                                (time) float64 291kB -0.0612 ... 0.6652
  * time_bes                            (time_bes) float64 12MB -0.0612 ... 0...
Data variables:
    density_gradient                    (time) float64 291kB ...
    filter_spectrometer_bes_voltage     (bes_channel, time_bes) float64 372MB ...
    filter_spectrometer_dalpha_voltage  (dalpha_channel, time) float64 872kB ...
Attributes:
    name:          spectrometer_visible
    description:   Spectrometer in visible light range diagnostic
    imas:          spectrometer_visible
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/4b391d33e0a4a7cccd3382bc72aade4b79ea941b0bee893b41dcff6be72a3fcb.png

PF Active#

profiles = xr.open_zarr(store, group='pf_active')
fig, axes = plt.subplots(3, 1)
axes = axes.flatten()

profiles['coil_current'].plot.line(x='time', ax=axes[0], add_legend=False)
profiles['coil_voltage'].plot.line(x='time', ax=axes[1], add_legend=False)
profiles['solenoid_current'].plot.line(x='time', ax=axes[2], add_legend=False)

plt.tight_layout()
profiles
<xarray.Dataset> Size: 437kB
Dimensions:                            (current_channel: 10, time: 2906,
                                        voltage_channel: 4,
                                        p2_inner_lower_coordinate_element: 12,
                                        p2_inner_upper_coordinate_element: 12,
                                        p2_outer_lower_coordinate_element: 8,
                                        p2_outer_upper_coordinate_element: 8,
                                        ...
                                        p4_upper_coordinate_element: 23,
                                        p5_lower_coordinate_element: 23,
                                        p5_upper_coordinate_element: 23,
                                        p6_lower_coordinate_element: 4,
                                        p6_upper_coordinate_element: 4,
                                        sol_coordinate_element: 656)
Coordinates: (12/16)
  * current_channel                    (current_channel) <U21 840B 'AMC_P2IL ...
  * p2_inner_lower_coordinate_element  (p2_inner_lower_coordinate_element) <U15 720B ...
  * p2_inner_upper_coordinate_element  (p2_inner_upper_coordinate_element) <U15 720B ...
  * p2_outer_lower_coordinate_element  (p2_outer_lower_coordinate_element) <U14 448B ...
  * p2_outer_upper_coordinate_element  (p2_outer_upper_coordinate_element) <U14 448B ...
  * p3_lower_coordinate_element        (p3_lower_coordinate_element) <U14 448B ...
    ...                                 ...
  * p5_upper_coordinate_element        (p5_upper_coordinate_element) <U15 1kB ...
  * p6_lower_coordinate_element        (p6_lower_coordinate_element) <U14 224B ...
  * p6_upper_coordinate_element        (p6_upper_coordinate_element) <U14 224B ...
  * sol_coordinate_element             (sol_coordinate_element) <U16 42kB 'co...
  * time                               (time) float64 23kB -0.0612 ... 0.665
  * voltage_channel                    (voltage_channel) <U12 192B '/xdc/pf/f...
Data variables: (12/55)
    coil_current                       (current_channel, time) float64 232kB ...
    coil_voltage                       (voltage_channel, time) float64 93kB ...
    p2_inner_lower_height              (p2_inner_lower_coordinate_element) float32 48B ...
    p2_inner_lower_r                   (p2_inner_lower_coordinate_element) float32 48B ...
    p2_inner_lower_width               (p2_inner_lower_coordinate_element) float32 48B ...
    p2_inner_lower_z                   (p2_inner_lower_coordinate_element) float32 48B ...
    ...                                 ...
    p6_upper_z                         (p6_upper_coordinate_element) float32 16B ...
    sol_height                         (sol_coordinate_element) float32 3kB ...
    sol_r                              (sol_coordinate_element) float32 3kB ...
    sol_width                          (sol_coordinate_element) float32 3kB ...
    sol_z                              (sol_coordinate_element) float32 3kB ...
    solenoid_current                   (time) float64 23kB 8.764e+03 ... 780.2
Attributes:
    name:          pf_active
    description:   
    imas:          pf_active
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/90588cce9eb90e3a4e9517a794c076c5cf893a3ae3ccd2a80128b2ec257a1226.png

Soft X-rays#

profiles = xr.open_zarr(store, group='soft_x_rays')
fig, axes = plt.subplots(3, 1)


profiles['horizontal_cam_lower'].plot.line(x='time', ax=axes[1], add_legend=False)
axes[1].set_ylim(0, 0.02)

profiles['horizontal_cam_upper'].plot.line(x='time', ax=axes[2], add_legend=False)
axes[2].set_ylim(0, 0.02)

if "tangential_cam" in profiles:
    profiles['tangential_cam'].plot.line(x='time', ax=axes[0], add_legend=False)
    axes[0].set_ylim(0, 0.2)

plt.tight_layout()
profiles
<xarray.Dataset> Size: 16MB
Dimensions:                                (horizontal_cam_lower_channel: 18,
                                            time: 36321,
                                            horizontal_cam_lower_geometry_channel: 18,
                                            horizontal_cam_upper_channel: 18,
                                            horizontal_cam_upper_geometry_channel: 18,
                                            inner_vertical_cam_geometry_channel: 12,
                                            outer_vertical_cam_geometry_channel: 12,
                                            tangential_cam_channel: 18,
                                            tangential_cam_geometry_channel: 18,
                                            third_horizontal_cam_geometry_channel: 18)
Coordinates:
  * horizontal_cam_lower_channel           (horizontal_cam_lower_channel) <U14 1kB ...
  * horizontal_cam_lower_geometry_channel  (horizontal_cam_lower_geometry_channel) <U23 2kB ...
  * horizontal_cam_upper_channel           (horizontal_cam_upper_channel) <U14 1kB ...
  * horizontal_cam_upper_geometry_channel  (horizontal_cam_upper_geometry_channel) <U23 2kB ...
  * inner_vertical_cam_geometry_channel    (inner_vertical_cam_geometry_channel) <U21 1kB ...
  * outer_vertical_cam_geometry_channel    (outer_vertical_cam_geometry_channel) <U21 1kB ...
  * tangential_cam_channel                 (tangential_cam_channel) <U12 864B ...
  * tangential_cam_geometry_channel        (tangential_cam_geometry_channel) <U17 1kB ...
  * third_horizontal_cam_geometry_channel  (third_horizontal_cam_geometry_channel) <U23 2kB ...
  * time                                   (time) float64 291kB -0.0612 ... 0...
Data variables: (12/33)
    horizontal_cam_lower                   (horizontal_cam_lower_channel, time) float64 5MB ...
    horizontal_cam_lower_endpoint_r        (horizontal_cam_lower_geometry_channel) float64 144B ...
    horizontal_cam_lower_endpoint_z        (horizontal_cam_lower_geometry_channel) float64 144B ...
    horizontal_cam_lower_origin_r          (horizontal_cam_lower_geometry_channel) float64 144B ...
    horizontal_cam_lower_origin_z          (horizontal_cam_lower_geometry_channel) float64 144B ...
    horizontal_cam_lower_phi               (horizontal_cam_lower_geometry_channel) float64 144B ...
    ...                                     ...
    tangential_cam_phi                     (tangential_cam_geometry_channel) float64 144B ...
    third_horizontal_cam_endpoint_r        (third_horizontal_cam_geometry_channel) float64 144B ...
    third_horizontal_cam_endpoint_z        (third_horizontal_cam_geometry_channel) float64 144B ...
    third_horizontal_cam_origin_r          (third_horizontal_cam_geometry_channel) float64 144B ...
    third_horizontal_cam_origin_z          (third_horizontal_cam_geometry_channel) float64 144B ...
    third_horizontal_cam_phi               (third_horizontal_cam_geometry_channel) float64 144B ...
Attributes:
    name:          soft_x_rays
    description:   Soft X-rays tomography diagnostic
    imas:          soft_x_rays
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/9efd0e8ec080d14168a2f7093433c6d227cec8e08a3496cd41f15ae08552d2bb.png

Thomson Profiles#

Thomson scattering measurements in a tokamak provide information about the plasma’s electron temperature and density profiles. The diagnostic analyses the scattering of laser light off free electrons in the plasma from a number of radial channels.

Below we plot the following profiles measured by the Thomson diagnostic

  • \(T_e\) - Electron temperature

  • \(N_e\) - Electron density

  • \(P_e\) - Electron pressure

profiles = xr.open_zarr(store, group='thomson_scattering')
profiles

fig, axes = plt.subplots(3, 1)
axes = axes.flatten()
profiles.t_e.plot(x='time', y='major_radius', ax=axes[0])
profiles.n_e.plot(x='time', y='major_radius', ax=axes[1])
profiles.p_e.plot(x='time', y='major_radius', ax=axes[2])
plt.tight_layout()

profiles
<xarray.Dataset> Size: 425kB
Dimensions:       (major_radius: 120, time: 146)
Coordinates:
  * major_radius  (major_radius) float64 960B 0.3 0.31 0.32 ... 1.47 1.48 1.49
  * time          (time) float64 1kB -0.0612 -0.0562 -0.0512 ... 0.6588 0.6638
Data variables:
    n_e           (major_radius, time) float64 140kB ...
    n_e_core      (time) float64 1kB ...
    p_e           (major_radius, time) float64 140kB ...
    t_e           (major_radius, time) float64 140kB ...
    t_e_core      (time) float64 1kB ...
Attributes:
    name:          thomson_scattering
    description:   Thomson scattering diagnostic
    imas:          thomson_scattering
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/595b613ee28ffe00d4b7da6737d4259f33aba90390cb6ff36a001516c9f3346b.png
fig, axes = plt.subplots(2, 1)
profiles['t_e_core'].plot(x='time', ax=axes[0])
profiles['n_e_core'].plot(x='time', ax=axes[1])
for ax in axes:
    ax.grid('on', alpha=0.5)
plt.tight_layout()
profiles
<xarray.Dataset> Size: 425kB
Dimensions:       (major_radius: 120, time: 146)
Coordinates:
  * major_radius  (major_radius) float64 960B 0.3 0.31 0.32 ... 1.47 1.48 1.49
  * time          (time) float64 1kB -0.0612 -0.0562 -0.0512 ... 0.6588 0.6638
Data variables:
    n_e           (major_radius, time) float64 140kB ...
    n_e_core      (time) float64 1kB ...
    p_e           (major_radius, time) float64 140kB ...
    t_e           (major_radius, time) float64 140kB ...
    t_e_core      (time) float64 1kB ...
Attributes:
    name:          thomson_scattering
    description:   Thomson scattering diagnostic
    imas:          thomson_scattering
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/b7990a9896dfa057533ac81bcac228d492598db749f056cb6d282596f0f93077.png

CXRS Profiles#

Charge Exchange Recombination Spectroscopy (CXRS) measurements provide information about ion temperature and plasma rotation. This diagnostic analyses the light emitted from charge exchange reactions between injected neutral beams and plasma ions.

Below we plot the following profiles measured by the CXRS diagnostic

  • \(T_i\) - Ion temperature

  • \(V_i\) - Ion velocity

profiles = xr.open_zarr(store, group='charge_exchange')

fig, axes = plt.subplots(2, 1)
profiles['t_i'].plot(x='time', y='major_radius', ax=axes[0], vmax=1000)
profiles['v_i'].plot(x='time', y='major_radius', ax=axes[1], vmax=1000)
plt.tight_layout()
profiles
<xarray.Dataset> Size: 376kB
Dimensions:       (major_radius: 160, time: 146)
Coordinates:
  * major_radius  (major_radius) float64 1kB 0.0 0.01 0.02 ... 1.57 1.58 1.59
  * time          (time) float64 1kB -0.0612 -0.0562 -0.0512 ... 0.6588 0.6638
Data variables:
    t_i           (major_radius, time) float64 187kB ...
    v_i           (major_radius, time) float64 187kB ...
Attributes:
    name:          charge_exchange
    description:   
    imas:          charge_exchange
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/aab813631395335b4b20d96ba2d02ccbcba03fd1396e62c8a50270a4f1f6fb91.png

Equilibrium#

profiles = xr.open_zarr(store, group='equilibrium')

profile_1d = profiles[["beta_tor_normal", "wmhd", "li", "elongation", "triangularity_upper", "q95", "vloop_dynamic", "ip_rating", "lcfs_r", "lcfs_z"]]
plot_1d_profiles(profile_1d)

profiles
<xarray.Dataset> Size: 10MB
Dimensions:              (time: 146, z: 65, major_radius: 65,
                          n_boundary_coords: 139, profile_r: 65,
                          n_x_points_r: 2, n_x_points_z: 2)
Coordinates:
  * major_radius         (major_radius) float64 520B 0.06 0.09 ... 1.95 1.98
  * n_boundary_coords    (n_boundary_coords) float32 556B 0.0 1.0 ... 138.0
  * n_x_points_r         (n_x_points_r) <U16 128B 'EFM_XPOINT1_R(C)' 'EFM_XPO...
  * n_x_points_z         (n_x_points_z) <U16 128B 'EFM_XPOINT1_Z(C)' 'EFM_XPO...
  * profile_r            (profile_r) float32 260B 0.0 0.01562 ... 0.9844 1.0
  * time                 (time) float64 1kB -0.0612 -0.0562 ... 0.6588 0.6638
  * z                    (z) float32 260B -2.0 -1.938 -1.875 ... 1.875 1.938 2.0
Data variables: (12/35)
    beta_pol             (time) float64 1kB ...
    beta_tor             (time) float64 1kB ...
    beta_tor_normal      (time) float64 1kB ...
    bphi_rmag            (time) float64 1kB ...
    bvac_rmag            (time) float64 1kB ...
    da_rating            (time) float64 1kB ...
    ...                   ...
    triangularity_upper  (time) float64 1kB ...
    vloop_dynamic        (time) float64 1kB ...
    vloop_static         (time) float64 1kB ...
    wmhd                 (time) float64 1kB ...
    x_point_r            (n_x_points_r, time) float64 2kB ...
    x_point_z            (n_x_points_z, time) float64 2kB ...
Attributes:
    name:          equilibrium
    description:   Description of a 2D, axi-symmetric, tokamak equilibrium; r...
    imas:          equilibrium
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/047faae06a216105fdf33eeeacd513b119a2db3fe52eb0cf642eb5cc272a5778.png
fig, axes = plt.subplots(1, 3, figsize=(10, 5))

profiles['j_phi'].isel(time=50).plot(ax=axes[0], x='major_radius')
profiles['psi'].isel(time=50).plot(ax=axes[1], x='major_radius')
profiles['q'].isel(time=50).plot(ax=axes[2])
plt.tight_layout()
_images/b18151fdc9ac106a94ca2836c3bbf95b571bd4c33da3d7c31b9944ba052e5da5.png

Gas Injection#

profiles = xr.open_zarr(store, group='gas_injection')

plot_1d_profiles(profiles[["inboard_total", "outboard_total", "pressure", "total_injected"]])
plt.tight_layout()
profiles
<xarray.Dataset> Size: 862kB
Dimensions:               (time: 2906, target_valve_channel: 12,
                           valve_channel: 20)
Coordinates:
  * target_valve_channel  (target_valve_channel) <U14 672B '/xdc/gas/t/g1' .....
  * time                  (time) float64 23kB -0.0612 -0.06095 ... 0.6648 0.665
  * valve_channel         (valve_channel) <U16 1kB '/xdc/gas/f/tc5a' ... '/xd...
Data variables:
    inboard_total         (time) float64 23kB ...
    outboard_total        (time) float64 23kB ...
    pressure              (time) float64 23kB ...
    total_injected        (time) float64 23kB ...
    valve_target_voltage  (target_valve_channel, time) float64 279kB ...
    valve_voltage         (valve_channel, time) float64 465kB ...
Attributes:
    name:          gas_injection
    description:   Gas injection by a system of pipes and valves.
    imas:          gas_injection
    license_name:  Creative Commons 4.0 BY-SA
    license_url:   https://creativecommons.org/licenses/by-sa/4.0/
_images/507da3ca913795e04d023a8d28bc8798154d461bb0b213481d143ad22d0bea5d.png