|
|
(28 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
− | SuperSym is a PyMOL plugin providing a large number of tools for visualization of space groups; unit cells; and symmetry axes, operators, and partners. Source code for version 1.0 is below.
| + | {{Infobox script-repo |
| + | |type = plugin |
| + | |filename = plugins/SuperSymPlugin.py |
| + | |author = [[User:Srballard|Stuart Ballard]] |
| + | |license = |
| + | }} |
| | | |
− | ==Dependencies and Acknowledgments==
| + | [[File:SuperSymExample.png|300px|thumb|right|Symmetry partners for 1hpv showing 6-1 screw axis]] |
| + | [[File:SuperSymExample2.png|300px|thumb|right|Full cell of symmetry partners with symmetry axes displayed]] |
| + | SuperSym is a PyMOL plugin providing a large number of tools for visualization of space groups; unit cells; and symmetry axes, operators, and partners. |
| | | |
− | Pre-v1.0 PyMOL may not display objects created by this plugin properly. Use at your own risk.
| + | The original source code is available from https://sourceforge.net/projects/supersym/ |
| | | |
− | This plugin requires cctbx and numeric python.
| + | == Dependencies == |
| | | |
− | Code for unit cell and symmetry axis building is borrowed from scripts created by Robert Campbell, available at [http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/ http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/]. This code has been modified for use in SuperSym.
| + | * [[CCTBX|cctbx]] |
| + | * numpy |
| | | |
− | [[FindSurfaceResidues]] is utilized for some of SuperSym's graphics generation, with some modifications. | + | '''PyMOL, cctbx and numpy must all be compiled with the same Python distribution!''' |
| + | See [[CCTBX]]. |
| | | |
− | ==Using SuperSym==
| + | This plugin was developed in 2010 for PyMOL version 1.2r1 and has not been updated since. |
| | | |
− | To use SuperSym, copy the text of source files to corresponding .py files. Place SuperSymMenu.py in pymol/modules/pmg_tk/startup, and all other files in pymol/modules.
| + | == Bugs == |
| | | |
− | To use functions of SuperSym directly, without creating a drop-down menu in the PyMOL GUI, ignore SuperSymMenu.py and run the other files in PyMOL as you would for any other script.
| + | Symmetry axes are not defined for all space groups, and do not display properly for some. |
| | | |
− | ==Source Files== | + | == Acknowledgments == |
| | | |
− | File: SuperSym.py
| + | Primary coding and development was done by Stuart Ballard. All comments, questions, and issues should be directed to him at srballard@wisc.edu. |
− | <source lang="python">
| |
− | from Tkinter import *
| |
− | import tkSimpleDialog
| |
− | import tkMessageBox
| |
− | import tkColorChooser
| |
− | import sys
| |
− | from pymol import stored, cmd, selector
| |
− | import math
| |
− | from cctbx import sgtbx, uctbx
| |
− | import numpy as N
| |
− | from numpy.linalg import *
| |
− | import draw_cell as draw_cell
| |
− | import draw_symops_cctbx as sym_axes
| |
| | | |
− | '''
| + | Code for unit cell and symmetry axis building is borrowed from scripts created by Robert Campbell and Ralf W. Grosse-Kunstleve, available at [http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/ http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/]. Some of this code has been modified for use in SuperSym. |
− | symDialog: Dialog generator and command issuer for generating symmetry partners
| |
| | | |
− | This function is called by SuperSymMenu when any symmetry partner generating option is
| + | [[FindSurfaceResidues]] is utilized for some of SuperSym's graphics generation, with some modifications. |
− | selected. It creates dialog windows and receives user input for symmetry generation parameters.
| |
− | | |
− | @app -- identifies the GUI interface to build dialog boxes onto.
| |
− | @mode -- determines specific treatment of symmetry building command
| |
− | '''
| |
− | def symDialog(app, mode):
| |
− | prefix = tkSimpleDialog.askstring('Prefix',
| |
− | 'Enter desired prefix for these partners:', parent=app.root)
| |
− | object = tkSimpleDialog.askstring('Object',
| |
− | 'Enter object to generate partners from:', parent=app.root)
| |
− | if (mode == 0): #make default symmetry set in cell [0,0,0]
| |
− | symset(prefix, object)
| |
− | if (mode == 1): #make symmetry set in custom cell
| |
− | cell = tkSimpleDialog.askstring('Cell',
| |
− | 'Enter lattice cell coordinates separated by commas (ex:x,y,z):', parent = app.root)
| |
− | x,y,z = cell.split(',')
| |
− | x,y,z = int(x),int(y),int(z)
| |
− | symset(prefix, object, x, y, z)
| |
− | if mode == 2: #make 2x2x2 block of symmetry sets
| |
− | for i in range(2):
| |
− | for j in range(2):
| |
− | for k in range(2):
| |
− | symset(prefix, object, i, j, k)
| |
− | if mode == 3: #make 3x3x3 block of symmetry sets
| |
− | for i in range(-1,2):
| |
− | for j in range(-1,2):
| |
− | for k in range(-1,2):
| |
− | symset(prefix, object, i, j, k)
| |
− | if mode == 4: #select individual partners by operation and cell
| |
− | ops = get_operations(object)
| |
− | opString = ""
| |
− | for i in range(len(ops)):
| |
− | opString = opString + str(i) + " : " + ops[i] + "\n"
| |
− | opIndeces = tkSimpleDialog.askstring("Symmetry Operations", opString +
| |
− | "Enter numbers of desired operations separated by commas (ex:0,2,9)", parent = app.root)
| |
− | opListStrings = opIndeces.split(",")
| |
− | opList = []
| |
− | for op in opListStrings:
| |
− | opList.append(int(op))
| |
− | cell = tkSimpleDialog.askstring('Cell',
| |
− | 'Enter lattice cell coordinates separated by commas (ex:x,y,z):', parent = app.root)
| |
− | x,y,z = cell.split(',')
| |
− | x,y,z = int(x),int(y),int(z)
| |
− | symset(prefix, object, x,y,z, opList)
| |
− | | |
− | '''
| |
− | colorDialog: Dialog generator for coloring commands
| |
− | | |
− | This function colors sets of symmetry partners defined by the user in the
| |
− | dialog which it generates.
| |
− | | |
− | @app -- identifies root menu calling this function
| |
− | @mode -- determines coloring scheme to execute
| |
− | '''
| |
− | def colorDialog(app, mode):
| |
− | prefix = tkSimpleDialog.askstring('Prefix',
| |
− | 'Enter the prefix of symmetry partners to color', parent = app.root)
| |
− | if mode == 0: #standard rainbow by symmetry operation
| |
− | colors = ["red", "orange", "yellow", "green", "blue", "purple",
| |
− | "salmon", "grey", "pink", "teal", "brown", "br0", "aquamarine",
| |
− | "deepolive", "dirtyviolet", "slate", "br4", "darksalmon", "br7",
| |
− | "chocolate", "firebrick", "brightorange"]
| |
− | for i in range(10):
| |
− | try: #required because PyMOL inappropriately throws an exception
| |
− | #when the cmd.color() function colors no objects
| |
− | cmd.color(colors[i], prefix + "0" + str(i) + "*")
| |
− | except:
| |
− | pass #allows us to move on to next symmetry operator
| |
− | for i in range(10,20):
| |
− | try: #required because PyMOL inappropriately throws an exception
| |
− | #when the cmd.color() function colors no objects
| |
− | cmd.color(colors[i], prefix + str(i) + "*")
| |
− | except:
| |
− | pass #allows us to move on to next symmetry operator
| |
− | if mode == 1: #specify for each symmetry operation
| |
− | cmd.iterate_state(1, prefix + "*", "stored.tmpObject = model")
| |
− | ops = get_operations(stored.tmpObject)
| |
− | opString = ""
| |
− | for i in range(len(ops)):
| |
− | opString = opString + str(i) + " : " + ops[i] + "\n"
| |
− | opIndeces = tkSimpleDialog.askstring("Symmetry Operations", opString +
| |
− | "Enter numbers of desired operations separated by commas (ex:0,2,9) or all", parent = app.root)
| |
− | if opIndeces == "all":
| |
− | opList = []
| |
− | for i in range(len(ops)):
| |
− | opList.append(i)
| |
− | else:
| |
− | opList = opIndeces.split(",")
| |
− | opStringList = opString.split("\n")
| |
− | for i in opList:
| |
− | tempColor = tkColorChooser.askcolor(title = "Color for " + opStringList[int(i)], parent = app.root)[0]
| |
− | rgb = []
| |
− | for value in tempColor:
| |
− | value = float(value)
| |
− | value = value/255
| |
− | rgb.append(value)
| |
− | cmd.set_color("tempColor", rgb)
| |
− | try:
| |
− | if int(i) < 10:
| |
− | cmd.color("tempColor", prefix + "0" + str(i) + "*")
| |
− | if int(i) > 9:
| |
− | cmd.color("tempColor", prefix + str(i) + "*")
| |
− | except:
| |
− | pass
| |
− | if mode == 2: #monochrome for a set of operations
| |
− | cmd.iterate_state(1, prefix + "*", "stored.tmpObject = model")
| |
− | ops = get_operations(stored.tmpObject)
| |
− | opString = ""
| |
− | for i in range(len(ops)):
| |
− | opString = opString + str(i) + " : " + ops[i] + "\n"
| |
− | opIndeces = tkSimpleDialog.askstring("Symmetry Operations", opString +
| |
− | "Enter numbers of desired operations separated by commas (ex:0,2,9) or all", parent = app.root)
| |
− | if opIndeces == 'all':
| |
− | opList = []
| |
− | for i in range(len(ops)):
| |
− | opList.append(i)
| |
− | else:
| |
− | opList = opIndeces.split(",")
| |
− | opStringList = opString.split("\n")
| |
− | tempColor = tkColorChooser.askcolor(parent = app.root)[0]
| |
− | rgb = []
| |
− | for value in tempColor:
| |
− | value = float(value)
| |
− | value = value/255
| |
− | rgb.append(value)
| |
− | cmd.set_color("tempColor", rgb)
| |
− | for i in opList:
| |
− | try:
| |
− | if int(i) < 10:
| |
− | cmd.color("tempColor", prefix + "0" + str(i) + "*")
| |
− | if int(i) > 9:
| |
− | cmd.color("tempColor", prefix + str(i) + "*")
| |
− | except:
| |
− | pass
| |
− | '''
| |
− | graphicsDialog: Dialog generator for graphics commands
| |
− | | |
− | This function sets visual representations for sets of symmetry partners.
| |
− | | |
− | @app -- identifies root menu
| |
− | @mode -- determines type of representation to show
| |
− | '''
| |
− | def graphicsDialog(app, mode):
| |
− | prefix = tkSimpleDialog.askstring('Prefix',
| |
− | 'Enter prefix of symmetry partners to display', parent = app.root)
| |
− | cmd.hide("everything", prefix + "*")
| |
− | if mode == 0: # show lines
| |
− | cmd.show("lines", prefix + "*")
| |
− | if mode == 1: # show ribbon
| |
− | cmd.show("ribbon", prefix + "*")
| |
− | if mode == 2: # sphere surface
| |
− | objSel = prefix + "*"
| |
− | findSurfaceResidues(objSel, 3.5, "surface")
| |
− | cmd.set("sphere_scale", 1.8)
| |
− | cmd.show("spheres", "surface")
| |
− | if mode == 3: # regular surface
| |
− | cmd.show("surface", prefix + "*")
| |
− | | |
− | '''
| |
− | cellDialog: dialog proxy for draw_cell
| |
− | | |
− | This function generates a unit cell representation
| |
− | FUTURE IMPLEMENTATIONS: select which lattice coordinates to generate unit cell for
| |
− | | |
− | @app -- identifies root menu
| |
− | '''
| |
− | def cellDialog(app):
| |
− | object = tkSimpleDialog.askstring('Object',
| |
− | 'Enter object to generate cell for:', parent = app.root)
| |
− | if tkMessageBox.askyesno('3D Printing', 'Going to print this model?', parent = app.root):
| |
− | draw_cell.draw_cell(object, 3.0)
| |
− | else:
| |
− | draw_cell.draw_cell(object)
| |
− | | |
− | '''
| |
− | axesDialog: dialog proxy for draw_symops_cctbx
| |
− | | |
− | This function generates one set of symmetry axes for a given object
| |
− | FUTURE IMPLEMENTATIONS: select individual axes to generate, attach to model for 3D printing,
| |
− | generate axes for multiple unit cells
| |
− | | |
− | @app -- identifies root menu
| |
− | '''
| |
− | def axesDialog(app):
| |
− | object = tkSimpleDialog.askstring('Object',
| |
− | 'Enter object to generate symmetry axes for:', parent = app.root)
| |
− | if tkMessageBox.askyesno('3D Printing', 'Going to print this model?', parent = app.root):
| |
− | sym_axes.draw_symops(object, 2.0)
| |
− | else:
| |
− | sym_axes.draw_symops(object)
| |
− | | |
− | '''
| |
− | cellShiftInfo: displays info for using cell_shift hotkeys
| |
− | | |
− | @app -- identifies root menu
| |
− | '''
| |
− | def cellShiftInfo(app):
| |
− | tkMessageBox.showinfo('Cell Shifting',
| |
− | "To shift a symmetry partner, simply click to select any part of it (select only one partner at a time). \n\n" +
| |
− | "Next, hold ALT and press the numpad key corresponding to the axis direction you\'d like to move. \n\n" +
| |
− | "Key assignments:\n" +
| |
− | "A (x) axis: down--4, up--6 \n" +
| |
− | "B (y) axis: down--2, up--8 \n" +
| |
− | "C (z) axis: down--1, up--5", parent = app.root)
| |
− | tkMessageBox.showwarning('Caution', 'Only attempt to shift symmetry partners created by SuperSym.'+
| |
− | 'Attempting to shift any other object will result in errors.')
| |
− | | |
− | def aboutInfo(app):
| |
− | tkMessageBox.showinfo('About',
| |
− | 'SuperSym v1.0\nDeveloped by Stuart Ballard (srballard@wisc.edu)\nDepartment of Biochemistry\n'+
| |
− | 'University of Wisconsin-Madison', parent = app.root)
| |
− | def helpInfo(app):
| |
− | tkMessageBox.showinfo('Help',
| |
− | 'For documentation see http://pymolwiki.org/index.php/SuperSym', parent = app.root)
| |
− | | |
− | '''
| |
− | symset: generates up to one full set of symmetry partners for a given object in a given lattice position
| |
− | | |
− | 1. Obtain all essential symmetry information from CCTBX. This includes the space group, unit cell parameters,
| |
− | and fractional coordinates corresponding to symmetry operations.
| |
− | 2. Generate transformation matrices to translate coordinates from orthogonal to fractional, and back.
| |
− | 3.
| |
− | '''
| |
− | def symset(prefix = "sym", object = -1, x=0,y=0,z=0, opList = []):
| |
− | if object == -1:
| |
− | object = cmd.get_names()[0]
| |
− | cell = [float(x),float(y),float(z)]
| |
− | view = cmd.get_view()
| |
− | cmd.show("lines", object)
| |
− | sgInfo = cmd.get_symmetry(object)
| |
− | raw_ops = []
| |
− | for s in sgtbx.space_group_info(sgInfo[6]).group():
| |
− | raw_ops.append(str(s))
| |
− | if (len(opList) == 0):
| |
− | for i in range(len(raw_ops)):
| |
− | opList.append(i)
| |
− | a,b,c,alpha,beta,gamma = sgInfo[0:6]
| |
− | ca = math.cos(math.radians(alpha))
| |
− | cb = math.cos(math.radians(beta))
| |
− | cg = math.cos(math.radians(gamma))
| |
− | sb = math.sin(math.radians(beta))
| |
− | sg = math.sin(math.radians(gamma))
| |
− | stored.fracToOrt = N.array([[a, b * cg, c * cb],
| |
− | [0.0, b * sg, c * (ca - cb * cg) / sg],
| |
− | [0.0, 0.0, c * sb * math.sqrt(1.0 - ((cb * cg - ca) / (sb * sg))**2)]])
| |
− | stored.fracToOrt = stored.fracToOrt.transpose()
| |
− | stored.ortToFrac = inv(stored.fracToOrt)
| |
− | for i in opList:
| |
− | try:
| |
− | stored.tmpOp = raw_ops[i]
| |
− | except:
| |
− | print "Bad symmetry partner numbers. Try again."
| |
− | quit()
| |
− | if i > 9:
| |
− | copy = prefix + str(i) + "_" + str(x) + "_" + str(y) + "_" + str(z)
| |
− | else:
| |
− | copy = prefix + "0" + str(i) + "_" + str(x) + "_" + str(y) + "_" + str(z)
| |
− | cmd.copy(copy, object)
| |
− | #COPIES COORDINATES OF EACH ATOM TO CORRESPONDING ONE IN GIVEN SYMMETRY PARTNER
| |
− | cmd.alter_state(1, copy, "x,y,z = cmd.sym_partner([x,y,z], stored.tmpOp)")
| |
− | #MOVES SYMMETRY PARTNER TO PROPER LATTICE COORDINATES AND CORRECTS FOR NATIVE LATTICE POSITION ERROR
| |
− | stored.xSum,stored.ySum,stored.zSum = 0.0,0.0,0.0
| |
− | atoms = cmd.count_atoms(copy)
| |
− | cmd.iterate_state(1, copy, "stored.xSum = stored.xSum + x; stored.ySum = stored.ySum + y; stored.zSum = stored.zSum + z")
| |
− | xMean = (stored.xSum / atoms)
| |
− | yMean = (stored.ySum / atoms)
| |
− | zMean = (stored.zSum / atoms)
| |
− | xError, yError, zError = N.dot(N.array([xMean,yMean,zMean]), stored.ortToFrac)
| |
− | dX,dY,dZ = -math.floor(xError) + cell[0], -math.floor(yError) + cell[1], -math.floor(zError) + cell[2]
| |
− | cell_shift(copy,dX,dY,dZ, 0)
| |
− | cmd.hide("everything", object)
| |
− | cmd.set_view(view)
| |
− | | |
− | def sym_partner(coords, op):
| |
− | fracCoords = N.dot(N.array(coords), stored.ortToFrac)
| |
− | op = op.replace("x", "(" + str(fracCoords[0]) + ")")
| |
− | op = op.replace("y", "(" + str(fracCoords[1]) + ")")
| |
− | op = op.replace("z", "(" + str(fracCoords[2]) + ")")
| |
− | op = op.split(",")
| |
− | for i in range(3):
| |
− | index = op[i].find("/")
| |
− | if index != -1:
| |
− | if len(op[i]) == index + 2:
| |
− | op[i] = op[i][0:index - 1] + str(float(op[i][index - 1]) / float(op[i][index + 1]))
| |
− | else:
| |
− | op[i] = op[i][0:index - 1] + str(float(op[i][index - 1]) / float(op[i][index + 1])) + op[i][index + 2:]
| |
− | op[i] = eval(op[i])
| |
− | return N.dot(N.array(op), stored.fracToOrt)
| |
− | | |
− | def cell_shift_proxyX1():
| |
− | cmd.iterate_state(1, "sele", "stored.tmpObject = model")
| |
− | cell_shift(stored.tmpObject, 1,0,0)
| |
− | def cell_shift_proxyX2():
| |
− | cmd.iterate_state(1, "sele", "stored.tmpObject = model")
| |
− | cell_shift(stored.tmpObject, -1,0,0)
| |
− | def cell_shift_proxyY1():
| |
− | cmd.iterate_state(1, "sele", "stored.tmpObject = model")
| |
− | cell_shift(stored.tmpObject, 0,1,0)
| |
− | def cell_shift_proxyY2():
| |
− | cmd.iterate_state(1, "sele", "stored.tmpObject = model")
| |
− | cell_shift(stored.tmpObject, 0,-1,0)
| |
− | def cell_shift_proxyZ1():
| |
− | cmd.iterate_state(1, "sele", "stored.tmpObject = model")
| |
− | cell_shift(stored.tmpObject, 0,0,1)
| |
− | def cell_shift_proxyZ2():
| |
− | cmd.iterate_state(1, "sele", "stored.tmpObject = model")
| |
− | cell_shift(stored.tmpObject, 0,0,-1)
| |
− | | |
− | def cell_shift(object, dX, dY, dZ, rename = 1):
| |
− | if rename:
| |
− | oldName = object.split("_")
| |
− | oldPre = oldName[0]
| |
− | oldX = int(oldName[1])
| |
− | oldY = int(oldName[2])
| |
− | oldZ = int(oldName[3])
| |
− | newX = "_" + str(int(dX) + oldX)
| |
− | newY = "_" + str(int(dY) + oldY)
| |
− | newZ = "_" + str(int(dZ) + oldZ)
| |
− | newName = oldPre + newX + newY + newZ
| |
− | #if cmd.get_names().find(newName) != -1:
| |
− | # print "Symmetry partner already exists in destination position!"
| |
− | # quit()
| |
− | cmd.set_name(object, newName)
| |
− | object = newName
| |
− | stored.shift = [float(dX),float(dY),float(dZ)]
| |
− | stored.sgInfo = cmd.get_symmetry(object)
| |
− | a,b,c,alpha,beta,gamma = stored.sgInfo[0:6]
| |
− | ca = math.cos(math.radians(alpha))
| |
− | cb = math.cos(math.radians(beta))
| |
− | cg = math.cos(math.radians(gamma))
| |
− | sb = math.sin(math.radians(beta))
| |
− | sg = math.sin(math.radians(gamma))
| |
− | stored.fracToOrt = N.array([[a, b * cg, c * cb],
| |
− | [0.0, b * sg, c * (ca - cb * cg) / sg],
| |
− | [0.0, 0.0, c * sb * math.sqrt(1.0 - ((cb * cg - ca) / (sb * sg))**2)]])
| |
− | stored.fracToOrt = stored.fracToOrt.transpose()
| |
− | stored.ortToFrac = inv(stored.fracToOrt)
| |
− | cmd.alter_state(1, object, "x,y,z = cmd.cell_shift_helper([x,y,z],stored.shift)")
| |
− |
| |
− | | |
− | def shift_and_copy(object, dX, dY, dZ):
| |
− | oldName = object.split("_")
| |
− | oldPre = oldName[0]
| |
− | oldX = int(oldName[1])
| |
− | oldY = int(oldName[2])
| |
− | oldZ = int(oldName[3])
| |
− | newX = "_" + str(int(dX) + oldX)
| |
− | newY = "_" + str(int(dY) + oldY)
| |
− | newZ = "_" + str(int(dZ) + oldZ)
| |
− | copy = oldPre + newX + newY + newZ
| |
− | if cmd.count_atoms(copy) != 0:
| |
− | print "Symmetry partner already exists in destination position!"
| |
− | quit()
| |
− | cmd.copy(newName, object)
| |
− | stored.shift = [float(dX),float(dY),float(dZ)]
| |
− | stored.sgInfo = cmd.get_symmetry(object)
| |
− | a,b,c,alpha,beta,gamma = stored.sgInfo[0:6]
| |
− | ca = math.cos(math.radians(alpha))
| |
− | cb = math.cos(math.radians(beta))
| |
− | cg = math.cos(math.radians(gamma))
| |
− | sb = math.sin(math.radians(beta))
| |
− | sg = math.sin(math.radians(gamma))
| |
− | stored.fracToOrt = N.array([[a, b * cg, c * cb],
| |
− | [0.0, b * sg, c * (ca - cb * cg) / sg],
| |
− | [0.0, 0.0, c * sb * math.sqrt(1.0 - ((cb * cg - ca) / (sb * sg))**2)]])
| |
− | stored.fracToOrt = stored.fracToOrt.transpose()
| |
− | stored.ortToFrac = inv(stored.fracToOrt)
| |
− | cmd.alter_state(1, newName, "x,y,z = cell_shift_helper([x,y,z],stored.shift)")
| |
− | | |
− | | |
− | def cell_shift_helper(coords, shift):
| |
− | fracCoords = N.dot(N.array(coords), stored.ortToFrac)
| |
− | for i in range(3):
| |
− | fracCoords[i] = fracCoords[i] + shift[i]
| |
− | coords = N.dot(N.array(fracCoords), stored.fracToOrt)
| |
− | return coords[0], coords[1], coords[2]
| |
− | | |
− | def get_operations(object):
| |
− | raw_ops = []
| |
− | sgInfo = cmd.get_symmetry(object)
| |
− | for s in sgtbx.space_group_info(sgInfo[6]).group():
| |
− | raw_ops.append(str(s))
| |
− | return raw_ops
| |
− | | |
− | def get_orthogonalization_matrix(object, quiet = 0):
| |
− | a,b,c,alpha,beta,gamma = cmd.get_symmetry(object)[0:6]
| |
− | ca = math.cos(math.radians(alpha))
| |
− | cb = math.cos(math.radians(beta))
| |
− | cg = math.cos(math.radians(gamma))
| |
− | sb = math.sin(math.radians(beta))
| |
− | sg = math.sin(math.radians(gamma))
| |
− | fracToOrt = N.array([[a, b * cg, c * cb],
| |
− | [0.0, b * sg, c * (ca - cb * cg) / sg],
| |
− | [0.0, 0.0, c * sb * math.sqrt(1.0 - ((cb * cg - ca) / (sb * sg))**2)]])
| |
− | if not quiet:
| |
− | print fracToOrt
| |
− | print inv(fracToOrt)
| |
− | return fracToOrt
| |
− | | |
− | # -*- coding: utf-8 -*-
| |
− | # this function is borrowed from findSurfaceResidues script on PyMOL wiki
| |
− | def findSurfaceResidues(objSel="(all)", cutoff=2.5, selName = 0):
| |
− | """
| |
− | findSurfaceResidues
| |
− | finds those residues on the surface of a protein
| |
− | that have at least 'cutoff' exposed A**2 surface area.
| |
− |
| |
− | PARAMS
| |
− | objSel (string)
| |
− | the object or selection in which to find
| |
− | exposed residues
| |
− | DEFAULT: (all)
| |
− |
| |
− | cutoff (float)
| |
− | your cutoff of what is exposed or not.
| |
− | DEFAULT: 2.5 Ang**2
| |
− |
| |
− | asSel (boolean)
| |
− | make a selection out of the residues found
| |
− |
| |
− | RETURNS
| |
− | (list: (chain, resv ) )
| |
− | A Python list of residue numbers corresponding
| |
− | to those residues w/more exposure than the cutoff.
| |
− |
| |
− | """
| |
− | tmpObj="__tmp"
| |
− | cmd.create( tmpObj, objSel + " and polymer");
| |
− | cmd.set("dot_solvent");
| |
− | cmd.get_area(selection=tmpObj, load_b=1)
| |
− |
| |
− | # threshold on what one considers an "exposed" atom (in A**2):
| |
− | cmd.remove( tmpObj + " and b < " + str(cutoff) )
| |
− |
| |
− | stored.tmp_dict = {}
| |
− | cmd.iterate(tmpObj, "stored.tmp_dict[(chain,resv)]=1")
| |
− | exposed = stored.tmp_dict.keys()
| |
− | exposed.sort()
| |
− |
| |
− | cmd.select(selName, objSel + " in " + tmpObj )
| |
− | cmd.delete(tmpObj)
| |
− |
| |
− | return exposed
| |
− | </source>
| |
− | File: SuperSymMenu.py
| |
− | <source lang="python">
| |
− | from Tkinter import *
| |
− | import tkFileDialog
| |
− | from pymol import cmd, selector
| |
− | from SuperSym import *
| |
− | | |
− | def __init__(self):
| |
− | #MAIN
| |
− | self.menuBar.addmenu('SuperSym','SuperSym')
| |
− | #DEFAULT SET BUILD
| |
− | self.menuBar.addmenuitem('SuperSym', 'command', 'Default Symmetry Partner Set',
| |
− | label = 'Default Symmetry Partner Set',
| |
− | command = lambda s = self: symDialog(s, 0))
| |
− | #UNIT CELL BUILD
| |
− | self.menuBar.addmenuitem('SuperSym', 'command', 'Draw Unit Cell',
| |
− | label = 'Draw Unit Cell',
| |
− | command = lambda s = self: cellDialog(s))
| |
− | #SYM SUBMENU
| |
− | self.menuBar.addcascademenu('SuperSym', 'Build Symmetry Partners')
| |
− | | |
− | self.menuBar.addmenuitem('Build Symmetry Partners', 'command', 'Cell [0,0,0] (default)',
| |
− | label = 'Cell [0,0,0] (default)',
| |
− | command = lambda s = self: symDialog(s, 0))
| |
− | | |
− | self.menuBar.addmenuitem('Build Symmetry Partners', 'command', 'Cell [x,y,z] (custom)',
| |
− | label = 'Cell [x,y,z] (custom)',
| |
− | command = lambda s = self: symDialog(s, 1))
| |
− | | |
− | self.menuBar.addmenuitem('Build Symmetry Partners', 'command', '2x2x2 Block',
| |
− | label = '2x2x2 Block',
| |
− | command = lambda s = self: symDialog(s, 2))
| |
− | | |
− | self.menuBar.addmenuitem('Build Symmetry Partners', 'command', '3x3x3 Block',
| |
− | label = '3x3x3 Block',
| |
− | command = lambda s = self: symDialog(s, 3))
| |
− | | |
− | self.menuBar.addmenuitem('Build Symmetry Partners', 'command', 'By Partner',
| |
− | label = 'By Partner',
| |
− | command = lambda s = self: symDialog(s, 4))
| |
− | #COLOR SUBMENU
| |
− | self.menuBar.addcascademenu('SuperSym', 'Coloring')
| |
− | | |
− | self.menuBar.addmenuitem('Coloring', 'command', 'Default Rainbow',
| |
− | label = 'Default Rainbow',
| |
− | command = lambda s = self: colorDialog(s, 0))
| |
− | | |
− | self.menuBar.addmenuitem('Coloring', 'command', 'Select color for each operation',
| |
− | label = 'Select color for each operation',
| |
− | command = lambda s = self: colorDialog(s, 1))
| |
− | | |
− | self.menuBar.addmenuitem('Coloring', 'command', 'Select one color for custom set of operations',
| |
− | label = 'Select one color for custom set of operations',
| |
− | command = lambda s = self: colorDialog(s, 2))
| |
− | #GRAPHICS SUBMENU
| |
− | self.menuBar.addcascademenu('SuperSym', 'Graphics')
| |
− | | |
− | self.menuBar.addmenuitem('Graphics', 'command', 'Lines',
| |
− | label = 'Lines',
| |
− | command = lambda s = self: graphicsDialog(s, 0))
| |
− | | |
− | self.menuBar.addmenuitem('Graphics', 'command', 'Ribbon',
| |
− | label = 'Ribbon',
| |
− | command = lambda s = self: graphicsDialog(s, 1))
| |
− | | |
− | self.menuBar.addmenuitem('Graphics', 'command', 'Sphere Surface (best for printing)',
| |
− | label = 'Sphere Surface (best for printing)',
| |
− | command = lambda s = self: graphicsDialog(s, 2))
| |
− | | |
− | self.menuBar.addmenuitem('Graphics', 'command', 'Surface (high load render)',
| |
− | label = 'Surface (high load render)',
| |
− | command = lambda s = self: graphicsDialog(s, 3))
| |
− | #SYM AXES SUBMENU
| |
− | self.menuBar.addcascademenu('SuperSym', 'Symmetry Axes')
| |
− | | |
− | self.menuBar.addmenuitem('Symmetry Axes', 'command', 'Build Axes',
| |
− | label = 'Build Axes',
| |
− | command = lambda s = self: axesDialog(s))
| |
− | #ADD OTHER SYMMETRY AXES OPTION HERE
| |
− | self.menuBar.addmenuitem('SuperSym', 'command', 'Move symmetry partners',
| |
− | label = 'Move symmetry partners',
| |
− | command = lambda s = self: cellShiftInfo(s))
| |
− | self.menuBar.addmenuitem('SuperSym', 'command', 'About',
| |
− | label = 'About',
| |
− | command = lambda s = self: aboutInfo(s))
| |
− | self.menuBar.addmenuitem('SuperSym', 'command', 'Help',
| |
− | label = 'Help',
| |
− | command = lambda s = self: helpInfo(s))
| |
− | cmd.cell_shift = cell_shift
| |
− | cmd.get_operations = get_operations
| |
− | cmd.get_matrix = get_orthogonalization_matrix
| |
− | cmd.symset = symset
| |
− | cmd.sym_partner = sym_partner
| |
− | cmd.cell_shift_helper = cell_shift_helper
| |
− | cmd.set_key("ALT-6", cell_shift_proxyX1)
| |
− | cmd.set_key("ALT-4", cell_shift_proxyX2)
| |
− | cmd.set_key("ALT-8", cell_shift_proxyY1)
| |
− | cmd.set_key("ALT-2", cell_shift_proxyY2)
| |
− | cmd.set_key("ALT-5", cell_shift_proxyZ1)
| |
− | cmd.set_key("ALT-1", cell_shift_proxyZ2)
| |
− | </source>
| |
− | File: draw_cell.py
| |
− | <source lang="python">
| |
− | #original code written by Robert Campbell
| |
− | #modified by Stuart Ballard
| |
− | from cctbx import uctbx, sgtbx
| |
− | from pymol.cgo import *
| |
− | from pymol import cmd
| |
− | from pymol.vfont import plain
| |
− | | |
− | def set_to_zero(a):
| |
− | if abs(a) < 1e-10:
| |
− | a=0
| |
− | return a
| |
− | | |
− | def draw_cell(obj,radius=1.0,mode=0):
| |
− | """
| |
− | From pymol issue the "run draw_cell.py" command to load the script,
| |
− | then issue the "draw_cell(object,<optional radius>)" command
| |
− | to actually run it and create the cgo object showing the unit cell
| |
− | border for the space group specified by molecular object 'object'.
| |
− | | |
− | e.g. load 1avv.pdb
| |
− | run draw_cell.py
| |
− | draw_cell 1avv 0.5 (or draw_cell('1avv',.5))
| |
− | | |
− | see also help(draw_cell_param) to draw the cell border for
| |
− | user-defined cell dimensions (i.e. not loaded from a pdb file)
| |
− | | |
− | See also "help(draw_cell_param) to draw the cell border by
| |
− | specifying the unit cell parameters directly (i.e. not loaded from
| |
− | a pdb file).
| |
− | """
| |
− | radius=float(radius)
| |
− | cell_info=cmd.get_symmetry(obj)
| |
− | draw_cell_param(cell_info[0:6],radius,mode)
| |
− | | |
− | def draw_cell_param(cell_param_list,radius=1.0,mode=0):
| |
− | """
| |
− | If you wish to draw the unit cell border for any cell without the
| |
− | need to load a pdb file, then do this:
| |
− | | |
− | e.g. run draw_cell.py
| |
− | draw_cell_param((45.2,45.2,70.8,90.,90.,120.),0.5)
| |
− | | |
− | to generate the cell border for this trigonal space group "p 31 2 1"
| |
− | with a radius of 0.5A. Labels for the origin, and A, B and C axes
| |
− | will appear as well. The perimeter of the cell is colored with the
| |
− | RGB components corresponding to the A,B,C components.
| |
− | """
| |
− |
| |
− | U=uctbx.unit_cell((cell_param_list))
| |
− | | |
− | vert_000 = map(set_to_zero,U.orthogonalize((0.,0.,0)))
| |
− | vert_100 = map(set_to_zero,U.orthogonalize((1.,0.,0)))
| |
− | vert_010 = map(set_to_zero,U.orthogonalize((0.,1.,0)))
| |
− | vert_001 = map(set_to_zero,U.orthogonalize((0.,0.,1)))
| |
− | vert_110 = map(set_to_zero,U.orthogonalize((1.,1.,0)))
| |
− | vert_011 = map(set_to_zero,U.orthogonalize((0.,1.,1)))
| |
− | vert_101 = map(set_to_zero,U.orthogonalize((1.,0.,1)))
| |
− | vert_111 = map(set_to_zero,U.orthogonalize((1.,1.,1)))
| |
− | | |
− | # vert_000 = map(None,U.orthogonalize((0.,0.,0)))
| |
− | # vert_100 = map(None,U.orthogonalize((1.,0.,0)))
| |
− | # vert_010 = map(None,U.orthogonalize((0.,1.,0)))
| |
− | # vert_001 = map(None,U.orthogonalize((0.,0.,1)))
| |
− | # vert_110 = map(None,U.orthogonalize((1.,1.,0)))
| |
− | # vert_011 = map(None,U.orthogonalize((0.,1.,1)))
| |
− | # vert_101 = map(None,U.orthogonalize((1.,0.,1)))
| |
− | # vert_111 = map(None,U.orthogonalize((1.,1.,1)))
| |
− | | |
− | #print vert_000
| |
− | | |
− | #CYLINDER = ['CYLINDER']
| |
− | #radius = [0.2]
| |
− | #print radius
| |
− | cell = []
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_000 + vert_100 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_000 + vert_010 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_000 + vert_001 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_100 + vert_110 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_100 + vert_101 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_010 + vert_110 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_010 + vert_011 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_001 + vert_101 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_001 + vert_011 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_110 + vert_111 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_101 + vert_111 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(CYLINDER)
| |
− | cell = cell + vert_011 + vert_111 + [radius] + [1,1,1] + [1,1,1]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_000 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_001 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_010 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_011 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_100 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_101 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_110 + [radius]
| |
− | cell.append(SPHERE)
| |
− | cell = cell + vert_111 + [radius]
| |
− | | |
− | cmd.load_cgo(cell,"cell")
| |
− | #return cell
| |
− | | |
− | if mode == 1:
| |
− | text = [COLOR, 1.0, 0.0, 1.0,]
| |
− | | |
− | #wire_text(text,plain,[-5.,-5.,-1],'Origin',[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]])
| |
− | #wire_text(text,plain,map(None,U.orthogonalize((1.05,0.0,0.0))),'A',[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]])
| |
− | #wire_text(text,plain,map(None,U.orthogonalize((0.0,1.05,0.0))),'B',[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]])
| |
− | #wire_text(text,plain,map(None,U.orthogonalize((0.0,0.0,1.05))),'C',[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]])
| |
− | | |
− | cyl_text(text,plain,[-5.,-5.,-1],'Origin',0.20,axes=[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]],color=[1.0,0.0,1.0])
| |
− | cyl_text(text,plain,map(None,U.orthogonalize((1.05,0.0,0.0))),'A',0.20,axes=[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]],color=[1.0,0.0,0.0])
| |
− | cyl_text(text,plain,map(None,U.orthogonalize((0.0,1.05,0.0))),'B',0.20,axes=[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]],color=[0.0,1.0,0.0])
| |
− | cyl_text(text,plain,map(None,U.orthogonalize((0.0,0.0,1.05))),'C',0.20,axes=[[3.0,0.0,0.0],[0.0,3.0,0.0],[0.0,0.0,3.0]],color=[0.0,0.0,1.0])
| |
− | | |
− | cmd.load_cgo(text,'text')
| |
− | | |
− | cmd.extend("draw_cell",draw_cell)
| |
− | </source>
| |
− | File: draw_symops_cctbx.py
| |
− | <source lang="python">
| |
− | #! /usr/bin/env python
| |
− | # Copyright (c) 2004 Robert L. Campbell
| |
− | | |
− | from cctbx import uctbx, sgtbx
| |
− | #import string, math
| |
− | from pymol.cgo import *
| |
− | from pymol import cmd
| |
− | | |
− | from all_axes_new import get_all_axes
| |
− | | |
− | import numpy as N
| |
− | #import numarray as N
| |
− | | |
− | print "Finished importing for draw_symops_cctbx.py"
| |
− | | |
− | def set_to_zero(a):
| |
− | if abs(a) < 1e-10:
| |
− | a=0
| |
− | return a
| |
− | | |
− | def draw_symbol(start,end,symb,color,radius=0.2):
| |
− | degtorad = N.pi/180.
| |
− | costhirty = N.cos(30.0*degtorad)
| |
− | sinthirty = N.sin(30.0*degtorad)
| |
− | symb_obj = []
| |
− | | |
− | if symb == '2' or symb == '2^1':
| |
− | pass
| |
− | | |
− | elif symb == '3' or symb == '3^1' or symb == '3^2':
| |
− | symb_obj = [ BEGIN, TRIANGLES, COLOR ] + color
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([radius, 0, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([-radius*sinthirty, radius*costhirty, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([-radius*sinthirty, -radius*costhirty, 0]))[0].tolist()
| |
− | | |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([radius, 0, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([-radius*sinthirty, radius*costhirty, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([-radius*sinthirty, -radius*costhirty, 0]))[0].tolist()
| |
− | symb_obj.append(END)
| |
− | | |
− | elif symb == '4' or symb == '4^1' or symb == '4^2' or symb == '4^3':
| |
− | symb_obj = [ BEGIN, TRIANGLES, COLOR ] + color
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([radius, radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([-radius, radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([-radius, -radius, 0]))[0].tolist()
| |
− | | |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([radius, radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([radius, -radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([start]) + N.array([-radius, -radius, 0]))[0].tolist()
| |
− | | |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([radius, radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([-radius, radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([-radius, -radius, 0]))[0].tolist()
| |
− | | |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([radius, radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([radius, -radius, 0]))[0].tolist()
| |
− | symb_obj.append(VERTEX)
| |
− | symb_obj = symb_obj + (N.array([end]) + N.array([-radius, -radius, 0]))[0].tolist()
| |
− | symb_obj.append(END)
| |
− | | |
− | elif symb == '6' or symb == '6^1' or symb == '6^2' or symb == '6^3' or symb == '6^4' or symb == '6^5':
| |
− | # hexagons still need to be created :)
| |
− | pass
| |
− | | |
− | return symb_obj
| |
− | | |
− | def draw_symops(obj,radius=0.2,extension=0):
| |
− | """
| |
− | From pymol issue the "run draw_symops_cctbx.py" command to load the script,
| |
− | then issue the "draw_symops(object,<optional radius>,<optional extension>)" command
| |
− | to actually run it and create the cgo object.
| |
− | | |
− | e.g. load 1avv.pdb
| |
− | run draw_symops_cctbx.py
| |
− | draw_symops 1avv, 0.5, .2
| |
− | or draw_symops('1avv',.5,.2)
| |
− | or draw_symops 1avv, radius=.5, extension=.2
| |
− | | |
− | The different axis types appear as different objects on the PyMOL menu so they can be turned
| |
− | on and off individually.
| |
− | | |
− | See also help(draw_symops_param) to draw operators by specifying the space group
| |
− | and cell dimensions directly (i.e. not loaded from a pdb file)
| |
− | | |
− | The 'extension' parameter is a fractional increase in the length of each symmetry
| |
− | operator axis drawn. i.e. a value of 0 is the default and a value of .2 increases
| |
− | the length by 20% at each end
| |
− | """
| |
− | radius=float(radius)
| |
− | extension=float(extension)
| |
− | cell_info=cmd.get_symmetry(obj)
| |
− | draw_symops_param(cell_info[0:6],cell_info[6],radius,extension)
| |
− | | |
− | def draw_symops_param(cell_param_list,sg,radius=0.2,extension=0):
| |
− | """
| |
− | If you wish to draw the symmetry operators for any cell without the need to load a
| |
− | pdb file, then do this:
| |
− | | |
− | e.g. run draw_symops_cctbx.py
| |
− | draw_symops_param((45.2,45.2,70.8,90.,90.,120.),'p3121',0.5,0.1)
| |
− |
| |
− | to generate the symmetry operators for this trigonal space group "p 31 2 1"
| |
− | of radius .5 with 10% added as an extension at each end.
| |
− | """
| |
− | radius=float(radius)
| |
− | extension=float(extension)
| |
− | | |
− | U=uctbx.unit_cell((cell_param_list))
| |
− | | |
− | #rotation axes
| |
− | # "2" "yellow",
| |
− | # "3" "orange",
| |
− | # "4" "mauve",
| |
− | # "6" "purple",
| |
− | | |
− | #screw axes (all sub_1 axes are green)
| |
− | # "21" "green",
| |
− | # "31" "green",
| |
− | # "32" "lime",
| |
− | # "41" "green",
| |
− | # "42" "cyan",
| |
− | # "43" "iceblue",
| |
− | # "61" "green",
| |
− | # "62" "silver",
| |
− | # "63" "cyan",
| |
− | # "64" "iceblue",
| |
− | # "65" "blue",
| |
− | | |
− | color = {
| |
− | "2" : [1.0, 1.0, 0.0],
| |
− | "3" : [1.0, 0.5, 0.0],
| |
− | "4" : [1.0, 0.5, 1.0],
| |
− | "6" : [1.0, 0.0, 1.0],
| |
− | "2^1" : [0.0, 1.0, 0.0],
| |
− | "3^1" : [0.0, 1.0, 0.0],
| |
− | "3^2" : [0.5, 1.0, 0.5],
| |
− | "4^1" : [0.0, 1.0, 0.0],
| |
− | "4^2" : [0.0, 1.0, 1.0],
| |
− | "4^3" : [0.5, 0.5, 1.0],
| |
− | "6^1" : [0.0, 1.0, 0.0],
| |
− | "6^2" : [0.8, 0.8, 0.8],
| |
− | "6^3" : [0.0, 1.0, 1.0],
| |
− | "6^4" : [0.5, 0.5, 1.0],
| |
− | "6^5" : [0.0, 0.0, 1.0],
| |
− | }
| |
− | | |
− | sg = sg.upper()
| |
− | symop_axes = get_all_axes(sg,extension=extension)
| |
− | | |
− | #CYLINDER = 'CYLINDER'
| |
− | ax_obj = {}
| |
− | #vert_obj = []
| |
| | | |
− | #debug_out = open('debug.log','w')
| + | ==Installing SuperSym== |
| | | |
− | if symop_axes:
| + | To install SuperSym v1.2, download SuperSymPlugin12.py from [https://sourceforge.net/projects/supersym/ https://sourceforge.net/projects/supersym/]. In PyMOL, go to: |
− | for i in range(len(symop_axes)):
| + | *Plugin > Manage Plugins > Install... |
− | #print symop_axes[i]
| + | A file selector dialog will appear. Select SuperSymPlugin12.py. PyMOL will direct you to restart, and upon doing so SuperSym will be accessible through the Plugin menu. |
− | start = map(set_to_zero,U.orthogonalize(map(None,symop_axes[i]['start'])))
| |
− | end = map(set_to_zero,U.orthogonalize(map(None,symop_axes[i]['end'])))
| |
− | ###############################################################################
| |
− | # Tried rounding off start and end values in order to understand why axes go
| |
− | # missing in the drawing, but seem to be present in the cgo. Doesn't help!
| |
− | # e.g. for space group 'p23' one of the 3-fold rotations is missing (0,0,0 -> x,-x,x)
| |
− | # changing one cell axis to something ever so slightly different recovers the axis
| |
− | # e.g. set cell to be (30.00001,30.,30.,90.,90.,90) and it works!
| |
− | # start = map(lambda x: round(x,3),U.orthogonalize(symop_axes[i]['start']))
| |
− | # end = map(lambda x: round(x,3),U.orthogonalize(symop_axes[i]['end']))
| |
− | ###############################################################################
| |
− | color_ax = color[symop_axes[i]['symb']]
| |
− | symb_ax = symop_axes[i]['symb']
| |
| | | |
− | #print "axis: ",symb_ax, start, end
| + | To use functions of SuperSym directly, without creating a drop-down menu, use the run command in PyMOL on SuperSymPlugin12.py. |
− | if ax_obj.has_key(symb_ax):
| |
− | ax_obj[symb_ax].append(CYLINDER)
| |
− | else:
| |
− | ax_obj[symb_ax] = [CYLINDER]
| |
| | | |
− | ax_obj[symb_ax] = ax_obj[symb_ax] + start + end + [radius]
| + | Note: previous errors resulting from incorrect naming of the plugin file have been resolved in v1.2. |
− | ax_obj[symb_ax] = ax_obj[symb_ax] + color[symb_ax] + color[symb_ax]
| |
− | ax_obj[symb_ax] = ax_obj[symb_ax] + draw_symbol(start,end,symb_ax,color[symb_ax],radius*6.)
| |
| | | |
− | # #######################################################################################
| + | ==Feedback== |
− | # # Debugging output to try to understand why some axes go missing in the drawing.
| |
− | # # They don't appear to be missing from the cgo object, though!
| |
− | # for xxx in ax_obj[symb_ax]:
| |
− | # if xxx == 9.0:
| |
− | # #print "\n\n",xxx
| |
− | # xxx = "\n\n" + str(xxx) + " "
| |
− | # debug_out.write(xxx)
| |
− | # else:
| |
− | # #print xxx
| |
− | # #xxx = "\n" + str(xxx) + " "
| |
− | # xxx = str(xxx) + " "
| |
− | # debug_out.write(xxx)
| |
− | # #print ax_obj[symb_ax]
| |
− | # debug_out.write("\n\n")
| |
− | # big_string = str(ax_obj)
| |
− | # debug_out.write(big_string)
| |
− | # # End of debugging output
| |
− | # #######################################################################################
| |
| | | |
− | else:
| + | Please post any comments, complaints, bug fix requests, useful tricks, or cool adaptations of SuperSym here. |
− | print "\nNo symmetry axes found for this space group: %s\n" % sg
| |
| | | |
− | for key in ax_obj.keys():
| + | ==The Menu== |
− | name=sg + "_" + key
| + | *'''Default Symmetry Partner Set''' |
− | cmd.load_cgo(ax_obj[key],name)
| + | ** See '''Build Symmetry Partners > Cell [0,0,0] (default)''' |
− | #debug_out.write("\n\n" + key + "\n" + str(ax_obj[key]))
| + | *'''Draw Unit Cell''' |
− | #return ax_obj
| + | **Creates a cgo object with unit cell axes as cylinders. This functions similarly to ''show cell'', but the cell axes are cylinders instead of lines, allowing for printing. |
| + | *'''Build Symmetry Partners >''' |
| + | **All options in this submenu generate sets of symmetry partners |
| + | **'''Cell [0,0,0] (default)''' |
| + | ***Generates a suite of symmetry partners for a given object for the default unit cell, which is lattice position [0,0,0] |
| + | **'''Cell [x,y,z] (custom)''' |
| + | ***Generates a suite of symmetry partners for a given object for a lattice position which you specify |
| + | **'''2x2x2 Block''' |
| + | ***Generates 8 sets of symmetry partners for a given object, filling lattice positions [0,0,0] through [1,1,1] |
| + | **'''3x3x3 Block''' |
| + | ***Generates 27 sets of symmetry partners for a given object, filling lattice positions [-1,-1,-1] through [1,1,1]. This option may take a long time to execute |
| + | **'''By Partner''' |
| + | ***Generates only those symmetry partners which the user specifies by their defining symmetry operators |
| + | *'''Coloring >''' |
| + | **'''Default Rainbow''' |
| + | ***Colors all symmetry objects with a specified by their symmetry operations automatically |
| + | **'''Select color for each operation''' |
| + | ***Select symmetry partners to color by their defining symmetry operation and select the color for each |
| + | **'''Select one color for custom set of operations''' |
| + | ***Select a set of symmetry partners defined by symmetry operations and select one color for all of them |
| + | *'''Graphics >''' |
| + | **'''Lines''' |
| + | ***Convenience function to display symmetry partners as lines |
| + | **'''Ribbon''' |
| + | **Convenience function to display symmetry partners as ribbons |
| + | **'''Cartoon''' |
| + | ***Convenience function to display symmetry partners as cartoons |
| + | **'''Sphere Surface (best for printing)''' |
| + | ***Uses the findSurfaceResidues function and shows surface residues as spheres. If printing, this option saves at least 60% of materials relative to regular surfaces, with minimal loss in resolution |
| + | **'''Surface (high load render)''' |
| + | ***Displays symmetry partners as surfaces. This option may take a very long time to execute |
| + | *'''Symmetry Axes >''' |
| + | **'''Build Axes''' |
| + | ***Builds all symmetry axes for the given object. This functionality will be customizable and extended in future versions |
| + | *'''Move symmetry partners''' |
| + | **Merely displays instructions for using built in hotkeys to move symmetry partners |
| + | *'''About''' |
| + | **Developer info |
| + | *'''Help''' |
| + | **Reference to this page |
| | | |
− | cmd.extend("draw_symops",draw_symops)
| + | [[Category:Plugins]] |
− | #cmd.extend("draw_symops_param",draw_symops_param)
| + | [[Category:Script_Library]] |
− | </source>
| + | [[Category:Math_Scripts]] |