boss_bench

Source code for boss_bench.data

"""Find and read the BoSS data files."""

import glob
import os

import h5py
import numpy as np

TRAJECTORY_FIELDS = ("traj_data", "traj_offsets", "config_offsets")


[docs] def list_files(data_dir, kind="confinement", split="test"): """List the data files of one kind and split. Args: data_dir (str): the folder with the downloaded files; it is searched recursively. kind (str): ``"confinement"`` or ``"trajectory"``. split (str): ``"train"`` or ``"test"``. Returns: list of str: the file paths, sorted. """ pattern = f"{kind}_data_{split}_split_*.hdf5" return sorted(glob.glob(os.path.join(data_dir, "**", pattern), recursive=True))
[docs] def load(paths, fields): """Read chosen fields of every configuration in a list of files. Every field can be read except the trajectory fields themselves: ``traj_data``, ``traj_offsets`` and ``config_offsets``. To load trajectories, use ``trajectory.read_trajectories``. Fields are returned as stored, with one row per configuration and gridded fields flattened: ``modB``, for example, has shape ``(n, 15 * 41 * 41)``. Args: paths (list of str): the files. fields (list of str): the names of the fields to read. Returns: dict: maps each field name to an array with one row per configuration, with the configurations of all files stacked in order. """ out = {name: [] for name in fields} for path in paths: with h5py.File(path, "r") as f: for name in fields: out[name].append(_read_rows(f[name], slice(None))) return {name: np.concatenate(arrays) for name, arrays in out.items()}
[docs] def load_record(f, config, fields=None): """Read the fields of one configuration. Every field can be read except the trajectory fields themselves: ``traj_data``, ``traj_offsets`` and ``config_offsets``. To load trajectories, use ``trajectory.read_trajectories``. Only the requested fields are read from disk, and gridded fields are returned flattened, as stored. Args: f (h5py.File): an open file, e.g. ``h5py.File(path, "r")``. config (int or str): the row index in the file or the ``uuid`` of the configuration. fields (list of str, optional): the names of the fields to read. By default, every field of the configuration. Returns: dict: maps each field name to its value for the configuration. Raises: KeyError: if no configuration in the file has this ``uuid``. """ i = _config_index(f, config) if fields is None: fields = [name for name in f if name not in TRAJECTORY_FIELDS] return {name: _read_rows(f[name], i) for name in fields}
def _config_index(f, config): """The index in a file of a stellarator configuration given by index or uuid. Args: f (h5py.File): an open file. config (int or str): the configuration, by its index in the file or its uuid. Returns: int: the index of the configuration in the file. Raises: KeyError: if a uuid is given that is not in the file. """ if not isinstance(config, str): return int(config) matches = np.flatnonzero(_read_rows(f["uuid"], slice(None)) == config) if len(matches) == 0: raise KeyError(f"no configuration with uuid {config} in {f.filename}") return int(matches[0]) def _read_rows(dataset, rows): """Read rows of an HDF5 dataset, decoding strings. Args: dataset (h5py.Dataset): the dataset. rows (int or slice): an index or slice into the first axis. Returns: np.ndarray or str: the selected rows, with byte strings decoded to str. """ if dataset.dtype.kind == "O": return dataset.asstr()[rows] return dataset[rows]