Skill Tracer
Skills › Scientific Agent Skills › pymatgen › transformations_workflows.md

transformations_workflows.md

393 lines · skills/pymatgen/references/transformations_workflows.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Transformations and provenance-preserving workflows
2
3Transformations create scientific hypotheses and derived structures. They are
4not harmless cleanup. Always retain the original, make assumptions explicit,
5bound candidate growth, and record parent/child checksums.
6

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 6
7## Transformation contract
8
9A pymatgen transformation exposes `apply_transformation(structure, ...)`.
10One-to-one transformations return a structure; one-to-many transformations can
11return ranked dictionaries when explicitly requested.
13```python
14from pymatgen.transformations.standard_transformations import (
15 SubstitutionTransformation,
16 SupercellTransformation,
19parent = structure.copy()
20supercell = SupercellTransformation([2, 2, 2]).apply_transformation(parent)
21substituted = SubstitutionTransformation({"Na": "K"}).apply_transformation(
22 parent
24```
26Even if a transformation currently returns a new object, keep `parent`
27unchanged and assert it against a pre-operation checksum.
29For every transformation, record:
31- fully qualified class and package versions
32- constructor arguments and defaults relied upon
33- parent artifact/checksum
34- occupancy, oxidation-state, charge, spin, and site-property assumptions
35- candidate count/ranking method
36- warnings and external executable use
37- child artifact/checksum

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.

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
Raw lines 7 to 38
39## Supercells
41```python
42from pymatgen.transformations.standard_transformations import (
43 SupercellTransformation,
46transformation = SupercellTransformation(
47 [[2, 0, 0], [0, 2, 0], [0, 0, 2]]
49child = transformation.apply_transformation(parent)
50```
52Check:
54- scaling-matrix determinant is a positive integer
55- expected site-count multiplier
56- volume-per-site consistency
57- atom/site-property mapping
58- periodic boundary conditions
59- memory and output growth
61Reject a matrix or candidate whose determinant/site count exceeds the reviewed
62bound. A non-diagonal matrix changes the cell basis and site ordering.

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 63
64## Substitution and disorder
66Complete substitution:
68```python
69from pymatgen.transformations.standard_transformations import (
70 SubstitutionTransformation,
73child = SubstitutionTransformation({"Fe": "Mn"}).apply_transformation(parent)
74```
76Partial substitution creates disorder:
78```python
79disordered = SubstitutionTransformation(
80 {"Fe": {"Fe": 0.5, "Mn": 0.5}}
81).apply_transformation(parent)
82```
84Verify composition, charge model, oxidation states, occupancy sums, and whether
85all intended sites—not just a selected sublattice—were transformed. Partial
86occupancy is an average/disordered representation, not one ordered atomic
87configuration.

Substitution 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 88
89## Removing species and sites
91```python
92from pymatgen.transformations.standard_transformations import (
93 RemoveSpeciesTransformation,
96child = RemoveSpeciesTransformation(["H"]).apply_transformation(parent)
97```
99Removing species changes composition, charge, and possibly connectivity.
100Never use it as silent parser cleanup. Record removed site indices/species and
101validate charge/stoichiometry afterward.

Removing 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 102
103## Primitive and conventional cells
105```python
106from pymatgen.transformations.standard_transformations import (
107 ConventionalCellTransformation,
108 PrimitiveCellTransformation,
111primitive = PrimitiveCellTransformation(
112 tolerance=0.5,
113).apply_transformation(parent)
114conventional = ConventionalCellTransformation(
115 symprec=0.01,
116 angle_tolerance=5,
117).apply_transformation(parent)
118```
120These results depend on symmetry tolerances and can change site order or site
121properties. Compare formula and volume per atom, preserve exact tolerances, and
122do not treat standardized cells from different conventions as byte-identical.

Primitive 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 123
124## Strain and deformation
126```python
127from pymatgen.transformations.standard_transformations import (
128 DeformStructureTransformation,
131deformed = DeformStructureTransformation(
132 [[1.01, 0, 0], [0, 1.0, 0], [0, 0, 1.0]]
133).apply_transformation(parent)
134```
136State whether a matrix is a deformation gradient, strain-like approximation,
137or lattice transform. Bound determinant, condition number, minimum distances,
138and strain magnitude. Generate positive and negative strains under one
139manifest for tensor fitting.

Strain 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 140
141## Oxidation-state decoration
143Oxidation states are inputs to several transformations and electrostatic
144rankings. Decoration can be explicit or guessed. Prefer explicit mappings
145grounded in chemistry:
147```python
148decorated = parent.copy()
149decorated.add_oxidation_state_by_element({"Li": 1, "O": -2})
150```
152If a guesser is explicitly approved, bound complexity and preserve all
153candidate assignments and assumptions. Do not present the first guess as a
154measured charge state.

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:

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 155
156## Ordering disordered structures
158```python
159from pymatgen.transformations.standard_transformations import (
160 OrderDisorderedStructureTransformation,
163transformation = OrderDisorderedStructureTransformation()
164ranked = transformation.apply_transformation(
165 disordered,
166 return_ranked_list=20,
168```
170Ordering can grow combinatorially. Before running:
172- verify rational occupancies and the required supercell
173- require oxidation states if electrostatic ranking needs them
174- cap maximum cell size, sites, candidates, runtime, RAM, and disk
175- state the ranking model and ties
176- preserve unreturned-candidate count when known
178The top-ranked ordering is model-dependent, not a unique ground state.

Ordering 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 179
180## EnumerateStructureTransformation and enumlib
182`EnumerateStructureTransformation` generates symmetrically distinct orderings
183and requires the external enumlib executables (`enum.x` and `makestr.x`).
184Several advanced transformations, including magnetic ordering, can rely on
185enumeration.
187Current installation docs recommend Enumlib.jl, which provides both executables
188in recent releases, alongside the original Fortran implementation. The docs
189record `makestr.x` tolerance failures on some inputs and a `makeStr.py` fallback;
190verify the selected implementation on the actual structure. Current pymatgen
191idealizes coordinates within the declared symmetry tolerance and raises when
192fewer structures are produced than enumerated. Preserve those warnings and
193the returned count. External enumlib execution was not tested in this refresh.
195Treat enumlib as a separate native-code execution:
1971. verify official source, version, build instructions, license, and hash
1982. resolve the executable path explicitly
1993. review exact argv and working directory
2004. isolate untrusted inputs
2015. enforce cell-size, candidate, CPU, RAM, disk, and wall-time limits
2026. preserve stdout/stderr and exit status
204Do not install or invoke enumlib automatically.

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.

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:

  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.

Raw lines 180 to 205
206## Doping and charge balance
208Advanced doping and charge-balance transformations encode chemical and
209electrostatic assumptions. A requested dopant does not uniquely define:
211- substituted host species/site
212- oxidation state
213- concentration/supercell
214- compensating vacancies or co-dopants
215- ordering
217Require those choices before execution and report every generated candidate.
218Validate composition and net formal charge after each transformation.

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.

Raw lines 206 to 219
220## Slabs and surfaces
222`SlabTransformation` and `SlabGenerator` require explicit Miller index, slab
223thickness, vacuum thickness, shift/termination, and cell-reduction choices.
224Bound the number of terminations and generated structures. Record whether
225sizes are in Å or unit planes.
227Never overwrite the bulk parent. Surface energies additionally require
228consistent bulk/slab methods, atom/reference accounting, surface area, and
229whether one or two equivalent surfaces are present.

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.

Raw lines 220 to 230
231## Magnetic ordering
233`MagOrderingTransformation` uses proposed magnetic moments and can enumerate
234orderings. Record:
236- magnetic species and moment magnitudes/units (typically μB)
237- collinear/non-collinear assumptions
238- supercell and ordering constraints
239- enumlib version if used
240- candidate count and ranking method
242Generated magnetic arrangements are calculation inputs, not converged magnetic
243ground states.

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.

Raw lines 231 to 244
245## Track history with TransformedStructure
247```python
248from pymatgen.alchemy.materials import TransformedStructure
249from pymatgen.transformations.standard_transformations import (
250 SubstitutionTransformation,
251 SupercellTransformation,
254tracked = TransformedStructure(parent.copy(), [])
255tracked.append_transformation(SupercellTransformation([2, 2, 2]))
256tracked.append_transformation(SubstitutionTransformation({"Na": "K"}))
258child = tracked.final_structure
259history = tracked.history
260```
262The history is useful but not sufficient provenance. Also store:
264- input and output checksums
265- warning stream
266- exact versions and dependency lock
267- user intent and acceptance criteria
268- units and coordinate conventions
269- external executable metadata
271Use strict JSON after schema validation; do not use pickle.

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

Raw lines 245 to 272
273## Workflow 1: validated local derivation
2751. Hash and validate the original.
2762. Capture parser warnings, units, PBC, coordinate mode, occupancy/disorder,
277 oxidation states, minimum distances, and site properties.
2783. Define transformation and bounds in a JSON plan.
2794. Apply to a copy.
2805. Validate the child and compare composition/site/lattice invariants expected
281 for that transformation.
2826. Write to a new path.
2837. Create an artifact manifest linking parent, plan, and child.
285Bundled helpers:
287```bash
288python scripts/composition_structure_validator.py structure input.cif
289python scripts/artifact_manifest.py \
290 --artifact input.cif --artifact transformed.json \
291 --workflow "reviewed supercell derivation" --output manifest.json
292```

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:

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
Raw lines 273 to 293
Runs code python scripts/composition_structure_validator.py :288
Runs code python scripts/artifact_manifest.py :289
294## Workflow 2: disorder to bounded ordered candidates
2961. Preserve the disordered parent as JSON/CIF.
2972. Validate occupancy sums and intended site groups.
2983. Define supercell/cell-size and candidate cap.
2994. State oxidation states and ranking model.
3005. Review enumlib native execution if required.
3016. Generate no more than the approved number of candidates.
3027. Validate each candidate and preserve mapping/rank.
3038. Do not call rank 1 the ground state without an appropriate converged energy
304 calculation.

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.
Raw lines 294 to 305
306## Workflow 3: compatible local phase diagram
3081. Collect total energies and composition for one compatible method/correction
309 scheme.
3102. Preserve run and correction provenance per entry.
3113. Include elemental endpoints and relevant competitors.
3124. Write strict JSON with `energy_basis: total_per_entry`.
3135. Run:
315```bash
316python scripts/phase_diagram_generator.py entries.json --analyze Li2O
317```
3196. Report eV/atom normalized outputs and dataset limitations.
3207. Preserve the exact entries JSON and report checksum.

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:
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.
Raw lines 306 to 321
Runs code python scripts/phase_diagram_generator.py :316
322## Workflow 4: VASP input preparation
324```python
325from pymatgen.io.vasp.sets import MPRelaxSet
327input_set = MPRelaxSet(
328 child,
329 user_incar_settings={"ENCUT": 600},
331```
333Before `write_input()`:
335- review every generated file and user override
336- verify VASP/input-set version compatibility
337- confirm functional, DFT+U, magnetism, spin/SOC, k-points, smearing, and
338 convergence
339- handle POTCARs only under the user's VASP license
340- write to a new calculation directory
342Pymatgen does not run VASP or establish convergence.

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 343
344## Workflow 5: band-structure chain
3461. Relax under a documented method and verify convergence.
3472. Parse the final structure to a new artifact.
3483. Perform a compatible static calculation.
3494. Generate a line-mode non-SCF calculation with a documented k-path and
350 crystallographic setting.
3515. Parse with projected eigenvalues disabled unless required.
3526. Report method, structure, k-path, spin/SOC, Fermi convention, and numerical
353 convergence with the gap.
355Each stage must link to the exact previous output checksum. Do not reuse a
356stale structure or charge density silently.

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.

Raw lines 344 to 357
358## Workflow 6: Materials Project to local analysis
3601. Dry-run a bounded query with explicit fields and limit.
3612. Review CC BY attribution, citation, and computed-data limitations.
3623. Execute only with `--execute` and the named `MP_API_KEY`.
3634. Preserve retrieval time, query, fields, origins, client versions, and
364 database release when available.
3655. Validate downloaded structures locally.
3666. Perform transformations/analysis offline on new derived artifacts.
368The database object is computed input with provenance, not experimental truth.

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.

Raw lines 358 to 369
370## Candidate and output bounds
372Every automated workflow should cap:
374- input bytes and sites
375- supercell determinant
376- generated candidates/slabs/orderings
377- neighbors, k-points, bands, and projected arrays
378- JSON records/bytes and plot points
379- CPU, RAM, disk, and wall time
381Stop on bound exhaustion and report partial progress; never silently truncate a
382candidate set and present it as exhaustive.

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.

Raw lines 370 to 383
384## Sources (verified 2026-09-30)
386- [pymatgen transformations API](https://pymatgen.org/pymatgen.transformations.html)
387- [pymatgen alchemy API](https://pymatgen.org/pymatgen.alchemy.html)
388- [pymatgen symmetry API](https://pymatgen.org/pymatgen.symmetry.html)
389- [pymatgen surface API](https://pymatgen.org/pymatgen.core.html)
390- [pymatgen VASP sets API](https://pymatgen.org/pymatgen.io.vasp.html)
391- [pymatgen installation and enumlib requirements](https://pymatgen.org/installation.html)
392- [pymatgen changelog](https://pymatgen.org/CHANGES.html)
393- [Official pymatgen tutorial series](https://github.com/computron/pymatgen_tutorials)