Add tooling for a versioned geant_steps dataset layout

Introduces raw/<kind>/<gen>/<detector>/shard-NNN.root and
processed/<kind>/<gen>/<schema>/<detector>/shard-NNN.parquet as the dataset
convention, plus scripts to operate on it: migrate_geant_steps.py for the
one-time move into this layout, bump_dataset_version.py to cut new
gen/schema versions with a logged reason, steps_to_parquet_parallel.py to
convert ROOT shards to parquet in parallel and place them correctly, and
create_root_files.py to generate new ROOT shards via a minicalosim
executable. The loader gains .manifest file support so pools/ (train/dev/
holdout shard lists) can be passed straight to `giant train`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 16:46:48 +02:00
parent 8475199609
commit 320365606a
9 changed files with 1627 additions and 0 deletions
+24
View File
@@ -5,9 +5,33 @@ import numpy as np
import pandas as pd
import pyarrow.parquet as pq
# A manifest is a plain text file listing one parquet path per line, used to
# name a curated subset of files (e.g. a train/holdout pool) without copying
# or symlinking the underlying parquet files. Lines are resolved relative to
# the manifest's own directory, so the manifest stays valid if the whole
# dataset tree is moved or copied elsewhere intact.
MANIFEST_SUFFIX = ".manifest"
def _read_manifest(path: Path) -> list[Path]:
files = []
for line in path.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
resolved = (path.parent / line).resolve()
if not resolved.is_file():
raise FileNotFoundError(f"{path} lists missing file: {resolved}")
files.append(resolved)
if not files:
raise FileNotFoundError(f"manifest {path} lists no files")
return files
def find_parquet_files(path: str | Path) -> list[Path]:
p = Path(path)
if p.suffix == MANIFEST_SUFFIX:
return _read_manifest(p)
if p.is_dir():
files = sorted(p.glob("*.parquet"))
if not files: