Pysimxrd User Manual

A practical guide for starting from crystal-structure data, reading the provided demo database, simulating one powder XRD pattern, tuning physical conditions, and building a high-throughput simulated dataset.

Contents 1. What Pysimxrd Does 2. Installation 3. Start from Data 4. Simulate One Pattern 5. Plot and Save Figures 6. Parameter Guide 7. WPEM Mode 8. High-throughput Simulation 9. Read Generated Data 10. Troubleshooting

1. What Pysimxrd Does

Pysimxrd generates physically varied powder X-ray diffraction patterns from crystal structures stored in an ASE database. The examples in sim/ show three common workflows:

Default simulationUse generator.parser(database, entry_id) to obtain a normalized 2-theta intensity profile.
Physical variationChange preferred orientation, grain size, thermal vibration, background, noise, and zero shift.
Dataset generationUse sim/ht_simxrd.py to generate many simulated patterns and save them into a new ASE database.

The package has two simulation paths. The default path uses pymatgen for peak positions and the shared broadening/noise model. The optional sim_model="WPEM" path uses in-repository diffraction-condition, extinction, multiplicity, and structure-factor logic.

2. Installation

Create a clean Python environment. The simulation tutorial in sim/tutorial_sim.ipynb recommends Python newer than 3.9.

conda create -n pysimxrd python=3.10
conda activate pysimxrd

Install from PyPI after release:

pip install Pysimxrd

Install from this repository during development:

cd SimXRD/src
pip install -e .

Optional packages for the examples:

pip install matplotlib tqdm
If you work from the repository without installing, run scripts with PYTHONPATH=src from the project root, or run them from an environment where Pysimxrd is installed.

3. Start from Data

Pysimxrd expects crystal structures in an ASE database. The repository includes a small example database at sim/demo_mp.db.

3.1 Inspect the demo database

from ase.db import connect

database = connect("sim/demo_mp.db")
print("number of structures:", database.count())

row = database.get(id=1)
atoms = row.toatoms()

print("formula:", atoms.get_chemical_formula())
print("cell parameters:", atoms.cell.cellpar())
print("symbols:", atoms.get_chemical_symbols()[:10])

An ASE row stores an atomic structure. Pysimxrd reads this row, converts the structure when needed, and returns a simulated XRD profile.

3.2 Prepare your own database

If you already have ASE Atoms objects, write them into a database:

from ase.db import connect

db = connect("my_crystals.db")
db.write(atoms, name="sample_001")

If your structures are in CIF files, load them with ASE and write them to a database:

from ase.io import read
from ase.db import connect

db = connect("my_crystals.db")
atoms = read("example.cif")
db.write(atoms, name="example")

After that, use my_crystals.db in exactly the same way as sim/demo_mp.db.

4. Simulate One Pattern

The core entry point is Pysimxrd.generator.parser. It returns x and y arrays.

from ase.db import connect
from Pysimxrd import generator

database = connect("sim/demo_mp.db")
entry_id = 1

x, y = generator.parser(database, entry_id)

print(len(x), len(y))
print(x[:5])
print(y[:5])

By default, x is 2-theta in degrees and y is normalized intensity.

Return d-spacing instead of 2-theta

x_d, intensity = generator.parser(
    database,
    entry_id,
    xrd="real",
)

5. Plot and Save Figures

The notebook sim/XRD.ipynb plots default settings, stronger preferred orientation, and stronger thermal vibration. The same code can be used in a Python script.

import matplotlib.pyplot as plt
from ase.db import connect
from Pysimxrd import generator

database = connect("sim/demo_mp.db")
x, y = generator.parser(database, entry_id=8)

plt.figure(figsize=(8, 6))
plt.plot(x, y, color="royalblue", linewidth=2.5)
plt.xlabel("2θ (degrees)", fontsize=14, weight="bold")
plt.ylabel("Intensity (a.u.)", fontsize=14, weight="bold")
plt.grid(True, which="both", linestyle="--", linewidth=0.5)
plt.tight_layout()
plt.savefig("xrd_pattern.png", dpi=300)
plt.show()
Default simulated XRD pattern
Default simulation example from sim/XRD.ipynb.

6. Parameter Guide

The high-throughput script sim/ht_simxrd.py documents the main simulation parameters. The most useful controls are:

ParameterMeaningTypical use
grainsizeSpecimen grain size in Angstroms.Smaller values broaden peaks.
prefect_orientationPreferred-orientation variation range. The name is kept for compatibility.Increase to vary relative peak intensities.
thermo_vibrationThermal vibration amplitude in Angstroms.Higher values reduce and broaden peak features.
zero_shift2-theta angular offset in degrees.Simulate instrument zero error.
background_orderPolynomial background order.Usually 4 or 6.
background_ratioBackground strength relative to peak intensity.Increase for noisier baseline.
mixture_noise_ratioUniform mixed-noise ratio.Increase for random intensity noise.
deformationWhether to randomly deform lattice constants.Use for data augmentation.
lattice_extinction_ratioStretching/compression ratio for deformation.Controls random length perturbation.
lattice_torsion_ratioShear ratio for deformation.Controls random angular/shear perturbation.

Examples from sim/XRD.ipynb

# More preferred-orientation variation
x, y = generator.parser(database, entry_id=8, prefect_orientation=[0.2, 0.2])

# Stronger thermal vibration and smaller grain size
x, y = generator.parser(database, entry_id=8, thermo_vibration=0.4, grainsize=5)
Preferred orientation example
Preferred-orientation example.
Thermal vibration example
Thermal vibration and small-grain example.

7. WPEM Mode

Use WPEM mode when you want the in-repository diffraction condition, systematic extinction, multiplicity, and structure-factor pipeline.

x, y = generator.parser(
    database,
    entry_id=1,
    sim_model="WPEM",
)

Use WPEM with deformation:

x, y = generator.parser(
    database,
    entry_id=1,
    sim_model="WPEM",
    deformation=True,
    lattice_extinction_ratio=0.01,
    lattice_torsion_ratio=0.01,
)
In WPEM deformation mode, symmetry information is obtained from the undeformed conventional cell. Deformed lattice constants are then used for peak position and d-spacing calculations. This keeps extinction and atom coordinates tied to the original symmetry while still producing peak shifts.

8. High-throughput Simulation

The file sim/ht_simxrd.py shows how to simulate many patterns from one input database and save them to a new ASE database.

Run the example from the sim/ directory:

cd sim
python ht_simxrd.py

For a long job, the notebook suggests:

nohup python ht_simxrd.py &

The script reads demo_mp.db, writes train.db, and by default generates one simulated pattern per structure in the demo script.

Core batch pattern

from ase.db import connect
from Pysimxrd import generator

input_db = connect("my_crystals.db")
output_db = connect("my_simulated_xrd.db")

for row in input_db.select():
    atoms = row.toatoms()
    x, y = generator.parser(input_db, row.id, deformation=True)
    output_db.write(
        atoms=atoms,
        latt_dis=str(x),
        intensity=str(y),
        Label=row.id,
    )

The high-throughput script adds randomized parameters such as grain size, orientation, thermal vibration, and zero shift for each simulation.

9. Read Generated Data

The generated database stores the original atoms plus simulated arrays as string fields. Convert them back to arrays with ast.literal_eval or numpy.fromstring depending on the string format you wrote.

from ase.db import connect
import numpy as np

db = connect("sim/train.db")
row = db.get(id=1)

atoms = row.toatoms()
x = np.fromstring(row.latt_dis.strip("[]"), sep=" ")
y = np.fromstring(row.intensity.strip("[]"), sep=",")

print(atoms.get_chemical_formula())
print(x.shape, y.shape)

If you save arrays with str(list(x)), use ast.literal_eval instead:

import ast
import numpy as np

x = np.array(ast.literal_eval(row.latt_dis))
y = np.array(ast.literal_eval(row.intensity))

10. Troubleshooting

ProblemFix
ModuleNotFoundError: PysimxrdInstall the package with pip install -e src from the repository root, or run with PYTHONPATH=src.
Database path not foundUse paths relative to the current working directory. From the project root use sim/demo_mp.db; from inside sim/ use demo_mp.db.
Entry id errorCheck database.count() and use ASE row ids, usually starting from 1.
Unexpected output axisUse xrd="reciprocal" for 2-theta and xrd="real" for d-spacing.
Slow batch simulationUse the process-pool pattern in sim/ht_simxrd.py and start with a small times value for testing.