Skip to content

Commit

Permalink
Add support for extended XYZ in abiml.py validate.
Browse files Browse the repository at this point in the history
Example:

    abiml.py validate sitraj.xyz --nn-names mace_mp --traj_range 0:11:2
  • Loading branch information
gmatteo committed Feb 18, 2024
1 parent 2141c81 commit d668706
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 36 deletions.
1 change: 0 additions & 1 deletion abipy/flowtk/qutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ def sbatch(self, slurm_filepath: PathLike) -> int:
fh.write(str(self))

queue_id = slurm_sbatch(slurm_filepath)

print("Saving slurm job ID in:", path_qid)
with open(path_qid, "wt") as fh:
fh.write(str(queue_id) + " # Slurm job id")
Expand Down
37 changes: 30 additions & 7 deletions abipy/ml/aseml.py
Original file line number Diff line number Diff line change
Expand Up @@ -2745,6 +2745,9 @@ def __init__(self, filepaths, nn_names, traj_range, verbose, workdir, prefix=Non
super().__init__(workdir, prefix)
self.filepaths = list_strings(filepaths)
self.traj_range = traj_range
if self.traj_range is not None and not isinstance(self.traj_range, range):
raise TypeError(f"traj_range should be either None or range instance while got {type(traj_range)}")

self.nn_names = list_strings(nn_names)
self.verbose = verbose

Expand All @@ -2771,6 +2774,10 @@ def get_abinitio_results(self) -> list[AseResults]:
def _get_results_filepath(self, filepath) -> list[AseResults]:
"""
Extract ab-initio results from self.filepath according to the file extension.
Supports:
- ABINIT HIST.nc
- vasprun.xml
- ASE extended xyz.
"""
basename = os.path.basename(filepath)
abi_results = []
Expand All @@ -2782,15 +2789,17 @@ def _get_results_filepath(self, filepath) -> list[AseResults]:
with HistFile(filepath) as hist:
# etotals in eV units.
etotals = hist.etotals
if self.traj_range is None: self.traj_range = range(0, len(hist.etotals), 1)
num_steps = len(hist.etotals)
if self.traj_range is None: self.traj_range = range(0, num_steps, 1)
print(f"Reading trajectory from {filepath=}, {num_steps=}, {self.traj_range=}")
forces_hist = hist.r.read_cart_forces(unit="eV ang^-1")
# GPa units.
stress_cart_tensors, pressures = hist.reader.read_cart_stress_tensors()
for istep, (structure, ene, stress, forces) in enumerate(zip(hist.structures, etotals, stress_cart_tensors, forces_hist)):
if not istep in self.traj_range: continue
r = AseResults(atoms=get_atoms(structure), ene=float(ene), forces=forces, stress=stress)
magmoms = None
r = AseResults(atoms=get_atoms(structure), ene=float(ene), forces=forces, stress=stress, magmoms=magmoms)
abi_results.append(r)
return abi_results

elif fnmatch(basename, "vasprun*.xml*"):
# Assume Vasprun file with structural relaxation or MD results.
Expand All @@ -2801,17 +2810,31 @@ def _get_results_filepath(self, filepath) -> list[AseResults]:
vasprun = Vasprun(filepath)

num_steps = len(vasprun.ionic_steps)
if self.traj_range is None: self.traj_range = range(0, num_steps, 1)
print(f"Reading trajectory from {filepath=}, {num_steps=}, {self.traj_range=}")
for istep, step in enumerate(vasprun.ionic_steps):
#print(step.keys())
if not istep in self.traj_range: continue
structure, forces, stress = step["structure"], step["forces"], step["stress"]
ene = get_energy_step(step)
r = AseResults(atoms=get_atoms(structure), ene=float(ene), forces=forces, stress=stress)
magmoms = None
r = AseResults(atoms=get_atoms(structure), ene=float(ene), forces=forces, stress=stress, magmoms=magmoms)
abi_results.append(r)

elif fnmatch(basename, "*.xyz"):
# Assume ASE extended xyz file.
atoms_list = read(filepath, index=":")
num_steps = len(atoms_list)
if self.traj_range is None: self.traj_range = range(0, num_steps, 1)
print(f"Reading trajectory from {filepath=}, {num_steps=}, {self.traj_range=}")
for istep, atoms in enumerate(atoms_list):
if not istep in self.traj_range: continue
r = AseResults.from_atoms(atoms)
abi_results.append(r)
return abi_results

raise ValueError(f"Don't know how to extract data from: {filepath=}")
else:
raise ValueError(f"Don't know how to extract data from: {filepath=}")

return abi_results

def run(self, nprocs, print_dataframes=True) -> AseResultsComparator:
"""
Expand Down
56 changes: 28 additions & 28 deletions abipy/scripts/abiml.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,15 @@ def relax(ctx, filepath, nn_name,
Usage example:
\b
abiml.py.py relax FILE --fmax 0.01 -r cell --optimizer FIRE -w OUT_DIR
abiml.py.py relax FILE --fix-inds "0 3" --fix-symbols "Si O"
abiml.py relax FILE --fmax 0.01 -r cell --optimizer FIRE -w OUT_DIR
abiml.py relax FILE --fix-inds "0 3" --fix-symbols "Si O"
where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc.
or a string such as __mp-134 to fetch the structure from the MP database.
To change the ML potential, use e.g.:
abiml.py.py relax -nn m3gnet [...]
abiml.py relax -nn m3gnet [...]
"""
atoms = _get_atoms_from_filepath(filepath)
aseml.fix_atoms(atoms, fix_inds=fix_inds, fix_symbols=fix_symbols)
Expand Down Expand Up @@ -282,14 +282,14 @@ def md(ctx, filepath, nn_name,
Usage example:
\b
abiml.py.py md FILE --temperature 1200 --timestep 2 --steps 5000 --workdir OUT_DIR
abiml.py.py md FILE --fix-inds "0 3" --fix-symbols "Si O"
abiml.py md FILE --temperature 1200 --timestep 2 --steps 5000 --workdir OUT_DIR
abiml.py md FILE --fix-inds "0 3" --fix-symbols "Si O"
where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc.
To change the ML potential, use e.g.:
abiml.py.py md -nn m3gnet [...]
abiml.py md -nn m3gnet [...]
To restart a MD run, use --workdir to specify a pre-existent directory.
"""
Expand Down Expand Up @@ -324,15 +324,15 @@ def neb(ctx, filepaths, nn_name,
Usage example:
\b
abiml.py.py neb START_FILE END_FILE --nimages 6 --fmax=0.05 --optimizer FIRE -w OUT_DIR
abiml.py.py neb START_FILE END_FILE --neb-method improvedtangent --climb
abiml.py.py neb START_FILE END_FILE --fix-inds "0 3" --fix-symbols "Si O"
abiml.py neb START_FILE END_FILE --nimages 6 --fmax=0.05 --optimizer FIRE -w OUT_DIR
abiml.py neb START_FILE END_FILE --neb-method improvedtangent --climb
abiml.py neb START_FILE END_FILE --fix-inds "0 3" --fix-symbols "Si O"
where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc.
To change the ML potential, use e.g.:
abiml.py.py neb -nn m3gnet [...]
abiml.py neb -nn m3gnet [...]
"""
initial_atoms = aseml.get_atoms(filepaths[0])
aseml.fix_atoms(initial_atoms, fix_inds=fix_inds, fix_symbols=fix_symbols)
Expand Down Expand Up @@ -366,15 +366,15 @@ def mneb(ctx, filepaths, nn_name,
Usage example:
\b
abiml.py.py mneb FILE1 FILE2 FILE2 ... --nimages 6 --fmax=0.05 -w OUT_DIR
abiml.py.py mneb FILE1 FILE2 FILE2 ... --neb-method improvedtangent --climb
abiml.py.py mneb FILE1 FILE2 FILE2 ... --fix-inds "0 3" --fix-symbols "Si O"
abiml.py mneb FILE1 FILE2 FILE2 ... --nimages 6 --fmax=0.05 -w OUT_DIR
abiml.py mneb FILE1 FILE2 FILE2 ... --neb-method improvedtangent --climb
abiml.py mneb FILE1 FILE2 FILE2 ... --fix-inds "0 3" --fix-symbols "Si O"
where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc.
To change the ML potential, use e.g.:
abiml.py.py mneb -nn m3gnet [...]
abiml.py mneb -nn m3gnet [...]
"""
# Fix atoms
atoms_list = [aseml.get_atoms(p) for p in filepaths]
Expand Down Expand Up @@ -414,14 +414,14 @@ def ph(ctx, filepath, nn_names,
Usage example:
\b
abiml.py.py ph FILE --distance 0.03 --supercell 2 2 2
abiml.py ph FILE --distance 0.03 --supercell 2 2 2
where `FILE` provides the crystalline structure
or a string such as __mp-134 to fetch the structure from the MP database.
To specify the list of ML potential, use e.g.:
abiml.py.py ddb -nn-names m3gnet --nn-names chgnet [...]
abiml.py ddb -nn-names m3gnet --nn-names chgnet [...]
To use all NN potentials supported, use:
Expand Down Expand Up @@ -469,14 +469,14 @@ def phddb(ctx, ddb_filepath, nn_names,
Usage example:
\b
abiml.py.py phddb DDB_FILE --distance 0.03 --dipdip 0 --supercell 2 2 2
abiml.py phddb DDB_FILE --distance 0.03 --dipdip 0 --supercell 2 2 2
where `DDB_FILE` is an Abinit DDB file
or a string such as __mp-134 to fetch the DDB from the MP database.
To specify the list of ML potential, use e.g.:
abiml.py.py phddb -nn-names m3gnet --nn-names chgnet [...]
abiml.py phddb -nn-names m3gnet --nn-names chgnet [...]
To use all NN potentials supported, use:
Expand Down Expand Up @@ -523,7 +523,7 @@ def order(ctx, filepath, nn_name,
Usage example:
\b
abiml.py.py order FILE --max-ns 10 --relax cell
abiml.py order FILE --max-ns 10 --relax cell
where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc.
Expand Down Expand Up @@ -561,14 +561,14 @@ def scan_relax(ctx, filepath, nn_name,
Usage example:
\b
abiml.py.py scan-relax FILE -isite 0 --mesh 4 # Move first atom in the structure
abiml.py.py scan-relax FILE -isite H # Add H to the structure read from FILE.
abiml.py scan-relax FILE -isite 0 --mesh 4 # Move first atom in the structure
abiml.py scan-relax FILE -isite H # Add H to the structure read from FILE.
where `FILE` is any file supported by abipy/pymatgen e.g. netcdf files, Abinit input, POSCAR, xsf, etc.
To change the ML potential, use e.g.:
abiml.py.py scan-relax -nn m3gnet [...]
abiml.py scan-relax -nn m3gnet [...]
"""
structure = Structure.from_file(filepath)

Expand All @@ -588,7 +588,7 @@ def scan_relax(ctx, filepath, nn_name,
@click.argument('filepaths', type=str, nargs=-1)
@add_nn_names_opt
@click.option("--traj_range", type=str, show_default=True,
help="Trajectory range e.g. `5` to select the first 5 iterations, `1:4` to select steps 1,2,3.",
help="Trajectory range e.g. `5` to select the first 5 iterations, `1:4` to select steps 1,2,3. `1:4:2 for 1,3",
default=None)
@click.option("-e", '--exposer', default="mpl", show_default=True, type=click.Choice(["mpl", "panel"]),
help='Plotting backend: mpl for matplotlib, panel for web-based')
Expand All @@ -608,13 +608,13 @@ def validate(ctx, filepaths,
usage example:
\b
abiml.py.py validate FILE --nn-names matgl --nn-names chgnet
abiml.py validate FILE --nn-names matgl --nn-names chgnet
where `FILE` can be either a _HIST.nc or a vasprun.xml FILE.
where `FILE` can be a HIST.nc, a vasprun.xml or an ASE extended XYZ file.
"""
traj_range = cli.range_from_str(traj_range)
nn_names = _get_nn_names(nn_names)
ml_comp = aseml.MlValidateWithAbinitio(filepaths, nn_names, traj_range, verbose, workdir, prefix="_abiml_compare_")
ml_comp = aseml.MlValidateWithAbinitio(filepaths, nn_names, traj_range, verbose, workdir, prefix="_abiml_validate_")
print(ml_comp)
c = ml_comp.run(nprocs=nprocs)

Expand Down Expand Up @@ -683,7 +683,7 @@ def compare(ctx, filepath, nn_names,
"""
atoms = _get_atoms_from_filepath(filepath)
nn_names = _get_nn_names(nn_names)
ml_comp = aseml.MlCompareNNs(atoms, nn_names, num_tests, rattle, stdev_rvol, verbose, workdir, prefix="_abiml_comp_")
ml_comp = aseml.MlCompareNNs(atoms, nn_names, num_tests, rattle, stdev_rvol, verbose, workdir, prefix="_abiml_compare_")
print(ml_comp.to_string(verbose=verbose))
ase_comp = ml_comp.run()
return 0
Expand Down Expand Up @@ -752,7 +752,7 @@ def cwf_eos(ctx, elements, nn_names,
# usage example:
#
# \b
# abiml.py.py train FILE --nn-names matgl
# abiml.py train FILE --nn-names matgl
#
# where `FILE` can be either a _HIST.nc or a vasprun.xml FILE.
# """
Expand Down

0 comments on commit d668706

Please sign in to comment.