History / version AEDTW9VK · saved

Cite this version

@software{constellaration_2026,
  author = {ScienceHub editor},
  title = {ConStellaration: dataset},
  version = {AEDTW9VK},
  year = {2026},
  publisher = {ScienceHub},
  url = {https://sciencehub.sh/sciencehub-team/constellaration/notebooks/dataset/history/ver_01M5Z4AJH24XDRYJEBAEDTW9VK}
}
editor, S. (2026). ConStellaration: dataset (Version AEDTW9VK) [Computer software]. ScienceHub. https://sciencehub.sh/sciencehub-team/constellaration/notebooks/dataset/history/ver_01M5Z4AJH24XDRYJEBAEDTW9VK
cff-version: 1.2.0
message: "If you use this version, cite it as below."
title: "ConStellaration: dataset"
type: software
authors:
  - family-names: "editor"
    given-names: "ScienceHub"
version: "AEDTW9VK"
date-released: "2026-10-27"
url: "https://sciencehub.sh/sciencehub-team/constellaration/notebooks/dataset/history/ver_01M5Z4AJH24XDRYJEBAEDTW9VK"

This address names exactly this version. The project page cites all versions.

20 cells changed against the version before: +245 −5 lines.

ChangedScript header+6−1
Added: # /// script
Added: # requires-python = ">=3.11"
Added: # dependencies = ["marimo>=0.25.1", "numpy", "pandas", "pyarrow", "matplotlib"]
Added: # ///
Added:
import marimo
__generated_with = "0.25.1"
Removed: app = marimo.App()
Added: app = marimo.App(width="medium", app_title="The ConStellaration dataset against its benchmarks")
ChangedSetup cell+30−1
Removed: import marimo as mo
Added: import numpy as np
Added: import pandas as pd
Added:
Added: DATA = "data/metrics.parquet"
Added: TOLERANCE = 0.01
Added:
Added: # Bounds of constellaration 0.2.6 (problems.py), as (column, upper or
Added: # lower, bound). "log10_qi" and "abs_edge_iota" are derived in `violations`.
Added: CONSTRAINTS = {
Added: "geometrical": [
Added: ("aspect_ratio", "upper", 4.0),
Added: ("average_triangularity", "upper", -0.5),
Added: ("abs_edge_iota", "lower", 0.3),
Added: ],
Added: "simple_to_build": [
Added: ("aspect_ratio", "upper", 10.0),
Added: ("abs_edge_iota", "lower", 0.25),
Added: ("log10_qi", "upper", -4.0),
Added: ("edge_mirror_ratio", "upper", 0.2),
Added: ("max_elongation", "upper", 5.0),
Added: ],
Added: "mhd_stable": [
Added: ("abs_edge_iota", "lower", 0.25),
Added: ("log10_qi", "upper", -3.5),
Added: ("edge_mirror_ratio", "upper", 0.25),
Added: ("flux_compression", "upper", 0.9),
Added: ("vacuum_well", "lower", 0.0),
Added: ],
Added: }
Added: TITLES = {"geometrical": "Geometrical", "simple_to_build": "Simple-to-build QI", "mhd_stable": "MHD-stable QI"}
RemovedCell−3
Removed: mo.md("""
Removed: # dataset
Removed: """)
AddedFunction load_metrics+10
Added: def load_metrics(path: str = DATA) -> pd.DataFrame:
Added: """The metrics of the 158,685 ConStellaration boundaries that passed the forward model.
Added:
Added: One row per boundary: `id` (the dataset's plasma_config_id),
Added: `n_field_periods`, `optimiser` (DESC or VMEC++), and eleven of the twelve metrics of
Added: constellaration's forward model under shorter names (all but the aspect
Added: ratio over edge rotational transform). Values are stored as
Added: 32-bit floats.
Added: """
Added: return pd.read_parquet(path)
AddedFunction violations+20
Added: def violations(problem: str, metrics: pd.DataFrame) -> pd.DataFrame:
Added: """Normalised constraint violations of every row for one benchmark problem.
Added:
Added: (value − bound)/|bound| for upper bounds and (bound − value)/|bound| for
Added: lower bounds, as constellaration computes them; positive means broken.
Added: The vacuum-well bound is 0, and the evaluator divides by 0.1 instead.
Added: One column per constraint plus `worst`, the largest violation.
Added: """
Added: derived = metrics.assign(
Added: abs_edge_iota=metrics["edge_iota_per_period"].abs(),
Added: log10_qi=np.log10(metrics["qi"]),
Added: )
Added: out = {}
Added: for column, side, bound in CONSTRAINTS[problem]:
Added: scale = abs(bound) if bound != 0 else 0.1
Added: sign = 1 if side == "upper" else -1
Added: out[f"{column} {'≤' if side == 'upper' else '≥'} {bound:g}"] = sign * (derived[column] - bound) / scale
Added: table = pd.DataFrame(out, index=metrics.index)
Added: table["worst"] = table.max(axis=1)
Added: return table
AddedFunction closest+15
Added: def closest(problem: str, n: int = 10, metrics: pd.DataFrame | None = None) -> pd.DataFrame:
Added: """The n rows nearest to feasibility for a problem, with their worst violation and the constraint behind it.
Added:
Added: Their `id` selects the full boundary in the Hugging Face dataset, which
Added: makes these rows natural starting points for an optimiser.
Added: """
Added: metrics = load_metrics() if metrics is None else metrics
Added: v = violations(problem, metrics)
Added: best = v["worst"].nsmallest(n).index
Added: return pd.DataFrame({
Added: "id": metrics.loc[best, "id"],
Added: "n_field_periods": metrics.loc[best, "n_field_periods"],
Added: "worst violation": v.loc[best, "worst"],
Added: "binding constraint": v.loc[best].drop(columns="worst").idxmax(axis=1),
Added: }).reset_index(drop=True)
AddedCell+2
Added: import marimo as mo
Added: import matplotlib.pyplot as plt
AddedCell+18
Added: mo.md(r"""
Added: # The ConStellaration dataset against its benchmarks
Added:
Added: Proxima Fusion's ConStellaration dataset holds 182,222 stellarator plasma
Added: boundaries, generated to be close to quasi-isodynamic (QI), together with
Added: the metrics of a fixed forward model for the 158,685 of them on which that
Added: model succeeded ([Cadena et al. 2025](https://arxiv.org/abs/2506.19583)).
Added: About 149,000 come from DESC optimisations towards sampled omnigenous
Added: target fields and about 10,000 from optimisations with VMEC++ in the loop;
Added: the field periods run from 1 to 5. The same paper defines three
Added: optimisation benchmarks on these metrics.
Added:
Added: How many of these boundaries already solve a benchmark, and how far are
Added: the rest? This notebook applies each problem's constraints, with the
Added: evaluator's 1 % tolerance, to the stored metrics. The answer matters to
Added: anyone who wants to start an optimiser from the data or train a
Added: generative model on it.
Added: """)
AddedCell+2
Added: metrics = load_metrics()
Added: table = {problem: violations(problem, metrics) for problem in CONSTRAINTS}
AddedCell+16
Added: _summary, _each = [], []
Added: for _problem, _v in table.items():
Added: _closest = _v["worst"].idxmin()
Added: _summary.append({
Added: "problem": TITLES[_problem],
Added: "feasible rows": int((_v["worst"] <= TOLERANCE).sum()),
Added: "smallest worst violation": round(float(_v["worst"].min()), 3),
Added: "binding at the closest row": _v.drop(columns="worst").loc[_closest].idxmax(),
Added: })
Added: for _c in _v.columns.drop("worst"):
Added: _each.append({"problem": TITLES[_problem], "constraint": _c, "rows meeting it": int((_v[_c] <= TOLERANCE).sum())})
Added: mo.vstack([
Added: mo.md(f"Rows evaluated: **{len(metrics):,}**."),
Added: mo.ui.table(pd.DataFrame(_summary), selection=None),
Added: mo.ui.table(pd.DataFrame(_each), selection=None, page_size=13),
Added: ])
AddedCell+18
Added: mo.md(r"""
Added: **No boundary in the dataset is feasible for any of the three problems.**
Added: The nearest misses break a constraint by 20 to 27 % of its bound. Each
Added: constraint on its own is met by many rows; it is their combination that
Added: the data does not reach. For the geometrical problem the limit is the
Added: aspect ratio: only 552 rows meet A ≤ 4 within the tolerance, and none of
Added: them combines it with strongly negative triangularity and enough
Added: rotational transform. For the two QI problems it is the QI residual
Added: itself: within the tolerance, 9 rows meet log₁₀ QI ≤ −4 and 169 meet
Added: log₁₀ QI ≤ −3.5.
Added:
Added: The paper reports the same situation indirectly. Its generative-model
Added: experiment had to relax problems 1 and 2 to find 41 and 52 feasible
Added: training points (§5, Fig. 8), and Ran et al. (2025, v5, §6.1.2) note
Added: that sweeping the released designs gives no non-zero score. Every
Added: non-zero leaderboard score therefore comes from boundaries outside the
Added: dataset.
Added: """)
AddedCell+8
Added: mo.md(r"""
Added: ## How much relaxation the data needs
Added:
Added: Raise the tolerance to see how quickly the dataset starts to contain
Added: "feasible" boundaries. At a tolerance of 0.25 an aspect ratio of 5 passes
Added: the bound of 4, a QI residual ten times the bound passes (log₁₀ QI of −3
Added: against −4), and the vacuum well may reach −0.025.
Added: """)
AddedCell+2
Added: tolerance = mo.ui.slider(0.01, 1.0, step=0.01, value=0.3, label="Tolerance", show_value=True, full_width=True)
Added: tolerance
AddedCell+17
Added: _fig, _ax = plt.subplots(figsize=(7, 3.6))
Added: _grid = np.linspace(0, 1, 201)
Added: for (_problem, _v), _color in zip(table.items(), ("#1f2328", "#0969da", "#9a6700")):
Added: _sorted = np.sort(_v["worst"].to_numpy())
Added: _ax.plot(_grid, np.searchsorted(_sorted, _grid, side="right"), color=_color, lw=1.8, label=TITLES[_problem])
Added: _ax.axvline(TOLERANCE, color="#cf222e", lw=0.8, ls="--")
Added: _ax.text(TOLERANCE + 0.01, 1.5, "evaluator's tolerance", color="#cf222e", fontsize=8)
Added: _ax.axvline(tolerance.value, color="#57606a", lw=0.8)
Added: _ax.set_yscale("symlog", linthresh=1)
Added: _ax.set_xlabel("tolerance on the normalised constraint violation")
Added: _ax.set_ylabel("rows meeting every constraint")
Added: _ax.legend(frameon=False, loc="upper left")
Added: for _side in ("top", "right"):
Added: _ax.spines[_side].set_visible(False)
Added: _fig.tight_layout()
Added: _counts = ", ".join(f"{TITLES[p]} {int((v['worst'] <= tolerance.value).sum()):,}" for p, v in table.items())
Added: mo.vstack([_fig, mo.md(f"At tolerance {tolerance.value:.2f}: {_counts}.")])
AddedCell+12
Added: mo.md(r"""
Added: ## QI quality against coil simplicity
Added:
Added: The two QI problems reward a large normalised magnetic gradient scale
Added: length $\tilde L_{\nabla B}$, a stand-in for coils that can sit far from
Added: the plasma, while asking for a small QI residual. Boundaries with a
Added: smaller QI residual tend to have a longer $\tilde L_{\nabla B}$
Added: (Spearman ρ = −0.34), but the longest $\tilde L_{\nabla B}$ falls as the
Added: residual bound tightens: 13.5 at log₁₀ QI ≤ −2.5, 7.1 at −3.5 and 4.6 at
Added: −4. The dashed lines are the
Added: two QI bounds.
Added: """)
AddedCell+21
Added: _fig, _ax = plt.subplots(figsize=(7, 4))
Added: _x = np.log10(metrics["qi"].to_numpy())
Added: _y = metrics["gradient_scale_length"].to_numpy()
Added: _ok = np.isfinite(_x) & np.isfinite(_y)
Added: _h = _ax.hexbin(_x[_ok], _y[_ok], gridsize=70, bins="log", cmap="Greys", mincnt=1)
Added: for _bound in (-4.0, -3.5):
Added: _ax.axvline(_bound, color="#0969da", lw=0.8, ls="--")
Added: _ax.set_xlabel("log₁₀ QI residual")
Added: _ax.set_ylabel("normalised L∇B")
Added: _fig.colorbar(_h, ax=_ax, label="boundaries")
Added: for _side in ("top", "right"):
Added: _ax.spines[_side].set_visible(False)
Added: _fig.tight_layout()
Added: _best = metrics.loc[_x <= -3.5, "gradient_scale_length"]
Added: mo.vstack([
Added: _fig,
Added: mo.md(
Added: f"Of the {len(_best)} boundaries with log₁₀ QI ≤ −3.5 without the tolerance, the longest normalised gradient scale "
Added: f"length is {_best.max():.2f}; the paper's baseline reaches 8.61 on the simple-to-build problem."
Added: ),
Added: ])
AddedCell+16
Added: mo.md(r"""
Added: ## Starting points
Added:
Added: The rows nearest to feasibility are still useful as starting points. The
Added: table lists them for the problem you choose; `closest(problem, n)` returns
Added: the same table from Python, and the `id` selects the boundary in the
Added: Hugging Face dataset:
Added:
Added: ```python
Added: from datasets import load_dataset
Added:
Added: ds = load_dataset("proxima-fusion/constellaration", split="train",
Added: columns=["plasma_config_id", "boundary.json"])
Added: row = ds.filter(lambda r: r["plasma_config_id"] == "…")[0]
Added: ```
Added: """)
AddedCell+2
Added: problem = mo.ui.dropdown(options={v: k for k, v in TITLES.items()}, value="MHD-stable QI", label="Problem")
Added: problem
AddedCell+1
Added: mo.ui.table(closest(problem.value, 15, metrics), selection=None)
AddedCell+29
Added: mo.md(r"""
Added: ## Data, limits and references
Added:
Added: **Data.** `data/metrics.parquet` holds the metric columns of the `default`
Added: configuration of
Added: [proxima-fusion/constellaration](https://huggingface.co/datasets/proxima-fusion/constellaration)
Added: (revision `3346beff`, 26 October 2026, MIT licence) for every row with
Added: metrics, renamed and stored as 32-bit floats, without the boundaries.
Added: `optimiser` is VMEC++ where the row has VMEC++ optimisation settings and
Added: DESC otherwise. `extract.sql` in this folder writes the file.
Added:
Added: **Limits.** The stored metrics come from the forward model of the paper
Added: (the dataset's error column is `misc.has_neurips_2025_forward_model_error`),
Added: not from a fresh run of constellaration 0.2.6. Upstream describes the
Added: numerical differences between the paper's 0.2.1 and 0.2.6 as negligible
Added: apart from the sign of the rotational transform. The constraints here use
Added: its absolute value, as 0.2.6 does; 10,113 rows have negative rotational
Added: transform and would have failed under 0.2.1. A difference of a few
Added: percent between the stored metrics and a fresh evaluation would not
Added: change any count above, since the nearest row misses by about 20 %.
Added:
Added: Cadena, S. A. et al. (2025). ConStellaration: A dataset of QI-like
Added: stellarator plasma boundaries and optimization benchmarks. *NeurIPS 2025
Added: Datasets and Benchmarks Track*. [arXiv:2506.19583](https://arxiv.org/abs/2506.19583).
Added:
Added: Ran, N., Wang, Y., Zhang, X., Li, Z., Ran, Q., Li, W. and Allmendinger, R.
Added: (2025). ExLLM: Experience-enhanced LLM optimization for molecular design
Added: and beyond. [arXiv:2502.12845](https://arxiv.org/abs/2502.12845).
Added: """)