Reading .CIFs

If you have a .CIF file, use amd.CifReader to extract the crystals. Here are some common patterns when reading .CIFs:

# loop over the reader and get AMDs (k=100) of crystals
amds = []
for p_set in amd.CifReader('file.cif'):
    amds.append(amd.AMD(p_set, 100))

# create list of crystals in a .cif
crystals = list(amd.CifReader('file.cif'))

# create list of crystals in individual .cifs in a folder
# read_one returns the first crystal, nice when the .cif has one crystal
import os
crystals = [amd.CifReader(os.path.join(folder, file)).read_one()
            for file in os.listdir(folder)]

The CifReader yields PeriodicSet objects, which can be passed to amd.AMD() or amd.PDD(). The PeriodicSet has attributes .name, .motif, .cell, .types (atomic types), and information about the asymmetric unit to help with AMD and PDD calculations.

See the references amd.io.CifReader or amd.periodicset.PeriodicSet for more.

Reading options

CifReader accepts the following parameters (many shared by io.CSDReader):

amd.CifReader('file.cif',
              reader='ase',
              remove_hydrogens=False,
              disorder='skip',
              heaviest_component=False,
              extract_data=None,
              include_if=None)
  • reader controls the backend package used to parse the file. The default is ase; to use csd-python-api pass ccdc. The ccdc reader can read any format accepted by ccdc’s EntryReader, though only .CIFs have been tested.

  • remove_hydrogens removes Hydrogen atoms from the structure.

  • disorder controls how disordered structures are handled. The default is to skip any crystal with disorder, since disorder conflicts with the periodic set model. To read disordered structures anyway, choose either ordered_sites to remove sites with disorder or all_sites include all sites regardless.

  • heaviest_component takes the heaviest connected molecule in the motif, intended for removing solvents. Only available when reader='ccdc'.

  • extract_data is used to extract more data from crystals, as in the example below.

  • include_if can remove unwanted structures, as in the example below.

An example only reading entries with a .polymorph label and extracting additional data:

import amd
from amd import ccdc_utils as cu

def has_polymorph_label(entry):
    if entry.polymorph is None:
        return False
    return True

include_if = [has_polymorph_label]

# data to extract. can be any functions accepting an entry, but ccdc_utils has some useful ones
extract = {
    'density':    cu.density,
    'formula':    cu.formula,
    'cell_str':   cu.cell_str_as_html,
    'spacegroup': cu.spacegroup
}

reader = amd.CifReader('file.cif', reader='ccdc', extract_data=extract, include_if=include_if)
...