Understanding Seed Files#
Learn what seed files are, how they work, and how to design effective seeds for structure searching.
What is a Seed?#
A seed file is a template that defines the search space for random structure generation. It specifies:
Which elements to include
How many atoms of each type
The initial cell dimensions
Constraints on the generated structures
Symmetry requirements
Think of a seed as a recipe: it doesn’t specify the exact structure, but rather the rules for generating possible structures.
Seed File Format#
AIRSS uses a CASTEP-style .cell file format. Here’s a simple example:
%BLOCK lattice_cart
4.0 0.0 0.0
0.0 4.0 0.0
0.0 0.0 4.0
%ENDBLOCK lattice_cart
%BLOCK positions_abs
Si 0.0 0.0 0.0 # Si0 % NUM=4
%ENDBLOCK positions_abs
#MINSEP=2.0
#VARVOL=20
#SYMMOPS=2-4
The # is a comment symbol for CASTEP, but not for buildcell. So the actual builcell directives always has a # prefix. A ## symbol will comment out the line for build CASTEP and buildcell.
Components#
lattice_cart: Initial cell vectors (will be randomized)
positions_abs: Atomic positions with generation tags
Generation tags: Comments starting with
#(e.g.,#MINSEP,#VARVOL)
Creating Seeds with airsspy#
In airsspy, you create seeds programmatically using the SeedAtoms class:
from airsspy import SeedAtoms
# Create a seed
seed = SeedAtoms('Si', cell=[4, 4, 4], pbc=True)
# Set per-atom tags
seed[0].num = 4 # Generate 4 Si atoms
# Set global tags
seed.gentags.minsep = 2.0 # Minimum separation
seed.gentags.varvol = 20 # Volume variation
seed.gentags.symmops = (2, 4) # 2-4 symmetry operations
This is equivalent to the file format shown above, but more convenient and less error-prone.
How buildcell Uses Seeds#
When you generate a structure from a seed:
Reads composition: Determines which atoms and how many
Calculates target volume: Based on cell size and number of atoms
Randomizes cell: Varies volume and cell shape
Places atoms: Randomly, respecting constraints
Applies symmetry: If symmetry operations requested
Checks constraints: Ensures minsep and other requirements met
If constraints can’t be satisfied, buildcell will timeout and return failure.
Designing Effective Seeds#
Start Simple#
Begin with minimal constraints:
seed = SeedAtoms('C4', cell=[3, 3, 3], pbc=True)
seed[0].num = 4
seed.gentags.minsep = 1.2 # Basic constraint only
Add more constraints if needed based on results.
Use Chemical Intuition#
Apply realistic constraints based on chemistry:
# Si-O system with realistic separations
seed = SeedAtoms('SiO2', cell=[5, 5, 5], pbc=True)
seed.gentags.minsep = (1.2, {
'Si-O': 1.5, # Si-O bonds typically ~1.6 Å
'O-O': 2.0, # O-O should be further apart
'Si-Si': 2.5 # Si-Si even further
})
Consider Symmetry#
If you expect certain symmetry:
# Likely to be cubic
seed.gentags.system = 'cubic'
seed.gentags.symmops = (4, 8)
# Or specific space group number
seed.gentags.symmno = 225 # Fm-3m
But don’t over-constrain - you might miss the true structure!
Volume Scaling#
The initial cell volume is multiplied by the number of formula units:
seed = SeedAtoms('C', cell=[2, 2, 2], pbc=True)
seed[0].num = 8
# Initial volume: 2³ = 8 ų
# Target volume: 8 × 8 = 64 ų
# Actual volume: 64 ± varvol%
Set targvol to override this behavior:
seed.gentags.targvol = 10.0 # 10 ų per formula unit
Common Seed Patterns#
Binary Compound#
# AB₂ compound (e.g., SiO₂, TiO₂)
seed = SeedAtoms('SiO2', cell=[5, 5, 5], pbc=True)
seed.gentags.minsep = (1.5, {'Si-O': 1.6, 'O-O': 2.0})
seed.gentags.varvol = 20
seed.gentags.symmops = (2, 4)
Pure Element#
# Elemental system (e.g., carbon, silicon)
seed = SeedAtoms('C', cell=[3, 3, 3], pbc=True)
seed[0].num = 8
seed.gentags.minsep = 1.3
seed.gentags.symmops = (4, 12) # Higher symmetry likely
Complex Composition#
# Multi-element system
seed = SeedAtoms('AlNO', cell=[4, 4, 4], pbc=True)
al = seed[0]
al.num = (2, 4) # 2-4 Al
n = seed[1]
n.num = 2 # Exactly 2 N
o = seed[2]
o.num = (2, 6) # 2-6 O
seed.gentags.minsep = (1.4, {
'Al-N': 1.7,
'Al-O': 1.6,
'N-O': 1.2
})
Surface Slab#
# Slab with vacuum
seed = SeedAtoms('Pt8', cell=[5, 5, 15], pbc=True)
seed[0].num = 8
seed.gentags.minsep = 2.5
seed.gentags.slab = True # Constrain to slab geometry
seed.gentags.vacuum = 10.0 # 10 Å vacuum
Troubleshooting Seeds#
Generation Always Fails#
If build_random_atoms() consistently returns None:
Problem: Constraints too tight Solution: Relax minsep or increase cell size
# Too tight
seed.gentags.minsep = 3.0 # For 8 atoms in 3×3×3 cell
# Better
seed.gentags.minsep = 1.8
Problem: Cell too small Solution: Increase initial cell dimensions
# Too small
seed = SeedAtoms('C8', cell=[2, 2, 2], pbc=True)
# Better
seed = SeedAtoms('C8', cell=[4, 4, 4], pbc=True)
All Structures Too Similar#
If generated structures lack diversity:
Problem: Too much symmetry Solution: Reduce symmetry constraints
# Too constrained
seed.gentags.symmops = (8, 12)
# More diverse
seed.gentags.symmops = (1, 4)
Problem: Not enough volume variation Solution: Increase varvol
# Too rigid
seed.gentags.varvol = 5
# More variation
seed.gentags.varvol = 30
Unrealistic Structures#
If generated structures are chemically unrealistic:
Problem: Minsep too small Solution: Use element-specific separations
# Generic
seed.gentags.minsep = 1.0
# Element-specific
seed.gentags.minsep = (1.2, {'Si-O': 1.5, 'O-O': 1.8})
Advanced Concepts#
Formula Units#
Use nform to control the number of formula units:
# SiO₂ with 2-4 formula units = 6-12 atoms total
seed = SeedAtoms('SiO2', cell=[5, 5, 5], pbc=True)
seed.gentags.nform = (2, 4)
Position Amplitudes#
Control how much atoms can move from initial positions:
seed = SeedAtoms('AB', cell=[4, 4, 4], pbc=True)
seed[0].posamp = 2.0 # A can move ±2 Å from initial position
seed[1].posamp = 0.5 # B stays closer to initial position
Nested Ranges#
Some parameters support nested ranges for sophisticated control:
# MINSEP with ranges
seed.gentags.minsep = ((1.5, 2.0), {'Si-O': (1.6, 1.9)})
# POSAMP nested ranges
seed.gentags.posamp = ((1.0, 2.0), {})
Best Practices#
Test your seed: Generate a few structures to verify constraints work
Inspect output: Look at generated structures to check they’re reasonable
Iterate: Start loose, tighten constraints based on results
Document: Keep notes on which seed parameters work well
Save seeds: Write successful seeds to files for reproducibility
# Save a seed for future use
seed.write_seed('good-seed.cell')
See Also#
Creating Seeds - Practical examples
Buildcell Parameters - Complete parameter reference
AIRSS Overview - Understanding the AIRSS method