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:])