trexio-validate checks the contents of TREXIO
files by recomputing them from the basis set stored in the file, using
libcint. It is meant to be run from the
test suites of programs that write TREXIO files, and is consumable from CMake.
Only Gaussian basis sets of molecular (non-periodic) systems are supported so far.
| Check | What is verified |
|---|---|
basis |
basis and AO data are consistent and supported: exactly one of ao.cartesian and ao.cartesian_shell is present, ao.num equals the number of functions the shells define (2l+1 or (l+1)(l+2)/2 per shell, as ao.cartesian or ao.cartesian_shell says), each shell has that many AOs in ao.shell, and all indices are in range |
nucleus_repulsion |
nucleus.repulsion matches the charges and coordinates |
electron_count |
electron.num = up_num + dn_num; mo.occupation sums to the electron count (per spin when mo.spin is present) |
mo_orthonormality |
C† S C = 1 with S computed from the basis set |
ao_1e_int_<op> |
stored AO integrals match the recomputed ones |
mo_1e_int_<op> |
stored MO integrals match C X CT |
ao_2e_int_eri |
every stored ERI matches, symmetry-equivalent entries agree, and no integral above the tolerance is missing |
mo_2e_int_eri |
the same for the MO ERIs (4-index transformation of the full AO tensor) |
<op> is one of overlap, kinetic, potential_n_e, core_hamiltonian,
dipole_x, dipole_y, dipole_z. By default, a check whose data is absent is
skipped; --require turns that into a failure.
The MO orthonormality check alone already tests most of the basis-set description: exponents, contraction coefficients, all three normalization factors, the AO ordering and the solid-harmonic convention. When it fails, the output says whether the MOs are merely unnormalized (a normalization-factor problem), and whether they are orthonormal with the overlap matrix stored in the file (the basis in the file differs from the one the program used).
For open-shell files, MO pairs with different mo.spin are not compared, nor
are spin-forbidden MO integrals.
Everything is computed from the definitions of the TREXIO specification
(trex.org), never from the conventions of a particular program:
- the contraction coefficients are Ns fks aks
(
shell_factor,prim_factor,coefficient), and AO i carries the extra factor N'i (ao.normalization); - whether shells are Cartesian or spherical is given for all of them by
ao.cartesian, or shell by shell byao.cartesian_shell(newer TREXIO); a file must have exactly one of the two; - Cartesian AOs are the monomials xaybzc in alphabetical order; spherical AOs are the Racah-normalized real regular solid harmonics Slm in the order 0, +1, −1, …, +l, −l, with the phases of the specification's table;
ao.shellgives the shell of each AO; the components of a shell follow the order in which its AOs appear;- the ERIs are stored in physicists' notation, ⟨ij|kl⟩ = (ik|jl);
- the dipole operators are μx = −x etc. about the origin.
libcint is used only for integrals over unnormalized Cartesian primitives. The Cartesian-to-TREXIO transformation is implemented here, and it is unit-tested against the specification's table of solid harmonics and against analytic overlap integrals.
trexio-validate [options] FILE...
-t, --tolerance X absolute tolerance of all comparisons (default 1e-8)
--tol CHECK=X tolerance for one check (repeatable)
-c, --checks A,B,... run only these checks
-s, --skip A,B,... do not run these checks
-r, --require A,B,... fail instead of skipping when data is missing ('all')
--max-eri-dim N size limit for checks needing the full ERI tensor (64)
-q, --quiet print only failures and the summary
-l, --list-checks list the available checks
-V, --version print the version
Exit status: 0 if every check that could run passed, 1 if any failed, 2 on usage errors, and 77 if nothing could be checked (e.g. a Slater-type basis). The CMake helper maps 77 to a skipped test.
Example output for a file whose AO integrals are in the wrong order:
PASS mo_orthonormality max |C^+ S C - 1| = 1.56e-14 (tol 1.00e-08); ...
FAIL ao_1e_int_overlap max |file - computed| = 8.19e-01 (tol 1.00e-08); worst at [8,14]:
found -0.3575141288, expected 0.461568113; AO 8 (shell 4, l=1, component 2, nucleus 0), ...
Requirements: CMake ≥ 3.21, a C++17 compiler, TREXIO 2.1 or later (the C library), and libcint (or its API-compatible fork qcint).
Older TREXIO releases lack some of the fields that can be checked. At configure
time, each function trexio-validate uses is looked up in trexio.h, and only
the code for the available ones is compiled. A check whose data the TREXIO in
use cannot read, such as the dipole integrals before TREXIO 2.6, is reported as
skipped with the reason (also in --list-checks), or as failed if it is
required by name; --require all means all checks this build can run. Fields
that cannot be read are listed in the output of the basis check. Notably,
without mo.spin (TREXIO before 2.2.3) the alpha and beta orbitals of an
open-shell file cannot be told apart. CI covers every minor release since 2.1.
cmake -S . -B build -DCMAKE_PREFIX_PATH=/path/to/trexio
cmake --build build
ctest --test-dir build
cmake --install build --prefix /path/to/prefixTREXIO is found through its CMake package, pkg-config, or plain
find_library/find_path, in this order; setting both TREXIO_INCLUDE_DIR
and TREXIO_LIBRARY selects a TREXIO explicitly, ahead of all of these. libcint
is found through LIBCINT_INCLUDE_DIR and LIBCINT_LIBRARY.
To build without installed dependencies, set TREXIO_VALIDATE_FETCH_TREXIO=ON
and/or TREXIO_VALIDATE_FETCH_LIBCINT=ON. These download TREXIO 2.6.1 and
libcint 6.1.3 and link them statically. TREXIO 2.6 needs a Fortran compiler to
configure, and HDF5 to read .h5 files.
Besides the program, the build produces the shared library libtrexio_validate
(C and C++ interfaces, see below) and the Python module trexio_validate
(options TREXIO_VALIDATE_LIBRARY and TREXIO_VALIDATE_PYTHON, both on by
default; the module is installed in TREXIO_VALIDATE_PYTHON_INSTALL_DIR, the
interpreter's site-packages below the prefix). The library is not built with
a bundled TREXIO, for the reason given in the next section.
find_package(TrexioValidate REQUIRED) # installed, or:
# FetchContent_Declare(TrexioValidate
# GIT_REPOSITORY https://github.com/TREX-CoE/trexio-validate.git
# GIT_TAG master)
# FetchContent_MakeAvailable(TrexioValidate)
# A test of your project that writes out.h5
add_test(NAME scf_water COMMAND my_program water.inp)
set_tests_properties(scf_water PROPERTIES FIXTURES_SETUP water_trexio)
trexio_validate_add_test(validate_water
FILE "${CMAKE_CURRENT_BINARY_DIR}/out.h5"
FIXTURES_REQUIRED water_trexio
REQUIRE mo_orthonormality ao_1e_int_overlap
TOLERANCE 1e-9)trexio_validate_add_test also accepts CHECKS, SKIP, DEPENDS,
LABELS, WORKING_DIRECTORY and EXTRA_ARGS; see
cmake/TrexioValidate.cmake. The executable is
available as the target TrexioValidate::trexio-validate for custom use.
examples/consumer is a complete example of both ways of
consuming the project, including the library.
When included as a subproject, the project neither builds its own tests nor
installs anything, unless TREXIO_VALIDATE_BUILD_TESTS /
TREXIO_VALIDATE_INSTALL are set.
A program can validate TREXIO data it has just written, including files of the
in-memory back end (TREXIO_MEMORY), by passing the open trexio_t* handle to
the library. The handle is only read, and it is not closed.
C (include/trexio_validate.h):
#include <trexio_validate.h>
trexio_validate_options_t* options = trexio_validate_options_create();
trexio_validate_options_require(options, "mo_orthonormality");
trexio_validate_report_t* report = NULL;
if (trexio_validate_run(file, options, &report) == TREXIO_VALIDATE_FAILED)
fputs(trexio_validate_report_text(report), stderr);
trexio_validate_report_destroy(report);
trexio_validate_options_destroy(options);C++ (include/trexio_validate.hpp, a header-only wrapper of the C interface):
#include <trexio_validate.hpp>
const auto report = trexio_validate::validate(file, trexio_validate::Options().require("all"));
if (!report.ok()) std::cerr << report.text();Link to TrexioValidate::trexio_validate, available after
find_package(TrexioValidate) or FetchContent; it brings TREXIO's include
directory and library along.
Python, e.g. for data written by a program's C++ core and handed to Python as the address of the handle:
import trexio_validate
report = trexio_validate.validate(address, require=["mo_orthonormality"], tolerance=1e-9)
print(report) # the same table as the program prints
report.raise_for_failure() # raises trexio_validate.ValidationErrorvalidate() accepts the handle as an integer address, a ctypes pointer, a
PyCapsule, or a trexio.File; validate_file() takes a path. The module
uses ctypes and needs no compilation; TREXIO_VALIDATE_LIBRARY in the
environment overrides the library it loads.
The handle must come from the TREXIO library that trexio-validate is linked
to. The layout of trexio_t is private to TREXIO, so a handle created by a
separately compiled copy of the library is not compatible in general. This is
satisfied when the program and trexio-validate link to the same installed
libtrexio. It is not guaranteed for the trexio Python packages on PyPI,
which compile their own copy of TREXIO into the extension module (it works
only if both copies come from identical sources and configuration); write such
files to disk and use validate_file() instead.
tests/data holds files written by the TREXIO interface of
pyscf-forge (pyscf/tools/trexio.py),
an independent producer, together with deliberately broken copies. They are
regenerated with tests/generate_data.py (needs pyscf and the TREXIO Python
module built with HDF5).
pyscf-forge's writer stores mo.coefficient in TREXIO's AO order, but
ao_1e_int and ao_2e_int in PySCF's own AO order
(pyscf-forge#214). The
generator therefore reorders the AO integrals of the valid files, and keeps the
unmodified output as bad_pyscf_forge_ao_integrals.h5, which must fail.
- effective core potentials (
ao_1e_int.ecp, andcore_hamiltonianwhen an ECP is present, are skipped); - Cholesky-decomposed and long-range ERIs;
- periodic systems, complex basis functions or MO integrals,
r_power ≠ 0, Slater-type and numerical orbitals; - consistency of determinants, CSFs, RDMs and other wave-function data.
BSD 3-Clause, like TREXIO; see LICENSE.