Supercell: Difference between revisions

From PyMOLWiki
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)