graphics python chemistry povray ase 28 September 2017

Superimpose chemical structures

How to make nice graphics from multiple structures

I was struggling recently how to present multiple chemical structures that differed slightly in their geometry but

import os
import re
from collections import OrderedDict
from ase import Atoms
import ase.io


def read_structures(path, fpatt, verbose=False):
    '''
    Read all the structures from `path` that match the `fpatt` pattern
    '''

    fpatt = re.compile(fpatt)

    out = {'II': OrderedDict(), 'III': OrderedDict(), 'IV': OrderedDict()}

    for fname in os.listdir(path):
        m = fpatt.match(fname)
        if m:
            symbol, oxs = m.group(1), m.group(2)
            out[oxs][symbol] = ase.io.read(os.path.join(path, fname))
        else:
            if verbose:
                print('ERROR ', fname)

    print('Read: ', ', '.join(['{}: {}'.format(k, len(v)) for k, v in out.items()]))

    return out

if __name__ == '__main__':

    path = 'AlPO-5-H'
    patt = r'([A-Za-z]+)\(([IV]+)\)-AlPO-5-O2-H\.traj'

    halpo = read_structures(path, patt)

    atoms = Atoms()

    for me, a in halpo['IV'].items():
        atoms = atoms + a

    transmittances = [0.8] * len(atoms)

    ase.io.write('Me-AlPO-5-H.pov', atoms,
        rotation='-15y',
        show_unit_cell=0,
        run_povray=True,
        display=False,
        pause=True,
        canvas_width=1024,
        camera_type='perspective',
        transmittances=transmittances)

    ase.io.write('Me-AlPO-5-H_0y.pov', atoms,
        rotation='',
        show_unit_cell=0,
        run_povray=True,
        display=False,
        pause=True,
        canvas_width=1024,
        camera_type='perspective',
        transmittances=transmittances)

Rendering the scenes for multiple structures was a bit too slow for my laptop so I had to use a supercomputer to speed things up.

This is a bit of a special case since the structures are taken from a periodic crystals and therefore all have the same unit cell size. It simpifies things a lot since then all the coordinates are given with respect to origin of the unit cell which is the same for all the materials. For (non-periodic) molecules we would have to align the molecules first since their coordinates can be defined with respect to different origins. One possible solution is to minimize the root mean square deviation between the structures in order to realign them which is usually done using the Kabsch algorithm. For those curious to see it in practice e is also a python available rmsdpy.