UUID and Lineage Tracking in ASSYST

This notebook demonstrates how ASSYST tracks the derivation history of structures using UUIDs.

from assyst.crystals import pyxtal
from assyst.perturbations import Rattle, Stretch, Series
from assyst.relax import Relax
from assyst.calculators import Morse
import ase

1. Initial Structure Generation

When we generate a structure with pyxtal, it automatically receives a UUID and a seed.

atoms = pyxtal(225, species=['Cu'], num_ions=[4])
print(f"Current UUID: {atoms.info['uuid']}")
print(f"Seed UUID:    {atoms.info['seed']}")
print(f"Lineage:      {atoms.info.get('lineage', [])}")

2. Relaxation

Relaxation creates a new structure with a new UUID and updates the lineage.

calc = Morse()
relax = Relax(max_steps=5)

atoms.calc = calc.get_calculator()
relaxed = relax.relax(atoms)

print(f"Current UUID: {relaxed.info['uuid']}")
print(f"Seed UUID:    {relaxed.info['seed']}")
print(f"Lineage:      {relaxed.info['lineage']}")

3. Applying Perturbations

Perturbations further extend the lineage.

rattle = Rattle(sigma=0.05)
perturbed = rattle(relaxed.copy())

print(f"Current UUID: {perturbed.info['uuid']}")
print(f"Seed UUID:    {perturbed.info['seed']}")
print(f"Lineage:      {perturbed.info['lineage']}")

4. Multiple Steps

Lineage accumulates as we apply more modifications.

stretch = Stretch(hydro=0.05, shear=0.05)
final = stretch(perturbed.copy())

print(f"Current UUID: {final.info['uuid']}")
print(f"Seed UUID:    {final.info['seed']}")
print(f"Lineage:      {final.info['lineage']}")