profilin-actin binding interface from David Oppenheimer on Vimeo.
In my cell biology course, we spend significant time on protein-protein interactions because they are so important for practically everything in cells. To show the interacting surface between two proteins I like to create a quick movie using PyMol. When combined with the interface residues script, the movie highlights the interacting surface nicely. Here’s how to do it.
Since I am obsessed with actin and actin-binding proteins, I will use the complex of actin with profilin for this demonstration. Profilin acts as an ATP exchange factor for G-actin. “Old” actin monomers from recently depolymerized actin filaments have ADP bound to them, and upon binding to profilin, will exchange the ADP for ATP. I found a nice structure (determined by X-ray diffraction) of actin bound to profilin on the RSCB Protein Data Bank website. Open PyMol and type the following into the Pymol command line:
viewport 640, 640 # these settings are for Instagram
fetch 1HLU, async=0
Extract the various part of the complex that we want to work with.
extract actin, /1hlu/A
extract profilin, /1hlu/B/P
extract ATP, /1HLU/D/A/ATP
extract Ca, /1HLU/C/A/CA
delete 1hlu
Go to the InterfaceResidues script website and scroll down the page until you reach the box The Code
. Copy the code and paste it into a new text file that you name InterfaceResidues.py
. Be sure to use a plain text editor and save the files as plain text so that no hidden or extraneous characters are included in the file. My favorite free text editor is TextWrangler. Even though you are saving the file as plain text, make sure that the file extension is .py
and not .txt
. Save the script to your PyMOL working directory.
from pymol import stored def interfaceResidues(cmpx, cA='c. A', cB='c. B', cutoff=1.0, selName="interface"): """ interfaceResidues -- finds 'interface' residues between two chains in a complex. PARAMS cmpx The complex containing cA and cB cA The first chain in which we search for residues at an interface with cB cB The second chain in which we search for residues at an interface with cA cutoff The difference in area OVER which residues are considered interface residues. Residues whose dASA from the complex to a single chain is greater than this cutoff are kept. Zero keeps all residues. selName The name of the selection to return. RETURNS * A selection of interface residues is created and named depending on what you passed into selName * An array of values is returned where each value is: ( modelName, residueNumber, dASA ) NOTES If you have two chains that are not from the same PDB that you want to complex together, use the create command like: create myComplex, pdb1WithChainA or pdb2withChainX then pass myComplex to this script like: interfaceResidues myComlpex, c. A, c. X This script calculates the area of the complex as a whole. Then, it separates the two chains that you pass in through the arguments cA and cB, alone. Once it has this, it calculates the difference and any residues ABOVE the cutoff are called interface residues. AUTHOR: Jason Vertrees, 2009. """ # Save user's settings, before setting dot_solvent oldDS = cmd.get("dot_solvent") cmd.set("dot_solvent", 1) # set some string names for temporary objects/selections tempC, selName1 = "tempComplex", selName+"1" chA, chB = "chA", "chB" # operate on a new object & turn off the original cmd.create(tempC, cmpx) cmd.disable(cmpx) # remove cruft and inrrelevant chains cmd.remove(tempC + " and not (polymer and (%s or %s))" % (cA, cB)) # get the area of the complete complex cmd.get_area(tempC, load_b=1) # copy the areas from the loaded b to the q, field. cmd.alter(tempC, 'q=b') # extract the two chains and calc. the new area # note: the q fields are copied to the new objects # chA and chB cmd.extract(chA, tempC + " and (" + cA + ")") cmd.extract(chB, tempC + " and (" + cB + ")") cmd.get_area(chA, load_b=1) cmd.get_area(chB, load_b=1) # update the chain-only objects w/the difference cmd.alter( "%s or %s" % (chA,chB), "b=b-q" ) # The calculations are done. Now, all we need to # do is to determine which residues are over the cutoff # and save them. stored.r, rVal, seen = [], [], [] cmd.iterate('%s or %s' % (chA, chB), 'stored.r.append((model,resi,b))') cmd.enable(cmpx) cmd.select(selName1, None) for (model,resi,diff) in stored.r: key=resi+"-"+model if abs(diff)>=float(cutoff): if key in seen: continue else: seen.append(key) rVal.append( (model,resi,diff) ) # expand the selection here; I chose to iterate over stored.r instead of # creating one large selection b/c if there are too many residues PyMOL # might crash on a very large selection. This is pretty much guaranteed # not to kill PyMOL; but, it might take a little longer to run. cmd.select( selName1, selName1 + " or (%s and i. %s)" % (model,resi)) # this is how you transfer a selection to another object. cmd.select(selName, cmpx + " in " + selName1) # clean up after ourselves cmd.delete(selName1) cmd.delete(chA) cmd.delete(chB) cmd.delete(tempC) # show the selection cmd.enable(selName) # reset users settings cmd.set("dot_solvent", oldDS) return rVal cmd.extend("interfaceResidues", interfaceResidues)
The InterfaceResidues
script relies on the interacting proteins have chains labeled A
and B
. Check that the complex has the correct chain labels.
get_chains 1hlu
# cmd.get_chains: ['A', 'P']
Because the chains are not named A and B, I have to create a complex with the 2 chains to use the InterfaceResidues
script. Run the script, create the complex, and identify the interacting residues.
run InterfaceResidues.py
create profilin-actin, chain A or chain P
interfaceResidues profilin-actin, c. A, c. P
The script will create a selection named (interface)
that contains the interface residues.
Next we want to color the protein so that the interacting surfaces are highlighted. PyMOL has many different ways to display proteins and residues, so you can let your artistic juices flow! Here I will use a surface representation and color the interacting residues using the YRB highlighting script developed by Hagemans et al.1.
Here we will create the interface residues objects for actin and profilin.
create int-actin, (interface) in actin
create int-profilin, (interface) in profilin
To get the YRB script to color just the residues in the interaction surface, you need to identify all the residues by name so you can exclude them from the object that you will color grey. Turn off all the objects except int-actin. Then select each of the residues using the mouse. Copy the residue path from the command line window. Change int-actin in the path to actin when you select the residues to color grey, or use residue number (resi 1+2+3).
To quickly make the list of residues in the interaction, do the following:
int-profilin
.orient int-profilin
.When this is done, we can create selections of the residues that are not in the interface so we can color them separately later.
select not-int-actin, actin and (not resi 351+354+355+167+166+169+170+171+172+173+375+374+373+372+371+133+113+369+368+365+361+283+284+285+286+290+287+289+288)
select not-int-profilin, profilin and (not resi 15+118+117+119+120+121+122+99+97+88+89+90+69+71+72+73+86+74+84+124+125+129+128+82+81+58+59+60+61+62)
deselect
disable all
enable profilin-actin
show lines, profilin-actin
orient profilin-actin
set_view (\
0.413371980, 0.062172260, 0.908435643,\
0.838299513, -0.415481538, -0.353022039,\
0.355487406, 0.907469451, -0.223868802,\
-0.000582412, -0.000603586, -291.505859375,\
12.634649277, 33.541786194, 69.472816467,\
216.508850098, 366.507873535, -20.000000000 )
disable all
enable actin
enable profilin
Download the YRB script from this link to the publication. Scroll to the Supplementary Information section and download (and unzip) the YRBscript.zip
file. Rename the file to YRBscript.pym
and place it in your pymol working directory. Run the script from within pymol.
run ~/pymol-work/1-scripts/YRBscript.pym
Color the protein.
show surface, actin
show surface, profilin
yrb
Note: the yrb
command hides hydrogens. This is probably okay as they somewhat obscure the yrb coloring.
#A script to highlight hydrophobicity and charge on protein surfaces #DHS065 Hagemans et al YRB script #created by Dominique Hagemans and Ianthe A.E.M. van Belzen, July 2015 #Rudiger group CPC, Utrecht University #yellow: C, CH, CH2, CH3 groups that are not bound to N or O groups. #red: negatively charged atoms #blue: positively charged atoms #grey: backbone, polar groups and remaining atoms #usage: #(1) save this script as file with a .py extension at desirable location #(2) open your structure in pymol and change to surface view. #(3) run this script: File --> Run --> DHS065 Hagemans et al YRB script #(4) give the command to colour all structures or a specific structure: #(4 a) "yrb" to colour all structures #(4 b) "yrb 'designation'" to colour only that specific structure from pymol import cmd def yrb(selection='all'): cmd.remove("hydro") cmd.set_color('yellow',[0.950,0.78,0.0]) cmd.set_color('grey',[0.95,0.95,0.95]) cmd.set_color('red',[1.0,0.4,0.4]) cmd.set_color('blue',[0.2,0.5,0.8]) mapping = {} mapping['arg'] = [ ('NE,NH2,NH1', 'blue'), ('CD,CZ', 'grey'), ('CG', 'yellow') ] mapping['asn'] = [ ('CG,OD1,ND2', 'grey') ] mapping['asp'] = [ ('CG', 'grey'), ('OD2,OD1', 'red') ] mapping['cys'] = [ ('SG', 'grey') ] mapping['gln'] = [ ('CG', 'yellow'), ('CD,OE1,NE2', 'grey') ] mapping['glu'] = [ ('CG', 'yellow'), ('CD', 'grey'), ('OE1,OE2', 'red') ] mapping['his'] = [ ('CG,CD2,ND1,NE2,CE1', 'grey') ] mapping['ile'] = [ ('CG1,CG2,CD1', 'yellow') ] mapping['leu'] = [ ('CG,CD1,CD2', 'yellow') ] mapping['lys'] = [ ('CG,CD', 'yellow'), ('CE', 'grey'), ('NZ', 'blue') ] mapping['met'] = [ ('CG,CE', 'yellow'), ('SD', 'grey') ] mapping['phe'] = [ ('CG,CD1,CE1,CZ,CE2,CD2', 'yellow') ] mapping['pro'] = [ ('CG', 'yellow'), ('CD', 'grey') ] mapping['ser'] = [ ('CB,OG', 'grey') ] mapping['thr'] = [ ('CB,OG1', 'grey'), ('CG2', 'yellow') ] mapping['trp'] = [ ('CG,CD2,CZ2,CH2,CZ3,CE3', 'yellow'), ('CD1,NE1,CE2', 'grey') ] mapping['tyr'] = [ ('CG,CE1,CD1,CE2,CD2', 'yellow'), ('CZ,OH', 'grey') ] mapping['val'] = [ ('CG1,CG2', 'yellow') ] obj_list = cmd.get_names('objects') for obj in obj_list: if (obj == selection or selection == 'all'): cmd.color('grey','(n. N,C,CA,O and ' + obj + ')') cmd.color('yellow','(n. CB and ' + obj + ')') for key in mapping: for (atom, color) in mapping[key]: cmd.color(color, '( n. ' + atom + ' and r. ' + key + ' and ' + obj + ' )') cmd.extend('yrb',yrb)
set_color pastelbeigeC= [0.906,0.824,0.573]
set_color pastelbeigeN= [1,0.937,0.745]
set_color pastelbeigeO= [0.808,0.71,0.408]
set_color pastelbeigeS= [0.698,0.584,0.247]
set_color pastellightgreenC= [0.753,0.851,0.537]
set_color pastellightgreenH= [0.91,0.957,0.808]
set_color pastellightgreenN= [0.863,0.937,0.698]
set_color pastellightgreenO= [0.643,0.757,0.38]
set_color pastellightgreenS= [0.525,0.655,0.231]
color pastelbeigeC, elem C and (not-int-actin)
color pastelbeigeN, elem N and (not-int-actin)
color pastelbeigeO, elem O and (not-int-actin)
color pastelbeigeS, elem S and (not-int-actin)
color pastellightgreenC, elem C and (not-int-profilin)
color pastellightgreenN, elem N and (not-int-profilin)
color pastellightgreenO, elem O and (not-int-profilin)
color pastellightgreenS, elem S and (not-int-profilin)
At this point, it is a good idea to save the PyMOL session. It is really easy to just load the .pse
session file if we mess something up later on rather than re-creating the entire process.
set matrix_mode, 1
set movie_panel, 1
set scene_buttons, 1
set cache_frames, 0
config_mouse three_button_motions, 1
Here is the script I use to make a movie with a simple rotation of each protein to show the interaction interface. You can either save these commands as a script file and then run the script from within PyMOL, or you can just cut these commands and paste them into the PyMOL command line. I built this script using information from the PyMOLwiki
python
for x in range(1):
cmd.madd("1 x60"); cmd.frame(1000);
cmd.rotate("y", -70, object="actin")
cmd.translate([-15,0,0], object="actin")
cmd.rotate("y", 90, object="profilin")
cmd.translate([35,0,15], object="profilin")
cmd.mview("store", object="actin")
cmd.mview("store", object="profilin")
cmd.mview("store")
cmd.mview("interpolate", object="actin")
cmd.mview("interpolate", object="profilin")
cmd.mview("reinterpolate")
# wait 0.5 second
cmd.madd("1 x15"); cmd.frame(1000);
cmd.mview("store", object="actin")
cmd.mview("store", object="profilin")
cmd.mview("store")
cmd.mview("interpolate", object="actin")
cmd.mview("interpolate", object="profilin")
cmd.mview("reinterpolate")
cmd.madd("1 x60"); cmd.frame(1000);
cmd.translate([15,0,0], object="actin")
cmd.rotate("y", 70, object="actin")
cmd.translate([-35,0,-15], object="profilin")
cmd.rotate("y", -90, object="profilin")
cmd.mview("store", object="actin")
cmd.mview("store", object="profilin")
cmd.mview("store")
cmd.mview("interpolate", object="actin")
cmd.mview("interpolate", object="profilin")
cmd.mview("reinterpolate")
# wait 0.5 second
cmd.madd("1 x15"); cmd.frame(1000);
cmd.mview("store", object="actin")
cmd.mview("store", object="profilin")
cmd.mview("store")
cmd.mview("interpolate", object="actin")
cmd.mview("interpolate", object="profilin")
cmd.mview("reinterpolate")
python end
png
filesset antialias, 1
set depth_cue, 0
set ambient,0.1
set specular, 0.3
set shininess, 100
set spec_count,1
set light_count,8
set direct,0.75
set ray_shadow_decay_factor, 0.1
set ray_shadow_decay_range, 2
set ambient_occlusion_mode, 1
set ambient_occlusion_scale, 15
set bg_gradient
set bg_rgb_top, [0.337,0.3961,0.451]
set bg_rgb_bottom, [0.09, 0.1255, 0.1647]
set hash_max, 220
set ray_trace_mode, 0
set depth_cue=0
set ray_trace_fog=0
set ray_trace_frames=1
set cache_frames=0
Move from the working directory to a new directory where you can store all the png
files, and write the png
files for the movie.
cd ../1-movies/actin-profilin-pngs
mpng actin-profilin
I have previously installed the free command line video tool, FFMPEG. There is definitely a learning curve when using ffmpeg, but luckily, there are lots of tutorials on the web for your learning enjoyment. Here are the options I used to make the movie. I got the explanations from the Joy of Data blog and the ffmpeg manual.
ffmpeg
-framerate 30 # input frame rate
-i image%03d.png # image names (image000.png, ..., image999.png)
-s:v 720x720 # video size
-c:v libx264 # encoder
-profile:v main # H.264 profile for video
-crf 12 # constant rate factor (0 to 23, 0 is lossless)
-pix_fmt yuv420p # pixel format; changes the rgb from the pngs to yuv
-preset veryslow # encoding speed (slow but higher quality per file size)
-tune stillimage # tunes the encoding settings for images
-r 30 # output frame rate
output_file.mp4 # movie file name
Open a terminal window, move into the .png
file directory and type the following:
ffmpeg -framerate 30 -pattern_type glob -i '*.png' -s:v 640x640 -c:v libx264 -profile:v main -crf 12 -tune stillimage -pix_fmt yuv420p -preset veryslow -r 30 actin-profilin.mp4
For Vimeo, use the following:
ffmpeg -framerate 30 -pattern_type glob -i '*.png' -s:v 720x720 -c:v libx264 -crf 18 -tune stillimage -pix_fmt yuv420p -preset veryslow -r 30 actin-profilin-vim.mp4