transformations_workflows.md
393 lines · skills/pymatgen/references/transformations_workflows.md at 5f2bc03
Most marks come from matching words in the file, so treat them as pointers.
Transformations and provenance-preserving workflows
Transformations create scientific hypotheses and derived structures. They are not harmless cleanup. Always retain the original, make assumptions explicit, bound candidate growth, and record parent/child checksums.
Raw lines 1 to 6Transformation contract
A pymatgen transformation exposes apply_transformation(structure, ...). One-to-one transformations return a structure; one-to-many transformations can return ranked dictionaries when explicitly requested.
from pymatgen.transformations.standard_transformations import (
SubstitutionTransformation,
SupercellTransformation,
)
parent = structure.copy()
supercell = SupercellTransformation([2, 2, 2]).apply_transformation(parent)
substituted = SubstitutionTransformation({"Na": "K"}).apply_transformation(
parent
)Even if a transformation currently returns a new object, keep parent unchanged and assert it against a pre-operation checksum.
For every transformation, record:
- fully qualified class and package versions
- constructor arguments and defaults relied upon
- parent artifact/checksum
- occupancy, oxidation-state, charge, spin, and site-property assumptions
- candidate count/ranking method
- warnings and external executable use
- child artifact/checksum
Supercells
from pymatgen.transformations.standard_transformations import (
SupercellTransformation,
)
transformation = SupercellTransformation(
[[2, 0, 0], [0, 2, 0], [0, 0, 2]]
)
child = transformation.apply_transformation(parent)Check:
- scaling-matrix determinant is a positive integer
- expected site-count multiplier
- volume-per-site consistency
- atom/site-property mapping
- periodic boundary conditions
- memory and output growth
Reject a matrix or candidate whose determinant/site count exceeds the reviewed bound. A non-diagonal matrix changes the cell basis and site ordering.
Raw lines 39 to 63Substitution and disorder
Complete substitution:
from pymatgen.transformations.standard_transformations import (
SubstitutionTransformation,
)
child = SubstitutionTransformation({"Fe": "Mn"}).apply_transformation(parent)Partial substitution creates disorder:
disordered = SubstitutionTransformation(
{"Fe": {"Fe": 0.5, "Mn": 0.5}}
).apply_transformation(parent)Verify composition, charge model, oxidation states, occupancy sums, and whether all intended sites—not just a selected sublattice—were transformed. Partial occupancy is an average/disordered representation, not one ordered atomic configuration.
Raw lines 64 to 88Removing species and sites
from pymatgen.transformations.standard_transformations import (
RemoveSpeciesTransformation,
)
child = RemoveSpeciesTransformation(["H"]).apply_transformation(parent)Removing species changes composition, charge, and possibly connectivity. Never use it as silent parser cleanup. Record removed site indices/species and validate charge/stoichiometry afterward.
Raw lines 89 to 102Primitive and conventional cells
from pymatgen.transformations.standard_transformations import (
ConventionalCellTransformation,
PrimitiveCellTransformation,
)
primitive = PrimitiveCellTransformation(
tolerance=0.5,
).apply_transformation(parent)
conventional = ConventionalCellTransformation(
symprec=0.01,
angle_tolerance=5,
).apply_transformation(parent)These results depend on symmetry tolerances and can change site order or site properties. Compare formula and volume per atom, preserve exact tolerances, and do not treat standardized cells from different conventions as byte-identical.
Raw lines 103 to 123Strain and deformation
from pymatgen.transformations.standard_transformations import (
DeformStructureTransformation,
)
deformed = DeformStructureTransformation(
[[1.01, 0, 0], [0, 1.0, 0], [0, 0, 1.0]]
).apply_transformation(parent)State whether a matrix is a deformation gradient, strain-like approximation, or lattice transform. Bound determinant, condition number, minimum distances, and strain magnitude. Generate positive and negative strains under one manifest for tensor fitting.
Raw lines 124 to 140Oxidation-state decoration
Oxidation states are inputs to several transformations and electrostatic rankings. Decoration can be explicit or guessed. Prefer explicit mappings grounded in chemistry:
decorated = parent.copy()
decorated.add_oxidation_state_by_element({"Li": 1, "O": -2})If a guesser is explicitly approved, bound complexity and preserve all candidate assignments and assumptions. Do not present the first guess as a measured charge state.
Raw lines 141 to 155Ordering disordered structures
from pymatgen.transformations.standard_transformations import (
OrderDisorderedStructureTransformation,
)
transformation = OrderDisorderedStructureTransformation()
ranked = transformation.apply_transformation(
disordered,
return_ranked_list=20,
)Ordering can grow combinatorially. Before running:
- verify rational occupancies and the required supercell
- require oxidation states if electrostatic ranking needs them
- cap maximum cell size, sites, candidates, runtime, RAM, and disk
- state the ranking model and ties
- preserve unreturned-candidate count when known
The top-ranked ordering is model-dependent, not a unique ground state.
Raw lines 156 to 179EnumerateStructureTransformation and enumlib
EnumerateStructureTransformation generates symmetrically distinct orderings and requires the external enumlib executables (enum.x and makestr.x). Several advanced transformations, including magnetic ordering, can rely on enumeration.
Current installation docs recommend Enumlib.jl, which provides both executables in recent releases, alongside the original Fortran implementation. The docs record makestr.x tolerance failures on some inputs and a makeStr.py fallback; verify the selected implementation on the actual structure. Current pymatgen idealizes coordinates within the declared symmetry tolerance and raises when fewer structures are produced than enumerated. Preserve those warnings and the returned count. External enumlib execution was not tested in this refresh.
Treat enumlib as a separate native-code execution:
- verify official source, version, build instructions, license, and hash
- resolve the executable path explicitly
- review exact argv and working directory
- isolate untrusted inputs
- enforce cell-size, candidate, CPU, RAM, disk, and wall-time limits
- preserve stdout/stderr and exit status
Do not install or invoke enumlib automatically.
Raw lines 180 to 205Doping and charge balance
Advanced doping and charge-balance transformations encode chemical and electrostatic assumptions. A requested dopant does not uniquely define:
- substituted host species/site
- oxidation state
- concentration/supercell
- compensating vacancies or co-dopants
- ordering
Require those choices before execution and report every generated candidate. Validate composition and net formal charge after each transformation.
Raw lines 206 to 219Slabs and surfaces
SlabTransformation and SlabGenerator require explicit Miller index, slab thickness, vacuum thickness, shift/termination, and cell-reduction choices. Bound the number of terminations and generated structures. Record whether sizes are in Å or unit planes.
Never overwrite the bulk parent. Surface energies additionally require consistent bulk/slab methods, atom/reference accounting, surface area, and whether one or two equivalent surfaces are present.
Raw lines 220 to 230Magnetic ordering
MagOrderingTransformation uses proposed magnetic moments and can enumerate orderings. Record:
- magnetic species and moment magnitudes/units (typically μB)
- collinear/non-collinear assumptions
- supercell and ordering constraints
- enumlib version if used
- candidate count and ranking method
Generated magnetic arrangements are calculation inputs, not converged magnetic ground states.
Raw lines 231 to 244Track history with TransformedStructure
from pymatgen.alchemy.materials import TransformedStructure
from pymatgen.transformations.standard_transformations import (
SubstitutionTransformation,
SupercellTransformation,
)
tracked = TransformedStructure(parent.copy(), [])
tracked.append_transformation(SupercellTransformation([2, 2, 2]))
tracked.append_transformation(SubstitutionTransformation({"Na": "K"}))
child = tracked.final_structure
history = tracked.historyThe history is useful but not sufficient provenance. Also store:
- input and output checksums
- warning stream
- exact versions and dependency lock
- user intent and acceptance criteria
- units and coordinate conventions
- external executable metadata
Use strict JSON after schema validation; do not use pickle.
Raw lines 245 to 272Workflow 1: validated local derivation
- Hash and validate the original.
- Capture parser warnings, units, PBC, coordinate mode, occupancy/disorder, oxidation states, minimum distances, and site properties.
- Define transformation and bounds in a JSON plan.
- Apply to a copy.
- Validate the child and compare composition/site/lattice invariants expected for that transformation.
- Write to a new path.
- Create an artifact manifest linking parent, plan, and child.
Bundled helpers:
python scripts/composition_structure_validator.py structure input.cif
python scripts/artifact_manifest.py \
--artifact input.cif --artifact transformed.json \
--workflow "reviewed supercell derivation" --output manifest.jsonRaw lines 273 to 293Workflow 2: disorder to bounded ordered candidates
- Preserve the disordered parent as JSON/CIF.
- Validate occupancy sums and intended site groups.
- Define supercell/cell-size and candidate cap.
- State oxidation states and ranking model.
- Review enumlib native execution if required.
- Generate no more than the approved number of candidates.
- Validate each candidate and preserve mapping/rank.
- Do not call rank 1 the ground state without an appropriate converged energy calculation.
Workflow 3: compatible local phase diagram
- Collect total energies and composition for one compatible method/correction scheme.
- Preserve run and correction provenance per entry.
- Include elemental endpoints and relevant competitors.
- Write strict JSON with
energy_basis: total_per_entry. - Run:
python scripts/phase_diagram_generator.py entries.json --analyze Li2O- Report eV/atom normalized outputs and dataset limitations.
- Preserve the exact entries JSON and report checksum.
Workflow 4: VASP input preparation
from pymatgen.io.vasp.sets import MPRelaxSet
input_set = MPRelaxSet(
child,
user_incar_settings={"ENCUT": 600},
)Before write_input():
- review every generated file and user override
- verify VASP/input-set version compatibility
- confirm functional, DFT+U, magnetism, spin/SOC, k-points, smearing, and convergence
- handle POTCARs only under the user's VASP license
- write to a new calculation directory
Pymatgen does not run VASP or establish convergence.
Raw lines 322 to 343Workflow 5: band-structure chain
- Relax under a documented method and verify convergence.
- Parse the final structure to a new artifact.
- Perform a compatible static calculation.
- Generate a line-mode non-SCF calculation with a documented k-path and crystallographic setting.
- Parse with projected eigenvalues disabled unless required.
- Report method, structure, k-path, spin/SOC, Fermi convention, and numerical convergence with the gap.
Each stage must link to the exact previous output checksum. Do not reuse a stale structure or charge density silently.
Raw lines 344 to 357Workflow 6: Materials Project to local analysis
- Dry-run a bounded query with explicit fields and limit.
- Review CC BY attribution, citation, and computed-data limitations.
- Execute only with
--executeand the namedMP_API_KEY. - Preserve retrieval time, query, fields, origins, client versions, and database release when available.
- Validate downloaded structures locally.
- Perform transformations/analysis offline on new derived artifacts.
The database object is computed input with provenance, not experimental truth.
Raw lines 358 to 369Candidate and output bounds
Every automated workflow should cap:
- input bytes and sites
- supercell determinant
- generated candidates/slabs/orderings
- neighbors, k-points, bands, and projected arrays
- JSON records/bytes and plot points
- CPU, RAM, disk, and wall time
Stop on bound exhaustion and report partial progress; never silently truncate a candidate set and present it as exhaustive.
Raw lines 370 to 383