Back to Claude Scientific Skills

Transformations and provenance-preserving workflows

skills/pymatgen/references/transformations_workflows.md

2.55.012.3 KB
Original Source

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.

Transformation 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.

python
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

python
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.

Substitution and disorder

Complete substitution:

python
from pymatgen.transformations.standard_transformations import (
    SubstitutionTransformation,
)

child = SubstitutionTransformation({"Fe": "Mn"}).apply_transformation(parent)

Partial substitution creates disorder:

python
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.

Removing species and sites

python
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.

Primitive and conventional cells

python
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.

Strain and deformation

python
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.

Oxidation-state decoration

Oxidation states are inputs to several transformations and electrostatic rankings. Decoration can be explicit or guessed. Prefer explicit mappings grounded in chemistry:

python
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.

Ordering disordered structures

python
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.

EnumerateStructureTransformation 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.

Treat enumlib as a separate native-code execution:

  1. verify official source, version, build instructions, license, and hash
  2. resolve the executable path explicitly
  3. review exact argv and working directory
  4. isolate untrusted inputs
  5. enforce cell-size, candidate, CPU, RAM, disk, and wall-time limits
  6. preserve stdout/stderr and exit status

Do not install or invoke enumlib automatically.

Doping 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.

Slabs 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.

Magnetic 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.

Track history with TransformedStructure

python
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.history

The 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.

Workflow 1: validated local derivation

  1. Hash and validate the original.
  2. Capture parser warnings, units, PBC, coordinate mode, occupancy/disorder, oxidation states, minimum distances, and site properties.
  3. Define transformation and bounds in a JSON plan.
  4. Apply to a copy.
  5. Validate the child and compare composition/site/lattice invariants expected for that transformation.
  6. Write to a new path.
  7. Create an artifact manifest linking parent, plan, and child.

Bundled helpers:

bash
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.json

Workflow 2: disorder to bounded ordered candidates

  1. Preserve the disordered parent as JSON/CIF.
  2. Validate occupancy sums and intended site groups.
  3. Define supercell/cell-size and candidate cap.
  4. State oxidation states and ranking model.
  5. Review enumlib native execution if required.
  6. Generate no more than the approved number of candidates.
  7. Validate each candidate and preserve mapping/rank.
  8. Do not call rank 1 the ground state without an appropriate converged energy calculation.

Workflow 3: compatible local phase diagram

  1. Collect total energies and composition for one compatible method/correction scheme.
  2. Preserve run and correction provenance per entry.
  3. Include elemental endpoints and relevant competitors.
  4. Write strict JSON with energy_basis: total_per_entry.
  5. Run:
bash
python scripts/phase_diagram_generator.py entries.json --analyze Li2O
  1. Report eV/atom normalized outputs and dataset limitations.
  2. Preserve the exact entries JSON and report checksum.

Workflow 4: VASP input preparation

python
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.

Workflow 5: band-structure chain

  1. Relax under a documented method and verify convergence.
  2. Parse the final structure to a new artifact.
  3. Perform a compatible static calculation.
  4. Generate a line-mode non-SCF calculation with a documented k-path and crystallographic setting.
  5. Parse with projected eigenvalues disabled unless required.
  6. 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.

Workflow 6: Materials Project to local analysis

  1. Dry-run a bounded query with explicit fields and limit.
  2. Review CC BY attribution, citation, and computed-data limitations.
  3. Execute only with --execute and the named MP_API_KEY.
  4. Preserve retrieval time, query, fields, origins, client versions, and database release when available.
  5. Validate downloaded structures locally.
  6. Perform transformations/analysis offline on new derived artifacts.

The database object is computed input with provenance, not experimental truth.

Candidate 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.

Sources (verified 2026-07-23)