CoolFace
Datasetpublic

OneScience-Group/MatPL

MatPL Dataset Description The MatPL dataset is an example dataset for training material potentials with OneScience-Group/NEP. It contains multiple material systems, including AuAg, Cu, HfO2, and LiSiC, and covers the pwmat/movement, pwmlff/npy, and extxyz data formats. The data include atomic coordinates, simulation cell information, energies, and forces for different material systems in different configurations, and serve as a standard benchmark dataset for… See the full description on the dataset page: https://huggingface.co/datasets/OneScience-Group/MatPL.

sourceHugging Facegpl-3.0updated 2mo agoView on Hugging Face
0likes94downloads
validate_matpl.py129 linesDownload Raw Back to scripts
1#!/usr/bin/env python32"""Validate the standardized OneScience MatPL dataset package."""3 4from __future__ import annotations5 6import argparse7import hashlib8import sys9from pathlib import Path10 11import numpy as np12 13 14EXPECTED_TOP_LEVEL = ["AuAg", "Cu", "HfO2", "LiSiC"]15 16 17def sha256_file(path: Path) -> str:18    digest = hashlib.sha256()19    with path.open("rb") as handle:20        for chunk in iter(lambda: handle.read(1024 * 1024), b""):21            digest.update(chunk)22    return digest.hexdigest()23 24 25def require_file(path: Path) -> None:26    if not path.is_file():27        raise FileNotFoundError(f"missing file: {path}")28 29 30def require_dir(path: Path) -> None:31    if not path.is_dir():32        raise FileNotFoundError(f"missing directory: {path}")33 34 35def check_movement(path: Path) -> None:36    require_file(path)37    with path.open(encoding="utf-8", errors="replace") as handle:38        text = handle.read(4096)39    if not text.strip():40        raise ValueError(f"empty MOVEMENT file: {path}")41    if "Iteration" not in text and "atoms" not in text.lower() and "lattice" not in text.lower():42        raise ValueError(f"unexpected MOVEMENT header: {path}")43 44 45def check_xyz(path: Path) -> None:46    require_file(path)47    with path.open(encoding="utf-8", errors="replace") as handle:48        first = handle.readline().strip()49        second = handle.readline()50    atoms = int(first)51    if atoms <= 0:52        raise ValueError(f"invalid xyz atom count in {path}")53    if not second:54        raise ValueError(f"missing xyz comment line in {path}")55 56 57def check_npy(path: Path) -> None:58    require_file(path)59    arr = np.load(path, allow_pickle=False)60    if arr.size == 0:61        raise ValueError(f"empty npy array: {path}")62 63 64def read_checksum_manifest(path: Path) -> list[tuple[str, str]]:65    require_file(path)66    entries: list[tuple[str, str]] = []67    with path.open(encoding="utf-8") as handle:68        for line_no, raw in enumerate(handle, start=1):69            line = raw.strip()70            if not line:71                continue72            parts = line.split(None, 1)73            if len(parts) != 2:74                raise ValueError(f"invalid checksum line {line_no}: {raw!r}")75            entries.append((parts[0], parts[1]))76    return entries77 78 79def validate_checksums(package_root: Path, manifest_path: Path) -> int:80    entries = read_checksum_manifest(manifest_path)81    for expected_hash, rel_path in entries:82        target = package_root / rel_path83        require_file(target)84        if sha256_file(target) != expected_hash:85            raise ValueError(f"checksum mismatch: {rel_path}")86    return len(entries)87 88 89def main() -> int:90    parser = argparse.ArgumentParser(description=__doc__)91    parser.add_argument("--dataset-root", default="data/MatPL")92    parser.add_argument("--checksum-manifest", default="metadata/sha256_manifest.txt")93    parser.add_argument("--skip-checksum", action="store_true")94    args = parser.parse_args()95 96    package_root = Path.cwd()97    dataset_root = Path(args.dataset_root)98    for name in EXPECTED_TOP_LEVEL:99        require_dir(dataset_root / name)100 101    check_movement(dataset_root / "Cu/pwdata/0_300_MOVEMENT")102    check_movement(dataset_root / "Cu/pwdata/1_500_MOVEMENT")103    check_movement(dataset_root / "Cu/pwdata/valid_movement")104    check_xyz(dataset_root / "AuAg/AuAg-5762.xyz")105 106    npy_files = sorted(dataset_root.glob("**/*.npy"))107    if len(npy_files) < 100:108        raise ValueError(f"too few npy files: {len(npy_files)}")109    for sample in npy_files[:8]:110        check_npy(sample)111 112    checksum_count = 0113    if not args.skip_checksum:114        checksum_count = validate_checksums(package_root, Path(args.checksum_manifest))115 116    print("MatPL dataset validation passed")117    print(f"top-level systems: {', '.join(EXPECTED_TOP_LEVEL)}")118    print(f"npy files: {len(npy_files)}")119    print(f"checksum entries verified: {checksum_count}")120    return 0121 122 123if __name__ == "__main__":124    try:125        raise SystemExit(main())126    except Exception as exc:127        print(f"MatPL dataset validation failed: {exc}", file=sys.stderr)128        raise SystemExit(1)129