Rotamer Toggle: Difference between revisions

From PyMOLWiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
===DESCRIPTION===
===DESCRIPTION===
Backbone-Dependent Rotamer library (Dunbrack, Cohen see ref) is imported into pymol giving access to this information.  There are a number of different ways to use the data, I've only implemented a few as well as added extra functions that seemed useful.
Backbone-Dependent Rotamer library (Dunbrack, Cohen ; see ref) is imported into pymol giving access to this information.  There are a number of different ways to use the data, I've only implemented a few as well as added extra functions that seemed useful.
*colorRotamers - color rotamers by closest matching rotamer angles from database; i.e. color by how common each rotamer of selection, blue - red (least to most common).
*colorRotamers - color rotamers by closest matching rotamer angles from database; i.e. color by how common each rotamer of selection, blue - red (least to most common).
*Rotamer Menu - an added menu into menu.py, which displays the most common rotamers for the given(clicked) residue; you can also set the residue any of the common rotamers as well
*Rotamer Menu - an added menu into menu.py, which displays the most common rotamers for the given(clicked) residue; you can also set the residue any of the common rotamers as well
Line 6: Line 6:
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)  
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)  


To setup a rotamer menu inside the residue menu:
To setup a rotamer menu inside the residue menu (default windows pymol installation):
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py
*copy mymenu.py  to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)
*copy mymenu.py  to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)
This is only one possible way to do this, I am sure there are many others.
This is only one possible way to do this, I am sure there are many others. I'm not going to post the bbdep, but there is a link in the References section to Dunbrack's download page (get the "sorted" lib)
 
Of course you can simply import rotamers.py and use the functions manually.
 
This should not have any OS specific stuff in it yet, but has only been tested on Windows. I'll test it on linux in the next few days.


===USAGE===
===USAGE===
Line 16: Line 20:
  set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]
  set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]
  set_phipsi selection phi_angle, psi_angle
  set_phipsi selection phi_angle, psi_angle
===EXAMPLES===
  colorRotamers chain A
  set_rotamer resi 40, -60,-40  (only set chi1,chi2 angles)
  set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)
 
===REFERENCES===
Dunbrack and Cohen. Protein Science 1997
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]


===Scripts (Rotamers.py ; MyMenu.py)===
===Scripts (Rotamers.py ; MyMenu.py)===
Rotamers.py
  <source lang="python">
  <source lang="python">
  ##################################################################
# File:          Rotamers.py
# Author:        Dan Kulp
# Creation Date: 6/8/05
#
# Notes:
#    Incorporation of Rotamer library
#    readRotLib() - fills rotdat;
#        indexed by "RES:PHI_BIN:PSI_BIN".
#
#    Three main functions:
#    1. colorRotamers - colors according
#          to rotamer probablitity
#    2. getBins(sel)
#          phi,psi bin for rotamer
#    3. set_rotamer - set a side-chain
#          to a specific rotamer
#
#    To setup a rotamer menu in the
#  right click, under "Residue"
#        1. cp mymenu.py modules/pymol/menu.py
#        2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)
#
# Requirements:
#  set ROTLIB to path for rotamer library
# Reference:
#  Dunbrack and Cohen. Protein Science 1997
####################################################################
import colorsys,sys
import string
import re
import editing
import os
import cmd
import math
# Path for library
ROTLIB=os.environ['PYMOL_PATH']+"/modules/pymol/bbdep02.May.sortlib"
# Place for library in memory..
rotdat = {}
def readRotLib():
    # Column indexes in rotamer library..
    RES  = 0
    PHI  = 1
    PSI  = 2
    PROB = 8
    CHI1 = 9
    CHI2 = 10
    CHI3 = 11
    CHI4 = 12
    if os.path.exists(ROTLIB):
print "File exists: "+ROTLIB
input = open(ROTLIB, 'r')
for line in input:
      # Parse by whitespace (I believe format is white space and not fixed-width columns)
    dat = re.split("\s+",line)
    # Add to rotamer library in memory :
    #  key format      RES:PHI_BIN:PSI_BIN
    #  value format    PROB, CHI1, CHI2, CHI3, CHI4
    try:
        rotdat[dat[RES]+":"+dat[PHI]+":"+dat[PSI]].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])
    except KeyError:
rotdat[dat[RES]+":"+dat[PHI]+":"+dat[PSI]] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]
   
    else:
print "Couldn't find Rotamer library"
# Atoms for each side-chain angle for each residue
CHIS = {}
CHIS["ARG"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD" ],
["CB","CG","CD","NE" ],
["CG","CD","NE","CZ" ]
      ]
CHIS["ASN"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","OD2" ]
      ]
CHIS["ASP"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","OD1" ]
      ]
CHIS["CYS"] = [ ["N","CA","CB","CG" ]
      ]
CHIS["GLN"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD" ],
["CB","CG","CD","OE1"]
      ]
CHIS["GLU"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD" ],
["CB","CG","CD","OE1"]
      ]
CHIS["HIS"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","ND1"]
      ]
CHIS["ILE"] = [ ["N","CA","CB","CG1" ],
["CA","CB","CG1","CD1" ]
      ]
CHIS["LEU"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD1" ]
      ]
CHIS["LYS"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD" ],
["CB","CG","CD","CE"],
["CG","CD","CE","NZ"]
      ]
CHIS["MET"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","SD" ],
["CB","CG","SD","CE"]
      ]
CHIS["PHE"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD1" ]
      ]
CHIS["PRO"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD" ]
      ]
CHIS["SER"] = [ ["N","CA","CB","OG" ]
      ]
CHIS["THR"] = [ ["N","CA","CB","OG1" ]
      ]
CHIS["TYR"] = [ ["N","CA","CB","CG" ],
["CA","CB","CG","CD1" ]
      ]
CHIS["VAL"] = [ ["N","CA","CB","CG1" ]
      ]
# Color Rotamer by side-chain angle position
#  'bin' side-chain angles into closest
def colorRotamers(sel):
    doRotamers(sel)
# Utility function, to set phi,psi angles for a given selection
# Note: Cartoon, Ribbon functionality will not display correctly after this
def set_phipsi(sel, phi,psi):
    doRotamers(sel,angles=[phi,psi],type="set")
# Set a rotamer, based on a selection, a restype and chi angles
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):
    at = cmd.get_model("byres ("+sel+")").atom[0]
    list = [chi1,chi2,chi3,chi4]
    for i in range(0,len(CHIS[at.resn])):
print "Setting Chi"+str(i+1)+" to "+str(list[i])
        editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],    
            sel + ' and name '+CHIS[at.resn][i][1],    
            sel + ' and name '+CHIS[at.resn][i][2],    
            sel + ' and name '+CHIS[at.resn][i][3], list[i])    
    # Remove some objects that got created
    cmd.delete("pk1")
    cmd.delete("pk2")
    cmd.delete("pkmol")
# Get Phi,Psi bins for given selection
# WARNING:  assume selection is single residue (will only return first residue bins)
def getBins(sel):
    return doRotamers(sel, type="bins")
# Specific comparison operator for rotamer prob data
def mycmp(first, second):
return cmp( first[1], second[1])
# Color Ramp...
def rot_color(vals):
nbins = 10
vals.sort(mycmp)
print "End sort: "+str(len(vals))+" : "+str(nbins)
# Coloring scheme...
i = 0
j = 0
rgb = [0.0,0.0,0.0]
sel_str = ""
while i < len(vals):
if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:
      hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)
      #convert to rgb and append to color list
      rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])
      if j < nbins-1:
              j += 1
cmd.set_color("RotProbColor"+str(i), rgb)
cmd.color("RotProbColor"+str(i), str(vals[i][0]))
i += 1
# Main function                         
def doRotamers(sel,angles=[], type="color"):                         
# Read in Rotamer library if not already done
if len(rotdat) == 0:
readRotLib()
# Set up some variables..
residues = ['dummy']  # Keep track of residues already done
probs = []            # probability of each residue conformation
phi = 0              # phi,psi angles of current residue
psi = 0
# Get atoms from selection
atoms = cmd.get_model("byres ("+sel+")")
        # Loop through atoms in selection
for at in atoms.atom:
    try:
      # Don't process Glycines or Alanines
      if not (at.resn == 'GLY' or at.resn == 'ALA'):
        if not at.chain+":"+at.resn+":"+at.resi in residues:
            residues.append(at.chain+":"+at.resn+":"+at.resi)
    # Check for a null chain id (some PDBs contain this)
    unit_select = ""
    if not at.chain == "":
unit_select = "chain "+str(at.chain)+" and "
    # Define selections for residue i-1, i and i+1   
    residue_def = unit_select+'resi '+str(at.resi)
      residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)
    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)
            # Compute phi/psi angle
    phi = cmd.get_dihedral(residue_def+' and name CB',residue_def+' and name CA',residue_def+' and name N',residue_def_prev+' and name C')
    psi = cmd.get_dihedral(residue_def+' and name O',residue_def+' and name C',residue_def+' and name CA',residue_def+' and name CB')
    if type == "set":
    print "Changing "+at.resn+str(at.resi)+" from "+str(phi)+","+str(psi)+" to "+str(angles[0])+","+str(angles[1])
    cmd.set_dihedral(residue_def+' and name CB',residue_def+' and name CA',residue_def+' and name N',residue_def_prev+' and name C',angles[0])
    cmd.set_dihedral(residue_def+' and name O',residue_def+' and name C',residue_def+' and name CA',residue_def+' and name CB', angles[1])
    continue
    # Find correct 10x10 degree bin        
    phi_digit = abs(int(phi)) - abs(int(phi/10)*10)
    psi_digit = abs(int(psi)) - abs(int(psi/10)*10)
   
    # Remember sign of phi,psi angles
        phi_sign = 1
    if phi < 0:    phi_sign = -1
    psi_sign = 1
    if psi < 0:    psi_sign = -1
    # Compute phi,psi bins
      phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)
    if phi_digit >= 5:    phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)
    psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)
    if psi_digit >= 5:    psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)
            print "Given "+at.resn+":"+at.resi+" PHI,PSI ("+str(phi)+","+str(psi)+") : bin ("+str(phi_bin)+","+str(psi_bin)+")"
    # Get current chi angle measurements
    chi = []
    for i in range(0,len(CHIS[at.resn])):
      chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],    
              residue_def + ' and name '+CHIS[at.resn][i][1],    
            residue_def + ' and name '+CHIS[at.resn][i][2],    
            residue_def + ' and name '+CHIS[at.resn][i][3]))    
    print "CHIs: "+str(chi)
    if type == 'bins':
        return [at.resn, phi_bin,psi_bin]
    # Compute probabilities for given chi angles
                    prob = 0
    prob_box = 22    
    for item in range(0,len(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)])):
print "Rotamer from db: "+str(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item])
if chi[0]:
    if chi[0] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) - (prob_box/2) and \
chi[0] <= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) + (prob_box/2):
if len(chi) == 1:
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
break
if chi[1] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) - (prob_box/2) and \
float(chi[1] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) + (prob_box/2):
if len(chi) == 2:
    prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
    break
if chi[2] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) - (prob_box/2) and \
  float(chi[2] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) + (prob_box/2):
        if len(chi) == 3:
        prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
        break
    if chi[3] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) - (prob_box/2) and \
      float(chi[3] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) + (prob_box/2):
        prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
        break
    print "PROB OF ROTAMER: "+str(prob)
    print "---------------------------"
    probs.append([residue_def, prob])
    except:
# probs.append([residue_def, -1])
print "Exception found"
continue
# Color according to rotamer probability
rot_color(probs)    
readRotLib()
cmd.extend('set_phipsi',set_phipsi)
cmd.extend('set_rotamer',set_rotamer)
cmd.extend('colorRotamers',colorRotamers)
</source>
MyMenu.py
<source lang="python">
#A* -------------------------------------------------------------------
#B* This file contains source code for the PyMOL computer program
#C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
#D* -------------------------------------------------------------------
#E* It is unlawful to modify or remove this copyright notice.
#F* -------------------------------------------------------------------
#G* Please see the accompanying LICENSE file for further information.
#H* -------------------------------------------------------------------
#I* Additional authors of this source file include:
#-* Dan Kulp (dwkulp@mail.med.upenn.edu) ; rotamer menu
#-*
#-*
#Z* -------------------------------------------------------------------
# pmm.py
# This section contains the menu contents and the associated commands
#
import cmd
import os
def mol_show(s):
  return [[ 2, 'Show:'      , ''                              ],
          [ 1, 'lines'      , 'cmd.show("lines"    ,"'+s+'")' ],
          [ 1, 'nonbonded'  , 'cmd.show("nonbonded" ,"'+s+'")' ],
          [ 1, 'sticks'    , 'cmd.show("sticks"    ,"'+s+'")' ],
          [ 1, 'ribbon'    , 'cmd.show("ribbon"    ,"'+s+'")' ],
          [ 1, 'cartoon'    , 'cmd.show("cartoon"  ,"'+s+'")' ],
          [ 0, ''          , ''                              ],
          [ 1, 'labels'    , 'cmd.show("labels"    ,"'+s+'")' ],
          [ 1, 'cell'      , 'cmd.show("cell"      ,"'+s+'")' ],
          [ 0, ''          , ''                              ],
          [ 1, 'dots'      , 'cmd.show("dots"      ,"'+s+'")' ],
          [ 1, 'spheres'    , 'cmd.show("spheres"  ,"'+s+'")' ],
          [ 1, 'nb_spheres' , 'cmd.show("nb_spheres","'+s+'")' ],
          [ 0, ''          , ''                              ],
          [ 1, 'mesh'      , 'cmd.show("mesh"      ,"'+s+'")' ],
          [ 1, 'surface'    , 'cmd.show("surface"  ,"'+s+'")' ],
          [ 0, ''          , ''                              ],         
          [ 1, 'main chain' , 'cmd.show("lines","((byres ('+s+'))&n;ca,c,n,o,h)")' ],
          [ 1, 'side chain' , 'cmd.show("lines","((byres ('+s+'))&(!n;c,n,o,h))")' ],
          ]
def mol_hide(s):
  return [[ 2, 'Hide:'    , ''                                ],
          [ 1, 'everything', 'cmd.hide("everything","'+s+'")'  ],
          [ 0, ''          , ''                                ],
          [ 1, 'lines'    , 'cmd.hide("lines"    ,"'+s+'")'  ],
          [ 1, 'nonbonded' , 'cmd.hide("nonbonded" ,"'+s+'")'  ],         
          [ 1, 'sticks'    , 'cmd.hide("sticks"    ,"'+s+'")'  ],
          [ 1, 'ribbon'    , 'cmd.hide("ribbon"    ,"'+s+'")'  ],
          [ 1, 'cartoon'  , 'cmd.hide("cartoon"  ,"'+s+'")' ],         
          [ 0, ''          , ''                                ],
          [ 1, 'labels'    , 'cmd.hide("labels"    ,"'+s+'")'  ],
          [ 1, 'cell'      , 'cmd.hide("cell"      ,"'+s+'")' ],
          [ 0, ''          , ''                                ],
          [ 1, 'dots'      , 'cmd.hide("dots"      ,"'+s+'")'  ],
          [ 1, 'spheres'  , 'cmd.hide("spheres"  ,"'+s+'")'  ],
          [ 1, 'nb_spheres', 'cmd.hide("nb_spheres","'+s+'")'  ],         
          [ 0, ''          , ''                                ],
          [ 1, 'mesh'      , 'cmd.hide("mesh"      ,"'+s+'")'  ],
          [ 1, 'surface'  , 'cmd.hide("surface"  ,"'+s+'")'  ],
          [ 0, ''          , ''                                ],
          [ 1, 'main chain', 'cmd.hide("((byres ('+s+'))&n;c,n,o,h)")' ],
          [ 1, 'side chain', 'cmd.hide("((byres ('+s+'))&!n;ca,c,n,o,h)")' ],
          [ 1, 'waters'    , 'cmd.hide("(resn HOH+WAT and ('+s+'))")'    ],                     
          [ 0, ''          , ''                                ],
          [ 1, 'hydrogens' , 'cmd.hide("('+s+' and hydro)")'  ],
          [ 0, ''          , ''                                ],         
          [ 1, 'unselected', 'cmd.hide("(not '+s+')")'        ],
          ]
def dist_show(s):
  return [[ 2, 'Show:'    , ''                              ],
          [ 1, 'dashes'    , 'cmd.show("dashes"    ,"'+s+'")' ],
          [ 1, 'labels'    , 'cmd.show("labels"    ,"'+s+'")' ]
          ] 
def dist_hide(s):
  return [[ 2, 'Hide:'    , ''                                ],
          [ 1, 'dashes'    , 'cmd.hide("dashes"    ,"'+s+'")'  ],
          [ 1, 'labels'    , 'cmd.hide("labels"    ,"'+s+'")'  ]
          ]
def cgo_show(s):
  return [[ 2, 'Show:'    , ''                              ],
          [ 1, 'cgo'    , 'cmd.show("cgo"    ,"'+s+'")' ],
          ] 
def cgo_hide(s):
  return [[ 2, 'Hide:'    , ''                                ],
          [ 1, 'cgo'    , 'cmd.hide("cgo"    ,"'+s+'")'  ],
          ]
def simple_show(s):
  return [[ 2, 'Show:'      , ''                            ],
          [ 1, 'everything'  , 'cmd.show("everything","'+s+'")'          ]]
def simple_hide(s):
  return [[ 2, 'Hide:'    ,''                                ],
          [ 1, 'everything'    ,'cmd.hide("everything","'+s+'")'        ]]
def mesh_show(s):
  return [[ 2, 'Show:'      , ''                            ],
          [ 1, 'mesh'        , 'cmd.show("mesh","'+s+'")'    ],         
          [ 1, 'cell'        , 'cmd.show("cell","'+s+'")'    ],
          [ 1, 'everything'  , 'cmd.enable("'+s+'")'          ]]
def mesh_hide(s):
  return [[ 2, 'Hide:'      , ''                            ],
          [ 1, 'mesh'        , 'cmd.hide("mesh","'+s+'")'    ],                     
          [ 1, 'cell'        , 'cmd.hide("cell","'+s+'")'      ],         
          [ 1, 'everything'  , 'cmd.disable("'+s+'")'          ]]
def by_elem(s):
  return [
      [ 2, 'By Element:'    ,''                              ],
      [ 1, '\\292C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbag("'+s+'")'],
  [ 1, '\\099C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbac("'+s+'")'],
  [ 1, '\\909C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbam("'+s+'")'],         
  [ 1, '\\990C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbay("'+s+'")'],
  [ 1, '\\955C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbas("'+s+'")'],
  [ 1, '\\777C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbaw("'+s+'")'],
  [ 1, '\\559C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbab("'+s+'")'],
  [ 1, '\\972C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbao("'+s+'")'],
  [ 1, ' \\777H\\229N\\922O\\950S\\905*'  , 'util.cnc("'+s+'")']]                   
def by_ss(s):
  return [
            [ 2, 'By Secondary Structure:'    ,''                              ],
  [ 1, '\\900Helix \\990Sheet \\090Loop'  , 'util.cbss("'+s+'","red","yellow","green")'],
  [ 1, '\\099Helix \\909Sheet \\955Loop'  , 'util.cbss("'+s+'","cyan","magenta","salmon")'],
          ]
def spectrum(s):
  return [
            [ 2, 'Spectrum:'    ,''                              ],
          [ 1, '\\900r\\950a\\990i\\090n\\099b\\059o\\009w\\888(e. c)',
            'cmd.spectrum("count",selection="('+s+')&e. c")'],         
          [ 1, '\\900r\\950a\\990i\\090n\\099b\\059o\\009w\\888(*/ca)',
            'cmd.spectrum("count",selection="('+s+')&*/ca")'],
          [ 1, '\\900r\\950a\\990i\\090n\\099b\\059o\\009w',
            'cmd.spectrum("count",selection="'+s+'",byres=1)'],
          [ 0, ''                                , ''                ],
          [ 1, 'b-factors'  , 'cmd.spectrum("b",selection=("'+s+'"))'        ],         
          ]
def by_chain(s):
  return [
      [ 2, 'By Chain:'    ,''                              ],
          [ 1, '\\900b\\950y \\090c\\099h\\059a\\009i\\705n\\888(e. c)',
            'util.color_chains("('+s+' and elem c)")'],
          [ 1, '\\900b\\950y \\090c\\099h\\059a\\009i\\705n\\888(*/ca)',
            'util.color_chains("('+s+' and name ca)")'],
          [ 1, '\\900b\\950y \\090c\\099h\\059a\\009i\\705n',
            'util.color_chains("('+s+')")'],
                [ 0, ''                                , ''                ],
          [ 1, '\\900c\\950h\\990a\\090i\\099n\\059b\\009o\\705w\\888s',
            'util.chainbow("('+s+')")'],                               
      ]
def mol_color(s):
  return [[ 2, 'Color:'    ,''                              ],
          [ 1, 'by chain' , by_chain(s) ],
          [ 1, 'by element'  , by_elem(s) ],
          [ 1, 'by ss  '  , by_ss(s) ],
          [ 1, '\\900s\\950p\\990e\\090c\\099t\\059r\\009u\\555m', spectrum(s) ],
          [ 0, ''                                , ''                ],         
          [ 1, '\\900red'        , 'cmd.color("red","'+s+'")'    ],
          [ 1, '\\090green'      , 'cmd.color("green","'+s+'")'  ],
          [ 1, '\\009blue'        , 'cmd.color("blue","'+s+'")'    ],
          [ 1, '\\990yellow'      , 'cmd.color("yellow","'+s+'")'  ],
          [ 1, '\\909magenta'    , 'cmd.color("magenta","'+s+'")' ],
          [ 1, '\\099cyan'        , 'cmd.color("cyan","'+s+'")'    ],         
          [ 1, '\\955salmon'      , 'cmd.color("salmon","'+s+'")'  ],
          [ 1, '\\595lime'        , 'cmd.color("lime","'+s+'")'    ],
          [ 1, '\\967pink'  ,'cmd.color("pink","'+s+'")'  ],
          [ 1, '\\559slate'      , 'cmd.color("slate","'+s+'")'  ],
          [ 1, '\\949violet'      , 'cmd.color("violet","'+s+'")'  ],
          [ 1, '\\950orange'      , 'cmd.color("orange","'+s+'")'  ],
          [ 1, '\\059marine'      , 'cmd.color("marine","'+s+'")'  ],
          [ 1, '\\905hotpink' ,'cmd.color("hotpink","'+s+'")'  ],
#          [ 1, '\\551olive'      , 'cmd.color("olive","'+s+'")'  ],
#          [ 1, '\\626purple'      , 'cmd.color("purple","'+s+'")'  ],
#          [ 1, '\\266teal'        , 'cmd.color("teal","'+s+'")'    ],
#          [ 1, '\\151forest'      , 'cmd.color("forest","'+s+'")'  ],
#          [ 1, '\\611firebrick'  , 'cmd.color("firebrick","'+s+'")'  ],
#          [ 1, '\\631chocolate'  , 'cmd.color("chocolate","'+s+'")'  ],         
          [ 1, '\\999white'      , 'cmd.color("white","'+s+'")'  ],
          [ 1, '\\987wheat'      , 'cmd.color("wheat","'+s+'")'  ],
          [ 1, '\\555grey'        , 'cmd.color("grey","'+s+'")'    ],
          [ 1, '\\222black'    ,'cmd.color("grey","'+s+'")'  ]
          ]
def general_color(s):
  return [[ 2, 'Color:'    ,''                        ],
          [ 1, '\\900red'        ,'cmd.color("red","'+s+'")'  ],
          [ 1, '\\090green'      ,'cmd.color("green","'+s+'")'  ],
          [ 1, '\\009blue'        ,'cmd.color("blue","'+s+'")'  ],
          [ 1, '\\990yellow'      ,'cmd.color("yellow","'+s+'")'  ],
          [ 1, '\\909magenta' ,'cmd.color("magenta","'+s+'")'  ],
          [ 1, '\\099cyan'  ,'cmd.color("cyan","'+s+'")'  ],         
          [ 1, '\\955salmon'      ,'cmd.color("salmon","'+s+'")'  ],
          [ 1, '\\595lime' ,'cmd.color("lime","'+s+'")'  ],
          [ 1, '\\967pink'  ,'cmd.color("pink","'+s+'")'  ],
          [ 1, '\\559slate'  ,'cmd.color("slate","'+s+'")'  ],
          [ 1, '\\949violet'  ,'cmd.color("violet","'+s+'")'  ],
          [ 1, '\\950orange'      ,'cmd.color("orange","'+s+'")'  ],
          [ 1, '\\059marine'      ,'cmd.color("marine","'+s+'")'  ],
          [ 1, '\\905hotpink' ,'cmd.color("hotpink","'+s+'")'  ],
#          [ 1, '\\551olive'  ,'cmd.color("olive","'+s+'")'  ],
#          [ 1, '\\626purple'  ,'cmd.color("purple","'+s+'")'  ],
#          [ 1, '\\266teal'  ,'cmd.color("teal","'+s+'")'  ],
#          [ 1, '\\151forest'  ,'cmd.color("forest","'+s+'")'  ],
#          [ 1, '\\611firebrick'  , 'cmd.color("firebrick","'+s+'")'  ],
#          [ 1, '\\631chocolate'  , 'cmd.color("chocolate","'+s+'")'  ],
          [ 1, '\\116density'    ,'cmd.color("density","'+s+'")'  ],
          [ 1, '\\999white'      ,'cmd.color("white","'+s+'")'  ],
          [ 1, '\\987wheat'      , 'cmd.color("wheat","'+s+'")'  ],
          [ 1, '\\555grey'    ,'cmd.color("grey","'+s+'")'  ],
          [ 1, '\\222black'    ,'cmd.color("grey","'+s+'")'  ]
          ]
def preset_ligand_sites(s):
  return [[ 2, 'Ligand Sites:', ''],
          [ 1, 'solid'  , 'preset.ligand_sites("'+s+'")'          ],
          [ 1, 'solid (better)'  , 'preset.ligand_sites_hq("'+s+'")'          ],
          [ 0, '', ''],
          [ 1, 'transparent'  , 'preset.ligand_sites_trans("'+s+'")'          ],
          [ 1, 'transparent (better)'  , 'preset.ligand_sites_trans_hq("'+s+'")'          ],
          [ 0, '', ''],
          [ 1, 'dot surface'  , 'preset.ligand_sites_dots("'+s+'")'          ],
          [ 0, '', ''],
          [ 1, 'mesh surface'  , 'preset.ligand_sites_mesh("'+s+'")'          ]]
def presets(s):
  return [[ 2, 'Preset:'      ,''                        ],   
          [ 1, 'simple'  ,'preset.simple("'+s+'")'          ],
          [ 1, 'simple (no solvent)'  ,'preset.simple_no_solv("'+s+'")'          ],         
          [ 1, 'technical'  , 'preset.technical("'+s+'")'          ],
          [ 1, 'ligands'  , 'preset.ligands("'+s+'")'          ],
          [ 1, 'ligand_sites'  , preset_ligand_sites(s)        ],
          [ 1, 'pretty ', 'preset.pretty("'+s+'")'          ],
          [ 1, 'pretty (with solvent)'    , 'preset.pretty_solv("'+s+'")'          ],
          [ 1, 'publication '  , 'preset.publication("'+s+'")'          ],
          [ 1, 'publication (with solvent)'  , 'preset.pub_solv("'+s+'")'          ],
          [ 0, ''              ,''                            ],                     
          [ 1, 'default'  ,'preset.default("'+s+'")'          ],         
          ]
#def hydrogens(s):
#  return [[ 2, 'Hydrogens:'      ,''                        ],   
#          [ 1, 'add'  ,'cmd.h_add("'+s+'")'          ],         
#          [ 1, 'remove'  ,'cmd.remove("('+s+') and hydro")'          ],
#          ]
def state(s):
  return [[ 2, 'State:'      ,''                        ],
          [ 1, 'freeze'  ,'cmd.set("state",cmd.get_state(),"'+s+'")'        ],
          [ 1, 'thaw'  ,'cmd.set("state",0,"'+s+'")'        ],         
          ]
 
def movement(s):
  return [[ 2, 'Movement:'      ,''                        ],   
          [ 1, 'protect'  ,'cmd.protect("'+s+'")'          ],
          [ 1, 'deprotect'  ,'cmd.deprotect("'+s+'")'          ],         
          ]
 
def selection(s):
  return [[ 2, 'Selection:'      ,''                        ],   
          [ 1, 'mask'  ,'cmd.mask("'+s+'")'          ],
          [ 1, 'unmask'  ,'cmd.unmask("'+s+'")'          ],         
          ]
def compute(s):
  return [[ 2, 'Compute:'      ,''                        ],   
          [ 1, 'atom count'  ,'cmd.count_atoms("'+s+'",quiet=0)'          ],
          [ 0, ''              ,''                            ],         
          [ 1, 'formal charge sum'  ,'util.sum_formal_charges("'+s+'",quiet=0)'          ],
          [ 1, 'partial charges sum'  ,'util.sum_partial_charges("'+s+'",quiet=0)'          ],                     
          ]
def vacuum(s):
  return [[ 2, 'Vacuum Electrostatics:'      ,''                        ],
          [ 2, '\\955WARNING:\\595 Unvalidated and experimental code!', '' ],
          [ 1, 'protein surface potential (absolute)', 'util.protein_vacuum_esp("'+s+'",quiet=0)'          ],
          [ 1, 'protein surface potential (relative)', 'util.protein_vacuum_esp("'+s+'",absolute=0,quiet=0)'          ],
          [ 2, '\\955NOTE:\\559 Due to absence of solvent dielectric', ''],
          [ 2, '\\559"screening", vacuum electrostatic potentials', ''],
          [ 2, '\\559for macromolecules are only qualitatively', ''],
          [ 2, '\\559meaningful.  Please view with skepticism!', '' ],
          ]
 
def mol_assign(s):
  return [[ 2, 'Assign:'      ,''                        ],   
          [ 1, 'Amber 99 atomic properties',  'util.assign_amber99("'+s+'")' ],
          ]
 
def mol_generate(s):
  return [[ 2, 'Generate:'      ,''                        ],
          [ 1, 'vacuum electrostatics', vacuum(s) ],         
#          [ 1, 'assign', mol_assign(s) ],
          ]
 
def invert(s):
  return [[ 2, 'Invert:'      ,''                        ],   
          [ 1, 'within object(s)'    ,'cmd.select("'+s+'","((byobj '+s+') and not '+s+')",show=1)'    ],
          [ 1, 'within segments(s)'    ,'cmd.select("'+s+'","((byseg '+s+') and not '+s+')",show=1)'    ],         
          [ 1, 'within chains(s)'    ,'cmd.select("'+s+'","((bychain '+s+') and not '+s+')",show=1)'    ],
          [ 1, 'within residues(s)'  ,'cmd.select("'+s+'","((byres '+s+') and not '+s+')",show=1)'    ],                     
          [ 0, ''              ,''                            ],
          [ 1, 'within molecule(s)'    ,'cmd.select("'+s+'","((bymol '+s+') and not '+s+')",show=1)'    ],
          [ 0, ''              ,''                            ],
          [ 1, 'within any'    ,'cmd.select("'+s+'","(not '+s+')",show=1)'    ],
          ]
def complete(s):
  return [[ 2, 'Complete:'      ,''                        ],   
          [ 1, 'resides'  ,'cmd.select("'+s+'","(byres '+s+')",show=1)'      ],
          [ 1, 'chains'  ,'cmd.select("'+s+'","(bychain '+s+')",show=1)'      ],
          [ 1, 'segments'  ,'cmd.select("'+s+'","(byseg '+s+')",show=1)'      ],
          [ 1, 'objects'  ,'cmd.select("'+s+'","(byobj '+s+')",show=1)'      ],
          [ 0, ''              ,''                            ],         
          [ 1, 'molecules'  ,'cmd.select("'+s+'","(bymol '+s+')",show=1)'      ],
          [ 0, ''              ,''                            ],
          [ 1, 'C-alphas'  ,'cmd.select("'+s+'","(bycalpha '+s+')",show=1)'      ],         
          ]
def expand(s):
  return [[ 2, 'Expand:'      ,''                        ],   
          [ 1, 'by 4 A'  ,'cmd.select("'+s+'","('+s+' expand 4)",show=1)' ],
          [ 1, 'by 6 A'  ,'cmd.select("'+s+'","('+s+' expand 6)",show=1)' ],         
          [ 1, 'by 8 A'  ,'cmd.select("'+s+'","('+s+' expand 8)",show=1)' ],
          [ 1, 'by 12 A'  ,'cmd.select("'+s+'","('+s+' expand 12)",show=1)' ],
          [ 1, 'by 16 A'  ,'cmd.select("'+s+'","('+s+' expand 16)",show=1)' ],
          [ 1, 'by 20 A'  ,'cmd.select("'+s+'","('+s+' expand 20)",show=1)' ],         
          [ 0, ''              ,''                            ],
          [ 1, 'by 4 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 4))",show=1)' ],
          [ 1, 'by 6 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 6))",show=1)' ],
          [ 1, 'by 8 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 8))",show=1)' ],
          [ 1, 'by 12 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 12))",show=1)' ],
          [ 1, 'by 16 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 16))",show=1)' ],
          [ 1, 'by 20 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 20))",show=1)' ],
          ]
def around(s):
  return [[ 2, 'Around:'      ,''                        ],   
          [ 1, 'atoms within 4 A'  ,'cmd.select("'+s+'","('+s+' around 4)",show=1)' ],
          [ 1, 'atoms within 6 A'  ,'cmd.select("'+s+'","('+s+' around 6)",show=1)' ],         
          [ 1, 'atoms within 8 A'  ,'cmd.select("'+s+'","('+s+' around 8)",show=1)' ],
          [ 1, 'atoms within 12 A'  ,'cmd.select("'+s+'","('+s+' around 12)",show=1)' ],
          [ 1, 'atoms within 16 A'  ,'cmd.select("'+s+'","('+s+' around 16)",show=1)' ],
          [ 1, 'atoms within 20 A'  ,'cmd.select("'+s+'","('+s+' around 20)",show=1)' ],                     
          [ 0, ''              ,''                            ],         
          [ 1, 'residues within 4 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 4))",show=1)' ],
          [ 1, 'residues within 6 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 6))",show=1)' ],
          [ 1, 'residues within 8 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 8))",show=1)' ],
          [ 1, 'residues within 16 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 12))",show=1)' ],
          [ 1, 'residues within 20 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 20))",show=1)' ],                               
          ]
 
def extend(s):
  return [[ 2, 'Extend:'      ,''                        ],   
          [ 1, 'by 1 bond'  ,'cmd.select("'+s+'","('+s+' extend 1)",show=1)' ],
          [ 1, 'by 2 bonds'  ,'cmd.select("'+s+'","('+s+' extend 2)",show=1)' ],         
          [ 1, 'by 3 bonds'  ,'cmd.select("'+s+'","('+s+' extend 3)",show=1)' ],
          [ 1, 'by 4 bonds'  ,'cmd.select("'+s+'","('+s+' extend 4)",show=1)' ],
          [ 1, 'by 5 bonds'  ,'cmd.select("'+s+'","('+s+' extend 5)",show=1)' ],
          [ 1, 'by 6 bonds'  ,'cmd.select("'+s+'","('+s+' extend 6)",show=1)' ],         
          [ 0, ''              ,''                            ],
          [ 1, 'by 1 bond, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 1))",show=1)' ],
          [ 1, 'by 2 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 2))",show=1)' ],
          [ 1, 'by 3 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 3))",show=1)' ],
          [ 1, 'by 4 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 4))",show=1)' ],
          [ 1, 'by 5 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 5))",show=1)' ],
          [ 1, 'by 6 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 6))",show=1)' ],
          ]
def sele_action(s):
  return [[ 2, 'Actions:'      ,''                        ],   
          [ 1, 'delete selection', 'cmd.delete("'+s+'")'          ],
          [ 1, 'rename selection', 'cmd.wizard("renaming","'+s+'")'          ],
          [ 0, ''              ,''                            ],
          [ 1, 'zoom'          ,'cmd.zoom("'+s+'")'            ],
          [ 1, 'center'        ,'cmd.center("'+s+'")'            ],         
          [ 1, 'origin'        ,'cmd.origin("'+s+'")'          ],
          [ 1, 'orient'        ,'cmd.orient("'+s+'")'          ],
          [ 0, ''              ,''                            ],
          [ 1, 'preset'        ,presets(s)        ],
          [ 0, ''              ,''                            ],
          [ 1, 'remove atoms'  ,'cmd.remove("'+s+'");cmd.delete("'+s+'")'          ],
          [ 0, ''              ,''                            ],
          [ 1, 'around'        , around(s)        ],         
          [ 1, 'expand'        , expand(s)        ],
          [ 1, 'extend'        , extend(s)        ],
          [ 1, 'invert'        , invert(s)        ],
          [ 1, 'complete'      , complete(s)        ],
          [ 0, ''          ,''                                              ],
          [ 1, 'duplicate selection'      ,'cmd.select("'+s+'")'          ],
          [ 1, 'create object'  ,'cmd.create(None,"'+s+'")'    ],         
          [ 1, 'find polar contacts'  ,
            'cmd.dist("'+s+'_polar_conts","'+s+'","'+s+'",quiet=1,mode=2,labels=0)'
            ],                     
          [ 0, ''          ,''                                  ],
          [ 1, 'selection'      , selection(s)        ],         
          [ 1, 'movement'      , movement(s)        ],
          [ 1, 'compute'        , compute(s)        ],         
          ]
def mol_action(s):
  return [[ 2, 'Actions:'    , ''                      ],   
          [ 1, 'zoom'        , 'cmd.zoom("'+s+'")'      ],
          [ 1, 'center'        ,'cmd.center("'+s+'")'            ],
          [ 1, 'origin'      , 'cmd.origin("'+s+'")'    ],
          [ 1, 'orient'      , 'cmd.orient("'+s+'")'    ],
          [ 0, ''          ,''                                              ],
          [ 1, 'preset'  , presets(s)      ],
          [ 0, ''          ,''                                              ],         
          [ 1, 'generate'  , mol_generate(s)      ],         
          [ 0, ''              ,''                            ],
          [ 1, 'assign sec. struc.'  ,'cmd.dss("'+s+'")'        ],
          [ 1, 'find polar contacts'  ,
            'cmd.dist("'+s+'_polar_conts","'+s+'","'+s+'",quiet=1,mode=2,labels=0)'
            ],                     
          [ 0, ''            , ''                      ],
          [ 1, 'rename object', 'cmd.wizard("renaming","'+s+'")'          ],
          [ 1, 'duplicate object'    ,'cmd.create(None,"'+s+'")'    ],         
          [ 1, 'delete object'      , 'cmd.delete("'+s+'")'    ],
          [ 0, ''          ,''                                              ],
          [ 1, 'add hydrogens'  ,'cmd.h_add("'+s+'")'    ],         
          [ 1, 'remove hydrogens'  ,'cmd.remove("(hydro and ('+s+'))")'    ],         
          [ 1, 'remove waters'  ,'cmd.remove("(resn HOH+WAT and ('+s+'))")'    ],
          [ 0, ''          ,''                                              ],
          [ 1, 'state'      , state(s)        ],                     
          [ 1, 'selection'      , selection(s)        ],         
          [ 1, 'movement'      , movement(s)        ],         
          [ 1, 'compute'        , compute(s)        ],
          ]
def simple_action(s):
  return [[ 2, 'Actions:'    , ''                      ],
          [ 1, 'zoom'        , 'cmd.zoom("'+s+'")'      ],
          [ 1, 'center'      , 'cmd.center("'+s+'")'    ],         
          [ 1, 'origin'      , 'cmd.origin("'+s+'")'    ],
          [ 0, ''            , ''                      ],
          [ 1, 'delete'      , 'cmd.delete("'+s+'")'    ],
          ]
def test1(s):
      return [[ 2, 'Test1:'    , ''                      ],   
          [ 1, 'zoom'        , 'cmd.zoom("all")'    ],
          [ 1, 'center'  , 'cmd.center("all")'  ],         
          [ 1, 'origin'  , 'cmd.origin("all")'  ],
          ]
def test2(s):
      return [[ 2, 'Test2:'    , ''                      ],   
          [ 1, 'zoom'        , 'cmd.zoom("all")'    ],
          [ 1, 'center'  , 'cmd.center("all")'  ],         
          [ 1, 'origin'  , 'cmd.origin("all")'  ],
          ]
def all_action(s):
  return [[ 2, 'Actions:'    , ''                      ],   
          [ 1, 'zoom'        , 'cmd.zoom("all")'    ],
          [ 1, 'center'  , 'cmd.center("all")'  ],         
          [ 1, 'origin'  , 'cmd.origin("all")'  ],
          [ 0, ''            , ''                      ],         
          [ 1, 'preset'  , presets(s)    ],         
          [ 0, ''            , ''                      ],         
          [ 1, 'delete everything'  , 'cmd.delete("all")'    ],         
          [ 0, ''          ,''                                              ],
          [ 1, 'add hydrogens' ,'cmd.h_add("'+s+'")'    ],         
          [ 1, 'remove hydrogens'  ,'cmd.remove("(elem h and ('+s+'))")'    ],
          [ 1, 'remove waters'  ,'cmd.remove("(resn HOH+WAT and ('+s+'))")'    ],                     
          [ 0, ''          ,''                                              ],
          [ 1, 'selection'      , selection(s)        ],                     
          [ 1, 'movement'      , movement(s)        ],
          [ 1, 'compute'        , compute(s)        ],                     
          ]
def mol_labels(s):
  return [[ 2, 'Labels:'        , ''                                  ],
          [ 1, 'clear'          , 'cmd.label("'+s+'","\'\'")'        ],
          [ 0, ''              , ''                                  ],
          [ 1, 'residues'      ,
  """cmd.label('''(name ca+C1*+C1' and (byres("""+s+""")))''','''"%s-%s"%(resn,resi)''')"""  ],
          [ 1, 'chains'      ,  'util.label_chains("'+s+'")'  ],
          [ 1, 'segments'      ,  'util.label_segments("'+s+'")'  ],         
          [ 0, ''              , ''                                  ],         
          [ 1, 'atom name'      , 'cmd.label("'+s+'","name")'        ],
          [ 1, 'element symbol' , 'cmd.label("'+s+'","elem")'        ],         
          [ 1, 'residue name'  , 'cmd.label("'+s+'","resn")'        ],
          [ 1, 'residue identifier'    , 'cmd.label("'+s+'","resi")'        ],
          [ 1, 'chain identifier' , 'cmd.label("'+s+'","chain")'        ],
          [ 1, 'segment identifier'      , 'cmd.label("'+s+'","segi")'        ],         
          [ 0, ''              , ''                                  ],
          [ 1, 'b-factor'      , 'cmd.label("'+s+'","\'%1.2f\'%b")'  ],
          [ 1, 'occupancy'      , 'cmd.label("'+s+'","\'%1.2f\'%q")'  ],
          [ 1, 'vdw radius'      , 'cmd.label("'+s+'","\'%1.2f\'%vdw")'  ],
          [ 0, ''              , ''                                  ],
          [ 1, 'partial charge(.2f)' ,           
  'cmd.label("'+s+'","\'%.2f\'%partial_charge")'                      ],
          [ 1, 'partial charge(.4f)' ,
  'cmd.label("'+s+'","\'%.4f\'%partial_charge")'                      ],
          [ 1, 'formal charge' ,
  'cmd.label("'+s+'","\'%d\'%formal_charge")'                      ],
          [ 1, 'bohr radius'      , 'cmd.label("'+s+'","\'%1.2f\'%bohr")'  ],                               
          [ 0, ''              , ''                                  ],
          [ 1, 'text type'      , 'cmd.label("'+s+'","text_type")'    ],
          [ 1, 'numeric type'  , 'cmd.label("'+s+'","numeric_type")' ],
          [ 0, ''              , ''                                  ],     
          [ 1, 'atom i.d.'            , 'cmd.label("'+s+'","id")' ],
          [ 1, 'atom i.d.(+1)'          , 'cmd.label("'+s+'","id+1")' ],
          ]
def mol_view(s):
  return [
      [ 1, 'zoom'          ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'          ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'          ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'          ,'cmd.orient("'+s+'")'            ],
      ]
def all_option(s):
  return [
      [ 2, '(all)'      , '' ],
      [ 1, 'show'      , mol_show(s) ],
      [ 1, 'hide'      , mol_hide(s) ],
      [ 1, 'color'      , mol_color(s) ],
      [ 1, 'view'      , mol_view(s) ],
      [ 1, 'preset'      , presets(s) ],
      [ 0, ''            , ''                      ],
      [ 1, 'zoom'          ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'          ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'          ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'          ,'cmd.orient("'+s+'")'            ],
      [ 0, ''            , ''                      ],
      [ 1, 'label'      , mol_labels(s) ],
      [ 0, '', '' ],
      [ 1, 'enable'        ,'cmd.enable("'+s+'")'            ],
      [ 1, 'disable'        ,'cmd.disable("'+s+'")'            ],
      ]
def enable_disable(enable):
  if enable:
      result = [[ 2, 'Enable', '' ]]
      cmmd = 'cmd.enable("'
  else:
      result = [[ 2, 'Disable', '']]
      cmmd = 'cmd.disable("'
  return result + map(lambda ob,cm=cmmd:[1,ob,cm+ob+'")'],['all']+cmd.get_names('objects'))
 
def main_menu():
  return [
      [ 2, 'Main Pop-Up'  , '' ],
      [ 1, 'zoom (vis)'          ,'cmd.zoom("visible")'            ],
      [ 1, 'center (vis)'          ,'cmd.center("visible")'            ],     
      [ 1, 'orient (vis)'          ,'cmd.orient("visible")'            ],
      [ 1, 'reset'          ,'cmd.reset()'            ],
      [ 0, ''            , ''                      ],         
      [ 1, '(all)'      , all_option("all") ],
      [ 1, '(visible)'      , all_option("visible") ],
      [ 0, ''            , ''                      ],
      [ 1, 'ray'          ,'cmd.ray()' ],
      [ 0, ''            , ''                      ],
      [ 1, 'enable', enable_disable(1) ],
      [ 1, 'disable', enable_disable(0) ], 
      [ 0, ''            , ''                      ],
      [ 1, 'delete all'          ,'cmd.delete("all")' ],
      [ 1, 'reinitialize'          ,'cmd.reinitialize()' ],
      [ 1, 'quit'          ,'cmd.quit()' ],
      ]
def pick_option(title,s,object=0):
 
  result = [
      [ 2, title, '' ],
      [ 1, 'color'      , mol_color(s) ],
      [ 1, 'show'      , mol_show(s) ],
      [ 1, 'hide'      , mol_hide(s) ],
      [ 1, 'preset'  , presets(s)      ],     
      [ 0, ''            , ''                      ],
      [ 1, 'zoom'          ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'          ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'          ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'          ,'cmd.orient("'+s+'")'            ],
      [ 1, 'indicate'        ,'cmd.indicate("'+s+'")'            ],
      [ 0, ''            , ''                      ],
      [ 1, 'labels'      , mol_labels(s) ],
      ]
# Edit dwkulp 6/11/05 , add a rotamer menu to residue menu
  if title == 'Residue':
result.extend([[ 1, 'rotamers'    , rotamer_menu(s)]])
  if object:
      result.extend([
        [ 0, ''            , ''                      ],       
        [ 1, 'disable'        ,'cmd.disable("'+s+'")'            ],
        [ 0, ''            , ''                      ],
        [ 1, 'delete'        ,'cmd.delete("'+s+'")'            ]       
        ])
  else:
      result.extend([
      [ 0, ''            , ''                      ],     
      [ 1, 'create object','cmd.create(None,"'+s+'")'            ],     
      [ 0, ''            , ''                      ],
      [ 1, 'remove'      , 'cmd.remove("'+s+'")' ],   
                    ])
  return result
def pick_option_rev(title,s,object=0):
  result = pick_option(title,s,object)[1:]
  result.reverse()
  return result
def pick_menu(s1,s2):
  if s1[-1]=='`':
      title = s1[0:-1]
  else:
      title = s1
  return [[ 2, title    , '' ],
          [ 1, 'atom'    , pick_option("Atom",s2) ],
          [ 1, 'residue' , pick_option("Residue","(byres ("+s2+"))") ],
          [ 1, 'chain'  , pick_option("Chain","(bychain ("+s2+"))") ],
          [ 1, 'segment' , pick_option("Segment","(byseg ("+s2+"))") ],
          [ 1, 'object'  , pick_option("Object","(byobject ("+s2+"))",1) ],
          [ 0, ''            , ''                      ],
          [ 1, 'molecule', pick_option("Molecule","(bymol ("+s2+"))") ],
          [ 0, ''            , ''                      ],
          [ 1, 'fragment', pick_option("Fragment","(byfrag ("+s2+"))") ],
          [ 1, 'fragment+joint(s)', pick_option("Fragment","((byfrag ("+s2+")) extend 1)") ],
          ]
     
def seq_menu(s2,s3):
 
  return [[ 2, 'Sequence'    , '' ],
          [ 1, 'selection', pick_option('('+s3+')',s3) ],
          [ 0, ''            , ''                      ],
          [ 1, 'residue' , pick_option("Residue","(byres ("+s2+"))") ],
          [ 1, 'chain'  , pick_option("Chain","(bychain ("+s2+"))") ],
          [ 1, 'segment' , pick_option("Segment","(byseg ("+s2+"))") ],
          [ 1, 'object'  , pick_option("Object","(byobject ("+s2+"))",1) ],
          [ 0, ''            , ''                      ],
          [ 1, 'molecule', pick_option("Molecule","(bymol ("+s2+"))") ],
          [ 0, ''            , ''                      ],
          [ 1, 'C-alpha'    , pick_option("C-alpha",s2) ],
          ]
     
def seq_option(title,s,object=0):
  c=len(title)-1
  while title[c]!='/':
      c = c-1
  title = title[0:c+1]
 
  result = [
      [ 2, title, '' ],
      [ 1, 'color'      , mol_color(s) ],
      [ 1, 'show'      , mol_show(s) ],
      [ 1, 'hide'      , mol_hide(s) ],
      [ 1, 'preset'  , presets(s)      ],     
      [ 0, ''            , ''                      ],
      [ 1, 'zoom'          ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'          ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'          ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'          ,'cmd.orient("'+s+'")'            ],
      [ 1, 'indicate'        ,'cmd.indicate("'+s+'")'            ],
      [ 0, ''            , ''                      ],
      [ 1, 'labels'      , mol_labels(s) ],
      ]
    
    
</source>
  if object:
      result.extend([
        [ 0, ''            , ''                      ],       
        [ 1, 'disable'        ,'cmd.disable("'+s+'")'            ],
        [ 0, ''            , ''                      ],
        [ 1, 'delete'        ,'cmd.delete("'+s+'")'            ]       
        ])
  else:
      result.extend([
      [ 0, ''            , ''                      ],     
      [ 1, 'create object','cmd.create(None,"'+s+'")'            ],           
      [ 0, ''            , ''                      ],
      [ 1, 'remove'      , 'cmd.remove("'+s+'")' ],   
                    ])
  return result
 
 
###############################################
# Dan Kulp
# Added Rotamer list to residue menu..
# rotamer.py must be importable (I placed it in
# the same directory as menu.py)
###############################################
 
import rotamers
 
 
def rotamer_menu(s):
# Check for rotamer library being loaded
if not rotamers.rotdat:
    return [ [2, "Must run rotamers.py first",'']]
 
# Check for valid rotamer residue..
res = cmd.get_model("byres ("+s+")").atom[0].resn
        if not res in rotamers.CHIS.keys():
    return [ [2, "Residue: "+res+" not known sidechain or does not have rotamers", '']]
 
# Get PHI,PSI bins for rotamer (also prints out current phi,psi, chi1,chi2,chi3,chi4)
bins = rotamers.doRotamers(s,type='bins')
 
# Add a title to the menu
result = [ [2, bins[0]+' Rotamers in bin ('+str(bins[1])+','+str(bins[2])+')','' ], [1, ':::PROB,CHI1,CHI2,CHI3,CHI4:::','']]
 
        # Grab the entries for this residue and phi,psi bins
match_rotamers = rotamers.rotdat[bins[0]+":"+str(bins[1])+":"+str(bins[2])]
 
# Set max number of rotamers to display (probably should be somewhere 'higher up' in the code)
max_rotamers = 10
 
 
if len(match_rotamers) < max_rotamers:
    max_rotamers = len(match_rotamers)


===EXAMPLES===
# Create menu entry for each possible rotamer
hide lines,all
        for item in range(0,max_rotamers):
hide ribbon
            result.append( [ 1, str(match_rotamers[item]), 'rotamers.set_rotamer("'+s+'","'\
    +str(match_rotamers[item][1])+'","'\
    +str(match_rotamers[item][2])+'","'\
    +str(match_rotamers[item][3])+'","'\
    +str(match_rotamers[item][4])+'")'])
return result


===SEE ALSO===
</source>
===REFERENCES===
Dunbrack and Cohen. Protein Science 1997


[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]


[[Category:Script_Library|Rotamer Toggle]]
[[Category:Script_Library|Rotamer Toggle]]

Revision as of 23:08, 11 May 2005

DESCRIPTION

Backbone-Dependent Rotamer library (Dunbrack, Cohen ; see ref) is imported into pymol giving access to this information. There are a number of different ways to use the data, I've only implemented a few as well as added extra functions that seemed useful.

  • colorRotamers - color rotamers by closest matching rotamer angles from database; i.e. color by how common each rotamer of selection, blue - red (least to most common).
  • Rotamer Menu - an added menu into menu.py, which displays the most common rotamers for the given(clicked) residue; you can also set the residue any of the common rotamers as well
  • set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles
  • set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)

To setup a rotamer menu inside the residue menu (default windows pymol installation):

  • copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py
  • copy mymenu.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)
  • copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)

This is only one possible way to do this, I am sure there are many others. I'm not going to post the bbdep, but there is a link in the References section to Dunbrack's download page (get the "sorted" lib)

Of course you can simply import rotamers.py and use the functions manually.

This should not have any OS specific stuff in it yet, but has only been tested on Windows. I'll test it on linux in the next few days.

USAGE

colorRotamers selection
set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]
set_phipsi selection phi_angle, psi_angle

EXAMPLES

  colorRotamers chain A
  set_rotamer resi 40, -60,-40   (only set chi1,chi2 angles)
  set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)
  

REFERENCES

Dunbrack and Cohen. Protein Science 1997

Dunbrack Lab Page (Contains backbone-dependent library)

Scripts (Rotamers.py ; MyMenu.py)

Rotamers.py

   ##################################################################
# File:          Rotamers.py
# Author:        Dan Kulp
# Creation Date: 6/8/05
#
# Notes:
#     Incorporation of Rotamer library
#     readRotLib() - fills rotdat; 
#        indexed by "RES:PHI_BIN:PSI_BIN".
#
#     Three main functions:
#     1. colorRotamers - colors according
#          to rotamer probablitity
#     2. getBins(sel)
#           phi,psi bin for rotamer
#     3. set_rotamer - set a side-chain 
#           to a specific rotamer	
#
#     To setup a rotamer menu in the 
#   right click, under "Residue"
#        1. cp mymenu.py modules/pymol/menu.py
#        2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)
#
# Requirements:
#  set ROTLIB to path for rotamer library
# Reference: 
#  Dunbrack and Cohen. Protein Science 1997
####################################################################

import colorsys,sys
import string
import re
import editing
import os
import cmd
import math

# Path for library
ROTLIB=os.environ['PYMOL_PATH']+"/modules/pymol/bbdep02.May.sortlib"

# Place for library in memory..
rotdat = {}

def readRotLib():	
    # Column indexes in rotamer library..
    RES  = 0
    PHI  = 1
    PSI  = 2
    PROB = 8
    CHI1 = 9
    CHI2 = 10
    CHI3 = 11
    CHI4 = 12

    if os.path.exists(ROTLIB):
		print "File exists: "+ROTLIB
		input = open(ROTLIB, 'r')
		for line in input:

	  	    # Parse by whitespace (I believe format is white space and not fixed-width columns)
		    dat = re.split("\s+",line)

		    # Add to rotamer library in memory : 
		    #   key format       RES:PHI_BIN:PSI_BIN
		    #   value format     PROB, CHI1, CHI2, CHI3, CHI4
		    try:
		        rotdat[dat[RES]+":"+dat[PHI]+":"+dat[PSI]].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])
		    except KeyError:
			rotdat[dat[RES]+":"+dat[PHI]+":"+dat[PSI]] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]

		    
    else:
	print "Couldn't find Rotamer library"


# Atoms for each side-chain angle for each residue
CHIS = {}
CHIS["ARG"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD" ],
		["CB","CG","CD","NE" ],
		["CG","CD","NE","CZ" ]
	      ]

CHIS["ASN"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","OD2" ]
	      ]

CHIS["ASP"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","OD1" ]
	      ]
CHIS["CYS"] = [ ["N","CA","CB","CG" ]
	      ]
CHIS["GLN"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD" ],
		["CB","CG","CD","OE1"]
	      ]

CHIS["GLU"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD" ],
		["CB","CG","CD","OE1"]
	      ]

CHIS["HIS"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","ND1"]
	      ]

CHIS["ILE"] = [ ["N","CA","CB","CG1" ],
		["CA","CB","CG1","CD1" ]
	      ]

CHIS["LEU"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD1" ]
	      ]

CHIS["LYS"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD" ],
		["CB","CG","CD","CE"],
		["CG","CD","CE","NZ"]
	      ]

CHIS["MET"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","SD" ],
		["CB","CG","SD","CE"]
	      ]

CHIS["PHE"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD1" ]
	      ]

CHIS["PRO"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD" ]
	      ]

CHIS["SER"] = [ ["N","CA","CB","OG" ]
	      ]

CHIS["THR"] = [ ["N","CA","CB","OG1" ]
	      ]
CHIS["TYR"] = [ ["N","CA","CB","CG" ],
		["CA","CB","CG","CD1" ]
	      ]

CHIS["VAL"] = [ ["N","CA","CB","CG1" ]
	      ]

# Color Rotamer by side-chain angle position
#  'bin' side-chain angles into closest
def colorRotamers(sel):
    doRotamers(sel)

# Utility function, to set phi,psi angles for a given selection
# Note: Cartoon, Ribbon functionality will not display correctly after this
def set_phipsi(sel, phi,psi):
    doRotamers(sel,angles=[phi,psi],type="set")

# Set a rotamer, based on a selection, a restype and chi angles
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):
    at = cmd.get_model("byres ("+sel+")").atom[0]

    list = [chi1,chi2,chi3,chi4]
    for i in range(0,len(CHIS[at.resn])):
	print "Setting Chi"+str(i+1)+" to "+str(list[i])
        editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],		    
		             sel + ' and name '+CHIS[at.resn][i][1],		    
		             sel + ' and name '+CHIS[at.resn][i][2],		    
		             sel + ' and name '+CHIS[at.resn][i][3], list[i])		    

    # Remove some objects that got created
    cmd.delete("pk1")
    cmd.delete("pk2")
    cmd.delete("pkmol")

# Get Phi,Psi bins for given selection
# WARNING:  assume selection is single residue (will only return first residue bins)
def getBins(sel):
    return doRotamers(sel, type="bins")

# Specific comparison operator for rotamer prob data 
def mycmp(first, second):
	return cmp( first[1], second[1])

# Color Ramp...
def rot_color(vals): 
	nbins = 10
	vals.sort(mycmp)
	print "End sort: "+str(len(vals))+" : "+str(nbins)


	# Coloring scheme...
	i = 0
	j = 0
	rgb = [0.0,0.0,0.0]
	sel_str = ""
	while i < len(vals):
		if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:
		      hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)

		      #convert to rgb and append to color list
		      rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])
		      if j < nbins-1:
		              j += 1	

		cmd.set_color("RotProbColor"+str(i), rgb)
		cmd.color("RotProbColor"+str(i), str(vals[i][0]))
		i += 1


# Main function                           
def doRotamers(sel,angles=[], type="color"):                           

	# Read in Rotamer library if not already done
	if len(rotdat) == 0:
		readRotLib()

	# Set up some variables..
	residues = ['dummy']  # Keep track of residues already done
	probs = []            # probability of each residue conformation
	phi = 0               # phi,psi angles of current residue
	psi = 0

	# Get atoms from selection
	atoms = cmd.get_model("byres ("+sel+")")

        # Loop through atoms in selection		
	for at in atoms.atom:
	    try:
	       # Don't process Glycines or Alanines
	       if not (at.resn == 'GLY' or at.resn == 'ALA'):
	        if not at.chain+":"+at.resn+":"+at.resi in residues:
	            residues.append(at.chain+":"+at.resn+":"+at.resi)

		    # Check for a null chain id (some PDBs contain this) 
		    unit_select = ""
		    if not at.chain == "":
			unit_select = "chain "+str(at.chain)+" and "

		    # Define selections for residue i-1, i and i+1    
		    residue_def = unit_select+'resi '+str(at.resi)
  		    residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)
		    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)

	            # Compute phi/psi angle
		    phi = cmd.get_dihedral(residue_def+' and name CB',residue_def+' and name CA',residue_def+' and name N',residue_def_prev+' and name C')
		    psi = cmd.get_dihedral(residue_def+' and name O',residue_def+' and name C',residue_def+' and name CA',residue_def+' and name CB')
		    if type == "set":
			    print "Changing "+at.resn+str(at.resi)+" from "+str(phi)+","+str(psi)+" to "+str(angles[0])+","+str(angles[1])
			    cmd.set_dihedral(residue_def+' and name CB',residue_def+' and name CA',residue_def+' and name N',residue_def_prev+' and name C',angles[0])
			    cmd.set_dihedral(residue_def+' and name O',residue_def+' and name C',residue_def+' and name CA',residue_def+' and name CB', angles[1])
			    continue
						
		    # Find correct 10x10 degree bin		        		
		    phi_digit = abs(int(phi)) - abs(int(phi/10)*10)
		    psi_digit = abs(int(psi)) - abs(int(psi/10)*10)
		    
		    # Remember sign of phi,psi angles
	    	    phi_sign = 1
		    if phi < 0:    phi_sign = -1

		    psi_sign = 1
		    if psi < 0:    psi_sign = -1

		    # Compute phi,psi bins
  		    phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)
		    if phi_digit >= 5:    phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)

		    psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)
		    if psi_digit >= 5:    psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)

	            print "Given "+at.resn+":"+at.resi+" PHI,PSI ("+str(phi)+","+str(psi)+") : bin ("+str(phi_bin)+","+str(psi_bin)+")"

		
		    # Get current chi angle measurements
		    chi = []
		    for i in range(0,len(CHIS[at.resn])):
		       chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],		    
		  			             residue_def + ' and name '+CHIS[at.resn][i][1],		    
					             residue_def + ' and name '+CHIS[at.resn][i][2],		    
					             residue_def + ' and name '+CHIS[at.resn][i][3]))		    
		    print "CHIs: "+str(chi)
		    if type == 'bins':
		         return [at.resn, phi_bin,psi_bin]

		    # Compute probabilities for given chi angles
                    prob = 0
		    prob_box = 22 		    
		    for item in range(0,len(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)])):
			print "Rotamer from db: "+str(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item])
			if chi[0]:
			    if chi[0] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) - (prob_box/2) and \
				chi[0] <= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) + (prob_box/2):
				if len(chi) == 1:
					prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
					break
				if chi[1] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) - (prob_box/2) and \
				 float(chi[1] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) + (prob_box/2):
					if len(chi) == 2:
					    prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
					    break
					if chi[2] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) - (prob_box/2) and \
					   float(chi[2] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) + (prob_box/2):
    					    if len(chi) == 3:
					        prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
					        break
					    if chi[3] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) - (prob_box/2) and \
					       float(chi[3] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) + (prob_box/2):
					        prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]
					        break

			
		    print "PROB OF ROTAMER: "+str(prob)
		    print "---------------------------"
		    probs.append([residue_def, prob])

	    except:
#		probs.append([residue_def, -1])
		print "Exception found"
		continue

	# Color according to rotamer probability
	rot_color(probs)	    

	




readRotLib()

cmd.extend('set_phipsi',set_phipsi)
cmd.extend('set_rotamer',set_rotamer)
cmd.extend('colorRotamers',colorRotamers)

MyMenu.py

#A* -------------------------------------------------------------------
#B* This file contains source code for the PyMOL computer program
#C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific. 
#D* -------------------------------------------------------------------
#E* It is unlawful to modify or remove this copyright notice.
#F* -------------------------------------------------------------------
#G* Please see the accompanying LICENSE file for further information. 
#H* -------------------------------------------------------------------
#I* Additional authors of this source file include:
#-* Dan Kulp (dwkulp@mail.med.upenn.edu) ; rotamer menu 
#-* 
#-*
#Z* -------------------------------------------------------------------

# pmm.py 
# This section contains the menu contents and the associated commands
#

import cmd
import os

def mol_show(s):
   return [[ 2, 'Show:'      , ''                               ],
           [ 1, 'lines'      , 'cmd.show("lines"     ,"'+s+'")' ],
           [ 1, 'nonbonded'  , 'cmd.show("nonbonded" ,"'+s+'")' ],
           [ 1, 'sticks'     , 'cmd.show("sticks"    ,"'+s+'")' ],
           [ 1, 'ribbon'     , 'cmd.show("ribbon"    ,"'+s+'")' ],
           [ 1, 'cartoon'    , 'cmd.show("cartoon"   ,"'+s+'")' ],
           [ 0, ''           , ''                               ],
           [ 1, 'labels'     , 'cmd.show("labels"    ,"'+s+'")' ],
           [ 1, 'cell'       , 'cmd.show("cell"      ,"'+s+'")' ],
           [ 0, ''           , ''                               ],
           [ 1, 'dots'       , 'cmd.show("dots"      ,"'+s+'")' ],
           [ 1, 'spheres'    , 'cmd.show("spheres"   ,"'+s+'")' ],
           [ 1, 'nb_spheres' , 'cmd.show("nb_spheres","'+s+'")' ],
           [ 0, ''           , ''                               ],
           [ 1, 'mesh'       , 'cmd.show("mesh"      ,"'+s+'")' ],
           [ 1, 'surface'    , 'cmd.show("surface"   ,"'+s+'")' ],
           [ 0, ''           , ''                               ],           
           [ 1, 'main chain' , 'cmd.show("lines","((byres ('+s+'))&n;ca,c,n,o,h)")' ],
           [ 1, 'side chain' , 'cmd.show("lines","((byres ('+s+'))&(!n;c,n,o,h))")' ],
           ]

def mol_hide(s):
   return [[ 2, 'Hide:'     , ''                                ],
           [ 1, 'everything', 'cmd.hide("everything","'+s+'")'  ],
           [ 0, ''          , ''                                ],
           [ 1, 'lines'     , 'cmd.hide("lines"     ,"'+s+'")'  ],
           [ 1, 'nonbonded' , 'cmd.hide("nonbonded" ,"'+s+'")'  ],           
           [ 1, 'sticks'    , 'cmd.hide("sticks"    ,"'+s+'")'  ],
           [ 1, 'ribbon'    , 'cmd.hide("ribbon"    ,"'+s+'")'  ],
           [ 1, 'cartoon'   , 'cmd.hide("cartoon"   ,"'+s+'")' ],           
           [ 0, ''          , ''                                ],
           [ 1, 'labels'    , 'cmd.hide("labels"    ,"'+s+'")'  ],
           [ 1, 'cell'      , 'cmd.hide("cell"      ,"'+s+'")' ],
           [ 0, ''          , ''                                ],
           [ 1, 'dots'      , 'cmd.hide("dots"      ,"'+s+'")'  ],
           [ 1, 'spheres'   , 'cmd.hide("spheres"   ,"'+s+'")'  ],
           [ 1, 'nb_spheres', 'cmd.hide("nb_spheres","'+s+'")'  ],           
           [ 0, ''          , ''                                ],
           [ 1, 'mesh'      , 'cmd.hide("mesh"      ,"'+s+'")'  ],
           [ 1, 'surface'   , 'cmd.hide("surface"   ,"'+s+'")'  ],
           [ 0, ''          , ''                                ],
           [ 1, 'main chain', 'cmd.hide("((byres ('+s+'))&n;c,n,o,h)")' ],
           [ 1, 'side chain', 'cmd.hide("((byres ('+s+'))&!n;ca,c,n,o,h)")' ],
           [ 1, 'waters'    , 'cmd.hide("(resn HOH+WAT and ('+s+'))")'     ],                      
           [ 0, ''          , ''                                ],
           [ 1, 'hydrogens' , 'cmd.hide("('+s+' and hydro)")'   ],
           [ 0, ''          , ''                                ],           
           [ 1, 'unselected', 'cmd.hide("(not '+s+')")'         ],
           ]

def dist_show(s):
   return [[ 2, 'Show:'     , ''                               ],
           [ 1, 'dashes'    , 'cmd.show("dashes"    ,"'+s+'")' ],
           [ 1, 'labels'    , 'cmd.show("labels"    ,"'+s+'")' ]
          ]   

def dist_hide(s):
   return [[ 2, 'Hide:'     , ''                                ],
           [ 1, 'dashes'    , 'cmd.hide("dashes"    ,"'+s+'")'  ],
           [ 1, 'labels'    , 'cmd.hide("labels"    ,"'+s+'")'  ]
          ]

def cgo_show(s):
   return [[ 2, 'Show:'     , ''                               ],
           [ 1, 'cgo'    , 'cmd.show("cgo"    ,"'+s+'")' ],
          ]   

def cgo_hide(s):
   return [[ 2, 'Hide:'     , ''                                ],
           [ 1, 'cgo'    , 'cmd.hide("cgo"    ,"'+s+'")'  ],
          ]

def simple_show(s):
   return [[ 2, 'Show:'       , ''                             ],
           [ 1, 'everything'  , 'cmd.show("everything","'+s+'")'          ]]

def simple_hide(s):
   return [[ 2, 'Hide:'     ,''                                ],
           [ 1, 'everything'    ,'cmd.hide("everything","'+s+'")'        ]]

def mesh_show(s):
   return [[ 2, 'Show:'       , ''                             ],
           [ 1, 'mesh'        , 'cmd.show("mesh","'+s+'")'     ],           
           [ 1, 'cell'        , 'cmd.show("cell","'+s+'")'     ],
           [ 1, 'everything'  , 'cmd.enable("'+s+'")'          ]]

def mesh_hide(s):
   return [[ 2, 'Hide:'       , ''                             ],
           [ 1, 'mesh'        , 'cmd.hide("mesh","'+s+'")'     ],                      
           [ 1, 'cell'        , 'cmd.hide("cell","'+s+'")'      ],           
           [ 1, 'everything'  , 'cmd.disable("'+s+'")'          ]]

def by_elem(s):
   return [
      [ 2, 'By Element:'     ,''                               ],
      [ 1, '\\292C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbag("'+s+'")'],
   [ 1, '\\099C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbac("'+s+'")'],
   [ 1, '\\909C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbam("'+s+'")'],           
   [ 1, '\\990C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbay("'+s+'")'],
   [ 1, '\\955C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbas("'+s+'")'],
   [ 1, '\\777C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbaw("'+s+'")'],
   [ 1, '\\559C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbab("'+s+'")'],
   [ 1, '\\972C\\777H\\229N\\922O\\950S\\905*'  , 'util.cbao("'+s+'")'],
   [ 1, ' \\777H\\229N\\922O\\950S\\905*'  , 'util.cnc("'+s+'")']]                     

def by_ss(s):
   return [
            [ 2, 'By Secondary Structure:'     ,''                               ],
   [ 1, '\\900Helix \\990Sheet \\090Loop'  , 'util.cbss("'+s+'","red","yellow","green")'],
   [ 1, '\\099Helix \\909Sheet \\955Loop'  , 'util.cbss("'+s+'","cyan","magenta","salmon")'],
           ]

def spectrum(s):
   return [
            [ 2, 'Spectrum:'     ,''                               ],
           [ 1, '\\900r\\950a\\990i\\090n\\099b\\059o\\009w\\888(e. c)',
             'cmd.spectrum("count",selection="('+s+')&e. c")'],           
           [ 1, '\\900r\\950a\\990i\\090n\\099b\\059o\\009w\\888(*/ca)',
             'cmd.spectrum("count",selection="('+s+')&*/ca")'],
           [ 1, '\\900r\\950a\\990i\\090n\\099b\\059o\\009w',
             'cmd.spectrum("count",selection="'+s+'",byres=1)'],
           [ 0, ''                                , ''                 ],
           [ 1, 'b-factors'   , 'cmd.spectrum("b",selection=("'+s+'"))'         ],           
           ]

def by_chain(s):
   return [
      [ 2, 'By Chain:'     ,''                               ],
           [ 1, '\\900b\\950y \\090c\\099h\\059a\\009i\\705n\\888(e. c)',
             'util.color_chains("('+s+' and elem c)")'],
           [ 1, '\\900b\\950y \\090c\\099h\\059a\\009i\\705n\\888(*/ca)',
             'util.color_chains("('+s+' and name ca)")'],
           [ 1, '\\900b\\950y \\090c\\099h\\059a\\009i\\705n',
             'util.color_chains("('+s+')")'],
                 [ 0, ''                                , ''                 ],
           [ 1, '\\900c\\950h\\990a\\090i\\099n\\059b\\009o\\705w\\888s',
             'util.chainbow("('+s+')")'],                                 
      ]
def mol_color(s):
   return [[ 2, 'Color:'     ,''                               ],
           [ 1, 'by chain' , by_chain(s) ],
           [ 1, 'by element'  , by_elem(s) ],
           [ 1, 'by ss  '  , by_ss(s) ],
           [ 1, '\\900s\\950p\\990e\\090c\\099t\\059r\\009u\\555m', spectrum(s) ],
           [ 0, ''                                , ''                 ],           
           [ 1, '\\900red'         , 'cmd.color("red","'+s+'")'     ],
           [ 1, '\\090green'       , 'cmd.color("green","'+s+'")'   ],
           [ 1, '\\009blue'        , 'cmd.color("blue","'+s+'")'    ],
           [ 1, '\\990yellow'      , 'cmd.color("yellow","'+s+'")'  ],
           [ 1, '\\909magenta'     , 'cmd.color("magenta","'+s+'")' ],
           [ 1, '\\099cyan'        , 'cmd.color("cyan","'+s+'")'    ],           
           [ 1, '\\955salmon'      , 'cmd.color("salmon","'+s+'")'  ],
           [ 1, '\\595lime'        , 'cmd.color("lime","'+s+'")'    ],
           [ 1, '\\967pink'  ,'cmd.color("pink","'+s+'")'  ],
           [ 1, '\\559slate'       , 'cmd.color("slate","'+s+'")'   ],
           [ 1, '\\949violet'      , 'cmd.color("violet","'+s+'")'  ],
           [ 1, '\\950orange'      , 'cmd.color("orange","'+s+'")'  ],
           [ 1, '\\059marine'      , 'cmd.color("marine","'+s+'")'  ],
           [ 1, '\\905hotpink' ,'cmd.color("hotpink","'+s+'")'  ],
#           [ 1, '\\551olive'       , 'cmd.color("olive","'+s+'")'   ],
#           [ 1, '\\626purple'      , 'cmd.color("purple","'+s+'")'  ],
#           [ 1, '\\266teal'        , 'cmd.color("teal","'+s+'")'    ],
#           [ 1, '\\151forest'      , 'cmd.color("forest","'+s+'")'  ],
#           [ 1, '\\611firebrick'   , 'cmd.color("firebrick","'+s+'")'  ],
#           [ 1, '\\631chocolate'   , 'cmd.color("chocolate","'+s+'")'  ],           
           [ 1, '\\999white'       , 'cmd.color("white","'+s+'")'   ],
           [ 1, '\\987wheat'       , 'cmd.color("wheat","'+s+'")'   ],
           [ 1, '\\555grey'        , 'cmd.color("grey","'+s+'")'    ],
           [ 1, '\\222black'    ,'cmd.color("grey","'+s+'")'  ]
           ]

def general_color(s):
   return [[ 2, 'Color:'     ,''                        ],
           [ 1, '\\900red'         ,'cmd.color("red","'+s+'")'  ],
           [ 1, '\\090green'       ,'cmd.color("green","'+s+'")'  ],
           [ 1, '\\009blue'        ,'cmd.color("blue","'+s+'")'  ],
           [ 1, '\\990yellow'      ,'cmd.color("yellow","'+s+'")'  ],
           [ 1, '\\909magenta' ,'cmd.color("magenta","'+s+'")'  ],
           [ 1, '\\099cyan'  ,'cmd.color("cyan","'+s+'")'  ],           
           [ 1, '\\955salmon'      ,'cmd.color("salmon","'+s+'")'  ],
           [ 1, '\\595lime' ,'cmd.color("lime","'+s+'")'  ],
           [ 1, '\\967pink'  ,'cmd.color("pink","'+s+'")'  ],
           [ 1, '\\559slate'  ,'cmd.color("slate","'+s+'")'  ],
           [ 1, '\\949violet'  ,'cmd.color("violet","'+s+'")'  ],
           [ 1, '\\950orange'      ,'cmd.color("orange","'+s+'")'  ],
           [ 1, '\\059marine'      ,'cmd.color("marine","'+s+'")'  ],
           [ 1, '\\905hotpink' ,'cmd.color("hotpink","'+s+'")'  ],
#           [ 1, '\\551olive'   ,'cmd.color("olive","'+s+'")'  ],
#           [ 1, '\\626purple'  ,'cmd.color("purple","'+s+'")'  ],
#           [ 1, '\\266teal'  ,'cmd.color("teal","'+s+'")'  ],
#           [ 1, '\\151forest'  ,'cmd.color("forest","'+s+'")'  ],
#           [ 1, '\\611firebrick'   , 'cmd.color("firebrick","'+s+'")'  ],
#           [ 1, '\\631chocolate'   , 'cmd.color("chocolate","'+s+'")'  ],
           [ 1, '\\116density'     ,'cmd.color("density","'+s+'")'  ],
           [ 1, '\\999white'       ,'cmd.color("white","'+s+'")'  ],
           [ 1, '\\987wheat'       , 'cmd.color("wheat","'+s+'")'   ],
           [ 1, '\\555grey'    ,'cmd.color("grey","'+s+'")'  ],
           [ 1, '\\222black'    ,'cmd.color("grey","'+s+'")'  ]
           ]

def preset_ligand_sites(s):
   return [[ 2, 'Ligand Sites:', ''],
           [ 1, 'solid'   , 'preset.ligand_sites("'+s+'")'          ],
           [ 1, 'solid (better)'   , 'preset.ligand_sites_hq("'+s+'")'          ],
           [ 0, '', ''],
           [ 1, 'transparent'   , 'preset.ligand_sites_trans("'+s+'")'          ],
           [ 1, 'transparent (better)'   , 'preset.ligand_sites_trans_hq("'+s+'")'          ],
           [ 0, '', ''],
           [ 1, 'dot surface'   , 'preset.ligand_sites_dots("'+s+'")'          ],
           [ 0, '', ''],
           [ 1, 'mesh surface'   , 'preset.ligand_sites_mesh("'+s+'")'          ]]

def presets(s):
   return [[ 2, 'Preset:'       ,''                        ],     
           [ 1, 'simple'   ,'preset.simple("'+s+'")'          ],
           [ 1, 'simple (no solvent)'   ,'preset.simple_no_solv("'+s+'")'          ],           
           [ 1, 'technical'   , 'preset.technical("'+s+'")'          ],
           [ 1, 'ligands'   , 'preset.ligands("'+s+'")'          ],
           [ 1, 'ligand_sites'   , preset_ligand_sites(s)         ],
           [ 1, 'pretty ', 'preset.pretty("'+s+'")'          ],
           [ 1, 'pretty (with solvent)'     , 'preset.pretty_solv("'+s+'")'          ],
           [ 1, 'publication '   , 'preset.publication("'+s+'")'          ],
           [ 1, 'publication (with solvent)'   , 'preset.pub_solv("'+s+'")'          ],
           [ 0, ''               ,''                             ],                      
           [ 1, 'default'   ,'preset.default("'+s+'")'          ],           
           ]

#def hydrogens(s):
#   return [[ 2, 'Hydrogens:'       ,''                        ],     
#           [ 1, 'add'   ,'cmd.h_add("'+s+'")'          ],           
#           [ 1, 'remove'   ,'cmd.remove("('+s+') and hydro")'          ],
#           ]

def state(s):
   return [[ 2, 'State:'       ,''                        ],
           [ 1, 'freeze'  ,'cmd.set("state",cmd.get_state(),"'+s+'")'        ],
           [ 1, 'thaw'  ,'cmd.set("state",0,"'+s+'")'        ],           
           ]
   
def movement(s):
   return [[ 2, 'Movement:'       ,''                        ],     
           [ 1, 'protect'   ,'cmd.protect("'+s+'")'          ],
           [ 1, 'deprotect'   ,'cmd.deprotect("'+s+'")'          ],           
           ]
   
def selection(s):
   return [[ 2, 'Selection:'       ,''                        ],     
           [ 1, 'mask'   ,'cmd.mask("'+s+'")'          ],
           [ 1, 'unmask'   ,'cmd.unmask("'+s+'")'          ],           
           ]

def compute(s):
   return [[ 2, 'Compute:'       ,''                        ],     
           [ 1, 'atom count'   ,'cmd.count_atoms("'+s+'",quiet=0)'          ],
           [ 0, ''               ,''                             ],           
           [ 1, 'formal charge sum'   ,'util.sum_formal_charges("'+s+'",quiet=0)'          ],
           [ 1, 'partial charges sum'   ,'util.sum_partial_charges("'+s+'",quiet=0)'          ],                      
           ]

def vacuum(s):
   return [[ 2, 'Vacuum Electrostatics:'       ,''                        ],
           [ 2, '\\955WARNING:\\595 Unvalidated and experimental code!', '' ],
           [ 1, 'protein surface potential (absolute)', 'util.protein_vacuum_esp("'+s+'",quiet=0)'          ],
           [ 1, 'protein surface potential (relative)', 'util.protein_vacuum_esp("'+s+'",absolute=0,quiet=0)'          ],
           [ 2, '\\955NOTE:\\559 Due to absence of solvent dielectric', ''],
           [ 2, '\\559"screening", vacuum electrostatic potentials', ''],
           [ 2, '\\559for macromolecules are only qualitatively', ''],
           [ 2, '\\559meaningful.  Please view with skepticism!', '' ],
           ]
   
def mol_assign(s):
   return [[ 2, 'Assign:'       ,''                        ],     
           [ 1, 'Amber 99 atomic properties',  'util.assign_amber99("'+s+'")' ],
           ]
   
def mol_generate(s):
   return [[ 2, 'Generate:'       ,''                        ],
           [ 1, 'vacuum electrostatics', vacuum(s) ],           
#           [ 1, 'assign', mol_assign(s) ],
           ]
   
def invert(s):
   return [[ 2, 'Invert:'       ,''                        ],     
           [ 1, 'within object(s)'     ,'cmd.select("'+s+'","((byobj '+s+') and not '+s+')",show=1)'    ],
           [ 1, 'within segments(s)'     ,'cmd.select("'+s+'","((byseg '+s+') and not '+s+')",show=1)'    ],           
           [ 1, 'within chains(s)'     ,'cmd.select("'+s+'","((bychain '+s+') and not '+s+')",show=1)'    ],
           [ 1, 'within residues(s)'   ,'cmd.select("'+s+'","((byres '+s+') and not '+s+')",show=1)'    ],                      
           [ 0, ''               ,''                             ],
           [ 1, 'within molecule(s)'     ,'cmd.select("'+s+'","((bymol '+s+') and not '+s+')",show=1)'    ],
           [ 0, ''               ,''                             ],
           [ 1, 'within any'     ,'cmd.select("'+s+'","(not '+s+')",show=1)'    ],
           ]

def complete(s):
   return [[ 2, 'Complete:'       ,''                        ],     

           [ 1, 'resides'  ,'cmd.select("'+s+'","(byres '+s+')",show=1)'      ],
           [ 1, 'chains'  ,'cmd.select("'+s+'","(bychain '+s+')",show=1)'      ],
           [ 1, 'segments'  ,'cmd.select("'+s+'","(byseg '+s+')",show=1)'      ],
           [ 1, 'objects'  ,'cmd.select("'+s+'","(byobj '+s+')",show=1)'      ],
           [ 0, ''               ,''                             ],           
           [ 1, 'molecules'  ,'cmd.select("'+s+'","(bymol '+s+')",show=1)'      ],
           [ 0, ''               ,''                             ],
           [ 1, 'C-alphas'  ,'cmd.select("'+s+'","(bycalpha '+s+')",show=1)'      ],           
           ]

def expand(s):
   return [[ 2, 'Expand:'       ,''                        ],     
           [ 1, 'by 4 A'  ,'cmd.select("'+s+'","('+s+' expand 4)",show=1)' ],
           [ 1, 'by 6 A'  ,'cmd.select("'+s+'","('+s+' expand 6)",show=1)' ],           
           [ 1, 'by 8 A'  ,'cmd.select("'+s+'","('+s+' expand 8)",show=1)' ],
           [ 1, 'by 12 A'  ,'cmd.select("'+s+'","('+s+' expand 12)",show=1)' ],
           [ 1, 'by 16 A'  ,'cmd.select("'+s+'","('+s+' expand 16)",show=1)' ],
           [ 1, 'by 20 A'  ,'cmd.select("'+s+'","('+s+' expand 20)",show=1)' ],           
           [ 0, ''               ,''                             ],
           [ 1, 'by 4 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 4))",show=1)' ],
           [ 1, 'by 6 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 6))",show=1)' ],
           [ 1, 'by 8 A, residues'   ,'cmd.select("'+s+'","(byres ('+s+' expand 8))",show=1)' ],
           [ 1, 'by 12 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 12))",show=1)' ],
           [ 1, 'by 16 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 16))",show=1)' ],
           [ 1, 'by 20 A, residues'  ,'cmd.select("'+s+'","(byres ('+s+' expand 20))",show=1)' ],
           ]

def around(s):
   return [[ 2, 'Around:'       ,''                        ],     
           [ 1, 'atoms within 4 A'  ,'cmd.select("'+s+'","('+s+' around 4)",show=1)' ],
           [ 1, 'atoms within 6 A'  ,'cmd.select("'+s+'","('+s+' around 6)",show=1)' ],           
           [ 1, 'atoms within 8 A'  ,'cmd.select("'+s+'","('+s+' around 8)",show=1)' ],
           [ 1, 'atoms within 12 A'  ,'cmd.select("'+s+'","('+s+' around 12)",show=1)' ],
           [ 1, 'atoms within 16 A'  ,'cmd.select("'+s+'","('+s+' around 16)",show=1)' ],
           [ 1, 'atoms within 20 A'  ,'cmd.select("'+s+'","('+s+' around 20)",show=1)' ],                      
           [ 0, ''               ,''                             ],           
           [ 1, 'residues within 4 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 4))",show=1)' ],
           [ 1, 'residues within 6 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 6))",show=1)' ],
           [ 1, 'residues within 8 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 8))",show=1)' ],
           [ 1, 'residues within 16 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 12))",show=1)' ],
           [ 1, 'residues within 20 A'  ,'cmd.select("'+s+'","(byres ('+s+' around 20))",show=1)' ],                                 
           ]
   
def extend(s):
   return [[ 2, 'Extend:'       ,''                        ],     
           [ 1, 'by 1 bond'  ,'cmd.select("'+s+'","('+s+' extend 1)",show=1)' ],
           [ 1, 'by 2 bonds'  ,'cmd.select("'+s+'","('+s+' extend 2)",show=1)' ],           
           [ 1, 'by 3 bonds'  ,'cmd.select("'+s+'","('+s+' extend 3)",show=1)' ],
           [ 1, 'by 4 bonds'  ,'cmd.select("'+s+'","('+s+' extend 4)",show=1)' ],
           [ 1, 'by 5 bonds'  ,'cmd.select("'+s+'","('+s+' extend 5)",show=1)' ],
           [ 1, 'by 6 bonds'  ,'cmd.select("'+s+'","('+s+' extend 6)",show=1)' ],           
           [ 0, ''               ,''                             ],
           [ 1, 'by 1 bond, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 1))",show=1)' ],
           [ 1, 'by 2 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 2))",show=1)' ],
           [ 1, 'by 3 bonds, residues'   ,'cmd.select("'+s+'","(byres ('+s+' extend 3))",show=1)' ],
           [ 1, 'by 4 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 4))",show=1)' ],
           [ 1, 'by 5 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 5))",show=1)' ],
           [ 1, 'by 6 bonds, residues'  ,'cmd.select("'+s+'","(byres ('+s+' extend 6))",show=1)' ],
           ]

def sele_action(s):
   return [[ 2, 'Actions:'       ,''                        ],     
           [ 1, 'delete selection', 'cmd.delete("'+s+'")'          ],
           [ 1, 'rename selection', 'cmd.wizard("renaming","'+s+'")'          ],
           [ 0, ''               ,''                             ],
           [ 1, 'zoom'           ,'cmd.zoom("'+s+'")'            ],
           [ 1, 'center'         ,'cmd.center("'+s+'")'            ],           
           [ 1, 'origin'         ,'cmd.origin("'+s+'")'          ],
           [ 1, 'orient'         ,'cmd.orient("'+s+'")'          ],
           [ 0, ''               ,''                             ],
           [ 1, 'preset'         ,presets(s)         ],
           [ 0, ''               ,''                             ],
           [ 1, 'remove atoms'   ,'cmd.remove("'+s+'");cmd.delete("'+s+'")'          ],
           [ 0, ''               ,''                             ],
           [ 1, 'around'         , around(s)         ],           
           [ 1, 'expand'         , expand(s)         ],
           [ 1, 'extend'         , extend(s)         ],
           [ 1, 'invert'         , invert(s)         ],
           [ 1, 'complete'       , complete(s)         ],
           [ 0, ''          ,''                                              ],
           [ 1, 'duplicate selection'      ,'cmd.select("'+s+'")'          ],
           [ 1, 'create object'  ,'cmd.create(None,"'+s+'")'     ],           
           [ 1, 'find polar contacts'  ,
             'cmd.dist("'+s+'_polar_conts","'+s+'","'+s+'",quiet=1,mode=2,labels=0)'
             ],                      
           [ 0, ''          ,''                                  ],
           [ 1, 'selection'      , selection(s)         ],           
           [ 1, 'movement'       , movement(s)         ],
           [ 1, 'compute'        , compute(s)         ],           
           ]


def mol_action(s):
   return [[ 2, 'Actions:'     , ''                       ],     
           [ 1, 'zoom'         , 'cmd.zoom("'+s+'")'      ],
           [ 1, 'center'         ,'cmd.center("'+s+'")'            ],
           [ 1, 'origin'       , 'cmd.origin("'+s+'")'    ],
           [ 1, 'orient'       , 'cmd.orient("'+s+'")'    ],
           [ 0, ''          ,''                                              ],
           [ 1, 'preset'  , presets(s)       ],
           [ 0, ''          ,''                                              ],           
           [ 1, 'generate'  , mol_generate(s)       ],           
           [ 0, ''               ,''                             ],
           [ 1, 'assign sec. struc.'  ,'cmd.dss("'+s+'")'        ],
           [ 1, 'find polar contacts'  ,
             'cmd.dist("'+s+'_polar_conts","'+s+'","'+s+'",quiet=1,mode=2,labels=0)'
             ],                      
           [ 0, ''             , ''                       ],
           [ 1, 'rename object', 'cmd.wizard("renaming","'+s+'")'          ],
           [ 1, 'duplicate object'    ,'cmd.create(None,"'+s+'")'     ],           
           [ 1, 'delete object'       , 'cmd.delete("'+s+'")'    ],
           [ 0, ''          ,''                                              ],
           [ 1, 'add hydrogens'  ,'cmd.h_add("'+s+'")'     ],           
           [ 1, 'remove hydrogens'  ,'cmd.remove("(hydro and ('+s+'))")'     ],           
           [ 1, 'remove waters'  ,'cmd.remove("(resn HOH+WAT and ('+s+'))")'     ],
           [ 0, ''          ,''                                              ],
           [ 1, 'state'      , state(s)         ],                      
           [ 1, 'selection'      , selection(s)         ],           
           [ 1, 'movement'       , movement(s)         ],           
           [ 1, 'compute'        , compute(s)         ],
           ]

def simple_action(s):
   return [[ 2, 'Actions:'     , ''                       ],
           [ 1, 'zoom'         , 'cmd.zoom("'+s+'")'      ],
           [ 1, 'center'       , 'cmd.center("'+s+'")'    ],           
           [ 1, 'origin'       , 'cmd.origin("'+s+'")'    ],
           [ 0, ''             , ''                       ],
           [ 1, 'delete'       , 'cmd.delete("'+s+'")'    ],
           ]

def test1(s):
      return [[ 2, 'Test1:'     , ''                      ],     
           [ 1, 'zoom'         , 'cmd.zoom("all")'     ],
           [ 1, 'center'   , 'cmd.center("all")'   ],           
           [ 1, 'origin'   , 'cmd.origin("all")'   ],
           ]

def test2(s):
      return [[ 2, 'Test2:'     , ''                      ],     
           [ 1, 'zoom'         , 'cmd.zoom("all")'     ],
           [ 1, 'center'   , 'cmd.center("all")'   ],           
           [ 1, 'origin'   , 'cmd.origin("all")'   ],
           ]

def all_action(s):
   return [[ 2, 'Actions:'     , ''                      ],     
           [ 1, 'zoom'         , 'cmd.zoom("all")'     ],
           [ 1, 'center'   , 'cmd.center("all")'   ],           
           [ 1, 'origin'   , 'cmd.origin("all")'   ],
           [ 0, ''             , ''                      ],           
           [ 1, 'preset'  , presets(s)     ],           
           [ 0, ''             , ''                      ],           
           [ 1, 'delete everything'  , 'cmd.delete("all")'     ],           
           [ 0, ''          ,''                                              ],
           [ 1, 'add hydrogens' ,'cmd.h_add("'+s+'")'     ],           
           [ 1, 'remove hydrogens'  ,'cmd.remove("(elem h and ('+s+'))")'     ],
           [ 1, 'remove waters'  ,'cmd.remove("(resn HOH+WAT and ('+s+'))")'     ],                      
           [ 0, ''          ,''                                              ],
           [ 1, 'selection'      , selection(s)         ],                      
           [ 1, 'movement'       , movement(s)         ],
           [ 1, 'compute'        , compute(s)         ],                      
           ]


def mol_labels(s):
   return [[ 2, 'Labels:'        , ''                                  ],
           [ 1, 'clear'          , 'cmd.label("'+s+'","\'\'")'         ],
           [ 0, ''               , ''                                  ],
           [ 1, 'residues'       ,
  """cmd.label('''(name ca+C1*+C1' and (byres("""+s+""")))''','''"%s-%s"%(resn,resi)''')"""  ],
           [ 1, 'chains'       ,   'util.label_chains("'+s+'")'  ],
           [ 1, 'segments'       ,   'util.label_segments("'+s+'")'  ],           
           [ 0, ''               , ''                                  ],           
           [ 1, 'atom name'      , 'cmd.label("'+s+'","name")'         ],
           [ 1, 'element symbol' , 'cmd.label("'+s+'","elem")'         ],           
           [ 1, 'residue name'  , 'cmd.label("'+s+'","resn")'         ],
           [ 1, 'residue identifier'    , 'cmd.label("'+s+'","resi")'         ],
           [ 1, 'chain identifier' , 'cmd.label("'+s+'","chain")'         ],
           [ 1, 'segment identifier'       , 'cmd.label("'+s+'","segi")'         ],           
           [ 0, ''               , ''                                  ],
           [ 1, 'b-factor'       , 'cmd.label("'+s+'","\'%1.2f\'%b")'  ],
           [ 1, 'occupancy'       , 'cmd.label("'+s+'","\'%1.2f\'%q")'  ],
           [ 1, 'vdw radius'       , 'cmd.label("'+s+'","\'%1.2f\'%vdw")'  ],
           [ 0, ''               , ''                                  ],
           [ 1, 'partial charge(.2f)' ,            
  'cmd.label("'+s+'","\'%.2f\'%partial_charge")'                      ],
           [ 1, 'partial charge(.4f)' , 
  'cmd.label("'+s+'","\'%.4f\'%partial_charge")'                      ],
           [ 1, 'formal charge' , 
  'cmd.label("'+s+'","\'%d\'%formal_charge")'                      ],
           [ 1, 'bohr radius'       , 'cmd.label("'+s+'","\'%1.2f\'%bohr")'  ],                                 
           [ 0, ''               , ''                                  ],
           [ 1, 'text type'      , 'cmd.label("'+s+'","text_type")'    ],
           [ 1, 'numeric type'   , 'cmd.label("'+s+'","numeric_type")' ],
           [ 0, ''               , ''                                  ],      
           [ 1, 'atom i.d.'             , 'cmd.label("'+s+'","id")' ],
           [ 1, 'atom i.d.(+1)'           , 'cmd.label("'+s+'","id+1")' ],
           ]


def mol_view(s):
   return [
      [ 1, 'zoom'           ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'           ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'           ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'           ,'cmd.orient("'+s+'")'            ],
      ]

def all_option(s):
   return [
      [ 2, '(all)'      , '' ],
      [ 1, 'show'      , mol_show(s) ],
      [ 1, 'hide'      , mol_hide(s) ],
      [ 1, 'color'      , mol_color(s) ],
      [ 1, 'view'      , mol_view(s) ],
      [ 1, 'preset'      , presets(s) ],
      [ 0, ''             , ''                      ],
      [ 1, 'zoom'           ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'           ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'           ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'           ,'cmd.orient("'+s+'")'            ],
      [ 0, ''             , ''                      ],
      [ 1, 'label'      , mol_labels(s) ],
      [ 0, '', '' ],
      [ 1, 'enable'         ,'cmd.enable("'+s+'")'            ],
      [ 1, 'disable'        ,'cmd.disable("'+s+'")'            ],
      ]

def enable_disable(enable):
   if enable:
      result = [[ 2, 'Enable', '' ]]
      cmmd = 'cmd.enable("'
   else:
      result = [[ 2, 'Disable', '']]
      cmmd = 'cmd.disable("'
   return result + map(lambda ob,cm=cmmd:[1,ob,cm+ob+'")'],['all']+cmd.get_names('objects'))
   
def main_menu():
   return [
      [ 2, 'Main Pop-Up'  , '' ],
      [ 1, 'zoom (vis)'           ,'cmd.zoom("visible")'            ],
      [ 1, 'center (vis)'           ,'cmd.center("visible")'            ],      
      [ 1, 'orient (vis)'           ,'cmd.orient("visible")'            ],
      [ 1, 'reset'           ,'cmd.reset()'            ],
      [ 0, ''             , ''                      ],           
      [ 1, '(all)'      , all_option("all") ],
      [ 1, '(visible)'      , all_option("visible") ],
      [ 0, ''             , ''                      ],
      [ 1, 'ray'           ,'cmd.ray()' ],
      [ 0, ''             , ''                      ],
      [ 1, 'enable', enable_disable(1) ],
      [ 1, 'disable', enable_disable(0) ],   
      [ 0, ''             , ''                      ],
      [ 1, 'delete all'           ,'cmd.delete("all")' ],
      [ 1, 'reinitialize'           ,'cmd.reinitialize()' ],
      [ 1, 'quit'           ,'cmd.quit()' ],
      ]

def pick_option(title,s,object=0):
   
   result = [
      [ 2, title, '' ],
      [ 1, 'color'      , mol_color(s) ],
      [ 1, 'show'      , mol_show(s) ],
      [ 1, 'hide'      , mol_hide(s) ],
      [ 1, 'preset'  , presets(s)       ],      
      [ 0, ''             , ''                      ],
      [ 1, 'zoom'           ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'           ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'           ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'           ,'cmd.orient("'+s+'")'            ],
      [ 1, 'indicate'        ,'cmd.indicate("'+s+'")'            ],
      [ 0, ''             , ''                      ],
      [ 1, 'labels'      , mol_labels(s) ],
      ]

# Edit dwkulp 6/11/05 , add a rotamer menu to residue menu
   if title == 'Residue':
	result.extend([[ 1, 'rotamers'    , rotamer_menu(s)]])

   if object:
      result.extend([
         [ 0, ''             , ''                      ],         
         [ 1, 'disable'        ,'cmd.disable("'+s+'")'            ],
         [ 0, ''             , ''                      ],
         [ 1, 'delete'        ,'cmd.delete("'+s+'")'            ]         
         ])
   else:
      result.extend([
      [ 0, ''             , ''                      ],      
      [ 1, 'create object','cmd.create(None,"'+s+'")'            ],      
      [ 0, ''             , ''                      ],
      [ 1, 'remove'      , 'cmd.remove("'+s+'")' ],     
                    ])
   return result

def pick_option_rev(title,s,object=0):
   result = pick_option(title,s,object)[1:]
   result.reverse()
   return result

def pick_menu(s1,s2):
   if s1[-1]=='`':
      title = s1[0:-1]
   else:
      title = s1
   return [[ 2, title     , '' ],
           [ 1, 'atom'    , pick_option("Atom",s2) ],
           [ 1, 'residue' , pick_option("Residue","(byres ("+s2+"))") ],
           [ 1, 'chain'   , pick_option("Chain","(bychain ("+s2+"))") ],
           [ 1, 'segment' , pick_option("Segment","(byseg ("+s2+"))") ],
           [ 1, 'object'  , pick_option("Object","(byobject ("+s2+"))",1) ],
           [ 0, ''             , ''                      ],
           [ 1, 'molecule', pick_option("Molecule","(bymol ("+s2+"))") ],
           [ 0, ''             , ''                      ],
           [ 1, 'fragment', pick_option("Fragment","(byfrag ("+s2+"))") ],
           [ 1, 'fragment+joint(s)', pick_option("Fragment","((byfrag ("+s2+")) extend 1)") ],
           ]
      
def seq_menu(s2,s3):
   
   return [[ 2, 'Sequence'    , '' ],
           [ 1, 'selection', pick_option('('+s3+')',s3) ],
           [ 0, ''             , ''                      ],
           [ 1, 'residue' , pick_option("Residue","(byres ("+s2+"))") ],
           [ 1, 'chain'   , pick_option("Chain","(bychain ("+s2+"))") ],
           [ 1, 'segment' , pick_option("Segment","(byseg ("+s2+"))") ],
           [ 1, 'object'  , pick_option("Object","(byobject ("+s2+"))",1) ],
           [ 0, ''             , ''                      ],
           [ 1, 'molecule', pick_option("Molecule","(bymol ("+s2+"))") ],
           [ 0, ''             , ''                      ],
           [ 1, 'C-alpha'    , pick_option("C-alpha",s2) ],
           ]
      

def seq_option(title,s,object=0):
   c=len(title)-1
   while title[c]!='/':
      c = c-1
   title = title[0:c+1]
   
   result = [
      [ 2, title, '' ],
      [ 1, 'color'      , mol_color(s) ],
      [ 1, 'show'      , mol_show(s) ],
      [ 1, 'hide'      , mol_hide(s) ],
      [ 1, 'preset'  , presets(s)       ],      
      [ 0, ''             , ''                      ],
      [ 1, 'zoom'           ,'cmd.zoom("'+s+'")'            ],
      [ 1, 'center'           ,'cmd.center("'+s+'")'            ],
      [ 1, 'origin'           ,'cmd.origin("'+s+'")'            ],
      [ 1, 'orient'           ,'cmd.orient("'+s+'")'            ],
      [ 1, 'indicate'        ,'cmd.indicate("'+s+'")'            ],
      [ 0, ''             , ''                      ],
      [ 1, 'labels'      , mol_labels(s) ],


      ]
   
   if object:
      result.extend([
         [ 0, ''             , ''                      ],         
         [ 1, 'disable'        ,'cmd.disable("'+s+'")'            ],
         [ 0, ''             , ''                      ],
         [ 1, 'delete'        ,'cmd.delete("'+s+'")'            ]         
         ])
   else:
      result.extend([
      [ 0, ''             , ''                      ],      
      [ 1, 'create object','cmd.create(None,"'+s+'")'            ],            
      [ 0, ''             , ''                      ],
      [ 1, 'remove'      , 'cmd.remove("'+s+'")' ],     
                    ])
   return result
   	

###############################################
# Dan Kulp
# Added Rotamer list to residue menu..
# rotamer.py must be importable (I placed it in 
# the same directory as menu.py)
###############################################

import rotamers


def rotamer_menu(s):
	# Check for rotamer library being loaded
	if not rotamers.rotdat:
	     return [ [2, "Must run rotamers.py first",'']]

	# Check for valid rotamer residue..
	res = cmd.get_model("byres ("+s+")").atom[0].resn
        if not res in rotamers.CHIS.keys():
	    return [ [2, "Residue: "+res+" not known sidechain or does not have rotamers", '']]

	# Get PHI,PSI bins for rotamer (also prints out current phi,psi, chi1,chi2,chi3,chi4)
	bins = rotamers.doRotamers(s,type='bins')

	# Add a title to the menu
	result = [ [2, bins[0]+' Rotamers in bin ('+str(bins[1])+','+str(bins[2])+')','' ], [1, ':::PROB,CHI1,CHI2,CHI3,CHI4:::','']]

        # Grab the entries for this residue and phi,psi bins
	match_rotamers = rotamers.rotdat[bins[0]+":"+str(bins[1])+":"+str(bins[2])]

	# Set max number of rotamers to display (probably should be somewhere 'higher up' in the code)
	max_rotamers = 10


	if len(match_rotamers) < max_rotamers:
	    max_rotamers = len(match_rotamers)

	# Create menu entry for each possible rotamer
        for item in range(0,max_rotamers):
             result.append( [ 1, str(match_rotamers[item]), 'rotamers.set_rotamer("'+s+'","'\
										    +str(match_rotamers[item][1])+'","'\
										    +str(match_rotamers[item][2])+'","'\
										    +str(match_rotamers[item][3])+'","'\
										    +str(match_rotamers[item][4])+'")'])
	return result