bouquet

The bouquet HDF5 archive — schema v2

Authoritative description of the on-disk layout written by bouquet ≥ 1.0.0 (schema v2 first shipped in the 1.0.0 release). The single source of truth in code is bouquet/schema.py (SCHEMA_VERSION, PROFILE_UNITS, fixed dataset names, write_profile / find_bytes_dataset); this document mirrors it for human readers. Prefer reading archives through bouquet.BouquetArchive or the functional readers (load_equilibrium, load_baseline_profiles, select_indices, load_config) rather than raw h5py — see workflows.md for worked examples.

Layout

{header}.h5                            file attrs: schema_version (=2),
│                                      bouquet_version, created, updated
├── config_json                        JSON dump of the run BouquetConfig
│                                      (root copy = most recent write; the
│                                      per-scan copies below are authoritative)
└── scan/<scan_key>/                   one group per scan point / time slice
    ├── config_json                    this slice's exact config
    ├── _baseline/                     written once per scan point
    │   ├── eqdsk, [pfile]             raw byte-perfect g-file / p-file
    │   ├── psi_N, psi_N_kinetic
    │   ├── n_e, T_e, n_i, T_i         kinetic profiles
    │   ├── pressure[, pressure_thermal]
    │   ├── j_phi[, j_BS, j_inductive] separated toroidal currents
    │   ├── sigma_ne/te/ni/ti/jphi     the uncertainty envelope used
    │   ├── [aux_<name>, sigma_aux_<name>]   switchboard channels
    │   ├── [recon_lcfs_ref]           10k-pt LCFS reference (boundary metric)
    │   ├── [x_points], [coil_currents, coil_names]
    │   └── attrs: Ip_target, l_i_target, source_kind, [diverted]
    └── <count>/                       one group per accepted draw
        │                              (integer; gaps = rejected draws)
        ├── eqdsk, [pfile]             raw bytes, fixed names
        ├── psi_N[, psi_N_kinetic]
        ├── j_phi, j_BS, j_inductive[, j_BS,edge]
        ├── n_e, T_e, n_i, T_i, w_ExB[, Zeff]
        ├── [pressure, pressure_thermal]
        ├── [aux_<name>]               perturbed switchboard channels
        ├── [coil_currents, coil_names]
        ├── [perturbed_lcfs_ref], [x_points]
        ├── [eq_fsa/]                  live-equilibrium flux-surface averages
        │   ├── psi_N                  (subgroup; see below)
        │   ├── F, avg_inv_R, avg_inv_R2, avg_B2
        │   └── q, dV_dpsi, f_trap, B_avg
        └── attrs: l_i(1), l_i(3), count, homotopy_*, max_F_drift_pct,
                   max_VSC_drift_pct, in_spec, inspec_*, l_i_target_used,
                   [diverted], [passes_coil_filter, passes_boundary_filter,
                   selected]           ← filter flags, written post-hoc

Conventions

Legacy (pre-v2) archives

Schema v2 was a clean break (2026-07). Files without the schema_version attr are pre-v2: BouquetArchive opens them with a warning (byte blobs still resolve via a suffix scan; profile keys keep their v1 bracketed names), and load_equilibrium raises a clear error. Regenerate old archives with the current package for full support.