Difference between revisions of "ColorByDisplacement"

From PyMOLWiki
Jump to navigation Jump to search
Line 21: Line 21:
  
 
<gallery heights="300px" widths="300px">
 
<gallery heights="300px" widths="300px">
Image:ColorByRMSD_1cbs_1hmt.png|1cbs and 1hmt aligned and colored by RMSD.  Dark blue is good alignment, higher deviations are in orange/yellow/red. Residues not used for alignment are colored white.
+
Image:ColorByDisplacement-CA-1.png|ColorByDisplacementCA used on 1HP1 and 1HPU aligned and colored by distance displacement.  Dark blue is low displacement, higher displacements are in orange/yellow/red. Residues not used for alignment should be colored white.
Image:ColorByRMSD_1eaz_1fao.png|1eaz and 1fao aligned and colored by RMSD.  Dark blue is good alignment, higher deviations are in orange/yellow/red. Residues not used for alignment are colored white.
+
Image:ColorByDisplacement-CA-2.png|ColorByDisplacementCA used on 1HP1 and 1HPU aligned and colored by distance displacement.  Dark blue is low displacement, higher displacements are in orange/yellow/red. Residues not used for alignment should be colored white.
 +
Image:ColorByDisplacement-All-1.png|ColorByDisplacementAll used on 1HP1 and 1HPU aligned and colored by distance displacement.  Dark blue is low displacement, higher displacements are in orange/yellow/red. Residues not used for alignment should be colored white.
 +
Image:ColorByDisplacement-All-2.png|ColorByDisplacementAll used on 1HP1 and 1HPU aligned and colored by distance displacement.  Dark blue is low displacement, higher displacements are in orange/yellow/red. Residues not used for alignment should be colored white.
 
</gallery>
 
</gallery>
  
 
<source lang="python">
 
<source lang="python">
 +
import pymol
 +
import cmd
 +
from pymol import stored
 +
 +
### Thanks for inspiration from:
 
"""
 
"""
--- ColorByRMSD: RMSD based coloring ---  
+
--- ColorByRMSD: RMSD based coloring ---
 
Authors : Shivender Shandilya; Jason Vertrees
 
Authors : Shivender Shandilya; Jason Vertrees
 
Program : ColorByRMSD
 
Program : ColorByRMSD
 
Date    : July 2009
 
Date    : July 2009
Version : 0.1.1
+
http://www.pymolwiki.org/index.php/ColorByRMSD
Mail    : firstname.lastname@umassmed.edu
 
 
Keywords: color rms rmsd colorbyrms colorbyrmsd
 
----------------------------------------------------------------------
 
Reference:
 
This email from Warren - http://www.mail-archive.com/pymol-users@lists.sourceforge.net/msg07078.html
 
Literature:
 
DeLano, W.L. The PyMOL Molecular Graphics System (2002) DeLano Scientific, San Carlos, CA, USA. http://www.pymol.org
 
----------------------------------------------------------------------
 
 
"""
 
"""
+
### Author Troels Linnet - troels.linnet att bbz.uni-leipzig.de
import pymol
+
"""
import cmd
+
--- ColorByDisplacementCA: Displacement based coloring ---
from pymol import stored
+
Authors : Troels E. Linnet
+
Program : ColorByDisplacementCA
def strTrue(p):
+
Date    : January 2011
    return p[0].upper() == "T"
+
email: troels.linnet att bbz.uni-leipzig.de
+
"""
# The main function that assigns current RMSD as the new B-factor
+
 
def rmsUpdateB(objA, alnAri, objB, alnBri):
+
"""
    for x in range(len(alnAri)):
+
     ColorByDisplacementCA --
        s1 = objA + " and n. CA and i. " + alnAri[x]
+
Show the distance displacement deviation in color to more easily see variable regions.
        s2 = objB + " and n. CA and i. " + alnBri[x]
+
 
        rmsd = cmd.rms_cur(s1, s2, matchmaker=4)
 
        cmd.alter( s1, "b = " + str(rmsd))
 
        cmd.alter( s2, "b = " + str(rmsd))
 
    cmd.sort(objA); cmd.sort(objB)
 
 
 
def colorByRMSD(objSel1, objSel2, doAlign="True", doPretty=None):
 
    """
 
     colorByRMSD -- align two structures and show the structural deviations
 
                  in color to more easily see variable regions.
 
 
 
     PARAMS
 
     PARAMS
+
 
 
         objSel1 (valid PyMOL object or selection)
 
         objSel1 (valid PyMOL object or selection)
             The first object to align. 
+
             The first object
+
 
 
         objSel2 (valid PyMOL object or selection)
 
         objSel2 (valid PyMOL object or selection)
             The second object to align
+
             The second object
+
 
         doAlign (boolean, either True or False)
+
         doColor (boolean, either True or False)
            Should this script align your proteins or just leave them as is?
+
             If doColor=True then a simple representation is created to
            If doAlign=True then your original proteins are aligned.
 
            If False, then they are not. Regardless, the B-factors are changed.
 
            DEFAULT: True
 
 
        doPretty (boolean, either True or False)
 
             If doPretty=True then a simple representation is created to
 
 
             highlight the differences.  If False, then no changes are made.
 
             highlight the differences.  If False, then no changes are made.
 
             DEFAULT: False
 
             DEFAULT: False
+
 
 
     RETURNS
 
     RETURNS
 
         None.
 
         None.
+
 
 
     SIDE-EFFECTS
 
     SIDE-EFFECTS
 
         Modifies the B-factor columns in your original structures.
 
         Modifies the B-factor columns in your original structures.
+
 
     """
+
"""
     # First create backup copies; names starting with __ (underscores) are
+
 
    # normally hidden by PyMOL
+
def strTrue(p):
 +
    return p[0].upper() == "T"
 +
 
 +
# The main function that assigns current displacement distance as the new B-factor
 +
def displacementUpdateB(objA, alnAri, objB, alnBri):
 +
    ### If residue is unassigned in one of the pdb files, we reset its value
 +
    for x in range(len(alnAri)):
 +
        s1 = objA + " and name CA and resi " + alnAri[x]
 +
cmd.alter( s1, "b = " + str(-0.01))
 +
     for x in range(len(alnBri)):
 +
s2 = objB + " and name CA and resi " + alnBri[x]
 +
        cmd.alter( s2, "b = " + str(-0.01))
 +
    cmd.sort(objA); cmd.sort(objB)
 +
     for x in range(len(alnAri)):
 +
        s1 = objA + " and name CA and resi " + alnAri[x]
 +
s2 = objB + " and name CA and resi " + alnAri[x]
 +
### Names starting with __ (underscores) are normally hidden by PyMOL
 +
tempObject = "__tempObject"
 +
Displacement = cmd.distance(tempObject, s1, s2)
 +
cmd.alter( s1, "b = " + str(Displacement))
 +
        cmd.alter( s2, "b = " + str(Displacement))
 +
cmd.delete(tempObject)
 +
    cmd.sort(objA); cmd.sort(objB)
 +
 
 +
def ColorByDisplacementCA(objSel1, objSel2, super1='all', super2='all', doColor="True", doAlign="True"):
 +
    AlignedWhite='no'
 +
    ### First create backup copies; names starting with __ (underscores) are normally hidden by PyMOL
 
     tObj1, tObj2, aln = "__tempObj1", "__tempObj2", "__aln"
 
     tObj1, tObj2, aln = "__tempObj1", "__tempObj2", "__aln"
+
 
 
     if strTrue(doAlign):
 
     if strTrue(doAlign):
         # perform the alignment
+
         ### Create temp objects
 
         cmd.create( tObj1, objSel1 )
 
         cmd.create( tObj1, objSel1 )
 
         cmd.create( tObj2, objSel2 )
 
         cmd.create( tObj2, objSel2 )
         cmd.super( tObj1, tObj2, object=aln )
+
### Align and make create an object aln which indicates which atoms were paired between the two structures
 +
### Super is must faster than align http://www.pymolwiki.org/index.php/Super
 +
         cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)
 +
### Modify the original matrix of object1 from the alignment
 
         cmd.matrix_copy(tObj1, objSel1)
 
         cmd.matrix_copy(tObj1, objSel1)
 
     else:
 
     else:
         # perform the alignment
+
         ### Create temp objects
 
         cmd.create( tObj1, objSel1 )
 
         cmd.create( tObj1, objSel1 )
 
         cmd.create( tObj2, objSel2 )
 
         cmd.create( tObj2, objSel2 )
         cmd.super( tObj1, tObj2, object=aln )
+
### Align and make create an object aln which indicates which atoms were paired between the two structures
+
### Super is must faster than align http://www.pymolwiki.org/index.php/Super
     # Modify the B-factor columns of the original objects,
+
         cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)
     # in order to identify the residues NOT used for alignment, later on
+
 
     cmd.alter( objSel1 + " or " + objSel2, "b=-10")
+
     ### Modify the B-factor columns of the original objects,
 +
     ### in order to identify the residues NOT used for alignment, later on
 +
     cmd.alter( objSel1 + " or " + objSel2, "b=-0.2")
 
     cmd.alter( tObj1 + " or " + tObj2, "chain='A'")
 
     cmd.alter( tObj1 + " or " + tObj2, "chain='A'")
 
     cmd.alter( tObj1 + " or " + tObj2, "segi='A'")
 
     cmd.alter( tObj1 + " or " + tObj2, "segi='A'")
+
 
     # Update pymol internal representations; one of these should do the trick
+
     ### Update pymol internal representations; one of these should do the trick
 
     cmd.refresh(); cmd.rebuild(); cmd.sort(tObj1); cmd.sort(tObj2)
 
     cmd.refresh(); cmd.rebuild(); cmd.sort(tObj1); cmd.sort(tObj2)
+
 
     #  Create lists for storage
+
     ###  Create lists for storage
 
     stored.alnAres, stored.alnBres = [], []
 
     stored.alnAres, stored.alnBres = [], []
+
 
     # Get the residue identifiers from the alignment object "aln"
+
     ### Iterate over objects
     cmd.iterate(tObj1 + " and n. CA and " + aln, "stored.alnAres.append(resi)")
+
     if AlignedWhite=='yes':
    cmd.iterate(tObj2 + " and n. CA and " + aln, "stored.alnBres.append(resi)")
+
        cmd.iterate(tObj1 + " and n. CA and not " + aln, "stored.alnAres.append(resi)")
+
cmd.iterate(tObj2 + " and n. CA and not " + aln, "stored.alnBres.append(resi)")
     # Change the B-factors for EACH object
+
    else:
     rmsUpdateB(tObj1,stored.alnAres,tObj2,stored.alnBres)
+
cmd.iterate(tObj1 + " and n. CA", "stored.alnAres.append(resi)")
+
        cmd.iterate(tObj2 + " and n. CA", "stored.alnBres.append(resi)")
     # Store the NEW B-factors
+
 
 +
     ### Change the B-factors for EACH object
 +
     displacementUpdateB(tObj1,stored.alnAres,tObj2,stored.alnBres)
 +
 
 +
     ### Store the NEW B-factors
 
     stored.alnAnb, stored.alnBnb = [], []
 
     stored.alnAnb, stored.alnBnb = [], []
     cmd.iterate(tObj1 + " and n. CA and " + aln, "stored.alnAnb.append(b)" )
+
     ### Iterate over objects and get b
    cmd.iterate(tObj2 + " and n. CA and " + aln, "stored.alnBnb.append(b)" )
+
    ### Iterate over objects which is not aligned
+
    if AlignedWhite=='yes':
     # Get rid of all intermediate objects and clean up
+
    cmd.iterate(tObj1 + " and n. CA and not " + aln, "stored.alnAnb.append(b)" )
 +
cmd.iterate(tObj2 + " and n. CA and not " + aln, "stored.alnBnb.append(b)" )
 +
    else:
 +
    cmd.iterate(tObj1 + " and n. CA", "stored.alnAnb.append(b)" )
 +
    cmd.iterate(tObj2 + " and n. CA", "stored.alnBnb.append(b)" )
 +
 
 +
     ### Get rid of all intermediate objects and clean up
 
     cmd.delete(tObj1)
 
     cmd.delete(tObj1)
 
     cmd.delete(tObj2)
 
     cmd.delete(tObj2)
 
     cmd.delete(aln)
 
     cmd.delete(aln)
+
 
     # Assign the just stored NEW B-factors to the original objects
+
     ### Assign the just stored NEW B-factors to the original objects
 
     for x in range(len(stored.alnAres)):
 
     for x in range(len(stored.alnAres)):
 
         cmd.alter(objSel1 + " and n. CA and i. " + str(stored.alnAres[x]), "b = " + str(stored.alnAnb[x]))
 
         cmd.alter(objSel1 + " and n. CA and i. " + str(stored.alnAres[x]), "b = " + str(stored.alnAnb[x]))
Line 144: Line 166:
 
     cmd.rebuild(); cmd.refresh(); cmd.sort(objSel1); cmd.sort(objSel2)
 
     cmd.rebuild(); cmd.refresh(); cmd.sort(objSel1); cmd.sort(objSel2)
  
     # Provide some useful information
+
     ### Provide some useful information
 
     stored.allRMSDval = []
 
     stored.allRMSDval = []
 
     stored.allRMSDval = stored.alnAnb + stored.alnBnb
 
     stored.allRMSDval = stored.alnAnb + stored.alnBnb
     print "\nColorByRMSD completed successfully."
+
     print "\nColorByDisplacementCA completed successfully."
     print "The MINIMUM RMSD value is: "+str(min(stored.allRMSDval))
+
     print "The MAXIMUM Displacement is: "+str(max(stored.allRMSDval)) +" residue "+str(stored.alnAres[int(stored.allRMSDval.index(max(stored.allRMSDval)))])
    print "The MAXIMUM RMSD value is: "+str(max(stored.allRMSDval))
 
  
     if doPretty!=None:
+
     if strTrue(doColor):
         # Showcase what we did
+
         ### Showcase what we did
         cmd.orient()
+
         #cmd.orient()
         cmd.hide("all")
+
         #cmd.hide("all")
 
         cmd.show_as("cartoon", objSel1 + " or " + objSel2)
 
         cmd.show_as("cartoon", objSel1 + " or " + objSel2)
         # Select the residues not used for alignment; they still have their B-factors as "-10"
+
         ### Select the residues not used for alignment; they still have their B-factors as "-0.2"
         cmd.select("notUsedForAln", "b < 0")
+
         cmd.select("notUsedForAln", "br. b=-0.2")
         # White-wash the residues not used for alignment
+
         ### White-wash the residues not used for alignment
 
         cmd.color("white", "notUsedForAln")
 
         cmd.color("white", "notUsedForAln")
         # Color the residues used for alignment according to their B-factors (RMSD values)
+
         ### Select the residues not in both pdb files; they have their B-factors as "-0. 01"
        cmd.spectrum("b", 'rainbow',  "((" + objSel1 + " and n. CA) or (n. CA and " + objSel2 +" )) and not notUsedForAln")
+
        cmd.select("ResNotInBothPDB", "br. b=-0.01")
         # Delete the selection of atoms not used for alignment
+
        ### White-wash the residues not used for alignment
         # If you would like to keep this selection intact,
+
        cmd.color("black", "ResNotInBothPDB")
         # just comment "cmd.delete" line and
+
        ### Color the residues used for alignment according to their B-factors (Displacment values)
         # uncomment the "cmd.disable" line below.
+
cmd.spectrum("b", 'rainbow',  "(" + objSel1 + " and n. CA) or (n. CA and " + objSel2 +" ) and not (notUsedForAln and ResNotInBothPDB)")
 +
         ### Delete the selection of atoms not used for alignment
 +
         ### If you would like to keep this selection intact,
 +
         ### just comment "cmd.delete" line and
 +
         ### uncomment the "cmd.disable" line abowe.
 +
        cmd.disable("notUsedForAln")
 
         cmd.delete("notUsedForAln")
 
         cmd.delete("notUsedForAln")
         # cmd.disable("notUsedForAln")  
+
         cmd.disable("ResNotInBothPDB")
 +
        cmd.delete("ResNotInBothPDB")
  
         print "\nObjects are now colored by C-alpha RMS deviation."
+
         print "\nObjects are now colored by C-alpha displacement deviation."
         print "All residues with RMSD values greater than the maximum are colored white..."
+
         print "Blue is minimum and red is maximum..."
+
        print "White is those residues used in the alignment algorithm"
cmd.extend("colorByRMSD", colorByRMSD)
+
print "Black is residues that does not exist in both files..."
 +
cmd.extend("ColorByDisplacementCA", ColorByDisplacementCA)
 +
 
 +
def displacementUpdateBAll(objA, alnAri, objB, alnBri):
 +
    AlignedWhite='no'
 +
    print "This will take a while to go through the for loops. Give me around 3-5 minutes..."
 +
    ### If residue is unassigned in one of the pdb files, we reset its value
 +
    for x in range(len(alnAri)):
 +
        s1 = objA + " and resi " + alnAri[x][0] + " and name " + str(alnAri[x][1])
 +
cmd.alter( s1, "b = " + str(-0.01))
 +
    for x in range(len(alnBri)):
 +
s2 = objB + " and resi " + alnBri[x][0] + " and name " + alnBri[x][1]
 +
        cmd.alter( s2, "b = " + str(-0.01))
 +
    cmd.sort(objA); cmd.sort(objB)
 +
    for x in range(len(alnAri)):
 +
        s1 = objA + " and resi " + alnAri[x][0] + " and name " + alnAri[x][1]
 +
s2 = objB + " and resi " + alnAri[x][0] + " and name " + alnAri[x][1]
 +
### Names starting with __ (underscores) are normally hidden by PyMOL
 +
tempObject = "__tempObject"
 +
Displacement = cmd.distance(tempObject, s1, s2)
 +
cmd.alter( s1, "b = " + str(Displacement))
 +
        cmd.alter( s2, "b = " + str(Displacement))
 +
cmd.delete(tempObject)
 +
    cmd.sort(objA); cmd.sort(objB)
 +
 
 +
def ColorByDisplacementAll(objSel1, objSel2, super1='all', super2='all', doColor="True", doAlign="True"):
 +
    AlignedWhite='yes'
 +
    ### First create backup copies; names starting with __ (underscores) are normally hidden by PyMOL
 +
    tObj1, tObj2, aln = "__tempObj1", "__tempObj2", "__aln"
 +
 
 +
    if strTrue(doAlign):
 +
        ### Create temp objects
 +
        cmd.create( tObj1, objSel1 )
 +
        cmd.create( tObj2, objSel2 )
 +
### Align and make create an object aln which indicates which atoms were paired between the two structures
 +
### Super is must faster than align http://www.pymolwiki.org/index.php/Super
 +
        cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)
 +
### Modify the original matrix of object1 from the alignment
 +
        cmd.matrix_copy(tObj1, objSel1)
 +
    else:
 +
        ### Create temp objects
 +
        cmd.create( tObj1, objSel1 )
 +
        cmd.create( tObj2, objSel2 )
 +
### Align and make create an object aln which indicates which atoms were paired between the two structures
 +
### Super is must faster than align http://www.pymolwiki.org/index.php/Super
 +
        cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)
 +
 
 +
    ### Modify the B-factor columns of the original objects,
 +
    ### in order to identify the residues NOT used for alignment, later on
 +
    cmd.alter( objSel1 + " or " + objSel2, "b=-0.2")
 +
    cmd.alter( tObj1 + " or " + tObj2, "chain='A'")
 +
    cmd.alter( tObj1 + " or " + tObj2, "segi='A'")
 +
 
 +
    ### Update pymol internal representations; one of these should do the trick
 +
    cmd.refresh(); cmd.rebuild(); cmd.sort(tObj1); cmd.sort(tObj2)
 +
 
 +
    ###  Create lists for storage
 +
    stored.alnAres, stored.alnBres = [], []
 +
 
 +
    ### Iterate over objects and get resi
 +
    if AlignedWhite=='yes':
 +
        cmd.iterate(tObj1 + " and not " + aln, "stored.alnAres.append((resi, name))")
 +
        cmd.iterate(tObj2 + " and not " + aln, "stored.alnBres.append((resi, name))")
 +
    else:
 +
        cmd.iterate(tObj1, "stored.alnAres.append((resi, name))")
 +
        cmd.iterate(tObj2, "stored.alnBres.append((resi, name))")
 +
 
 +
    ### Change the B-factors for EACH object
 +
    displacementUpdateBAll(tObj1,stored.alnAres,tObj2,stored.alnBres)
 +
 
 +
    ### Store the NEW B-factors
 +
    stored.alnAnb, stored.alnBnb = [], []
 +
    ### Iterate over objects and get b
 +
    ### Iterate over objects which is not aligned
 +
    if AlignedWhite=='yes':
 +
        cmd.iterate(tObj1 + " and not " + aln, "stored.alnAnb.append(b)" )
 +
        cmd.iterate(tObj2 + " and not " + aln, "stored.alnBnb.append(b)" )
 +
    else:
 +
        cmd.iterate(tObj1, "stored.alnAnb.append(b)" )
 +
        cmd.iterate(tObj2, "stored.alnBnb.append(b)" )
 +
 
 +
    ### Get rid of all intermediate objects and clean up
 +
    cmd.delete(tObj1)
 +
    cmd.delete(tObj2)
 +
    cmd.delete(aln)
 +
 
 +
    ### Assign the just stored NEW B-factors to the original objects
 +
    print "Sooon ready. 1 more minute"
 +
    for x in range(len(stored.alnAres)):
 +
        cmd.alter(objSel1 + " and resi " + str(stored.alnAres[x][0]) + " and name " + str(stored.alnAres[x][1]), "b = " + str(stored.alnAnb[x]))
 +
    for x in range(len(stored.alnBres)):
 +
        cmd.alter(objSel2 + " and resi " + str(stored.alnBres[x][0]) + " and name " + str(stored.alnBres[x][1]), "b = " + str(stored.alnBnb[x]))
 +
    cmd.rebuild(); cmd.refresh(); cmd.sort(objSel1); cmd.sort(objSel2)
 +
 
 +
    ### Provide some useful information
 +
    stored.allRMSDval = []
 +
    stored.allRMSDval = stored.alnAnb + stored.alnBnb
 +
    print "\nColorByDisplacementAll completed successfully."
 +
    print "The MAXIMUM Displacement is: "+str(max(stored.allRMSDval)) +" residue "+str(stored.alnAres[int(stored.allRMSDval.index(max(stored.allRMSDval)))])
 +
 
 +
    if strTrue(doColor):
 +
        ### Showcase what we did
 +
        #cmd.orient()
 +
        #cmd.hide("all")
 +
        cmd.show("sticks", objSel1 + " or " + objSel2)
 +
        ### Select the residues not used for alignment; they still have their B-factors as "-0.2"
 +
        cmd.select("notUsedForAln", "b=-0.2")
 +
        ### White-wash the residues not used for alignment
 +
        cmd.color("white", "notUsedForAln")
 +
        ### Select the residues not in both pdb files; they have their B-factors as "-0.01"
 +
        cmd.select("ResNotInBothPDB", "b=-0.01")
 +
        ### White-wash the residues not used for alignment
 +
        cmd.color("black", "ResNotInBothPDB")
 +
        ### Color the residues used for alignment according to their B-factors (Displacment values)
 +
        cmd.spectrum("b", 'rainbow',  "(" + objSel1 + ") or (" + objSel2 +" ) and not (notUsedForAln and ResNotInBothPDB)")
 +
        ### Delete the selection of atoms not used for alignment
 +
        ### If you would like to keep this selection intact,
 +
        ### just comment "cmd.delete" line and
 +
        ### uncomment the "cmd.disable" line abowe.
 +
        #cmd.disable("notUsedForAln")
 +
        cmd.delete("notUsedForAln")
 +
        #cmd.disable("ResNotInBothPDB")
 +
        cmd.delete("ResNotInBothPDB")
 +
        print "\nObjects are now colored by C-alpha displacement deviation."
 +
        print "Blue is minimum and red is maximum..."
 +
        print "White is those residues used in the alignment algorithm"
 +
print "Black is residues that does not exist in both files..."
 +
cmd.extend("ColorByDisplacementAll", ColorByDisplacementAll)
 
</source>
 
</source>
  
 
[[Category:Script_Library]]
 
[[Category:Script_Library]]
 
[[Category:Structural_Biology_Scripts]]
 
[[Category:Structural_Biology_Scripts]]

Revision as of 17:48, 5 January 2011

Acknowledgement

This script is based on the scaffold from ColorByRMSD. Peace love and harmomy goes to Shivender Shandilya and Jason Vertrees.

Introduction

This script allows you to color two structures by distance displacement between a Open and Closed form of a protein, as calculated by PyMol's internal distance command. The pairwise, C-alpha or all-atom. . The RMSD values are stored as B-factors of these residues, which are colored by a rainbow color spectrum, with blue specifying the minimum pairwise RMSD and red indicating the maximum. With uncommenting/commenting it is possible to make Residues NOT used by Super for superposition, and hence for distance displacement calculation, colored white.

Code

Please use this script with the option doColor=T to print the coloring. Do keep in mind, all original B-factors values are overwritten!

There exist two versions.
ColorByDisplacementCA is quick and is between CA atoms. Ideal for helices representation.
ColorByDisplacementAll is between All atoms in residues and is quite slow => 3-5 mins for a run. Ideal for sticks representation.


Examples

# example #1
ColorByDisplacementCA O5NT, C5NT, doColor=T, doAlign=T, super1=resi 26-355, super2=resi 26-355
ColorByDisplacementAll O5NT, C5NT, doColor=T, doAlign=T, super1=resi 26-355, super2=resi 26-355
import pymol
import cmd
from pymol import stored

### Thanks for inspiration from:
"""
--- ColorByRMSD: RMSD based coloring ---
Authors : Shivender Shandilya; Jason Vertrees
Program : ColorByRMSD
Date    : July 2009
http://www.pymolwiki.org/index.php/ColorByRMSD
"""
### Author Troels Linnet - troels.linnet att bbz.uni-leipzig.de
"""
--- ColorByDisplacementCA: Displacement based coloring ---
Authors : Troels E. Linnet
Program : ColorByDisplacementCA
Date    : January 2011
email: troels.linnet att bbz.uni-leipzig.de
"""

"""
    ColorByDisplacementCA --
	Show the distance displacement deviation in color to more easily see variable regions.

    PARAMS

        objSel1 (valid PyMOL object or selection)
            The first object

        objSel2 (valid PyMOL object or selection)
            The second object

        doColor (boolean, either True or False)
            If doColor=True then a simple representation is created to
            highlight the differences.  If False, then no changes are made.
            DEFAULT: False

    RETURNS
        None.

    SIDE-EFFECTS
        Modifies the B-factor columns in your original structures.

"""

def strTrue(p):
    return p[0].upper() == "T"

# The main function that assigns current displacement distance as the new B-factor
def displacementUpdateB(objA, alnAri, objB, alnBri):
    ### If residue is unassigned in one of the pdb files, we reset its value
    for x in range(len(alnAri)):
        s1 = objA + " and name CA and resi " + alnAri[x]
 	cmd.alter( s1, "b = " + str(-0.01))
    for x in range(len(alnBri)):
	s2 = objB + " and name CA and resi " + alnBri[x]
        cmd.alter( s2, "b = " + str(-0.01))
    cmd.sort(objA); cmd.sort(objB)
    for x in range(len(alnAri)):
        s1 = objA + " and name CA and resi " + alnAri[x]
	s2 = objB + " and name CA and resi " + alnAri[x]
	### Names starting with __ (underscores) are normally hidden by PyMOL
	tempObject = "__tempObject"
	Displacement = cmd.distance(tempObject, s1, s2)
 	cmd.alter( s1, "b = " + str(Displacement))
        cmd.alter( s2, "b = " + str(Displacement))
	cmd.delete(tempObject)
    cmd.sort(objA); cmd.sort(objB)

def ColorByDisplacementCA(objSel1, objSel2, super1='all', super2='all', doColor="True", doAlign="True"):
    AlignedWhite='no'
    ### First create backup copies; names starting with __ (underscores) are normally hidden by PyMOL
    tObj1, tObj2, aln = "__tempObj1", "__tempObj2", "__aln"

    if strTrue(doAlign):
        ### Create temp objects
        cmd.create( tObj1, objSel1 )
        cmd.create( tObj2, objSel2 )
	### Align and make create an object aln which indicates which atoms were paired between the two structures
	### Super is must faster than align http://www.pymolwiki.org/index.php/Super
        cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)
	### Modify the original matrix of object1 from the alignment
        cmd.matrix_copy(tObj1, objSel1)
    else:
        ### Create temp objects
        cmd.create( tObj1, objSel1 )
        cmd.create( tObj2, objSel2 )
	### Align and make create an object aln which indicates which atoms were paired between the two structures
	### Super is must faster than align http://www.pymolwiki.org/index.php/Super
        cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)

    ### Modify the B-factor columns of the original objects,
    ### in order to identify the residues NOT used for alignment, later on
    cmd.alter( objSel1 + " or " + objSel2, "b=-0.2")
    cmd.alter( tObj1 + " or " + tObj2, "chain='A'")
    cmd.alter( tObj1 + " or " + tObj2, "segi='A'")

    ### Update pymol internal representations; one of these should do the trick
    cmd.refresh(); cmd.rebuild(); cmd.sort(tObj1); cmd.sort(tObj2)

    ###  Create lists for storage
    stored.alnAres, stored.alnBres = [], []

    ### Iterate over objects
    if AlignedWhite=='yes':
        cmd.iterate(tObj1 + " and n. CA and not " + aln, "stored.alnAres.append(resi)")
	cmd.iterate(tObj2 + " and n. CA and not " + aln, "stored.alnBres.append(resi)")
    else:
	cmd.iterate(tObj1 + " and n. CA", "stored.alnAres.append(resi)")
        cmd.iterate(tObj2 + " and n. CA", "stored.alnBres.append(resi)")

    ### Change the B-factors for EACH object
    displacementUpdateB(tObj1,stored.alnAres,tObj2,stored.alnBres)

    ### Store the NEW B-factors
    stored.alnAnb, stored.alnBnb = [], []
    ### Iterate over objects and get b
    ### Iterate over objects which is not aligned
    if AlignedWhite=='yes':
    	cmd.iterate(tObj1 + " and n. CA and not " + aln, "stored.alnAnb.append(b)" )
	cmd.iterate(tObj2 + " and n. CA and not " + aln, "stored.alnBnb.append(b)" )
    else:
    	cmd.iterate(tObj1 + " and n. CA", "stored.alnAnb.append(b)" )
    	cmd.iterate(tObj2 + " and n. CA", "stored.alnBnb.append(b)" )

    ### Get rid of all intermediate objects and clean up
    cmd.delete(tObj1)
    cmd.delete(tObj2)
    cmd.delete(aln)

    ### Assign the just stored NEW B-factors to the original objects
    for x in range(len(stored.alnAres)):
        cmd.alter(objSel1 + " and n. CA and i. " + str(stored.alnAres[x]), "b = " + str(stored.alnAnb[x]))
    for x in range(len(stored.alnBres)):
        cmd.alter(objSel2 + " and n. CA and i. " + str(stored.alnBres[x]), "b = " + str(stored.alnBnb[x]))
    cmd.rebuild(); cmd.refresh(); cmd.sort(objSel1); cmd.sort(objSel2)

    ### Provide some useful information
    stored.allRMSDval = []
    stored.allRMSDval = stored.alnAnb + stored.alnBnb
    print "\nColorByDisplacementCA completed successfully."
    print "The MAXIMUM Displacement is: "+str(max(stored.allRMSDval)) +" residue "+str(stored.alnAres[int(stored.allRMSDval.index(max(stored.allRMSDval)))])

    if strTrue(doColor):
        ### Showcase what we did
        #cmd.orient()
        #cmd.hide("all")
        cmd.show_as("cartoon", objSel1 + " or " + objSel2)
        ### Select the residues not used for alignment; they still have their B-factors as "-0.2"
        cmd.select("notUsedForAln", "br. b=-0.2")
        ### White-wash the residues not used for alignment
        cmd.color("white", "notUsedForAln")
        ### Select the residues not in both pdb files; they have their B-factors as "-0. 01"
        cmd.select("ResNotInBothPDB", "br. b=-0.01")
        ### White-wash the residues not used for alignment
        cmd.color("black", "ResNotInBothPDB")
        ### Color the residues used for alignment according to their B-factors (Displacment values)
	cmd.spectrum("b", 'rainbow',  "(" + objSel1 + " and n. CA) or (n. CA and " + objSel2 +" ) and not (notUsedForAln and ResNotInBothPDB)")
        ### Delete the selection of atoms not used for alignment
        ### If you would like to keep this selection intact,
        ### just comment "cmd.delete" line and
        ### uncomment the "cmd.disable" line abowe.
        cmd.disable("notUsedForAln")
        cmd.delete("notUsedForAln")
        cmd.disable("ResNotInBothPDB")
        cmd.delete("ResNotInBothPDB")

        print "\nObjects are now colored by C-alpha displacement deviation."
        print "Blue is minimum and red is maximum..."
        print "White is those residues used in the alignment algorithm"
	print "Black is residues that does not exist in both files..."
cmd.extend("ColorByDisplacementCA", ColorByDisplacementCA)

def displacementUpdateBAll(objA, alnAri, objB, alnBri):
    AlignedWhite='no'
    print "This will take a while to go through the for loops. Give me around 3-5 minutes..."
    ### If residue is unassigned in one of the pdb files, we reset its value
    for x in range(len(alnAri)):
        s1 = objA + " and resi " + alnAri[x][0] + " and name " + str(alnAri[x][1])
 	cmd.alter( s1, "b = " + str(-0.01))
    for x in range(len(alnBri)):
	s2 = objB + " and resi " + alnBri[x][0] + " and name " + alnBri[x][1]
        cmd.alter( s2, "b = " + str(-0.01))
    cmd.sort(objA); cmd.sort(objB)
    for x in range(len(alnAri)):
        s1 = objA + " and resi " + alnAri[x][0] + " and name " + alnAri[x][1]
	s2 = objB + " and resi " + alnAri[x][0] + " and name " + alnAri[x][1]
	### Names starting with __ (underscores) are normally hidden by PyMOL
	tempObject = "__tempObject"
	Displacement = cmd.distance(tempObject, s1, s2)
 	cmd.alter( s1, "b = " + str(Displacement))
        cmd.alter( s2, "b = " + str(Displacement))
	cmd.delete(tempObject)
    cmd.sort(objA); cmd.sort(objB)

def ColorByDisplacementAll(objSel1, objSel2, super1='all', super2='all', doColor="True", doAlign="True"):
    AlignedWhite='yes'
    ### First create backup copies; names starting with __ (underscores) are normally hidden by PyMOL
    tObj1, tObj2, aln = "__tempObj1", "__tempObj2", "__aln"

    if strTrue(doAlign):
        ### Create temp objects
        cmd.create( tObj1, objSel1 )
        cmd.create( tObj2, objSel2 )
	### Align and make create an object aln which indicates which atoms were paired between the two structures
	### Super is must faster than align http://www.pymolwiki.org/index.php/Super
        cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)
	### Modify the original matrix of object1 from the alignment
        cmd.matrix_copy(tObj1, objSel1)
    else:
        ### Create temp objects
        cmd.create( tObj1, objSel1 )
        cmd.create( tObj2, objSel2 )
	### Align and make create an object aln which indicates which atoms were paired between the two structures
	### Super is must faster than align http://www.pymolwiki.org/index.php/Super
        cmd.super(tObj1 + ' and ' + str(super1), tObj2 + ' and ' + str(super2), object=aln)

    ### Modify the B-factor columns of the original objects,
    ### in order to identify the residues NOT used for alignment, later on
    cmd.alter( objSel1 + " or " + objSel2, "b=-0.2")
    cmd.alter( tObj1 + " or " + tObj2, "chain='A'")
    cmd.alter( tObj1 + " or " + tObj2, "segi='A'")

    ### Update pymol internal representations; one of these should do the trick
    cmd.refresh(); cmd.rebuild(); cmd.sort(tObj1); cmd.sort(tObj2)

    ###  Create lists for storage
    stored.alnAres, stored.alnBres = [], []

    ### Iterate over objects and get resi
    if AlignedWhite=='yes':
        cmd.iterate(tObj1 + " and not " + aln, "stored.alnAres.append((resi, name))")
        cmd.iterate(tObj2 + " and not " + aln, "stored.alnBres.append((resi, name))")
    else:
        cmd.iterate(tObj1, "stored.alnAres.append((resi, name))")
        cmd.iterate(tObj2, "stored.alnBres.append((resi, name))")

    ### Change the B-factors for EACH object
    displacementUpdateBAll(tObj1,stored.alnAres,tObj2,stored.alnBres)

    ### Store the NEW B-factors
    stored.alnAnb, stored.alnBnb = [], []
    ### Iterate over objects and get b
    ### Iterate over objects which is not aligned
    if AlignedWhite=='yes':
        cmd.iterate(tObj1 + " and not " + aln, "stored.alnAnb.append(b)" )
        cmd.iterate(tObj2 + " and not " + aln, "stored.alnBnb.append(b)" )
    else:
        cmd.iterate(tObj1, "stored.alnAnb.append(b)" )
        cmd.iterate(tObj2, "stored.alnBnb.append(b)" )

    ### Get rid of all intermediate objects and clean up
    cmd.delete(tObj1)
    cmd.delete(tObj2)
    cmd.delete(aln)

    ### Assign the just stored NEW B-factors to the original objects
    print "Sooon ready. 1 more minute"
    for x in range(len(stored.alnAres)):
        cmd.alter(objSel1 + " and resi " + str(stored.alnAres[x][0]) + " and name " + str(stored.alnAres[x][1]), "b = " + str(stored.alnAnb[x]))
    for x in range(len(stored.alnBres)):
        cmd.alter(objSel2 + " and resi " + str(stored.alnBres[x][0]) + " and name " + str(stored.alnBres[x][1]), "b = " + str(stored.alnBnb[x]))
    cmd.rebuild(); cmd.refresh(); cmd.sort(objSel1); cmd.sort(objSel2)

    ### Provide some useful information
    stored.allRMSDval = []
    stored.allRMSDval = stored.alnAnb + stored.alnBnb
    print "\nColorByDisplacementAll completed successfully."
    print "The MAXIMUM Displacement is: "+str(max(stored.allRMSDval)) +" residue "+str(stored.alnAres[int(stored.allRMSDval.index(max(stored.allRMSDval)))])

    if strTrue(doColor):
        ### Showcase what we did
        #cmd.orient()
        #cmd.hide("all")
        cmd.show("sticks", objSel1 + " or " + objSel2)
        ### Select the residues not used for alignment; they still have their B-factors as "-0.2"
        cmd.select("notUsedForAln", "b=-0.2")
        ### White-wash the residues not used for alignment
        cmd.color("white", "notUsedForAln")
        ### Select the residues not in both pdb files; they have their B-factors as "-0.01"
        cmd.select("ResNotInBothPDB", "b=-0.01")
        ### White-wash the residues not used for alignment
        cmd.color("black", "ResNotInBothPDB")
        ### Color the residues used for alignment according to their B-factors (Displacment values)
        cmd.spectrum("b", 'rainbow',  "(" + objSel1 + ") or (" + objSel2 +" ) and not (notUsedForAln and ResNotInBothPDB)")
        ### Delete the selection of atoms not used for alignment
        ### If you would like to keep this selection intact,
        ### just comment "cmd.delete" line and
        ### uncomment the "cmd.disable" line abowe.
        #cmd.disable("notUsedForAln")
        cmd.delete("notUsedForAln")
        #cmd.disable("ResNotInBothPDB")
        cmd.delete("ResNotInBothPDB")
        print "\nObjects are now colored by C-alpha displacement deviation."
        print "Blue is minimum and red is maximum..."
        print "White is those residues used in the alignment algorithm"
	print "Black is residues that does not exist in both files..."
cmd.extend("ColorByDisplacementAll", ColorByDisplacementAll)