On Sat, Apr 24, 2010 at 5:25 PM, James Stroud <xtald...@gmail.com> wrote:

> I want to programmatically generate the symmetry mates for a molecule and
> write out the files containing the symmetry related molecules. I'm resisting
> the urge to reinvent the wheel.
>
> What is the best way to do this? I'd prefer to do it within a python
> program using an open source library, but I'd settle for scripting an
> external program if that is the only option.


Either PyMOL or CCTBX can do this, but it may take some experimenting and
fine-tuning to get exactly what you want, which isn't entirely clear from
your question.  PyMOL just generates symmetry-related molecules within a
specified radius of the original object, which is okay for interactive use
(or if you just want to see crystal packing), but less useful if you want
just the molecules related by the symmetry operators of the space group, or
just the unit cell.  (I'm assuming you can use PyMOL as a module to do this
instead of running the full program, but I haven't tried this before.)

Within CCTBX, it is very easy (although not at all intuitive) to apply the
symmetry operators; a very rough example is appended below.  However, these
won't necessarily pack together or fill the unit cell.  It is possible I am
doing something completely wrong, because I never really understood symmetry
very well, but the new chains all align perfectly with symmetry mates
created by PyMOL, so I think the operators are being used correctly.  An
example in P212121 is shown here:
http://cci.lbl.gov/~nat/img/symops.png
I suspect there is an easy way to fill the unit cell instead, but I'm too
tired to figure it out right now.  If I can get my simple script working
satisfactorily I'll add it to CCTBX.

On the non-Python side, Gerard Kleywegt's program XPAND appears to be
designed for this - haven't tried that either, but I suspect it will give
you something closer to what you want.  Not sure whether CCP4 exposes
similar functionality anywhere.

-Nat


# usage: cctbx.python <script_name> <pdb_file>
# the PDB file must contain a CRYST1 record.

from iotbx.file_reader import any_file
import scitbx.matrix
from scitbx.array_family import flex
import sys, os

def run (args) :
  pdb_file = args[0]
  pdb_inp = any_file(pdb_file, force_type="pdb").file_object
  symm = pdb_inp.crystal_symmetry()
  sg = symm.space_group()
  uc = symm.unit_cell()
  symops = sg.all_ops()
  out = open("unit_cell.pdb", "w")
  for symop in symops :
    r = symop.r()
    t = symop.t()
    rt = scitbx.matrix.rt((r.as_double(), t.as_double()))
    pdb_hierarchy = pdb_inp.construct_hierarchy().deep_copy()
    atoms = pdb_hierarchy.atoms()
    sites_frac = uc.fractionalize(sites_cart=atoms.extract_xyz())
    new_sites = sites_frac * r.as_double() + t.as_double()
    atoms.set_xyz(uc.orthogonalize(sites_frac=new_sites))
    out.write(pdb_hierarchy.as_pdb_string())
  out.close()

if __name__ == "__main__" :
  run(sys.argv[1:])

Reply via email to