I have tried a bunch of apps such as Mercury, OpenLabel but they cannot convert CIF files to XYZ files in bulk. I am also thinking of doing it in Python but just want to know if there's an app for this. Thank you.
2 Answers
ASE
You can use the ase python library to achieve this.
I tested the following code with 3 CIF files obtained from the Crystallographic Open Data: 1569089, 1000017, 1000003 and it produces their respective XYZ files.
Code
from ase.io import read, write
# Define the list of CIF files to convert
cif_files = ['1569089.cif', '1000017.cif', '1000003.cif']
for cif_file in cif_files:
# Read the CIF file using ASE
atoms = read(cif_file)
# Define the output XYZ file name
xyz_file = cif_file.replace('.cif', '.xyz')
# Write the atoms to the output XYZ file using ASE
write(xyz_file, atoms, format='xyz')
Non-molecular systems
For non-molecular structures, the procedure outlined by Vandan Revanur is entirely reasonable. As Geoff mentioned in the comments, you could also opt for OpenBabel instead which allows you to do the conversion in Python or directly on the command-line if you prefer.
On the command-line, it would be something like:
obabel 1569089.cif -O 1569089.xyz
Or to convert files in bulk, either:
for file in *.cif; do obabel "$file" -O "${file/.cif/.xyz}"; done
Or simply:
obabel *.cif -O .xyz -m
Note that by default ASE and OBabel handle the conversion differently. OBabel appears to extract the unit cell, while ASE extracts some form of the super-cell? You can probably tweak this by providing the right options to each, I'd recommend referring to the ASE/Obabel manual if you need to do this.
Molecular systems
For molecules, however, we need to do a bit more work. The cif file rarely contains the coordinates of only a single molecule; some atoms will likely be duplicated due to inhomogeneity in the crystal (multiple occupancies, crystal defects etc.) and solvent and/or counter-ions may be included.
Fortunately, the cod-tools package provides a number of great scripts for dealing with exactly these sorts of problems. After downloading the package (apt install cod-tools
on debian-like systems), you can extract molecules from a cif file using the appropriately named cif_molecule
command.
Using 1569774.cif as an example:
cif_molecule 1569774.cif --largest --one-datablock-output -i --continue-on-errors > 1569774_mol.cif
You can convert the resulting molecular cif file as normal:
obabel 1569774_mol.cif -O 1569774_mol.xyz
The resulting structure might still contain solvent molecules and/or counter ions. If you want to remove these too, specify the -r
option to obabel:
obabel 1569774_mol.cif -O 1569774_mol.xyz -r
For bulk conversion, this would look like:
for file in *.cif; do cif_molecule "$file" --largest --one-datablock-output -i --continue-on-errors | obabel -i cif -O "${file/.cif/.xyz}" -r; done
Note that this extraction process will necessarily lose information. If you just want to visualise the crystal structure, or want to extract the molecule for some further processing (maybe as a starting point for quantum chemistry) this is totally fine. If you want to understand the crystal structure itself, best to leave the file in the cif format.
obabel *.cif -O .xyz -m
you could also do this withpymatgen
or ASE $\endgroup$