Supercell: Difference between revisions
Jump to navigation
Jump to search
(categories) |
(symexpcell) |
||
Line 2: | Line 2: | ||
Can display multiple copies of the unit cell. | Can display multiple copies of the unit cell. | ||
Can also fill the unit cell (and its copies) with symmetry mates. | |||
See [http://sourceforge.net/mailarchive/forum.php?thread_name=l2vdcf611bd1004140816zeca28714mf76b9f72008099ab%40mail.gmail.com&forum_name=pymol-users thread on pymol-users mailing list]. | See [http://sourceforge.net/mailarchive/forum.php?thread_name=l2vdcf611bd1004140816zeca28714mf76b9f72008099ab%40mail.gmail.com&forum_name=pymol-users thread on pymol-users mailing list]. | ||
Line 12: | Line 13: | ||
supercell 2,1,1, 2x19, green | supercell 2,1,1, 2x19, green | ||
supercell 1,1,2, 2x19, orange, name=super2 | supercell 1,1,2, 2x19, orange, name=super2 | ||
supercell 1,1,2, 2x19, orange, name=super2, withmates=1 | |||
</source> | </source> | ||
Line 21: | Line 23: | ||
PyMOL python script (load with `run supercell.py`) | PyMOL python script (load with `run supercell.py`) | ||
Usage: See "help supercell" | Usage: See "help supercell" and "help symexpcell" | ||
''' | ''' | ||
from pymol import cmd, cgo | from pymol import cmd, cgo, xray | ||
from math import cos, sin, radians, sqrt | from math import cos, sin, radians, sqrt | ||
import numpy | import numpy | ||
Line 43: | Line 45: | ||
return basis * edges # numpy.array multiplication! | return basis * edges # numpy.array multiplication! | ||
def supercell(a=1, b=1, c=1, object=None, color='blue', name='supercell'): | def supercell(a=1, b=1, c=1, object=None, color='blue', name='supercell', withmates=0): | ||
''' | ''' | ||
DESCRIPTION | DESCRIPTION | ||
Line 53: | Line 55: | ||
USAGE | USAGE | ||
supercell a, b, c [, object [, color [, name]]] | supercell a, b, c [, object [, color [, name [, withmates]]]] | ||
ARGUMENTS | ARGUMENTS | ||
Line 65: | Line 67: | ||
name = string: name of the cgo object to create {default: supercell} | name = string: name of the cgo object to create {default: supercell} | ||
withmates = bool: also create symmetry mates in displayed cells | |||
{default: 0} | |||
SEE ALSO | SEE ALSO | ||
Line 73: | Line 78: | ||
if object is None: | if object is None: | ||
object = cmd.get_object_list()[0] | object = cmd.get_object_list()[0] | ||
withmates = int(withmates) | |||
sym = cmd.get_symmetry(object) | sym = cmd.get_symmetry(object) | ||
Line 111: | Line 117: | ||
obj.append(cgo.VERTEX) | obj.append(cgo.VERTEX) | ||
obj.extend((shift + vj[j] + vi).tolist()) | obj.extend((shift + vj[j] + vi).tolist()) | ||
if withmates: | |||
symexpcell('m%d%d%d_' % tuple(t), object, *t) | |||
cmd.delete(name) | cmd.delete(name) | ||
cmd.load_cgo(obj, name) | cmd.load_cgo(obj, name) | ||
def symexpcell(prefix='mate', object=None, a=0, b=0, c=0): | |||
''' | |||
DESCRIPTION | |||
Creates all symmetry-related objects for the specified object that | |||
occur with their bounding box center within the unit cell. | |||
USAGE | |||
symexpcell prefix, object, [a, b, c] | |||
ARGUMENTS | |||
prefix = string: prefix of new objects | |||
object = string: object for which to create symmetry mates | |||
a, b, c = integer: create neighboring cell {default: 0,0,0} | |||
SEE ALSO | |||
symexp | |||
''' | |||
if object is None: | |||
object = cmd.get_object_list()[0] | |||
sym = cmd.get_symmetry(object) | |||
cell_edges = sym[0:3] | |||
cell_angles = sym[3:6] | |||
spacegroup = sym[6] | |||
basis = cellbasis(cell_angles, cell_edges) | |||
basis = numpy.matrix(basis) | |||
extent = cmd.get_extent(object) | |||
center = sum(numpy.array(extent)) * 0.5 | |||
center = numpy.matrix(center.tolist() + [1.0]).T | |||
center_cell = basis.I * center | |||
extra_shift = [[float(i)] for i in (a,b,c)] | |||
i = 0 | |||
matrices = xray.sg_sym_to_mat_list(spacegroup) | |||
for mat in matrices: | |||
i += 1 | |||
mat = numpy.matrix(mat) | |||
shift = numpy.floor(mat * center_cell) | |||
mat[0:3,3] -= shift[0:3,0] | |||
mat[0:3,3] += extra_shift | |||
mat = basis * mat * basis.I | |||
mat_list = list(mat.flat) | |||
name = '%s%d' % (prefix, i) | |||
cmd.create(name, object) | |||
cmd.transform_object(name, mat_list) | |||
cmd.color(i+1, name) | |||
cmd.extend('symexpcell', symexpcell) | |||
cmd.extend('supercell', supercell) | cmd.extend('supercell', supercell) | ||
</source> | </source> |
Revision as of 04:30, 17 April 2010
Overview
Can display multiple copies of the unit cell. Can also fill the unit cell (and its copies) with symmetry mates.
See thread on pymol-users mailing list.
Example
run supercell.py
fetch 2x19, async=0
supercell 2,1,1, 2x19, green
supercell 1,1,2, 2x19, orange, name=super2
supercell 1,1,2, 2x19, orange, name=super2, withmates=1
The Code
'''
(c) 2010 Thomas Holder
PyMOL python script (load with `run supercell.py`)
Usage: See "help supercell" and "help symexpcell"
'''
from pymol import cmd, cgo, xray
from math import cos, sin, radians, sqrt
import numpy
def cellbasis(angles, edges):
'''
For the unit cell with given angles and edge lengths calculate the basis
transformation (vectors) as a 4x4 numpy.array
'''
rad = [radians(i) for i in angles]
basis = numpy.identity(4)
basis[0][1] = cos(rad[2])
basis[1][1] = sin(rad[2])
basis[0][2] = cos(rad[1])
basis[1][2] = (cos(rad[0]) - basis[0][1]*basis[0][2])/basis[1][1]
basis[2][2] = sqrt(1 - basis[0][2]**2 - basis[1][2]**2)
edges.append(1.0)
return basis * edges # numpy.array multiplication!
def supercell(a=1, b=1, c=1, object=None, color='blue', name='supercell', withmates=0):
'''
DESCRIPTION
Draw a supercell, as requested by Nicolas Bock on the pymol-users
mailing list (Subject: [PyMOL] feature request: supercell construction
Date: 04/12/2010 10:12:17 PM (Mon, 12 Apr 2010 14:12:17 -0600))
USAGE
supercell a, b, c [, object [, color [, name [, withmates]]]]
ARGUMENTS
a, b, c = integer: repeat cell in x,y,z direction a,b,c times
{default: 1,1,1}
object = string: name of object to take cell definition from
color = string: color of cell {default: blue}
name = string: name of the cgo object to create {default: supercell}
withmates = bool: also create symmetry mates in displayed cells
{default: 0}
SEE ALSO
show cell
'''
if object is None:
object = cmd.get_object_list()[0]
withmates = int(withmates)
sym = cmd.get_symmetry(object)
cell_edges = sym[0:3]
cell_angles = sym[3:6]
basis = cellbasis(cell_angles, cell_edges)
assert isinstance(basis, numpy.ndarray)
ts = list()
for i in range(int(a)):
for j in range(int(b)):
for k in range(int(c)):
ts.append([i,j,k])
obj = [
cgo.BEGIN,
cgo.LINES,
cgo.COLOR,
]
obj.extend(cmd.get_color_tuple(color))
for t in ts:
shift = basis[0:3,0:3] * t
shift = shift[:,0] + shift[:,1] + shift[:,2]
for i in range(3):
vi = basis[0:3,i]
vj = [
numpy.array([0.,0.,0.]),
basis[0:3,(i+1)%3],
basis[0:3,(i+2)%3],
basis[0:3,(i+1)%3] + basis[0:3,(i+2)%3]
]
for j in range(4):
obj.append(cgo.VERTEX)
obj.extend((shift + vj[j]).tolist())
obj.append(cgo.VERTEX)
obj.extend((shift + vj[j] + vi).tolist())
if withmates:
symexpcell('m%d%d%d_' % tuple(t), object, *t)
cmd.delete(name)
cmd.load_cgo(obj, name)
def symexpcell(prefix='mate', object=None, a=0, b=0, c=0):
'''
DESCRIPTION
Creates all symmetry-related objects for the specified object that
occur with their bounding box center within the unit cell.
USAGE
symexpcell prefix, object, [a, b, c]
ARGUMENTS
prefix = string: prefix of new objects
object = string: object for which to create symmetry mates
a, b, c = integer: create neighboring cell {default: 0,0,0}
SEE ALSO
symexp
'''
if object is None:
object = cmd.get_object_list()[0]
sym = cmd.get_symmetry(object)
cell_edges = sym[0:3]
cell_angles = sym[3:6]
spacegroup = sym[6]
basis = cellbasis(cell_angles, cell_edges)
basis = numpy.matrix(basis)
extent = cmd.get_extent(object)
center = sum(numpy.array(extent)) * 0.5
center = numpy.matrix(center.tolist() + [1.0]).T
center_cell = basis.I * center
extra_shift = [[float(i)] for i in (a,b,c)]
i = 0
matrices = xray.sg_sym_to_mat_list(spacegroup)
for mat in matrices:
i += 1
mat = numpy.matrix(mat)
shift = numpy.floor(mat * center_cell)
mat[0:3,3] -= shift[0:3,0]
mat[0:3,3] += extra_shift
mat = basis * mat * basis.I
mat_list = list(mat.flat)
name = '%s%d' % (prefix, i)
cmd.create(name, object)
cmd.transform_object(name, mat_list)
cmd.color(i+1, name)
cmd.extend('symexpcell', symexpcell)
cmd.extend('supercell', supercell)