<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.pymol.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cowsandmilk</id>
	<title>PyMOL Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.pymol.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cowsandmilk"/>
	<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php/Special:Contributions/Cowsandmilk"/>
	<updated>2026-05-25T16:24:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.1</generator>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Bg_gradient&amp;diff=846</id>
		<title>Bg gradient</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Bg_gradient&amp;diff=846"/>
		<updated>2012-07-07T15:42:59Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Enable background gradients in the viewer window.  (Ray trace in pymol 1.5+)&lt;br /&gt;
&lt;br /&gt;
[[Image:bg_grad.png|350px|set bg_gradient]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Usage =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# enable&lt;br /&gt;
&lt;br /&gt;
set bg_gradient&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;br /&gt;
[[bg_rgb_top]], [[bg_rgb_bottom]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Git_install_scripts&amp;diff=7546</id>
		<title>Git install scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Git_install_scripts&amp;diff=7546"/>
		<updated>2011-12-19T13:30:55Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Manual download of scripts ==&lt;br /&gt;
If you don't have the option or want't to install git on your system, then go to&lt;br /&gt;
 https://github.com/Pymol-Scripts/Pymol-script-repo&lt;br /&gt;
Click the &amp;quot;ZIP&amp;quot; button, near the top left corner.&lt;br /&gt;
Now unpack the files to a directory. For example:&lt;br /&gt;
 C:/Users/YOURNAME/Documents/Pymol-script-repo&lt;br /&gt;
or&lt;br /&gt;
 /home/YOURNAME/Software/pymol&lt;br /&gt;
&lt;br /&gt;
Now go to: '''Adding Pymol-script-repo to PyMOL search path''' [http://www.pymolwiki.org/index.php/Git_install#Adding_Pymol-script-repo_to_PyMOL_search_path]&lt;br /&gt;
&lt;br /&gt;
== Git install instructions ==&lt;br /&gt;
=== For Windows users ===&lt;br /&gt;
# Install [http://code.google.com/p/msysgit/downloads/list?can=3&amp;amp;q=official+Git Git for Windows].&lt;br /&gt;
Use following settings in options, [http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/ (You can read more here)].&lt;br /&gt;
* Windows Explorer Integration -&amp;gt; Context Menu Entries -&amp;gt; Git Bash Here + Git GUI here&lt;br /&gt;
* Run Git and included Unix tools from Windows Command prompts&lt;br /&gt;
* Checkout Windows style, commit Unix-style endings&lt;br /&gt;
&lt;br /&gt;
# Navigate to: '''C:\Users\YOURNAME\Documents\pymol'''&lt;br /&gt;
# Right click in folder -&amp;gt; Select: Git Gui -&amp;gt; Clone Existing Repository&lt;br /&gt;
# Source Location: git://github.com/Pymol-Scripts/Pymol-script-repo.git&lt;br /&gt;
# Target Directory: C:\\Users\\YOURNAME\\Documents\\pymol\Pymol-script-repo&lt;br /&gt;
#: A backslash &amp;quot;\&amp;quot; in a string is [http://effbot.org/pyref/string-literals.htm is used for escape sequences]. To get a real backslash in a string, use double backslash &amp;quot;\\&amp;quot;   &lt;br /&gt;
You now have all the scripts available in your directory.&lt;br /&gt;
&lt;br /&gt;
Add '''python.exe''' to your '''PATH''', so external .py scripts can be executed.&amp;lt;br&amp;gt;&lt;br /&gt;
Open control panel. Search for, and click: '''Edit environment variables for your account'''&amp;lt;br&amp;gt;&lt;br /&gt;
Add to end of variable PATH: ''';C:\Python27'''   (Or other path to your python python.exe)&amp;lt;br&amp;gt;&lt;br /&gt;
Click start button, and open '''cmd.exe'''. Try starting python by writing: '''python'''&lt;br /&gt;
&lt;br /&gt;
=== For Linux users ===&lt;br /&gt;
# Install git&lt;br /&gt;
 # Debian/Ubuntu/Mint&lt;br /&gt;
 sudo apt-get install git&lt;br /&gt;
 # Fedora&lt;br /&gt;
 su -c 'yum install git'&lt;br /&gt;
 # openSUSE&lt;br /&gt;
 sudo zypper in git&lt;br /&gt;
&lt;br /&gt;
# Navigate to desired folder: &lt;br /&gt;
 cd /home/YOURNAME/Software/pymol&lt;br /&gt;
 git clone git://github.com/Pymol-Scripts/Pymol-script-repo.git&lt;br /&gt;
You now have all the scripts available in: /home/YOURNAME/Software/pymol/Pymol-script-repo&lt;br /&gt;
&lt;br /&gt;
== Adding Pymol-script-repo to PyMOL search path ==&lt;br /&gt;
You now have to add the &amp;quot;Pymol-script-repo&amp;quot; directory to the PyMOL search path. &lt;br /&gt;
&lt;br /&gt;
The project also have automatically plugin installer: http://www.pymolwiki.org/index.php/plugindirectory &amp;lt;br&amp;gt;&lt;br /&gt;
This is activated with: '''import plugins'''. &amp;lt;br&amp;gt;&lt;br /&gt;
'''You have to remove old installations of plugins first, to get the automatic plugin installation to work.'''&lt;br /&gt;
=== For Windows users ===&lt;br /&gt;
# Open notepad&lt;br /&gt;
# Write (Remember double backslashes)&lt;br /&gt;
 import sys,os&lt;br /&gt;
 sys.path.append('C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo')&lt;br /&gt;
 os.environ['PYMOL_GIT_MOD']='C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo\\modules'&lt;br /&gt;
 import plugins&lt;br /&gt;
 os.chdir('C:\\Users\\YOURNAME\\Documents\\pymol')                                # Your standard working dir&lt;br /&gt;
Save under: '''C:\Users\YOURNAME\pymolrc.pym''' (Set: &amp;quot;Save as type&amp;quot; to &amp;quot;All files&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== For Linux users ===&lt;br /&gt;
 gedit ~/.pymolrc&lt;br /&gt;
Write&lt;br /&gt;
 import sys,os&lt;br /&gt;
 sys.path.append('/home/YOU/Software/pymol/Pymol-script-repo')&lt;br /&gt;
 os.environ['PYMOL_GIT_MOD']='/home/YOU/Software/pymol/Pymol-script-repo/modules'&lt;br /&gt;
 import plugins&lt;br /&gt;
 os.chdir('/home/YOU/Software/pymol/')                              # Your standard working dir&lt;br /&gt;
Save and exit&lt;br /&gt;
&lt;br /&gt;
== Test the Scripts ==&lt;br /&gt;
Now start PyMOL, and test in PyMOL.&lt;br /&gt;
 print sys.path&lt;br /&gt;
 import colorbydisplacement&lt;br /&gt;
 help(colorbydisplacement)&lt;br /&gt;
&lt;br /&gt;
== Get latest changes to scripts ==&lt;br /&gt;
If new scripts are available or changes have been made, then:&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Navigate to '''C:\Users\YOURNAME\Documents\Pymol-script-repo'''&lt;br /&gt;
# Right click in folder -&amp;gt; Select: Git Bash&lt;br /&gt;
# Write in terminal&lt;br /&gt;
 git pull origin master&lt;br /&gt;
&lt;br /&gt;
=== For Ubuntu/Mint users ===&lt;br /&gt;
# Navigate to '''/home/YOURNAME/Software/pymol/Pymol-script-repo'''&lt;br /&gt;
# Write in terminal.&lt;br /&gt;
 git pull origin master&lt;br /&gt;
&lt;br /&gt;
= Do you want to contribute with a script? =&lt;br /&gt;
Information how to contribute scripts to the repository. It's easy! &amp;lt;br&amp;gt;&lt;br /&gt;
http://www.pymolwiki.org/index.php/git_authors&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Git_install_scripts&amp;diff=7545</id>
		<title>Git install scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Git_install_scripts&amp;diff=7545"/>
		<updated>2011-12-19T13:28:29Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* For Linux users */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Manual download of scripts ==&lt;br /&gt;
If you don't have the option or want't to install git on your system, then go to&lt;br /&gt;
 https://github.com/Pymol-Scripts/Pymol-script-repo&lt;br /&gt;
Click the &amp;quot;ZIP&amp;quot; button, near the top left corner.&lt;br /&gt;
Now unpack the files to a directory. For example:&lt;br /&gt;
 C:/Users/YOURNAME/Documents/Pymol-script-repo&lt;br /&gt;
or&lt;br /&gt;
 /home/YOURNAME/Software/pymol&lt;br /&gt;
&lt;br /&gt;
Now go to: '''Adding Pymol-script-repo to PyMOL search path''' [http://www.pymolwiki.org/index.php/Git_install#Adding_Pymol-script-repo_to_PyMOL_search_path]&lt;br /&gt;
&lt;br /&gt;
== Git install instructions ==&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Install [http://code.google.com/p/msysgit/downloads/list?can=3&amp;amp;q=official+Git Git for Windows].&lt;br /&gt;
Use following settings in options, [http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/ (You can read more here)].&lt;br /&gt;
* Windows Explorer Integration -&amp;gt; Context Menu Entries -&amp;gt; Git Bash Here + Git GUI here&lt;br /&gt;
* Run Git and included Unix tools from Windows Command prompts&lt;br /&gt;
* Checkout Windows style, commit Unix-style endings&lt;br /&gt;
&lt;br /&gt;
# Navigate to: '''C:\Users\YOURNAME\Documents\pymol'''&lt;br /&gt;
# Right click in folder -&amp;gt; Select: Git Gui -&amp;gt; Clone Existing Repository&lt;br /&gt;
# Source Location: git://github.com/Pymol-Scripts/Pymol-script-repo.git&lt;br /&gt;
# Target Directory: C:\\Users\\YOURNAME\\Documents\\pymol\Pymol-script-repo&lt;br /&gt;
#: A backslash &amp;quot;\&amp;quot; in a string is [http://effbot.org/pyref/string-literals.htm is used for escape sequences]. To get a real backslash in a string, use double backslash &amp;quot;\\&amp;quot;   &lt;br /&gt;
You now have all the scripts available in your directory.&lt;br /&gt;
&lt;br /&gt;
Add '''python.exe''' to your '''PATH''', so external .py scripts can be executed.&amp;lt;br&amp;gt;&lt;br /&gt;
Open control panel. Search for, and click: '''Edit environment variables for your account'''&amp;lt;br&amp;gt;&lt;br /&gt;
Add to end of variable PATH: ''';C:\Python27'''   (Or other path to your python python.exe)&amp;lt;br&amp;gt;&lt;br /&gt;
Click start button, and open '''cmd.exe'''. Try starting python by writing: '''python'''&lt;br /&gt;
&lt;br /&gt;
=== For Linux users ===&lt;br /&gt;
# Install git&lt;br /&gt;
 # Debian/Ubuntu/Mint&lt;br /&gt;
 sudo apt-get install git&lt;br /&gt;
 # Fedora&lt;br /&gt;
 su -c 'yum install git'&lt;br /&gt;
 # openSUSE&lt;br /&gt;
 sudo zypper in git&lt;br /&gt;
&lt;br /&gt;
# Navigate to desired folder: &lt;br /&gt;
 cd /home/YOURNAME/Software/pymol&lt;br /&gt;
 git clone git://github.com/Pymol-Scripts/Pymol-script-repo.git&lt;br /&gt;
You now have all the scripts available in: /home/YOURNAME/Software/pymol/Pymol-script-repo&lt;br /&gt;
&lt;br /&gt;
== Adding Pymol-script-repo to PyMOL search path ==&lt;br /&gt;
You now have to add the &amp;quot;Pymol-script-repo&amp;quot; directory to the PyMOL search path. &lt;br /&gt;
&lt;br /&gt;
The project also have automatically plugin installer: http://www.pymolwiki.org/index.php/plugindirectory &amp;lt;br&amp;gt;&lt;br /&gt;
This is activated with: '''import plugins'''. &amp;lt;br&amp;gt;&lt;br /&gt;
'''You have to remove old installations of plugins first, to get the automatic plugin installation to work.'''&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Open notepad&lt;br /&gt;
# Write (Remember double backslashes)&lt;br /&gt;
 import sys,os&lt;br /&gt;
 sys.path.append('C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo')&lt;br /&gt;
 os.environ['PYMOL_GIT_MOD']='C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo\\modules'&lt;br /&gt;
 import plugins&lt;br /&gt;
 os.chdir('C:\\Users\\YOURNAME\\Documents\\pymol')                                # Your standard working dir&lt;br /&gt;
Save under: '''C:\Users\YOURNAME\pymolrc.pym''' (Set: &amp;quot;Save as type&amp;quot; to &amp;quot;All files&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== For Ubuntu/Mint users ===&lt;br /&gt;
 gedit ~/.pymolrc&lt;br /&gt;
Write&lt;br /&gt;
 import sys,os&lt;br /&gt;
 sys.path.append('/home/YOU/Software/pymol/Pymol-script-repo')&lt;br /&gt;
 os.environ['PYMOL_GIT_MOD']='/home/YOU/Software/pymol/Pymol-script-repo/modules'&lt;br /&gt;
 import plugins&lt;br /&gt;
 os.chdir('/home/YOU/Software/pymol/')                              # Your standard working dir&lt;br /&gt;
Save and exit&lt;br /&gt;
&lt;br /&gt;
== Test the Scripts ==&lt;br /&gt;
Now start PyMOL, and test in PyMOL.&lt;br /&gt;
 print sys.path&lt;br /&gt;
 import colorbydisplacement&lt;br /&gt;
 help(colorbydisplacement)&lt;br /&gt;
&lt;br /&gt;
== Get latest changes to scripts ==&lt;br /&gt;
If new scripts are available or changes have been made, then:&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Navigate to '''C:\Users\YOURNAME\Documents\Pymol-script-repo'''&lt;br /&gt;
# Right click in folder -&amp;gt; Select: Git Bash&lt;br /&gt;
# Write in terminal&lt;br /&gt;
 git pull origin master&lt;br /&gt;
&lt;br /&gt;
=== For Ubuntu/Mint users ===&lt;br /&gt;
# Navigate to '''/home/YOURNAME/Software/pymol/Pymol-script-repo'''&lt;br /&gt;
# Write in terminal.&lt;br /&gt;
 git pull origin master&lt;br /&gt;
&lt;br /&gt;
= Do you want to contribute with a script? =&lt;br /&gt;
Information how to contribute scripts to the repository. It's easy! &amp;lt;br&amp;gt;&lt;br /&gt;
http://www.pymolwiki.org/index.php/git_authors&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Git_install_scripts&amp;diff=7544</id>
		<title>Git install scripts</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Git_install_scripts&amp;diff=7544"/>
		<updated>2011-12-19T13:27:39Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* Git install instructions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Manual download of scripts ==&lt;br /&gt;
If you don't have the option or want't to install git on your system, then go to&lt;br /&gt;
 https://github.com/Pymol-Scripts/Pymol-script-repo&lt;br /&gt;
Click the &amp;quot;ZIP&amp;quot; button, near the top left corner.&lt;br /&gt;
Now unpack the files to a directory. For example:&lt;br /&gt;
 C:/Users/YOURNAME/Documents/Pymol-script-repo&lt;br /&gt;
or&lt;br /&gt;
 /home/YOURNAME/Software/pymol&lt;br /&gt;
&lt;br /&gt;
Now go to: '''Adding Pymol-script-repo to PyMOL search path''' [http://www.pymolwiki.org/index.php/Git_install#Adding_Pymol-script-repo_to_PyMOL_search_path]&lt;br /&gt;
&lt;br /&gt;
== Git install instructions ==&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Install [http://code.google.com/p/msysgit/downloads/list?can=3&amp;amp;q=official+Git Git for Windows].&lt;br /&gt;
Use following settings in options, [http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/ (You can read more here)].&lt;br /&gt;
* Windows Explorer Integration -&amp;gt; Context Menu Entries -&amp;gt; Git Bash Here + Git GUI here&lt;br /&gt;
* Run Git and included Unix tools from Windows Command prompts&lt;br /&gt;
* Checkout Windows style, commit Unix-style endings&lt;br /&gt;
&lt;br /&gt;
# Navigate to: '''C:\Users\YOURNAME\Documents\pymol'''&lt;br /&gt;
# Right click in folder -&amp;gt; Select: Git Gui -&amp;gt; Clone Existing Repository&lt;br /&gt;
# Source Location: git://github.com/Pymol-Scripts/Pymol-script-repo.git&lt;br /&gt;
# Target Directory: C:\\Users\\YOURNAME\\Documents\\pymol\Pymol-script-repo&lt;br /&gt;
#: A backslash &amp;quot;\&amp;quot; in a string is [http://effbot.org/pyref/string-literals.htm is used for escape sequences]. To get a real backslash in a string, use double backslash &amp;quot;\\&amp;quot;   &lt;br /&gt;
You now have all the scripts available in your directory.&lt;br /&gt;
&lt;br /&gt;
Add '''python.exe''' to your '''PATH''', so external .py scripts can be executed.&amp;lt;br&amp;gt;&lt;br /&gt;
Open control panel. Search for, and click: '''Edit environment variables for your account'''&amp;lt;br&amp;gt;&lt;br /&gt;
Add to end of variable PATH: ''';C:\Python27'''   (Or other path to your python python.exe)&amp;lt;br&amp;gt;&lt;br /&gt;
Click start button, and open '''cmd.exe'''. Try starting python by writing: '''python'''&lt;br /&gt;
&lt;br /&gt;
=== For Linux users ===&lt;br /&gt;
# Install git&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu/Mint&lt;br /&gt;
sudo apt-get install git&lt;br /&gt;
# Fedora&lt;br /&gt;
su -c 'yum install git'&lt;br /&gt;
# openSUSE&lt;br /&gt;
sudo zypper in git&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# Navigate to desired folder: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /home/YOURNAME/Software/pymol&lt;br /&gt;
git clone git://github.com/Pymol-Scripts/Pymol-script-repo.git&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
You now have all the scripts available in: /home/YOURNAME/Software/pymol/Pymol-script-repo&lt;br /&gt;
&lt;br /&gt;
== Adding Pymol-script-repo to PyMOL search path ==&lt;br /&gt;
You now have to add the &amp;quot;Pymol-script-repo&amp;quot; directory to the PyMOL search path. &lt;br /&gt;
&lt;br /&gt;
The project also have automatically plugin installer: http://www.pymolwiki.org/index.php/plugindirectory &amp;lt;br&amp;gt;&lt;br /&gt;
This is activated with: '''import plugins'''. &amp;lt;br&amp;gt;&lt;br /&gt;
'''You have to remove old installations of plugins first, to get the automatic plugin installation to work.'''&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Open notepad&lt;br /&gt;
# Write (Remember double backslashes)&lt;br /&gt;
 import sys,os&lt;br /&gt;
 sys.path.append('C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo')&lt;br /&gt;
 os.environ['PYMOL_GIT_MOD']='C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo\\modules'&lt;br /&gt;
 import plugins&lt;br /&gt;
 os.chdir('C:\\Users\\YOURNAME\\Documents\\pymol')                                # Your standard working dir&lt;br /&gt;
Save under: '''C:\Users\YOURNAME\pymolrc.pym''' (Set: &amp;quot;Save as type&amp;quot; to &amp;quot;All files&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== For Ubuntu/Mint users ===&lt;br /&gt;
 gedit ~/.pymolrc&lt;br /&gt;
Write&lt;br /&gt;
 import sys,os&lt;br /&gt;
 sys.path.append('/home/YOU/Software/pymol/Pymol-script-repo')&lt;br /&gt;
 os.environ['PYMOL_GIT_MOD']='/home/YOU/Software/pymol/Pymol-script-repo/modules'&lt;br /&gt;
 import plugins&lt;br /&gt;
 os.chdir('/home/YOU/Software/pymol/')                              # Your standard working dir&lt;br /&gt;
Save and exit&lt;br /&gt;
&lt;br /&gt;
== Test the Scripts ==&lt;br /&gt;
Now start PyMOL, and test in PyMOL.&lt;br /&gt;
 print sys.path&lt;br /&gt;
 import colorbydisplacement&lt;br /&gt;
 help(colorbydisplacement)&lt;br /&gt;
&lt;br /&gt;
== Get latest changes to scripts ==&lt;br /&gt;
If new scripts are available or changes have been made, then:&lt;br /&gt;
=== For windows users ===&lt;br /&gt;
# Navigate to '''C:\Users\YOURNAME\Documents\Pymol-script-repo'''&lt;br /&gt;
# Right click in folder -&amp;gt; Select: Git Bash&lt;br /&gt;
# Write in terminal&lt;br /&gt;
 git pull origin master&lt;br /&gt;
&lt;br /&gt;
=== For Ubuntu/Mint users ===&lt;br /&gt;
# Navigate to '''/home/YOURNAME/Software/pymol/Pymol-script-repo'''&lt;br /&gt;
# Write in terminal.&lt;br /&gt;
 git pull origin master&lt;br /&gt;
&lt;br /&gt;
= Do you want to contribute with a script? =&lt;br /&gt;
Information how to contribute scripts to the repository. It's easy! &amp;lt;br&amp;gt;&lt;br /&gt;
http://www.pymolwiki.org/index.php/git_authors&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Linux_Install&amp;diff=12462</id>
		<title>Linux Install</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Linux_Install&amp;diff=12462"/>
		<updated>2011-12-02T16:06:11Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* Install from Source */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes how to install open-source PyMOL on Linux.&lt;br /&gt;
&lt;br /&gt;
== Install Distribution-specific binary Package ==&lt;br /&gt;
&lt;br /&gt;
Many Linux distributions provide binary packages for open-source PyMOL. They often do not provide the latest version, but if the provided package fits your needs this is the most convenient way to install PyMOL.&lt;br /&gt;
&lt;br /&gt;
Command line install examples for some popular distributions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu&lt;br /&gt;
sudo apt-get install pymol&lt;br /&gt;
&lt;br /&gt;
# Fedora&lt;br /&gt;
yum install pymol&lt;br /&gt;
&lt;br /&gt;
# Gentoo&lt;br /&gt;
emerge -av pymol&lt;br /&gt;
&lt;br /&gt;
# openSUSE (12.1 and later)&lt;br /&gt;
sudo zypper install pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install from Source ==&lt;br /&gt;
&lt;br /&gt;
Installation from source gives you the latest version and is the generic way to install PyMOL.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Libraries as well as development files (headers) of the following software is&lt;br /&gt;
required:&lt;br /&gt;
&lt;br /&gt;
* [http://subversion.apache.org/ Subversion] to download the source code&lt;br /&gt;
* [http://www.python.org/ Python] (with distutils)&lt;br /&gt;
* [http://pmw.sf.net Pmw] (Python Megawidgets)&lt;br /&gt;
* OpenGL driver (I use [http://www.nvidia.com/object/unix.html NVidia])&lt;br /&gt;
* libpng&lt;br /&gt;
* freetype&lt;br /&gt;
&lt;br /&gt;
On many Linux systems, one of the following commands installs all requirements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu/Mint11&lt;br /&gt;
sudo apt-get install subversion build-essential python-dev python-pmw \&lt;br /&gt;
  libglew-dev freeglut3-dev libpng-dev libfreetype6-dev&lt;br /&gt;
&lt;br /&gt;
# Fedora&lt;br /&gt;
yum install subversion python-devel freeglut-devel freetype-devel tkinter python-pmw&lt;br /&gt;
&lt;br /&gt;
# Gentoo&lt;br /&gt;
emerge -av dev-vcs/subversion dev-lang/python dev-python/pmw media-libs/glew \&lt;br /&gt;
  media-libs/freeglut media-libs/libpng media-libs/freetype&lt;br /&gt;
&lt;br /&gt;
# openSUSE&lt;br /&gt;
sudo zypper install python-devel freeglut-devel gcc-c++ glew-devel libpng-devel python-pmw subversion&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get latest Source from SVN ===&lt;br /&gt;
&lt;br /&gt;
This will download the latest source to '''/tmp/pymol''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp&lt;br /&gt;
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol pymol&lt;br /&gt;
cd pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compile and install ===&lt;br /&gt;
&lt;br /&gt;
This will install PyMOL as normal user into '''/opt/pymol-svn'''. If you don't have write permissions to '''/opt''', change the &amp;lt;code&amp;gt;prefix&amp;lt;/code&amp;gt; variable to something like '''$HOME/pymol-svn'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
&lt;br /&gt;
prefix=/opt/pymol-svn&lt;br /&gt;
modules=$prefix/modules&lt;br /&gt;
&lt;br /&gt;
python setup.py build install \&lt;br /&gt;
    --home=$prefix \&lt;br /&gt;
    --install-purelib=$modules \&lt;br /&gt;
    --install-platlib=$modules&lt;br /&gt;
&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
python setup2.py install&lt;br /&gt;
install pymol $prefix/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now launch PyMOL like this (you may copy this launcher into your '''$PATH''',&lt;br /&gt;
like to '''/usr/local/bin'''):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/pymol-svn/pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Problems ==&lt;br /&gt;
&lt;br /&gt;
* gcc-4.5 is broken for pymol install, use gcc-4.4 (Mint11 Linux, PyMOL 1.4.1, reported by [[User:Tlinnet]])&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential gcc-4.4 g++-4.4&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you get an error message &amp;quot;ImportError: No module named Pmw&amp;quot; and lack half of the user interface, then run the additional command&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python setup2.py install pmw&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:to install a copy of the Python MegaWidgets.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu/Mint Compile and install with MPEG support ==&lt;br /&gt;
Make a text file &amp;quot;installpymol.sh&amp;quot; and make it executable&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x installpymol.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put this in the file, modify the first 3 lines&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
pymolsvn=/home/tlinnet/Software/pymol/svnpymol&lt;br /&gt;
pymoldir=/home/tlinnet/Software/pymol&lt;br /&gt;
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol&lt;br /&gt;
 &lt;br /&gt;
###################################################&lt;br /&gt;
[ -d $pymoldir ] || mkdir $pymoldir&lt;br /&gt;
[ -d $pymolsvn ] || mkdir $pymolsvn&lt;br /&gt;
[ -d $pymoldir/wikiscripts ] || mkdir $pymoldir/wikiscripts&lt;br /&gt;
 &lt;br /&gt;
sudo apt-get install subversion build-essential python-dev python-pmw \&lt;br /&gt;
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev&lt;br /&gt;
 &lt;br /&gt;
# gcc 4.5 broken for install in ubuntu&lt;br /&gt;
sudo apt-get install gcc-4.4 g++-4.4&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
 &lt;br /&gt;
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol $pymolsvn&lt;br /&gt;
 &lt;br /&gt;
modules=$pymoldir/modules&lt;br /&gt;
cd $pymolsvn&lt;br /&gt;
python setup.py build&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
sudo python setup2.py install&lt;br /&gt;
install $pymolsvn/pymol $pymoldir/&lt;br /&gt;
 &lt;br /&gt;
## To add a path/folder where you can put pymol wikiscripts&lt;br /&gt;
t=&amp;quot;'&amp;quot;&lt;br /&gt;
echo &amp;quot;import sys&amp;quot; &amp;gt;&amp;gt; ~/.pymolrc&lt;br /&gt;
echo &amp;quot;sys.path.append($t$pymoldir/wikiscripts$t)&amp;quot; &amp;gt;&amp;gt; ~/.pymolrc&lt;br /&gt;
 &lt;br /&gt;
########## Setup freemol - for MPEG support ############&lt;br /&gt;
[ -d $pymolsvn ] || mkdir $freemolsvn&lt;br /&gt;
svn co svn://bioinformatics.org/svnroot/freemol/trunk $freemolsvn&lt;br /&gt;
 &lt;br /&gt;
cd $freemolsvn/src/mpeg_encode&lt;br /&gt;
export FREEMOL=$freemolsvn/freemol&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
 &lt;br /&gt;
## Make a shortcut to export freemol and then execute pymol&lt;br /&gt;
echo '#!/bin/bash' &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
echo &amp;quot;export FREEMOL=$freemolsvn/freemol&amp;quot; &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
echo &amp;quot;#$pymoldir/pymol&amp;quot; &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
tail -n +2 $pymoldir/pymol &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
chmod u+x $pymoldir/pymolMPEG.sh &lt;br /&gt;
 &lt;br /&gt;
## Make a link, so we can call execute pymol&lt;br /&gt;
sudo ln -s $pymoldir/pymolMPEG.sh /usr/bin/pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Update script ===&lt;br /&gt;
To pull and update PyMOL, one can make this script&lt;br /&gt;
&lt;br /&gt;
Make a text file &amp;quot;updatepymol.sh&amp;quot; and make it executable&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x updatepymol.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put this in the file, modify the first 3 lines&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
pymolsvn=/home/tlinnet/Software/pymol/svnpymol&lt;br /&gt;
pymoldir=/home/tlinnet/Software/pymol&lt;br /&gt;
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol&lt;br /&gt;
 &lt;br /&gt;
# gcc 4.5 broken for install in ubuntu&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
 &lt;br /&gt;
svn up $pymolsvn&lt;br /&gt;
svn up $freemolsvn&lt;br /&gt;
 &lt;br /&gt;
modules=$pymoldir/modules&lt;br /&gt;
cd $pymolsvn&lt;br /&gt;
python setup.py build&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
sudo python setup2.py install&lt;br /&gt;
install $pymolsvn/pymol $pymoldir/&lt;br /&gt;
 &lt;br /&gt;
########## Setup freemol - for MPEG support ############&lt;br /&gt;
cd $freemolsvn/src/mpeg_encode&lt;br /&gt;
export FREEMOL=$freemolsvn/freemol&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change MPEG settings ===&lt;br /&gt;
Change settings in&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/home/tlinnet/Software/pymol/svnfreemol/freemol/libpy/freemol/mpeg_encode.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
For example, change in line 205:&amp;lt;br&amp;gt; &lt;br /&gt;
FRAME_RATE 24&amp;lt;br&amp;gt;&lt;br /&gt;
(Not, only legal values is allowed: 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60)&lt;br /&gt;
&lt;br /&gt;
Then restart PyMOL. &lt;br /&gt;
&lt;br /&gt;
[[Category:Installation|Linux Installation]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Linux_Install&amp;diff=12461</id>
		<title>Linux Install</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Linux_Install&amp;diff=12461"/>
		<updated>2011-12-02T16:01:26Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes how to install open-source PyMOL on Linux.&lt;br /&gt;
&lt;br /&gt;
== Install Distribution-specific binary Package ==&lt;br /&gt;
&lt;br /&gt;
Many Linux distributions provide binary packages for open-source PyMOL. They often do not provide the latest version, but if the provided package fits your needs this is the most convenient way to install PyMOL.&lt;br /&gt;
&lt;br /&gt;
Command line install examples for some popular distributions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu&lt;br /&gt;
sudo apt-get install pymol&lt;br /&gt;
&lt;br /&gt;
# Fedora&lt;br /&gt;
yum install pymol&lt;br /&gt;
&lt;br /&gt;
# Gentoo&lt;br /&gt;
emerge -av pymol&lt;br /&gt;
&lt;br /&gt;
# openSUSE (12.1 and later)&lt;br /&gt;
sudo zypper install pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install from Source ==&lt;br /&gt;
&lt;br /&gt;
Installation from source gives you the latest version and is the generic way to install PyMOL.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Libraries as well as development files (headers) of the following software is&lt;br /&gt;
required:&lt;br /&gt;
&lt;br /&gt;
* [http://subversion.apache.org/ Subversion] to download the source code&lt;br /&gt;
* [http://www.python.org/ Python] (with distutils)&lt;br /&gt;
* [http://pmw.sf.net Pmw] (Python Megawidgets)&lt;br /&gt;
* OpenGL driver (I use [http://www.nvidia.com/object/unix.html NVidia])&lt;br /&gt;
* libpng&lt;br /&gt;
* freetype&lt;br /&gt;
&lt;br /&gt;
On many Linux systems, one of the following commands installs all requirements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu/Mint11&lt;br /&gt;
sudo apt-get install subversion build-essential python-dev python-pmw \&lt;br /&gt;
  libglew-dev freeglut3-dev libpng-dev libfreetype6-dev&lt;br /&gt;
&lt;br /&gt;
# Fedora&lt;br /&gt;
yum install subversion python-devel freeglut-devel freetype-devel tkinter python-pmw&lt;br /&gt;
&lt;br /&gt;
# Gentoo&lt;br /&gt;
emerge -av dev-vcs/subversion dev-lang/python dev-python/pmw media-libs/glew \&lt;br /&gt;
  media-libs/freeglut media-libs/libpng media-libs/freetype&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get latest Source from SVN ===&lt;br /&gt;
&lt;br /&gt;
This will download the latest source to '''/tmp/pymol''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp&lt;br /&gt;
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol pymol&lt;br /&gt;
cd pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compile and install ===&lt;br /&gt;
&lt;br /&gt;
This will install PyMOL as normal user into '''/opt/pymol-svn'''. If you don't have write permissions to '''/opt''', change the &amp;lt;code&amp;gt;prefix&amp;lt;/code&amp;gt; variable to something like '''$HOME/pymol-svn'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
&lt;br /&gt;
prefix=/opt/pymol-svn&lt;br /&gt;
modules=$prefix/modules&lt;br /&gt;
&lt;br /&gt;
python setup.py build install \&lt;br /&gt;
    --home=$prefix \&lt;br /&gt;
    --install-purelib=$modules \&lt;br /&gt;
    --install-platlib=$modules&lt;br /&gt;
&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
python setup2.py install&lt;br /&gt;
install pymol $prefix/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now launch PyMOL like this (you may copy this launcher into your '''$PATH''',&lt;br /&gt;
like to '''/usr/local/bin'''):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/pymol-svn/pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Problems ==&lt;br /&gt;
&lt;br /&gt;
* gcc-4.5 is broken for pymol install, use gcc-4.4 (Mint11 Linux, PyMOL 1.4.1, reported by [[User:Tlinnet]])&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential gcc-4.4 g++-4.4&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you get an error message &amp;quot;ImportError: No module named Pmw&amp;quot; and lack half of the user interface, then run the additional command&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python setup2.py install pmw&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:to install a copy of the Python MegaWidgets.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu/Mint Compile and install with MPEG support ==&lt;br /&gt;
Make a text file &amp;quot;installpymol.sh&amp;quot; and make it executable&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x installpymol.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put this in the file, modify the first 3 lines&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
pymolsvn=/home/tlinnet/Software/pymol/svnpymol&lt;br /&gt;
pymoldir=/home/tlinnet/Software/pymol&lt;br /&gt;
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol&lt;br /&gt;
 &lt;br /&gt;
###################################################&lt;br /&gt;
[ -d $pymoldir ] || mkdir $pymoldir&lt;br /&gt;
[ -d $pymolsvn ] || mkdir $pymolsvn&lt;br /&gt;
[ -d $pymoldir/wikiscripts ] || mkdir $pymoldir/wikiscripts&lt;br /&gt;
 &lt;br /&gt;
sudo apt-get install subversion build-essential python-dev python-pmw \&lt;br /&gt;
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev&lt;br /&gt;
 &lt;br /&gt;
# gcc 4.5 broken for install in ubuntu&lt;br /&gt;
sudo apt-get install gcc-4.4 g++-4.4&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
 &lt;br /&gt;
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol $pymolsvn&lt;br /&gt;
 &lt;br /&gt;
modules=$pymoldir/modules&lt;br /&gt;
cd $pymolsvn&lt;br /&gt;
python setup.py build&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
sudo python setup2.py install&lt;br /&gt;
install $pymolsvn/pymol $pymoldir/&lt;br /&gt;
 &lt;br /&gt;
## To add a path/folder where you can put pymol wikiscripts&lt;br /&gt;
t=&amp;quot;'&amp;quot;&lt;br /&gt;
echo &amp;quot;import sys&amp;quot; &amp;gt;&amp;gt; ~/.pymolrc&lt;br /&gt;
echo &amp;quot;sys.path.append($t$pymoldir/wikiscripts$t)&amp;quot; &amp;gt;&amp;gt; ~/.pymolrc&lt;br /&gt;
 &lt;br /&gt;
########## Setup freemol - for MPEG support ############&lt;br /&gt;
[ -d $pymolsvn ] || mkdir $freemolsvn&lt;br /&gt;
svn co svn://bioinformatics.org/svnroot/freemol/trunk $freemolsvn&lt;br /&gt;
 &lt;br /&gt;
cd $freemolsvn/src/mpeg_encode&lt;br /&gt;
export FREEMOL=$freemolsvn/freemol&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
 &lt;br /&gt;
## Make a shortcut to export freemol and then execute pymol&lt;br /&gt;
echo '#!/bin/bash' &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
echo &amp;quot;export FREEMOL=$freemolsvn/freemol&amp;quot; &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
echo &amp;quot;#$pymoldir/pymol&amp;quot; &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
tail -n +2 $pymoldir/pymol &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
chmod u+x $pymoldir/pymolMPEG.sh &lt;br /&gt;
 &lt;br /&gt;
## Make a link, so we can call execute pymol&lt;br /&gt;
sudo ln -s $pymoldir/pymolMPEG.sh /usr/bin/pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Update script ===&lt;br /&gt;
To pull and update PyMOL, one can make this script&lt;br /&gt;
&lt;br /&gt;
Make a text file &amp;quot;updatepymol.sh&amp;quot; and make it executable&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x updatepymol.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put this in the file, modify the first 3 lines&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
pymolsvn=/home/tlinnet/Software/pymol/svnpymol&lt;br /&gt;
pymoldir=/home/tlinnet/Software/pymol&lt;br /&gt;
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol&lt;br /&gt;
 &lt;br /&gt;
# gcc 4.5 broken for install in ubuntu&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
 &lt;br /&gt;
svn up $pymolsvn&lt;br /&gt;
svn up $freemolsvn&lt;br /&gt;
 &lt;br /&gt;
modules=$pymoldir/modules&lt;br /&gt;
cd $pymolsvn&lt;br /&gt;
python setup.py build&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
sudo python setup2.py install&lt;br /&gt;
install $pymolsvn/pymol $pymoldir/&lt;br /&gt;
 &lt;br /&gt;
########## Setup freemol - for MPEG support ############&lt;br /&gt;
cd $freemolsvn/src/mpeg_encode&lt;br /&gt;
export FREEMOL=$freemolsvn/freemol&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change MPEG settings ===&lt;br /&gt;
Change settings in&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/home/tlinnet/Software/pymol/svnfreemol/freemol/libpy/freemol/mpeg_encode.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
For example, change in line 205:&amp;lt;br&amp;gt; &lt;br /&gt;
FRAME_RATE 24&amp;lt;br&amp;gt;&lt;br /&gt;
(Not, only legal values is allowed: 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60)&lt;br /&gt;
&lt;br /&gt;
Then restart PyMOL. &lt;br /&gt;
&lt;br /&gt;
[[Category:Installation|Linux Installation]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Linux_Install&amp;diff=12460</id>
		<title>Linux Install</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Linux_Install&amp;diff=12460"/>
		<updated>2011-12-02T15:44:31Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes how to install open-source PyMOL on Linux.&lt;br /&gt;
&lt;br /&gt;
== Install Distribution-specific binary Package ==&lt;br /&gt;
&lt;br /&gt;
Many Linux distributions provide binary packages for open-source PyMOL. They often do not provide the latest version, but if the provided package fits your needs this is the most convenient way to install PyMOL.&lt;br /&gt;
&lt;br /&gt;
Command line install examples for some popular distributions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu&lt;br /&gt;
sudo apt-get install pymol&lt;br /&gt;
&lt;br /&gt;
# Fedora&lt;br /&gt;
yum install pymol&lt;br /&gt;
&lt;br /&gt;
# Gentoo&lt;br /&gt;
emerge -av pymol&lt;br /&gt;
&lt;br /&gt;
# OpenSUSE (12.1 and later)&lt;br /&gt;
sudo zypper install pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Install from Source ==&lt;br /&gt;
&lt;br /&gt;
Installation from source gives you the latest version and is the generic way to install PyMOL.&lt;br /&gt;
&lt;br /&gt;
=== Requirements ===&lt;br /&gt;
&lt;br /&gt;
Libraries as well as development files (headers) of the following software is&lt;br /&gt;
required:&lt;br /&gt;
&lt;br /&gt;
* [http://subversion.apache.org/ Subversion] to download the source code&lt;br /&gt;
* [http://www.python.org/ Python] (with distutils)&lt;br /&gt;
* [http://pmw.sf.net Pmw] (Python Megawidgets)&lt;br /&gt;
* OpenGL driver (I use [http://www.nvidia.com/object/unix.html NVidia])&lt;br /&gt;
* libpng&lt;br /&gt;
* freetype&lt;br /&gt;
&lt;br /&gt;
On many Linux systems, one of the following commands installs all requirements:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Debian/Ubuntu/Mint11&lt;br /&gt;
sudo apt-get install subversion build-essential python-dev python-pmw \&lt;br /&gt;
  libglew-dev freeglut3-dev libpng-dev libfreetype6-dev&lt;br /&gt;
&lt;br /&gt;
# Fedora&lt;br /&gt;
yum install subversion python-devel freeglut-devel freetype-devel tkinter python-pmw&lt;br /&gt;
&lt;br /&gt;
# Gentoo&lt;br /&gt;
emerge -av dev-vcs/subversion dev-lang/python dev-python/pmw media-libs/glew \&lt;br /&gt;
  media-libs/freeglut media-libs/libpng media-libs/freetype&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Get latest Source from SVN ===&lt;br /&gt;
&lt;br /&gt;
This will download the latest source to '''/tmp/pymol''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
cd /tmp&lt;br /&gt;
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol pymol&lt;br /&gt;
cd pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compile and install ===&lt;br /&gt;
&lt;br /&gt;
This will install PyMOL as normal user into '''/opt/pymol-svn'''. If you don't have write permissions to '''/opt''', change the &amp;lt;code&amp;gt;prefix&amp;lt;/code&amp;gt; variable to something like '''$HOME/pymol-svn'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
&lt;br /&gt;
prefix=/opt/pymol-svn&lt;br /&gt;
modules=$prefix/modules&lt;br /&gt;
&lt;br /&gt;
python setup.py build install \&lt;br /&gt;
    --home=$prefix \&lt;br /&gt;
    --install-purelib=$modules \&lt;br /&gt;
    --install-platlib=$modules&lt;br /&gt;
&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
python setup2.py install&lt;br /&gt;
install pymol $prefix/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now launch PyMOL like this (you may copy this launcher into your '''$PATH''',&lt;br /&gt;
like to '''/usr/local/bin'''):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/opt/pymol-svn/pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Problems ==&lt;br /&gt;
&lt;br /&gt;
* gcc-4.5 is broken for pymol install, use gcc-4.4 (Mint11 Linux, PyMOL 1.4.1, reported by [[User:Tlinnet]])&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install build-essential gcc-4.4 g++-4.4&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If you get an error message &amp;quot;ImportError: No module named Pmw&amp;quot; and lack half of the user interface, then run the additional command&lt;br /&gt;
:&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python setup2.py install pmw&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:to install a copy of the Python MegaWidgets.&lt;br /&gt;
&lt;br /&gt;
== Ubuntu/Mint Compile and install with MPEG support ==&lt;br /&gt;
Make a text file &amp;quot;installpymol.sh&amp;quot; and make it executable&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x installpymol.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put this in the file, modify the first 3 lines&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
pymolsvn=/home/tlinnet/Software/pymol/svnpymol&lt;br /&gt;
pymoldir=/home/tlinnet/Software/pymol&lt;br /&gt;
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol&lt;br /&gt;
 &lt;br /&gt;
###################################################&lt;br /&gt;
[ -d $pymoldir ] || mkdir $pymoldir&lt;br /&gt;
[ -d $pymolsvn ] || mkdir $pymolsvn&lt;br /&gt;
[ -d $pymoldir/wikiscripts ] || mkdir $pymoldir/wikiscripts&lt;br /&gt;
 &lt;br /&gt;
sudo apt-get install subversion build-essential python-dev python-pmw \&lt;br /&gt;
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev&lt;br /&gt;
 &lt;br /&gt;
# gcc 4.5 broken for install in ubuntu&lt;br /&gt;
sudo apt-get install gcc-4.4 g++-4.4&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
 &lt;br /&gt;
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol $pymolsvn&lt;br /&gt;
 &lt;br /&gt;
modules=$pymoldir/modules&lt;br /&gt;
cd $pymolsvn&lt;br /&gt;
python setup.py build&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
sudo python setup2.py install&lt;br /&gt;
install $pymolsvn/pymol $pymoldir/&lt;br /&gt;
 &lt;br /&gt;
## To add a path/folder where you can put pymol wikiscripts&lt;br /&gt;
t=&amp;quot;'&amp;quot;&lt;br /&gt;
echo &amp;quot;import sys&amp;quot; &amp;gt;&amp;gt; ~/.pymolrc&lt;br /&gt;
echo &amp;quot;sys.path.append($t$pymoldir/wikiscripts$t)&amp;quot; &amp;gt;&amp;gt; ~/.pymolrc&lt;br /&gt;
 &lt;br /&gt;
########## Setup freemol - for MPEG support ############&lt;br /&gt;
[ -d $pymolsvn ] || mkdir $freemolsvn&lt;br /&gt;
svn co svn://bioinformatics.org/svnroot/freemol/trunk $freemolsvn&lt;br /&gt;
 &lt;br /&gt;
cd $freemolsvn/src/mpeg_encode&lt;br /&gt;
export FREEMOL=$freemolsvn/freemol&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
 &lt;br /&gt;
## Make a shortcut to export freemol and then execute pymol&lt;br /&gt;
echo '#!/bin/bash' &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
echo &amp;quot;export FREEMOL=$freemolsvn/freemol&amp;quot; &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
echo &amp;quot;#$pymoldir/pymol&amp;quot; &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
tail -n +2 $pymoldir/pymol &amp;gt;&amp;gt; $pymoldir/pymolMPEG.sh&lt;br /&gt;
chmod u+x $pymoldir/pymolMPEG.sh &lt;br /&gt;
 &lt;br /&gt;
## Make a link, so we can call execute pymol&lt;br /&gt;
sudo ln -s $pymoldir/pymolMPEG.sh /usr/bin/pymol&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Update script ===&lt;br /&gt;
To pull and update PyMOL, one can make this script&lt;br /&gt;
&lt;br /&gt;
Make a text file &amp;quot;updatepymol.sh&amp;quot; and make it executable&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
chmod u+x updatepymol.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put this in the file, modify the first 3 lines&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash -e&lt;br /&gt;
pymolsvn=/home/tlinnet/Software/pymol/svnpymol&lt;br /&gt;
pymoldir=/home/tlinnet/Software/pymol&lt;br /&gt;
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol&lt;br /&gt;
 &lt;br /&gt;
# gcc 4.5 broken for install in ubuntu&lt;br /&gt;
export CC=/usr/bin/gcc-4.4&lt;br /&gt;
 &lt;br /&gt;
svn up $pymolsvn&lt;br /&gt;
svn up $freemolsvn&lt;br /&gt;
 &lt;br /&gt;
modules=$pymoldir/modules&lt;br /&gt;
cd $pymolsvn&lt;br /&gt;
python setup.py build&lt;br /&gt;
sudo python setup.py install&lt;br /&gt;
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules&lt;br /&gt;
export PYTHONPATH=$modules:$PYTHONPATH&lt;br /&gt;
sudo python setup2.py install&lt;br /&gt;
install $pymolsvn/pymol $pymoldir/&lt;br /&gt;
 &lt;br /&gt;
########## Setup freemol - for MPEG support ############&lt;br /&gt;
cd $freemolsvn/src/mpeg_encode&lt;br /&gt;
export FREEMOL=$freemolsvn/freemol&lt;br /&gt;
./configure&lt;br /&gt;
make&lt;br /&gt;
make install&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change MPEG settings ===&lt;br /&gt;
Change settings in&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
/home/tlinnet/Software/pymol/svnfreemol/freemol/libpy/freemol/mpeg_encode.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
For example, change in line 205:&amp;lt;br&amp;gt; &lt;br /&gt;
FRAME_RATE 24&amp;lt;br&amp;gt;&lt;br /&gt;
(Not, only legal values is allowed: 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60)&lt;br /&gt;
&lt;br /&gt;
Then restart PyMOL. &lt;br /&gt;
&lt;br /&gt;
[[Category:Installation|Linux Installation]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=System&amp;diff=9037</id>
		<title>System</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=System&amp;diff=9037"/>
		<updated>2010-05-05T00:38:10Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* PYMOL API */ correct arguments&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The '''system''' command, executes a command in a subshell under Unix or Windows.&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# execute 'command'&lt;br /&gt;
system command&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===PYMOL API===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
cmd.system(string command,int async=0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===NOTES===&lt;br /&gt;
async can only be specified from the Python level (not the command language)&lt;br /&gt;
*if async is 0 (default), then the result code from &amp;quot;system&amp;quot; is returned in r &lt;br /&gt;
*if async is 1, then the command is run in a separate thread whose object is returned&lt;br /&gt;
 &lt;br /&gt;
===SEE ALSO===&lt;br /&gt;
[[ls]], [[cd]], [[pwd]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commands|System]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Connect_mode&amp;diff=7601</id>
		<title>Connect mode</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Connect_mode&amp;diff=7601"/>
		<updated>2010-04-22T20:02:06Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: Created page with '= Overview = Sets how bonds are made when loading a file.  Values: * 0 = distance-based and CONECT records * 1 = CONECT records * 2 = distance-based * 3 = (who knows, the code is…'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
Sets how bonds are made when loading a file.&lt;br /&gt;
&lt;br /&gt;
Values:&lt;br /&gt;
* 0 = distance-based and CONECT records&lt;br /&gt;
* 1 = CONECT records&lt;br /&gt;
* 2 = distance-based&lt;br /&gt;
* 3 = (who knows, the code is complicated)&lt;br /&gt;
&lt;br /&gt;
= Syntax =&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# ignore CONECT records&lt;br /&gt;
set connect_mode, 2&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= See Also =&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Kabsch&amp;diff=12166</id>
		<title>Kabsch</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Kabsch&amp;diff=12166"/>
		<updated>2010-02-14T19:17:43Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* The Code */ indentation changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Intro==&lt;br /&gt;
The Kabsch algorithm uses linear and vector algebra to find the optimal rotation and translation of two sets of points in N-dimensional space as to minimize the RMSD between them.  The following program is a Python implementation of the Kabsch algorithm.&lt;br /&gt;
&lt;br /&gt;
This program when called will align the two selections, optimally, convert the proteins in the selection to ribbons and change the color of the selections to show the matched alignments.&lt;br /&gt;
&lt;br /&gt;
'''WHAT THIS DOESN'T DO''': This program does NOT provide a pairwise alignment of two structures from scratch.  You have to tell it what the equivlanced items are.  See [[Cealign]].&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' This has '''NOT''' been tested on any other machine than mine, by me.  It works on all PyMols 0.97 and newer (haven't tested earlier versions) and I use Python 2.3's Numeric Version 23.3.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' I have added new Kabsch code.  The new code uses SVD, and fixed an old bug.  For ease of use, try the new code (requires numpy, though).&lt;br /&gt;
&lt;br /&gt;
==To use==&lt;br /&gt;
&lt;br /&gt;
# Save this script to Kabsch.py&lt;br /&gt;
# Open PyMol&lt;br /&gt;
# Load the alignment script: '''run Kabsch.py'''  (The command '''optAlign''' is now defined in PyMol.)&lt;br /&gt;
# Load your proteins&lt;br /&gt;
# Align the proper segments (see below examples)&lt;br /&gt;
&lt;br /&gt;
To align two equivalent sets of residues do:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
optAlign SEL1 and n. CA and i. a-b, SEL2 and n. CA and i. c-d&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
where&lt;br /&gt;
* '''SEL1''' is the first protein&lt;br /&gt;
* '''a-b''' is the range of residues to align in the first protein&lt;br /&gt;
* '''SEL2''' is the second protein&lt;br /&gt;
* '''c-d''' is the range of residues to align in the second protein&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
* Ensure that you're equivalencing '''N''' atoms to '''N''' atoms (run [[Count_Atoms]] over your two selections to ensure they are the same length).&lt;br /&gt;
* Sometimes PyMol doesn't seem to superimpose them right the first time.  Hit the up-arrow and rerun the program if this happens.  It always superimposes the correctly the second time.  I think it has something to do with the orientation.  I'll fix this when I find the error.&lt;br /&gt;
* The RMSD is only between the equivlanced atoms.  Use PyMol's [[Rms_Cur]] if you want a full RMSD.&lt;br /&gt;
* Make sure your atom selections are numbered correctly.  Many times PDB files start residue numbers at something other than 0 or 1.  To ensure you're aligning the right things, do &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;set seq_view,1&amp;lt;/source&amp;gt; to turn on the sequence viewer and double check your residue numbers.  If a protein has residue one numbered as something other than one, say 2064, simply run &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;alter (SEL), resi=str(int(resi)-2064)&amp;lt;/source&amp;gt; and then &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;sort&amp;lt;/source&amp;gt; where '''SEL''' is the name of the protein and 2064 is the offset to adjust by.  Your protein will now work as needed.  See [[Alter]].  This capability is also provided in a script; See [[zero_residues]].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Windows users are having problems running the script.  Python tells them first off &amp;quot;TypeError: Can't convert rank-0 arrays to Python scalars.&amp;quot;  The fix to that breaks some code in Numeric -- which I don't maintain.&amp;lt;/li&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;However, to make this work, you can change the code in &amp;lt;b&amp;gt;Numeric.py&amp;lt;/b&amp;gt; supplied with Pymol, located in the folder &amp;quot;&amp;lt;Pymol Home&amp;gt;\modules\Numeric\&amp;quot; (for example:  &amp;quot;C:\Program Files\DeLano Scientific\PyMOL\modules\Numeric&amp;quot;).&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Essentially, you need to search for the line: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt; if axis2 &amp;lt; 0: axis2 = axis1 + n  # (should be around line 250) &amp;lt;/source&amp;gt; and replace it with: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;if axis2 &amp;lt; 0: axis2 = axis2 + n &amp;lt;/source&amp;gt;&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Examples===&lt;br /&gt;
 optAlign 1cll and n. CA and i. 4-20+30-60, 1ggz and n. CA and i. 4-20+30-60&lt;br /&gt;
&lt;br /&gt;
 optAlign 1kao and n. CA and i. 20-50, 1ctq and n. CA and i. 20-50&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:OptAlign1.png|1cll and 1ggz loaded&lt;br /&gt;
Image:OptAlign2.png|1cll and 1ggz aligned to residues 5-50+55-80 shown in red&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kabsch can also align hetero-atoms:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
load 1cll.pdb&lt;br /&gt;
load 1ggz.pdb&lt;br /&gt;
optAlign 1cll and e. CA, 1ggz and e. CA&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The above aligns the 4 Calciums in each structure.&lt;br /&gt;
&lt;br /&gt;
==The Code==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!python&lt;br /&gt;
 &lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# @SUMMARY: -- QKabsch.py.  A python implementation of the optimal superposition&lt;br /&gt;
#     of two sets of vectors as proposed by Kabsch 1976 &amp;amp; 1978.&lt;br /&gt;
#&lt;br /&gt;
# @AUTHOR: Jason Vertrees&lt;br /&gt;
# @COPYRIGHT: Jason Vertrees (C), 2005-2007&lt;br /&gt;
# @LICENSE: Released under GPL:&lt;br /&gt;
# This program is free software; you can redistribute it and/or modify&lt;br /&gt;
#    it under the terms of the GNU General Public License as published by&lt;br /&gt;
#    the Free Software Foundation; either version 2 of the License, or&lt;br /&gt;
#    (at your option) any later version.&lt;br /&gt;
# This program is distributed in the hope that it will be useful, but WITHOUT&lt;br /&gt;
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS&lt;br /&gt;
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.&lt;br /&gt;
#&lt;br /&gt;
# You should have received a copy of the GNU General Public License along with&lt;br /&gt;
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin&lt;br /&gt;
# Street, Fifth Floor, Boston, MA 02110-1301, USA &lt;br /&gt;
#&lt;br /&gt;
# DATE  : 2007-01-01&lt;br /&gt;
# REV   : 2&lt;br /&gt;
# REQUIREMENTS: numpy&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
from array import *&lt;br /&gt;
 &lt;br /&gt;
# system stuff&lt;br /&gt;
import os&lt;br /&gt;
import copy&lt;br /&gt;
 &lt;br /&gt;
# pretty printing&lt;br /&gt;
import pprint&lt;br /&gt;
 &lt;br /&gt;
# for importing as a plugin into PyMol&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
from pymol import stored&lt;br /&gt;
from pymol import selector&lt;br /&gt;
 &lt;br /&gt;
# using numpy for linear algebra&lt;br /&gt;
import numpy&lt;br /&gt;
 &lt;br /&gt;
def optAlign( sel1, sel2 ):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	optAlign performs the Kabsch alignment algorithm upon the alpha-carbons of two selections.&lt;br /&gt;
	Example:   optAlign MOL1 and i. 20-40, MOL2 and i. 102-122&lt;br /&gt;
	Example 2: optAlign 1GGZ and i. 4-146 and n. CA, 1CLL and i. 4-146 and n. CA&lt;br /&gt;
 &lt;br /&gt;
	Two RMSDs are returned.  One comes from the Kabsch algorithm and the other from&lt;br /&gt;
	PyMol based upon your selections.&lt;br /&gt;
 &lt;br /&gt;
	By default, this program will optimally align the ALPHA CARBONS of the selections provided.&lt;br /&gt;
	To turn off this feature remove the lines between the commented &amp;quot;REMOVE ALPHA CARBONS&amp;quot; below.&lt;br /&gt;
 &lt;br /&gt;
	@param sel1: First PyMol selection with N-atoms&lt;br /&gt;
	@param sel2: Second PyMol selection with N-atoms&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	cmd.reset()&lt;br /&gt;
 &lt;br /&gt;
	# make the lists for holding coordinates&lt;br /&gt;
	# partial lists&lt;br /&gt;
	stored.sel1 = []&lt;br /&gt;
	stored.sel2 = []&lt;br /&gt;
	# full lists&lt;br /&gt;
	stored.mol1 = []&lt;br /&gt;
	stored.mol2 = []&lt;br /&gt;
 &lt;br /&gt;
	# -- CUT HERE&lt;br /&gt;
	sel1 = sel1 + &amp;quot; and N. CA&amp;quot;&lt;br /&gt;
	sel2 = sel2 + &amp;quot; and N. CA&amp;quot;&lt;br /&gt;
	# -- CUT HERE&lt;br /&gt;
 &lt;br /&gt;
	# Get the selected coordinates.  We&lt;br /&gt;
	# align these coords.&lt;br /&gt;
	cmd.iterate_state(1, selector.process(sel1), &amp;quot;stored.sel1.append([x,y,z])&amp;quot;)&lt;br /&gt;
	cmd.iterate_state(1, selector.process(sel2), &amp;quot;stored.sel2.append([x,y,z])&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
	# get molecule name&lt;br /&gt;
	mol1 = cmd.identify(sel1,1)[0][0]&lt;br /&gt;
	mol2 = cmd.identify(sel2,1)[0][0]&lt;br /&gt;
 &lt;br /&gt;
	# Get all molecule coords.  We do this because&lt;br /&gt;
	# we have to rotate the whole molcule, not just&lt;br /&gt;
	# the aligned selection&lt;br /&gt;
	cmd.iterate_state(1, mol1, &amp;quot;stored.mol1.append([x,y,z])&amp;quot;)&lt;br /&gt;
	cmd.iterate_state(1, mol2, &amp;quot;stored.mol2.append([x,y,z])&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
	# check for consistency&lt;br /&gt;
	assert( len(stored.sel1) == len(stored.sel2))&lt;br /&gt;
	L = len(stored.sel1)&lt;br /&gt;
	assert( L &amp;gt; 0 )&lt;br /&gt;
 &lt;br /&gt;
	# must alway center the two proteins to avoid&lt;br /&gt;
	# affine transformations.  Center the two proteins&lt;br /&gt;
	# to their selections.&lt;br /&gt;
	COM1 = numpy.sum(stored.sel1,axis=0) / float(L)&lt;br /&gt;
	COM2 = numpy.sum(stored.sel2,axis=0) / float(L)&lt;br /&gt;
	stored.sel1 = stored.sel1 - COM1&lt;br /&gt;
	stored.sel2 = stored.sel2 - COM2&lt;br /&gt;
 &lt;br /&gt;
	# Initial residual, see Kabsch.&lt;br /&gt;
	E0 = numpy.sum( numpy.sum(stored.sel1 * stored.sel1,axis=0),axis=0) + numpy.sum( numpy.sum(stored.sel2 * stored.sel2,axis=0),axis=0)&lt;br /&gt;
 &lt;br /&gt;
	#&lt;br /&gt;
	# This beautiful step provides the answer.  V and Wt are the orthonormal&lt;br /&gt;
	# bases that when multiplied by each other give us the rotation matrix, U.&lt;br /&gt;
	# S, (Sigma, from SVD) provides us with the error!  Isn't SVD great!&lt;br /&gt;
	V, S, Wt = numpy.linalg.svd( numpy.dot( numpy.transpose(stored.sel2), stored.sel1))&lt;br /&gt;
 &lt;br /&gt;
	# we already have our solution, in the results from SVD.&lt;br /&gt;
	# we just need to check for reflections and then produce&lt;br /&gt;
	# the rotation.  V and Wt are orthonormal, so their det's&lt;br /&gt;
	# are +/-1.&lt;br /&gt;
	reflect = float(str(float(numpy.linalg.det(V) * numpy.linalg.det(Wt))))&lt;br /&gt;
 &lt;br /&gt;
	if reflect == -1.0:&lt;br /&gt;
		S[-1] = -S[-1]&lt;br /&gt;
		V[:,-1] = -V[:,-1]&lt;br /&gt;
 &lt;br /&gt;
	RMSD = E0 - (2.0 * sum(S))&lt;br /&gt;
	RMSD = numpy.sqrt(abs(RMSD / L))&lt;br /&gt;
 &lt;br /&gt;
	#U is simply V*Wt&lt;br /&gt;
	U = numpy.dot(V, Wt)&lt;br /&gt;
 &lt;br /&gt;
	# rotate and translate the molecule&lt;br /&gt;
	stored.sel2 = numpy.dot((stored.mol2 - COM2), U)&lt;br /&gt;
	stored.sel2 = stored.sel2.tolist()&lt;br /&gt;
	# center the molecule&lt;br /&gt;
	stored.sel1 = stored.mol1 - COM1&lt;br /&gt;
	stored.sel1 = stored.sel1.tolist()&lt;br /&gt;
 &lt;br /&gt;
	# let PyMol know about the changes to the coordinates&lt;br /&gt;
	cmd.alter_state(1,mol1,&amp;quot;(x,y,z)=stored.sel1.pop(0)&amp;quot;)&lt;br /&gt;
	cmd.alter_state(1,mol2,&amp;quot;(x,y,z)=stored.sel2.pop(0)&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
	print &amp;quot;RMSD=%f&amp;quot; % RMSD&lt;br /&gt;
 &lt;br /&gt;
	# make the alignment OBVIOUS&lt;br /&gt;
	cmd.hide('everything')&lt;br /&gt;
	cmd.show('ribbon', sel1 + ' or ' + sel2)&lt;br /&gt;
	cmd.color('gray70', mol1 )&lt;br /&gt;
	cmd.color('paleyellow', mol2 )&lt;br /&gt;
	cmd.color('red', 'visible')&lt;br /&gt;
	cmd.show('ribbon', 'not visible')&lt;br /&gt;
	cmd.center('visible')&lt;br /&gt;
	cmd.orient()&lt;br /&gt;
	cmd.zoom('visible')&lt;br /&gt;
 &lt;br /&gt;
cmd.extend(&amp;quot;optAlign&amp;quot;, optAlign)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The Old Code ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!python&lt;br /&gt;
&lt;br /&gt;
##############################################################################&lt;br /&gt;
#&lt;br /&gt;
# @SUMMARY: -- Kabsch.py.  A python implementation of the optimal superposition&lt;br /&gt;
#     of two sets of vectors as proposed by Kabsch 1976 &amp;amp; 1978.&lt;br /&gt;
#&lt;br /&gt;
# @AUTHOR: Jason Vertrees&lt;br /&gt;
# @COPYRIGHT: Jason Vertrees (C), 2005-2007&lt;br /&gt;
# @LICENSE: Released under GPL:&lt;br /&gt;
# This program is free software; you can redistribute it and/or modify&lt;br /&gt;
#    it under the terms of the GNU General Public License as published by&lt;br /&gt;
#    the Free Software Foundation; either version 2 of the License, or&lt;br /&gt;
#    (at your option) any later version.&lt;br /&gt;
# This program is distributed in the hope that it will be useful, but WITHOUT&lt;br /&gt;
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS&lt;br /&gt;
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.&lt;br /&gt;
#&lt;br /&gt;
# You should have received a copy of the GNU General Public License along with&lt;br /&gt;
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin&lt;br /&gt;
# Street, Fifth Floor, Boston, MA 02110-1301, USA &lt;br /&gt;
#&lt;br /&gt;
# DATE  : 2005-04-07&lt;br /&gt;
# REV   : 2&lt;br /&gt;
# NOTES: Updated RMSD, notes, cleaned up the code a little.&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
# math imports&lt;br /&gt;
import math&lt;br /&gt;
import Numeric&lt;br /&gt;
import LinearAlgebra&lt;br /&gt;
import Matrix&lt;br /&gt;
&lt;br /&gt;
from array import *&lt;br /&gt;
&lt;br /&gt;
# system stuff&lt;br /&gt;
import os&lt;br /&gt;
import copy&lt;br /&gt;
&lt;br /&gt;
# pretty printing&lt;br /&gt;
import pprint&lt;br /&gt;
&lt;br /&gt;
# for importing as a plugin into PyMol&lt;br /&gt;
#import tkSimpleDialog&lt;br /&gt;
#import tkMessageBox&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
from pymol import stored&lt;br /&gt;
from pymol import selector&lt;br /&gt;
&lt;br /&gt;
class kabsch:&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	Kabsch alignment of two set of vectors to produce and optimal alignemnt.&lt;br /&gt;
&lt;br /&gt;
	Steps&lt;br /&gt;
	=====	&lt;br /&gt;
		1.  Calculate the center of mass for each protein.  Then, move the protein&lt;br /&gt;
		to its center of mass.  We choose as a convention, to use the origin as &lt;br /&gt;
		the center of mass of the first set of coordinates.  This will allow us to&lt;br /&gt;
		return one translation vector, instead of two.&lt;br /&gt;
		&lt;br /&gt;
		Update: Since any rotation around a point that's not the origin, is in fact&lt;br /&gt;
		an affine rotation.  So, to beat that, we translate both to the center.&lt;br /&gt;
		&lt;br /&gt;
		NAME: superpose(c1, c2)&lt;br /&gt;
		POST: T is now defined.&lt;br /&gt;
		&lt;br /&gt;
		2.  Calculate the matrix, R, by (eq7, 1976).  r_{i,j} = sum_n w_n * y_{ni} * x_{nj},&lt;br /&gt;
		where y_{ni} is the ith component of the vector y_n.&lt;br /&gt;
		NAME: calcR&lt;br /&gt;
		POST: R is now defined&lt;br /&gt;
		&lt;br /&gt;
		3.  Calculate RtR (R-transpose * R).&lt;br /&gt;
		NAME: calcRtR&lt;br /&gt;
		POST: RtR is now defined&lt;br /&gt;
		&lt;br /&gt;
		4.  Calculate the corresponding eigenpairs for RtR, and sort them accordingly:&lt;br /&gt;
		m1 &amp;gt;= m2 &amp;gt;= m3; set v3 = v1 x v2 to ensure a RHS&lt;br /&gt;
		NAME: calcEigenPairs&lt;br /&gt;
		POST: The eigen pairs are calculated, sorted such that m1 &amp;gt;= m2 &amp;gt;= m3 and&lt;br /&gt;
		v3 = v1 x v2.&lt;br /&gt;
		&lt;br /&gt;
		5.  Calculate R*v_k and normalize the first two vectors to obtain b_1, b_2 and set&lt;br /&gt;
		b_3 = b_1 x b_2.  This also takes care of m1 &amp;gt; m2 = 0. &lt;br /&gt;
		NAME: calcBVectors&lt;br /&gt;
		POST: b-Vectors are defined and returned&lt;br /&gt;
		&lt;br /&gt;
		6.  Calculate U=(u_{ij})=(sum n b_{ki} * a_{kj}) to obtain the best rotation.  Set&lt;br /&gt;
		sigma_3 = -1 if b3(Ra3) &amp;lt; 0 else sigma_3 = +1.&lt;br /&gt;
		NAME: calcU&lt;br /&gt;
		POST: U is defined&lt;br /&gt;
		&lt;br /&gt;
		7.  Calculate the RMSD.  The residual error is then&lt;br /&gt;
		The E = E0 - sqrt(m1) - sqrt(m2) - sigma_3(sqrt(m3)).&lt;br /&gt;
		NAME: calcRMSD&lt;br /&gt;
		POST: RMSD is computed.&lt;br /&gt;
	&lt;br /&gt;
	 @note: This should be a static method that takes three parameters&lt;br /&gt;
		&lt;br /&gt;
		1. The first protein's coordinates, f.  This program will &lt;br /&gt;
		accept coordinates in the form an array of 3D vectors/lists&lt;br /&gt;
		&lt;br /&gt;
		2. The second protein's coordinates, g.&lt;br /&gt;
		&lt;br /&gt;
		3. The array of integer pairs representing the pairs to align.&lt;br /&gt;
		Coordinates should be formatted as as array of 2D vectors/lists.&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
	def __init__(self):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Constructor.  @see kabsch.align.&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
		#&lt;br /&gt;
		# Instance Variables:  All three of these will be updated&lt;br /&gt;
		# every time the user calls ~.align.  Just to warn ya'.&lt;br /&gt;
		#		&lt;br /&gt;
		# U, the rotation matrix&lt;br /&gt;
		self.U = []&lt;br /&gt;
		# T, the translation vector&lt;br /&gt;
		self.T = []&lt;br /&gt;
		# R, the RMSD&lt;br /&gt;
		self.R = -1.0&lt;br /&gt;
&lt;br /&gt;
		#self.menuBar.addmenuitem('Plugin', 'command', 'Kabsch Align', label = &amp;quot;Align Selections to Optial RMSD&amp;quot;, command = lamda s=self: fetchPDBDialog(s))&lt;br /&gt;
		&lt;br /&gt;
				&lt;br /&gt;
	def align(self, c1, c2, pairs):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Finds the best alignment of c1 and c2's pairs resulting in&lt;br /&gt;
		the smallest possible RMSD.&lt;br /&gt;
&lt;br /&gt;
				&lt;br /&gt;
		@note:&lt;br /&gt;
			- All weights in this first version are set to 1.  Kabsch allows,&lt;br /&gt;
			differential weighting.  In the future, I may extend to this option,&lt;br /&gt;
			and then pairs may become 3D (r1, r2, weight) or I may add another&lt;br /&gt;
			parameter.&lt;br /&gt;
		&lt;br /&gt;
			- Helper functions will soon be provided such that the user may&lt;br /&gt;
			just use this package alone to compute the rotation.&lt;br /&gt;
		&lt;br /&gt;
		@param c1: coordinats of the first vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c1: Python list&lt;br /&gt;
		   &lt;br /&gt;
		@param c2: coordinates of the second set of vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c2: Python list&lt;br /&gt;
		   &lt;br /&gt;
		@param pairs: the list of pairs as an array of 2D pairs.&lt;br /&gt;
		@type  pairs: Python list of 2D lists.&lt;br /&gt;
		&lt;br /&gt;
		@return: U, the rotation matrix that gives the optimal rotation between the two proteins.&lt;br /&gt;
			&lt;br /&gt;
			T, the translation vector given to align the two objects centers of mass.&lt;br /&gt;
			&lt;br /&gt;
			R, the RMSD of the final rotation.&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		#&lt;br /&gt;
		# First we move the center of mass of one protein, to the&lt;br /&gt;
		# center of mass of the other.  This removes any translation&lt;br /&gt;
		# between the two.&lt;br /&gt;
		#&lt;br /&gt;
		T1, T2, c1, c2 = self.superpose(c1, c2)&lt;br /&gt;
		# Calculate the initial RMSD&lt;br /&gt;
		E0 = self.calcE0(c1, c2)&lt;br /&gt;
		# Calculate R via eq. 7.&lt;br /&gt;
		R = self.calcR(c1, c2)&lt;br /&gt;
		# Calculate R(transpose)*R&lt;br /&gt;
		RtR = self.calcRtR(R)&lt;br /&gt;
		# Determined the eigenpairs for the matrix RtR.&lt;br /&gt;
		eValues, eVectors = self.calcEigenPairs(RtR)&lt;br /&gt;
		# Determine the bVectors as required&lt;br /&gt;
		bVectors = self.calcBVectors(R, eVectors)&lt;br /&gt;
		# Calculate the roation matrix&lt;br /&gt;
		U = self.calcU(eVectors, bVectors)&lt;br /&gt;
		# Calculate the final RMSD using U.&lt;br /&gt;
		RMSD = self.calcRMSD(E0, eValues, eVectors, bVectors, R, len(c1))&lt;br /&gt;
		&lt;br /&gt;
		return U, T1, T2, RMSD, c1, c2&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
	def superpose(self, c1, c2 ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate the center of mass for each protein.  Then, move the protein&lt;br /&gt;
		to its center of mass.  We choose as a convention, to use the origin as &lt;br /&gt;
		the center of mass of the first set of coordinates.  This will allow us to&lt;br /&gt;
		return one translation vector, instead of two.&lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@precondition: c1 and c2 are well defined lists of N-dimensional points with length &amp;gt; 0.&lt;br /&gt;
		@postcondition: T is now defined.&lt;br /&gt;
		&lt;br /&gt;
		@param c1: coordinats of the first vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c1: Python list&lt;br /&gt;
		   &lt;br /&gt;
		@param c2: coordinates of the second set of vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c2: Python list&lt;br /&gt;
		&lt;br /&gt;
		@return: T the translation vector.&lt;br /&gt;
		&lt;br /&gt;
			c2 one list of coordinates that of c2 translated to the COM of c1.&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		# make sure we don't get bad data&lt;br /&gt;
		if (len(c1) != len(c2)):&lt;br /&gt;
			print &amp;quot;Two different length selections, with lengths, %d and %d.&amp;quot; % (len(c1), len(c2))&lt;br /&gt;
			print &amp;quot;This algorithm must be used with selections of the same length.&amp;quot;	&lt;br /&gt;
			print &amp;quot;In PyMol, type 'count_atoms sel1' where sel1 are your selections to find out their lengths.&amp;quot;&lt;br /&gt;
			print &amp;quot;Example:   optAlign MOL1 and i. 20-40, MOL2 and i. 102-122&amp;quot;&lt;br /&gt;
        		print &amp;quot;Example 2: optAlign 1GGZ and i. 4-146 and n. CA, 1CLL and i. 4-146 and n. CA&amp;quot;&lt;br /&gt;
&lt;br /&gt;
			&lt;br /&gt;
		assert(len(c1) == len(c2) != 0)&lt;br /&gt;
&lt;br /&gt;
		L = len(c1)&lt;br /&gt;
		&lt;br /&gt;
		#&lt;br /&gt;
		# Centers of Mass&lt;br /&gt;
		#&lt;br /&gt;
		c1COM = Numeric.zeros((3,1), Numeric.Float64)&lt;br /&gt;
		c2COM = Numeric.zeros((3,1), Numeric.Float64)&lt;br /&gt;
&lt;br /&gt;
		# calculate the CsOM		&lt;br /&gt;
		for i in range(0, L):&lt;br /&gt;
			for j in range(0,3):&lt;br /&gt;
				c1COM[j] = c1COM[j] + c1[i][j]&lt;br /&gt;
				c2COM[j] = c2COM[j] + c2[i][j]&lt;br /&gt;
		&lt;br /&gt;
		T1 = - c1COM / L&lt;br /&gt;
		T2 = - c2COM / L&lt;br /&gt;
&lt;br /&gt;
		# move everything back to the origin.&lt;br /&gt;
		for i in range(0, L):&lt;br /&gt;
			for j in range(0,3):&lt;br /&gt;
				c1[i][j] = c1[i][j] + T1[j]&lt;br /&gt;
				c2[i][j] = c2[i][j] + T2[j]&lt;br /&gt;
				&lt;br /&gt;
		return T1, T2, c1, c2&lt;br /&gt;
&lt;br /&gt;
					&lt;br /&gt;
	def calcR( self, c1, c2 ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate the matrix, R, by (eq7, 1976).  M{r_{i,j} = sum_n w_n * y_{ni} * x_{nj}},&lt;br /&gt;
		where M{y_{ni}} is the ith component of the vector M{y_n}.&lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@param c1: coordinats of the first vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c1: Python list&lt;br /&gt;
		   &lt;br /&gt;
		@param c2: coordinates of the second set of vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c2: Python list&lt;br /&gt;
&lt;br /&gt;
		@postcondition: R is now defined.&lt;br /&gt;
		&lt;br /&gt;
		@return: R&lt;br /&gt;
		@rtype : 3x3 matrix&lt;br /&gt;
				&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		# Create the 3x3 matrix&lt;br /&gt;
		R = Numeric.zeros((3,3), Numeric.Float64)&lt;br /&gt;
		L = len(c1)&lt;br /&gt;
		&lt;br /&gt;
		for k in range(0, L):&lt;br /&gt;
			for i in range(0, 3):&lt;br /&gt;
				for j in range(0, 3):&lt;br /&gt;
					R[i][j] = R[i][j] + (c2[k][i] * c1[k][j])&lt;br /&gt;
		&lt;br /&gt;
		# return R the 3x3 PSD Matrix.&lt;br /&gt;
		return R&lt;br /&gt;
		&lt;br /&gt;
	&lt;br /&gt;
	def calcRtR( self, R ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate RtR (R-transpose * R).&lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@param R: Matrix&lt;br /&gt;
		@type  R: 3x3 Matrix&lt;br /&gt;
		&lt;br /&gt;
		@precondition: R is a the well formed matrix as per Kabsch.&lt;br /&gt;
		@postcondition: RtR is now defined&lt;br /&gt;
		&lt;br /&gt;
		@return: M{R^tR}&lt;br /&gt;
		@rtype : 3x3 matrix&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		RtR = Numeric.matrixmultiply(Numeric.transpose(R), R)&lt;br /&gt;
		&lt;br /&gt;
		return RtR&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	def calcEigenPairs( self, RtR ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate the corresponding eigenpairs for RtR, and sort them accordingly:&lt;br /&gt;
		M{m1 &amp;gt;= m2 &amp;gt;= m3}; set M{v3 = v1 x v2} to ensure a RHS&lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@postcondition: The eigen pairs are calculated, sorted such that M{m1 &amp;gt;= m2 &amp;gt;= m3} and&lt;br /&gt;
		M{v3 = v1 x v2}.&lt;br /&gt;
		&lt;br /&gt;
		@param RtR: 3x3 Matrix of M{R^t * R}.&lt;br /&gt;
		@type  RtR: 3x3 Matrix&lt;br /&gt;
		@return : Eigenpairs for the RtR matrix.&lt;br /&gt;
		@rtype  : List of stuff&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		eVal, eVec = LinearAlgebra.eigenvectors(RtR)&lt;br /&gt;
&lt;br /&gt;
		# This is cool.  We sort it using Numeric.sort(eVal)&lt;br /&gt;
		# then we reverse it using nifty-crazy ass notation [::-1].&lt;br /&gt;
		eVal2 = Numeric.sort(eVal)[::-1]&lt;br /&gt;
		eVec2 = [[],[],[]] #Numeric.zeros((3,3), Numeric.Float64)&lt;br /&gt;
				&lt;br /&gt;
		# Map the vectors to their appropriate owners		&lt;br /&gt;
		if ( eVal2[0] == eVal[0]):&lt;br /&gt;
			eVec2[0] = eVec[0]&lt;br /&gt;
			if ( eVal2[1] == eVal[1] ):&lt;br /&gt;
				eVec2[1] = eVec[1]&lt;br /&gt;
				eVec2[2] = eVec[2]&lt;br /&gt;
			else:&lt;br /&gt;
				eVec2[1] = eVec[2]&lt;br /&gt;
				eVec2[2] = eVec[1]&lt;br /&gt;
		elif( eVal2[0] == eVal[1]):&lt;br /&gt;
			eVec2[0] = eVec[1]&lt;br /&gt;
			if ( eVal2[1] == eVal[0] ):&lt;br /&gt;
				eVec2[1] = eVec[0]&lt;br /&gt;
				eVec2[2] = eVec[2]&lt;br /&gt;
			else:&lt;br /&gt;
				eVec2[1] = eVec[2]&lt;br /&gt;
				eVec2[2] = eVec[0]&lt;br /&gt;
		elif( eVal2[0] == eVal[2]):&lt;br /&gt;
			eVec2[0] = eVec[2]&lt;br /&gt;
			if ( eVal2[1] == eVal[1] ):&lt;br /&gt;
				eVec2[1] = eVec[1]&lt;br /&gt;
				eVec2[2] = eVec[0]&lt;br /&gt;
			else:&lt;br /&gt;
				eVec2[1] = eVec[0]&lt;br /&gt;
				eVec2[2] = eVec[1]&lt;br /&gt;
&lt;br /&gt;
		eVec2[2][0] = eVec2[0][1]*eVec2[1][2] - eVec2[0][2]*eVec2[1][1]&lt;br /&gt;
		eVec2[2][1] = eVec2[0][2]*eVec2[1][0] - eVec2[0][0]*eVec2[1][2]&lt;br /&gt;
		eVec2[2][2] = eVec2[0][0]*eVec2[1][1] - eVec2[0][1]*eVec2[1][0]&lt;br /&gt;
		&lt;br /&gt;
		return [eVal2, eVec2]&lt;br /&gt;
		&lt;br /&gt;
	&lt;br /&gt;
	def calcBVectors( self, R, eVectors ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate M{R*a_k} and normalize the first two vectors to obtain M{b_1, b_2} and set&lt;br /&gt;
		M{b_3 = b_1 x b_2}.  This also takes care of {m2 &amp;gt; m3 = 0}. &lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@postcondition: b-Vectors are defined and returned&lt;br /&gt;
		&lt;br /&gt;
		@return: The three B-vectors&lt;br /&gt;
		@rtype: List of 3D vectors (Python LOL).&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		bVectors = Numeric.zeros((3,3), Numeric.Float64)&lt;br /&gt;
&lt;br /&gt;
		for i in range(0,3):&lt;br /&gt;
			bVectors[i] = Numeric.matrixmultiply(R, eVectors[i])&lt;br /&gt;
&lt;br /&gt;
		bVectors[0] = bVectors[0] / Numeric.sqrt(Numeric.add.reduce(bVectors[0]**2))&lt;br /&gt;
		bVectors[1] = bVectors[1] / Numeric.sqrt(Numeric.add.reduce(bVectors[1]**2))&lt;br /&gt;
		bVectors[2] = bVectors[2] / Numeric.sqrt(Numeric.add.reduce(bVectors[2]**2))&lt;br /&gt;
		&lt;br /&gt;
		bVectors[2][0] = bVectors[0][1]*bVectors[1][2] - bVectors[0][2]*bVectors[1][1]&lt;br /&gt;
		bVectors[2][1] = bVectors[0][2]*bVectors[1][0] - bVectors[0][0]*bVectors[1][2]&lt;br /&gt;
		bVectors[2][2] = bVectors[0][0]*bVectors[1][1] - bVectors[0][1]*bVectors[1][0]&lt;br /&gt;
		&lt;br /&gt;
		return bVectors&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
	def calcU( self, eVectors, bVectors ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate M{U=(u_{ij})=(sum n b_{ki} * a_{kj})} to obtain the best rotation.  Set&lt;br /&gt;
		M{sigma_3 = -1 if b3(Ra3) &amp;lt; 0 else sigma_3 = +1}.&lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@postcondition: U is defined&lt;br /&gt;
		&lt;br /&gt;
		@param eVectors: Eigenvectors for the system.&lt;br /&gt;
		@type  eVectors: Eigenvectors&lt;br /&gt;
		&lt;br /&gt;
		@param bVectors: BVectors as described by Kabsch.&lt;br /&gt;
		@type  bVectors: BVectors&lt;br /&gt;
		&lt;br /&gt;
		@return: U the rotation matrix.&lt;br /&gt;
		@rtype  :3x3 matrix.&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		U = Numeric.zeros((3,3), Numeric.Float64)&lt;br /&gt;
		&lt;br /&gt;
		for k in range(0,3):&lt;br /&gt;
			for i in range(0,3):&lt;br /&gt;
				for j in range(0,3):&lt;br /&gt;
					U[i][j] = U[i][j] + Numeric.matrixmultiply(bVectors[k][i], eVectors[k][j])&lt;br /&gt;
		&lt;br /&gt;
		return U&lt;br /&gt;
	&lt;br /&gt;
		&lt;br /&gt;
	def calcE0( self, c1, c2 ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculates the initial RMSD, which Kacbsch called E0.&lt;br /&gt;
		(CORRECT)&lt;br /&gt;
		&lt;br /&gt;
		@param c1: coordinats of the first vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c1: Python list&lt;br /&gt;
		   &lt;br /&gt;
		@param c2: coordinates of the second set of vectors, as an array of 3D vectors.&lt;br /&gt;
		@type  c2: Python list&lt;br /&gt;
		&lt;br /&gt;
		@return: E0 the initial RMSD.&lt;br /&gt;
		@rtype : float.&lt;br /&gt;
				&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		E0 = 0.0&lt;br /&gt;
		&lt;br /&gt;
		L = len(c1)&lt;br /&gt;
		for i in range( 0, L ):&lt;br /&gt;
			for j in range(0, 3):&lt;br /&gt;
				E0 = E0 + 0.5*( (c1[i][j]*c1[i][j])+(c2[i][j]*c2[i][j]))&lt;br /&gt;
		&lt;br /&gt;
		return E0&lt;br /&gt;
	&lt;br /&gt;
	def calcRMSD( self, E0, eValues, eVectors, bVectors, R, N):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculate the RMSD.  The residual error is then&lt;br /&gt;
		The M{E = E0 - sqrt(m1) - sqrt(m2) - sigma_3(sqrt(m3))}.&lt;br /&gt;
		&lt;br /&gt;
		@param E0: Initial RMSD as calculated in L{calcE0}.&lt;br /&gt;
		@type  E0: float.&lt;br /&gt;
		&lt;br /&gt;
		@param eVectors: Eigenvectors as calculated from L{calcEigenPairs}&lt;br /&gt;
		@type eVectors: vectors, dammit!&lt;br /&gt;
		&lt;br /&gt;
		@param bVectors: B-vectors as calc. from L{calcBVectors}&lt;br /&gt;
		@type  bVectors: More vectors.&lt;br /&gt;
		&lt;br /&gt;
		@param R: The matrix R, from L{calcR}.&lt;br /&gt;
		@type  R: 3x3 matrix.		&lt;br /&gt;
&lt;br /&gt;
		@param N: Number of equivalenced points&lt;br /&gt;
		@type  N: integer&lt;br /&gt;
		&lt;br /&gt;
		@postcondition: RMSD is computed.&lt;br /&gt;
		@return: The RMSD.&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		sigma3 = 0&lt;br /&gt;
		if ( Numeric.matrixmultiply(bVectors[2], Numeric.matrixmultiply( R, eVectors[2])) &amp;lt; 0):&lt;br /&gt;
			sigma3 = -1&lt;br /&gt;
		else:&lt;br /&gt;
			sigma3 = 1&lt;br /&gt;
&lt;br /&gt;
		E = math.sqrt( 2*(E0 - math.sqrt(eValues[0]) - math.sqrt(eValues[1]) - sigma3*(math.sqrt(eValues[2]))) / N)&lt;br /&gt;
		&lt;br /&gt;
		return E&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
	def calcSimpleRMSD( self, c1, c2 ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Calculates the usual concept of RMSD between two set of points.  The CalcRMSD above&lt;br /&gt;
		sticks to Kabsch's alignment method protocol and calculates something much different.&lt;br /&gt;
		@see kabsch.calcRMSD&lt;br /&gt;
		&lt;br /&gt;
		@param c1: List of points #1&lt;br /&gt;
		@type  c1: LOL&lt;br /&gt;
		&lt;br /&gt;
		@param c2: List of points #2&lt;br /&gt;
		@type  c2: LOL&lt;br /&gt;
		&lt;br /&gt;
		@return: RMSD between the two&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		RMSD = 0.0&lt;br /&gt;
		for i in range(0, len(c1)):&lt;br /&gt;
			for j in range(0,3):&lt;br /&gt;
				RMSD = RMSD + (c2[i][j]-c1[i][j])**2&lt;br /&gt;
				&lt;br /&gt;
		RMSD = RMSD / len(c1)&lt;br /&gt;
		RMSD = Numeric.sqrt(RMSD)&lt;br /&gt;
		return RMSD&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
	#####################################################################&lt;br /&gt;
	#&lt;br /&gt;
	# UTIL Functions&lt;br /&gt;
	def rotatePoints(self, U, c2):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Rotate all points in c2 based on the rotation matrix U.&lt;br /&gt;
		&lt;br /&gt;
		@param U: 3x3 Rotation matrix&lt;br /&gt;
		@type  U: 3x3 matrix&lt;br /&gt;
		&lt;br /&gt;
		@param c2: List of points to rotate&lt;br /&gt;
		@type  c2: List of 3D vectors&lt;br /&gt;
		&lt;br /&gt;
		@return: List of rotated points&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	&lt;br /&gt;
		L = len(c2)&lt;br /&gt;
&lt;br /&gt;
		for n in range(0,L):&lt;br /&gt;
			c2[n][0] = c2[n][0] * U[0][0] + c2[n][1] * U[1][0] + c2[n][2] * U[2][0]&lt;br /&gt;
			c2[n][1] = c2[n][0] * U[0][1] + c2[n][1] * U[1][1] + c2[n][2] * U[2][1]&lt;br /&gt;
			c2[n][2] = c2[n][0] * U[0][2] + c2[n][1] * U[1][2] + c2[n][2] * U[2][2]&lt;br /&gt;
		&lt;br /&gt;
		return c2&lt;br /&gt;
	&lt;br /&gt;
	def writeU( self, U, fileName ):&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		Convenience function.  Writes U to disk.&lt;br /&gt;
		&lt;br /&gt;
		&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
		&lt;br /&gt;
		if ( len(fileName) == 0 ):&lt;br /&gt;
			fileName = &amp;quot;./U&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
		outFile = open( fileName, &amp;quot;wb&amp;quot;)&lt;br /&gt;
		for i in range(0,3):&lt;br /&gt;
			for j in range(0,3):&lt;br /&gt;
				outFile.write( str(U[i][j]).ljust(20) )&lt;br /&gt;
			outFile.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
		outFile.close()		&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
def optAlign( sel1, sel2 ):&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	optAlign performs the Kabsch alignment algorithm upon the alpha-carbons of two selections.&lt;br /&gt;
	Example:   optAlign MOL1 and i. 20-40, MOL2 and i. 102-122&lt;br /&gt;
	Example 2: optAlign 1GGZ and i. 4-146 and n. CA, 1CLL and i. 4-146 and n. CA&lt;br /&gt;
	&lt;br /&gt;
	Two RMSDs are returned.  One comes from the Kabsch algorithm and the other from&lt;br /&gt;
	PyMol based upon your selections.&lt;br /&gt;
&lt;br /&gt;
	By default, this program will optimally align the ALPHA CARBONS of the selections provided.&lt;br /&gt;
	To turn off this feature remove the lines between the commented &amp;quot;REMOVE ALPHA CARBONS&amp;quot; below.&lt;br /&gt;
	&lt;br /&gt;
	@param sel1: First PyMol selection with N-atoms&lt;br /&gt;
	@param sel2: Second PyMol selection with N-atoms&lt;br /&gt;
	&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	cmd.reset()&lt;br /&gt;
&lt;br /&gt;
	# make the lists for holding coordinates&lt;br /&gt;
	# partial lists&lt;br /&gt;
	stored.sel1 = []&lt;br /&gt;
	stored.sel2 = []&lt;br /&gt;
	# full lists&lt;br /&gt;
	stored.mol1 = []&lt;br /&gt;
	stored.mol2 = []&lt;br /&gt;
&lt;br /&gt;
	# now put the coordinates into a list&lt;br /&gt;
	# partials&lt;br /&gt;
&lt;br /&gt;
	# -- REMOVE ALPHA CARBONS&lt;br /&gt;
	sel1 = sel1 + &amp;quot; and N. CA&amp;quot;&lt;br /&gt;
	sel2 = sel2 + &amp;quot; and N. CA&amp;quot;&lt;br /&gt;
	# -- REMOVE ALPHA CARBONS&lt;br /&gt;
&lt;br /&gt;
	cmd.iterate_state(1, selector.process(sel1), &amp;quot;stored.sel1.append([x,y,z])&amp;quot;)&lt;br /&gt;
	cmd.iterate_state(1, selector.process(sel2), &amp;quot;stored.sel2.append([x,y,z])&amp;quot;)&lt;br /&gt;
	# full molecule&lt;br /&gt;
	mol1 = cmd.identify(sel1,1)[0][0]&lt;br /&gt;
	mol2 = cmd.identify(sel2,1)[0][0]&lt;br /&gt;
	cmd.iterate_state(1, mol1, &amp;quot;stored.mol1.append([x,y,z])&amp;quot;)&lt;br /&gt;
	cmd.iterate_state(1, mol2, &amp;quot;stored.mol2.append([x,y,z])&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	K = kabsch()&lt;br /&gt;
	U, T1, T2, RMSD, c1, c2 = K.align(stored.sel1, stored.sel2, [])&lt;br /&gt;
&lt;br /&gt;
	stored.mol2 = map(lambda v:[T2[0]+((v[0]*U[0][0])+(v[1]*U[1][0])+(v[2]*U[2][0])),T2[1]+((v[0]*U[0][1])+(v[1]*U[1][1])+(v[2]*U[2][1])),T2[2]+((v[0]*U[0][2])+(v[1]*U[1][2])+(v[2]*U[2][2]))],stored.mol2)&lt;br /&gt;
	#stored.mol1 = map(lambda v:[ v[0]+T1[0], v[1]+T1[1], v[2]+T1[2] ], stored.mol1)&lt;br /&gt;
	stored.mol1 = map(lambda v:[ v[0]+T1[0], v[1]+T1[1], v[2]+T1[2] ], stored.mol1)&lt;br /&gt;
&lt;br /&gt;
	cmd.alter_state(1,mol1,&amp;quot;(x,y,z)=stored.mol1.pop(0)&amp;quot;)&lt;br /&gt;
	cmd.alter_state(1,mol2,&amp;quot;(x,y,z)=stored.mol2.pop(0)&amp;quot;)&lt;br /&gt;
	cmd.alter( 'all',&amp;quot;segi=''&amp;quot;)&lt;br /&gt;
	cmd.alter('all', &amp;quot;chain=''&amp;quot;)&lt;br /&gt;
	print &amp;quot;RMSD=%f&amp;quot; % cmd.rms_cur(sel1, sel2)&lt;br /&gt;
	print &amp;quot;MY RMSD=%f&amp;quot; % RMSD&lt;br /&gt;
	cmd.hide('everything')&lt;br /&gt;
	cmd.show('ribbon', sel1 + ' or ' + sel2)&lt;br /&gt;
	cmd.color('gray70', mol1 )&lt;br /&gt;
	cmd.color('paleyellow', mol2 )&lt;br /&gt;
	cmd.color('red', 'visible')&lt;br /&gt;
	cmd.show('ribbon', 'not visible')&lt;br /&gt;
	cmd.center('visible')&lt;br /&gt;
	cmd.orient()&lt;br /&gt;
	cmd.zoom('visible')&lt;br /&gt;
&lt;br /&gt;
cmd.extend(&amp;quot;optAlign&amp;quot;, optAlign)	&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''[Kabsch, 1976]''' Kabsch, W. (1976).&lt;br /&gt;
A solution for the best rotation to relate two sets of vectors.&lt;br /&gt;
''Acta. Crystal'', 32A:922-923.&lt;br /&gt;
&lt;br /&gt;
'''[Kabsch, 1978]''' Kabsch, W. (1978).&lt;br /&gt;
A discussion of the solution for the best rotation to related two sets of vectors.&lt;br /&gt;
''Acta. Crystal'', 34A:827-828.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|Kabsch Alignment]]&lt;br /&gt;
[[Category:Structure_Alignment|Kabsch Alignment]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Rotamer_Toggle&amp;diff=9570</id>
		<title>Rotamer Toggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Rotamer_Toggle&amp;diff=9570"/>
		<updated>2010-02-14T19:12:21Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* SCRIPTS (Rotamers.py ; MyMenu.py) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
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.&lt;br /&gt;
*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&lt;br /&gt;
*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).&lt;br /&gt;
*set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles&lt;br /&gt;
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)&lt;br /&gt;
*createRotamerPDBs - create pdb for each rotamer of given selection ; filter by rotamer-probability&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:RotamerMenu.png|Rotamer Menu for a GLN residue&lt;br /&gt;
Image:GLURotamerComparison5.png|Rotamer Comparison of crystal structure and most common for GLU; just as an example&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Print out while selecting most common rotamer from above-left image (GLN residue):&lt;br /&gt;
  Given GLN:40 PHI,PSI (-171.626373291,-96.0500335693) : bin (-170,-100)&lt;br /&gt;
  CHIs: [179.18069458007812, 72.539344787597656, -47.217315673828125]&lt;br /&gt;
  Setting Chi1 to -176.9&lt;br /&gt;
  Setting Chi2 to 177.4&lt;br /&gt;
  Setting Chi3 to 0.7&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
run &amp;quot;rotamers.py&amp;quot; and use functions from commandline.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
To setup a rotamer menu inside the residue menu (default windows pymol installation):&lt;br /&gt;
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py&lt;br /&gt;
*copy mymenu.py   to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)&lt;br /&gt;
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)&lt;br /&gt;
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 &amp;quot;sorted&amp;quot; lib)&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Pymolv0.97, Windows platform, Red Hat Linux 9.0 and Fedora Core 4. Will test v0.98 and MacOSX later on.&lt;br /&gt;
*The way it's setup now, when you import rotamers , it will automatically read-in the rotamer database; this may not be what you want.&lt;br /&gt;
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
TASKS TODO:&lt;br /&gt;
*Rotamer Movie, using mset, etc create movie to watch cycle through rotamers&lt;br /&gt;
*Code could be organized a bit better; due to time constraints this is good for now..&lt;br /&gt;
&lt;br /&gt;
TASKS DONE:&lt;br /&gt;
*Store crystal structure in rotamer menu, so you can go back to original orientation&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
 colorRotamers selection&lt;br /&gt;
 set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]&lt;br /&gt;
 set_phipsi selection phi_angle, psi_angle&lt;br /&gt;
 createRotamerPBDs selection [,ncutoff] [,pcutoff] [,prefix]&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
   colorRotamers chain A&lt;br /&gt;
   set_rotamer resi 40, -60,-40   (only set chi1,chi2 angles)&lt;br /&gt;
   set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)&lt;br /&gt;
   createRotamerPDBs resi 10-12, ncutoff=3 (create 9 PDBs; each with one of the 3 most probable rotamers for resi 10,11,12)&lt;br /&gt;
   createRotamerPDBs resi 14, pcutoff=0.4  (create a pdb file for each rotamer of residue 14 with probablity &amp;gt; 0.4)&lt;br /&gt;
&lt;br /&gt;
===REFERENCES===&lt;br /&gt;
Dunbrack and Cohen. Protein Science 1997&lt;br /&gt;
&lt;br /&gt;
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (Rotamers.py ; MyMenu.py)===&lt;br /&gt;
Rotamers.py &lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
##################################################################&lt;br /&gt;
# File:          Rotamers.py&lt;br /&gt;
# Author:        Dan Kulp&lt;br /&gt;
# Creation Date: 6/8/05&lt;br /&gt;
# Contact:       dwkulp@mail.med.upenn.edu&lt;br /&gt;
#&lt;br /&gt;
# Notes:&lt;br /&gt;
#     Incorporation of Rotamer library&lt;br /&gt;
#     readRotLib() - fills rotdat; &lt;br /&gt;
#        indexed by &amp;quot;RES:PHI_BIN:PSI_BIN&amp;quot;.&lt;br /&gt;
#&lt;br /&gt;
#     Three main functions:&lt;br /&gt;
#     1. colorRotamers - colors according&lt;br /&gt;
#          to rotamer probablitity&lt;br /&gt;
#     2. getBins(sel)&lt;br /&gt;
#           phi,psi bin for rotamer&lt;br /&gt;
#     3. set_rotamer - set a side-chain &lt;br /&gt;
#           to a specific rotamer&lt;br /&gt;
#&lt;br /&gt;
#     To setup a rotamer menu in the &lt;br /&gt;
#   right click, under &amp;quot;Residue&amp;quot;&lt;br /&gt;
#        1. cp mymenu.py modules/pymol/menu.py&lt;br /&gt;
#        2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)&lt;br /&gt;
#&lt;br /&gt;
# Requirements:&lt;br /&gt;
#  set ROTLIB to path for rotamer library&lt;br /&gt;
# Reference: &lt;br /&gt;
#  Dunbrack and Cohen. Protein Science 1997&lt;br /&gt;
####################################################################&lt;br /&gt;
 &lt;br /&gt;
import colorsys,sys&lt;br /&gt;
import re&lt;br /&gt;
import editing&lt;br /&gt;
import os&lt;br /&gt;
import cmd&lt;br /&gt;
import math&lt;br /&gt;
 &lt;br /&gt;
# Path for library&lt;br /&gt;
ROTLIB=os.environ['PYMOL_PATH']+&amp;quot;/modules/pymol/bbdep02.May.sortlib&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# Place for library in memory..&lt;br /&gt;
rotdat = {}&lt;br /&gt;
 &lt;br /&gt;
def readRotLib():&lt;br /&gt;
    # Column indexes in rotamer library..&lt;br /&gt;
    RES  = 0&lt;br /&gt;
    PHI  = 1&lt;br /&gt;
    PSI  = 2&lt;br /&gt;
    PROB = 8&lt;br /&gt;
    CHI1 = 9&lt;br /&gt;
    CHI2 = 10&lt;br /&gt;
    CHI3 = 11&lt;br /&gt;
    CHI4 = 12&lt;br /&gt;
 &lt;br /&gt;
    if os.path.exists(ROTLIB):&lt;br /&gt;
                print &amp;quot;File exists: &amp;quot;+ROTLIB&lt;br /&gt;
                input = open(ROTLIB, 'r')&lt;br /&gt;
                for line in input:&lt;br /&gt;
 &lt;br /&gt;
                    # Parse by whitespace (I believe format is white space and not fixed-width columns)&lt;br /&gt;
                    dat = re.split(&amp;quot;\s+&amp;quot;,line)&lt;br /&gt;
 &lt;br /&gt;
                    # Add to rotamer library in memory : &lt;br /&gt;
                    #   key format       RES:PHI_BIN:PSI_BIN&lt;br /&gt;
                    #   value format     PROB, CHI1, CHI2, CHI3, CHI4&lt;br /&gt;
                    key=dat[RES]+&amp;quot;:&amp;quot;+dat[PHI]+&amp;quot;:&amp;quot;+dat[PSI]&lt;br /&gt;
                    if key in rotdat:&lt;br /&gt;
                        rotdat[key].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])&lt;br /&gt;
                    else:&lt;br /&gt;
                        rotdat[key] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Couldn't find Rotamer library&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Atoms for each side-chain angle for each residue&lt;br /&gt;
CHIS = {}&lt;br /&gt;
CHIS[&amp;quot;ARG&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;NE&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;NE&amp;quot;,&amp;quot;CZ&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;ASN&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;OD2&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;ASP&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;OD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
CHIS[&amp;quot;CYS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;SG&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;GLN&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;OE1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;GLU&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;OE1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;HIS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;ND1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;ILE&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;LEU&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;LYS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;CE&amp;quot;],&lt;br /&gt;
                [&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;CE&amp;quot;,&amp;quot;NZ&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;MET&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;SD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;SD&amp;quot;,&amp;quot;CE&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;PHE&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;PRO&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;SER&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;OG&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;THR&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;OG1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;TRP&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;TYR&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;VAL&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
# Color Rotamer by side-chain angle position&lt;br /&gt;
#  'bin' side-chain angles into closest&lt;br /&gt;
def colorRotamers(sel):&lt;br /&gt;
    doRotamers(sel)&lt;br /&gt;
 &lt;br /&gt;
# Utility function, to set phi,psi angles for a given selection&lt;br /&gt;
# Note: Cartoon, Ribbon functionality will not display correctly after this&lt;br /&gt;
def set_phipsi(sel, phi,psi):&lt;br /&gt;
    doRotamers(sel,angles=[phi,psi],type=&amp;quot;set&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
# Set a rotamer, based on a selection, a restype and chi angles&lt;br /&gt;
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):&lt;br /&gt;
    at = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;).atom[0]&lt;br /&gt;
 &lt;br /&gt;
    list = [chi1,chi2,chi3,chi4]&lt;br /&gt;
    for i in range(len(CHIS[at.resn])):&lt;br /&gt;
        print &amp;quot;Setting Chi&amp;quot;+str(i+1)+&amp;quot; to &amp;quot;+str(list[i])&lt;br /&gt;
        editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],&lt;br /&gt;
                             sel + ' and name '+CHIS[at.resn][i][1],&lt;br /&gt;
                             sel + ' and name '+CHIS[at.resn][i][2],&lt;br /&gt;
                             sel + ' and name '+CHIS[at.resn][i][3], str(list[i]))&lt;br /&gt;
 &lt;br /&gt;
    # Remove some objects that got created&lt;br /&gt;
    cmd.delete(&amp;quot;pk1&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;pk2&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;pkmol&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
# Get Phi,Psi bins for given selection&lt;br /&gt;
# WARNING:  assume selection is single residue (will only return first residue bins)&lt;br /&gt;
def getBins(sel):&lt;br /&gt;
    return doRotamers(sel, type=&amp;quot;bins&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
# Color Ramp...&lt;br /&gt;
def rot_color(vals): &lt;br /&gt;
        nbins = 10&lt;br /&gt;
        vals.sort(key=lambda x:x[1])&lt;br /&gt;
#       print &amp;quot;End sort: &amp;quot;+str(len(vals))+&amp;quot; : &amp;quot;+str(nbins)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
        # Coloring scheme...&lt;br /&gt;
        j = 0&lt;br /&gt;
        rgb = [0.0,0.0,0.0]&lt;br /&gt;
        sel_str = &amp;quot;&amp;quot;&lt;br /&gt;
        for i in range(len(vals)):&lt;br /&gt;
                if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:&lt;br /&gt;
                      hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)&lt;br /&gt;
 &lt;br /&gt;
                      #convert to rgb and append to color list&lt;br /&gt;
                      rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])&lt;br /&gt;
                      if j &amp;lt; nbins-1:&lt;br /&gt;
                              j += 1&lt;br /&gt;
 &lt;br /&gt;
                cmd.set_color(&amp;quot;RotProbColor&amp;quot;+str(i), rgb)&lt;br /&gt;
                cmd.color(&amp;quot;RotProbColor&amp;quot;+str(i), str(vals[i][0]))&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Main function&lt;br /&gt;
def doRotamers(sel,angles=[], type=&amp;quot;color&amp;quot;):&lt;br /&gt;
 &lt;br /&gt;
        # Read in Rotamer library if not already done&lt;br /&gt;
        if len(rotdat) == 0:&lt;br /&gt;
                readRotLib()&lt;br /&gt;
 &lt;br /&gt;
        # Set up some variables..&lt;br /&gt;
        residues = ['dummy']  # Keep track of residues already done&lt;br /&gt;
        probs = []            # probability of each residue conformation&lt;br /&gt;
        phi = 0               # phi,psi angles of current residue&lt;br /&gt;
        psi = 0&lt;br /&gt;
 &lt;br /&gt;
        # Get atoms from selection&lt;br /&gt;
        atoms = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
        # Loop through atoms in selection&lt;br /&gt;
        for at in atoms.atom:&lt;br /&gt;
            try:&lt;br /&gt;
               # Don't process Glycines or Alanines&lt;br /&gt;
               if not (at.resn == 'GLY' or at.resn == 'ALA'):&lt;br /&gt;
                if at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi not in residues:&lt;br /&gt;
                    residues.append(at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi)&lt;br /&gt;
 &lt;br /&gt;
                    # Check for a null chain id (some PDBs contain this) &lt;br /&gt;
                    unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
                    if at.chain != &amp;quot;&amp;quot;:&lt;br /&gt;
                        unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
                    # Define selections for residue i-1, i and i+1&lt;br /&gt;
                    residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
                    residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)&lt;br /&gt;
                    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)&lt;br /&gt;
 &lt;br /&gt;
                    # Compute phi/psi angle&lt;br /&gt;
 &lt;br /&gt;
                    phi = cmd.get_dihedral(residue_def_prev+' and name C',residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C')&lt;br /&gt;
                    psi = cmd.get_dihedral(residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',residue_def_next+' and name N')&lt;br /&gt;
                    if type == &amp;quot;set&amp;quot;:&lt;br /&gt;
                            print &amp;quot;Changing &amp;quot;+at.resn+str(at.resi)+&amp;quot; from &amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)+&amp;quot; to &amp;quot;+str(angles[0])+&amp;quot;,&amp;quot;+str(angles[1])&lt;br /&gt;
                            cmd.set_dihedral(residue_def_prev+' and name C',residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',angles[0])&lt;br /&gt;
                            cmd.set_dihedral(residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',residue_def_next+' and name N', angles[1])&lt;br /&gt;
                            continue&lt;br /&gt;
 &lt;br /&gt;
                    # Find correct 10x10 degree bin                                     &lt;br /&gt;
                    phi_digit = abs(int(phi)) - abs(int(phi/10)*10)&lt;br /&gt;
                    psi_digit = abs(int(psi)) - abs(int(psi/10)*10)&lt;br /&gt;
 &lt;br /&gt;
                    # Remember sign of phi,psi angles&lt;br /&gt;
                    phi_sign = 1&lt;br /&gt;
                    if phi &amp;lt; 0:    phi_sign = -1&lt;br /&gt;
 &lt;br /&gt;
                    psi_sign = 1&lt;br /&gt;
                    if psi &amp;lt; 0:    psi_sign = -1&lt;br /&gt;
 &lt;br /&gt;
                    # Compute phi,psi bins&lt;br /&gt;
                    phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)&lt;br /&gt;
                    if phi_digit &amp;gt;= 5:    phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)&lt;br /&gt;
 &lt;br /&gt;
                    psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)&lt;br /&gt;
                    if psi_digit &amp;gt;= 5:    psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)&lt;br /&gt;
 &lt;br /&gt;
                    print &amp;quot;Given &amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi+&amp;quot; PHI,PSI (&amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)+&amp;quot;) : bin (&amp;quot;+str(phi_bin)+&amp;quot;,&amp;quot;+str(psi_bin)+&amp;quot;)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                    # Get current chi angle measurements&lt;br /&gt;
                    chi = []&lt;br /&gt;
                    for i in range(len(CHIS[at.resn])):&lt;br /&gt;
                       chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],&lt;br /&gt;
                                                     residue_def + ' and name '+CHIS[at.resn][i][1],&lt;br /&gt;
                                                     residue_def + ' and name '+CHIS[at.resn][i][2],&lt;br /&gt;
                                                     residue_def + ' and name '+CHIS[at.resn][i][3]))&lt;br /&gt;
                    print &amp;quot;CHIs: &amp;quot;+str(chi)&lt;br /&gt;
                    if type == 'bins':&lt;br /&gt;
                         return [at.resn, phi_bin,psi_bin]&lt;br /&gt;
 &lt;br /&gt;
                    # Compute probabilities for given chi angles&lt;br /&gt;
                    prob = 0&lt;br /&gt;
                    prob_box = 22                   &lt;br /&gt;
                    for item in range(len(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)])):&lt;br /&gt;
                        print &amp;quot;Rotamer from db: &amp;quot;+str(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item])&lt;br /&gt;
                        if chi[0]:&lt;br /&gt;
                            if chi[0] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][1]) - (prob_box/2) and \&lt;br /&gt;
                                chi[0] &amp;lt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][1]) + (prob_box/2):&lt;br /&gt;
                                if len(chi) == 1:&lt;br /&gt;
                                        prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                        break&lt;br /&gt;
                                if chi[1] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][2]) - (prob_box/2) and \&lt;br /&gt;
                                 float(chi[1] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][2]) + (prob_box/2):&lt;br /&gt;
                                        if len(chi) == 2:&lt;br /&gt;
                                            prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                            break&lt;br /&gt;
                                        if chi[2] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][3]) - (prob_box/2) and \&lt;br /&gt;
                                           float(chi[2] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][3]) + (prob_box/2):&lt;br /&gt;
                                            if len(chi) == 3:&lt;br /&gt;
                                                prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                                break&lt;br /&gt;
                                            if chi[3] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][4]) - (prob_box/2) and \&lt;br /&gt;
                                               float(chi[3] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][4]) + (prob_box/2):&lt;br /&gt;
                                                prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                                break&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                    print &amp;quot;PROB OF ROTAMER: &amp;quot;+str(prob)&lt;br /&gt;
                    print &amp;quot;---------------------------&amp;quot;&lt;br /&gt;
                    probs.append([residue_def, prob])&lt;br /&gt;
 &lt;br /&gt;
            except:&lt;br /&gt;
#               probs.append([residue_def, -1])&lt;br /&gt;
                print &amp;quot;Exception found&amp;quot;&lt;br /&gt;
                continue&lt;br /&gt;
 &lt;br /&gt;
        # Color according to rotamer probability&lt;br /&gt;
        rot_color(probs)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
#  Create PDB files containing most probable rotamers&lt;br /&gt;
def createRotamerPDBs(sel,ncutoff=10,pcutoff=0,prefix=&amp;quot;ROTAMER&amp;quot;):&lt;br /&gt;
 &lt;br /&gt;
        # Get atoms from selection&lt;br /&gt;
        atoms = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
        # Set up some variables..&lt;br /&gt;
        residues = ['dummy']  # Keep track of residues already done&lt;br /&gt;
 &lt;br /&gt;
        # Loop through atoms in selection&lt;br /&gt;
        for at in atoms.atom:&lt;br /&gt;
                if at.resn in ('GLY','ALA') or &amp;quot;%s:%s:%s&amp;quot; % (at.chain,at.resn,at.resi) in residues:&lt;br /&gt;
                        continue&lt;br /&gt;
 &lt;br /&gt;
                # Add to residue list (keep track of which ones we've done)&lt;br /&gt;
                residues.append(&amp;quot;%s:%s:%s&amp;quot; % (at.chain,at.resn,at.resi))&lt;br /&gt;
 &lt;br /&gt;
                # Check for a null chain id (some PDBs contain this)&lt;br /&gt;
                unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
                if not at.chain == &amp;quot;&amp;quot;:&lt;br /&gt;
                    unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
                # Define selections for residue &lt;br /&gt;
                residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
 &lt;br /&gt;
                # Get bin (phi,psi) definitions for this residue&lt;br /&gt;
                bin = doRotamers(residue_def, type='bins')&lt;br /&gt;
 &lt;br /&gt;
                # Store crystal angle&lt;br /&gt;
                crystal_angles = [0.0,0.0,0.0,0.0]&lt;br /&gt;
                for angle in range(3):&lt;br /&gt;
                        try:&lt;br /&gt;
                                crystal_angles[angle] = bin[3][angle]&lt;br /&gt;
                        except IndexError:&lt;br /&gt;
                                break&lt;br /&gt;
 &lt;br /&gt;
                # Retreive list of rotamers for this phi,psi bin + residue type&lt;br /&gt;
                match_rotamers = rotdat[&amp;quot;%s:%s:%s&amp;quot; % (bin[0],str(bin[1]),str(bin[2]))]&lt;br /&gt;
 &lt;br /&gt;
                count = 0&lt;br /&gt;
                for item in range(len(match_rotamers)):&lt;br /&gt;
 &lt;br /&gt;
                        # Store probablity&lt;br /&gt;
                        prob = match_rotamers[item][0]&lt;br /&gt;
 &lt;br /&gt;
                        # Check cutoffs&lt;br /&gt;
                        if float(prob) &amp;lt;= float(pcutoff):&lt;br /&gt;
                                continue&lt;br /&gt;
 &lt;br /&gt;
                        if float(count) &amp;gt;= float(ncutoff):&lt;br /&gt;
                                break&lt;br /&gt;
 &lt;br /&gt;
                        # Increment count&lt;br /&gt;
                        count += 1&lt;br /&gt;
 &lt;br /&gt;
                        # Output to screen ...&lt;br /&gt;
                        print &amp;quot;Residue %s%s, rotamer %i, prob %s&amp;quot; % (str(at.resn),str(at.resi),int(item),str(prob))&lt;br /&gt;
 &lt;br /&gt;
                        # Set to new rotamer&lt;br /&gt;
                        set_rotamer(residue_def,match_rotamers[item][1],match_rotamers[item][2],match_rotamers[item][3],match_rotamers[item][4])                                                                                                &lt;br /&gt;
 &lt;br /&gt;
                        # Store in PDB file&lt;br /&gt;
                        cmd.save(&amp;quot;%s_%s%s_%i_%s.pdb&amp;quot; % (prefix,str(at.resn),str(at.resi),int(item),str(prob)))&lt;br /&gt;
 &lt;br /&gt;
                        # Reset crystal angle&lt;br /&gt;
                        set_rotamer(residue_def,crystal_angles[0],crystal_angles[1],crystal_angles[2],crystal_angles[3])&lt;br /&gt;
 &lt;br /&gt;
# Uncommenting this is nice because it loads rotamer library upon startup&lt;br /&gt;
#  however, it slows the PyMOL loading process a lot&lt;br /&gt;
#  instead I've put this call into the menuing code..&lt;br /&gt;
# readRotLib()&lt;br /&gt;
 &lt;br /&gt;
cmd.extend('set_phipsi',set_phipsi)&lt;br /&gt;
cmd.extend('set_rotamer',set_rotamer)&lt;br /&gt;
cmd.extend('colorRotamers',colorRotamers)&lt;br /&gt;
cmd.extend('createRotamerPDBs',createRotamerPDBs)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MyMenu.py&lt;br /&gt;
 Since menu.py is copyrighted I can't post my edited version, but you can create it very simply by adding these two peices of code&lt;br /&gt;
&lt;br /&gt;
1. In the &amp;quot;pick_option(title,s,object=0)&amp;quot; function of menu.py add the following code after the first &amp;quot;result =&amp;quot; statement&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Edit dwkulp 6/11/05 , add a rotamer menu to residue menu&lt;br /&gt;
   if title == 'Residue':&lt;br /&gt;
	result.extend([[ 1, 'rotamers'    , rotamer_menu(s)]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. At the end of the file add this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
###############################################&lt;br /&gt;
# Dan Kulp&lt;br /&gt;
# Added Rotamer list to residue menu..&lt;br /&gt;
# rotamer.py must be importable (I placed it in &lt;br /&gt;
# the same directory as menu.py)&lt;br /&gt;
###############################################&lt;br /&gt;
&lt;br /&gt;
import rotamers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def rotamer_menu(s):&lt;br /&gt;
	# Check for rotamer library being loaded&lt;br /&gt;
	if not rotamers.rotdat:&lt;br /&gt;
             rotamers.readRotLib()&lt;br /&gt;
#	     return [ [2, &amp;quot;Must run rotamers.py first&amp;quot;,'']]&lt;br /&gt;
&lt;br /&gt;
	# Check for valid rotamer residue..&lt;br /&gt;
	res = cmd.get_model(&amp;quot;byres (&amp;quot;+s+&amp;quot;)&amp;quot;).atom[0].resn&lt;br /&gt;
        if not res in rotamers.CHIS.keys():&lt;br /&gt;
	    return [ [2, &amp;quot;Residue: &amp;quot;+res+&amp;quot; not known sidechain or does not have rotamers&amp;quot;, '']]&lt;br /&gt;
&lt;br /&gt;
	# Get PHI,PSI bins for rotamer (also prints out current phi,psi, chi1,chi2,chi3,chi4)&lt;br /&gt;
	bins = rotamers.doRotamers(s,type='bins')&lt;br /&gt;
&lt;br /&gt;
	# Add a title to the menu&lt;br /&gt;
	result = [ [2, bins[0]+' Rotamers in bin ('+str(bins[1])+','+str(bins[2])+')','' ], [1, ':::PROB,CHI1,CHI2,CHI3,CHI4:::','']]&lt;br /&gt;
&lt;br /&gt;
        # Grab the entries for this residue and phi,psi bins&lt;br /&gt;
	match_rotamers = rotamers.rotdat[bins[0]+&amp;quot;:&amp;quot;+str(bins[1])+&amp;quot;:&amp;quot;+str(bins[2])]&lt;br /&gt;
&lt;br /&gt;
	# Set max number of rotamers to display (probably should be somewhere 'higher up' in the code)&lt;br /&gt;
	max_rotamers = min(10, len(match_rotamers))&lt;br /&gt;
&lt;br /&gt;
	# Create menu entry for each possible rotamer&lt;br /&gt;
        for item in range(max_rotamers):&lt;br /&gt;
             result.append( [ 1, str(match_rotamers[item]), 'rotamers.set_rotamer(&amp;quot;'+s+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][1])+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][2])+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][3])+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][4])+'&amp;quot;)'])&lt;br /&gt;
	return result&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|Rotamer Toggle]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Structural_Biology_Scripts|Rotamer Toggle]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Wfmesh&amp;diff=10834</id>
		<title>Wfmesh</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Wfmesh&amp;diff=10834"/>
		<updated>2010-02-14T19:10:01Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* SCRIPTS (WFMesh.py) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
This script will create an object for any Wavefront(.OBJ) mesh file.  This is a way to extend the number of objects you can use. Also, you have more control over the coloring, transformations, etc than the CGOs. Although there are a number of these obj files on the web, you can also easily created them with open source tools ([http://www.openfx.org OpenFX], [http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]). It takes literally, 2 min to get an object created and then loaded into pymol.  Simply open OpenFX Designer, click File-&amp;gt;Insert-&amp;gt;Model, then choose any of the models (or create your own of course!), then export it as .3ds file.  Then open the .3ds file from Crossroads3D and export as Wavefront OBJ.   &lt;br /&gt;
&lt;br /&gt;
*createWFMesh - create a mesh object from Wavefront (*.obj) formated file&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]&lt;br /&gt;
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:ThirdParty_Scripts]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
Simply &amp;quot;run WFMesh.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Pymolv0.97, Windows platform, should work on linux as well.&lt;br /&gt;
*Coloring is fixed for grey and sections of mesh are stored, but not used.&lt;br /&gt;
*Simple opengl calls; not optimized (display lists, etc) or anything.&lt;br /&gt;
*Vertex Normal code is broken, so normals are per polygon right now.&lt;br /&gt;
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
createWFObj file, name  [,translate=[0,0,0]] [,flip=0]&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
   createWFObj &amp;quot;ship.obj&amp;quot; &amp;quot;Ship&amp;quot;&lt;br /&gt;
   createWFObj &amp;quot;torus.obj&amp;quot; &amp;quot;Torus&amp;quot; flip=1  # Flip = 1, if OBJ created by openFX, crossroads3D combination&lt;br /&gt;
   createWFObj &amp;quot;torus.obj&amp;quot; &amp;quot;Torus&amp;quot; translate=[10,10,0] flip=1      &lt;br /&gt;
   &lt;br /&gt;
===REFERENCES===&lt;br /&gt;
[http://www.openfx.org OpenFX]&lt;br /&gt;
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (WFMesh.py)===&lt;br /&gt;
WFMesh.py&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
###############################################&lt;br /&gt;
#  File:          WFObj.py&lt;br /&gt;
#  Author:        Dan Kulp&lt;br /&gt;
#  Creation Date: 5/13/05&lt;br /&gt;
#&lt;br /&gt;
#  Notes:&lt;br /&gt;
#  Create openGL objects from a wavefront (obj) file&lt;br /&gt;
###############################################&lt;br /&gt;
 &lt;br /&gt;
import os&lt;br /&gt;
import re&lt;br /&gt;
import math&lt;br /&gt;
from pymol.opengl.gl import *&lt;br /&gt;
from pymol.callback import Callback&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)&lt;br /&gt;
def createWFObj(file, name,translate=[0,0,0],flip=0):&lt;br /&gt;
        obj = WFMesh(file,translate,flip)&lt;br /&gt;
        cmd.load_callback(obj,name)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Class for Wavefront Mesh&lt;br /&gt;
class WFMesh(Callback):&lt;br /&gt;
 &lt;br /&gt;
    verts = []        # list of vertices&lt;br /&gt;
    polys = []        # list of poylgons&lt;br /&gt;
    pnorms = []       # list of polynomal normals&lt;br /&gt;
    vnorms = {}       # dict. of vertex normals&lt;br /&gt;
    vavenorms = []    # list of vertex normals, redundant -- I'm far froma python pro.&lt;br /&gt;
    sections = {}     # list of sections of mesh&lt;br /&gt;
 &lt;br /&gt;
    # Read mesh into memory&lt;br /&gt;
    def readOBJ(self,file):&lt;br /&gt;
        if os.path.exists(file):&lt;br /&gt;
            input = open(file,'r')&lt;br /&gt;
            for line in input:&lt;br /&gt;
                dat = re.split(&amp;quot;\s+&amp;quot;, line)&lt;br /&gt;
 &lt;br /&gt;
                # Find vertex line&lt;br /&gt;
                if line[0] == 'v' and line[1] != 't' and line[1] != 'n':    self.verts.append([dat[1],dat[2],dat[3]])&lt;br /&gt;
 &lt;br /&gt;
                # Find polygon line&lt;br /&gt;
                if line[0] == 'f':    self.polys.append([dat[1],dat[2],dat[3]])&lt;br /&gt;
 &lt;br /&gt;
                # Find section line&lt;br /&gt;
                if line[0] == 'g':    self.sections[len(self.polys)] = dat[1] &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    # Compute the normals for each polygon and each vertex              &lt;br /&gt;
    def computeNorms(self):&lt;br /&gt;
 &lt;br /&gt;
        # Compute norms for each polygon&lt;br /&gt;
        for p in self.polys:&lt;br /&gt;
                v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\&lt;br /&gt;
                       float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\&lt;br /&gt;
                       float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \&lt;br /&gt;
                      ]&lt;br /&gt;
 &lt;br /&gt;
                v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\&lt;br /&gt;
                       float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\&lt;br /&gt;
                       float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \&lt;br /&gt;
                      ] &lt;br /&gt;
 &lt;br /&gt;
                # Compute poly normal&lt;br /&gt;
                polynorm = self.cross(v12,v13) &lt;br /&gt;
                norm = self.normalize(polynorm)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                # Files created by OpenFX, Crossroads combination need have their normals flipped       &lt;br /&gt;
                if self.flip:&lt;br /&gt;
                        norm[0] = -norm[0]&lt;br /&gt;
                        norm[1] = -norm[1]&lt;br /&gt;
                        norm[2] = -norm[2]&lt;br /&gt;
 &lt;br /&gt;
                # Append poly norm to polygonal norm array&lt;br /&gt;
                self.pnorms.append(norm)&lt;br /&gt;
 &lt;br /&gt;
                # Add norm to each vertexes norm..&lt;br /&gt;
                try:&lt;br /&gt;
                    self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],&lt;br /&gt;
                                            float(self.vnorms[int(p[0])-1][1]) + norm[1],&lt;br /&gt;
                                            float(self.vnorms[int(p[0])-1][2]) + norm[2]&lt;br /&gt;
                                           ]&lt;br /&gt;
                except:&lt;br /&gt;
                    self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
 &lt;br /&gt;
                try:                                       &lt;br /&gt;
                    self.vnorms[int(p[1])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][1]) + norm[1],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][2]) + norm[2]&lt;br /&gt;
                                           ]&lt;br /&gt;
                except:&lt;br /&gt;
                    self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
 &lt;br /&gt;
                try:&lt;br /&gt;
                    self.vnorms[int(p[2])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][1]) + norm[1],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][2]) + norm[2]&lt;br /&gt;
                                           ]&lt;br /&gt;
                except:&lt;br /&gt;
                    self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
        # Average out each vnorm..&lt;br /&gt;
        index = 0&lt;br /&gt;
        for v in self.vnorms.values():&lt;br /&gt;
                self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4])         &lt;br /&gt;
                index += 1&lt;br /&gt;
 &lt;br /&gt;
    # Utility function to normalize a given vector&lt;br /&gt;
    def normalize(self,v):&lt;br /&gt;
        mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]&lt;br /&gt;
        if mag &amp;lt;= 0:&lt;br /&gt;
            mag = 1&lt;br /&gt;
        else:&lt;br /&gt;
            mag = math.sqrt(mag)&lt;br /&gt;
 &lt;br /&gt;
        return [v[0]/mag, v[1]/mag,v[2]/mag]&lt;br /&gt;
 &lt;br /&gt;
    # Utility cross product function&lt;br /&gt;
    def cross(self,v1,v2):&lt;br /&gt;
        x = 0&lt;br /&gt;
        y = 1&lt;br /&gt;
        z = 2&lt;br /&gt;
 &lt;br /&gt;
        return [v1[y]*v2[z] - v1[z]*v2[y],\&lt;br /&gt;
                v1[z]*v2[x] - v1[x]*v2[z],\&lt;br /&gt;
                v1[x]*v2[y] - v1[y]*v2[x]&lt;br /&gt;
                ]&lt;br /&gt;
 &lt;br /&gt;
    # Constructor&lt;br /&gt;
    def __init__(self, file,translate=[0,0,0],flip=0):&lt;br /&gt;
        self.verts = []&lt;br /&gt;
        self.polys = [] &lt;br /&gt;
        self.pnorms = []&lt;br /&gt;
        self.vnorms = {}&lt;br /&gt;
        self.vavenorms = []&lt;br /&gt;
        self.translate = translate&lt;br /&gt;
        self.flip      = flip &lt;br /&gt;
 &lt;br /&gt;
        print &amp;quot;Read in file: &amp;quot;+str(file)&lt;br /&gt;
        self.readOBJ(file)&lt;br /&gt;
        print &amp;quot;Done reading in WFMesh, now compute norms&amp;quot;&lt;br /&gt;
        self.computeNorms()&lt;br /&gt;
        print &amp;quot;Done computing norms, now display WFMesh&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # Draw Function&lt;br /&gt;
    def __call__(self):&lt;br /&gt;
 &lt;br /&gt;
        glColorMaterial(GL_FRONT, GL_DIFFUSE);  &lt;br /&gt;
        glEnable(GL_COLOR_MATERIAL);&lt;br /&gt;
        glShadeModel(GL_SMOOTH);&lt;br /&gt;
 &lt;br /&gt;
        # Color Everything grey&lt;br /&gt;
        glColor3f(0.5,0.5,0.5);&lt;br /&gt;
 &lt;br /&gt;
        index = 0&lt;br /&gt;
        glPushMatrix()&lt;br /&gt;
        glTranslated(self.translate[0],self.translate[1],self.translate[2])&lt;br /&gt;
        for p in self.polys:&lt;br /&gt;
                glBegin(GL_POLYGON)&lt;br /&gt;
                glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))&lt;br /&gt;
 &lt;br /&gt;
                for i in range(0,len(p)):&lt;br /&gt;
                        glVertex3f(float(self.verts[int(p[i])-1][0]),float(self.verts[int(p[i])-1][1]),float(self.verts[int(p[i])-1][2]))&lt;br /&gt;
 &lt;br /&gt;
                        # Vertex Normals - not computed correctly, so commented out for now&lt;br /&gt;
#                       norm = self.vnorms[int(p[i])-1]&lt;br /&gt;
#                       glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))&lt;br /&gt;
                glEnd()&lt;br /&gt;
                index += 1&lt;br /&gt;
        glPopMatrix()&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
cmd.extend(&amp;quot;createWFObj&amp;quot;, createWFObj)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ADDITIONAL RESOURCES===&lt;br /&gt;
Torus.obj&lt;br /&gt;
[http://pymolwiki.org/images/9/98/Torus.zip Torus.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|WFMesh]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Wfmesh&amp;diff=10833</id>
		<title>Wfmesh</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Wfmesh&amp;diff=10833"/>
		<updated>2010-02-14T19:09:27Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: Undo revision 8034 by Cowsandmilk (Talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
This script will create an object for any Wavefront(.OBJ) mesh file.  This is a way to extend the number of objects you can use. Also, you have more control over the coloring, transformations, etc than the CGOs. Although there are a number of these obj files on the web, you can also easily created them with open source tools ([http://www.openfx.org OpenFX], [http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]). It takes literally, 2 min to get an object created and then loaded into pymol.  Simply open OpenFX Designer, click File-&amp;gt;Insert-&amp;gt;Model, then choose any of the models (or create your own of course!), then export it as .3ds file.  Then open the .3ds file from Crossroads3D and export as Wavefront OBJ.   &lt;br /&gt;
&lt;br /&gt;
*createWFMesh - create a mesh object from Wavefront (*.obj) formated file&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]&lt;br /&gt;
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:ThirdParty_Scripts]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
Simply &amp;quot;run WFMesh.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Pymolv0.97, Windows platform, should work on linux as well.&lt;br /&gt;
*Coloring is fixed for grey and sections of mesh are stored, but not used.&lt;br /&gt;
*Simple opengl calls; not optimized (display lists, etc) or anything.&lt;br /&gt;
*Vertex Normal code is broken, so normals are per polygon right now.&lt;br /&gt;
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
createWFObj file, name  [,translate=[0,0,0]] [,flip=0]&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
   createWFObj &amp;quot;ship.obj&amp;quot; &amp;quot;Ship&amp;quot;&lt;br /&gt;
   createWFObj &amp;quot;torus.obj&amp;quot; &amp;quot;Torus&amp;quot; flip=1  # Flip = 1, if OBJ created by openFX, crossroads3D combination&lt;br /&gt;
   createWFObj &amp;quot;torus.obj&amp;quot; &amp;quot;Torus&amp;quot; translate=[10,10,0] flip=1      &lt;br /&gt;
   &lt;br /&gt;
===REFERENCES===&lt;br /&gt;
[http://www.openfx.org OpenFX]&lt;br /&gt;
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (WFMesh.py)===&lt;br /&gt;
WFMesh.py&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
###############################################&lt;br /&gt;
#  File:          WFObj.py&lt;br /&gt;
#  Author:        Dan Kulp&lt;br /&gt;
#  Creation Date: 5/13/05&lt;br /&gt;
#&lt;br /&gt;
#  Notes:&lt;br /&gt;
#  Create openGL objects from a wavefront (obj) file&lt;br /&gt;
###############################################&lt;br /&gt;
&lt;br /&gt;
import os&lt;br /&gt;
import re&lt;br /&gt;
import math&lt;br /&gt;
from pymol.opengl.gl import *&lt;br /&gt;
from pymol.callback import Callback&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)&lt;br /&gt;
def createWFObj(file, name,translate=[0,0,0],flip=0):&lt;br /&gt;
	obj = WFMesh(file,translate,flip)&lt;br /&gt;
	cmd.load_callback(obj,name)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Class for Wavefront Mesh&lt;br /&gt;
class WFMesh(Callback):&lt;br /&gt;
&lt;br /&gt;
    verts = []        # list of vertices&lt;br /&gt;
    polys = []        # list of poylgons&lt;br /&gt;
    pnorms = []       # list of polynomal normals&lt;br /&gt;
    vnorms = {}       # dict. of vertex normals&lt;br /&gt;
    vavenorms = []    # list of vertex normals, redundant -- I'm far froma python pro.&lt;br /&gt;
    sections = {}     # list of sections of mesh&lt;br /&gt;
&lt;br /&gt;
    # Read mesh into memory&lt;br /&gt;
    def readOBJ(self,file):&lt;br /&gt;
        if os.path.exists(file):&lt;br /&gt;
	    input = open(file,'r')&lt;br /&gt;
	    for line in input:&lt;br /&gt;
		dat = re.split(&amp;quot;\s+&amp;quot;, line)&lt;br /&gt;
&lt;br /&gt;
		# Find vertex line&lt;br /&gt;
		if line[0] == 'v' and line[1] != 't' and line[1] != 'n':    self.verts.append([dat[1],dat[2],dat[3]])&lt;br /&gt;
&lt;br /&gt;
		# Find polygon line&lt;br /&gt;
       	        if line[0] == 'f':    self.polys.append([dat[1],dat[2],dat[3]])&lt;br /&gt;
&lt;br /&gt;
		# Find section line&lt;br /&gt;
		if line[0] == 'g':    self.sections[len(self.polys)] = dat[1] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    # Compute the normals for each polygon and each vertex   		&lt;br /&gt;
    def computeNorms(self):&lt;br /&gt;
&lt;br /&gt;
	# Compute norms for each polygon&lt;br /&gt;
	for p in self.polys:&lt;br /&gt;
		v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\&lt;br /&gt;
		       float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\&lt;br /&gt;
		       float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \&lt;br /&gt;
		      ]&lt;br /&gt;
			&lt;br /&gt;
		v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\&lt;br /&gt;
		       float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\&lt;br /&gt;
		       float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \&lt;br /&gt;
		      ]	&lt;br /&gt;
&lt;br /&gt;
		# Compute poly normal&lt;br /&gt;
		polynorm = self.cross(v12,v13) &lt;br /&gt;
		norm = self.normalize(polynorm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		# Files created by OpenFX, Crossroads combination need have their normals flipped	&lt;br /&gt;
		if self.flip:&lt;br /&gt;
			norm[0] = -norm[0]&lt;br /&gt;
			norm[1] = -norm[1]&lt;br /&gt;
			norm[2] = -norm[2]&lt;br /&gt;
&lt;br /&gt;
		# Append poly norm to polygonal norm array&lt;br /&gt;
		self.pnorms.append(norm)&lt;br /&gt;
&lt;br /&gt;
		# Add norm to each vertexes norm..&lt;br /&gt;
	        try:&lt;br /&gt;
		    self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],&lt;br /&gt;
					    float(self.vnorms[int(p[0])-1][1]) + norm[1],&lt;br /&gt;
					    float(self.vnorms[int(p[0])-1][2]) + norm[2]&lt;br /&gt;
					   ]&lt;br /&gt;
		except:&lt;br /&gt;
		    self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
&lt;br /&gt;
	        try:					   &lt;br /&gt;
		    self.vnorms[int(p[1])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],&lt;br /&gt;
					    float(self.vnorms[int(p[1])-1][1]) + norm[1],&lt;br /&gt;
					    float(self.vnorms[int(p[1])-1][2]) + norm[2]&lt;br /&gt;
					   ]&lt;br /&gt;
		except:&lt;br /&gt;
		    self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
&lt;br /&gt;
		try:&lt;br /&gt;
		    self.vnorms[int(p[2])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],&lt;br /&gt;
					    float(self.vnorms[int(p[1])-1][1]) + norm[1],&lt;br /&gt;
					    float(self.vnorms[int(p[1])-1][2]) + norm[2]&lt;br /&gt;
					   ]&lt;br /&gt;
		except:&lt;br /&gt;
		    self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
&lt;br /&gt;
      &lt;br /&gt;
        # Average out each vnorm..&lt;br /&gt;
	index = 0&lt;br /&gt;
      	for v in self.vnorms.values():&lt;br /&gt;
		self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4])		&lt;br /&gt;
		index += 1&lt;br /&gt;
&lt;br /&gt;
    # Utility function to normalize a given vector&lt;br /&gt;
    def normalize(self,v):&lt;br /&gt;
	mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]&lt;br /&gt;
	if mag &amp;lt;= 0:&lt;br /&gt;
  	    mag = 1&lt;br /&gt;
	else:&lt;br /&gt;
	    mag = math.sqrt(mag)&lt;br /&gt;
		&lt;br /&gt;
	return [v[0]/mag, v[1]/mag,v[2]/mag]&lt;br /&gt;
&lt;br /&gt;
    # Utility cross product function&lt;br /&gt;
    def cross(self,v1,v2):&lt;br /&gt;
	x = 0&lt;br /&gt;
	y = 1&lt;br /&gt;
	z = 2&lt;br /&gt;
&lt;br /&gt;
	return [v1[y]*v2[z] - v1[z]*v2[y],\&lt;br /&gt;
		v1[z]*v2[x] - v1[x]*v2[z],\&lt;br /&gt;
		v1[x]*v2[y] - v1[y]*v2[x]&lt;br /&gt;
		]&lt;br /&gt;
		          	&lt;br /&gt;
    # Constructor&lt;br /&gt;
    def __init__(self, file,translate=[0,0,0],flip=0):&lt;br /&gt;
        self.verts = []&lt;br /&gt;
        self.polys = [] &lt;br /&gt;
        self.pnorms = []&lt;br /&gt;
        self.vnorms = {}&lt;br /&gt;
        self.vavenorms = []&lt;br /&gt;
	self.translate = translate&lt;br /&gt;
	self.flip      = flip &lt;br /&gt;
&lt;br /&gt;
        print &amp;quot;Read in file: &amp;quot;+str(file)&lt;br /&gt;
	self.readOBJ(file)&lt;br /&gt;
	print &amp;quot;Done reading in WFMesh, now compute norms&amp;quot;&lt;br /&gt;
	self.computeNorms()&lt;br /&gt;
	print &amp;quot;Done computing norms, now display WFMesh&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Draw Function&lt;br /&gt;
    def __call__(self):&lt;br /&gt;
	&lt;br /&gt;
	glColorMaterial(GL_FRONT, GL_DIFFUSE);	&lt;br /&gt;
        glEnable(GL_COLOR_MATERIAL);&lt;br /&gt;
	glShadeModel(GL_SMOOTH);&lt;br /&gt;
&lt;br /&gt;
	# Color Everything grey&lt;br /&gt;
        glColor3f(0.5,0.5,0.5);&lt;br /&gt;
&lt;br /&gt;
	index = 0&lt;br /&gt;
	glPushMatrix()&lt;br /&gt;
	glTranslated(self.translate[0],self.translate[1],self.translate[2])&lt;br /&gt;
	for p in self.polys:&lt;br /&gt;
		glBegin(GL_POLYGON)&lt;br /&gt;
		glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))&lt;br /&gt;
		&lt;br /&gt;
		for i in range(0,len(p)):&lt;br /&gt;
			glVertex3f(float(self.verts[int(p[i])-1][0]),float(self.verts[int(p[i])-1][1]),float(self.verts[int(p[i])-1][2]))&lt;br /&gt;
&lt;br /&gt;
			# Vertex Normals - not computed correctly, so commented out for now&lt;br /&gt;
#			norm = self.vnorms[int(p[i])-1]&lt;br /&gt;
#			glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))&lt;br /&gt;
		glEnd()&lt;br /&gt;
		index += 1&lt;br /&gt;
	glPopMatrix()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
cmd.extend(&amp;quot;createWFObj&amp;quot;, createWFObj)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ADDITIONAL RESOURCES===&lt;br /&gt;
Torus.obj&lt;br /&gt;
[http://pymolwiki.org/images/9/98/Torus.zip Torus.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|WFMesh]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=DynoPlot&amp;diff=8243</id>
		<title>DynoPlot</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=DynoPlot&amp;diff=8243"/>
		<updated>2010-02-14T19:08:37Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* SCRIPTS (DynoPlot.py) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
This script was setup to do generic plotting, that is given a set of data and axis labels it would create a plot. Initially, I had it setup to draw the plot directly in the PyMol window (allowing for both 2D and 3D style plots), but because I couldn't figure out how to billboard CGO objects (Warren told me at the time that it couldn't be done) I took a different approach.  The plot now exists in it's own window and can only do 2D plots.  It is however interactive.  I only have here a Rama.(phi,psi) plot, but the code can be easily extended to other types of data.  For instance, I had this working for an energy vs distance data that I had generated by another script.&lt;br /&gt;
&lt;br /&gt;
This script will create a Phi vs Psi(Ramachandran) plot of the selection given.  The plot will display data points which can be dragged around Phi,Psi space with the corresponding residue's Phi,Psi angles changing in the structure (PyMol window).&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:RamaPlotInitComposite.png|Initial Ramachandran plot of 1ENV&lt;br /&gt;
Image:RamaPlotBentComposite.png|Modified pose and plot of 1ENV&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
place the DynoPlot.py script into the appropriate startup directory then restart PyMol&lt;br /&gt;
&lt;br /&gt;
==== LINUX old-style installation ====&lt;br /&gt;
&lt;br /&gt;
$PYMOL_PATH/modules/pmg_tk/startup/&lt;br /&gt;
&lt;br /&gt;
==== LINUX distutils installation ====&lt;br /&gt;
&lt;br /&gt;
/usr/lib/pythonX.X/site-packages/pmg_tk/startup/&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
PYMOL_PATH/modules/pmg_tk/startup/ , where PYMOL_PATH on Windows is defaulted to C:/Program Files/DeLano Scientific/PyMol/start/&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Windows, PyMol version 0.97&lt;br /&gt;
*This is an initial version, which needs some work.  &lt;br /&gt;
*Left, Right mouse buttons do different things; Right = identify data point, Left = drag data point around&lt;br /&gt;
*Post comments/questions or send them to: dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
rama SELECTION&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===    &lt;br /&gt;
*load pdb file 1ENV (download it or use the PDB loader plugin)&lt;br /&gt;
*select resi 129-136&lt;br /&gt;
*rama sel01&lt;br /&gt;
*rock   # the object needs to be moving in order for the angles to be updated.&lt;br /&gt;
&lt;br /&gt;
===REFERENCES===&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (DynoPlot.py)===&lt;br /&gt;
DynoPlot.py&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
###############################################&lt;br /&gt;
#  File:          DynoPlot.py&lt;br /&gt;
#  Author:        Dan Kulp&lt;br /&gt;
#  Creation Date: 8/29/05&lt;br /&gt;
#&lt;br /&gt;
#  Notes:&lt;br /&gt;
#  Draw plots that display interactive data.&lt;br /&gt;
#   Phi,Psi plot shown.&lt;br /&gt;
###############################################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from __future__ import division&lt;br /&gt;
from __future__ import generators&lt;br /&gt;
&lt;br /&gt;
import os,math&lt;br /&gt;
import Tkinter&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
import Pmw&lt;br /&gt;
import distutils.spawn # used for find_executable&lt;br /&gt;
import random&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    import pymol&lt;br /&gt;
    REAL_PYMOL = True&lt;br /&gt;
except ImportError:&lt;br /&gt;
        print &amp;quot;Nope&amp;quot;&lt;br /&gt;
&lt;br /&gt;
canvas = None&lt;br /&gt;
rootframe = None&lt;br /&gt;
init = 0&lt;br /&gt;
&lt;br /&gt;
class SimplePlot(Tkinter.Canvas):&lt;br /&gt;
&lt;br /&gt;
        # Class variables&lt;br /&gt;
        mark = 'Oval' # Only 'Oval' for now..&lt;br /&gt;
        mark_size = 5&lt;br /&gt;
        xlabels = []   # axis labels&lt;br /&gt;
        ylabels = []&lt;br /&gt;
        spacingx = 0   # spacing in x direction&lt;br /&gt;
        spacingy = 0&lt;br /&gt;
        xmin = 0       # min value from each axis&lt;br /&gt;
        ymin = 0&lt;br /&gt;
        lastx = 0      # previous x,y pos of mouse&lt;br /&gt;
        lasty = 0&lt;br /&gt;
        down  = 0      # flag for mouse pressed&lt;br /&gt;
        item = (0,)    # items array used for clickable events&lt;br /&gt;
        shapes = {}    # store plot data, x,y etc..&lt;br /&gt;
&lt;br /&gt;
        def axis(self,xmin=40,xmax=300,ymin=10,ymax=290,xint=290,yint=40,xlabels=[],ylabels=[]):&lt;br /&gt;
&lt;br /&gt;
                # Store variables in self object&lt;br /&gt;
                self.xlabels = xlabels&lt;br /&gt;
                self.ylabels = ylabels&lt;br /&gt;
                self.spacingx = (xmax-xmin) / (len(xlabels) - 1)&lt;br /&gt;
                self.spacingy = (ymax-ymin) / (len(ylabels) - 1)&lt;br /&gt;
                self.xmin = xmin&lt;br /&gt;
                self.ymin = ymin&lt;br /&gt;
&lt;br /&gt;
                # Create axis lines&lt;br /&gt;
                self.create_line((xmin,xint,xmax,xint),fill=&amp;quot;black&amp;quot;,width=3)&lt;br /&gt;
                self.create_line((yint,ymin,yint,ymax),fill=&amp;quot;black&amp;quot;,width=3)&lt;br /&gt;
&lt;br /&gt;
                # Create tick marks and labels&lt;br /&gt;
                nextspot = xmin&lt;br /&gt;
                for label in xlabels:&lt;br /&gt;
                    self.create_line((nextspot, xint+5,nextspot, xint-5),fill=&amp;quot;black&amp;quot;,width=2)&lt;br /&gt;
                    self.create_text(nextspot, xint-15, text=label)&lt;br /&gt;
                    if len(xlabels) == 1:&lt;br /&gt;
                        nextspot = xmax&lt;br /&gt;
                    else:&lt;br /&gt;
                        nextspot += (xmax - xmin)/ (len(xlabels) - 1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                nextspot = ymax&lt;br /&gt;
                for label in ylabels:&lt;br /&gt;
                    self.create_line((yint+5,nextspot,yint-5,nextspot),fill=&amp;quot;black&amp;quot;,width=2)&lt;br /&gt;
                    self.create_text(yint-20,nextspot,text=label)&lt;br /&gt;
                    if len(ylabels) == 1:&lt;br /&gt;
                        nextspot = ymin&lt;br /&gt;
                    else:&lt;br /&gt;
                        nextspot -= (ymax - ymin)/ (len(ylabels) - 1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Plot a point&lt;br /&gt;
        def plot(self,xp,yp,meta):&lt;br /&gt;
&lt;br /&gt;
                # Convert from 'label' space to 'pixel' space&lt;br /&gt;
                x = self.convertToPixel(&amp;quot;X&amp;quot;,xp)&lt;br /&gt;
                y = self.convertToPixel(&amp;quot;Y&amp;quot;,yp)&lt;br /&gt;
&lt;br /&gt;
                if self.mark == &amp;quot;Oval&amp;quot;:&lt;br /&gt;
                    oval = self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline=&amp;quot;black&amp;quot;,fill=&amp;quot;SkyBlue2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                    self.shapes[oval] = [x,y,0,xp,yp,meta]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Repaint all points&lt;br /&gt;
        def repaint(self):&lt;br /&gt;
                for value in self.shapes.values():&lt;br /&gt;
                        x = value[0]&lt;br /&gt;
                        y = value[1]&lt;br /&gt;
                        self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline=&amp;quot;black&amp;quot;,fill=&amp;quot;SkyBlue2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        # Convert from pixel space to label space&lt;br /&gt;
        def convertToLabel(self,axis, value):&lt;br /&gt;
&lt;br /&gt;
                # Defaultly use X-axis info&lt;br /&gt;
                label0  = self.xlabels[0]&lt;br /&gt;
                label1  = self.xlabels[1]&lt;br /&gt;
                spacing = self.spacingx&lt;br /&gt;
                min     = self.xmin&lt;br /&gt;
&lt;br /&gt;
                # Set info for Y-axis use&lt;br /&gt;
                if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
                    label0    = self.ylabels[0]&lt;br /&gt;
                    label1    = self.ylabels[1]&lt;br /&gt;
                    spacing   = self.spacingy&lt;br /&gt;
                    min       = self.ymin&lt;br /&gt;
&lt;br /&gt;
                pixel = value - min&lt;br /&gt;
                label = pixel / spacing&lt;br /&gt;
                label = label0 + label * abs(label1 - label0)&lt;br /&gt;
&lt;br /&gt;
                if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
                        label = - label&lt;br /&gt;
&lt;br /&gt;
                return label&lt;br /&gt;
&lt;br /&gt;
        # Converts value from 'label' space to 'pixel' space&lt;br /&gt;
        def convertToPixel(self,axis, value):&lt;br /&gt;
&lt;br /&gt;
                # Defaultly use X-axis info&lt;br /&gt;
                label0  = self.xlabels[0]&lt;br /&gt;
                label1  = self.xlabels[1]&lt;br /&gt;
                spacing = self.spacingx&lt;br /&gt;
                min     = self.xmin&lt;br /&gt;
&lt;br /&gt;
                # Set info for Y-axis use&lt;br /&gt;
                if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
                    label0    = self.ylabels[0]&lt;br /&gt;
                    label1    = self.ylabels[1]&lt;br /&gt;
                    spacing   = self.spacingy&lt;br /&gt;
                    min       = self.ymin       &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                # Get axis increment in 'label' space&lt;br /&gt;
                inc = abs(label1 - label0)&lt;br /&gt;
&lt;br /&gt;
                # 'Label' difference from value and smallest label (label0)&lt;br /&gt;
                diff = float(value - label0)&lt;br /&gt;
&lt;br /&gt;
                # Get whole number in 'label' space&lt;br /&gt;
                whole = int(diff / inc)&lt;br /&gt;
&lt;br /&gt;
                # Get fraction number in 'label' space&lt;br /&gt;
                part = float(float(diff/inc) - whole)&lt;br /&gt;
&lt;br /&gt;
                # Return 'pixel' position value&lt;br /&gt;
                pixel = whole * spacing + part * spacing&lt;br /&gt;
&lt;br /&gt;
#               print &amp;quot;Pixel: %f * %f + %f * %f = %f&amp;quot; % (whole, spacing, part, spacing,pixel)&lt;br /&gt;
&lt;br /&gt;
                # Reverse number by subtracting total number of pixels - value pixels&lt;br /&gt;
                if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
                   tot_label_diff = float(self.ylabels[len(self.ylabels)- 1] - label0)&lt;br /&gt;
                   tot_label_whole = int(tot_label_diff / inc)&lt;br /&gt;
                   tot_label_part = float(float(tot_label_diff / inc) - tot_label_whole)&lt;br /&gt;
                   tot_label_pix  = tot_label_whole * spacing + tot_label_part *spacing&lt;br /&gt;
&lt;br /&gt;
                   pixel = tot_label_pix - pixel&lt;br /&gt;
&lt;br /&gt;
                # Add min edge pixels&lt;br /&gt;
                pixel = pixel + min&lt;br /&gt;
&lt;br /&gt;
                return pixel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Print out which data point you just clicked on..&lt;br /&gt;
        def pickWhich(self,event):&lt;br /&gt;
&lt;br /&gt;
            # Find closest data point               &lt;br /&gt;
            x = event.widget.canvasx(event.x)&lt;br /&gt;
            y = event.widget.canvasx(event.y)&lt;br /&gt;
            spot = event.widget.find_closest(x,y)&lt;br /&gt;
&lt;br /&gt;
            # Print the shape's meta information corresponding with the shape that was picked&lt;br /&gt;
            if spot[0] in self.shapes:&lt;br /&gt;
                print &amp;quot;Residue(Ca): %s\n&amp;quot; % self.shapes[spot[0]][5][2]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Mouse Down Event&lt;br /&gt;
        def down(self,event):&lt;br /&gt;
&lt;br /&gt;
            # Store x,y position&lt;br /&gt;
            self.lastx = event.x&lt;br /&gt;
            self.lasty = event.y&lt;br /&gt;
&lt;br /&gt;
            # Find the currently selected item&lt;br /&gt;
            x = event.widget.canvasx(event.x)&lt;br /&gt;
            y = event.widget.canvasx(event.y)&lt;br /&gt;
            self.item = event.widget.find_closest(x,y)&lt;br /&gt;
&lt;br /&gt;
            # Identify that the mouse is down&lt;br /&gt;
            self.down  = 1&lt;br /&gt;
&lt;br /&gt;
        # Mouse Up Event&lt;br /&gt;
        def up(self,event):&lt;br /&gt;
&lt;br /&gt;
            # Get label space version of x,y&lt;br /&gt;
            labelx = self.convertToLabel(&amp;quot;X&amp;quot;,event.x)&lt;br /&gt;
            labely = self.convertToLabel(&amp;quot;Y&amp;quot;,event.y)&lt;br /&gt;
&lt;br /&gt;
            # Convert new position into label space..&lt;br /&gt;
            if self.item[0] in self.shapes:&lt;br /&gt;
                self.shapes[self.item[0]][0] = event.x&lt;br /&gt;
                self.shapes[self.item[0]][1] = event.y&lt;br /&gt;
                self.shapes[self.item[0]][2] =  1&lt;br /&gt;
                self.shapes[self.item[0]][3] = labelx&lt;br /&gt;
                self.shapes[self.item[0]][4] = labely&lt;br /&gt;
&lt;br /&gt;
            # Reset Flags&lt;br /&gt;
            self.item = (0,)&lt;br /&gt;
            self.down = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Mouse Drag(Move) Event&lt;br /&gt;
        def drag(self,event):&lt;br /&gt;
&lt;br /&gt;
                # Check that mouse is down and item clicked is a valid data point&lt;br /&gt;
                if self.down and self.item[0] in self.shapes:&lt;br /&gt;
&lt;br /&gt;
                    self.move(self.item, event.x - self.lastx, event.y - self.lasty)&lt;br /&gt;
&lt;br /&gt;
                    self.lastx = event.x&lt;br /&gt;
                    self.lasty = event.y&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def __init__(self):&lt;br /&gt;
&lt;br /&gt;
        self.menuBar.addcascademenu('Plugin', 'PlotTools', 'Plot Tools',&lt;br /&gt;
                                    label='Plot Tools')&lt;br /&gt;
        self.menuBar.addmenuitem('PlotTools', 'command',&lt;br /&gt;
                                 'Launch Rama Plot',&lt;br /&gt;
                                 label='Rama Plot',&lt;br /&gt;
                                 command = lambda s=self: ramaplot())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def ramaplot(x=0,y=0,meta=[],clear=0):&lt;br /&gt;
    global canvas&lt;br /&gt;
    global rootframe&lt;br /&gt;
    global init&lt;br /&gt;
&lt;br /&gt;
    # If no window is open&lt;br /&gt;
    if init == 0:&lt;br /&gt;
        rootframe=Tk()&lt;br /&gt;
        rootframe.title(' Dynamic Angle Plotting ')&lt;br /&gt;
        rootframe.protocol(&amp;quot;WM_DELETE_WINDOW&amp;quot;, close_callback)&lt;br /&gt;
&lt;br /&gt;
        canvas = SimplePlot(rootframe,width=320,height=320)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;Button-2&amp;gt;&amp;quot;,canvas.pickWhich)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;Button-3&amp;gt;&amp;quot;,canvas.pickWhich)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;ButtonPress-1&amp;gt;&amp;quot;,canvas.down)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;ButtonRelease-1&amp;gt;&amp;quot;,canvas.up)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;Motion&amp;gt;&amp;quot;,canvas.drag)&lt;br /&gt;
        canvas.pack(side=Tkinter.LEFT,fill=&amp;quot;both&amp;quot;,expand=1)&lt;br /&gt;
        canvas.axis(xint=150,xlabels=[-180,-150,-120,-90,-60,-30,0,30,60,90,120,150,180],ylabels=[-180,-150,-120,-90,-60,-30,0,30,60,90,120,150,180])&lt;br /&gt;
        canvas.update()&lt;br /&gt;
        init = 1&lt;br /&gt;
    else:&lt;br /&gt;
      canvas.plot(int(x), int(y),meta)&lt;br /&gt;
&lt;br /&gt;
def close_callback():&lt;br /&gt;
    global init&lt;br /&gt;
    global rootframe&lt;br /&gt;
    init = 0&lt;br /&gt;
    rootframe.destroy()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# New Callback object, so that we can update the structure when phi,psi points are moved.&lt;br /&gt;
class DynoRamaObject:&lt;br /&gt;
        global canvas&lt;br /&gt;
&lt;br /&gt;
        def start(self,sel):&lt;br /&gt;
&lt;br /&gt;
            # Get selection model&lt;br /&gt;
            model = cmd.get_model(sel)&lt;br /&gt;
            residues = ['dummy']&lt;br /&gt;
            resnames = ['dummy']&lt;br /&gt;
            phi = []&lt;br /&gt;
            psi = []&lt;br /&gt;
            dummy = []&lt;br /&gt;
            i = 0&lt;br /&gt;
&lt;br /&gt;
            # Loop through each atom&lt;br /&gt;
            for at in model.atom:&lt;br /&gt;
&lt;br /&gt;
                # Only plot once per residue&lt;br /&gt;
                if at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi not in residues:&lt;br /&gt;
                    residues.append(at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi)&lt;br /&gt;
                    resnames.append(at.resn+at.resi)&lt;br /&gt;
                    dummy.append(i)&lt;br /&gt;
                    i += 1&lt;br /&gt;
&lt;br /&gt;
                    # Check for a null chain id (some PDBs contain this)&lt;br /&gt;
                    unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
                    if at.chain != &amp;quot;&amp;quot;:&lt;br /&gt;
                        unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
&lt;br /&gt;
                    # Define selections for residue i-1, i and i+1&lt;br /&gt;
                    residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
                    residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)&lt;br /&gt;
                    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)&lt;br /&gt;
&lt;br /&gt;
                    try:&lt;br /&gt;
                        # Store phi,psi residue definitions to pass on to plot routine&lt;br /&gt;
                        phi_psi = [&lt;br /&gt;
                                # Phi angles&lt;br /&gt;
                                   residue_def_prev+' and name C',&lt;br /&gt;
                                   residue_def+' and name N',&lt;br /&gt;
                                   residue_def+' and name CA',&lt;br /&gt;
                                   residue_def+' and name C',&lt;br /&gt;
                                # Psi angles&lt;br /&gt;
                                   residue_def+' and name N',&lt;br /&gt;
                                   residue_def+' and name CA',&lt;br /&gt;
                                   residue_def+' and name C',&lt;br /&gt;
                                   residue_def_next+' and name N']&lt;br /&gt;
&lt;br /&gt;
                        # Compute phi/psi angle&lt;br /&gt;
                        phi = cmd.get_dihedral(phi_psi[0],phi_psi[1],phi_psi[2],phi_psi[3])&lt;br /&gt;
                        psi = cmd.get_dihedral(phi_psi[4],phi_psi[5],phi_psi[6],phi_psi[7])&lt;br /&gt;
&lt;br /&gt;
                        print &amp;quot;Plotting Phi,Psi: &amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)&lt;br /&gt;
                        ramaplot(phi,psi,meta=phi_psi)&lt;br /&gt;
                    except:&lt;br /&gt;
                        continue&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        def __call__(self):&lt;br /&gt;
&lt;br /&gt;
            # Loop through each item on plot to see if updated&lt;br /&gt;
            for key,value in canvas.shapes.items():&lt;br /&gt;
                dihedrals = value[5]&lt;br /&gt;
&lt;br /&gt;
                # Look for update flag...&lt;br /&gt;
                if value[2]:&lt;br /&gt;
&lt;br /&gt;
                    # Set residue's phi,psi to new values&lt;br /&gt;
                    print &amp;quot;Re-setting Phi,Psi: %s,%s&amp;quot; % (value[3],value[4])&lt;br /&gt;
                    cmd.set_dihedral(dihedrals[0],dihedrals[1],dihedrals[2],dihedrals[3],value[3])&lt;br /&gt;
                    cmd.set_dihedral(dihedrals[4],dihedrals[5],dihedrals[6],dihedrals[7],value[4])&lt;br /&gt;
&lt;br /&gt;
                    value[2] = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# The wrapper function, used to create the Ploting window and the PyMol callback object                 &lt;br /&gt;
def rama(sel):&lt;br /&gt;
        rama = DynoRamaObject()&lt;br /&gt;
        rama.start(sel)&lt;br /&gt;
        cmd.load_callback(rama, &amp;quot;DynoRamaObject&amp;quot;)&lt;br /&gt;
        cmd.zoom(&amp;quot;all&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Extend these commands&lt;br /&gt;
cmd.extend('rama',rama)&lt;br /&gt;
cmd.extend('ramaplot',ramaplot)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ADDITIONAL RESOURCES===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|DynoPlot]]&lt;br /&gt;
[[Category:Structural_Biology_Scripts|DynoPlot]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=DynoPlot&amp;diff=8242</id>
		<title>DynoPlot</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=DynoPlot&amp;diff=8242"/>
		<updated>2010-02-14T19:07:09Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: Undo revision 8032 by Cowsandmilk (Talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
This script was setup to do generic plotting, that is given a set of data and axis labels it would create a plot. Initially, I had it setup to draw the plot directly in the PyMol window (allowing for both 2D and 3D style plots), but because I couldn't figure out how to billboard CGO objects (Warren told me at the time that it couldn't be done) I took a different approach.  The plot now exists in it's own window and can only do 2D plots.  It is however interactive.  I only have here a Rama.(phi,psi) plot, but the code can be easily extended to other types of data.  For instance, I had this working for an energy vs distance data that I had generated by another script.&lt;br /&gt;
&lt;br /&gt;
This script will create a Phi vs Psi(Ramachandran) plot of the selection given.  The plot will display data points which can be dragged around Phi,Psi space with the corresponding residue's Phi,Psi angles changing in the structure (PyMol window).&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:RamaPlotInitComposite.png|Initial Ramachandran plot of 1ENV&lt;br /&gt;
Image:RamaPlotBentComposite.png|Modified pose and plot of 1ENV&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
place the DynoPlot.py script into the appropriate startup directory then restart PyMol&lt;br /&gt;
&lt;br /&gt;
==== LINUX old-style installation ====&lt;br /&gt;
&lt;br /&gt;
$PYMOL_PATH/modules/pmg_tk/startup/&lt;br /&gt;
&lt;br /&gt;
==== LINUX distutils installation ====&lt;br /&gt;
&lt;br /&gt;
/usr/lib/pythonX.X/site-packages/pmg_tk/startup/&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
PYMOL_PATH/modules/pmg_tk/startup/ , where PYMOL_PATH on Windows is defaulted to C:/Program Files/DeLano Scientific/PyMol/start/&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Windows, PyMol version 0.97&lt;br /&gt;
*This is an initial version, which needs some work.  &lt;br /&gt;
*Left, Right mouse buttons do different things; Right = identify data point, Left = drag data point around&lt;br /&gt;
*Post comments/questions or send them to: dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
rama SELECTION&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===    &lt;br /&gt;
*load pdb file 1ENV (download it or use the PDB loader plugin)&lt;br /&gt;
*select resi 129-136&lt;br /&gt;
*rama sel01&lt;br /&gt;
*rock   # the object needs to be moving in order for the angles to be updated.&lt;br /&gt;
&lt;br /&gt;
===REFERENCES===&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (DynoPlot.py)===&lt;br /&gt;
DynoPlot.py&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
###############################################&lt;br /&gt;
#  File:          DynoPlot.py&lt;br /&gt;
#  Author:        Dan Kulp&lt;br /&gt;
#  Creation Date: 8/29/05&lt;br /&gt;
#&lt;br /&gt;
#  Notes:&lt;br /&gt;
#  Draw plots that display interactive data. &lt;br /&gt;
#   Phi,Psi plot shown.&lt;br /&gt;
###############################################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from __future__ import division&lt;br /&gt;
from __future__ import generators&lt;br /&gt;
&lt;br /&gt;
import os,math&lt;br /&gt;
import Tkinter&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
import Pmw&lt;br /&gt;
import distutils.spawn # used for find_executable&lt;br /&gt;
import random&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    import pymol&lt;br /&gt;
    REAL_PYMOL = True&lt;br /&gt;
except ImportError:&lt;br /&gt;
	print &amp;quot;Nope&amp;quot;&lt;br /&gt;
&lt;br /&gt;
canvas = None&lt;br /&gt;
init = 0&lt;br /&gt;
&lt;br /&gt;
class SimplePlot(Tkinter.Canvas):&lt;br /&gt;
&lt;br /&gt;
	# Class variables&lt;br /&gt;
	mark = 'Oval' # Only 'Oval' for now..&lt;br /&gt;
	mark_size = 5&lt;br /&gt;
	xlabels = []   # axis labels&lt;br /&gt;
	ylabels = []&lt;br /&gt;
	spacingx = 0   # spacing in x direction&lt;br /&gt;
	spacingy = 0    &lt;br /&gt;
	xmin = 0       # min value from each axis&lt;br /&gt;
	ymin = 0&lt;br /&gt;
	lastx = 0      # previous x,y pos of mouse   &lt;br /&gt;
	lasty = 0&lt;br /&gt;
	down  = 0      # flag for mouse pressed&lt;br /&gt;
	item = (0,)    # items array used for clickable events&lt;br /&gt;
	shapes = {}    # store plot data, x,y etc..&lt;br /&gt;
&lt;br /&gt;
	def axis(self,xmin=40,xmax=300,ymin=10,ymax=290,xint=290,yint=40,xlabels=[],ylabels=[]):&lt;br /&gt;
&lt;br /&gt;
		# Store variables in self object&lt;br /&gt;
		self.xlabels = xlabels&lt;br /&gt;
		self.ylabels = ylabels&lt;br /&gt;
		self.spacingx = (xmax-xmin) / (len(xlabels) - 1)&lt;br /&gt;
		self.spacingy = (ymax-ymin) / (len(ylabels) - 1)&lt;br /&gt;
		self.xmin = xmin&lt;br /&gt;
		self.ymin = ymin&lt;br /&gt;
&lt;br /&gt;
		# Create axis lines&lt;br /&gt;
		self.create_line((xmin,xint,xmax,xint),fill=&amp;quot;black&amp;quot;,width=3)&lt;br /&gt;
		self.create_line((yint,ymin,yint,ymax),fill=&amp;quot;black&amp;quot;,width=3)&lt;br /&gt;
&lt;br /&gt;
		# Create tick marks and labels&lt;br /&gt;
		nextspot = xmin&lt;br /&gt;
		for label in xlabels:&lt;br /&gt;
		    self.create_line((nextspot, xint+5,nextspot, xint-5),fill=&amp;quot;black&amp;quot;,width=2)&lt;br /&gt;
		    self.create_text(nextspot, xint-15, text=label)&lt;br /&gt;
		    if len(xlabels) == 1:&lt;br /&gt;
			nextspot = xmax&lt;br /&gt;
		    else:&lt;br /&gt;
		        nextspot += (xmax - xmin)/ (len(xlabels) - 1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		nextspot = ymax&lt;br /&gt;
    		for label in ylabels:&lt;br /&gt;
		    self.create_line((yint+5,nextspot,yint-5,nextspot),fill=&amp;quot;black&amp;quot;,width=2)&lt;br /&gt;
		    self.create_text(yint-20,nextspot,text=label)&lt;br /&gt;
		    if len(ylabels) == 1:&lt;br /&gt;
			nextspot = ymin&lt;br /&gt;
		    else:&lt;br /&gt;
		        nextspot -= (ymax - ymin)/ (len(ylabels) - 1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	# Plot a point&lt;br /&gt;
	def plot(self,xp,yp,meta):&lt;br /&gt;
		&lt;br /&gt;
		# Convert from 'label' space to 'pixel' space&lt;br /&gt;
		x = self.convertToPixel(&amp;quot;X&amp;quot;,xp)&lt;br /&gt;
		y = self.convertToPixel(&amp;quot;Y&amp;quot;,yp)&lt;br /&gt;
&lt;br /&gt;
		if self.mark == &amp;quot;Oval&amp;quot;:&lt;br /&gt;
		    oval = self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline=&amp;quot;black&amp;quot;,fill=&amp;quot;SkyBlue2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		    self.shapes[oval] = [x,y,0,xp,yp,meta]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	# Repaint all points		&lt;br /&gt;
	def repaint(self):&lt;br /&gt;
		for value in self.shapes.values():&lt;br /&gt;
			x = value[0]&lt;br /&gt;
			y = value[1]&lt;br /&gt;
			self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline=&amp;quot;black&amp;quot;,fill=&amp;quot;SkyBlue2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	# Convert from pixel space to label space&lt;br /&gt;
	def convertToLabel(self,axis, value):&lt;br /&gt;
&lt;br /&gt;
		# Defaultly use X-axis info&lt;br /&gt;
		label0  = self.xlabels[0]&lt;br /&gt;
		label1  = self.xlabels[1]&lt;br /&gt;
		spacing = self.spacingx&lt;br /&gt;
		min     = self.xmin&lt;br /&gt;
&lt;br /&gt;
		# Set info for Y-axis use&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
	  	    label0    = self.ylabels[0]&lt;br /&gt;
  		    label1    = self.ylabels[1]&lt;br /&gt;
		    spacing   = self.spacingy&lt;br /&gt;
		    min       = self.ymin	&lt;br /&gt;
&lt;br /&gt;
		pixel = value - min&lt;br /&gt;
		label = pixel / spacing&lt;br /&gt;
		label = label0 + label * abs(label1 - label0)&lt;br /&gt;
&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
			label = - label&lt;br /&gt;
&lt;br /&gt;
		return label&lt;br /&gt;
&lt;br /&gt;
	# Converts value from 'label' space to 'pixel' space&lt;br /&gt;
	def convertToPixel(self,axis, value):&lt;br /&gt;
&lt;br /&gt;
		# Defaultly use X-axis info&lt;br /&gt;
		label0  = self.xlabels[0]&lt;br /&gt;
		label1  = self.xlabels[1]&lt;br /&gt;
		spacing = self.spacingx&lt;br /&gt;
		min     = self.xmin&lt;br /&gt;
&lt;br /&gt;
		# Set info for Y-axis use&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
	  	    label0    = self.ylabels[0]&lt;br /&gt;
  		    label1    = self.ylabels[1]&lt;br /&gt;
		    spacing   = self.spacingy&lt;br /&gt;
		    min       = self.ymin	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		# Get axis increment in 'label' space&lt;br /&gt;
		inc = abs(label1 - label0)&lt;br /&gt;
&lt;br /&gt;
		# 'Label' difference from value and smallest label (label0)&lt;br /&gt;
		diff = float(value - label0)&lt;br /&gt;
		&lt;br /&gt;
		# Get whole number in 'label' space&lt;br /&gt;
		whole = int(diff / inc)&lt;br /&gt;
&lt;br /&gt;
		# Get fraction number in 'label' space&lt;br /&gt;
		part = float(float(diff/inc) - whole)&lt;br /&gt;
&lt;br /&gt;
		# Return 'pixel' position value&lt;br /&gt;
		pixel = whole * spacing + part * spacing&lt;br /&gt;
&lt;br /&gt;
#		print &amp;quot;Pixel: %f * %f + %f * %f = %f&amp;quot; % (whole, spacing, part, spacing,pixel)&lt;br /&gt;
&lt;br /&gt;
		# Reverse number by subtracting total number of pixels - value pixels&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
		   tot_label_diff = float(self.ylabels[len(self.ylabels)- 1] - label0)&lt;br /&gt;
		   tot_label_whole = int(tot_label_diff / inc)&lt;br /&gt;
		   tot_label_part = float(float(tot_label_diff / inc) - tot_label_whole)&lt;br /&gt;
		   tot_label_pix  = tot_label_whole * spacing + tot_label_part *spacing&lt;br /&gt;
&lt;br /&gt;
		   pixel = tot_label_pix - pixel&lt;br /&gt;
&lt;br /&gt;
		# Add min edge pixels&lt;br /&gt;
		pixel = pixel + min&lt;br /&gt;
		&lt;br /&gt;
		return pixel&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	# Print out which data point you just clicked on..&lt;br /&gt;
	def pickWhich(self,event):&lt;br /&gt;
			&lt;br /&gt;
	    # Find closest data point		    &lt;br /&gt;
	    x = event.widget.canvasx(event.x)&lt;br /&gt;
            y = event.widget.canvasx(event.y)&lt;br /&gt;
	    spot = event.widget.find_closest(x,y)&lt;br /&gt;
&lt;br /&gt;
	    # Print the shape's meta information corresponding with the shape that was picked&lt;br /&gt;
	    if spot[0] in self.shapes:&lt;br /&gt;
		print &amp;quot;Residue(Ca): %s\n&amp;quot; % self.shapes[spot[0]][5][2]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        # Mouse Down Event&lt;br /&gt;
	def down(self,event):&lt;br /&gt;
&lt;br /&gt;
	    # Store x,y position&lt;br /&gt;
	    self.lastx = event.x&lt;br /&gt;
	    self.lasty = event.y&lt;br /&gt;
&lt;br /&gt;
	    # Find the currently selected item&lt;br /&gt;
	    x = event.widget.canvasx(event.x)&lt;br /&gt;
            y = event.widget.canvasx(event.y)&lt;br /&gt;
	    self.item = event.widget.find_closest(x,y)&lt;br /&gt;
	&lt;br /&gt;
	    # Identify that the mouse is down&lt;br /&gt;
	    self.down  = 1&lt;br /&gt;
&lt;br /&gt;
	# Mouse Up Event&lt;br /&gt;
	def up(self,event):&lt;br /&gt;
&lt;br /&gt;
	    # Get label space version of x,y&lt;br /&gt;
	    labelx = self.convertToLabel(&amp;quot;X&amp;quot;,event.x)&lt;br /&gt;
	    labely = self.convertToLabel(&amp;quot;Y&amp;quot;,event.y)&lt;br /&gt;
&lt;br /&gt;
	    # Convert new position into label space..&lt;br /&gt;
	    if self.item[0] in self.shapes:&lt;br /&gt;
	        self.shapes[self.item[0]][0] = event.x&lt;br /&gt;
	        self.shapes[self.item[0]][1] = event.y&lt;br /&gt;
	        self.shapes[self.item[0]][2] =  1&lt;br /&gt;
	        self.shapes[self.item[0]][3] = labelx&lt;br /&gt;
	        self.shapes[self.item[0]][4] = labely&lt;br /&gt;
&lt;br /&gt;
	    # Reset Flags&lt;br /&gt;
	    self.item = (0,)&lt;br /&gt;
            self.down = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	# Mouse Drag(Move) Event&lt;br /&gt;
	def drag(self,event):&lt;br /&gt;
		&lt;br /&gt;
	 	# Check that mouse is down and item clicked is a valid data point&lt;br /&gt;
		if self.down and self.item[0] in self.shapes:&lt;br /&gt;
			&lt;br /&gt;
		    self.move(self.item, event.x - self.lastx, event.y - self.lasty)&lt;br /&gt;
&lt;br /&gt;
		    self.lastx = event.x&lt;br /&gt;
		    self.lasty = event.y&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def __init__(self):&lt;br /&gt;
&lt;br /&gt;
        self.menuBar.addcascademenu('Plugin', 'PlotTools', 'Plot Tools',&lt;br /&gt;
                                    label='Plot Tools')&lt;br /&gt;
        self.menuBar.addmenuitem('PlotTools', 'command',&lt;br /&gt;
                                 'Launch Rama Plot',&lt;br /&gt;
                                 label='Rama Plot',&lt;br /&gt;
                                 command = lambda s=self: ramaplot())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def ramaplot(x=0,y=0,meta=[],clear=0):&lt;br /&gt;
    global canvas&lt;br /&gt;
    global init&lt;br /&gt;
&lt;br /&gt;
    # If no window is open&lt;br /&gt;
    if init == 0:&lt;br /&gt;
        rootframe=Tk()&lt;br /&gt;
        rootframe.title(' Dynamic Angle Plotting ')&lt;br /&gt;
&lt;br /&gt;
        canvas = SimplePlot(rootframe,width=320,height=320)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;Button-2&amp;gt;&amp;quot;,canvas.pickWhich)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;Button-3&amp;gt;&amp;quot;,canvas.pickWhich)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;ButtonPress-1&amp;gt;&amp;quot;,canvas.down)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;ButtonRelease-1&amp;gt;&amp;quot;,canvas.up)&lt;br /&gt;
        canvas.bind(&amp;quot;&amp;lt;Motion&amp;gt;&amp;quot;,canvas.drag)&lt;br /&gt;
        canvas.pack(side=Tkinter.LEFT,fill=&amp;quot;both&amp;quot;,expand=1)&lt;br /&gt;
        canvas.axis(xint=150,xlabels=[-180,-150,-120,-90,-60,-30,0,30,60,90,120,150,180],ylabels=[-180,-150,-120,-90,-60,-30,0,30,60,90,120,150,180])&lt;br /&gt;
        canvas.update()&lt;br /&gt;
	init = 1&lt;br /&gt;
    else:&lt;br /&gt;
      canvas.plot(int(x), int(y),meta)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# New Callback object, so that we can update the structure when phi,psi points are moved.&lt;br /&gt;
class DynoRamaObject:&lt;br /&gt;
	global canvas&lt;br /&gt;
&lt;br /&gt;
	def start(self,sel):&lt;br /&gt;
&lt;br /&gt;
	    # Get selection model&lt;br /&gt;
  	    model = cmd.get_model(sel)&lt;br /&gt;
	    residues = ['dummy']&lt;br /&gt;
	    resnames = ['dummy']&lt;br /&gt;
	    phi = []&lt;br /&gt;
 	    psi = []&lt;br /&gt;
	    dummy = []&lt;br /&gt;
	    i = 0&lt;br /&gt;
&lt;br /&gt;
            # Loop through each atom&lt;br /&gt;
	    for at in model.atom:&lt;br /&gt;
&lt;br /&gt;
		# Only plot once per residue&lt;br /&gt;
    		if at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi not in residues:&lt;br /&gt;
	     	    residues.append(at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi)&lt;br /&gt;
	    	    resnames.append(at.resn+at.resi)&lt;br /&gt;
	    	    dummy.append(i)&lt;br /&gt;
	    	    i += 1&lt;br /&gt;
&lt;br /&gt;
    	    	    # Check for a null chain id (some PDBs contain this) &lt;br /&gt;
	    	    unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
	    	    if at.chain != &amp;quot;&amp;quot;:&lt;br /&gt;
	    		unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
&lt;br /&gt;
    		    # Define selections for residue i-1, i and i+1    &lt;br /&gt;
		    residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
  		    residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)&lt;br /&gt;
		    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)&lt;br /&gt;
&lt;br /&gt;
		    try:&lt;br /&gt;
			# Store phi,psi residue definitions to pass on to plot routine&lt;br /&gt;
			phi_psi = [&lt;br /&gt;
				# Phi angles&lt;br /&gt;
 				   residue_def_prev+' and name C',&lt;br /&gt;
				   residue_def+' and name N',&lt;br /&gt;
				   residue_def+' and name CA',&lt;br /&gt;
				   residue_def+' and name C',&lt;br /&gt;
				# Psi angles&lt;br /&gt;
				   residue_def+' and name N',&lt;br /&gt;
				   residue_def+' and name CA',&lt;br /&gt;
				   residue_def+' and name C',&lt;br /&gt;
			  	   residue_def_next+' and name N']&lt;br /&gt;
&lt;br /&gt;
  		        # Compute phi/psi angle&lt;br /&gt;
		        phi = cmd.get_dihedral(phi_psi[0],phi_psi[1],phi_psi[2],phi_psi[3])&lt;br /&gt;
		        psi = cmd.get_dihedral(phi_psi[4],phi_psi[5],phi_psi[6],phi_psi[7])&lt;br /&gt;
			&lt;br /&gt;
			print &amp;quot;Plotting Phi,Psi: &amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)    &lt;br /&gt;
		        ramaplot(phi,psi,meta=phi_psi)&lt;br /&gt;
		    except:&lt;br /&gt;
			continue&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	def __call__(self):&lt;br /&gt;
&lt;br /&gt;
	    # Loop through each item on plot to see if updated&lt;br /&gt;
	    for key,value in canvas.shapes.items():&lt;br /&gt;
		dihedrals = value[5]&lt;br /&gt;
&lt;br /&gt;
		# Look for update flag...&lt;br /&gt;
		if value[2]:&lt;br /&gt;
&lt;br /&gt;
		    # Set residue's phi,psi to new values&lt;br /&gt;
		    print &amp;quot;Re-setting Phi,Psi: %s,%s&amp;quot; % (value[3],value[4])    &lt;br /&gt;
		    cmd.set_dihedral(dihedrals[0],dihedrals[1],dihedrals[2],dihedrals[3],value[3])		    	&lt;br /&gt;
		    cmd.set_dihedral(dihedrals[4],dihedrals[5],dihedrals[6],dihedrals[7],value[4])		    	&lt;br /&gt;
&lt;br /&gt;
		    value[2] = 0&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
	&lt;br /&gt;
# The wrapper function, used to create the Ploting window and the PyMol callback object	    		&lt;br /&gt;
def rama(sel):&lt;br /&gt;
	rama = DynoRamaObject()&lt;br /&gt;
	rama.start(sel)&lt;br /&gt;
	cmd.load_callback(rama, &amp;quot;DynoRamaObject&amp;quot;)&lt;br /&gt;
	cmd.zoom(&amp;quot;all&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Extend these commands&lt;br /&gt;
cmd.extend('rama',rama)		    			&lt;br /&gt;
cmd.extend('ramaplot',ramaplot)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ADDITIONAL RESOURCES===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|DynoPlot]]&lt;br /&gt;
[[Category:Structural_Biology_Scripts|DynoPlot]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Rotamer_Toggle&amp;diff=9569</id>
		<title>Rotamer Toggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Rotamer_Toggle&amp;diff=9569"/>
		<updated>2010-02-14T18:56:09Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: Undo revision 8036 by Cowsandmilk (Talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
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.&lt;br /&gt;
*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&lt;br /&gt;
*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).&lt;br /&gt;
*set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles&lt;br /&gt;
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)&lt;br /&gt;
*createRotamerPDBs - create pdb for each rotamer of given selection ; filter by rotamer-probability&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:RotamerMenu.png|Rotamer Menu for a GLN residue&lt;br /&gt;
Image:GLURotamerComparison5.png|Rotamer Comparison of crystal structure and most common for GLU; just as an example&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Print out while selecting most common rotamer from above-left image (GLN residue):&lt;br /&gt;
  Given GLN:40 PHI,PSI (-171.626373291,-96.0500335693) : bin (-170,-100)&lt;br /&gt;
  CHIs: [179.18069458007812, 72.539344787597656, -47.217315673828125]&lt;br /&gt;
  Setting Chi1 to -176.9&lt;br /&gt;
  Setting Chi2 to 177.4&lt;br /&gt;
  Setting Chi3 to 0.7&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
run &amp;quot;rotamers.py&amp;quot; and use functions from commandline.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
To setup a rotamer menu inside the residue menu (default windows pymol installation):&lt;br /&gt;
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py&lt;br /&gt;
*copy mymenu.py   to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)&lt;br /&gt;
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)&lt;br /&gt;
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 &amp;quot;sorted&amp;quot; lib)&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Pymolv0.97, Windows platform, Red Hat Linux 9.0 and Fedora Core 4. Will test v0.98 and MacOSX later on.&lt;br /&gt;
*The way it's setup now, when you import rotamers , it will automatically read-in the rotamer database; this may not be what you want.&lt;br /&gt;
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
TASKS TODO:&lt;br /&gt;
*Rotamer Movie, using mset, etc create movie to watch cycle through rotamers&lt;br /&gt;
*Code could be organized a bit better; due to time constraints this is good for now..&lt;br /&gt;
&lt;br /&gt;
TASKS DONE:&lt;br /&gt;
*Store crystal structure in rotamer menu, so you can go back to original orientation&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
 colorRotamers selection&lt;br /&gt;
 set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]&lt;br /&gt;
 set_phipsi selection phi_angle, psi_angle&lt;br /&gt;
 createRotamerPBDs selection [,ncutoff] [,pcutoff] [,prefix]&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
   colorRotamers chain A&lt;br /&gt;
   set_rotamer resi 40, -60,-40   (only set chi1,chi2 angles)&lt;br /&gt;
   set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)&lt;br /&gt;
   createRotamerPDBs resi 10-12, ncutoff=3 (create 9 PDBs; each with one of the 3 most probable rotamers for resi 10,11,12)&lt;br /&gt;
   createRotamerPDBs resi 14, pcutoff=0.4  (create a pdb file for each rotamer of residue 14 with probablity &amp;gt; 0.4)&lt;br /&gt;
&lt;br /&gt;
===REFERENCES===&lt;br /&gt;
Dunbrack and Cohen. Protein Science 1997&lt;br /&gt;
&lt;br /&gt;
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (Rotamers.py ; MyMenu.py)===&lt;br /&gt;
Rotamers.py &lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
##################################################################&lt;br /&gt;
# File:          Rotamers.py&lt;br /&gt;
# Author:        Dan Kulp&lt;br /&gt;
# Creation Date: 6/8/05&lt;br /&gt;
# Contact:       dwkulp@mail.med.upenn.edu&lt;br /&gt;
#&lt;br /&gt;
# Notes:&lt;br /&gt;
#     Incorporation of Rotamer library&lt;br /&gt;
#     readRotLib() - fills rotdat; &lt;br /&gt;
#        indexed by &amp;quot;RES:PHI_BIN:PSI_BIN&amp;quot;.&lt;br /&gt;
#&lt;br /&gt;
#     Three main functions:&lt;br /&gt;
#     1. colorRotamers - colors according&lt;br /&gt;
#          to rotamer probablitity&lt;br /&gt;
#     2. getBins(sel)&lt;br /&gt;
#           phi,psi bin for rotamer&lt;br /&gt;
#     3. set_rotamer - set a side-chain &lt;br /&gt;
#           to a specific rotamer	&lt;br /&gt;
#&lt;br /&gt;
#     To setup a rotamer menu in the &lt;br /&gt;
#   right click, under &amp;quot;Residue&amp;quot;&lt;br /&gt;
#        1. cp mymenu.py modules/pymol/menu.py&lt;br /&gt;
#        2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)&lt;br /&gt;
#&lt;br /&gt;
# Requirements:&lt;br /&gt;
#  set ROTLIB to path for rotamer library&lt;br /&gt;
# Reference: &lt;br /&gt;
#  Dunbrack and Cohen. Protein Science 1997&lt;br /&gt;
####################################################################&lt;br /&gt;
&lt;br /&gt;
import colorsys,sys&lt;br /&gt;
import re&lt;br /&gt;
import editing&lt;br /&gt;
import os&lt;br /&gt;
import cmd&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Path for library&lt;br /&gt;
ROTLIB=os.environ['PYMOL_PATH']+&amp;quot;/modules/pymol/bbdep02.May.sortlib&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Place for library in memory..&lt;br /&gt;
rotdat = {}&lt;br /&gt;
&lt;br /&gt;
def readRotLib():	&lt;br /&gt;
    # Column indexes in rotamer library..&lt;br /&gt;
    RES  = 0&lt;br /&gt;
    PHI  = 1&lt;br /&gt;
    PSI  = 2&lt;br /&gt;
    PROB = 8&lt;br /&gt;
    CHI1 = 9&lt;br /&gt;
    CHI2 = 10&lt;br /&gt;
    CHI3 = 11&lt;br /&gt;
    CHI4 = 12&lt;br /&gt;
&lt;br /&gt;
    if os.path.exists(ROTLIB):&lt;br /&gt;
		print &amp;quot;File exists: &amp;quot;+ROTLIB&lt;br /&gt;
		input = open(ROTLIB, 'r')&lt;br /&gt;
		for line in input:&lt;br /&gt;
&lt;br /&gt;
	  	    # Parse by whitespace (I believe format is white space and not fixed-width columns)&lt;br /&gt;
		    dat = re.split(&amp;quot;\s+&amp;quot;,line)&lt;br /&gt;
&lt;br /&gt;
		    # Add to rotamer library in memory : &lt;br /&gt;
		    #   key format       RES:PHI_BIN:PSI_BIN&lt;br /&gt;
		    #   value format     PROB, CHI1, CHI2, CHI3, CHI4&lt;br /&gt;
		    key = dat[RES]+&amp;quot;:&amp;quot;+dat[PHI]+&amp;quot;:&amp;quot;+dat[PSI]&lt;br /&gt;
		    if key in rotdat:&lt;br /&gt;
		        rotdat[key].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])&lt;br /&gt;
		    else:&lt;br /&gt;
			rotdat[key] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]&lt;br /&gt;
&lt;br /&gt;
		    &lt;br /&gt;
    else:&lt;br /&gt;
	print &amp;quot;Couldn't find Rotamer library&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Atoms for each side-chain angle for each residue&lt;br /&gt;
CHIS = {}&lt;br /&gt;
CHIS[&amp;quot;ARG&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;NE&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;NE&amp;quot;,&amp;quot;CZ&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;ASN&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;OD2&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;ASP&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;OD1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
CHIS[&amp;quot;CYS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;SG&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
CHIS[&amp;quot;GLN&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;OE1&amp;quot;]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;GLU&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;OE1&amp;quot;]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;HIS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;ND1&amp;quot;]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;ILE&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;LEU&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;LYS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;CE&amp;quot;],&lt;br /&gt;
		[&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;CE&amp;quot;,&amp;quot;NZ&amp;quot;]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;MET&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;SD&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;SD&amp;quot;,&amp;quot;CE&amp;quot;]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;PHE&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;PRO&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;SER&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;OG&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;THR&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;OG1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;TRP&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot;]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;TYR&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
		[&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
CHIS[&amp;quot;VAL&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot; ]&lt;br /&gt;
	      ]&lt;br /&gt;
&lt;br /&gt;
# Color Rotamer by side-chain angle position&lt;br /&gt;
#  'bin' side-chain angles into closest&lt;br /&gt;
def colorRotamers(sel):&lt;br /&gt;
    doRotamers(sel)&lt;br /&gt;
&lt;br /&gt;
# Utility function, to set phi,psi angles for a given selection&lt;br /&gt;
# Note: Cartoon, Ribbon functionality will not display correctly after this&lt;br /&gt;
def set_phipsi(sel, phi,psi):&lt;br /&gt;
    doRotamers(sel,angles=[phi,psi],type=&amp;quot;set&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Set a rotamer, based on a selection, a restype and chi angles&lt;br /&gt;
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):&lt;br /&gt;
    at = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;).atom[0]&lt;br /&gt;
&lt;br /&gt;
    list = [chi1,chi2,chi3,chi4]&lt;br /&gt;
    for i in range(len(CHIS[at.resn])):&lt;br /&gt;
	print &amp;quot;Setting Chi&amp;quot;+str(i+1)+&amp;quot; to &amp;quot;+str(list[i])&lt;br /&gt;
        editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],		    &lt;br /&gt;
		             sel + ' and name '+CHIS[at.resn][i][1],		    &lt;br /&gt;
		             sel + ' and name '+CHIS[at.resn][i][2],		    &lt;br /&gt;
		             sel + ' and name '+CHIS[at.resn][i][3], str(list[i]))		    &lt;br /&gt;
&lt;br /&gt;
    # Remove some objects that got created&lt;br /&gt;
    cmd.delete(&amp;quot;pk1&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;pk2&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;pkmol&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Get Phi,Psi bins for given selection&lt;br /&gt;
# WARNING:  assume selection is single residue (will only return first residue bins)&lt;br /&gt;
def getBins(sel):&lt;br /&gt;
    return doRotamers(sel, type=&amp;quot;bins&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Color Ramp...&lt;br /&gt;
def rot_color(vals): &lt;br /&gt;
	nbins = 10&lt;br /&gt;
	vals.sort(key=lambda x: x[1])&lt;br /&gt;
#	print &amp;quot;End sort: &amp;quot;+str(len(vals))+&amp;quot; : &amp;quot;+str(nbins)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	# Coloring scheme...&lt;br /&gt;
	j = 0&lt;br /&gt;
	rgb = [0.0,0.0,0.0]&lt;br /&gt;
	sel_str = &amp;quot;&amp;quot;&lt;br /&gt;
	for i in range(len(vals)):&lt;br /&gt;
		if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:&lt;br /&gt;
		      hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)&lt;br /&gt;
&lt;br /&gt;
		      #convert to rgb and append to color list&lt;br /&gt;
		      rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])&lt;br /&gt;
		      if j &amp;lt; nbins-1:&lt;br /&gt;
		              j += 1	&lt;br /&gt;
&lt;br /&gt;
		cmd.set_color(&amp;quot;RotProbColor&amp;quot;+str(i), rgb)&lt;br /&gt;
		cmd.color(&amp;quot;RotProbColor&amp;quot;+str(i), str(vals[i][0]))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Main function                           &lt;br /&gt;
def doRotamers(sel,angles=[], type=&amp;quot;color&amp;quot;):                           &lt;br /&gt;
&lt;br /&gt;
	# Read in Rotamer library if not already done&lt;br /&gt;
	if len(rotdat) == 0:&lt;br /&gt;
		readRotLib()&lt;br /&gt;
&lt;br /&gt;
	# Set up some variables..&lt;br /&gt;
	residues = ['dummy']  # Keep track of residues already done&lt;br /&gt;
	probs = []            # probability of each residue conformation&lt;br /&gt;
	phi = 0               # phi,psi angles of current residue&lt;br /&gt;
	psi = 0&lt;br /&gt;
&lt;br /&gt;
	# Get atoms from selection&lt;br /&gt;
	atoms = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        # Loop through atoms in selection		&lt;br /&gt;
	for at in atoms.atom:&lt;br /&gt;
	    try:&lt;br /&gt;
	       # Don't process Glycines or Alanines&lt;br /&gt;
	       if not (at.resn == 'GLY' or at.resn == 'ALA'):&lt;br /&gt;
	        if at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi not in residues:&lt;br /&gt;
	            residues.append(at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi)&lt;br /&gt;
&lt;br /&gt;
		    # Check for a null chain id (some PDBs contain this) &lt;br /&gt;
		    unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
		    if at.chain != &amp;quot;&amp;quot;:&lt;br /&gt;
			unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
&lt;br /&gt;
		    # Define selections for residue i-1, i and i+1    &lt;br /&gt;
		    residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
  		    residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)&lt;br /&gt;
		    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)&lt;br /&gt;
&lt;br /&gt;
	            # Compute phi/psi angle&lt;br /&gt;
&lt;br /&gt;
		    phi = cmd.get_dihedral(residue_def_prev+' and name C',residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C')&lt;br /&gt;
		    psi = cmd.get_dihedral(residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',residue_def_next+' and name N')&lt;br /&gt;
		    if type == &amp;quot;set&amp;quot;:&lt;br /&gt;
			    print &amp;quot;Changing &amp;quot;+at.resn+str(at.resi)+&amp;quot; from &amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)+&amp;quot; to &amp;quot;+str(angles[0])+&amp;quot;,&amp;quot;+str(angles[1])&lt;br /&gt;
			    cmd.set_dihedral(residue_def_prev+' and name C',residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',angles[0])&lt;br /&gt;
			    cmd.set_dihedral(residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',residue_def_next+' and name N', angles[1])&lt;br /&gt;
			    continue&lt;br /&gt;
						&lt;br /&gt;
		    # Find correct 10x10 degree bin		        		&lt;br /&gt;
		    phi_digit = abs(int(phi)) - abs(int(phi/10)*10)&lt;br /&gt;
		    psi_digit = abs(int(psi)) - abs(int(psi/10)*10)&lt;br /&gt;
		    &lt;br /&gt;
		    # Remember sign of phi,psi angles&lt;br /&gt;
	    	    phi_sign = 1&lt;br /&gt;
		    if phi &amp;lt; 0:    phi_sign = -1&lt;br /&gt;
&lt;br /&gt;
		    psi_sign = 1&lt;br /&gt;
		    if psi &amp;lt; 0:    psi_sign = -1&lt;br /&gt;
&lt;br /&gt;
		    # Compute phi,psi bins&lt;br /&gt;
  		    phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)&lt;br /&gt;
		    if phi_digit &amp;gt;= 5:    phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)&lt;br /&gt;
&lt;br /&gt;
		    psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)&lt;br /&gt;
		    if psi_digit &amp;gt;= 5:    psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)&lt;br /&gt;
&lt;br /&gt;
	            print &amp;quot;Given &amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi+&amp;quot; PHI,PSI (&amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)+&amp;quot;) : bin (&amp;quot;+str(phi_bin)+&amp;quot;,&amp;quot;+str(psi_bin)+&amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		    # Get current chi angle measurements&lt;br /&gt;
		    chi = []&lt;br /&gt;
		    for i in range(len(CHIS[at.resn])):&lt;br /&gt;
		       chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],		    &lt;br /&gt;
		  			             residue_def + ' and name '+CHIS[at.resn][i][1],		    &lt;br /&gt;
					             residue_def + ' and name '+CHIS[at.resn][i][2],		    &lt;br /&gt;
					             residue_def + ' and name '+CHIS[at.resn][i][3]))		    &lt;br /&gt;
		    print &amp;quot;CHIs: &amp;quot;+str(chi)&lt;br /&gt;
		    if type == 'bins':&lt;br /&gt;
		         return [at.resn, phi_bin,psi_bin]&lt;br /&gt;
&lt;br /&gt;
		    # Compute probabilities for given chi angles&lt;br /&gt;
                    prob = 0&lt;br /&gt;
		    prob_box = 22 		    &lt;br /&gt;
		    for item in range(len(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)])):&lt;br /&gt;
			print &amp;quot;Rotamer from db: &amp;quot;+str(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item])&lt;br /&gt;
			if chi[0]:&lt;br /&gt;
			    if chi[0] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][1]) - (prob_box/2) and \&lt;br /&gt;
				chi[0] &amp;lt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][1]) + (prob_box/2):&lt;br /&gt;
				if len(chi) == 1:&lt;br /&gt;
					prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
					break&lt;br /&gt;
				if chi[1] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][2]) - (prob_box/2) and \&lt;br /&gt;
				 float(chi[1] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][2]) + (prob_box/2):&lt;br /&gt;
					if len(chi) == 2:&lt;br /&gt;
					    prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
					    break&lt;br /&gt;
					if chi[2] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][3]) - (prob_box/2) and \&lt;br /&gt;
					   float(chi[2] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][3]) + (prob_box/2):&lt;br /&gt;
    					    if len(chi) == 3:&lt;br /&gt;
					        prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
					        break&lt;br /&gt;
					    if chi[3] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][4]) - (prob_box/2) and \&lt;br /&gt;
					       float(chi[3] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][4]) + (prob_box/2):&lt;br /&gt;
					        prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
					        break&lt;br /&gt;
&lt;br /&gt;
			&lt;br /&gt;
		    print &amp;quot;PROB OF ROTAMER: &amp;quot;+str(prob)&lt;br /&gt;
		    print &amp;quot;---------------------------&amp;quot;&lt;br /&gt;
		    probs.append([residue_def, prob])&lt;br /&gt;
&lt;br /&gt;
	    except:&lt;br /&gt;
#		probs.append([residue_def, -1])&lt;br /&gt;
		print &amp;quot;Exception found&amp;quot;&lt;br /&gt;
		continue&lt;br /&gt;
&lt;br /&gt;
	# Color according to rotamer probability&lt;br /&gt;
	rot_color(probs)	    &lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#  Create PDB files containing most probable rotamers&lt;br /&gt;
def createRotamerPDBs(sel,ncutoff=10,pcutoff=0,prefix=&amp;quot;ROTAMER&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
	# Get atoms from selection&lt;br /&gt;
	atoms = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	# Set up some variables..&lt;br /&gt;
	residues = ['dummy']  # Keep track of residues already done&lt;br /&gt;
&lt;br /&gt;
	# Loop through atoms in selection		&lt;br /&gt;
	for at in atoms.atom:&lt;br /&gt;
		if at.resn in ('GLY', 'ALA') or &amp;quot;%s:%s:%s&amp;quot; % (at.chain,at.resn,at.resi) in residues:&lt;br /&gt;
			continue&lt;br /&gt;
&lt;br /&gt;
		# Add to residue list (keep track of which ones we've done)&lt;br /&gt;
		residues.append(&amp;quot;%s:%s:%s&amp;quot; % (at.chain,at.resn,at.resi))&lt;br /&gt;
&lt;br /&gt;
	        # Check for a null chain id (some PDBs contain this) &lt;br /&gt;
	        unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
	        if at.chain != &amp;quot;&amp;quot;:&lt;br /&gt;
		    unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
&lt;br /&gt;
	        # Define selections for residue &lt;br /&gt;
		residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
&lt;br /&gt;
		# Get bin (phi,psi) definitions for this residue&lt;br /&gt;
		bin = doRotamers(residue_def, type='bins')&lt;br /&gt;
&lt;br /&gt;
		# Store crystal angle&lt;br /&gt;
		crystal_angles = [0.0,0.0,0.0,0.0]&lt;br /&gt;
		for angle in range(3):&lt;br /&gt;
			try:&lt;br /&gt;
				crystal_angles[angle] = bin[3][angle]&lt;br /&gt;
			except IndexError:&lt;br /&gt;
				break&lt;br /&gt;
&lt;br /&gt;
		# Retreive list of rotamers for this phi,psi bin + residue type&lt;br /&gt;
		match_rotamers = rotdat[&amp;quot;%s:%s:%s&amp;quot; % (bin[0],str(bin[1]),str(bin[2]))]&lt;br /&gt;
		&lt;br /&gt;
		count = 0&lt;br /&gt;
		for item in range(len(match_rotamers)):&lt;br /&gt;
&lt;br /&gt;
			# Store probablity&lt;br /&gt;
			prob = match_rotamers[item][0]&lt;br /&gt;
&lt;br /&gt;
			# Check cutoffs&lt;br /&gt;
			if float(prob) &amp;lt;= float(pcutoff):&lt;br /&gt;
				continue&lt;br /&gt;
&lt;br /&gt;
			if float(count) &amp;gt;= float(ncutoff):&lt;br /&gt;
				break&lt;br /&gt;
&lt;br /&gt;
			# Increment count&lt;br /&gt;
			count += 1&lt;br /&gt;
&lt;br /&gt;
			# Output to screen ...&lt;br /&gt;
			print &amp;quot;Residue %s%s, rotamer %i, prob %s&amp;quot; % (at.resn,at.resi,item,prob)&lt;br /&gt;
&lt;br /&gt;
			# Set to new rotamer&lt;br /&gt;
			set_rotamer(residue_def,match_rotamers[item][1],match_rotamers[item][2],match_rotamers[item][3],match_rotamers[item][4])												&lt;br /&gt;
				&lt;br /&gt;
			# Store in PDB file&lt;br /&gt;
			cmd.save(&amp;quot;%s_%s%s_%i_%s.pdb&amp;quot; % (prefix,str(at.resn),str(at.resi),int(item),str(prob)))&lt;br /&gt;
			&lt;br /&gt;
			# Reset crystal angle&lt;br /&gt;
			set_rotamer(residue_def,crystal_angles[0],crystal_angles[1],crystal_angles[2],crystal_angles[3])&lt;br /&gt;
&lt;br /&gt;
# Uncommenting this is nice because it loads rotamer library upon startup&lt;br /&gt;
#  however, it slows the PyMOL loading process a lot&lt;br /&gt;
#  instead I've put this call into the menuing code..&lt;br /&gt;
# readRotLib()&lt;br /&gt;
&lt;br /&gt;
cmd.extend('set_phipsi',set_phipsi)&lt;br /&gt;
cmd.extend('set_rotamer',set_rotamer)&lt;br /&gt;
cmd.extend('colorRotamers',colorRotamers)&lt;br /&gt;
cmd.extend('createRotamerPDBs',createRotamerPDBs)&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MyMenu.py&lt;br /&gt;
 Since menu.py is copyrighted I can't post my edited version, but you can create it very simply by adding these two peices of code&lt;br /&gt;
&lt;br /&gt;
1. In the &amp;quot;pick_option(title,s,object=0)&amp;quot; function of menu.py add the following code after the first &amp;quot;result =&amp;quot; statement&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Edit dwkulp 6/11/05 , add a rotamer menu to residue menu&lt;br /&gt;
   if title == 'Residue':&lt;br /&gt;
	result.extend([[ 1, 'rotamers'    , rotamer_menu(s)]])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. At the end of the file add this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
###############################################&lt;br /&gt;
# Dan Kulp&lt;br /&gt;
# Added Rotamer list to residue menu..&lt;br /&gt;
# rotamer.py must be importable (I placed it in &lt;br /&gt;
# the same directory as menu.py)&lt;br /&gt;
###############################################&lt;br /&gt;
&lt;br /&gt;
import rotamers&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def rotamer_menu(s):&lt;br /&gt;
	# Check for rotamer library being loaded&lt;br /&gt;
	if not rotamers.rotdat:&lt;br /&gt;
             rotamers.readRotLib()&lt;br /&gt;
#	     return [ [2, &amp;quot;Must run rotamers.py first&amp;quot;,'']]&lt;br /&gt;
&lt;br /&gt;
	# Check for valid rotamer residue..&lt;br /&gt;
	res = cmd.get_model(&amp;quot;byres (&amp;quot;+s+&amp;quot;)&amp;quot;).atom[0].resn&lt;br /&gt;
        if not res in rotamers.CHIS.keys():&lt;br /&gt;
	    return [ [2, &amp;quot;Residue: &amp;quot;+res+&amp;quot; not known sidechain or does not have rotamers&amp;quot;, '']]&lt;br /&gt;
&lt;br /&gt;
	# Get PHI,PSI bins for rotamer (also prints out current phi,psi, chi1,chi2,chi3,chi4)&lt;br /&gt;
	bins = rotamers.doRotamers(s,type='bins')&lt;br /&gt;
&lt;br /&gt;
	# Add a title to the menu&lt;br /&gt;
	result = [ [2, bins[0]+' Rotamers in bin ('+str(bins[1])+','+str(bins[2])+')','' ], [1, ':::PROB,CHI1,CHI2,CHI3,CHI4:::','']]&lt;br /&gt;
&lt;br /&gt;
        # Grab the entries for this residue and phi,psi bins&lt;br /&gt;
	match_rotamers = rotamers.rotdat[bins[0]+&amp;quot;:&amp;quot;+str(bins[1])+&amp;quot;:&amp;quot;+str(bins[2])]&lt;br /&gt;
&lt;br /&gt;
	# Set max number of rotamers to display (probably should be somewhere 'higher up' in the code)&lt;br /&gt;
	max_rotamers = min(10, len(match_rotamers))&lt;br /&gt;
&lt;br /&gt;
	# Create menu entry for each possible rotamer&lt;br /&gt;
        for item in range(max_rotamers):&lt;br /&gt;
             result.append( [ 1, str(match_rotamers[item]), 'rotamers.set_rotamer(&amp;quot;'+s+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][1])+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][2])+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][3])+'&amp;quot;,&amp;quot;'\&lt;br /&gt;
										    +str(match_rotamers[item][4])+'&amp;quot;)'])&lt;br /&gt;
	return result&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|Rotamer Toggle]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Structural_Biology_Scripts|Rotamer Toggle]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Rotamer_Toggle&amp;diff=9568</id>
		<title>Rotamer Toggle</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Rotamer_Toggle&amp;diff=9568"/>
		<updated>2010-02-02T13:03:30Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
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.&lt;br /&gt;
*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&lt;br /&gt;
*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).&lt;br /&gt;
*set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles&lt;br /&gt;
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)&lt;br /&gt;
*createRotamerPDBs - create pdb for each rotamer of given selection ; filter by rotamer-probability&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:RotamerMenu.png|Rotamer Menu for a GLN residue&lt;br /&gt;
Image:GLURotamerComparison5.png|Rotamer Comparison of crystal structure and most common for GLU; just as an example&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Print out while selecting most common rotamer from above-left image (GLN residue):&lt;br /&gt;
  Given GLN:40 PHI,PSI (-171.626373291,-96.0500335693) : bin (-170,-100)&lt;br /&gt;
  CHIs: [179.18069458007812, 72.539344787597656, -47.217315673828125]&lt;br /&gt;
  Setting Chi1 to -176.9&lt;br /&gt;
  Setting Chi2 to 177.4&lt;br /&gt;
  Setting Chi3 to 0.7&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
run &amp;quot;rotamers.py&amp;quot; and use functions from commandline.&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
To setup a rotamer menu inside the residue menu (default windows pymol installation):&lt;br /&gt;
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py&lt;br /&gt;
*copy mymenu.py   to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)&lt;br /&gt;
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)&lt;br /&gt;
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 &amp;quot;sorted&amp;quot; lib)&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Pymolv0.97, Windows platform, Red Hat Linux 9.0 and Fedora Core 4. Will test v0.98 and MacOSX later on.&lt;br /&gt;
*The way it's setup now, when you import rotamers , it will automatically read-in the rotamer database; this may not be what you want.&lt;br /&gt;
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
TASKS TODO:&lt;br /&gt;
*Rotamer Movie, using mset, etc create movie to watch cycle through rotamers&lt;br /&gt;
*Code could be organized a bit better; due to time constraints this is good for now..&lt;br /&gt;
&lt;br /&gt;
TASKS DONE:&lt;br /&gt;
*Store crystal structure in rotamer menu, so you can go back to original orientation&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
 colorRotamers selection&lt;br /&gt;
 set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]&lt;br /&gt;
 set_phipsi selection phi_angle, psi_angle&lt;br /&gt;
 createRotamerPBDs selection [,ncutoff] [,pcutoff] [,prefix]&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
   colorRotamers chain A&lt;br /&gt;
   set_rotamer resi 40, -60,-40   (only set chi1,chi2 angles)&lt;br /&gt;
   set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)&lt;br /&gt;
   createRotamerPDBs resi 10-12, ncutoff=3 (create 9 PDBs; each with one of the 3 most probable rotamers for resi 10,11,12)&lt;br /&gt;
   createRotamerPDBs resi 14, pcutoff=0.4  (create a pdb file for each rotamer of residue 14 with probablity &amp;gt; 0.4)&lt;br /&gt;
&lt;br /&gt;
===REFERENCES===&lt;br /&gt;
Dunbrack and Cohen. Protein Science 1997&lt;br /&gt;
&lt;br /&gt;
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (Rotamers.py ; MyMenu.py)===&lt;br /&gt;
Rotamers.py &lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
##################################################################&lt;br /&gt;
# File:          Rotamers.py&lt;br /&gt;
# Author:        Dan Kulp&lt;br /&gt;
# Creation Date: 6/8/05&lt;br /&gt;
# Contact:       dwkulp@mail.med.upenn.edu&lt;br /&gt;
#&lt;br /&gt;
# Notes:&lt;br /&gt;
#     Incorporation of Rotamer library&lt;br /&gt;
#     readRotLib() - fills rotdat; &lt;br /&gt;
#        indexed by &amp;quot;RES:PHI_BIN:PSI_BIN&amp;quot;.&lt;br /&gt;
#&lt;br /&gt;
#     Three main functions:&lt;br /&gt;
#     1. colorRotamers - colors according&lt;br /&gt;
#          to rotamer probablitity&lt;br /&gt;
#     2. getBins(sel)&lt;br /&gt;
#           phi,psi bin for rotamer&lt;br /&gt;
#     3. set_rotamer - set a side-chain &lt;br /&gt;
#           to a specific rotamer&lt;br /&gt;
#&lt;br /&gt;
#     To setup a rotamer menu in the &lt;br /&gt;
#   right click, under &amp;quot;Residue&amp;quot;&lt;br /&gt;
#        1. cp mymenu.py modules/pymol/menu.py&lt;br /&gt;
#        2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)&lt;br /&gt;
#&lt;br /&gt;
# Requirements:&lt;br /&gt;
#  set ROTLIB to path for rotamer library&lt;br /&gt;
# Reference: &lt;br /&gt;
#  Dunbrack and Cohen. Protein Science 1997&lt;br /&gt;
####################################################################&lt;br /&gt;
 &lt;br /&gt;
import colorsys,sys&lt;br /&gt;
import string&lt;br /&gt;
import re&lt;br /&gt;
import editing&lt;br /&gt;
import os&lt;br /&gt;
import cmd&lt;br /&gt;
import math&lt;br /&gt;
 &lt;br /&gt;
# Path for library&lt;br /&gt;
ROTLIB=os.environ['PYMOL_PATH']+&amp;quot;/modules/pymol/bbdep02.May.sortlib&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
# Place for library in memory..&lt;br /&gt;
rotdat = {}&lt;br /&gt;
 &lt;br /&gt;
def readRotLib():&lt;br /&gt;
    # Column indexes in rotamer library..&lt;br /&gt;
    RES  = 0&lt;br /&gt;
    PHI  = 1&lt;br /&gt;
    PSI  = 2&lt;br /&gt;
    PROB = 8&lt;br /&gt;
    CHI1 = 9&lt;br /&gt;
    CHI2 = 10&lt;br /&gt;
    CHI3 = 11&lt;br /&gt;
    CHI4 = 12&lt;br /&gt;
 &lt;br /&gt;
    if os.path.exists(ROTLIB):&lt;br /&gt;
                print &amp;quot;File exists: &amp;quot;+ROTLIB&lt;br /&gt;
                input = open(ROTLIB, 'r')&lt;br /&gt;
                for line in input:&lt;br /&gt;
 &lt;br /&gt;
                    # Parse by whitespace (I believe format is white space and not fixed-width columns)&lt;br /&gt;
                    dat = re.split(&amp;quot;\s+&amp;quot;,line)&lt;br /&gt;
 &lt;br /&gt;
                    # Add to rotamer library in memory : &lt;br /&gt;
                    #   key format       RES:PHI_BIN:PSI_BIN&lt;br /&gt;
                    #   value format     PROB, CHI1, CHI2, CHI3, CHI4&lt;br /&gt;
                    try:&lt;br /&gt;
                        rotdat[dat[RES]+&amp;quot;:&amp;quot;+dat[PHI]+&amp;quot;:&amp;quot;+dat[PSI]].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])&lt;br /&gt;
                    except KeyError:&lt;br /&gt;
                        rotdat[dat[RES]+&amp;quot;:&amp;quot;+dat[PHI]+&amp;quot;:&amp;quot;+dat[PSI]] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    else:&lt;br /&gt;
        print &amp;quot;Couldn't find Rotamer library&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Atoms for each side-chain angle for each residue&lt;br /&gt;
CHIS = {}&lt;br /&gt;
CHIS[&amp;quot;ARG&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;NE&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;NE&amp;quot;,&amp;quot;CZ&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;ASN&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;OD2&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;ASP&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;OD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
CHIS[&amp;quot;CYS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;SG&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;GLN&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;OE1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;GLU&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;OE1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;HIS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;ND1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;ILE&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;LEU&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;LYS&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;CE&amp;quot;],&lt;br /&gt;
                [&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot;,&amp;quot;CE&amp;quot;,&amp;quot;NZ&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;MET&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;SD&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;SD&amp;quot;,&amp;quot;CE&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;PHE&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;PRO&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;SER&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;OG&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;THR&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;OG1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;TRP&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot;]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;TYR&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot; ],&lt;br /&gt;
                [&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG&amp;quot;,&amp;quot;CD1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
CHIS[&amp;quot;VAL&amp;quot;] = [ [&amp;quot;N&amp;quot;,&amp;quot;CA&amp;quot;,&amp;quot;CB&amp;quot;,&amp;quot;CG1&amp;quot; ]&lt;br /&gt;
              ]&lt;br /&gt;
 &lt;br /&gt;
# Color Rotamer by side-chain angle position&lt;br /&gt;
#  'bin' side-chain angles into closest&lt;br /&gt;
def colorRotamers(sel):&lt;br /&gt;
    doRotamers(sel)&lt;br /&gt;
 &lt;br /&gt;
# Utility function, to set phi,psi angles for a given selection&lt;br /&gt;
# Note: Cartoon, Ribbon functionality will not display correctly after this&lt;br /&gt;
def set_phipsi(sel, phi,psi):&lt;br /&gt;
    doRotamers(sel,angles=[phi,psi],type=&amp;quot;set&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
# Set a rotamer, based on a selection, a restype and chi angles&lt;br /&gt;
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):&lt;br /&gt;
    at = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;).atom[0]&lt;br /&gt;
 &lt;br /&gt;
    list = [chi1,chi2,chi3,chi4]&lt;br /&gt;
    for i in range(0,len(CHIS[at.resn])):&lt;br /&gt;
        print &amp;quot;Setting Chi&amp;quot;+str(i+1)+&amp;quot; to &amp;quot;+str(list[i])&lt;br /&gt;
        editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],&lt;br /&gt;
                             sel + ' and name '+CHIS[at.resn][i][1],&lt;br /&gt;
                             sel + ' and name '+CHIS[at.resn][i][2],&lt;br /&gt;
                             sel + ' and name '+CHIS[at.resn][i][3], str(list[i]))&lt;br /&gt;
 &lt;br /&gt;
    # Remove some objects that got created&lt;br /&gt;
    cmd.delete(&amp;quot;pk1&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;pk2&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;pkmol&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
# Get Phi,Psi bins for given selection&lt;br /&gt;
# WARNING:  assume selection is single residue (will only return first residue bins)&lt;br /&gt;
def getBins(sel):&lt;br /&gt;
    return doRotamers(sel, type=&amp;quot;bins&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
# Specific comparison operator for rotamer prob data &lt;br /&gt;
def mycmp(first, second):&lt;br /&gt;
        return cmp( first[1], second[1])&lt;br /&gt;
 &lt;br /&gt;
# Color Ramp...&lt;br /&gt;
def rot_color(vals): &lt;br /&gt;
        nbins = 10&lt;br /&gt;
        vals.sort(mycmp)&lt;br /&gt;
#       print &amp;quot;End sort: &amp;quot;+str(len(vals))+&amp;quot; : &amp;quot;+str(nbins)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
        # Coloring scheme...&lt;br /&gt;
        i = 0&lt;br /&gt;
        j = 0&lt;br /&gt;
        rgb = [0.0,0.0,0.0]&lt;br /&gt;
        sel_str = &amp;quot;&amp;quot;&lt;br /&gt;
        while i &amp;lt; len(vals):&lt;br /&gt;
                if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:&lt;br /&gt;
                      hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)&lt;br /&gt;
 &lt;br /&gt;
                      #convert to rgb and append to color list&lt;br /&gt;
                      rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])&lt;br /&gt;
                      if j &amp;lt; nbins-1:&lt;br /&gt;
                              j += 1&lt;br /&gt;
 &lt;br /&gt;
                cmd.set_color(&amp;quot;RotProbColor&amp;quot;+str(i), rgb)&lt;br /&gt;
                cmd.color(&amp;quot;RotProbColor&amp;quot;+str(i), str(vals[i][0]))&lt;br /&gt;
                i += 1&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Main function&lt;br /&gt;
def doRotamers(sel,angles=[], type=&amp;quot;color&amp;quot;):&lt;br /&gt;
 &lt;br /&gt;
        # Read in Rotamer library if not already done&lt;br /&gt;
        if len(rotdat) == 0:&lt;br /&gt;
                readRotLib()&lt;br /&gt;
 &lt;br /&gt;
        # Set up some variables..&lt;br /&gt;
        residues = ['dummy']  # Keep track of residues already done&lt;br /&gt;
        probs = []            # probability of each residue conformation&lt;br /&gt;
        phi = 0               # phi,psi angles of current residue&lt;br /&gt;
        psi = 0&lt;br /&gt;
 &lt;br /&gt;
        # Get atoms from selection&lt;br /&gt;
        atoms = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
        # Loop through atoms in selection&lt;br /&gt;
        for at in atoms.atom:&lt;br /&gt;
            try:&lt;br /&gt;
               # Don't process Glycines or Alanines&lt;br /&gt;
               if not (at.resn == 'GLY' or at.resn == 'ALA'):&lt;br /&gt;
                if not at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi in residues:&lt;br /&gt;
                    residues.append(at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi)&lt;br /&gt;
 &lt;br /&gt;
                    # Check for a null chain id (some PDBs contain this) &lt;br /&gt;
                    unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
                    if not at.chain == &amp;quot;&amp;quot;:&lt;br /&gt;
                        unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
                    # Define selections for residue i-1, i and i+1&lt;br /&gt;
                    residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
                    residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)&lt;br /&gt;
                    residue_def_next = unit_select+'resi '+str(int(at.resi)+1)&lt;br /&gt;
 &lt;br /&gt;
                    # Compute phi/psi angle&lt;br /&gt;
 &lt;br /&gt;
                    phi = cmd.get_dihedral(residue_def_prev+' and name C',residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C')&lt;br /&gt;
                    psi = cmd.get_dihedral(residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',residue_def_next+' and name N')&lt;br /&gt;
                    if type == &amp;quot;set&amp;quot;:&lt;br /&gt;
                            print &amp;quot;Changing &amp;quot;+at.resn+str(at.resi)+&amp;quot; from &amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)+&amp;quot; to &amp;quot;+str(angles[0])+&amp;quot;,&amp;quot;+str(angles[1])&lt;br /&gt;
                            cmd.set_dihedral(residue_def_prev+' and name C',residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',angles[0])&lt;br /&gt;
                            cmd.set_dihedral(residue_def+' and name N',residue_def+' and name CA',residue_def+' and name C',residue_def_next+' and name N', angles[1])&lt;br /&gt;
                            continue&lt;br /&gt;
 &lt;br /&gt;
                    # Find correct 10x10 degree bin                                     &lt;br /&gt;
                    phi_digit = abs(int(phi)) - abs(int(phi/10)*10)&lt;br /&gt;
                    psi_digit = abs(int(psi)) - abs(int(psi/10)*10)&lt;br /&gt;
 &lt;br /&gt;
                    # Remember sign of phi,psi angles&lt;br /&gt;
                    phi_sign = 1&lt;br /&gt;
                    if phi &amp;lt; 0:    phi_sign = -1&lt;br /&gt;
 &lt;br /&gt;
                    psi_sign = 1&lt;br /&gt;
                    if psi &amp;lt; 0:    psi_sign = -1&lt;br /&gt;
 &lt;br /&gt;
                    # Compute phi,psi bins&lt;br /&gt;
                    phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)&lt;br /&gt;
                    if phi_digit &amp;gt;= 5:    phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)&lt;br /&gt;
 &lt;br /&gt;
                    psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)&lt;br /&gt;
                    if psi_digit &amp;gt;= 5:    psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)&lt;br /&gt;
 &lt;br /&gt;
                    print &amp;quot;Given &amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi+&amp;quot; PHI,PSI (&amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)+&amp;quot;) : bin (&amp;quot;+str(phi_bin)+&amp;quot;,&amp;quot;+str(psi_bin)+&amp;quot;)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                    # Get current chi angle measurements&lt;br /&gt;
                    chi = []&lt;br /&gt;
                    for i in range(0,len(CHIS[at.resn])):&lt;br /&gt;
                       chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],&lt;br /&gt;
                                                     residue_def + ' and name '+CHIS[at.resn][i][1],&lt;br /&gt;
                                                     residue_def + ' and name '+CHIS[at.resn][i][2],&lt;br /&gt;
                                                     residue_def + ' and name '+CHIS[at.resn][i][3]))&lt;br /&gt;
                    print &amp;quot;CHIs: &amp;quot;+str(chi)&lt;br /&gt;
                    if type == 'bins':&lt;br /&gt;
                         return [at.resn, phi_bin,psi_bin]&lt;br /&gt;
 &lt;br /&gt;
                    # Compute probabilities for given chi angles&lt;br /&gt;
                    prob = 0&lt;br /&gt;
                    prob_box = 22                   &lt;br /&gt;
                    for item in range(0,len(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)])):&lt;br /&gt;
                        print &amp;quot;Rotamer from db: &amp;quot;+str(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item])&lt;br /&gt;
                        if chi[0]:&lt;br /&gt;
                            if chi[0] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][1]) - (prob_box/2) and \&lt;br /&gt;
                                chi[0] &amp;lt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][1]) + (prob_box/2):&lt;br /&gt;
                                if len(chi) == 1:&lt;br /&gt;
                                        prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                        break&lt;br /&gt;
                                if chi[1] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][2]) - (prob_box/2) and \&lt;br /&gt;
                                 float(chi[1] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][2]) + (prob_box/2):&lt;br /&gt;
                                        if len(chi) == 2:&lt;br /&gt;
                                            prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                            break&lt;br /&gt;
                                        if chi[2] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][3]) - (prob_box/2) and \&lt;br /&gt;
                                           float(chi[2] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][3]) + (prob_box/2):&lt;br /&gt;
                                            if len(chi) == 3:&lt;br /&gt;
                                                prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                                break&lt;br /&gt;
                                            if chi[3] &amp;gt;= float(rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][4]) - (prob_box/2) and \&lt;br /&gt;
                                               float(chi[3] &amp;lt;= rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][4]) + (prob_box/2):&lt;br /&gt;
                                                prob = rotdat[at.resn+&amp;quot;:&amp;quot;+str(phi_bin)+&amp;quot;:&amp;quot;+str(psi_bin)][item][0]&lt;br /&gt;
                                                break&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                    print &amp;quot;PROB OF ROTAMER: &amp;quot;+str(prob)&lt;br /&gt;
                    print &amp;quot;---------------------------&amp;quot;&lt;br /&gt;
                    probs.append([residue_def, prob])&lt;br /&gt;
 &lt;br /&gt;
            except:&lt;br /&gt;
#               probs.append([residue_def, -1])&lt;br /&gt;
                print &amp;quot;Exception found&amp;quot;&lt;br /&gt;
                continue&lt;br /&gt;
 &lt;br /&gt;
        # Color according to rotamer probability&lt;br /&gt;
        rot_color(probs)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
#  Create PDB files containing most probable rotamers&lt;br /&gt;
def createRotamerPDBs(sel,ncutoff=10,pcutoff=0,prefix=&amp;quot;ROTAMER&amp;quot;):&lt;br /&gt;
 &lt;br /&gt;
        # Get atoms from selection&lt;br /&gt;
        atoms = cmd.get_model(&amp;quot;byres (&amp;quot;+sel+&amp;quot;)&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
        # Set up some variables..&lt;br /&gt;
        residues = ['dummy']  # Keep track of residues already done&lt;br /&gt;
 &lt;br /&gt;
        # Loop through atoms in selection&lt;br /&gt;
        for at in atoms.atom:&lt;br /&gt;
                if at.resn == 'GLY' or at.resn == 'ALA' or &amp;quot;%s:%s:%s&amp;quot; % (at.chain,at.resn,at.resi) in residues:&lt;br /&gt;
                        continue&lt;br /&gt;
 &lt;br /&gt;
                # Add to residue list (keep track of which ones we've done)&lt;br /&gt;
                residues.append(&amp;quot;%s:%s:%s&amp;quot; % (at.chain,at.resn,at.resi))&lt;br /&gt;
 &lt;br /&gt;
                # Check for a null chain id (some PDBs contain this)&lt;br /&gt;
                unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
                if not at.chain == &amp;quot;&amp;quot;:&lt;br /&gt;
                    unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
 &lt;br /&gt;
                # Define selections for residue &lt;br /&gt;
                residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
 &lt;br /&gt;
                # Get bin (phi,psi) definitions for this residue&lt;br /&gt;
                bin = doRotamers(residue_def, type='bins')&lt;br /&gt;
 &lt;br /&gt;
                # Store crystal angle&lt;br /&gt;
                crystal_angles = [0.0,0.0,0.0,0.0]&lt;br /&gt;
                for angle in range(0,3):&lt;br /&gt;
                        try:&lt;br /&gt;
                                crystal_angles[angle] = bin[3][angle]&lt;br /&gt;
                        except IndexError:&lt;br /&gt;
                                break&lt;br /&gt;
 &lt;br /&gt;
                # Retreive list of rotamers for this phi,psi bin + residue type&lt;br /&gt;
                match_rotamers = rotdat[&amp;quot;%s:%s:%s&amp;quot; % (bin[0],str(bin[1]),str(bin[2]))]&lt;br /&gt;
 &lt;br /&gt;
                count = 0&lt;br /&gt;
                for item in range(0, len(match_rotamers)):&lt;br /&gt;
 &lt;br /&gt;
                        # Store probablity&lt;br /&gt;
                        prob = match_rotamers[item][0]&lt;br /&gt;
 &lt;br /&gt;
                        # Check cutoffs&lt;br /&gt;
                        if float(prob) &amp;lt;= float(pcutoff):&lt;br /&gt;
                                continue&lt;br /&gt;
 &lt;br /&gt;
                        if float(count) &amp;gt;= float(ncutoff):&lt;br /&gt;
                                break&lt;br /&gt;
 &lt;br /&gt;
                        # Increment count&lt;br /&gt;
                        count += 1&lt;br /&gt;
 &lt;br /&gt;
                        # Output to screen ...&lt;br /&gt;
                        print &amp;quot;Residue %s%s, rotamer %i, prob %s&amp;quot; % (str(at.resn),str(at.resi),int(item),str(prob))&lt;br /&gt;
 &lt;br /&gt;
                        # Set to new rotamer&lt;br /&gt;
                        set_rotamer(residue_def,match_rotamers[item][1],match_rotamers[item][2],match_rotamers[item][3],match_rotamers[item][4])                                                                                                &lt;br /&gt;
 &lt;br /&gt;
                        # Store in PDB file&lt;br /&gt;
                        cmd.save(&amp;quot;%s_%s%s_%i_%s.pdb&amp;quot; % (prefix,str(at.resn),str(at.resi),int(item),str(prob)))&lt;br /&gt;
 &lt;br /&gt;
                        # Reset crystal angle&lt;br /&gt;
                        set_rotamer(residue_def,crystal_angles[0],crystal_angles[1],crystal_angles[2],crystal_angles[3])&lt;br /&gt;
 &lt;br /&gt;
# Uncommenting this is nice because it loads rotamer library upon startup&lt;br /&gt;
#  however, it slows the PyMOL loading process a lot&lt;br /&gt;
#  instead I've put this call into the menuing code..&lt;br /&gt;
# readRotLib()&lt;br /&gt;
 &lt;br /&gt;
cmd.extend('set_phipsi',set_phipsi)&lt;br /&gt;
cmd.extend('set_rotamer',set_rotamer)&lt;br /&gt;
cmd.extend('colorRotamers',colorRotamers)&lt;br /&gt;
cmd.extend('createRotamerPDBs',createRotamerPDBs)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|Rotamer Toggle]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Structural_Biology_Scripts|Rotamer Toggle]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Wfmesh&amp;diff=10832</id>
		<title>Wfmesh</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Wfmesh&amp;diff=10832"/>
		<updated>2010-02-02T12:58:28Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
This script will create an object for any Wavefront(.OBJ) mesh file.  This is a way to extend the number of objects you can use. Also, you have more control over the coloring, transformations, etc than the CGOs. Although there are a number of these obj files on the web, you can also easily created them with open source tools ([http://www.openfx.org OpenFX], [http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]). It takes literally, 2 min to get an object created and then loaded into pymol.  Simply open OpenFX Designer, click File-&amp;gt;Insert-&amp;gt;Model, then choose any of the models (or create your own of course!), then export it as .3ds file.  Then open the .3ds file from Crossroads3D and export as Wavefront OBJ.   &lt;br /&gt;
&lt;br /&gt;
*createWFMesh - create a mesh object from Wavefront (*.obj) formated file&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]&lt;br /&gt;
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:ThirdParty_Scripts]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
Simply &amp;quot;run WFMesh.py&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Pymolv0.97, Windows platform, should work on linux as well.&lt;br /&gt;
*Coloring is fixed for grey and sections of mesh are stored, but not used.&lt;br /&gt;
*Simple opengl calls; not optimized (display lists, etc) or anything.&lt;br /&gt;
*Vertex Normal code is broken, so normals are per polygon right now.&lt;br /&gt;
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
createWFObj file, name  [,translate=[0,0,0]] [,flip=0]&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
   createWFObj &amp;quot;ship.obj&amp;quot; &amp;quot;Ship&amp;quot;&lt;br /&gt;
   createWFObj &amp;quot;torus.obj&amp;quot; &amp;quot;Torus&amp;quot; flip=1  # Flip = 1, if OBJ created by openFX, crossroads3D combination&lt;br /&gt;
   createWFObj &amp;quot;torus.obj&amp;quot; &amp;quot;Torus&amp;quot; translate=[10,10,0] flip=1      &lt;br /&gt;
   &lt;br /&gt;
===REFERENCES===&lt;br /&gt;
[http://www.openfx.org OpenFX]&lt;br /&gt;
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (WFMesh.py)===&lt;br /&gt;
WFMesh.py&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
###############################################&lt;br /&gt;
#  File:          WFObj.py&lt;br /&gt;
#  Author:        Dan Kulp&lt;br /&gt;
#  Creation Date: 5/13/05&lt;br /&gt;
#&lt;br /&gt;
#  Notes:&lt;br /&gt;
#  Create openGL objects from a wavefront (obj) file&lt;br /&gt;
###############################################&lt;br /&gt;
 &lt;br /&gt;
import os&lt;br /&gt;
import string&lt;br /&gt;
import re&lt;br /&gt;
import math&lt;br /&gt;
from pymol.opengl.gl import *&lt;br /&gt;
from pymol.callback import Callback&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)&lt;br /&gt;
def createWFObj(file, name,translate=[0,0,0],flip=0):&lt;br /&gt;
        obj = WFMesh(file,translate,flip)&lt;br /&gt;
        cmd.load_callback(obj,name)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Class for Wavefront Mesh&lt;br /&gt;
class WFMesh(Callback):&lt;br /&gt;
 &lt;br /&gt;
    verts = []        # list of vertices&lt;br /&gt;
    polys = []        # list of poylgons&lt;br /&gt;
    pnorms = []       # list of polynomal normals&lt;br /&gt;
    vnorms = {}       # dict. of vertex normals&lt;br /&gt;
    vavenorms = []    # list of vertex normals, redundant -- I'm far froma python pro.&lt;br /&gt;
    sections = {}     # list of sections of mesh&lt;br /&gt;
 &lt;br /&gt;
    # Read mesh into memory&lt;br /&gt;
    def readOBJ(self,file):&lt;br /&gt;
        if os.path.exists(file):&lt;br /&gt;
            input = open(file,'r')&lt;br /&gt;
            for line in input:&lt;br /&gt;
                dat = re.split(&amp;quot;\s+&amp;quot;, line)&lt;br /&gt;
 &lt;br /&gt;
                # Find vertex line&lt;br /&gt;
                if line[0] == 'v' and line[1] != 't' and line[1] != 'n':    self.verts.append([dat[1],dat[2],dat[3]])&lt;br /&gt;
 &lt;br /&gt;
                # Find polygon line&lt;br /&gt;
                if line[0] == 'f':    self.polys.append([dat[1],dat[2],dat[3]])&lt;br /&gt;
 &lt;br /&gt;
                # Find section line&lt;br /&gt;
                if line[0] == 'g':    self.sections[len(self.polys)] = dat[1] &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    # Compute the normals for each polygon and each vertex              &lt;br /&gt;
    def computeNorms(self):&lt;br /&gt;
 &lt;br /&gt;
        # Compute norms for each polygon&lt;br /&gt;
        for p in self.polys:&lt;br /&gt;
                v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\&lt;br /&gt;
                       float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\&lt;br /&gt;
                       float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \&lt;br /&gt;
                      ]&lt;br /&gt;
 &lt;br /&gt;
                v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\&lt;br /&gt;
                       float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\&lt;br /&gt;
                       float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \&lt;br /&gt;
                      ] &lt;br /&gt;
 &lt;br /&gt;
                # Compute poly normal&lt;br /&gt;
                polynorm = self.cross(v12,v13) &lt;br /&gt;
                norm = self.normalize(polynorm)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
                # Files created by OpenFX, Crossroads combination need have their normals flipped       &lt;br /&gt;
                if self.flip:&lt;br /&gt;
                        norm[0] = -norm[0]&lt;br /&gt;
                        norm[1] = -norm[1]&lt;br /&gt;
                        norm[2] = -norm[2]&lt;br /&gt;
 &lt;br /&gt;
                # Append poly norm to polygonal norm array&lt;br /&gt;
                self.pnorms.append(norm)&lt;br /&gt;
 &lt;br /&gt;
                # Add norm to each vertexes norm..&lt;br /&gt;
                try:&lt;br /&gt;
                    self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],&lt;br /&gt;
                                            float(self.vnorms[int(p[0])-1][1]) + norm[1],&lt;br /&gt;
                                            float(self.vnorms[int(p[0])-1][2]) + norm[2]&lt;br /&gt;
                                           ]&lt;br /&gt;
                except:&lt;br /&gt;
                    self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
 &lt;br /&gt;
                try:                                       &lt;br /&gt;
                    self.vnorms[int(p[1])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][1]) + norm[1],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][2]) + norm[2]&lt;br /&gt;
                                           ]&lt;br /&gt;
                except:&lt;br /&gt;
                    self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
 &lt;br /&gt;
                try:&lt;br /&gt;
                    self.vnorms[int(p[2])-1]  = [float(self.vnorms[int(p[1])-1][0]) + norm[0],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][1]) + norm[1],&lt;br /&gt;
                                            float(self.vnorms[int(p[1])-1][2]) + norm[2]&lt;br /&gt;
                                           ]&lt;br /&gt;
                except:&lt;br /&gt;
                    self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
        # Average out each vnorm..&lt;br /&gt;
        index = 0&lt;br /&gt;
        for v in self.vnorms.values():&lt;br /&gt;
                self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4])         &lt;br /&gt;
                index += 1&lt;br /&gt;
 &lt;br /&gt;
    # Utility function to normalize a given vector&lt;br /&gt;
    def normalize(self,v):&lt;br /&gt;
        mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]&lt;br /&gt;
        if mag &amp;lt;= 0:&lt;br /&gt;
            mag = 1&lt;br /&gt;
        else:&lt;br /&gt;
            mag = math.sqrt(mag)&lt;br /&gt;
 &lt;br /&gt;
        return [v[0]/mag, v[1]/mag,v[2]/mag]&lt;br /&gt;
 &lt;br /&gt;
    # Utility cross product function&lt;br /&gt;
    def cross(self,v1,v2):&lt;br /&gt;
        x = 0&lt;br /&gt;
        y = 1&lt;br /&gt;
        z = 2&lt;br /&gt;
 &lt;br /&gt;
        return [v1[y]*v2[z] - v1[z]*v2[y],\&lt;br /&gt;
                v1[z]*v2[x] - v1[x]*v2[z],\&lt;br /&gt;
                v1[x]*v2[y] - v1[y]*v2[x]&lt;br /&gt;
                ]&lt;br /&gt;
 &lt;br /&gt;
    # Constructor&lt;br /&gt;
    def __init__(self, file,translate=[0,0,0],flip=0):&lt;br /&gt;
        self.verts = []&lt;br /&gt;
        self.polys = [] &lt;br /&gt;
        self.pnorms = []&lt;br /&gt;
        self.vnorms = {}&lt;br /&gt;
        self.vavenorms = []&lt;br /&gt;
        self.translate = translate&lt;br /&gt;
        self.flip      = flip &lt;br /&gt;
 &lt;br /&gt;
        print &amp;quot;Read in file: &amp;quot;+str(file)&lt;br /&gt;
        self.readOBJ(file)&lt;br /&gt;
        print &amp;quot;Done reading in WFMesh, now compute norms&amp;quot;&lt;br /&gt;
        self.computeNorms()&lt;br /&gt;
        print &amp;quot;Done computing norms, now display WFMesh&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    # Draw Function&lt;br /&gt;
    def __call__(self):&lt;br /&gt;
 &lt;br /&gt;
        glColorMaterial(GL_FRONT, GL_DIFFUSE);  &lt;br /&gt;
        glEnable(GL_COLOR_MATERIAL);&lt;br /&gt;
        glShadeModel(GL_SMOOTH);&lt;br /&gt;
 &lt;br /&gt;
        # Color Everything grey&lt;br /&gt;
        glColor3f(0.5,0.5,0.5);&lt;br /&gt;
 &lt;br /&gt;
        index = 0&lt;br /&gt;
        glPushMatrix()&lt;br /&gt;
        glTranslated(self.translate[0],self.translate[1],self.translate[2])&lt;br /&gt;
        for p in self.polys:&lt;br /&gt;
                glBegin(GL_POLYGON)&lt;br /&gt;
                glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))&lt;br /&gt;
 &lt;br /&gt;
                for i in range(0,len(p)):&lt;br /&gt;
                        glVertex3f(float(self.verts[int(p[i])-1][0]),float(self.verts[int(p[i])-1][1]),float(self.verts[int(p[i])-1][2]))&lt;br /&gt;
 &lt;br /&gt;
                        # Vertex Normals - not computed correctly, so commented out for now&lt;br /&gt;
#                       norm = self.vnorms[int(p[i])-1]&lt;br /&gt;
#                       glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))&lt;br /&gt;
                glEnd()&lt;br /&gt;
                index += 1&lt;br /&gt;
        glPopMatrix()&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
cmd.extend(&amp;quot;createWFObj&amp;quot;, createWFObj)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ADDITIONAL RESOURCES===&lt;br /&gt;
Torus.obj&lt;br /&gt;
[http://pymolwiki.org/images/9/98/Torus.zip Torus.zip]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|WFMesh]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Color_Objects&amp;diff=7564</id>
		<title>Color Objects</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Color_Objects&amp;diff=7564"/>
		<updated>2010-02-02T12:56:42Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#####################################################################&lt;br /&gt;
#&lt;br /&gt;
# Colour by object&lt;br /&gt;
#&lt;br /&gt;
#####################################################################&lt;br /&gt;
 &lt;br /&gt;
def color_obj(rainbow=0):&lt;br /&gt;
 &lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
AUTHOR &lt;br /&gt;
 &lt;br /&gt;
        Gareth Stockwell&lt;br /&gt;
 &lt;br /&gt;
USAGE&lt;br /&gt;
 &lt;br /&gt;
        color_obj(rainbow=0)&lt;br /&gt;
 &lt;br /&gt;
        This function colours each object currently in the PyMOL heirarchy&lt;br /&gt;
        with a different colour.  Colours used are either the 22 named&lt;br /&gt;
        colours used by PyMOL (in which case the 23rd object, if it exists,&lt;br /&gt;
        gets the same colour as the first), or are the colours of the rainbow&lt;br /&gt;
 &lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
        # Process arguments&lt;br /&gt;
        rainbow = int(rainbow)&lt;br /&gt;
 &lt;br /&gt;
        # Get names of all PyMOL objects&lt;br /&gt;
        obj_list = cmd.get_names('models')&lt;br /&gt;
 &lt;br /&gt;
        if rainbow:&lt;br /&gt;
 &lt;br /&gt;
           print &amp;quot;\nColouring objects as rainbow\n&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
           nobj = len(obj_list)&lt;br /&gt;
 &lt;br /&gt;
           # Create colours starting at blue(240) to red(0), using intervals&lt;br /&gt;
           # of 240/(nobj-1)&lt;br /&gt;
           for j in range(nobj):&lt;br /&gt;
              hsv = (240-j*240/(nobj-1), 1, 1)&lt;br /&gt;
              # Convert to RGB&lt;br /&gt;
              rgb = hsv_to_rgb(hsv)&lt;br /&gt;
              # Define the new colour&lt;br /&gt;
              cmd.set_color(&amp;quot;col&amp;quot; + str(j), rgb)&lt;br /&gt;
              print obj_list[j], rgb&lt;br /&gt;
              # Colour the object&lt;br /&gt;
              cmd.color(&amp;quot;col&amp;quot; + str(j), obj_list[j])&lt;br /&gt;
 &lt;br /&gt;
        else:&lt;br /&gt;
 &lt;br /&gt;
           print &amp;quot;\nColouring objects using PyMOL defined colours\n&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
           # List of available colours&lt;br /&gt;
           colours = ['red', 'green', 'blue', 'yellow', 'violet', 'cyan',    \&lt;br /&gt;
           'salmon', 'lime', 'pink', 'slate', 'magenta', 'orange', 'marine', \&lt;br /&gt;
           'olive', 'purple', 'teal', 'forest', 'firebrick', 'chocolate',    \&lt;br /&gt;
           'wheat', 'white', 'grey' ]&lt;br /&gt;
           ncolours = len(colours)&lt;br /&gt;
 &lt;br /&gt;
           # Loop over objects&lt;br /&gt;
           i = 0&lt;br /&gt;
           for obj in obj_list:&lt;br /&gt;
              print &amp;quot;  &amp;quot;, obj, colours[i]&lt;br /&gt;
              cmd.color(colours[i], obj)&lt;br /&gt;
              i = i+1&lt;br /&gt;
              if(i == ncolours):&lt;br /&gt;
                 i = 0&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# HSV to RGB routine taken from Robert L. Campbell's color_b.py script&lt;br /&gt;
#   See http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/&lt;br /&gt;
# Original algorithm from: http://www.cs.rit.edu/~ncs/color/t_convert.html&lt;br /&gt;
def hsv_to_rgb(hsv):&lt;br /&gt;
 &lt;br /&gt;
        h = float(hsv[0])&lt;br /&gt;
        s = float(hsv[1])&lt;br /&gt;
        v = float(hsv[2])&lt;br /&gt;
 &lt;br /&gt;
        if( s == 0 ) :&lt;br /&gt;
                #achromatic (grey)&lt;br /&gt;
                r = g = b = v&lt;br /&gt;
 &lt;br /&gt;
        else:&lt;br /&gt;
                # sector 0 to 5&lt;br /&gt;
                h = h/60.            &lt;br /&gt;
                i = int(h)&lt;br /&gt;
                f = h - i                       # factorial part of h&lt;br /&gt;
                #print h,i,f&lt;br /&gt;
                p = v * ( 1 - s )&lt;br /&gt;
                q = v * ( 1 - s * f )&lt;br /&gt;
                t = v * ( 1 - s * ( 1 - f ) )&lt;br /&gt;
 &lt;br /&gt;
                if i == 0:&lt;br /&gt;
                        (r,g,b) = (v,t,p)&lt;br /&gt;
                elif i == 1:&lt;br /&gt;
                        (r,g,b) = (q,v,p)&lt;br /&gt;
                elif i == 2:&lt;br /&gt;
                        (r,g,b) = (p,v,t)&lt;br /&gt;
                elif i == 3:&lt;br /&gt;
                        (r,g,b) = (p,q,v)&lt;br /&gt;
                elif i == 4:&lt;br /&gt;
                        (r,g,b) = (t,p,v)&lt;br /&gt;
                elif i == 5:&lt;br /&gt;
                        (r,g,b) = (v,p,q)&lt;br /&gt;
                else:&lt;br /&gt;
                        (r,g,b) = (v,v,v)&lt;br /&gt;
                        print &amp;quot;error, i not equal 1-5&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
        return [r,g,b]&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
# Add color_obj to the PyMOL command list &lt;br /&gt;
cmd.extend(&amp;quot;color_obj&amp;quot;,color_obj)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|Color Objects]]&lt;br /&gt;
[[Category:Coloring]]&lt;br /&gt;
[[Category:ObjSel_Scripts]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=DynoPlot&amp;diff=8241</id>
		<title>DynoPlot</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=DynoPlot&amp;diff=8241"/>
		<updated>2010-02-02T12:55:55Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===DESCRIPTION===&lt;br /&gt;
This script was setup to do generic plotting, that is given a set of data and axis labels it would create a plot. Initially, I had it setup to draw the plot directly in the PyMol window (allowing for both 2D and 3D style plots), but because I couldn't figure out how to billboard CGO objects (Warren told me at the time that it couldn't be done) I took a different approach.  The plot now exists in it's own window and can only do 2D plots.  It is however interactive.  I only have here a Rama.(phi,psi) plot, but the code can be easily extended to other types of data.  For instance, I had this working for an energy vs distance data that I had generated by another script.&lt;br /&gt;
&lt;br /&gt;
This script will create a Phi vs Psi(Ramachandran) plot of the selection given.  The plot will display data points which can be dragged around Phi,Psi space with the corresponding residue's Phi,Psi angles changing in the structure (PyMol window).&lt;br /&gt;
&lt;br /&gt;
===IMAGES===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Image:RamaPlotInitComposite.png|Initial Ramachandran plot of 1ENV&lt;br /&gt;
Image:RamaPlotBentComposite.png|Modified pose and plot of 1ENV&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===SETUP===&lt;br /&gt;
place the DynoPlot.py script into the appropriate startup directory then restart PyMol&lt;br /&gt;
&lt;br /&gt;
==== LINUX old-style installation ====&lt;br /&gt;
&lt;br /&gt;
$PYMOL_PATH/modules/pmg_tk/startup/&lt;br /&gt;
&lt;br /&gt;
==== LINUX distutils installation ====&lt;br /&gt;
&lt;br /&gt;
/usr/lib/pythonX.X/site-packages/pmg_tk/startup/&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
PYMOL_PATH/modules/pmg_tk/startup/ , where PYMOL_PATH on Windows is defaulted to C:/Program Files/DeLano Scientific/PyMol/start/&lt;br /&gt;
&lt;br /&gt;
===NOTES / STATUS===&lt;br /&gt;
*Tested on Windows, PyMol version 0.97&lt;br /&gt;
*This is an initial version, which needs some work.  &lt;br /&gt;
*Left, Right mouse buttons do different things; Right = identify data point, Left = drag data point around&lt;br /&gt;
*Post comments/questions or send them to: dwkulp@mail.med.upenn.edu&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
rama SELECTION&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===    &lt;br /&gt;
*load pdb file 1ENV (download it or use the PDB loader plugin)&lt;br /&gt;
*select resi 129-136&lt;br /&gt;
*rama sel01&lt;br /&gt;
*rock   # the object needs to be moving in order for the angles to be updated.&lt;br /&gt;
&lt;br /&gt;
===REFERENCES===&lt;br /&gt;
&lt;br /&gt;
===SCRIPTS (DynoPlot.py)===&lt;br /&gt;
DynoPlot.py&lt;br /&gt;
 &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
###############################################&lt;br /&gt;
#  File:          DynoPlot.py&lt;br /&gt;
#  Author:        Dan Kulp&lt;br /&gt;
#  Creation Date: 8/29/05&lt;br /&gt;
#&lt;br /&gt;
#  Notes:&lt;br /&gt;
#  Draw plots that display interactive data. &lt;br /&gt;
#   Phi,Psi plot shown.&lt;br /&gt;
###############################################&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from __future__ import division&lt;br /&gt;
from __future__ import generators&lt;br /&gt;
&lt;br /&gt;
import os,math&lt;br /&gt;
import Tkinter&lt;br /&gt;
from Tkinter import *&lt;br /&gt;
import Pmw&lt;br /&gt;
import distutils.spawn # used for find_executable&lt;br /&gt;
import random&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
	import pymol&lt;br /&gt;
	REAL_PYMOL = True&lt;br /&gt;
except ImportError:&lt;br /&gt;
	print &amp;quot;Nope&amp;quot;&lt;br /&gt;
&lt;br /&gt;
canvas = None&lt;br /&gt;
rootframe = None&lt;br /&gt;
init = 0&lt;br /&gt;
&lt;br /&gt;
class SimplePlot(Tkinter.Canvas):&lt;br /&gt;
	&lt;br /&gt;
	# Class variables&lt;br /&gt;
	mark = 'Oval' # Only 'Oval' for now..&lt;br /&gt;
	mark_size = 5&lt;br /&gt;
	xlabels = []   # axis labels&lt;br /&gt;
	ylabels = []&lt;br /&gt;
	spacingx = 0   # spacing in x direction&lt;br /&gt;
	spacingy = 0    &lt;br /&gt;
	xmin = 0       # min value from each axis&lt;br /&gt;
	ymin = 0&lt;br /&gt;
	lastx = 0      # previous x,y pos of mouse   &lt;br /&gt;
	lasty = 0&lt;br /&gt;
	down  = 0      # flag for mouse pressed&lt;br /&gt;
	item = (0,)    # items array used for clickable events&lt;br /&gt;
	shapes = {}    # store plot data, x,y etc..&lt;br /&gt;
	&lt;br /&gt;
	def axis(self,xmin=40,xmax=300,ymin=10,ymax=290,xint=290,yint=40,xlabels=[],ylabels=[]):&lt;br /&gt;
		&lt;br /&gt;
		# Store variables in self object&lt;br /&gt;
		self.xlabels = xlabels&lt;br /&gt;
		self.ylabels = ylabels&lt;br /&gt;
		self.spacingx = (xmax-xmin) / (len(xlabels) - 1)&lt;br /&gt;
		self.spacingy = (ymax-ymin) / (len(ylabels) - 1)&lt;br /&gt;
		self.xmin = xmin&lt;br /&gt;
		self.ymin = ymin&lt;br /&gt;
		&lt;br /&gt;
		# Create axis lines&lt;br /&gt;
		self.create_line((xmin,xint,xmax,xint),fill=&amp;quot;black&amp;quot;,width=3)&lt;br /&gt;
		self.create_line((yint,ymin,yint,ymax),fill=&amp;quot;black&amp;quot;,width=3)&lt;br /&gt;
		&lt;br /&gt;
		# Create tick marks and labels&lt;br /&gt;
		nextspot = xmin&lt;br /&gt;
		for label in xlabels:&lt;br /&gt;
			self.create_line((nextspot, xint+5,nextspot, xint-5),fill=&amp;quot;black&amp;quot;,width=2)&lt;br /&gt;
			self.create_text(nextspot, xint-15, text=label)&lt;br /&gt;
			if len(xlabels) == 1:&lt;br /&gt;
				nextspot = xmax&lt;br /&gt;
			else:&lt;br /&gt;
				nextspot = nextspot + (xmax - xmin)/ (len(xlabels) - 1)&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		nextspot = ymax&lt;br /&gt;
		for label in ylabels:&lt;br /&gt;
			self.create_line((yint+5,nextspot,yint-5,nextspot),fill=&amp;quot;black&amp;quot;,width=2)&lt;br /&gt;
			self.create_text(yint-20,nextspot,text=label)&lt;br /&gt;
			if len(ylabels) == 1:&lt;br /&gt;
				nextspot = ymin&lt;br /&gt;
			else:&lt;br /&gt;
				nextspot = nextspot - (ymax - ymin)/ (len(ylabels) - 1)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	# Plot a point&lt;br /&gt;
	def plot(self,xp,yp,meta):&lt;br /&gt;
		&lt;br /&gt;
		# Convert from 'label' space to 'pixel' space&lt;br /&gt;
		x = self.convertToPixel(&amp;quot;X&amp;quot;,xp)&lt;br /&gt;
		y = self.convertToPixel(&amp;quot;Y&amp;quot;,yp)&lt;br /&gt;
		&lt;br /&gt;
		if self.mark == &amp;quot;Oval&amp;quot;:&lt;br /&gt;
			oval = self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline=&amp;quot;black&amp;quot;,fill=&amp;quot;SkyBlue2&amp;quot;)&lt;br /&gt;
			&lt;br /&gt;
			self.shapes[oval] = [x,y,0,xp,yp,meta]&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	# Repaint all points		&lt;br /&gt;
	def repaint(self):&lt;br /&gt;
		for key,value in self.shapes.items():&lt;br /&gt;
			x = value[0]&lt;br /&gt;
			y = value[1]&lt;br /&gt;
			self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline=&amp;quot;black&amp;quot;,fill=&amp;quot;SkyBlue2&amp;quot;)&lt;br /&gt;
	&lt;br /&gt;
	# Convert from pixel space to label space&lt;br /&gt;
	def convertToLabel(self,axis, value):&lt;br /&gt;
		&lt;br /&gt;
		# Defaultly use X-axis info&lt;br /&gt;
		label0  = self.xlabels[0]&lt;br /&gt;
		label1  = self.xlabels[1]&lt;br /&gt;
		spacing = self.spacingx&lt;br /&gt;
		min     = self.xmin&lt;br /&gt;
		&lt;br /&gt;
		# Set info for Y-axis use&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
			label0    = self.ylabels[0]&lt;br /&gt;
			label1    = self.ylabels[1]&lt;br /&gt;
			spacing   = self.spacingy&lt;br /&gt;
			min       = self.ymin	&lt;br /&gt;
		&lt;br /&gt;
		pixel = value - min&lt;br /&gt;
		label = pixel / spacing&lt;br /&gt;
		label = label0 + label * abs(label1 - label0)&lt;br /&gt;
		&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
			label = - label&lt;br /&gt;
		&lt;br /&gt;
		return label&lt;br /&gt;
	&lt;br /&gt;
	# Converts value from 'label' space to 'pixel' space&lt;br /&gt;
	def convertToPixel(self,axis, value):&lt;br /&gt;
		&lt;br /&gt;
		# Defaultly use X-axis info&lt;br /&gt;
		label0  = self.xlabels[0]&lt;br /&gt;
		label1  = self.xlabels[1]&lt;br /&gt;
		spacing = self.spacingx&lt;br /&gt;
		min     = self.xmin&lt;br /&gt;
		&lt;br /&gt;
		# Set info for Y-axis use&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
			label0    = self.ylabels[0]&lt;br /&gt;
			label1    = self.ylabels[1]&lt;br /&gt;
			spacing   = self.spacingy&lt;br /&gt;
			min       = self.ymin	&lt;br /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		# Get axis increment in 'label' space&lt;br /&gt;
		inc = abs(label1 - label0)&lt;br /&gt;
		&lt;br /&gt;
		# 'Label' difference from value and smallest label (label0)&lt;br /&gt;
		diff = float(value - label0)&lt;br /&gt;
		&lt;br /&gt;
		# Get whole number in 'label' space&lt;br /&gt;
		whole = int(diff / inc)&lt;br /&gt;
		&lt;br /&gt;
		# Get fraction number in 'label' space&lt;br /&gt;
		part = float(float(diff/inc) - whole)&lt;br /&gt;
		&lt;br /&gt;
		# Return 'pixel' position value&lt;br /&gt;
		pixel = whole * spacing + part * spacing&lt;br /&gt;
		&lt;br /&gt;
		#		print &amp;quot;Pixel: %f * %f + %f * %f = %f&amp;quot; % (whole, spacing, part, spacing,pixel)&lt;br /&gt;
		&lt;br /&gt;
		# Reverse number by subtracting total number of pixels - value pixels&lt;br /&gt;
		if axis == &amp;quot;Y&amp;quot;:&lt;br /&gt;
			tot_label_diff = float(self.ylabels[len(self.ylabels)- 1] - label0)&lt;br /&gt;
			tot_label_whole = int(tot_label_diff / inc)&lt;br /&gt;
			tot_label_part = float(float(tot_label_diff / inc) - tot_label_whole)&lt;br /&gt;
			tot_label_pix  = tot_label_whole * spacing + tot_label_part *spacing&lt;br /&gt;
			&lt;br /&gt;
			pixel = tot_label_pix - pixel&lt;br /&gt;
		&lt;br /&gt;
		# Add min edge pixels&lt;br /&gt;
		pixel = pixel + min&lt;br /&gt;
		&lt;br /&gt;
		return pixel&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	# Print out which data point you just clicked on..&lt;br /&gt;
	def pickWhich(self,event):&lt;br /&gt;
		&lt;br /&gt;
		# Find closest data point		    &lt;br /&gt;
		x = event.widget.canvasx(event.x)&lt;br /&gt;
		y = event.widget.canvasx(event.y)&lt;br /&gt;
		spot = event.widget.find_closest(x,y)&lt;br /&gt;
		&lt;br /&gt;
		# Print the shape's meta information corresponding with the shape that was picked&lt;br /&gt;
		if self.shapes.has_key(spot[0]):&lt;br /&gt;
			print &amp;quot;Residue(Ca): %s\n&amp;quot; % str(self.shapes[spot[0]][5][2])&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	# Mouse Down Event&lt;br /&gt;
	def down(self,event):&lt;br /&gt;
		&lt;br /&gt;
		# Store x,y position&lt;br /&gt;
		self.lastx = event.x&lt;br /&gt;
		self.lasty = event.y&lt;br /&gt;
		&lt;br /&gt;
		# Find the currently selected item&lt;br /&gt;
		x = event.widget.canvasx(event.x)&lt;br /&gt;
		y = event.widget.canvasx(event.y)&lt;br /&gt;
		self.item = event.widget.find_closest(x,y)&lt;br /&gt;
		&lt;br /&gt;
		# Identify that the mouse is down&lt;br /&gt;
		self.down  = 1&lt;br /&gt;
	&lt;br /&gt;
	# Mouse Up Event&lt;br /&gt;
	def up(self,event):&lt;br /&gt;
		&lt;br /&gt;
		# Get label space version of x,y&lt;br /&gt;
		labelx = self.convertToLabel(&amp;quot;X&amp;quot;,event.x)&lt;br /&gt;
		labely = self.convertToLabel(&amp;quot;Y&amp;quot;,event.y)&lt;br /&gt;
		&lt;br /&gt;
		# Convert new position into label space..&lt;br /&gt;
		if self.shapes.has_key(self.item[0]):&lt;br /&gt;
			self.shapes[self.item[0]][0] = event.x&lt;br /&gt;
			self.shapes[self.item[0]][1] = event.y&lt;br /&gt;
			self.shapes[self.item[0]][2] =  1&lt;br /&gt;
			self.shapes[self.item[0]][3] = labelx&lt;br /&gt;
			self.shapes[self.item[0]][4] = labely&lt;br /&gt;
		&lt;br /&gt;
		# Reset Flags&lt;br /&gt;
		self.item = (0,)&lt;br /&gt;
		self.down = 0&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	# Mouse Drag(Move) Event&lt;br /&gt;
	def drag(self,event):&lt;br /&gt;
		&lt;br /&gt;
		# Check that mouse is down and item clicked is a valid data point&lt;br /&gt;
		if self.down and self.shapes.has_key(self.item[0]):&lt;br /&gt;
			&lt;br /&gt;
			self.move(self.item, event.x - self.lastx, event.y - self.lasty)&lt;br /&gt;
			&lt;br /&gt;
			self.lastx = event.x&lt;br /&gt;
			self.lasty = event.y&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def __init__(self):&lt;br /&gt;
	&lt;br /&gt;
	self.menuBar.addcascademenu('Plugin', 'PlotTools', 'Plot Tools',&lt;br /&gt;
	label='Plot Tools')&lt;br /&gt;
	self.menuBar.addmenuitem('PlotTools', 'command',&lt;br /&gt;
	'Launch Rama Plot',&lt;br /&gt;
	label='Rama Plot',&lt;br /&gt;
	command = lambda s=self: ramaplot())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def ramaplot(x=0,y=0,meta=[],clear=0):&lt;br /&gt;
	global canvas&lt;br /&gt;
	global rootframe&lt;br /&gt;
	global init&lt;br /&gt;
	&lt;br /&gt;
	# If no window is open&lt;br /&gt;
	if init == 0:&lt;br /&gt;
		rootframe=Tk()&lt;br /&gt;
		rootframe.title(' Dynamic Angle Plotting ')&lt;br /&gt;
		rootframe.protocol(&amp;quot;WM_DELETE_WINDOW&amp;quot;, close_callback)&lt;br /&gt;
		&lt;br /&gt;
		canvas = SimplePlot(rootframe,width=320,height=320)&lt;br /&gt;
		canvas.bind(&amp;quot;&amp;lt;Button-2&amp;gt;&amp;quot;,canvas.pickWhich)&lt;br /&gt;
		canvas.bind(&amp;quot;&amp;lt;Button-3&amp;gt;&amp;quot;,canvas.pickWhich)&lt;br /&gt;
		canvas.bind(&amp;quot;&amp;lt;ButtonPress-1&amp;gt;&amp;quot;,canvas.down)&lt;br /&gt;
		canvas.bind(&amp;quot;&amp;lt;ButtonRelease-1&amp;gt;&amp;quot;,canvas.up)&lt;br /&gt;
		canvas.bind(&amp;quot;&amp;lt;Motion&amp;gt;&amp;quot;,canvas.drag)&lt;br /&gt;
		canvas.pack(side=Tkinter.LEFT,fill=&amp;quot;both&amp;quot;,expand=1)&lt;br /&gt;
		canvas.axis(xint=150,xlabels=range(-180,181,30),ylabels=range(-180,181, 30))&lt;br /&gt;
		canvas.update()&lt;br /&gt;
		init = 1&lt;br /&gt;
	else:&lt;br /&gt;
		canvas.plot(int(x), int(y),meta)&lt;br /&gt;
&lt;br /&gt;
def close_callback():&lt;br /&gt;
	global init&lt;br /&gt;
	global rootframe&lt;br /&gt;
	init=0&lt;br /&gt;
	rootframe.destroy()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# New Callback object, so that we can update the structure when phi,psi points are moved.&lt;br /&gt;
class DynoRamaObject:&lt;br /&gt;
	global canvas&lt;br /&gt;
	&lt;br /&gt;
	def start(self,sel):&lt;br /&gt;
		&lt;br /&gt;
		# Get selection model&lt;br /&gt;
		model = cmd.get_model(sel)&lt;br /&gt;
		residues = ['dummy']&lt;br /&gt;
		resnames = ['dummy']&lt;br /&gt;
		phi = []&lt;br /&gt;
		psi = []&lt;br /&gt;
		dummy = []&lt;br /&gt;
		i = 0&lt;br /&gt;
		&lt;br /&gt;
		# Loop through each atom&lt;br /&gt;
		for at in model.atom:&lt;br /&gt;
			&lt;br /&gt;
			# Only plot once per residue&lt;br /&gt;
			if not at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi in residues:&lt;br /&gt;
				residues.append(at.chain+&amp;quot;:&amp;quot;+at.resn+&amp;quot;:&amp;quot;+at.resi)&lt;br /&gt;
				resnames.append(at.resn+at.resi)&lt;br /&gt;
				dummy.append(i)&lt;br /&gt;
				i += 1&lt;br /&gt;
				&lt;br /&gt;
				# Check for a null chain id (some PDBs contain this) &lt;br /&gt;
				unit_select = &amp;quot;&amp;quot;&lt;br /&gt;
				if not at.chain == &amp;quot;&amp;quot;:&lt;br /&gt;
					unit_select = &amp;quot;chain &amp;quot;+str(at.chain)+&amp;quot; and &amp;quot;&lt;br /&gt;
				&lt;br /&gt;
				# Define selections for residue i-1, i and i+1    &lt;br /&gt;
				residue_def = unit_select+'resi '+str(at.resi)&lt;br /&gt;
				residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)&lt;br /&gt;
				residue_def_next = unit_select+'resi '+str(int(at.resi)+1)&lt;br /&gt;
				&lt;br /&gt;
				try:&lt;br /&gt;
					# Store phi,psi residue definitions to pass on to plot routine&lt;br /&gt;
					phi_psi = [&lt;br /&gt;
					# Phi angles&lt;br /&gt;
					residue_def_prev+' and name C',&lt;br /&gt;
					residue_def+' and name N',&lt;br /&gt;
					residue_def+' and name CA',&lt;br /&gt;
					residue_def+' and name C',&lt;br /&gt;
					# Psi angles&lt;br /&gt;
					residue_def+' and name N',&lt;br /&gt;
					residue_def+' and name CA',&lt;br /&gt;
					residue_def+' and name C',&lt;br /&gt;
					residue_def_next+' and name N']&lt;br /&gt;
					&lt;br /&gt;
					# Compute phi/psi angle&lt;br /&gt;
					phi = cmd.get_dihedral(phi_psi[0],phi_psi[1],phi_psi[2],phi_psi[3])&lt;br /&gt;
					psi = cmd.get_dihedral(phi_psi[4],phi_psi[5],phi_psi[6],phi_psi[7])&lt;br /&gt;
					&lt;br /&gt;
					print &amp;quot;Plotting Phi,Psi: &amp;quot;+str(phi)+&amp;quot;,&amp;quot;+str(psi)    &lt;br /&gt;
					ramaplot(phi,psi,meta=phi_psi)&lt;br /&gt;
				except:&lt;br /&gt;
					continue&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	def __call__(self):&lt;br /&gt;
		&lt;br /&gt;
		# Loop through each item on plot to see if updated&lt;br /&gt;
		for key,value in canvas.shapes.items():&lt;br /&gt;
			dihedrals = value[5]&lt;br /&gt;
			&lt;br /&gt;
			# Look for update flag...&lt;br /&gt;
			if value[2]:&lt;br /&gt;
				&lt;br /&gt;
				# Set residue's phi,psi to new values&lt;br /&gt;
				print &amp;quot;Re-setting Phi,Psi: &amp;quot;+str(value[3])+&amp;quot;,&amp;quot;+str(value[4])    &lt;br /&gt;
				cmd.set_dihedral(dihedrals[0],dihedrals[1],dihedrals[2],dihedrals[3],value[3])		    	&lt;br /&gt;
				cmd.set_dihedral(dihedrals[4],dihedrals[5],dihedrals[6],dihedrals[7],value[4])		    	&lt;br /&gt;
				&lt;br /&gt;
				value[2] = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# The wrapper function, used to create the Ploting window and the PyMol callback object	    		&lt;br /&gt;
def rama(sel):&lt;br /&gt;
	rama = DynoRamaObject()&lt;br /&gt;
	rama.start(sel)&lt;br /&gt;
	cmd.load_callback(rama, &amp;quot;DynoRamaObject&amp;quot;)&lt;br /&gt;
	cmd.zoom(&amp;quot;all&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Extend these commands&lt;br /&gt;
cmd.extend('rama',rama)		    			&lt;br /&gt;
cmd.extend('ramaplot',ramaplot)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ADDITIONAL RESOURCES===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|DynoPlot]]&lt;br /&gt;
[[Category:Structural_Biology_Scripts|DynoPlot]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Process_All_Files_In_Directory&amp;diff=8450</id>
		<title>Process All Files In Directory</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Process_All_Files_In_Directory&amp;diff=8450"/>
		<updated>2010-02-02T12:54:19Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Explanation=&lt;br /&gt;
For a given directory with PDB files in it, the following code will output, for each PDB, the bound disulfide bond lengths like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1alk.pdb&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  A CYS 178 SG&lt;br /&gt;
    1.975&lt;br /&gt;
  A CYS 286 SG&lt;br /&gt;
  A CYS 336 SG&lt;br /&gt;
    1.995&lt;br /&gt;
  B CYS 168 SG&lt;br /&gt;
  B CYS 178 SG&lt;br /&gt;
    1.996&lt;br /&gt;
  B CYS 286 SG&lt;br /&gt;
  B CYS 336 SG&lt;br /&gt;
    2.032&lt;br /&gt;
1btu.pdb&lt;br /&gt;
   CYS 42 SG&lt;br /&gt;
   CYS 58 SG&lt;br /&gt;
    2.039&lt;br /&gt;
   CYS 136 SG&lt;br /&gt;
   CYS 201 SG&lt;br /&gt;
    2.031&lt;br /&gt;
   CYS 168 SG&lt;br /&gt;
   CYS 182 SG&lt;br /&gt;
    2.001&lt;br /&gt;
   CYS 191 SG&lt;br /&gt;
   CYS 220 SG&lt;br /&gt;
    2.019&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Bound Disulfides=&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
from glob import glob&lt;br /&gt;
&lt;br /&gt;
for file in glob(&amp;quot;*.pdb&amp;quot;):&lt;br /&gt;
    print file&lt;br /&gt;
    cmd.load(file,'prot')&lt;br /&gt;
    for a in cmd.index(&amp;quot;elem s and bound_to elem s&amp;quot;):&lt;br /&gt;
        if cmd.select(&amp;quot;s1&amp;quot;,&amp;quot;%s`%d&amp;quot;%a) and \&lt;br /&gt;
           cmd.select(&amp;quot;s2&amp;quot;,&amp;quot;elem s and bound_to %s`%d&amp;quot;%a):&lt;br /&gt;
            if cmd.select(&amp;quot;(s1|s2) and not ?skip&amp;quot;):&lt;br /&gt;
                cmd.iterate(&amp;quot;s1|s2&amp;quot;,&amp;quot;print ' ',chain,resn,resi,name&amp;quot;)&lt;br /&gt;
                print '   ',round(cmd.dist(&amp;quot;tmp&amp;quot;,&amp;quot;s1&amp;quot;,&amp;quot;s2&amp;quot;),3)&lt;br /&gt;
                cmd.select(&amp;quot;skip&amp;quot;,&amp;quot;s1|s2|?skip&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;all&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=All Sulfur Distances=&lt;br /&gt;
Note that the above is for bonded sulfurs in disulfides.  For all intra-cysteine gamma sulfur distances, you'd want to do something more like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1alk.pdb&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  A CYS 178 SG&lt;br /&gt;
    1.975&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  A CYS 286 SG&lt;br /&gt;
    35.845&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  A CYS 336 SG&lt;br /&gt;
    35.029&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  B CYS 168 SG&lt;br /&gt;
    63.64&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  B CYS 178 SG&lt;br /&gt;
    63.775&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  B CYS 286 SG&lt;br /&gt;
    39.02&lt;br /&gt;
  A CYS 168 SG&lt;br /&gt;
  B CYS 336 SG&lt;br /&gt;
    39.314&lt;br /&gt;
1btu.pdb&lt;br /&gt;
   CYS 42 SG&lt;br /&gt;
   CYS 58 SG&lt;br /&gt;
    2.039&lt;br /&gt;
   CYS 42 SG&lt;br /&gt;
   CYS 136 SG&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
from glob import glob&lt;br /&gt;
&lt;br /&gt;
for file in glob(&amp;quot;*.pdb&amp;quot;):&lt;br /&gt;
    print file&lt;br /&gt;
    cmd.load(file,'prot')&lt;br /&gt;
    for a in cmd.index(&amp;quot;CYS/SG&amp;quot;):&lt;br /&gt;
        for b in cmd.index(&amp;quot;CYS/SG&amp;quot;):&lt;br /&gt;
            if a[1]&amp;lt;b[1]:&lt;br /&gt;
                cmd.select(&amp;quot;s1&amp;quot;,&amp;quot;%s`%d&amp;quot;%a)&lt;br /&gt;
                cmd.select(&amp;quot;s2&amp;quot;,&amp;quot;%s`%d&amp;quot;%b)&lt;br /&gt;
                if cmd.select(&amp;quot;(s1|s2) and not ?skip&amp;quot;):&lt;br /&gt;
                    cmd.iterate(&amp;quot;s1|s2&amp;quot;,&amp;quot;print ' ',chain,resn,resi,name&amp;quot;)&lt;br /&gt;
                    print '   ',round(cmd.dist(&amp;quot;tmp&amp;quot;,&amp;quot;s1&amp;quot;,&amp;quot;s2&amp;quot;),3)&lt;br /&gt;
                    cmd.select(&amp;quot;skip&amp;quot;,&amp;quot;s1|s2|?skip&amp;quot;)&lt;br /&gt;
    cmd.delete(&amp;quot;all&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Script_Library|Processing All File in Directory]]&lt;br /&gt;
[[Category:System_Scripts]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Ideas&amp;diff=11838</id>
		<title>Ideas</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Ideas&amp;diff=11838"/>
		<updated>2010-01-24T20:08:10Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* High-Level Enhancement Ideas (Mostly Python-oriented) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Ideas for PyMOL Development ===&lt;br /&gt;
&lt;br /&gt;
This page was originally developed for the 2008 Google Summer of Code competition, but seeing as PyMOL wasn't selected, this page can instead serve as a resource for ongoing PyMOL development efforts.&lt;br /&gt;
&lt;br /&gt;
== Where to Start ==&lt;br /&gt;
&lt;br /&gt;
Always start with Python and only delve down into the C code when absolutely necessary.  Although PyMOL is mostly a C-based application, much of the that code is opaque, fragile, and unforgiving. Although C code refactoring is an important project goal, such work may not be ideal since once mistake could potentially to destabilize the entire platform. &lt;br /&gt;
&lt;br /&gt;
Fortunately, the Python interpreter and the PyMOL command and selection languages make it possible to extend PyMOL safely and quickly.  Even when performance is critical, Python should be the interface between external C, C++, and Java code and PyMOL's internal C data structures.&lt;br /&gt;
&lt;br /&gt;
== Choosing a Topic ==&lt;br /&gt;
&lt;br /&gt;
The best open-source code is usually written by an end-users attempting to meet their own pressing needs.  So if you have already have a specific need which relates to PyMOL, then we strongly encourage you to follow up on that first!&lt;br /&gt;
&lt;br /&gt;
If you are looking for ideas,  then try to seek out enhancements and/or integrations that will impact the largest potential user base.  For example, imagine what new things might be useful to virtually all medicinal chemists, all structural biologists, all movie-makers, all paper-writers, and so forth.&lt;br /&gt;
&lt;br /&gt;
The ideas below are organized by category.  Right now, integration with other open-source projects seems like the approach most likely to yield significant benefit, so those ideas are first.&lt;br /&gt;
&lt;br /&gt;
== Integration Ideas (Linking Out to Useful Open-Source Tools) ==&lt;br /&gt;
&lt;br /&gt;
In most cases, depending on the need, integration can be accomplished through standalone Python scripts, through new PyMOL commands, through PyMOL Wizards, or via Tkinter plugins.&lt;br /&gt;
&lt;br /&gt;
* APBS (electrostatics calculations):  Improve the existing plugin. Michael Lerner is currently leading this effort.  See [[APBS]]&lt;br /&gt;
:: yea ([[User:Inchoate|Tree]] [[User:Jedgold|Jedgold]]&amp;quot;[[User:Vcpmartin|Vcpmartin]]&amp;quot;) / nay (0)&lt;br /&gt;
* RDKit (cheminformatics, depiction, UFF cleanup, etc.):  Lots of potential here, however C++ coding may be necessary for more advanced integration tasks. [http://www.rdkit.org RDKit home]&lt;br /&gt;
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)&lt;br /&gt;
* GIMP (image manipulation):  Streamline &amp;amp; document the process of exporting images from PyMOL into GIMP and preparing them for submission to scientific Journals.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Jmol (publishing visualizations inside of web pages): Liason between PyMOL &amp;amp; Jmol projects to develop a shared molecular visualization data model compatible with both applications.&lt;br /&gt;
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Firefox (plugin): Develop an PyMOL plugin compatible with Firefox.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* MMTK (molecular mechanics -- Python/flexible):  Develop the ability to round-trip molecular systems from PyMOL, into MMTK, and back.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* GROMACS (molecular mechanics -- C/fast) - Maybe some ideas can be shared with this guy. [http://www.kde-apps.org/content/show.php/Gromacs+GUI+?content=47665 Gromacs GUI]&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]] [[User:Mglerner|Michael Lerner]]) / nay (0)&lt;br /&gt;
* OpenOffice (escape Microsoft hegemony): Develop an PyMOL plugin.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* IPython integration (interactive shell): a robust alternative to the PyMOL command line?&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* R (statistics): PyMOL a 3D viewer environment for visualizating &amp;amp; manipulating large statistical data sets?&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
&lt;br /&gt;
Are there other key open-source packages we might specifically target for integration with PyMOL, either through GSoC or beyond?&lt;br /&gt;
&lt;br /&gt;
== High-Level Enhancement Ideas (Mostly Python-oriented) ==&lt;br /&gt;
&lt;br /&gt;
* Work on [[#More Ideas (Please add your own!)| MolViz]]&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop new plugins which automate routine tasks.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Improve the Python API documentation.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Flesh out the new &amp;quot;from pymol2 import PyMOL&amp;quot; instance-based PyMOL API.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop alternate Tkinter &amp;quot;skins&amp;quot; (for custom OEM-like applications).&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop a Tkinter/TOGL widget which holds a PyMOL viewer instance.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop a PyQt widget which holds a PyMOL viewer instance.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Create a plugin-manager GUI in the style of Firefox, Rythmbox, Gedit, Eclipse. A GUI where it is easy to turn off/on plugins, configure them and see help-contents for them. Maybe also some way to paste a url to install a new Plugin.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Add a plugin for a GUI window with the same functionality as the &amp;quot;Control Panel&amp;quot; window in SwissPDB Viewer.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Extend and modify the PyMOL command language so as to be compatible with existing RasMol and/or Jmol scripts.&lt;br /&gt;
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Enhance the Mutagenesis Wizard in order to support Nucleic acids and/or Sugars.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Better tab completion for commands&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) /nay(0)&lt;br /&gt;
&lt;br /&gt;
== Low-Level Enhancement Ideas (Mostly C-oriented) ==&lt;br /&gt;
&lt;br /&gt;
* Enable editing of displayed sequence alignments.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]], [[User:Aschreyer|Aschreyer]], [[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
::: Would this then feed back to the structural alignment? [[User:Jedgold|Jedgold]]&lt;br /&gt;
* Add multi-line textual annotations&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Support additional annotation object including: arrow, lines, and blobs.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Add display of secondary structure into the sequence viewer.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Enable per-object Z clipping (especially in the ray tracer)&lt;br /&gt;
:: yea ([[User:Gregori|Gregori]], [[User:Xevi|Xevi]], [[User:Johnm|Johnm]]) / nay (0)&lt;br /&gt;
::: I would go a step further with fully customizable selection-based clipping planes (XYZ, color and transparency) ([[User:Gregori|Gregori]])&lt;br /&gt;
* Highlight H-bonds, salt bridges, Pi-stacking, Pi-cations, etc.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Build in a simple forcefield and energy minimizer suitable for use with Mutagenesis.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Incorporate a suite of standard NMR visualizations (restraint violations, per-residue RMS, etc.)&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]&amp;quot;[[User:Vcpmartin|Vcpmartin]]&amp;quot;) / nay (0)&lt;br /&gt;
* Enumeration and display of low-energy conformers.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]]) / nay (0)&lt;br /&gt;
::: This could be done by integrating RDKit, I think. [[User:Aschreyer|Aschreyer]]&lt;br /&gt;
* Automated structure grafting (poor-man's homology modeling).&lt;br /&gt;
:: yea (0) / nay ([[User:Jedgold|Jedgold]], [[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
::: Perhaps a plugin to Modeller instead? ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]])&lt;br /&gt;
* Import of alignment files.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Implement IMD (Interactive Molecular Dynamics) Interface, see http://www.ks.uiuc.edu/Research/vmd/imd/&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Add buttons for '''Set ChainID''' and '''Renumber Residues From...''' to Edit menu or Actions (wrapper around Alter command)&lt;br /&gt;
:: yea ([[User:Sheehanj|Sheehanj]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Difficult C-level Code Refactoring Ideas ==&lt;br /&gt;
&lt;br /&gt;
* Assemble a test suite which thoroughly exercises the existing code (a prerequisite to major refactoring).&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Catch &amp;amp; handle memory-allocation failures gracefully (instead of crashing).&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Replace PyMOL's memory management &amp;amp; custom containers with a simple runtime object model.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Separate the View and the Controllers from the Model so that they can all run asynchronously (on multiple cores).&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Enable generalized undo of changes made to the Model.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]&amp;quot;[[User:Vcpmartin|Vcpmartin]], [[User:Lucajovine|Luca Jovine]]&amp;quot;, [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Clean up the internal matrix handling code.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Ideas Involving Proprietary APIs ==&lt;br /&gt;
&lt;br /&gt;
Since these involve closed-source APIs and infrastructure, they aren't suitable for open-source development efforts.  However, such requests are noted here for the sake of complete coverage.&lt;br /&gt;
&lt;br /&gt;
* Create a Windows port with &amp;quot;native&amp;quot; look &amp;amp; feel. &amp;lt;- Could this be done in PyQT or PyGTK?. Then it would look &amp;quot;native&amp;quot;, but be cross-platform and not proprietary.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Integrate directly via Mathematica via MathLink.&lt;br /&gt;
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])&lt;br /&gt;
* Further enhance JyMOL (Java-JNI/wrapped PyMOL)&lt;br /&gt;
:: yea ([[User:Inchoate|Tree]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Integrate with Matlab.&lt;br /&gt;
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])&lt;br /&gt;
* Quicklook Plugin on the Mac&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== More Ideas (Please add your own!) ==&lt;br /&gt;
* [http://molviz.cs.toronto.edu/molviz MolViz] is a project to incorporate head tracking input into [http://pymol.sourceforge.net/ PyMol]. This is accomplished through a [[ImmersiveViz]] script written in Python to control the molecule's position using the existing [http://www.pymolwiki.org/index.php/Category:Commands PyMol API]. Related projects would include:&lt;br /&gt;
** Improving the existing [[ImmersiveViz]] PyMol plugin for more precise control of the environment.&lt;br /&gt;
** Developing new input drivers for the Wiimote form of control. This would require some bluetooth hacking.&lt;br /&gt;
** Implementing some other forms of input for head tracking, such as fisheye head tracking, IR webcam tracking, etc (refer to the end of this [[http://www.youtube.com/watch?v=ncShaY4VSac video]] for a better description).&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Provide a 2D chemical depiction of the current 3D view.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
::: RDKit?&lt;br /&gt;
* Spreadsheet view with additional information (e.g. IC50's).&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Create additional documentation, screen casts, &amp;amp; tutorials.&lt;br /&gt;
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)&lt;br /&gt;
* Export 3D PDF images.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* &amp;lt;strike&amp;gt;Add extra &amp;quot;Single Word Selectors&amp;quot; like &amp;quot;nucleic&amp;quot;, &amp;quot;protein&amp;quot;, &amp;quot;water&amp;quot;, &amp;quot;ions&amp;quot;, &amp;quot;backbone&amp;quot; (for nucleic acids or proteins), &amp;quot;mainchain&amp;quot;, &amp;quot;sidechain&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Add functionality that allows you to select atoms based on their location (i.e. select (x_coordinate &amp;lt; 10) and (z_coordinate &amp;gt; 0))&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* set pdb_mirror option to use PDB mirrors other than RCSB for fetching structures (PDBe, PDBj); the EBI mirror is much faster from Europe for example.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]]) / nay (0)&lt;br /&gt;
* have the ability to link the TK console to the viewer so that users don't have to constantly alt+tab between what they want&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* have the ability to disable typing in the viewer and automatically type in the TK console (I like being able to cut/paste/home/end)&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* I see a lot of &amp;quot;can pymol do this&amp;quot; threads - any ideas of a good UI for a page of &amp;quot;things PyMOL can do?&amp;quot;&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* make an option where I can turn on a coordinate grid - perhaps an object that is a cuboid grid around any object in the view so I can still alter how it's rendered?&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* iPhone / Nexus One app(s)&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* single-color bonds between nonidentical or any spherical atoms colored specifically&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* double bonds as two parallel cylinders&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* export scenes as [http://www.khronos.org/webgl/ WebGL] / Could make mobile apps, presentation plugins obsolete&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* export images in vector format&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]]) / nay (0)&lt;br /&gt;
* Keynote plugin&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Electron density contour sliders&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Automatic electron density map generation from PDB mmcif files or user-supplied MTZ files&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]], [[User:Johnm|Johnm]]) / nay (0)&lt;br /&gt;
* Display of crystallographic symmetry and NCS axes, with possibility of showing symbols indicating what kind of axes they are&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Automatic symmetry expansion to show overall crystal packing; automatic generation of scenes showing crystal packing interface details&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Ideas&amp;diff=11837</id>
		<title>Ideas</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Ideas&amp;diff=11837"/>
		<updated>2010-01-24T20:06:20Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* Ideas Involving Proprietary APIs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Ideas for PyMOL Development ===&lt;br /&gt;
&lt;br /&gt;
This page was originally developed for the 2008 Google Summer of Code competition, but seeing as PyMOL wasn't selected, this page can instead serve as a resource for ongoing PyMOL development efforts.&lt;br /&gt;
&lt;br /&gt;
== Where to Start ==&lt;br /&gt;
&lt;br /&gt;
Always start with Python and only delve down into the C code when absolutely necessary.  Although PyMOL is mostly a C-based application, much of the that code is opaque, fragile, and unforgiving. Although C code refactoring is an important project goal, such work may not be ideal since once mistake could potentially to destabilize the entire platform. &lt;br /&gt;
&lt;br /&gt;
Fortunately, the Python interpreter and the PyMOL command and selection languages make it possible to extend PyMOL safely and quickly.  Even when performance is critical, Python should be the interface between external C, C++, and Java code and PyMOL's internal C data structures.&lt;br /&gt;
&lt;br /&gt;
== Choosing a Topic ==&lt;br /&gt;
&lt;br /&gt;
The best open-source code is usually written by an end-users attempting to meet their own pressing needs.  So if you have already have a specific need which relates to PyMOL, then we strongly encourage you to follow up on that first!&lt;br /&gt;
&lt;br /&gt;
If you are looking for ideas,  then try to seek out enhancements and/or integrations that will impact the largest potential user base.  For example, imagine what new things might be useful to virtually all medicinal chemists, all structural biologists, all movie-makers, all paper-writers, and so forth.&lt;br /&gt;
&lt;br /&gt;
The ideas below are organized by category.  Right now, integration with other open-source projects seems like the approach most likely to yield significant benefit, so those ideas are first.&lt;br /&gt;
&lt;br /&gt;
== Integration Ideas (Linking Out to Useful Open-Source Tools) ==&lt;br /&gt;
&lt;br /&gt;
In most cases, depending on the need, integration can be accomplished through standalone Python scripts, through new PyMOL commands, through PyMOL Wizards, or via Tkinter plugins.&lt;br /&gt;
&lt;br /&gt;
* APBS (electrostatics calculations):  Improve the existing plugin. Michael Lerner is currently leading this effort.  See [[APBS]]&lt;br /&gt;
:: yea ([[User:Inchoate|Tree]] [[User:Jedgold|Jedgold]]&amp;quot;[[User:Vcpmartin|Vcpmartin]]&amp;quot;) / nay (0)&lt;br /&gt;
* RDKit (cheminformatics, depiction, UFF cleanup, etc.):  Lots of potential here, however C++ coding may be necessary for more advanced integration tasks. [http://www.rdkit.org RDKit home]&lt;br /&gt;
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)&lt;br /&gt;
* GIMP (image manipulation):  Streamline &amp;amp; document the process of exporting images from PyMOL into GIMP and preparing them for submission to scientific Journals.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Jmol (publishing visualizations inside of web pages): Liason between PyMOL &amp;amp; Jmol projects to develop a shared molecular visualization data model compatible with both applications.&lt;br /&gt;
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Firefox (plugin): Develop an PyMOL plugin compatible with Firefox.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* MMTK (molecular mechanics -- Python/flexible):  Develop the ability to round-trip molecular systems from PyMOL, into MMTK, and back.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* GROMACS (molecular mechanics -- C/fast) - Maybe some ideas can be shared with this guy. [http://www.kde-apps.org/content/show.php/Gromacs+GUI+?content=47665 Gromacs GUI]&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]] [[User:Mglerner|Michael Lerner]]) / nay (0)&lt;br /&gt;
* OpenOffice (escape Microsoft hegemony): Develop an PyMOL plugin.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* IPython integration (interactive shell): a robust alternative to the PyMOL command line?&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* R (statistics): PyMOL a 3D viewer environment for visualizating &amp;amp; manipulating large statistical data sets?&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
&lt;br /&gt;
Are there other key open-source packages we might specifically target for integration with PyMOL, either through GSoC or beyond?&lt;br /&gt;
&lt;br /&gt;
== High-Level Enhancement Ideas (Mostly Python-oriented) ==&lt;br /&gt;
&lt;br /&gt;
* Work on [[#More Ideas (Please add your own!)| MolViz]]&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop new plugins which automate routine tasks.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Improve the Python API documentation.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Flesh out the new &amp;quot;from pymol2 import PyMOL&amp;quot; instance-based PyMOL API.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop alternate Tkinter &amp;quot;skins&amp;quot; (for custom OEM-like applications).&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop a Tkinter/TOGL widget which holds a PyMOL viewer instance.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop a PyQt widget which holds a PyMOL viewer instance.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Create a plugin-manager GUI in the style of Firefox, Rythmbox, Gedit, Eclipse. A GUI where it is easy to turn off/on plugins, configure them and see help-contents for them. Maybe also some way to paste a url to install a new Plugin.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Add a plugin for a GUI window with the same functionality as the &amp;quot;Control Panel&amp;quot; window in SwissPDB Viewer.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Extend and modify the PyMOL command language so as to be compatible with existing RasMol and/or Jmol scripts.&lt;br /&gt;
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Enhance the Mutagenesis Wizard in order to support Nucleic acids and/or Sugars.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Low-Level Enhancement Ideas (Mostly C-oriented) ==&lt;br /&gt;
&lt;br /&gt;
* Enable editing of displayed sequence alignments.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]], [[User:Aschreyer|Aschreyer]], [[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
::: Would this then feed back to the structural alignment? [[User:Jedgold|Jedgold]]&lt;br /&gt;
* Add multi-line textual annotations&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Support additional annotation object including: arrow, lines, and blobs.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Add display of secondary structure into the sequence viewer.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Enable per-object Z clipping (especially in the ray tracer)&lt;br /&gt;
:: yea ([[User:Gregori|Gregori]], [[User:Xevi|Xevi]], [[User:Johnm|Johnm]]) / nay (0)&lt;br /&gt;
::: I would go a step further with fully customizable selection-based clipping planes (XYZ, color and transparency) ([[User:Gregori|Gregori]])&lt;br /&gt;
* Highlight H-bonds, salt bridges, Pi-stacking, Pi-cations, etc.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Build in a simple forcefield and energy minimizer suitable for use with Mutagenesis.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Incorporate a suite of standard NMR visualizations (restraint violations, per-residue RMS, etc.)&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]&amp;quot;[[User:Vcpmartin|Vcpmartin]]&amp;quot;) / nay (0)&lt;br /&gt;
* Enumeration and display of low-energy conformers.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]]) / nay (0)&lt;br /&gt;
::: This could be done by integrating RDKit, I think. [[User:Aschreyer|Aschreyer]]&lt;br /&gt;
* Automated structure grafting (poor-man's homology modeling).&lt;br /&gt;
:: yea (0) / nay ([[User:Jedgold|Jedgold]], [[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
::: Perhaps a plugin to Modeller instead? ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]])&lt;br /&gt;
* Import of alignment files.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Implement IMD (Interactive Molecular Dynamics) Interface, see http://www.ks.uiuc.edu/Research/vmd/imd/&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Add buttons for '''Set ChainID''' and '''Renumber Residues From...''' to Edit menu or Actions (wrapper around Alter command)&lt;br /&gt;
:: yea ([[User:Sheehanj|Sheehanj]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Difficult C-level Code Refactoring Ideas ==&lt;br /&gt;
&lt;br /&gt;
* Assemble a test suite which thoroughly exercises the existing code (a prerequisite to major refactoring).&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Catch &amp;amp; handle memory-allocation failures gracefully (instead of crashing).&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Replace PyMOL's memory management &amp;amp; custom containers with a simple runtime object model.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Separate the View and the Controllers from the Model so that they can all run asynchronously (on multiple cores).&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Enable generalized undo of changes made to the Model.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]&amp;quot;[[User:Vcpmartin|Vcpmartin]], [[User:Lucajovine|Luca Jovine]]&amp;quot;, [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Clean up the internal matrix handling code.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Ideas Involving Proprietary APIs ==&lt;br /&gt;
&lt;br /&gt;
Since these involve closed-source APIs and infrastructure, they aren't suitable for open-source development efforts.  However, such requests are noted here for the sake of complete coverage.&lt;br /&gt;
&lt;br /&gt;
* Create a Windows port with &amp;quot;native&amp;quot; look &amp;amp; feel. &amp;lt;- Could this be done in PyQT or PyGTK?. Then it would look &amp;quot;native&amp;quot;, but be cross-platform and not proprietary.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Integrate directly via Mathematica via MathLink.&lt;br /&gt;
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])&lt;br /&gt;
* Further enhance JyMOL (Java-JNI/wrapped PyMOL)&lt;br /&gt;
:: yea ([[User:Inchoate|Tree]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Integrate with Matlab.&lt;br /&gt;
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])&lt;br /&gt;
* Quicklook Plugin on the Mac&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== More Ideas (Please add your own!) ==&lt;br /&gt;
* [http://molviz.cs.toronto.edu/molviz MolViz] is a project to incorporate head tracking input into [http://pymol.sourceforge.net/ PyMol]. This is accomplished through a [[ImmersiveViz]] script written in Python to control the molecule's position using the existing [http://www.pymolwiki.org/index.php/Category:Commands PyMol API]. Related projects would include:&lt;br /&gt;
** Improving the existing [[ImmersiveViz]] PyMol plugin for more precise control of the environment.&lt;br /&gt;
** Developing new input drivers for the Wiimote form of control. This would require some bluetooth hacking.&lt;br /&gt;
** Implementing some other forms of input for head tracking, such as fisheye head tracking, IR webcam tracking, etc (refer to the end of this [[http://www.youtube.com/watch?v=ncShaY4VSac video]] for a better description).&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Provide a 2D chemical depiction of the current 3D view.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
::: RDKit?&lt;br /&gt;
* Spreadsheet view with additional information (e.g. IC50's).&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Create additional documentation, screen casts, &amp;amp; tutorials.&lt;br /&gt;
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)&lt;br /&gt;
* Export 3D PDF images.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* &amp;lt;strike&amp;gt;Add extra &amp;quot;Single Word Selectors&amp;quot; like &amp;quot;nucleic&amp;quot;, &amp;quot;protein&amp;quot;, &amp;quot;water&amp;quot;, &amp;quot;ions&amp;quot;, &amp;quot;backbone&amp;quot; (for nucleic acids or proteins), &amp;quot;mainchain&amp;quot;, &amp;quot;sidechain&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Add functionality that allows you to select atoms based on their location (i.e. select (x_coordinate &amp;lt; 10) and (z_coordinate &amp;gt; 0))&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* set pdb_mirror option to use PDB mirrors other than RCSB for fetching structures (PDBe, PDBj); the EBI mirror is much faster from Europe for example.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]]) / nay (0)&lt;br /&gt;
* have the ability to link the TK console to the viewer so that users don't have to constantly alt+tab between what they want&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* have the ability to disable typing in the viewer and automatically type in the TK console (I like being able to cut/paste/home/end)&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* I see a lot of &amp;quot;can pymol do this&amp;quot; threads - any ideas of a good UI for a page of &amp;quot;things PyMOL can do?&amp;quot;&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* make an option where I can turn on a coordinate grid - perhaps an object that is a cuboid grid around any object in the view so I can still alter how it's rendered?&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* iPhone / Nexus One app(s)&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* single-color bonds between nonidentical or any spherical atoms colored specifically&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* double bonds as two parallel cylinders&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* export scenes as [http://www.khronos.org/webgl/ WebGL] / Could make mobile apps, presentation plugins obsolete&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* export images in vector format&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]]) / nay (0)&lt;br /&gt;
* Keynote plugin&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Electron density contour sliders&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Automatic electron density map generation from PDB mmcif files or user-supplied MTZ files&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]], [[User:Johnm|Johnm]]) / nay (0)&lt;br /&gt;
* Display of crystallographic symmetry and NCS axes, with possibility of showing symbols indicating what kind of axes they are&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Automatic symmetry expansion to show overall crystal packing; automatic generation of scenes showing crystal packing interface details&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Ideas&amp;diff=11836</id>
		<title>Ideas</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Ideas&amp;diff=11836"/>
		<updated>2010-01-24T19:54:38Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Ideas for PyMOL Development ===&lt;br /&gt;
&lt;br /&gt;
This page was originally developed for the 2008 Google Summer of Code competition, but seeing as PyMOL wasn't selected, this page can instead serve as a resource for ongoing PyMOL development efforts.&lt;br /&gt;
&lt;br /&gt;
== Where to Start ==&lt;br /&gt;
&lt;br /&gt;
Always start with Python and only delve down into the C code when absolutely necessary.  Although PyMOL is mostly a C-based application, much of the that code is opaque, fragile, and unforgiving. Although C code refactoring is an important project goal, such work may not be ideal since once mistake could potentially to destabilize the entire platform. &lt;br /&gt;
&lt;br /&gt;
Fortunately, the Python interpreter and the PyMOL command and selection languages make it possible to extend PyMOL safely and quickly.  Even when performance is critical, Python should be the interface between external C, C++, and Java code and PyMOL's internal C data structures.&lt;br /&gt;
&lt;br /&gt;
== Choosing a Topic ==&lt;br /&gt;
&lt;br /&gt;
The best open-source code is usually written by an end-users attempting to meet their own pressing needs.  So if you have already have a specific need which relates to PyMOL, then we strongly encourage you to follow up on that first!&lt;br /&gt;
&lt;br /&gt;
If you are looking for ideas,  then try to seek out enhancements and/or integrations that will impact the largest potential user base.  For example, imagine what new things might be useful to virtually all medicinal chemists, all structural biologists, all movie-makers, all paper-writers, and so forth.&lt;br /&gt;
&lt;br /&gt;
The ideas below are organized by category.  Right now, integration with other open-source projects seems like the approach most likely to yield significant benefit, so those ideas are first.&lt;br /&gt;
&lt;br /&gt;
== Integration Ideas (Linking Out to Useful Open-Source Tools) ==&lt;br /&gt;
&lt;br /&gt;
In most cases, depending on the need, integration can be accomplished through standalone Python scripts, through new PyMOL commands, through PyMOL Wizards, or via Tkinter plugins.&lt;br /&gt;
&lt;br /&gt;
* APBS (electrostatics calculations):  Improve the existing plugin. Michael Lerner is currently leading this effort.  See [[APBS]]&lt;br /&gt;
:: yea ([[User:Inchoate|Tree]] [[User:Jedgold|Jedgold]]&amp;quot;[[User:Vcpmartin|Vcpmartin]]&amp;quot;) / nay (0)&lt;br /&gt;
* RDKit (cheminformatics, depiction, UFF cleanup, etc.):  Lots of potential here, however C++ coding may be necessary for more advanced integration tasks. [http://www.rdkit.org RDKit home]&lt;br /&gt;
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)&lt;br /&gt;
* GIMP (image manipulation):  Streamline &amp;amp; document the process of exporting images from PyMOL into GIMP and preparing them for submission to scientific Journals.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Jmol (publishing visualizations inside of web pages): Liason between PyMOL &amp;amp; Jmol projects to develop a shared molecular visualization data model compatible with both applications.&lt;br /&gt;
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Firefox (plugin): Develop an PyMOL plugin compatible with Firefox.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* MMTK (molecular mechanics -- Python/flexible):  Develop the ability to round-trip molecular systems from PyMOL, into MMTK, and back.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* GROMACS (molecular mechanics -- C/fast) - Maybe some ideas can be shared with this guy. [http://www.kde-apps.org/content/show.php/Gromacs+GUI+?content=47665 Gromacs GUI]&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]] [[User:Mglerner|Michael Lerner]]) / nay (0)&lt;br /&gt;
* OpenOffice (escape Microsoft hegemony): Develop an PyMOL plugin.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* IPython integration (interactive shell): a robust alternative to the PyMOL command line?&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* R (statistics): PyMOL a 3D viewer environment for visualizating &amp;amp; manipulating large statistical data sets?&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
&lt;br /&gt;
Are there other key open-source packages we might specifically target for integration with PyMOL, either through GSoC or beyond?&lt;br /&gt;
&lt;br /&gt;
== High-Level Enhancement Ideas (Mostly Python-oriented) ==&lt;br /&gt;
&lt;br /&gt;
* Work on [[#More Ideas (Please add your own!)| MolViz]]&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop new plugins which automate routine tasks.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Improve the Python API documentation.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Flesh out the new &amp;quot;from pymol2 import PyMOL&amp;quot; instance-based PyMOL API.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop alternate Tkinter &amp;quot;skins&amp;quot; (for custom OEM-like applications).&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop a Tkinter/TOGL widget which holds a PyMOL viewer instance.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Develop a PyQt widget which holds a PyMOL viewer instance.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Create a plugin-manager GUI in the style of Firefox, Rythmbox, Gedit, Eclipse. A GUI where it is easy to turn off/on plugins, configure them and see help-contents for them. Maybe also some way to paste a url to install a new Plugin.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Add a plugin for a GUI window with the same functionality as the &amp;quot;Control Panel&amp;quot; window in SwissPDB Viewer.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Extend and modify the PyMOL command language so as to be compatible with existing RasMol and/or Jmol scripts.&lt;br /&gt;
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Enhance the Mutagenesis Wizard in order to support Nucleic acids and/or Sugars.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Low-Level Enhancement Ideas (Mostly C-oriented) ==&lt;br /&gt;
&lt;br /&gt;
* Enable editing of displayed sequence alignments.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]], [[User:Aschreyer|Aschreyer]], [[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
::: Would this then feed back to the structural alignment? [[User:Jedgold|Jedgold]]&lt;br /&gt;
* Add multi-line textual annotations&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Support additional annotation object including: arrow, lines, and blobs.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Add display of secondary structure into the sequence viewer.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Enable per-object Z clipping (especially in the ray tracer)&lt;br /&gt;
:: yea ([[User:Gregori|Gregori]], [[User:Xevi|Xevi]], [[User:Johnm|Johnm]]) / nay (0)&lt;br /&gt;
::: I would go a step further with fully customizable selection-based clipping planes (XYZ, color and transparency) ([[User:Gregori|Gregori]])&lt;br /&gt;
* Highlight H-bonds, salt bridges, Pi-stacking, Pi-cations, etc.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Build in a simple forcefield and energy minimizer suitable for use with Mutagenesis.&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Incorporate a suite of standard NMR visualizations (restraint violations, per-residue RMS, etc.)&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]&amp;quot;[[User:Vcpmartin|Vcpmartin]]&amp;quot;) / nay (0)&lt;br /&gt;
* Enumeration and display of low-energy conformers.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]]) / nay (0)&lt;br /&gt;
::: This could be done by integrating RDKit, I think. [[User:Aschreyer|Aschreyer]]&lt;br /&gt;
* Automated structure grafting (poor-man's homology modeling).&lt;br /&gt;
:: yea (0) / nay ([[User:Jedgold|Jedgold]], [[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
::: Perhaps a plugin to Modeller instead? ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]])&lt;br /&gt;
* Import of alignment files.&lt;br /&gt;
:: yea ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Implement IMD (Interactive Molecular Dynamics) Interface, see http://www.ks.uiuc.edu/Research/vmd/imd/&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Add buttons for '''Set ChainID''' and '''Renumber Residues From...''' to Edit menu or Actions (wrapper around Alter command)&lt;br /&gt;
:: yea ([[User:Sheehanj|Sheehanj]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Difficult C-level Code Refactoring Ideas ==&lt;br /&gt;
&lt;br /&gt;
* Assemble a test suite which thoroughly exercises the existing code (a prerequisite to major refactoring).&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Catch &amp;amp; handle memory-allocation failures gracefully (instead of crashing).&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Replace PyMOL's memory management &amp;amp; custom containers with a simple runtime object model.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Separate the View and the Controllers from the Model so that they can all run asynchronously (on multiple cores).&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* Enable generalized undo of changes made to the Model.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]&amp;quot;[[User:Vcpmartin|Vcpmartin]], [[User:Lucajovine|Luca Jovine]]&amp;quot;, [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Clean up the internal matrix handling code.&lt;br /&gt;
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
&lt;br /&gt;
== Ideas Involving Proprietary APIs ==&lt;br /&gt;
&lt;br /&gt;
Since these involve closed-source APIs and infrastructure, they aren't suitable for open-source development efforts.  However, such requests are noted here for the sake of complete coverage.&lt;br /&gt;
&lt;br /&gt;
* Create a Windows port with &amp;quot;native&amp;quot; look &amp;amp; feel. &amp;lt;- Could this be done in PyQT or PyGTK?. Then it would look &amp;quot;native&amp;quot;, but be cross-platform and not proprietary.&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Integrate directly via Mathematica via MathLink.&lt;br /&gt;
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])&lt;br /&gt;
* Further enhance JyMOL (Java-JNI/wrapped PyMOL)&lt;br /&gt;
:: yea ([[User:Inchoate|Tree]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* Integrate with Matlab.&lt;br /&gt;
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])&lt;br /&gt;
&lt;br /&gt;
== More Ideas (Please add your own!) ==&lt;br /&gt;
* [http://molviz.cs.toronto.edu/molviz MolViz] is a project to incorporate head tracking input into [http://pymol.sourceforge.net/ PyMol]. This is accomplished through a [[ImmersiveViz]] script written in Python to control the molecule's position using the existing [http://www.pymolwiki.org/index.php/Category:Commands PyMol API]. Related projects would include:&lt;br /&gt;
** Improving the existing [[ImmersiveViz]] PyMol plugin for more precise control of the environment.&lt;br /&gt;
** Developing new input drivers for the Wiimote form of control. This would require some bluetooth hacking.&lt;br /&gt;
** Implementing some other forms of input for head tracking, such as fisheye head tracking, IR webcam tracking, etc (refer to the end of this [[http://www.youtube.com/watch?v=ncShaY4VSac video]] for a better description).&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Provide a 2D chemical depiction of the current 3D view.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
::: RDKit?&lt;br /&gt;
* Spreadsheet view with additional information (e.g. IC50's).&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* Create additional documentation, screen casts, &amp;amp; tutorials.&lt;br /&gt;
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)&lt;br /&gt;
* Export 3D PDF images.&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])&lt;br /&gt;
* &amp;lt;strike&amp;gt;Add extra &amp;quot;Single Word Selectors&amp;quot; like &amp;quot;nucleic&amp;quot;, &amp;quot;protein&amp;quot;, &amp;quot;water&amp;quot;, &amp;quot;ions&amp;quot;, &amp;quot;backbone&amp;quot; (for nucleic acids or proteins), &amp;quot;mainchain&amp;quot;, &amp;quot;sidechain&amp;quot;&amp;lt;/strike&amp;gt;&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* Add functionality that allows you to select atoms based on their location (i.e. select (x_coordinate &amp;lt; 10) and (z_coordinate &amp;gt; 0))&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* set pdb_mirror option to use PDB mirrors other than RCSB for fetching structures (PDBe, PDBj); the EBI mirror is much faster from Europe for example.&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]]) / nay (0)&lt;br /&gt;
* have the ability to link the TK console to the viewer so that users don't have to constantly alt+tab between what they want&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* have the ability to disable typing in the viewer and automatically type in the TK console (I like being able to cut/paste/home/end)&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* I see a lot of &amp;quot;can pymol do this&amp;quot; threads - any ideas of a good UI for a page of &amp;quot;things PyMOL can do?&amp;quot;&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* make an option where I can turn on a coordinate grid - perhaps an object that is a cuboid grid around any object in the view so I can still alter how it's rendered?&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* iPhone / Nexus One app(s)&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* single-color bonds between nonidentical or any spherical atoms colored specifically&lt;br /&gt;
:: yea (0) / nay (0)&lt;br /&gt;
* double bonds as two parallel cylinders&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)&lt;br /&gt;
* export scenes as [http://www.khronos.org/webgl/ WebGL] / Could make mobile apps, presentation plugins obsolete&lt;br /&gt;
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)&lt;br /&gt;
* export images in vector format&lt;br /&gt;
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]]) / nay (0)&lt;br /&gt;
* Keynote plugin&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Electron density contour sliders&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Automatic electron density map generation from PDB mmcif files or user-supplied MTZ files&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]], [[User:Johnm|Johnm]]) / nay (0)&lt;br /&gt;
* Display of crystallographic symmetry and NCS axes, with possibility of showing symbols indicating what kind of axes they are&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;br /&gt;
* Automatic symmetry expansion to show overall crystal packing; automatic generation of scenes showing crystal packing interface details&lt;br /&gt;
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Plugins_Tutorial&amp;diff=13034</id>
		<title>Plugins Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Plugins_Tutorial&amp;diff=13034"/>
		<updated>2008-07-29T17:21:45Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: mediawiki formatted the code with a space on the left side, which makes copying and pasting the code annoying&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Learn By Example==&lt;br /&gt;
This tutorial is a more sophisticated version of the [[PDB Loader Service]] plugin that is bundled with PyMol.  It is a relatively simple plugin, but should prove to be a good starting point for developing new plugins.&lt;br /&gt;
&lt;br /&gt;
===Registering your Plugin===&lt;br /&gt;
First you must add your plugin to the ''Plugins'' menu.  This is most easily done in the ''__init__'' method of your plugin.  A callback, fetchPDBDialog, is added.  It is passed a reference to the main Tk app.  It will need this in order to create new content in the main Tkinter loop.  It is not strictly required in this example, but is needed in more complex interfaces.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def __init__(self):&lt;br /&gt;
    self.menuBar.addmenuitem('Plugin', 'command',&lt;br /&gt;
                             'PDB Loader Service',&lt;br /&gt;
                             label = 'PDB Loader Service',&lt;br /&gt;
                             command = lambda s=self : fetchPDBDialog(s))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Adding Functionality===&lt;br /&gt;
For this example we are going to dynamically download and load a pdb structure into the pymol interface.  Here is a simple method which does that given a pdbCode.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def remote(pdbCode):&lt;br /&gt;
    pdbCode = pdbCode.upper()&lt;br /&gt;
    try:&lt;br /&gt;
       pdbFile = urllib2.urlopen('&amp;lt;nowiki&amp;gt;http://www.rcsb.org/pdb/cgi/export.cgi/&amp;lt;/nowiki&amp;gt;' +&lt;br /&gt;
                                 pdbCode + '.pdb.gz?format=PDB&amp;amp;pdbId=' +&lt;br /&gt;
                                 pdbCode + '&amp;amp;compression=gz')&lt;br /&gt;
       cmd.read_pdbstr(zlib.decompress(pdbFile.read()[22:], -zlib.MAX_WBITS), pdbCode)&lt;br /&gt;
    except:&lt;br /&gt;
       print &amp;quot;Unexpected error:&amp;quot;, sys.exc_info()[0]&lt;br /&gt;
       tkMessageBox.showerror('Invalid Code',&lt;br /&gt;
                              'You entered an invalid pdb code:' + pdbCode)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating the Interface===&lt;br /&gt;
Now we need to write the callback method, ''fetchPDBDialog'', which creates the interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 def fetchPDBDialog(app):&lt;br /&gt;
    pdbCode = tkSimpleDialog.askstring('PDB Loader Service',&lt;br /&gt;
                                       'Please enter a 4-digit pdb code:',&lt;br /&gt;
                                       parent=app.root)&lt;br /&gt;
    remote(pdbCode)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pretty simple!  As of now you have a fully functional plugin that will prompt the user for a pdb code, download it from [http://www.rcsb.org/pdb/ RCSB], and load it into the PyMol interface.&lt;br /&gt;
&lt;br /&gt;
===Extending Plugins to the Command Line===&lt;br /&gt;
Opening the dialog can be tedious, so let's add a command line callback to make use of this new functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 cmd.extend('remote', remote)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can type ''remote 1di9'', for example, to load the the corresponding pdb.&lt;br /&gt;
&lt;br /&gt;
==Full Source==&lt;br /&gt;
Here is the complete example.  You can save this file and load it into PyMol with the ''Plugin -&amp;gt; Install Plugin...'' menu item.  I also include the sample license that Warren provides for plugin developers. It is optional, of course.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Copyright Notice&lt;br /&gt;
# ================&lt;br /&gt;
# &lt;br /&gt;
# The PyMOL Plugin source code in this file is copyrighted, but you can&lt;br /&gt;
# freely use and copy it as long as you don't change or remove any of&lt;br /&gt;
# the copyright notices.&lt;br /&gt;
# &lt;br /&gt;
# ----------------------------------------------------------------------&lt;br /&gt;
# This PyMOL Plugin is Copyright (C) 2004 by Charles Moad &amp;lt;cmoad@indiana.edu&amp;gt;&lt;br /&gt;
# &lt;br /&gt;
#                        All Rights Reserved&lt;br /&gt;
# &lt;br /&gt;
# Permission to use, copy, modify, distribute, and distribute modified&lt;br /&gt;
# versions of this software and its documentation for any purpose and&lt;br /&gt;
# without fee is hereby granted, provided that the above copyright&lt;br /&gt;
# notice appear in all copies and that both the copyright notice and&lt;br /&gt;
# this permission notice appear in supporting documentation, and that&lt;br /&gt;
# the name(s) of the author(s) not be used in advertising or publicity&lt;br /&gt;
# pertaining to distribution of the software without specific, written&lt;br /&gt;
# prior permission.&lt;br /&gt;
# &lt;br /&gt;
# THE AUTHOR(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,&lt;br /&gt;
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN&lt;br /&gt;
# NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR&lt;br /&gt;
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF&lt;br /&gt;
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR&lt;br /&gt;
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR&lt;br /&gt;
# PERFORMANCE OF THIS SOFTWARE.&lt;br /&gt;
# ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
import tkSimpleDialog&lt;br /&gt;
import tkMessageBox&lt;br /&gt;
from pymol import cmd&lt;br /&gt;
import sys, urllib2, zlib&lt;br /&gt;
&lt;br /&gt;
def __init__(self):&lt;br /&gt;
   self.menuBar.addmenuitem('Plugin', 'command',&lt;br /&gt;
                            'PDB Loader Service',&lt;br /&gt;
                            label = 'PDB Loader Service',&lt;br /&gt;
                            command = lambda s=self : fetchPDBDialog(s))&lt;br /&gt;
&lt;br /&gt;
def remote(pdbCode):&lt;br /&gt;
   pdbCode = pdbCode.upper()&lt;br /&gt;
   try:&lt;br /&gt;
      pdbFile = urllib2.urlopen('http://www.rcsb.org/pdb/cgi/export.cgi/' +&lt;br /&gt;
                                pdbCode + '.pdb.gz?format=PDB&amp;amp;pdbId=' +&lt;br /&gt;
                                pdbCode + '&amp;amp;compression=gz')&lt;br /&gt;
      cmd.read_pdbstr(zlib.decompress(pdbFile.read()[22:], -zlib.MAX_WBITS), pdbCode)&lt;br /&gt;
   except:&lt;br /&gt;
      print &amp;quot;Unexpected error:&amp;quot;, sys.exc_info()[0]&lt;br /&gt;
      tkMessageBox.showerror('Invalid Code',&lt;br /&gt;
                             'You entered an invalid pdb code:' + pdbCode)&lt;br /&gt;
&lt;br /&gt;
def fetchPDBDialog(app):&lt;br /&gt;
   pdbCode = tkSimpleDialog.askstring('PDB Loader Service',&lt;br /&gt;
                                      'Please enter a 4-digit pdb code:',&lt;br /&gt;
                                      parent=app.root)&lt;br /&gt;
   &lt;br /&gt;
   remote(pdbCode)&lt;br /&gt;
&lt;br /&gt;
cmd.extend('remote', remote)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Developers|Plugins_Tutorial]]&lt;br /&gt;
[[Category:Plugins|Plugins_Tutorial]]&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Label&amp;diff=13829</id>
		<title>Label</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Label&amp;diff=13829"/>
		<updated>2008-07-11T22:27:29Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: /* UTF8 Fonts */ fix typo of setting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Label_pre.png|thumb|PyMol Labels]]&lt;br /&gt;
===DESCRIPTION===&lt;br /&gt;
'''label''' allows one to configure the appearance of text labels for PyMOL objects.  It, labels one or more atoms properties over a selection using the python evaluator with a separate name space for each atom.  The symbols defined in the name space are:&lt;br /&gt;
* '''name''', the atom name&lt;br /&gt;
* '''resn''', the residue name&lt;br /&gt;
*'''resi''', the residue number/identifier&lt;br /&gt;
*'''chain''', the chain name&lt;br /&gt;
*'''q''',&lt;br /&gt;
*'''b''', the occupancy/b-factor&lt;br /&gt;
*'''segi''', the segment identifier&lt;br /&gt;
*'''type''' ''(ATOM,HETATM)'', the type of atom&lt;br /&gt;
*'''formal_charge''', the formal charge&lt;br /&gt;
*'''partial_charge''', the partial charge&lt;br /&gt;
*'''numeric_type''', the numeric type&lt;br /&gt;
*'''text_type''', the text type&lt;br /&gt;
&lt;br /&gt;
All strings in the expression must be explicitly quoted.  This operation typically takes several seconds per thousand atoms altered.  To clear labels, simply omit the expression or set it to ''.&lt;br /&gt;
&lt;br /&gt;
===USAGE===&lt;br /&gt;
 label (selection),expression&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===SETTINGS===&lt;br /&gt;
====FONT====&lt;br /&gt;
There are 10 different scalable fonts.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;set label_font_id, number&amp;lt;/source&amp;gt;&lt;br /&gt;
where number is 5 through 14.&lt;br /&gt;
=====UTF8 Fonts=====&lt;br /&gt;
&lt;br /&gt;
[[Image:New_fonts.jpeg|thumb|New fonts in PyMol.  Notice the alpha and beta characters.]]&lt;br /&gt;
&lt;br /&gt;
Newer versions support UTF8 fonts; use '''label_font_id''' from above to 15 or 16.  The good news about the UTF8 fonts is that they support the alpha and beta characters. (See image.)&lt;br /&gt;
&lt;br /&gt;
Here's some example code for the image at right:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# roman&lt;br /&gt;
set label_font_id, 15&lt;br /&gt;
set label_shadow_mode, 3&lt;br /&gt;
label 5/CA, &amp;quot;\316\261-Helix&amp;quot;&lt;br /&gt;
label 10/CA, &amp;quot;\316\262-Sheet&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# italic&lt;br /&gt;
set label_font_id, 16&lt;br /&gt;
&lt;br /&gt;
# make bigger&lt;br /&gt;
set label_size, 50&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====SIZE====&lt;br /&gt;
The font size can be adjusted&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;set label_size, number&amp;lt;/source&amp;gt;&lt;br /&gt;
where number is the point size (or -number for Angstroms)&lt;br /&gt;
&lt;br /&gt;
====COLOR====&lt;br /&gt;
Set a label's color by&lt;br /&gt;
 set label_color, color&lt;br /&gt;
where color is a valid PyMol color.&lt;br /&gt;
&lt;br /&gt;
====EXPRESSION====&lt;br /&gt;
To set what the label reads (see above)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;label selection, expression&amp;lt;/source&amp;gt;&lt;br /&gt;
For example&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
 label all, name&lt;br /&gt;
 label resi 10, b&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====POSITION====&lt;br /&gt;
To position labels&lt;br /&gt;
 edit_mode&lt;br /&gt;
then&lt;br /&gt;
ctrl-middle-click-and-drag to position the label in space. (On Windows systems this appears to be shift-left-click-and-drag, presumably because those mice lack a true middle button.)&lt;br /&gt;
&lt;br /&gt;
ctrl-shift-left-click-and-drag alters a label's z-plane. (Windows only? This may use the middle button, rather than shift-left, under *NIX / 3-button mice systems.)&lt;br /&gt;
&lt;br /&gt;
===EXAMPLES===&lt;br /&gt;
 label (chain A),chain&lt;br /&gt;
 label (n;ca),&amp;quot;%s-%s&amp;quot; % (resn,resi)&lt;br /&gt;
 label (resi 200),&amp;quot;%1.3f&amp;quot; % partial_charge&lt;br /&gt;
&lt;br /&gt;
The following image was created with&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
label (resi 200),&amp;quot;%1.3f&amp;quot; % b&lt;br /&gt;
set label_font_id, 10&lt;br /&gt;
set label_size, 10&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
and finally, some labels were moved around in '''edit_mode'''.&lt;br /&gt;
[[Image:Label_ex.png|thumb|Labels.]]&lt;br /&gt;
&lt;br /&gt;
===Users Comments===&lt;br /&gt;
====Labels Using ID Numbers====&lt;br /&gt;
The following commnent,&lt;br /&gt;
 label SELECTION, &amp;quot; %s&amp;quot; % ID &lt;br /&gt;
labels the SELECTION with atom ID numbers.&lt;br /&gt;
&lt;br /&gt;
You can make more complicated selections/lables such as&lt;br /&gt;
 label SELECTION, &amp;quot; %s:%s %s&amp;quot; % (resi, resn, name)&lt;br /&gt;
which will give you something like &amp;quot;GLU:139 CG&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====Labels Using One Letter Abbreviations====&lt;br /&gt;
* First, Add this to your $HOME/.pymolrc  file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# start $HOME/.pymolrc modification&lt;br /&gt;
one_letter ={'VAL':'V', 'ILE':'I', 'LEU':'L', 'GLU':'E', 'GLN':'Q', \&lt;br /&gt;
'ASP':'D', 'ASN':'N', 'HIS':'H', 'TRP':'W', 'PHE':'F', 'TYR':'Y',    \&lt;br /&gt;
'ARG':'R', 'LYS':'K', 'SER':'S', 'THR':'T', 'MET':'M', 'ALA':'A',    \&lt;br /&gt;
'GLY':'G', 'PRO':'P', 'CYS':'C'}&lt;br /&gt;
# end modification&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*. Second, instead of:&lt;br /&gt;
 label n. ca, resn&lt;br /&gt;
use:&lt;br /&gt;
 label n. ca, one_letter[resn]&lt;br /&gt;
&lt;br /&gt;
[[Category:Commands|label]]&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
	<entry>
		<id>https://wiki.pymol.org/index.php?title=Gallery&amp;diff=5918</id>
		<title>Gallery</title>
		<link rel="alternate" type="text/html" href="https://wiki.pymol.org/index.php?title=Gallery&amp;diff=5918"/>
		<updated>2008-06-08T03:52:25Z</updated>

		<summary type="html">&lt;p&gt;Cowsandmilk: Link Grid Mode to the correct page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| align=&amp;quot;center&amp;quot;&lt;br /&gt;
|+ style=&amp;quot;width: 90%; font-size:190%; font-weight: bold; color:#038; text-align:center; padding: 5px; margin-bottom: 15px; colspan:4&amp;quot; | PyMOLWiki Gallery&lt;br /&gt;
|- style=&amp;quot;text-align:center; font-weight: bold; font-size:120%; color:#333;&amp;quot;&lt;br /&gt;
| Cool PyMOL-generated Images and their Scripts.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;''[[Talk:Gallery#Adding|Add Your Own]]''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{GalleryImage&lt;br /&gt;
|image=Gm2.png|size=200px|title=Grid Mode|description=This image shows [[Grid mode|Grid Mode]] in action.&lt;br /&gt;
|cmdString=&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
fetch 1cll 1sra 1ggz 5pnt 1rlw 1cdy;&lt;br /&gt;
set grid_mode&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|seeAlso=&lt;br /&gt;
*[[Fetch]]&lt;br /&gt;
*[[Set]]&lt;br /&gt;
*[[grid_mode]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{GalleryImage&lt;br /&gt;
|image=Fov60.png|size=200px|title=Cool Perspective|description=This image shows a perspective through [[Field_Of_View]].&lt;br /&gt;
|cmdString=&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
load prot.pdb;&lt;br /&gt;
zoom i. 46-49 and n. CA&lt;br /&gt;
set field_of_view, 60&lt;br /&gt;
ray&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|seeAlso=&lt;br /&gt;
*[[Load]]&lt;br /&gt;
*[[Ray]]&lt;br /&gt;
*[[Zoom]]&lt;br /&gt;
*[[Set]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{GalleryImage&lt;br /&gt;
|image=Pocket.png|size=200px|title=Representing a binding pocket|description=This image shows a nice way to show binding surfaces&lt;br /&gt;
|cmdString=&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
load $TUT/1hpv.pdb, tmp&lt;br /&gt;
extract lig, organic&lt;br /&gt;
extract prot, polymer&lt;br /&gt;
delete tmp&lt;br /&gt;
&lt;br /&gt;
set surface_carve_cutoff, 4.5&lt;br /&gt;
set surface_carve_selection, lig&lt;br /&gt;
set surface_carve_normal_cutoff, -0.1&lt;br /&gt;
&lt;br /&gt;
show surface, prot within 8 of lig&lt;br /&gt;
set two_sided_lighting&lt;br /&gt;
set transparency, 0.5&lt;br /&gt;
show sticks, lig&lt;br /&gt;
orient lig&lt;br /&gt;
&lt;br /&gt;
set surface_color, white&lt;br /&gt;
set surface_type, 2  # mesh&lt;br /&gt;
unset ray_shadows&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|seeAlso=&lt;br /&gt;
*[[extract]]&lt;br /&gt;
*[[delete]]&lt;br /&gt;
*[[show]]&lt;br /&gt;
*[[set]]&lt;br /&gt;
*[[orient]]&lt;br /&gt;
*[[surface_carve_cutoff]]&lt;br /&gt;
*[[surface_carve_selection]]&lt;br /&gt;
*[[surface_carve_normal_cutoff]]&lt;br /&gt;
*[[surface_color]]&lt;br /&gt;
*[[surface_type]]&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Cowsandmilk</name></author>
	</entry>
</feed>