A unified command-line toolkit for atomistic / MD structure workflows.
Project description
pymdkit
A single command-line tool that bundles a collection of atomistic / molecular-dynamics
structure scripts behind one executable: pymdkit. Instead of copying individual
scripts into each working folder and running python some_script.py, you install
pymdkit once and call any tool from anywhere as pymdkit <command> [options].
Every command exposes named -flags (no positional guessing), and each underlying
script is still runnable on its own.
Install
Create a clean conda environment, activate it, then install pymdkit with pip:
conda create -n pymdkit python=3.10
conda activate pymdkit
pip install pymdkit
This installs the pymdkit command into the active conda environment, together
with its direct dependencies (numpy, ase, pymatgen, mp-api, pyxtal, dpdata). Some of these packages may install their own transitive dependencies.
Verify:
pymdkit -version
pymdkit -help # lists every command
pymdkit <command> -help # shows that command's flags
Commands
Commands that transform structures accept either a single file (-i/-o) or a
whole folder (-if/-of); commands that analyse VASP runs scan the current
directory for job sub-folders automatically.
| Command | What it does |
|---|---|
add-groups |
Tag atoms with a GPUMD group index by element order |
electrostatic-energy |
Compute CIF electrostatic energy with pymatgen EwaldSummation |
ehull |
Auto-detect VASP job folders and compute E_hull vs Materials Project |
final-energy |
List VASP job final energies from lowest to highest |
gather-contcar |
Collect CONTCARs from VASP job folders into one folder, renamed <folder>.vasp |
msd |
Diffusivity & conductivity from GPUMD MSD jobs (auto-scans <structure>/<temp>/) |
nep-rmse |
Compute NEP energy/force/stress RMSE with ASCII plots and optional candidate selection |
perturb |
Generate perturbed structures with dpdata |
vasp2xyz |
Collect SCF-converged VASP job folders (any name) into one extxyz file |
submit-vasp |
Submit/resubmit VASP job folders while limiting active queue jobs |
rmsd |
Compute RMSD between two structure files, or all pairs in a folder |
stable-entry |
Download stable Materials Project structures for a chemical system |
stru2xyz |
Convert structure file(s) of any format to extxyz |
substitute |
Randomly substitute or remove selected atoms/sites from a structure |
supercell |
Build a supercell with cell lengths capped at a maximum (Angstrom); optional per-temperature GPUMD setup |
symmetrize |
Import space-group symmetry into a structure file (or folder) -> CIF |
vasp-relax |
Write VASP relaxation inputs for a structure (or folder); INCAR tags overridable |
vasp-static |
Write VASP static / single-point inputs for a structure (or folder) |
Examples
pymdkit add-groups -i opted.cif -elements Li Y Cl -o model.xyz
pymdkit add-groups -if cifs/ -elements Li Y Cl -of cifs-grouped/ # whole folder
pymdkit add-groups -elements Li Y Cl # scan subfolders, tag each model.xyz in place
pymdkit stru2xyz -i opted.vasp -o opted.xyz # convert one file
pymdkit stru2xyz -if vasp-opted -of xyz-opted # convert a whole folder
pymdkit stru2xyz # scan subfolders, convert structures in place
pymdkit supercell -i opted.vasp -o sc.vasp -max-abc 20 # cell lengths <= 20 A
pymdkit supercell -if vasp-opted -max-abc 20 -individual # per-structure ./<name>/<name>.<ext>
pymdkit supercell -if extxyz-opted -max-abc 24 -individual -temp 500 600 -md-if input-files -add-groups Li Y Cl
# GPUMD: ./<name>/model.xyz (grouped) + ./<name>/<T>/ jobs
pymdkit vasp-relax -i opted.vasp # relax inputs in current dir
pymdkit vasp-relax -if optimal_occupancy # one ./<name>/ job folder per structure
pymdkit vasp-static -if cifs/ -custom-setting my_incar.txt # static inputs, custom INCAR
pymdkit vasp-static -it traj.xyz # one ./frame_N/ job per trajectory frame
pymdkit msd # scans <structure>/<temp>/ -> per-job msd/ + msd_summary.txt
pymdkit msd -diffuse_ion Li -ion_charge 1 # choose the mobile ion for conductivity
pymdkit stable-entry -s Li La Ta Cl # MP stable entries -> Li-La-Ta-Cl-stable-entries/
pymdkit ehull -mp-api-key $MP_API_KEY # scans ./ for VASP jobs -> ehull.txt
pymdkit ehull -local Li-La-Ta-Cl-stable-entries-opted
pymdkit final-energy # scans ./ for VASP jobs -> final-energy.txt with convergence status
pymdkit gather-contcar -of vasp-opted # CONTCARs -> vasp-opted/<folder>.vasp
pymdkit gather-contcar -of vasp-opted -ehull 0.028 # only structures with E_hull < 0.028 eV/atom
pymdkit vasp2xyz # scans ./ for VASP output folders -> scf-converged.xyz
pymdkit vasp2xyz -position-only # write positions only, without energy/forces/stress
pymdkit submit-vasp -subscript sub_vasp -queue slurm -max-job-num 30
nohup pymdkit submit-vasp -subscript sub_vasp -queue slurm -max-job-num 30 > submit-vasp.log 2>&1 &
pymdkit substitute -i Li3YCl6.cif -se Li -sn 3 -we Na -wn 3 -on 100
pymdkit substitute -i Li3YCl6.cif -se Li -sn 3 -we none -on 100
pymdkit substitute -i Li96Ta6La11Cl72.cif -se Li1 Li2 -sn 20 67 -we none -on 100
pymdkit substitute -i Li96Ta6La11Cl72.cif -se Li2 -we none -ref La Ta -d 1.01 1.02
pymdkit substitute -i Li96Ta6La11Cl72.cif -se Li2 -we none -ref La Ta
pymdkit electrostatic-energy -i Li3YCl6.cif
pymdkit electrostatic-energy -if Li3YCl6-all
pymdkit nep-rmse # writes energy/force/stress train txt files, rmse_value.txt, and terminal plots
pymdkit nep-rmse -select-candidate -xyz train.xyz # interactive candidate selection; writes candidate.xyz and accurate.xyz
pymdkit perturb -i example.xyz -atom 0.2 -lattice 0.03 -n 100 -o example-perturb-atom-0.2-lattice-0.03.xyz
pymdkit rmsd a.cif b.cif # RMSD of two files -> rmsd.txt
pymdkit rmsd vasp-opted/ # all pairs in a folder -> rmsd.txt
pymdkit symmetrize -i opted.cif -symprec 0.01 -add_oxidation yes -o opted-symm.cif
pymdkit symmetrize -if my_cifs/ -symprec 0.01 -add_oxidation no -of my_cifs-symm
VASP input commands (vasp-relax, vasp-static) always produce individual
jobs (one structure per folder): -i writes into the current dir (or -o),
-if creates one ./<name>/ folder per structure, and -it creates one
./frame_N/ folder per trajectory frame - all directly in the current path.
They start from sensible default INCAR settings; override them by passing a
settings file with -custom-setting FILE. The file may be a Python-dict block
or KEY = VALUE lines (a None/blank value clears a tag):
custom_settings = {
"ENCUT": "600.0",
"ISIF": "3",
"MAGMOM": None
}
vasp-static -it traj.xyz (also available on vasp-relax) reads a
multi-structure trajectory and writes one job sub-folder per frame
(frame_1/, frame_2/, ..., prefix configurable via -frame-prefix). Each
folder also keeps a frame_N.xyz, so Config_type survives for a later
vasp2xyz.
Each command's full flag list is in pymdkit <command> -help.
For long VASP batch submission, run submit-vasp with nohup and & if you
want it to keep sleeping, checking the queue, and submitting new jobs after you
exit the terminal:
nohup pymdkit submit-vasp -subscript sub_vasp -queue slurm -max-job-num 30 > submit-vasp.log 2>&1 &
The command itself controls the loop: it submits until the active queue reaches
-max-job-num, sleeps when the queue is full, checks again, and continues until
all needed jobs are submitted. nohup ... & is what makes that loop continue in
the background after logout.
substitute -ref removes selected sites near reference sites and writes one
<input-stem>_substitute.cif in the current path. If -d is omitted, each
cutoff is 0.7 * (selected covalent radius + reference covalent radius) using
the covalent radii from Cordero et al., Dalton Trans., 2008, 2832-2838.
VASP-output readers (vasp2xyz, ehull, and other future VASP-output
commands) use the global priority vaspout.h5 > vasprun.xml > OUTCAR.
ehull auto-detects every sub-folder of the current path that contains a
supported VASP output, groups them by chemical system (elements ordered by
electronegativity, e.g. Li-Y-Cl), and builds/reuses one mp_cache_<system>.json
per system - so a pure Li-Y-Cl batch yields a single mp_cache_Li-Y-Cl.json, while
a mixed Li-Y-Cl + La-O batch yields both mp_cache_Li-Y-Cl.json and
mp_cache_La-O.json. (Formation energy is reported alongside E_hull in
ehull.txt.)
Layout
pymdkit/
|-- pyproject.toml # package metadata + the `pymdkit` entry point
|-- README.md
`-- src/pymdkit/
|-- pymdkit_main.py # dispatcher: discovers and runs commands
`-- commands/ # one module per command
|-- _fileio.py # shared -i/-o/-if/-of helper (not a command)
|-- _vaspset.py # shared VASP input-set helper (not a command)
|-- add_groups.py
|-- compute_ehull.py
|-- compute_rmsd.py
|-- electrostatic_energy.py
|-- final_energy.py
|-- perturb.py
|-- nep_rmse.py
|-- stable_entry.py
|-- submit_vasp.py
|-- stru2xyz.py
|-- substitute.py
|-- supercell.py
|-- vasp2xyz.py
|-- vasp_relax.py
|-- vasp_static.py
|-- ...
`-- symmetrize.py
Modules whose name starts with _ are shared helpers and are skipped by the
dispatcher, so they never appear as commands.
Adding a new tool later
Drop a module in src/pymdkit/commands/ that defines four things:
COMMAND = "my-tool" # the subcommand name you'll type
HELP = "One-line description."
def add_arguments(parser): # register flags
parser.add_argument("-input", required=True)
def run(args): # do the work; return an exit code (0 = ok)
...
return 0
if __name__ == "__main__": # keeps the script runnable on its own
import argparse
_p = argparse.ArgumentParser(description=__doc__)
add_arguments(_p)
raise SystemExit(run(_p.parse_args()))
It will appear in pymdkit -help automatically - no central registration needed.
Put heavy imports (pymatgen, ase, ...) inside run() where practical; the dispatcher
reads each command's name and help without importing it, so pymdkit -help stays
fast and a missing optional dependency only affects the one command that needs it.
Running a script standalone
Every command module still works directly, which is handy for debugging:
python src/pymdkit/commands/supercell.py -i in.cif -max-abc 20 -o sc.vasp
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pymdkit-1.2.4.tar.gz.
File metadata
- Download URL: pymdkit-1.2.4.tar.gz
- Upload date:
- Size: 61.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28130fb9abb18ac932553bab441f8aaee6a1ffb327690b991553a33a453a9a35
|
|
| MD5 |
dbba31f0d4296191c058d3013677249c
|
|
| BLAKE2b-256 |
540e0ae354b42461cf22986fb522a7f432765e5e8e326642473cb62460a64451
|
File details
Details for the file pymdkit-1.2.4-py3-none-any.whl.
File metadata
- Download URL: pymdkit-1.2.4-py3-none-any.whl
- Upload date:
- Size: 69.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64307a3911b6f999ea0e5b3af24d853eb3f43270883d5138393d3b52ed80dc9d
|
|
| MD5 |
c9e491aaedd59b569ee898d2fbc9681f
|
|
| BLAKE2b-256 |
82d498fe28e6c4da583f5be6937ab5c617f0b1c828100bcbad7f367ccb4d36ed
|