Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Analyze, validate, convert, and transform materials structures and computed materials data with current pymatgen APIs, including local phase diagrams, symmetry sensitivity, electronic-structure I/O, and explicitly bounded Materials Project queries.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 235% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 2309% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 152% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 81% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 109% | 0% |
Use pymatgen for explicit, provenance-preserving work with compositions, molecules, periodic structures, computed entries, symmetry, phase diagrams, electronic structures, and electronic-structure-code files. Treat every parse, conversion, symmetry assignment, transformation, and database result as method- and parameter-dependent.
The MIT frontmatter license covers this skill. pymatgen and pymatgen-core are MIT; mp-api declares BSD-3-Clause-LBNL. Materials Project data is generally CC BY 4.0, while contributed data remains owned by its contributors. Check the exact artifact and data terms before redistribution.
pymatgen==2026.5.4 is the latest stable wrapper release (2026-05-04).Package metadata requires Python 3.11+ and directly requires pymatgen-core>=2026.4.16.
pymatgen-core==2026.7.16 is the latest stable core release (2026-07-16).It now contains core objects, symmetry/lattice operations, and the I/O layer, all under the existing pymatgen.* namespace.
mp-api==0.46.4 is the latest stable Materials Project client(2026-06-15), requires Python 3.11+, and depends on pymatgen>2024.2.20.
distributions prevents pymatgen==2026.5.4 from silently resolving to a different future core.
infer semantic-version compatibility from the numbers.
Create a project lock for reproducibility:
bashuv init --python 3.11 uv add "pymatgen==2026.5.4" "pymatgen-core==2026.7.16" "mp-api==0.46.4" uv lock uv sync --frozen
For a disposable reviewed environment:
bashuv venv --python 3.11 .venv-pymatgen uv pip install --python .venv-pymatgen/bin/python \ "pymatgen==2026.5.4" "pymatgen-core==2026.7.16" "mp-api==0.46.4"
Direct pins do not freeze all transitive wheels. Preserve uv.lock, platform, Python version, package versions, and artifact hashes.
Molecule or periodicStructure; record lattice and periodic boundary conditions.
g/cm³, but each API's documented contract is authoritative.
Structure coordinates are fractional unlesscoords_are_cartesian=True; Molecule coordinates are Cartesian.
stoichiometry, and correction warnings; do not silently accept fixes.
guess oxidation states implicitly.
thermodynamic analysis.
symprec in Å andangle_tolerance in degrees with every assignment.
software versions, warnings, and parent/child checksums.
and round-trip-check scientifically relevant properties.
schemes. A computed hull is conditional on the supplied entry set.
fields, result limit, cache behavior, output, license, and citation before an explicit execution step.
general object graph; use schema-validated JSON and explicit constructors.
Use the public convenience imports:
pythonfrom pymatgen.core import Composition, Element, Lattice, Molecule, Structure composition = Composition("LiFePO4", strict=True) iron = Element("Fe") lattice = Lattice.cubic(5.64) # Å structure = Structure( lattice, ["Na", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]], coords_are_cartesian=False, validate_proximity=True, ) molecule = Molecule( ["O", "H", "H"], [[0.0, 0.0, 0.0], [0.758, 0.0, 0.504], [-0.758, 0.0, 0.504]], charge=0, spin_multiplicity=1, )
Structure and Molecule are mutable; use IStructure/IMolecule or an explicit copy when mutation would compromise provenance. See core classes.
Prefer the bundled validator, which captures CIF and Python warnings and reports units, occupancy, disorder, oxidation states, periodicity, coordinate mode, and minimum distances:
bashpython scripts/composition_structure_validator.py composition "Fe2O3" python scripts/composition_structure_validator.py structure structure.cif python scripts/structure_analyzer.py structure.cif --symmetry
For direct CIF work, use the current parser method and inspect both warning channels:
pythonimport warnings from pymatgen.io.cif import CifParser with warnings.catch_warnings(record=True) as caught: warnings.simplefilter("always") parser = CifParser("input.cif", check_cif=True) structures = parser.parse_structures( primitive=False, check_occu=True, on_error="raise", ) parser_messages = list(parser.warnings) python_messages = [str(item.message) for item in caught]
Do not parse untrusted files in a privileged process. A critical malicious-CIF code-execution flaw affected pymatgen through 2024.2.8 and was fixed in 2024.2.20; the pinned release is newer, but parsers still process attacker controlled input. Use isolation and CPU/RAM/disk/time limits.
Space-group assignment depends on tolerances and structure quality:
pythonfrom pymatgen.symmetry.analyzer import SpacegroupAnalyzer analyzer = SpacegroupAnalyzer( structure, symprec=0.01, # Å angle_tolerance=5.0, # degrees ) symbol = analyzer.get_space_group_symbol() number = analyzer.get_space_group_number()
The Materials Project pipeline commonly uses symprec=0.1 Å, while pymatgen's documented default is 0.01 Å; these can produce different assignments. Generate a sensitivity report instead of changing tolerance until a preferred answer appears:
bashpython scripts/symmetry_sensitivity_report.py structure.cif \ --symprec 0.001,0.01,0.1 --angle-tolerance 1,5
See analysis modules.
Plan first; the planner does not open files or import pymatgen:
bashpython scripts/io_conversion_plan.py \ --input input.cif --input-format cif \ --output POSCAR.new --output-format poscar \ --periodic --coordinate-mode direct
Then convert to a new path with explicit loss acknowledgement:
bashpython scripts/structure_converter.py input.cif POSCAR.new \ --output-format poscar --coordinate-mode direct --allow-lossy \ --acknowledge-parser-warnings
CIF, POSCAR, XYZ, and JSON do not preserve the same semantics. Check lattice, periodicity, coordinate mode, species ordering, selective dynamics, site properties, oxidation states, labels, and disorder after every conversion. See I/O formats.
Transform a copy and preserve history:
pythonfrom pymatgen.alchemy.materials import TransformedStructure from pymatgen.transformations.standard_transformations import ( SubstitutionTransformation, SupercellTransformation, ) tracked = TransformedStructure(structure.copy(), []) tracked.append_transformation(SupercellTransformation([2, 2, 2])) tracked.append_transformation(SubstitutionTransformation({"Na": "K"})) derived = tracked.final_structure history = tracked.history
One-to-many ordering, doping, slab, and magnetic transformations can expand combinatorially or invoke optional executables. Bound candidates, sites, supercell size, runtime, and output count. See transformations and workflows.
The bundled generator is offline and accepts only a strict JSON schema with total eV per entry and provenance:
json{ "schema_version": "1.0", "energy_unit": "eV", "energy_basis": "total_per_entry", "provenance": { "source": "reviewed local calculations", "method": "one compatible energy/correction scheme" }, "entries": [ { "entry_id": "local-Li", "composition": "Li", "energy_eV": -1.0, "provenance": {"source": "calculation manifest sha256:..."} } ] }
bashpython scripts/phase_diagram_generator.py entries.json --analyze Li2O
Elemental endpoints and all competing phases must be present. Do not mix raw energies from different functionals, pseudopotentials, magnetic states, or correction conventions. Computed on-hull status is not experimental stability.
Parse only the data needed:
pythonfrom pymatgen.io.vasp import Vasprun run = Vasprun( "vasprun.xml", parse_dos=True, parse_eigen=True, parse_projected_eigen=False, parse_potcar_file=False, ) band_structure = run.get_band_structure(line_mode=True) band_gap = band_structure.get_band_gap() complete_dos = run.complete_dos
Projected eigenvalues can require extreme memory. Verify convergence, k-path, spin/SOC settings, Fermi-level conventions, smearing, and projection basis before interpreting gaps or DOS. A parser success is not a converged calculation.
Current Q-Chem interfaces are pymatgen.io.qchem.inputs.QCInput and pymatgen.io.qchem.outputs.QCOutput:
pythonfrom pymatgen.io.qchem.inputs import QCInput job = QCInput( molecule, rem={"job_type": "sp", "method": "wb97x-v", "basis": "def2-svpd"}, ) text = str(job)
Pymatgen writes inputs and parses outputs; it does not grant a VASP or Q-Chem license or establish method validity. POTCAR files are VASP-licensed and are not distributed by pymatgen. Never redistribute them or scan unrelated directories for them. Optional tools such as enumlib, Bader, packmol, ffmpeg, and Zeo++ are native/external executables: review provenance, licenses, argv, working directory, and resource limits before a separate explicit invocation.
Use only:
pythonfrom mp_api.client import MPRester
The client reads MP_API_KEY when constructed. Supply only that named environment variable through the user's shell or secret manager. Do not accept the key as a CLI argument, traverse .env files, dump environment variables, or print exception data without redaction.
Dry-run planning is the default:
bashpython scripts/mp_query.py \ --chemsys Li-Fe-O \ --energy-above-hull 0 0.05 \ --fields formula_pretty,energy_above_hull,band_gap,origins \ --limit 25
Only --execute permits one bounded summary query and requires a new output:
bashpython scripts/mp_query.py \ --material-id mp-149 \ --fields formula_pretty,structure,origins,last_updated \ --limit 1 --output mp-149.json --execute
The CLI sets num_chunks=1, requires explicit fields and filters, caps results, does not implement an implicit result cache, and never overwrites output. MPRester initialization also performs compatibility/heartbeat metadata requests; the plan discloses these, disables the platform-detail user agent and local database-version notification log, and records the returned database version. The summary workflow does not request full-dataset cache downloads. mp-api 0.46.4 retries HTTP 429/502/504 according to its own configured policy and respects Retry-After; do not invent a numeric service quota or add an unbounded retry loop.
Materials Project core values are computed, method-dependent data—not experimental truth. PBE commonly overestimates lattice parameters and systematically underestimates band gaps; aggregated values can change across database releases. Preserve retrieval time, query, fields, material/task origins, database release when available, client versions, CC BY attribution, and the canonical plus property-specific citations. See Materials Project API.
All CLIs have dependency-free --help, lazy scientific imports, bounded JSON, and no implicit network:
scripts/composition_structure_validator.py — strict composition/structurechecks; optional oxidation-state guessing is explicit and bounded.
scripts/structure_analyzer.py — bounded lattice, sites, symmetry, distance,and optional CrystalNN report.
scripts/symmetry_sensitivity_report.py — tolerance-grid space groups.scripts/io_conversion_plan.py — dependency-free representation-loss plan.scripts/structure_converter.py — one-file conversion to a new path.scripts/phase_diagram_generator.py — strict local computed-entry hull.scripts/mp_query.py — dry-run MP query plan and opt-in bounded client.scripts/artifact_manifest.py — checksums, versions, sources, and provenance.Use:
bashpython scripts/artifact_manifest.py \ --artifact input.cif --artifact analysis.json \ --workflow "local symmetry sensitivity" --output manifest.json
Other measured skills in the registry, with their headline benchmark lift.