An interactive dashboard for exploring tokamak plasma shot data. Point it at a shot-statistics file and get an instant browser UI for slicing, visualising, and comparing shots.

cluster_id, cluster_name columns appended when clustering has been run.--shap-data).reference_shot_col in config).TraceBackend or ShotDataBackend and registering via plugins: in config.Python ≥ 3.12
pip install nice-shot
pip install "nice-shot[shap]" # + SHAP plots, xarray, matplotlib
nice-shot path/to/shot_stats.parquet
SHOT_DATA is the only required argument — everything else has a default. Open http://localhost:8050 in a browser.
By default nice-shot runs under gunicorn with 4 worker processes, which supports multiple concurrent users. On first run, UMAP/PCA is computed in the master process and cached; subsequent starts are instant.
For local development with hot-reload use --debug:
nice-shot path/to/shot_stats.parquet --debug
| Flag | Default | Description |
|---|---|---|
SHOT_DATA |
— (required) | Shot statistics file (.csv or .parquet) |
--config PATH |
nice_shot/config.yaml |
YAML config file |
--data-dir PATH |
data/mastu/ |
Directory of per-shot files (parquet backend) |
--projection PATH |
— | Pre-computed 2-D embedding; skips UMAP/PCA entirely |
--shap-data PATH |
— | SHAP values NetCDF (.nc); enables the SHAP tab |
--workers N |
4 |
Gunicorn worker processes (ignored in --debug mode) |
--port PORT |
8050 |
Port to listen on |
--debug |
off | Use the single-process Flask dev server instead of gunicorn |
Every option in nice_shot/config.yaml also has a CLI flag of the same name. An explicit CLI flag overrides the config file, which overrides the built-in default:
| Flag | Config field |
|---|---|
--backend NAME |
backend |
--signals SIGNAL [SIGNAL ...] |
signals |
--min-time SECONDS |
time_window.min_time |
--max-time SECONDS |
time_window.max_time |
--timebase-hz HZ |
uda.timebase_hz |
--projection-method {umap,pca} |
projection_method |
--variable-column NAME |
variable_column |
--umap-features COLUMN [COLUMN ...] |
umap_features |
--umap-exclude-features COLUMN [COLUMN ...] |
umap_exclude_features |
--reference-shot-col NAME |
reference_shot_col |
--plugins MODULE [MODULE ...] |
plugins |
--backend-option KEY=VALUE (repeatable) |
backend_options (merged per-key) |
Run nice-shot --help for full descriptions.
Edit nice_shot/config.yaml (or pass --config to point elsewhere):
backend: parquet # parquet | uda | sal
signals: # columns shown in the time-trace panel
- ip
- ne
- dalpha
time_window:
min_time: 0.0
max_time: 1.0
projection_method: umap # umap | pca
umap_features: # omit to use all numeric columns
- ip_max
- ne_max
- bt_max
reference_shot_col: reference__number # omit to hide the feature
Any of these can be overridden for a single run with the matching CLI flag — see Config-backed flags above.
Shot statistics file (SHOT_DATA) — a flat .parquet or .csv with one row per shot. The shot ID column is detected automatically (shot_id, shot, pulse, number, …).
Per-shot traces (--data-dir) — one .parquet or .csv per shot, laid out as:
<data-dir>/<any-subdir>/<shot_id>.parquet
Each file needs a time column and one column per configured signal.
Pre-computed projection (--projection) — a .npy (shape (n,2) or (n,3)), .csv, or .parquet with shot ID and two coordinate columns.
SHAP values (--shap-data) — an xarray NetCDF file with shot_id and feature dimensions.
See docs/data-formats.md for full schema details.
uv run --dev zensical serve
Opens the full documentation at http://localhost:8000.