https://pymolwiki.org/api.php?action=feedcontributions&user=Cowsandmilk&feedformat=atomPyMOLWiki - User contributions [en]2024-03-28T14:11:29ZUser contributionsMediaWiki 1.35.7https://pymolwiki.org/index.php?title=Bg_gradient&diff=10779Bg gradient2012-07-07T15:42:59Z<p>Cowsandmilk: </p>
<hr />
<div>Enable background gradients in the viewer window. (Ray trace in pymol 1.5+)<br />
<br />
[[Image:bg_grad.png|350px|set bg_gradient]]<br />
<br />
<br />
= Usage =<br />
<source lang="python"><br />
# enable<br />
<br />
set bg_gradient<br />
</source><br />
<br />
= See Also =<br />
[[bg_rgb_top]], [[bg_rgb_bottom]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Git_install_scripts&diff=10272Git install scripts2011-12-19T13:30:55Z<p>Cowsandmilk: </p>
<hr />
<div>== Manual download of scripts ==<br />
If you don't have the option or want't to install git on your system, then go to<br />
https://github.com/Pymol-Scripts/Pymol-script-repo<br />
Click the "ZIP" button, near the top left corner.<br />
Now unpack the files to a directory. For example:<br />
C:/Users/YOURNAME/Documents/Pymol-script-repo<br />
or<br />
/home/YOURNAME/Software/pymol<br />
<br />
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]<br />
<br />
== Git install instructions ==<br />
=== For Windows users ===<br />
# Install [http://code.google.com/p/msysgit/downloads/list?can=3&q=official+Git Git for Windows].<br />
Use following settings in options, [http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/ (You can read more here)].<br />
* Windows Explorer Integration -> Context Menu Entries -> Git Bash Here + Git GUI here<br />
* Run Git and included Unix tools from Windows Command prompts<br />
* Checkout Windows style, commit Unix-style endings<br />
<br />
# Navigate to: '''C:\Users\YOURNAME\Documents\pymol'''<br />
# Right click in folder -> Select: Git Gui -> Clone Existing Repository<br />
# Source Location: git://github.com/Pymol-Scripts/Pymol-script-repo.git<br />
# Target Directory: C:\\Users\\YOURNAME\\Documents\\pymol\Pymol-script-repo<br />
#: A backslash "\" 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 "\\" <br />
You now have all the scripts available in your directory.<br />
<br />
Add '''python.exe''' to your '''PATH''', so external .py scripts can be executed.<br><br />
Open control panel. Search for, and click: '''Edit environment variables for your account'''<br><br />
Add to end of variable PATH: ''';C:\Python27''' (Or other path to your python python.exe)<br><br />
Click start button, and open '''cmd.exe'''. Try starting python by writing: '''python'''<br />
<br />
=== For Linux users ===<br />
# Install git<br />
# Debian/Ubuntu/Mint<br />
sudo apt-get install git<br />
# Fedora<br />
su -c 'yum install git'<br />
# openSUSE<br />
sudo zypper in git<br />
<br />
# Navigate to desired folder: <br />
cd /home/YOURNAME/Software/pymol<br />
git clone git://github.com/Pymol-Scripts/Pymol-script-repo.git<br />
You now have all the scripts available in: /home/YOURNAME/Software/pymol/Pymol-script-repo<br />
<br />
== Adding Pymol-script-repo to PyMOL search path ==<br />
You now have to add the "Pymol-script-repo" directory to the PyMOL search path. <br />
<br />
The project also have automatically plugin installer: http://www.pymolwiki.org/index.php/plugindirectory <br><br />
This is activated with: '''import plugins'''. <br><br />
'''You have to remove old installations of plugins first, to get the automatic plugin installation to work.'''<br />
=== For Windows users ===<br />
# Open notepad<br />
# Write (Remember double backslashes)<br />
import sys,os<br />
sys.path.append('C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo')<br />
os.environ['PYMOL_GIT_MOD']='C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo\\modules'<br />
import plugins<br />
os.chdir('C:\\Users\\YOURNAME\\Documents\\pymol') # Your standard working dir<br />
Save under: '''C:\Users\YOURNAME\pymolrc.pym''' (Set: "Save as type" to "All files")<br />
<br />
=== For Linux users ===<br />
gedit ~/.pymolrc<br />
Write<br />
import sys,os<br />
sys.path.append('/home/YOU/Software/pymol/Pymol-script-repo')<br />
os.environ['PYMOL_GIT_MOD']='/home/YOU/Software/pymol/Pymol-script-repo/modules'<br />
import plugins<br />
os.chdir('/home/YOU/Software/pymol/') # Your standard working dir<br />
Save and exit<br />
<br />
== Test the Scripts ==<br />
Now start PyMOL, and test in PyMOL.<br />
print sys.path<br />
import colorbydisplacement<br />
help(colorbydisplacement)<br />
<br />
== Get latest changes to scripts ==<br />
If new scripts are available or changes have been made, then:<br />
=== For windows users ===<br />
# Navigate to '''C:\Users\YOURNAME\Documents\Pymol-script-repo'''<br />
# Right click in folder -> Select: Git Bash<br />
# Write in terminal<br />
git pull origin master<br />
<br />
=== For Ubuntu/Mint users ===<br />
# Navigate to '''/home/YOURNAME/Software/pymol/Pymol-script-repo'''<br />
# Write in terminal.<br />
git pull origin master<br />
<br />
= Do you want to contribute with a script? =<br />
Information how to contribute scripts to the repository. It's easy! <br><br />
http://www.pymolwiki.org/index.php/git_authors</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Git_install_scripts&diff=10271Git install scripts2011-12-19T13:28:29Z<p>Cowsandmilk: /* For Linux users */</p>
<hr />
<div>== Manual download of scripts ==<br />
If you don't have the option or want't to install git on your system, then go to<br />
https://github.com/Pymol-Scripts/Pymol-script-repo<br />
Click the "ZIP" button, near the top left corner.<br />
Now unpack the files to a directory. For example:<br />
C:/Users/YOURNAME/Documents/Pymol-script-repo<br />
or<br />
/home/YOURNAME/Software/pymol<br />
<br />
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]<br />
<br />
== Git install instructions ==<br />
=== For windows users ===<br />
# Install [http://code.google.com/p/msysgit/downloads/list?can=3&q=official+Git Git for Windows].<br />
Use following settings in options, [http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/ (You can read more here)].<br />
* Windows Explorer Integration -> Context Menu Entries -> Git Bash Here + Git GUI here<br />
* Run Git and included Unix tools from Windows Command prompts<br />
* Checkout Windows style, commit Unix-style endings<br />
<br />
# Navigate to: '''C:\Users\YOURNAME\Documents\pymol'''<br />
# Right click in folder -> Select: Git Gui -> Clone Existing Repository<br />
# Source Location: git://github.com/Pymol-Scripts/Pymol-script-repo.git<br />
# Target Directory: C:\\Users\\YOURNAME\\Documents\\pymol\Pymol-script-repo<br />
#: A backslash "\" 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 "\\" <br />
You now have all the scripts available in your directory.<br />
<br />
Add '''python.exe''' to your '''PATH''', so external .py scripts can be executed.<br><br />
Open control panel. Search for, and click: '''Edit environment variables for your account'''<br><br />
Add to end of variable PATH: ''';C:\Python27''' (Or other path to your python python.exe)<br><br />
Click start button, and open '''cmd.exe'''. Try starting python by writing: '''python'''<br />
<br />
=== For Linux users ===<br />
# Install git<br />
# Debian/Ubuntu/Mint<br />
sudo apt-get install git<br />
# Fedora<br />
su -c 'yum install git'<br />
# openSUSE<br />
sudo zypper in git<br />
<br />
# Navigate to desired folder: <br />
cd /home/YOURNAME/Software/pymol<br />
git clone git://github.com/Pymol-Scripts/Pymol-script-repo.git<br />
You now have all the scripts available in: /home/YOURNAME/Software/pymol/Pymol-script-repo<br />
<br />
== Adding Pymol-script-repo to PyMOL search path ==<br />
You now have to add the "Pymol-script-repo" directory to the PyMOL search path. <br />
<br />
The project also have automatically plugin installer: http://www.pymolwiki.org/index.php/plugindirectory <br><br />
This is activated with: '''import plugins'''. <br><br />
'''You have to remove old installations of plugins first, to get the automatic plugin installation to work.'''<br />
=== For windows users ===<br />
# Open notepad<br />
# Write (Remember double backslashes)<br />
import sys,os<br />
sys.path.append('C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo')<br />
os.environ['PYMOL_GIT_MOD']='C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo\\modules'<br />
import plugins<br />
os.chdir('C:\\Users\\YOURNAME\\Documents\\pymol') # Your standard working dir<br />
Save under: '''C:\Users\YOURNAME\pymolrc.pym''' (Set: "Save as type" to "All files")<br />
<br />
=== For Ubuntu/Mint users ===<br />
gedit ~/.pymolrc<br />
Write<br />
import sys,os<br />
sys.path.append('/home/YOU/Software/pymol/Pymol-script-repo')<br />
os.environ['PYMOL_GIT_MOD']='/home/YOU/Software/pymol/Pymol-script-repo/modules'<br />
import plugins<br />
os.chdir('/home/YOU/Software/pymol/') # Your standard working dir<br />
Save and exit<br />
<br />
== Test the Scripts ==<br />
Now start PyMOL, and test in PyMOL.<br />
print sys.path<br />
import colorbydisplacement<br />
help(colorbydisplacement)<br />
<br />
== Get latest changes to scripts ==<br />
If new scripts are available or changes have been made, then:<br />
=== For windows users ===<br />
# Navigate to '''C:\Users\YOURNAME\Documents\Pymol-script-repo'''<br />
# Right click in folder -> Select: Git Bash<br />
# Write in terminal<br />
git pull origin master<br />
<br />
=== For Ubuntu/Mint users ===<br />
# Navigate to '''/home/YOURNAME/Software/pymol/Pymol-script-repo'''<br />
# Write in terminal.<br />
git pull origin master<br />
<br />
= Do you want to contribute with a script? =<br />
Information how to contribute scripts to the repository. It's easy! <br><br />
http://www.pymolwiki.org/index.php/git_authors</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Git_install_scripts&diff=10270Git install scripts2011-12-19T13:27:39Z<p>Cowsandmilk: /* Git install instructions */</p>
<hr />
<div>== Manual download of scripts ==<br />
If you don't have the option or want't to install git on your system, then go to<br />
https://github.com/Pymol-Scripts/Pymol-script-repo<br />
Click the "ZIP" button, near the top left corner.<br />
Now unpack the files to a directory. For example:<br />
C:/Users/YOURNAME/Documents/Pymol-script-repo<br />
or<br />
/home/YOURNAME/Software/pymol<br />
<br />
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]<br />
<br />
== Git install instructions ==<br />
=== For windows users ===<br />
# Install [http://code.google.com/p/msysgit/downloads/list?can=3&q=official+Git Git for Windows].<br />
Use following settings in options, [http://www.geekgumbo.com/2010/04/09/installing-git-on-windows/ (You can read more here)].<br />
* Windows Explorer Integration -> Context Menu Entries -> Git Bash Here + Git GUI here<br />
* Run Git and included Unix tools from Windows Command prompts<br />
* Checkout Windows style, commit Unix-style endings<br />
<br />
# Navigate to: '''C:\Users\YOURNAME\Documents\pymol'''<br />
# Right click in folder -> Select: Git Gui -> Clone Existing Repository<br />
# Source Location: git://github.com/Pymol-Scripts/Pymol-script-repo.git<br />
# Target Directory: C:\\Users\\YOURNAME\\Documents\\pymol\Pymol-script-repo<br />
#: A backslash "\" 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 "\\" <br />
You now have all the scripts available in your directory.<br />
<br />
Add '''python.exe''' to your '''PATH''', so external .py scripts can be executed.<br><br />
Open control panel. Search for, and click: '''Edit environment variables for your account'''<br><br />
Add to end of variable PATH: ''';C:\Python27''' (Or other path to your python python.exe)<br><br />
Click start button, and open '''cmd.exe'''. Try starting python by writing: '''python'''<br />
<br />
=== For Linux users ===<br />
# Install git<br />
<source lang="bash"><br />
# Debian/Ubuntu/Mint<br />
sudo apt-get install git<br />
# Fedora<br />
su -c 'yum install git'<br />
# openSUSE<br />
sudo zypper in git<br />
</source><br />
# Navigate to desired folder: <br />
<source lang="bash"><br />
cd /home/YOURNAME/Software/pymol<br />
git clone git://github.com/Pymol-Scripts/Pymol-script-repo.git<br />
</source><br />
You now have all the scripts available in: /home/YOURNAME/Software/pymol/Pymol-script-repo<br />
<br />
== Adding Pymol-script-repo to PyMOL search path ==<br />
You now have to add the "Pymol-script-repo" directory to the PyMOL search path. <br />
<br />
The project also have automatically plugin installer: http://www.pymolwiki.org/index.php/plugindirectory <br><br />
This is activated with: '''import plugins'''. <br><br />
'''You have to remove old installations of plugins first, to get the automatic plugin installation to work.'''<br />
=== For windows users ===<br />
# Open notepad<br />
# Write (Remember double backslashes)<br />
import sys,os<br />
sys.path.append('C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo')<br />
os.environ['PYMOL_GIT_MOD']='C:\\Users\\YOURNAME\\Documents\\pymol\\Pymol-script-repo\\modules'<br />
import plugins<br />
os.chdir('C:\\Users\\YOURNAME\\Documents\\pymol') # Your standard working dir<br />
Save under: '''C:\Users\YOURNAME\pymolrc.pym''' (Set: "Save as type" to "All files")<br />
<br />
=== For Ubuntu/Mint users ===<br />
gedit ~/.pymolrc<br />
Write<br />
import sys,os<br />
sys.path.append('/home/YOU/Software/pymol/Pymol-script-repo')<br />
os.environ['PYMOL_GIT_MOD']='/home/YOU/Software/pymol/Pymol-script-repo/modules'<br />
import plugins<br />
os.chdir('/home/YOU/Software/pymol/') # Your standard working dir<br />
Save and exit<br />
<br />
== Test the Scripts ==<br />
Now start PyMOL, and test in PyMOL.<br />
print sys.path<br />
import colorbydisplacement<br />
help(colorbydisplacement)<br />
<br />
== Get latest changes to scripts ==<br />
If new scripts are available or changes have been made, then:<br />
=== For windows users ===<br />
# Navigate to '''C:\Users\YOURNAME\Documents\Pymol-script-repo'''<br />
# Right click in folder -> Select: Git Bash<br />
# Write in terminal<br />
git pull origin master<br />
<br />
=== For Ubuntu/Mint users ===<br />
# Navigate to '''/home/YOURNAME/Software/pymol/Pymol-script-repo'''<br />
# Write in terminal.<br />
git pull origin master<br />
<br />
= Do you want to contribute with a script? =<br />
Information how to contribute scripts to the repository. It's easy! <br><br />
http://www.pymolwiki.org/index.php/git_authors</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Linux_Install&diff=9774Linux Install2011-12-02T16:06:11Z<p>Cowsandmilk: /* Install from Source */</p>
<hr />
<div>This page describes how to install open-source PyMOL on Linux.<br />
<br />
== Install Distribution-specific binary Package ==<br />
<br />
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.<br />
<br />
Command line install examples for some popular distributions:<br />
<br />
<source lang="bash"><br />
# Debian/Ubuntu<br />
sudo apt-get install pymol<br />
<br />
# Fedora<br />
yum install pymol<br />
<br />
# Gentoo<br />
emerge -av pymol<br />
<br />
# openSUSE (12.1 and later)<br />
sudo zypper install pymol<br />
</source><br />
<br />
== Install from Source ==<br />
<br />
Installation from source gives you the latest version and is the generic way to install PyMOL.<br />
<br />
=== Requirements ===<br />
<br />
Libraries as well as development files (headers) of the following software is<br />
required:<br />
<br />
* [http://subversion.apache.org/ Subversion] to download the source code<br />
* [http://www.python.org/ Python] (with distutils)<br />
* [http://pmw.sf.net Pmw] (Python Megawidgets)<br />
* OpenGL driver (I use [http://www.nvidia.com/object/unix.html NVidia])<br />
* libpng<br />
* freetype<br />
<br />
On many Linux systems, one of the following commands installs all requirements:<br />
<br />
<source lang="bash"><br />
# Debian/Ubuntu/Mint11<br />
sudo apt-get install subversion build-essential python-dev python-pmw \<br />
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev<br />
<br />
# Fedora<br />
yum install subversion python-devel freeglut-devel freetype-devel tkinter python-pmw<br />
<br />
# Gentoo<br />
emerge -av dev-vcs/subversion dev-lang/python dev-python/pmw media-libs/glew \<br />
media-libs/freeglut media-libs/libpng media-libs/freetype<br />
<br />
# openSUSE<br />
sudo zypper install python-devel freeglut-devel gcc-c++ glew-devel libpng-devel python-pmw subversion<br />
</source><br />
<br />
=== Get latest Source from SVN ===<br />
<br />
This will download the latest source to '''/tmp/pymol''':<br />
<br />
<source lang="bash"><br />
cd /tmp<br />
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol pymol<br />
cd pymol<br />
</source><br />
<br />
=== Compile and install ===<br />
<br />
This will install PyMOL as normal user into '''/opt/pymol-svn'''. If you don't have write permissions to '''/opt''', change the <code>prefix</code> variable to something like '''$HOME/pymol-svn'''.<br />
<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
<br />
prefix=/opt/pymol-svn<br />
modules=$prefix/modules<br />
<br />
python setup.py build install \<br />
--home=$prefix \<br />
--install-purelib=$modules \<br />
--install-platlib=$modules<br />
<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
python setup2.py install<br />
install pymol $prefix/<br />
</source><br />
<br />
Now launch PyMOL like this (you may copy this launcher into your '''$PATH''',<br />
like to '''/usr/local/bin'''):<br />
<br />
<source lang="bash"><br />
/opt/pymol-svn/pymol<br />
</source><br />
<br />
== Problems ==<br />
<br />
* gcc-4.5 is broken for pymol install, use gcc-4.4 (Mint11 Linux, PyMOL 1.4.1, reported by [[User:Tlinnet]])<br />
<source lang="bash"><br />
sudo apt-get install build-essential gcc-4.4 g++-4.4<br />
export CC=/usr/bin/gcc-4.4<br />
</source><br />
<br />
* If you get an error message "ImportError: No module named Pmw" and lack half of the user interface, then run the additional command<br />
:<source lang="bash"><br />
python setup2.py install pmw<br />
</source><br />
<br />
:to install a copy of the Python MegaWidgets.<br />
<br />
== Ubuntu/Mint Compile and install with MPEG support ==<br />
Make a text file "installpymol.sh" and make it executable<br />
<source lang="bash"><br />
chmod u+x installpymol.sh<br />
</source><br />
<br />
Put this in the file, modify the first 3 lines<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
pymolsvn=/home/tlinnet/Software/pymol/svnpymol<br />
pymoldir=/home/tlinnet/Software/pymol<br />
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol<br />
<br />
###################################################<br />
[ -d $pymoldir ] || mkdir $pymoldir<br />
[ -d $pymolsvn ] || mkdir $pymolsvn<br />
[ -d $pymoldir/wikiscripts ] || mkdir $pymoldir/wikiscripts<br />
<br />
sudo apt-get install subversion build-essential python-dev python-pmw \<br />
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev<br />
<br />
# gcc 4.5 broken for install in ubuntu<br />
sudo apt-get install gcc-4.4 g++-4.4<br />
export CC=/usr/bin/gcc-4.4<br />
<br />
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol $pymolsvn<br />
<br />
modules=$pymoldir/modules<br />
cd $pymolsvn<br />
python setup.py build<br />
sudo python setup.py install<br />
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
sudo python setup2.py install<br />
install $pymolsvn/pymol $pymoldir/<br />
<br />
## To add a path/folder where you can put pymol wikiscripts<br />
t="'"<br />
echo "import sys" >> ~/.pymolrc<br />
echo "sys.path.append($t$pymoldir/wikiscripts$t)" >> ~/.pymolrc<br />
<br />
########## Setup freemol - for MPEG support ############<br />
[ -d $pymolsvn ] || mkdir $freemolsvn<br />
svn co svn://bioinformatics.org/svnroot/freemol/trunk $freemolsvn<br />
<br />
cd $freemolsvn/src/mpeg_encode<br />
export FREEMOL=$freemolsvn/freemol<br />
./configure<br />
make<br />
make install<br />
<br />
## Make a shortcut to export freemol and then execute pymol<br />
echo '#!/bin/bash' >> $pymoldir/pymolMPEG.sh<br />
echo "export FREEMOL=$freemolsvn/freemol" >> $pymoldir/pymolMPEG.sh<br />
echo "#$pymoldir/pymol" >> $pymoldir/pymolMPEG.sh<br />
tail -n +2 $pymoldir/pymol >> $pymoldir/pymolMPEG.sh<br />
chmod u+x $pymoldir/pymolMPEG.sh <br />
<br />
## Make a link, so we can call execute pymol<br />
sudo ln -s $pymoldir/pymolMPEG.sh /usr/bin/pymol<br />
</source><br />
<br />
=== Update script ===<br />
To pull and update PyMOL, one can make this script<br />
<br />
Make a text file "updatepymol.sh" and make it executable<br />
<source lang="bash"><br />
chmod u+x updatepymol.sh<br />
</source><br />
<br />
Put this in the file, modify the first 3 lines<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
pymolsvn=/home/tlinnet/Software/pymol/svnpymol<br />
pymoldir=/home/tlinnet/Software/pymol<br />
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol<br />
<br />
# gcc 4.5 broken for install in ubuntu<br />
export CC=/usr/bin/gcc-4.4<br />
<br />
svn up $pymolsvn<br />
svn up $freemolsvn<br />
<br />
modules=$pymoldir/modules<br />
cd $pymolsvn<br />
python setup.py build<br />
sudo python setup.py install<br />
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
sudo python setup2.py install<br />
install $pymolsvn/pymol $pymoldir/<br />
<br />
########## Setup freemol - for MPEG support ############<br />
cd $freemolsvn/src/mpeg_encode<br />
export FREEMOL=$freemolsvn/freemol<br />
./configure<br />
make<br />
make install<br />
</source><br />
<br />
=== Change MPEG settings ===<br />
Change settings in<br />
<source lang="bash"><br />
/home/tlinnet/Software/pymol/svnfreemol/freemol/libpy/freemol/mpeg_encode.py<br />
</source><br />
For example, change in line 205:<br> <br />
FRAME_RATE 24<br><br />
(Not, only legal values is allowed: 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60)<br />
<br />
Then restart PyMOL. <br />
<br />
[[Category:Installation|Linux Installation]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Linux_Install&diff=9773Linux Install2011-12-02T16:01:26Z<p>Cowsandmilk: </p>
<hr />
<div>This page describes how to install open-source PyMOL on Linux.<br />
<br />
== Install Distribution-specific binary Package ==<br />
<br />
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.<br />
<br />
Command line install examples for some popular distributions:<br />
<br />
<source lang="bash"><br />
# Debian/Ubuntu<br />
sudo apt-get install pymol<br />
<br />
# Fedora<br />
yum install pymol<br />
<br />
# Gentoo<br />
emerge -av pymol<br />
<br />
# openSUSE (12.1 and later)<br />
sudo zypper install pymol<br />
</source><br />
<br />
== Install from Source ==<br />
<br />
Installation from source gives you the latest version and is the generic way to install PyMOL.<br />
<br />
=== Requirements ===<br />
<br />
Libraries as well as development files (headers) of the following software is<br />
required:<br />
<br />
* [http://subversion.apache.org/ Subversion] to download the source code<br />
* [http://www.python.org/ Python] (with distutils)<br />
* [http://pmw.sf.net Pmw] (Python Megawidgets)<br />
* OpenGL driver (I use [http://www.nvidia.com/object/unix.html NVidia])<br />
* libpng<br />
* freetype<br />
<br />
On many Linux systems, one of the following commands installs all requirements:<br />
<br />
<source lang="bash"><br />
# Debian/Ubuntu/Mint11<br />
sudo apt-get install subversion build-essential python-dev python-pmw \<br />
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev<br />
<br />
# Fedora<br />
yum install subversion python-devel freeglut-devel freetype-devel tkinter python-pmw<br />
<br />
# Gentoo<br />
emerge -av dev-vcs/subversion dev-lang/python dev-python/pmw media-libs/glew \<br />
media-libs/freeglut media-libs/libpng media-libs/freetype<br />
</source><br />
<br />
=== Get latest Source from SVN ===<br />
<br />
This will download the latest source to '''/tmp/pymol''':<br />
<br />
<source lang="bash"><br />
cd /tmp<br />
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol pymol<br />
cd pymol<br />
</source><br />
<br />
=== Compile and install ===<br />
<br />
This will install PyMOL as normal user into '''/opt/pymol-svn'''. If you don't have write permissions to '''/opt''', change the <code>prefix</code> variable to something like '''$HOME/pymol-svn'''.<br />
<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
<br />
prefix=/opt/pymol-svn<br />
modules=$prefix/modules<br />
<br />
python setup.py build install \<br />
--home=$prefix \<br />
--install-purelib=$modules \<br />
--install-platlib=$modules<br />
<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
python setup2.py install<br />
install pymol $prefix/<br />
</source><br />
<br />
Now launch PyMOL like this (you may copy this launcher into your '''$PATH''',<br />
like to '''/usr/local/bin'''):<br />
<br />
<source lang="bash"><br />
/opt/pymol-svn/pymol<br />
</source><br />
<br />
== Problems ==<br />
<br />
* gcc-4.5 is broken for pymol install, use gcc-4.4 (Mint11 Linux, PyMOL 1.4.1, reported by [[User:Tlinnet]])<br />
<source lang="bash"><br />
sudo apt-get install build-essential gcc-4.4 g++-4.4<br />
export CC=/usr/bin/gcc-4.4<br />
</source><br />
<br />
* If you get an error message "ImportError: No module named Pmw" and lack half of the user interface, then run the additional command<br />
:<source lang="bash"><br />
python setup2.py install pmw<br />
</source><br />
<br />
:to install a copy of the Python MegaWidgets.<br />
<br />
== Ubuntu/Mint Compile and install with MPEG support ==<br />
Make a text file "installpymol.sh" and make it executable<br />
<source lang="bash"><br />
chmod u+x installpymol.sh<br />
</source><br />
<br />
Put this in the file, modify the first 3 lines<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
pymolsvn=/home/tlinnet/Software/pymol/svnpymol<br />
pymoldir=/home/tlinnet/Software/pymol<br />
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol<br />
<br />
###################################################<br />
[ -d $pymoldir ] || mkdir $pymoldir<br />
[ -d $pymolsvn ] || mkdir $pymolsvn<br />
[ -d $pymoldir/wikiscripts ] || mkdir $pymoldir/wikiscripts<br />
<br />
sudo apt-get install subversion build-essential python-dev python-pmw \<br />
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev<br />
<br />
# gcc 4.5 broken for install in ubuntu<br />
sudo apt-get install gcc-4.4 g++-4.4<br />
export CC=/usr/bin/gcc-4.4<br />
<br />
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol $pymolsvn<br />
<br />
modules=$pymoldir/modules<br />
cd $pymolsvn<br />
python setup.py build<br />
sudo python setup.py install<br />
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
sudo python setup2.py install<br />
install $pymolsvn/pymol $pymoldir/<br />
<br />
## To add a path/folder where you can put pymol wikiscripts<br />
t="'"<br />
echo "import sys" >> ~/.pymolrc<br />
echo "sys.path.append($t$pymoldir/wikiscripts$t)" >> ~/.pymolrc<br />
<br />
########## Setup freemol - for MPEG support ############<br />
[ -d $pymolsvn ] || mkdir $freemolsvn<br />
svn co svn://bioinformatics.org/svnroot/freemol/trunk $freemolsvn<br />
<br />
cd $freemolsvn/src/mpeg_encode<br />
export FREEMOL=$freemolsvn/freemol<br />
./configure<br />
make<br />
make install<br />
<br />
## Make a shortcut to export freemol and then execute pymol<br />
echo '#!/bin/bash' >> $pymoldir/pymolMPEG.sh<br />
echo "export FREEMOL=$freemolsvn/freemol" >> $pymoldir/pymolMPEG.sh<br />
echo "#$pymoldir/pymol" >> $pymoldir/pymolMPEG.sh<br />
tail -n +2 $pymoldir/pymol >> $pymoldir/pymolMPEG.sh<br />
chmod u+x $pymoldir/pymolMPEG.sh <br />
<br />
## Make a link, so we can call execute pymol<br />
sudo ln -s $pymoldir/pymolMPEG.sh /usr/bin/pymol<br />
</source><br />
<br />
=== Update script ===<br />
To pull and update PyMOL, one can make this script<br />
<br />
Make a text file "updatepymol.sh" and make it executable<br />
<source lang="bash"><br />
chmod u+x updatepymol.sh<br />
</source><br />
<br />
Put this in the file, modify the first 3 lines<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
pymolsvn=/home/tlinnet/Software/pymol/svnpymol<br />
pymoldir=/home/tlinnet/Software/pymol<br />
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol<br />
<br />
# gcc 4.5 broken for install in ubuntu<br />
export CC=/usr/bin/gcc-4.4<br />
<br />
svn up $pymolsvn<br />
svn up $freemolsvn<br />
<br />
modules=$pymoldir/modules<br />
cd $pymolsvn<br />
python setup.py build<br />
sudo python setup.py install<br />
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
sudo python setup2.py install<br />
install $pymolsvn/pymol $pymoldir/<br />
<br />
########## Setup freemol - for MPEG support ############<br />
cd $freemolsvn/src/mpeg_encode<br />
export FREEMOL=$freemolsvn/freemol<br />
./configure<br />
make<br />
make install<br />
</source><br />
<br />
=== Change MPEG settings ===<br />
Change settings in<br />
<source lang="bash"><br />
/home/tlinnet/Software/pymol/svnfreemol/freemol/libpy/freemol/mpeg_encode.py<br />
</source><br />
For example, change in line 205:<br> <br />
FRAME_RATE 24<br><br />
(Not, only legal values is allowed: 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60)<br />
<br />
Then restart PyMOL. <br />
<br />
[[Category:Installation|Linux Installation]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Linux_Install&diff=9772Linux Install2011-12-02T15:44:31Z<p>Cowsandmilk: </p>
<hr />
<div>This page describes how to install open-source PyMOL on Linux.<br />
<br />
== Install Distribution-specific binary Package ==<br />
<br />
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.<br />
<br />
Command line install examples for some popular distributions:<br />
<br />
<source lang="bash"><br />
# Debian/Ubuntu<br />
sudo apt-get install pymol<br />
<br />
# Fedora<br />
yum install pymol<br />
<br />
# Gentoo<br />
emerge -av pymol<br />
<br />
# OpenSUSE (12.1 and later)<br />
sudo zypper install pymol<br />
</source><br />
<br />
== Install from Source ==<br />
<br />
Installation from source gives you the latest version and is the generic way to install PyMOL.<br />
<br />
=== Requirements ===<br />
<br />
Libraries as well as development files (headers) of the following software is<br />
required:<br />
<br />
* [http://subversion.apache.org/ Subversion] to download the source code<br />
* [http://www.python.org/ Python] (with distutils)<br />
* [http://pmw.sf.net Pmw] (Python Megawidgets)<br />
* OpenGL driver (I use [http://www.nvidia.com/object/unix.html NVidia])<br />
* libpng<br />
* freetype<br />
<br />
On many Linux systems, one of the following commands installs all requirements:<br />
<br />
<source lang="bash"><br />
# Debian/Ubuntu/Mint11<br />
sudo apt-get install subversion build-essential python-dev python-pmw \<br />
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev<br />
<br />
# Fedora<br />
yum install subversion python-devel freeglut-devel freetype-devel tkinter python-pmw<br />
<br />
# Gentoo<br />
emerge -av dev-vcs/subversion dev-lang/python dev-python/pmw media-libs/glew \<br />
media-libs/freeglut media-libs/libpng media-libs/freetype<br />
</source><br />
<br />
=== Get latest Source from SVN ===<br />
<br />
This will download the latest source to '''/tmp/pymol''':<br />
<br />
<source lang="bash"><br />
cd /tmp<br />
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol pymol<br />
cd pymol<br />
</source><br />
<br />
=== Compile and install ===<br />
<br />
This will install PyMOL as normal user into '''/opt/pymol-svn'''. If you don't have write permissions to '''/opt''', change the <code>prefix</code> variable to something like '''$HOME/pymol-svn'''.<br />
<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
<br />
prefix=/opt/pymol-svn<br />
modules=$prefix/modules<br />
<br />
python setup.py build install \<br />
--home=$prefix \<br />
--install-purelib=$modules \<br />
--install-platlib=$modules<br />
<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
python setup2.py install<br />
install pymol $prefix/<br />
</source><br />
<br />
Now launch PyMOL like this (you may copy this launcher into your '''$PATH''',<br />
like to '''/usr/local/bin'''):<br />
<br />
<source lang="bash"><br />
/opt/pymol-svn/pymol<br />
</source><br />
<br />
== Problems ==<br />
<br />
* gcc-4.5 is broken for pymol install, use gcc-4.4 (Mint11 Linux, PyMOL 1.4.1, reported by [[User:Tlinnet]])<br />
<source lang="bash"><br />
sudo apt-get install build-essential gcc-4.4 g++-4.4<br />
export CC=/usr/bin/gcc-4.4<br />
</source><br />
<br />
* If you get an error message "ImportError: No module named Pmw" and lack half of the user interface, then run the additional command<br />
:<source lang="bash"><br />
python setup2.py install pmw<br />
</source><br />
<br />
:to install a copy of the Python MegaWidgets.<br />
<br />
== Ubuntu/Mint Compile and install with MPEG support ==<br />
Make a text file "installpymol.sh" and make it executable<br />
<source lang="bash"><br />
chmod u+x installpymol.sh<br />
</source><br />
<br />
Put this in the file, modify the first 3 lines<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
pymolsvn=/home/tlinnet/Software/pymol/svnpymol<br />
pymoldir=/home/tlinnet/Software/pymol<br />
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol<br />
<br />
###################################################<br />
[ -d $pymoldir ] || mkdir $pymoldir<br />
[ -d $pymolsvn ] || mkdir $pymolsvn<br />
[ -d $pymoldir/wikiscripts ] || mkdir $pymoldir/wikiscripts<br />
<br />
sudo apt-get install subversion build-essential python-dev python-pmw \<br />
libglew-dev freeglut3-dev libpng-dev libfreetype6-dev<br />
<br />
# gcc 4.5 broken for install in ubuntu<br />
sudo apt-get install gcc-4.4 g++-4.4<br />
export CC=/usr/bin/gcc-4.4<br />
<br />
svn co https://pymol.svn.sourceforge.net/svnroot/pymol/trunk/pymol $pymolsvn<br />
<br />
modules=$pymoldir/modules<br />
cd $pymolsvn<br />
python setup.py build<br />
sudo python setup.py install<br />
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
sudo python setup2.py install<br />
install $pymolsvn/pymol $pymoldir/<br />
<br />
## To add a path/folder where you can put pymol wikiscripts<br />
t="'"<br />
echo "import sys" >> ~/.pymolrc<br />
echo "sys.path.append($t$pymoldir/wikiscripts$t)" >> ~/.pymolrc<br />
<br />
########## Setup freemol - for MPEG support ############<br />
[ -d $pymolsvn ] || mkdir $freemolsvn<br />
svn co svn://bioinformatics.org/svnroot/freemol/trunk $freemolsvn<br />
<br />
cd $freemolsvn/src/mpeg_encode<br />
export FREEMOL=$freemolsvn/freemol<br />
./configure<br />
make<br />
make install<br />
<br />
## Make a shortcut to export freemol and then execute pymol<br />
echo '#!/bin/bash' >> $pymoldir/pymolMPEG.sh<br />
echo "export FREEMOL=$freemolsvn/freemol" >> $pymoldir/pymolMPEG.sh<br />
echo "#$pymoldir/pymol" >> $pymoldir/pymolMPEG.sh<br />
tail -n +2 $pymoldir/pymol >> $pymoldir/pymolMPEG.sh<br />
chmod u+x $pymoldir/pymolMPEG.sh <br />
<br />
## Make a link, so we can call execute pymol<br />
sudo ln -s $pymoldir/pymolMPEG.sh /usr/bin/pymol<br />
</source><br />
<br />
=== Update script ===<br />
To pull and update PyMOL, one can make this script<br />
<br />
Make a text file "updatepymol.sh" and make it executable<br />
<source lang="bash"><br />
chmod u+x updatepymol.sh<br />
</source><br />
<br />
Put this in the file, modify the first 3 lines<br />
<source lang="bash"><br />
#!/bin/bash -e<br />
pymolsvn=/home/tlinnet/Software/pymol/svnpymol<br />
pymoldir=/home/tlinnet/Software/pymol<br />
freemolsvn=/home/tlinnet/Software/pymol/svnfreemol<br />
<br />
# gcc 4.5 broken for install in ubuntu<br />
export CC=/usr/bin/gcc-4.4<br />
<br />
svn up $pymolsvn<br />
svn up $freemolsvn<br />
<br />
modules=$pymoldir/modules<br />
cd $pymolsvn<br />
python setup.py build<br />
sudo python setup.py install<br />
sudo python setup.py install --home=$pymoldir --install-purelib=$modules --install-platlib=$modules<br />
export PYTHONPATH=$modules:$PYTHONPATH<br />
sudo python setup2.py install<br />
install $pymolsvn/pymol $pymoldir/<br />
<br />
########## Setup freemol - for MPEG support ############<br />
cd $freemolsvn/src/mpeg_encode<br />
export FREEMOL=$freemolsvn/freemol<br />
./configure<br />
make<br />
make install<br />
</source><br />
<br />
=== Change MPEG settings ===<br />
Change settings in<br />
<source lang="bash"><br />
/home/tlinnet/Software/pymol/svnfreemol/freemol/libpy/freemol/mpeg_encode.py<br />
</source><br />
For example, change in line 205:<br> <br />
FRAME_RATE 24<br><br />
(Not, only legal values is allowed: 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60)<br />
<br />
Then restart PyMOL. <br />
<br />
[[Category:Installation|Linux Installation]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=System&diff=8245System2010-05-05T00:38:10Z<p>Cowsandmilk: /* PYMOL API */ correct arguments</p>
<hr />
<div><br />
The '''system''' command, executes a command in a subshell under Unix or Windows.<br />
<br />
===USAGE===<br />
<source lang="python"><br />
# execute 'command'<br />
system command<br />
</source><br />
<br />
===PYMOL API===<br />
<source lang="python"><br />
cmd.system(string command,int async=0)<br />
</source><br />
<br />
===NOTES===<br />
async can only be specified from the Python level (not the command language)<br />
*if async is 0 (default), then the result code from "system" is returned in r <br />
*if async is 1, then the command is run in a separate thread whose object is returned<br />
<br />
===SEE ALSO===<br />
[[ls]], [[cd]], [[pwd]]<br />
<br />
[[Category:Commands|System]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Connect_mode&diff=8221Connect mode2010-04-22T20:02:06Z<p>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…'</p>
<hr />
<div>= Overview =<br />
Sets how bonds are made when loading a file.<br />
<br />
Values:<br />
* 0 = distance-based and CONECT records<br />
* 1 = CONECT records<br />
* 2 = distance-based<br />
* 3 = (who knows, the code is complicated)<br />
<br />
= Syntax =<br />
<source lang="python"><br />
# ignore CONECT records<br />
set connect_mode, 2<br />
<br />
</source><br />
<br />
= See Also =</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Kabsch&diff=8055Kabsch2010-02-14T19:17:43Z<p>Cowsandmilk: /* The Code */ indentation changes</p>
<hr />
<div>==Intro==<br />
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.<br />
<br />
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.<br />
<br />
'''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]].<br />
<br />
'''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.<br />
<br />
'''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).<br />
<br />
==To use==<br />
<br />
# Save this script to Kabsch.py<br />
# Open PyMol<br />
# Load the alignment script: '''run Kabsch.py''' (The command '''optAlign''' is now defined in PyMol.)<br />
# Load your proteins<br />
# Align the proper segments (see below examples)<br />
<br />
To align two equivalent sets of residues do:<br />
<source lang="python"><br />
optAlign SEL1 and n. CA and i. a-b, SEL2 and n. CA and i. c-d<br />
</source><br />
where<br />
* '''SEL1''' is the first protein<br />
* '''a-b''' is the range of residues to align in the first protein<br />
* '''SEL2''' is the second protein<br />
* '''c-d''' is the range of residues to align in the second protein<br />
<br />
===Caveats===<br />
* Ensure that you're equivalencing '''N''' atoms to '''N''' atoms (run [[Count_Atoms]] over your two selections to ensure they are the same length).<br />
* 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.<br />
* The RMSD is only between the equivlanced atoms. Use PyMol's [[Rms_Cur]] if you want a full RMSD.<br />
* 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 <source lang="python">set seq_view,1</source> 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 <source lang="python">alter (SEL), resi=str(int(resi)-2064)</source> and then <source lang="python">sort</source> 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]].<br><br />
<br />
== Notes ==<br />
<ol><li>Windows users are having problems running the script. Python tells them first off "TypeError: Can't convert rank-0 arrays to Python scalars." The fix to that breaks some code in Numeric -- which I don't maintain.</li><br><br />
<li>However, to make this work, you can change the code in <b>Numeric.py</b> supplied with Pymol, located in the folder "<Pymol Home>\modules\Numeric\" (for example: "C:\Program Files\DeLano Scientific\PyMOL\modules\Numeric").<br><br><br />
Essentially, you need to search for the line: <source lang="python"> if axis2 < 0: axis2 = axis1 + n # (should be around line 250) </source> and replace it with: <source lang="python">if axis2 < 0: axis2 = axis2 + n </source></li></ol><br />
<br />
===Examples===<br />
optAlign 1cll and n. CA and i. 4-20+30-60, 1ggz and n. CA and i. 4-20+30-60<br />
<br />
optAlign 1kao and n. CA and i. 20-50, 1ctq and n. CA and i. 20-50<br />
<br />
<gallery><br />
Image:OptAlign1.png|1cll and 1ggz loaded<br />
Image:OptAlign2.png|1cll and 1ggz aligned to residues 5-50+55-80 shown in red<br />
</gallery><br />
<br />
Kabsch can also align hetero-atoms:<br />
<source lang="python"><br />
load 1cll.pdb<br />
load 1ggz.pdb<br />
optAlign 1cll and e. CA, 1ggz and e. CA<br />
</source><br />
The above aligns the 4 Calciums in each structure.<br />
<br />
==The Code==<br />
<source lang="python"><br />
#!python<br />
<br />
##############################################################################<br />
#<br />
# @SUMMARY: -- QKabsch.py. A python implementation of the optimal superposition<br />
# of two sets of vectors as proposed by Kabsch 1976 & 1978.<br />
#<br />
# @AUTHOR: Jason Vertrees<br />
# @COPYRIGHT: Jason Vertrees (C), 2005-2007<br />
# @LICENSE: Released under GPL:<br />
# This program is free software; you can redistribute it and/or modify<br />
# it under the terms of the GNU General Public License as published by<br />
# the Free Software Foundation; either version 2 of the License, or<br />
# (at your option) any later version.<br />
# This program is distributed in the hope that it will be useful, but WITHOUT<br />
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS<br />
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.<br />
#<br />
# You should have received a copy of the GNU General Public License along with<br />
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin<br />
# Street, Fifth Floor, Boston, MA 02110-1301, USA <br />
#<br />
# DATE : 2007-01-01<br />
# REV : 2<br />
# REQUIREMENTS: numpy<br />
#<br />
#############################################################################<br />
from array import *<br />
<br />
# system stuff<br />
import os<br />
import copy<br />
<br />
# pretty printing<br />
import pprint<br />
<br />
# for importing as a plugin into PyMol<br />
from pymol import cmd<br />
from pymol import stored<br />
from pymol import selector<br />
<br />
# using numpy for linear algebra<br />
import numpy<br />
<br />
def optAlign( sel1, sel2 ):<br />
"""<br />
optAlign performs the Kabsch alignment algorithm upon the alpha-carbons of two selections.<br />
Example: optAlign MOL1 and i. 20-40, MOL2 and i. 102-122<br />
Example 2: optAlign 1GGZ and i. 4-146 and n. CA, 1CLL and i. 4-146 and n. CA<br />
<br />
Two RMSDs are returned. One comes from the Kabsch algorithm and the other from<br />
PyMol based upon your selections.<br />
<br />
By default, this program will optimally align the ALPHA CARBONS of the selections provided.<br />
To turn off this feature remove the lines between the commented "REMOVE ALPHA CARBONS" below.<br />
<br />
@param sel1: First PyMol selection with N-atoms<br />
@param sel2: Second PyMol selection with N-atoms<br />
"""<br />
cmd.reset()<br />
<br />
# make the lists for holding coordinates<br />
# partial lists<br />
stored.sel1 = []<br />
stored.sel2 = []<br />
# full lists<br />
stored.mol1 = []<br />
stored.mol2 = []<br />
<br />
# -- CUT HERE<br />
sel1 = sel1 + " and N. CA"<br />
sel2 = sel2 + " and N. CA"<br />
# -- CUT HERE<br />
<br />
# Get the selected coordinates. We<br />
# align these coords.<br />
cmd.iterate_state(1, selector.process(sel1), "stored.sel1.append([x,y,z])")<br />
cmd.iterate_state(1, selector.process(sel2), "stored.sel2.append([x,y,z])")<br />
<br />
# get molecule name<br />
mol1 = cmd.identify(sel1,1)[0][0]<br />
mol2 = cmd.identify(sel2,1)[0][0]<br />
<br />
# Get all molecule coords. We do this because<br />
# we have to rotate the whole molcule, not just<br />
# the aligned selection<br />
cmd.iterate_state(1, mol1, "stored.mol1.append([x,y,z])")<br />
cmd.iterate_state(1, mol2, "stored.mol2.append([x,y,z])")<br />
<br />
# check for consistency<br />
assert( len(stored.sel1) == len(stored.sel2))<br />
L = len(stored.sel1)<br />
assert( L > 0 )<br />
<br />
# must alway center the two proteins to avoid<br />
# affine transformations. Center the two proteins<br />
# to their selections.<br />
COM1 = numpy.sum(stored.sel1,axis=0) / float(L)<br />
COM2 = numpy.sum(stored.sel2,axis=0) / float(L)<br />
stored.sel1 = stored.sel1 - COM1<br />
stored.sel2 = stored.sel2 - COM2<br />
<br />
# Initial residual, see Kabsch.<br />
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)<br />
<br />
#<br />
# This beautiful step provides the answer. V and Wt are the orthonormal<br />
# bases that when multiplied by each other give us the rotation matrix, U.<br />
# S, (Sigma, from SVD) provides us with the error! Isn't SVD great!<br />
V, S, Wt = numpy.linalg.svd( numpy.dot( numpy.transpose(stored.sel2), stored.sel1))<br />
<br />
# we already have our solution, in the results from SVD.<br />
# we just need to check for reflections and then produce<br />
# the rotation. V and Wt are orthonormal, so their det's<br />
# are +/-1.<br />
reflect = float(str(float(numpy.linalg.det(V) * numpy.linalg.det(Wt))))<br />
<br />
if reflect == -1.0:<br />
S[-1] = -S[-1]<br />
V[:,-1] = -V[:,-1]<br />
<br />
RMSD = E0 - (2.0 * sum(S))<br />
RMSD = numpy.sqrt(abs(RMSD / L))<br />
<br />
#U is simply V*Wt<br />
U = numpy.dot(V, Wt)<br />
<br />
# rotate and translate the molecule<br />
stored.sel2 = numpy.dot((stored.mol2 - COM2), U)<br />
stored.sel2 = stored.sel2.tolist()<br />
# center the molecule<br />
stored.sel1 = stored.mol1 - COM1<br />
stored.sel1 = stored.sel1.tolist()<br />
<br />
# let PyMol know about the changes to the coordinates<br />
cmd.alter_state(1,mol1,"(x,y,z)=stored.sel1.pop(0)")<br />
cmd.alter_state(1,mol2,"(x,y,z)=stored.sel2.pop(0)")<br />
<br />
print "RMSD=%f" % RMSD<br />
<br />
# make the alignment OBVIOUS<br />
cmd.hide('everything')<br />
cmd.show('ribbon', sel1 + ' or ' + sel2)<br />
cmd.color('gray70', mol1 )<br />
cmd.color('paleyellow', mol2 )<br />
cmd.color('red', 'visible')<br />
cmd.show('ribbon', 'not visible')<br />
cmd.center('visible')<br />
cmd.orient()<br />
cmd.zoom('visible')<br />
<br />
cmd.extend("optAlign", optAlign)<br />
</source><br />
<br />
=== The Old Code ===<br />
<br />
<source lang="python"><br />
#!python<br />
<br />
##############################################################################<br />
#<br />
# @SUMMARY: -- Kabsch.py. A python implementation of the optimal superposition<br />
# of two sets of vectors as proposed by Kabsch 1976 & 1978.<br />
#<br />
# @AUTHOR: Jason Vertrees<br />
# @COPYRIGHT: Jason Vertrees (C), 2005-2007<br />
# @LICENSE: Released under GPL:<br />
# This program is free software; you can redistribute it and/or modify<br />
# it under the terms of the GNU General Public License as published by<br />
# the Free Software Foundation; either version 2 of the License, or<br />
# (at your option) any later version.<br />
# This program is distributed in the hope that it will be useful, but WITHOUT<br />
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS<br />
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.<br />
#<br />
# You should have received a copy of the GNU General Public License along with<br />
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin<br />
# Street, Fifth Floor, Boston, MA 02110-1301, USA <br />
#<br />
# DATE : 2005-04-07<br />
# REV : 2<br />
# NOTES: Updated RMSD, notes, cleaned up the code a little.<br />
#<br />
#############################################################################<br />
# math imports<br />
import math<br />
import Numeric<br />
import LinearAlgebra<br />
import Matrix<br />
<br />
from array import *<br />
<br />
# system stuff<br />
import os<br />
import copy<br />
<br />
# pretty printing<br />
import pprint<br />
<br />
# for importing as a plugin into PyMol<br />
#import tkSimpleDialog<br />
#import tkMessageBox<br />
from pymol import cmd<br />
from pymol import stored<br />
from pymol import selector<br />
<br />
class kabsch:<br />
"""<br />
Kabsch alignment of two set of vectors to produce and optimal alignemnt.<br />
<br />
Steps<br />
===== <br />
1. Calculate the center of mass for each protein. Then, move the protein<br />
to its center of mass. We choose as a convention, to use the origin as <br />
the center of mass of the first set of coordinates. This will allow us to<br />
return one translation vector, instead of two.<br />
<br />
Update: Since any rotation around a point that's not the origin, is in fact<br />
an affine rotation. So, to beat that, we translate both to the center.<br />
<br />
NAME: superpose(c1, c2)<br />
POST: T is now defined.<br />
<br />
2. Calculate the matrix, R, by (eq7, 1976). r_{i,j} = sum_n w_n * y_{ni} * x_{nj},<br />
where y_{ni} is the ith component of the vector y_n.<br />
NAME: calcR<br />
POST: R is now defined<br />
<br />
3. Calculate RtR (R-transpose * R).<br />
NAME: calcRtR<br />
POST: RtR is now defined<br />
<br />
4. Calculate the corresponding eigenpairs for RtR, and sort them accordingly:<br />
m1 >= m2 >= m3; set v3 = v1 x v2 to ensure a RHS<br />
NAME: calcEigenPairs<br />
POST: The eigen pairs are calculated, sorted such that m1 >= m2 >= m3 and<br />
v3 = v1 x v2.<br />
<br />
5. Calculate R*v_k and normalize the first two vectors to obtain b_1, b_2 and set<br />
b_3 = b_1 x b_2. This also takes care of m1 > m2 = 0. <br />
NAME: calcBVectors<br />
POST: b-Vectors are defined and returned<br />
<br />
6. Calculate U=(u_{ij})=(sum n b_{ki} * a_{kj}) to obtain the best rotation. Set<br />
sigma_3 = -1 if b3(Ra3) < 0 else sigma_3 = +1.<br />
NAME: calcU<br />
POST: U is defined<br />
<br />
7. Calculate the RMSD. The residual error is then<br />
The E = E0 - sqrt(m1) - sqrt(m2) - sigma_3(sqrt(m3)).<br />
NAME: calcRMSD<br />
POST: RMSD is computed.<br />
<br />
@note: This should be a static method that takes three parameters<br />
<br />
1. The first protein's coordinates, f. This program will <br />
accept coordinates in the form an array of 3D vectors/lists<br />
<br />
2. The second protein's coordinates, g.<br />
<br />
3. The array of integer pairs representing the pairs to align.<br />
Coordinates should be formatted as as array of 2D vectors/lists.<br />
<br />
<br />
<br />
"""<br />
<br />
def __init__(self):<br />
"""<br />
Constructor. @see kabsch.align.<br />
<br />
"""<br />
<br />
#<br />
# Instance Variables: All three of these will be updated<br />
# every time the user calls ~.align. Just to warn ya'.<br />
# <br />
# U, the rotation matrix<br />
self.U = []<br />
# T, the translation vector<br />
self.T = []<br />
# R, the RMSD<br />
self.R = -1.0<br />
<br />
#self.menuBar.addmenuitem('Plugin', 'command', 'Kabsch Align', label = "Align Selections to Optial RMSD", command = lamda s=self: fetchPDBDialog(s))<br />
<br />
<br />
def align(self, c1, c2, pairs):<br />
"""<br />
Finds the best alignment of c1 and c2's pairs resulting in<br />
the smallest possible RMSD.<br />
<br />
<br />
@note:<br />
- All weights in this first version are set to 1. Kabsch allows,<br />
differential weighting. In the future, I may extend to this option,<br />
and then pairs may become 3D (r1, r2, weight) or I may add another<br />
parameter.<br />
<br />
- Helper functions will soon be provided such that the user may<br />
just use this package alone to compute the rotation.<br />
<br />
@param c1: coordinats of the first vectors, as an array of 3D vectors.<br />
@type c1: Python list<br />
<br />
@param c2: coordinates of the second set of vectors, as an array of 3D vectors.<br />
@type c2: Python list<br />
<br />
@param pairs: the list of pairs as an array of 2D pairs.<br />
@type pairs: Python list of 2D lists.<br />
<br />
@return: U, the rotation matrix that gives the optimal rotation between the two proteins.<br />
<br />
T, the translation vector given to align the two objects centers of mass.<br />
<br />
R, the RMSD of the final rotation.<br />
"""<br />
<br />
#<br />
# First we move the center of mass of one protein, to the<br />
# center of mass of the other. This removes any translation<br />
# between the two.<br />
#<br />
T1, T2, c1, c2 = self.superpose(c1, c2)<br />
# Calculate the initial RMSD<br />
E0 = self.calcE0(c1, c2)<br />
# Calculate R via eq. 7.<br />
R = self.calcR(c1, c2)<br />
# Calculate R(transpose)*R<br />
RtR = self.calcRtR(R)<br />
# Determined the eigenpairs for the matrix RtR.<br />
eValues, eVectors = self.calcEigenPairs(RtR)<br />
# Determine the bVectors as required<br />
bVectors = self.calcBVectors(R, eVectors)<br />
# Calculate the roation matrix<br />
U = self.calcU(eVectors, bVectors)<br />
# Calculate the final RMSD using U.<br />
RMSD = self.calcRMSD(E0, eValues, eVectors, bVectors, R, len(c1))<br />
<br />
return U, T1, T2, RMSD, c1, c2<br />
<br />
<br />
def superpose(self, c1, c2 ):<br />
"""<br />
Calculate the center of mass for each protein. Then, move the protein<br />
to its center of mass. We choose as a convention, to use the origin as <br />
the center of mass of the first set of coordinates. This will allow us to<br />
return one translation vector, instead of two.<br />
(CORRECT)<br />
<br />
@precondition: c1 and c2 are well defined lists of N-dimensional points with length > 0.<br />
@postcondition: T is now defined.<br />
<br />
@param c1: coordinats of the first vectors, as an array of 3D vectors.<br />
@type c1: Python list<br />
<br />
@param c2: coordinates of the second set of vectors, as an array of 3D vectors.<br />
@type c2: Python list<br />
<br />
@return: T the translation vector.<br />
<br />
c2 one list of coordinates that of c2 translated to the COM of c1.<br />
<br />
"""<br />
<br />
# make sure we don't get bad data<br />
if (len(c1) != len(c2)):<br />
print "Two different length selections, with lengths, %d and %d." % (len(c1), len(c2))<br />
print "This algorithm must be used with selections of the same length." <br />
print "In PyMol, type 'count_atoms sel1' where sel1 are your selections to find out their lengths."<br />
print "Example: optAlign MOL1 and i. 20-40, MOL2 and i. 102-122"<br />
print "Example 2: optAlign 1GGZ and i. 4-146 and n. CA, 1CLL and i. 4-146 and n. CA"<br />
<br />
<br />
assert(len(c1) == len(c2) != 0)<br />
<br />
L = len(c1)<br />
<br />
#<br />
# Centers of Mass<br />
#<br />
c1COM = Numeric.zeros((3,1), Numeric.Float64)<br />
c2COM = Numeric.zeros((3,1), Numeric.Float64)<br />
<br />
# calculate the CsOM <br />
for i in range(0, L):<br />
for j in range(0,3):<br />
c1COM[j] = c1COM[j] + c1[i][j]<br />
c2COM[j] = c2COM[j] + c2[i][j]<br />
<br />
T1 = - c1COM / L<br />
T2 = - c2COM / L<br />
<br />
# move everything back to the origin.<br />
for i in range(0, L):<br />
for j in range(0,3):<br />
c1[i][j] = c1[i][j] + T1[j]<br />
c2[i][j] = c2[i][j] + T2[j]<br />
<br />
return T1, T2, c1, c2<br />
<br />
<br />
def calcR( self, c1, c2 ):<br />
"""<br />
Calculate the matrix, R, by (eq7, 1976). M{r_{i,j} = sum_n w_n * y_{ni} * x_{nj}},<br />
where M{y_{ni}} is the ith component of the vector M{y_n}.<br />
(CORRECT)<br />
<br />
@param c1: coordinats of the first vectors, as an array of 3D vectors.<br />
@type c1: Python list<br />
<br />
@param c2: coordinates of the second set of vectors, as an array of 3D vectors.<br />
@type c2: Python list<br />
<br />
@postcondition: R is now defined.<br />
<br />
@return: R<br />
@rtype : 3x3 matrix<br />
<br />
"""<br />
<br />
# Create the 3x3 matrix<br />
R = Numeric.zeros((3,3), Numeric.Float64)<br />
L = len(c1)<br />
<br />
for k in range(0, L):<br />
for i in range(0, 3):<br />
for j in range(0, 3):<br />
R[i][j] = R[i][j] + (c2[k][i] * c1[k][j])<br />
<br />
# return R the 3x3 PSD Matrix.<br />
return R<br />
<br />
<br />
def calcRtR( self, R ):<br />
"""<br />
Calculate RtR (R-transpose * R).<br />
(CORRECT)<br />
<br />
@param R: Matrix<br />
@type R: 3x3 Matrix<br />
<br />
@precondition: R is a the well formed matrix as per Kabsch.<br />
@postcondition: RtR is now defined<br />
<br />
@return: M{R^tR}<br />
@rtype : 3x3 matrix<br />
<br />
"""<br />
<br />
RtR = Numeric.matrixmultiply(Numeric.transpose(R), R)<br />
<br />
return RtR<br />
<br />
<br />
def calcEigenPairs( self, RtR ):<br />
"""<br />
Calculate the corresponding eigenpairs for RtR, and sort them accordingly:<br />
M{m1 >= m2 >= m3}; set M{v3 = v1 x v2} to ensure a RHS<br />
(CORRECT)<br />
<br />
@postcondition: The eigen pairs are calculated, sorted such that M{m1 >= m2 >= m3} and<br />
M{v3 = v1 x v2}.<br />
<br />
@param RtR: 3x3 Matrix of M{R^t * R}.<br />
@type RtR: 3x3 Matrix<br />
@return : Eigenpairs for the RtR matrix.<br />
@rtype : List of stuff<br />
<br />
"""<br />
<br />
eVal, eVec = LinearAlgebra.eigenvectors(RtR)<br />
<br />
# This is cool. We sort it using Numeric.sort(eVal)<br />
# then we reverse it using nifty-crazy ass notation [::-1].<br />
eVal2 = Numeric.sort(eVal)[::-1]<br />
eVec2 = [[],[],[]] #Numeric.zeros((3,3), Numeric.Float64)<br />
<br />
# Map the vectors to their appropriate owners <br />
if ( eVal2[0] == eVal[0]):<br />
eVec2[0] = eVec[0]<br />
if ( eVal2[1] == eVal[1] ):<br />
eVec2[1] = eVec[1]<br />
eVec2[2] = eVec[2]<br />
else:<br />
eVec2[1] = eVec[2]<br />
eVec2[2] = eVec[1]<br />
elif( eVal2[0] == eVal[1]):<br />
eVec2[0] = eVec[1]<br />
if ( eVal2[1] == eVal[0] ):<br />
eVec2[1] = eVec[0]<br />
eVec2[2] = eVec[2]<br />
else:<br />
eVec2[1] = eVec[2]<br />
eVec2[2] = eVec[0]<br />
elif( eVal2[0] == eVal[2]):<br />
eVec2[0] = eVec[2]<br />
if ( eVal2[1] == eVal[1] ):<br />
eVec2[1] = eVec[1]<br />
eVec2[2] = eVec[0]<br />
else:<br />
eVec2[1] = eVec[0]<br />
eVec2[2] = eVec[1]<br />
<br />
eVec2[2][0] = eVec2[0][1]*eVec2[1][2] - eVec2[0][2]*eVec2[1][1]<br />
eVec2[2][1] = eVec2[0][2]*eVec2[1][0] - eVec2[0][0]*eVec2[1][2]<br />
eVec2[2][2] = eVec2[0][0]*eVec2[1][1] - eVec2[0][1]*eVec2[1][0]<br />
<br />
return [eVal2, eVec2]<br />
<br />
<br />
def calcBVectors( self, R, eVectors ):<br />
"""<br />
Calculate M{R*a_k} and normalize the first two vectors to obtain M{b_1, b_2} and set<br />
M{b_3 = b_1 x b_2}. This also takes care of {m2 > m3 = 0}. <br />
(CORRECT)<br />
<br />
@postcondition: b-Vectors are defined and returned<br />
<br />
@return: The three B-vectors<br />
@rtype: List of 3D vectors (Python LOL).<br />
"""<br />
<br />
bVectors = Numeric.zeros((3,3), Numeric.Float64)<br />
<br />
for i in range(0,3):<br />
bVectors[i] = Numeric.matrixmultiply(R, eVectors[i])<br />
<br />
bVectors[0] = bVectors[0] / Numeric.sqrt(Numeric.add.reduce(bVectors[0]**2))<br />
bVectors[1] = bVectors[1] / Numeric.sqrt(Numeric.add.reduce(bVectors[1]**2))<br />
bVectors[2] = bVectors[2] / Numeric.sqrt(Numeric.add.reduce(bVectors[2]**2))<br />
<br />
bVectors[2][0] = bVectors[0][1]*bVectors[1][2] - bVectors[0][2]*bVectors[1][1]<br />
bVectors[2][1] = bVectors[0][2]*bVectors[1][0] - bVectors[0][0]*bVectors[1][2]<br />
bVectors[2][2] = bVectors[0][0]*bVectors[1][1] - bVectors[0][1]*bVectors[1][0]<br />
<br />
return bVectors<br />
<br />
<br />
<br />
def calcU( self, eVectors, bVectors ):<br />
"""<br />
Calculate M{U=(u_{ij})=(sum n b_{ki} * a_{kj})} to obtain the best rotation. Set<br />
M{sigma_3 = -1 if b3(Ra3) < 0 else sigma_3 = +1}.<br />
(CORRECT)<br />
<br />
@postcondition: U is defined<br />
<br />
@param eVectors: Eigenvectors for the system.<br />
@type eVectors: Eigenvectors<br />
<br />
@param bVectors: BVectors as described by Kabsch.<br />
@type bVectors: BVectors<br />
<br />
@return: U the rotation matrix.<br />
@rtype :3x3 matrix.<br />
<br />
"""<br />
<br />
U = Numeric.zeros((3,3), Numeric.Float64)<br />
<br />
for k in range(0,3):<br />
for i in range(0,3):<br />
for j in range(0,3):<br />
U[i][j] = U[i][j] + Numeric.matrixmultiply(bVectors[k][i], eVectors[k][j])<br />
<br />
return U<br />
<br />
<br />
def calcE0( self, c1, c2 ):<br />
"""<br />
Calculates the initial RMSD, which Kacbsch called E0.<br />
(CORRECT)<br />
<br />
@param c1: coordinats of the first vectors, as an array of 3D vectors.<br />
@type c1: Python list<br />
<br />
@param c2: coordinates of the second set of vectors, as an array of 3D vectors.<br />
@type c2: Python list<br />
<br />
@return: E0 the initial RMSD.<br />
@rtype : float.<br />
<br />
"""<br />
<br />
E0 = 0.0<br />
<br />
L = len(c1)<br />
for i in range( 0, L ):<br />
for j in range(0, 3):<br />
E0 = E0 + 0.5*( (c1[i][j]*c1[i][j])+(c2[i][j]*c2[i][j]))<br />
<br />
return E0<br />
<br />
def calcRMSD( self, E0, eValues, eVectors, bVectors, R, N):<br />
"""<br />
Calculate the RMSD. The residual error is then<br />
The M{E = E0 - sqrt(m1) - sqrt(m2) - sigma_3(sqrt(m3))}.<br />
<br />
@param E0: Initial RMSD as calculated in L{calcE0}.<br />
@type E0: float.<br />
<br />
@param eVectors: Eigenvectors as calculated from L{calcEigenPairs}<br />
@type eVectors: vectors, dammit!<br />
<br />
@param bVectors: B-vectors as calc. from L{calcBVectors}<br />
@type bVectors: More vectors.<br />
<br />
@param R: The matrix R, from L{calcR}.<br />
@type R: 3x3 matrix. <br />
<br />
@param N: Number of equivalenced points<br />
@type N: integer<br />
<br />
@postcondition: RMSD is computed.<br />
@return: The RMSD.<br />
<br />
"""<br />
sigma3 = 0<br />
if ( Numeric.matrixmultiply(bVectors[2], Numeric.matrixmultiply( R, eVectors[2])) < 0):<br />
sigma3 = -1<br />
else:<br />
sigma3 = 1<br />
<br />
E = math.sqrt( 2*(E0 - math.sqrt(eValues[0]) - math.sqrt(eValues[1]) - sigma3*(math.sqrt(eValues[2]))) / N)<br />
<br />
return E<br />
<br />
<br />
def calcSimpleRMSD( self, c1, c2 ):<br />
"""<br />
Calculates the usual concept of RMSD between two set of points. The CalcRMSD above<br />
sticks to Kabsch's alignment method protocol and calculates something much different.<br />
@see kabsch.calcRMSD<br />
<br />
@param c1: List of points #1<br />
@type c1: LOL<br />
<br />
@param c2: List of points #2<br />
@type c2: LOL<br />
<br />
@return: RMSD between the two<br />
<br />
"""<br />
<br />
RMSD = 0.0<br />
for i in range(0, len(c1)):<br />
for j in range(0,3):<br />
RMSD = RMSD + (c2[i][j]-c1[i][j])**2<br />
<br />
RMSD = RMSD / len(c1)<br />
RMSD = Numeric.sqrt(RMSD)<br />
return RMSD<br />
<br />
<br />
#####################################################################<br />
#<br />
# UTIL Functions<br />
def rotatePoints(self, U, c2):<br />
"""<br />
Rotate all points in c2 based on the rotation matrix U.<br />
<br />
@param U: 3x3 Rotation matrix<br />
@type U: 3x3 matrix<br />
<br />
@param c2: List of points to rotate<br />
@type c2: List of 3D vectors<br />
<br />
@return: List of rotated points<br />
<br />
"""<br />
<br />
L = len(c2)<br />
<br />
for n in range(0,L):<br />
c2[n][0] = c2[n][0] * U[0][0] + c2[n][1] * U[1][0] + c2[n][2] * U[2][0]<br />
c2[n][1] = c2[n][0] * U[0][1] + c2[n][1] * U[1][1] + c2[n][2] * U[2][1]<br />
c2[n][2] = c2[n][0] * U[0][2] + c2[n][1] * U[1][2] + c2[n][2] * U[2][2]<br />
<br />
return c2<br />
<br />
def writeU( self, U, fileName ):<br />
"""<br />
Convenience function. Writes U to disk.<br />
<br />
"""<br />
<br />
if ( len(fileName) == 0 ):<br />
fileName = "./U"<br />
<br />
outFile = open( fileName, "wb")<br />
for i in range(0,3):<br />
for j in range(0,3):<br />
outFile.write( str(U[i][j]).ljust(20) )<br />
outFile.write("\n")<br />
outFile.close() <br />
<br />
<br />
<br />
def optAlign( sel1, sel2 ):<br />
"""<br />
optAlign performs the Kabsch alignment algorithm upon the alpha-carbons of two selections.<br />
Example: optAlign MOL1 and i. 20-40, MOL2 and i. 102-122<br />
Example 2: optAlign 1GGZ and i. 4-146 and n. CA, 1CLL and i. 4-146 and n. CA<br />
<br />
Two RMSDs are returned. One comes from the Kabsch algorithm and the other from<br />
PyMol based upon your selections.<br />
<br />
By default, this program will optimally align the ALPHA CARBONS of the selections provided.<br />
To turn off this feature remove the lines between the commented "REMOVE ALPHA CARBONS" below.<br />
<br />
@param sel1: First PyMol selection with N-atoms<br />
@param sel2: Second PyMol selection with N-atoms<br />
"""<br />
cmd.reset()<br />
<br />
# make the lists for holding coordinates<br />
# partial lists<br />
stored.sel1 = []<br />
stored.sel2 = []<br />
# full lists<br />
stored.mol1 = []<br />
stored.mol2 = []<br />
<br />
# now put the coordinates into a list<br />
# partials<br />
<br />
# -- REMOVE ALPHA CARBONS<br />
sel1 = sel1 + " and N. CA"<br />
sel2 = sel2 + " and N. CA"<br />
# -- REMOVE ALPHA CARBONS<br />
<br />
cmd.iterate_state(1, selector.process(sel1), "stored.sel1.append([x,y,z])")<br />
cmd.iterate_state(1, selector.process(sel2), "stored.sel2.append([x,y,z])")<br />
# full molecule<br />
mol1 = cmd.identify(sel1,1)[0][0]<br />
mol2 = cmd.identify(sel2,1)[0][0]<br />
cmd.iterate_state(1, mol1, "stored.mol1.append([x,y,z])")<br />
cmd.iterate_state(1, mol2, "stored.mol2.append([x,y,z])")<br />
<br />
K = kabsch()<br />
U, T1, T2, RMSD, c1, c2 = K.align(stored.sel1, stored.sel2, [])<br />
<br />
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)<br />
#stored.mol1 = map(lambda v:[ v[0]+T1[0], v[1]+T1[1], v[2]+T1[2] ], stored.mol1)<br />
stored.mol1 = map(lambda v:[ v[0]+T1[0], v[1]+T1[1], v[2]+T1[2] ], stored.mol1)<br />
<br />
cmd.alter_state(1,mol1,"(x,y,z)=stored.mol1.pop(0)")<br />
cmd.alter_state(1,mol2,"(x,y,z)=stored.mol2.pop(0)")<br />
cmd.alter( 'all',"segi=''")<br />
cmd.alter('all', "chain=''")<br />
print "RMSD=%f" % cmd.rms_cur(sel1, sel2)<br />
print "MY RMSD=%f" % RMSD<br />
cmd.hide('everything')<br />
cmd.show('ribbon', sel1 + ' or ' + sel2)<br />
cmd.color('gray70', mol1 )<br />
cmd.color('paleyellow', mol2 )<br />
cmd.color('red', 'visible')<br />
cmd.show('ribbon', 'not visible')<br />
cmd.center('visible')<br />
cmd.orient()<br />
cmd.zoom('visible')<br />
<br />
cmd.extend("optAlign", optAlign) <br />
</source><br />
<br />
==References==<br />
'''[Kabsch, 1976]''' Kabsch, W. (1976).<br />
A solution for the best rotation to relate two sets of vectors.<br />
''Acta. Crystal'', 32A:922-923.<br />
<br />
'''[Kabsch, 1978]''' Kabsch, W. (1978).<br />
A discussion of the solution for the best rotation to related two sets of vectors.<br />
''Acta. Crystal'', 34A:827-828.<br />
<br />
<br />
[[Category:Script_Library|Kabsch Alignment]]<br />
[[Category:Structure_Alignment|Kabsch Alignment]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Rotamer_Toggle&diff=8054Rotamer Toggle2010-02-14T19:12:21Z<p>Cowsandmilk: /* SCRIPTS (Rotamers.py ; MyMenu.py) */</p>
<hr />
<div>===DESCRIPTION===<br />
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.<br />
*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<br />
*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).<br />
*set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles<br />
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)<br />
*createRotamerPDBs - create pdb for each rotamer of given selection ; filter by rotamer-probability<br />
<br />
===IMAGES===<br />
<gallery><br />
Image:RotamerMenu.png|Rotamer Menu for a GLN residue<br />
Image:GLURotamerComparison5.png|Rotamer Comparison of crystal structure and most common for GLU; just as an example<br />
</gallery><br />
<br />
Print out while selecting most common rotamer from above-left image (GLN residue):<br />
Given GLN:40 PHI,PSI (-171.626373291,-96.0500335693) : bin (-170,-100)<br />
CHIs: [179.18069458007812, 72.539344787597656, -47.217315673828125]<br />
Setting Chi1 to -176.9<br />
Setting Chi2 to 177.4<br />
Setting Chi3 to 0.7<br />
<br />
===SETUP===<br />
run "rotamers.py" and use functions from commandline.<br />
<br />
or<br />
<br />
To setup a rotamer menu inside the residue menu (default windows pymol installation):<br />
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py<br />
*copy mymenu.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)<br />
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)<br />
This is only one possible way to do this, I am sure there are many others. I'm not going to post the bbdep, but there is a link in the References section to Dunbrack's download page (get the "sorted" lib)<br />
<br />
===NOTES / STATUS===<br />
*Tested on Pymolv0.97, Windows platform, Red Hat Linux 9.0 and Fedora Core 4. Will test v0.98 and MacOSX later on.<br />
*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.<br />
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu<br />
<br />
TASKS TODO:<br />
*Rotamer Movie, using mset, etc create movie to watch cycle through rotamers<br />
*Code could be organized a bit better; due to time constraints this is good for now..<br />
<br />
TASKS DONE:<br />
*Store crystal structure in rotamer menu, so you can go back to original orientation<br />
<br />
===USAGE===<br />
colorRotamers selection<br />
set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]<br />
set_phipsi selection phi_angle, psi_angle<br />
createRotamerPBDs selection [,ncutoff] [,pcutoff] [,prefix]<br />
<br />
===EXAMPLES===<br />
colorRotamers chain A<br />
set_rotamer resi 40, -60,-40 (only set chi1,chi2 angles)<br />
set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)<br />
createRotamerPDBs resi 10-12, ncutoff=3 (create 9 PDBs; each with one of the 3 most probable rotamers for resi 10,11,12)<br />
createRotamerPDBs resi 14, pcutoff=0.4 (create a pdb file for each rotamer of residue 14 with probablity > 0.4)<br />
<br />
===REFERENCES===<br />
Dunbrack and Cohen. Protein Science 1997<br />
<br />
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]<br />
<br />
===SCRIPTS (Rotamers.py ; MyMenu.py)===<br />
Rotamers.py <br />
<source lang="python"><br />
##################################################################<br />
# File: Rotamers.py<br />
# Author: Dan Kulp<br />
# Creation Date: 6/8/05<br />
# Contact: dwkulp@mail.med.upenn.edu<br />
#<br />
# Notes:<br />
# Incorporation of Rotamer library<br />
# readRotLib() - fills rotdat; <br />
# indexed by "RES:PHI_BIN:PSI_BIN".<br />
#<br />
# Three main functions:<br />
# 1. colorRotamers - colors according<br />
# to rotamer probablitity<br />
# 2. getBins(sel)<br />
# phi,psi bin for rotamer<br />
# 3. set_rotamer - set a side-chain <br />
# to a specific rotamer<br />
#<br />
# To setup a rotamer menu in the <br />
# right click, under "Residue"<br />
# 1. cp mymenu.py modules/pymol/menu.py<br />
# 2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)<br />
#<br />
# Requirements:<br />
# set ROTLIB to path for rotamer library<br />
# Reference: <br />
# Dunbrack and Cohen. Protein Science 1997<br />
####################################################################<br />
<br />
import colorsys,sys<br />
import re<br />
import editing<br />
import os<br />
import cmd<br />
import math<br />
<br />
# Path for library<br />
ROTLIB=os.environ['PYMOL_PATH']+"/modules/pymol/bbdep02.May.sortlib"<br />
<br />
# Place for library in memory..<br />
rotdat = {}<br />
<br />
def readRotLib():<br />
# Column indexes in rotamer library..<br />
RES = 0<br />
PHI = 1<br />
PSI = 2<br />
PROB = 8<br />
CHI1 = 9<br />
CHI2 = 10<br />
CHI3 = 11<br />
CHI4 = 12<br />
<br />
if os.path.exists(ROTLIB):<br />
print "File exists: "+ROTLIB<br />
input = open(ROTLIB, 'r')<br />
for line in input:<br />
<br />
# Parse by whitespace (I believe format is white space and not fixed-width columns)<br />
dat = re.split("\s+",line)<br />
<br />
# Add to rotamer library in memory : <br />
# key format RES:PHI_BIN:PSI_BIN<br />
# value format PROB, CHI1, CHI2, CHI3, CHI4<br />
key=dat[RES]+":"+dat[PHI]+":"+dat[PSI]<br />
if key in rotdat:<br />
rotdat[key].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])<br />
else:<br />
rotdat[key] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]<br />
<br />
<br />
else:<br />
print "Couldn't find Rotamer library"<br />
<br />
<br />
# Atoms for each side-chain angle for each residue<br />
CHIS = {}<br />
CHIS["ARG"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","NE" ],<br />
["CG","CD","NE","CZ" ]<br />
]<br />
<br />
CHIS["ASN"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","OD2" ]<br />
]<br />
<br />
CHIS["ASP"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","OD1" ]<br />
]<br />
CHIS["CYS"] = [ ["N","CA","CB","SG" ]<br />
]<br />
<br />
CHIS["GLN"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","OE1"]<br />
]<br />
<br />
CHIS["GLU"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","OE1"]<br />
]<br />
<br />
CHIS["HIS"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","ND1"]<br />
]<br />
<br />
CHIS["ILE"] = [ ["N","CA","CB","CG1" ],<br />
["CA","CB","CG1","CD1" ]<br />
]<br />
<br />
CHIS["LEU"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["LYS"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","CE"],<br />
["CG","CD","CE","NZ"]<br />
]<br />
<br />
CHIS["MET"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","SD" ],<br />
["CB","CG","SD","CE"]<br />
]<br />
<br />
CHIS["PHE"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["PRO"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ]<br />
]<br />
<br />
CHIS["SER"] = [ ["N","CA","CB","OG" ]<br />
]<br />
<br />
CHIS["THR"] = [ ["N","CA","CB","OG1" ]<br />
]<br />
<br />
CHIS["TRP"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1"]<br />
]<br />
<br />
CHIS["TYR"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["VAL"] = [ ["N","CA","CB","CG1" ]<br />
]<br />
<br />
# Color Rotamer by side-chain angle position<br />
# 'bin' side-chain angles into closest<br />
def colorRotamers(sel):<br />
doRotamers(sel)<br />
<br />
# Utility function, to set phi,psi angles for a given selection<br />
# Note: Cartoon, Ribbon functionality will not display correctly after this<br />
def set_phipsi(sel, phi,psi):<br />
doRotamers(sel,angles=[phi,psi],type="set")<br />
<br />
# Set a rotamer, based on a selection, a restype and chi angles<br />
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):<br />
at = cmd.get_model("byres ("+sel+")").atom[0]<br />
<br />
list = [chi1,chi2,chi3,chi4]<br />
for i in range(len(CHIS[at.resn])):<br />
print "Setting Chi"+str(i+1)+" to "+str(list[i])<br />
editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],<br />
sel + ' and name '+CHIS[at.resn][i][1],<br />
sel + ' and name '+CHIS[at.resn][i][2],<br />
sel + ' and name '+CHIS[at.resn][i][3], str(list[i]))<br />
<br />
# Remove some objects that got created<br />
cmd.delete("pk1")<br />
cmd.delete("pk2")<br />
cmd.delete("pkmol")<br />
<br />
# Get Phi,Psi bins for given selection<br />
# WARNING: assume selection is single residue (will only return first residue bins)<br />
def getBins(sel):<br />
return doRotamers(sel, type="bins")<br />
<br />
# Color Ramp...<br />
def rot_color(vals): <br />
nbins = 10<br />
vals.sort(key=lambda x:x[1])<br />
# print "End sort: "+str(len(vals))+" : "+str(nbins)<br />
<br />
<br />
# Coloring scheme...<br />
j = 0<br />
rgb = [0.0,0.0,0.0]<br />
sel_str = ""<br />
for i in range(len(vals)):<br />
if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:<br />
hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)<br />
<br />
#convert to rgb and append to color list<br />
rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])<br />
if j < nbins-1:<br />
j += 1<br />
<br />
cmd.set_color("RotProbColor"+str(i), rgb)<br />
cmd.color("RotProbColor"+str(i), str(vals[i][0]))<br />
<br />
<br />
# Main function<br />
def doRotamers(sel,angles=[], type="color"):<br />
<br />
# Read in Rotamer library if not already done<br />
if len(rotdat) == 0:<br />
readRotLib()<br />
<br />
# Set up some variables..<br />
residues = ['dummy'] # Keep track of residues already done<br />
probs = [] # probability of each residue conformation<br />
phi = 0 # phi,psi angles of current residue<br />
psi = 0<br />
<br />
# Get atoms from selection<br />
atoms = cmd.get_model("byres ("+sel+")")<br />
<br />
# Loop through atoms in selection<br />
for at in atoms.atom:<br />
try:<br />
# Don't process Glycines or Alanines<br />
if not (at.resn == 'GLY' or at.resn == 'ALA'):<br />
if at.chain+":"+at.resn+":"+at.resi not in residues:<br />
residues.append(at.chain+":"+at.resn+":"+at.resi)<br />
<br />
# Check for a null chain id (some PDBs contain this) <br />
unit_select = ""<br />
if at.chain != "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue i-1, i and i+1<br />
residue_def = unit_select+'resi '+str(at.resi)<br />
residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)<br />
residue_def_next = unit_select+'resi '+str(int(at.resi)+1)<br />
<br />
# Compute phi/psi angle<br />
<br />
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')<br />
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')<br />
if type == "set":<br />
print "Changing "+at.resn+str(at.resi)+" from "+str(phi)+","+str(psi)+" to "+str(angles[0])+","+str(angles[1])<br />
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])<br />
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])<br />
continue<br />
<br />
# Find correct 10x10 degree bin <br />
phi_digit = abs(int(phi)) - abs(int(phi/10)*10)<br />
psi_digit = abs(int(psi)) - abs(int(psi/10)*10)<br />
<br />
# Remember sign of phi,psi angles<br />
phi_sign = 1<br />
if phi < 0: phi_sign = -1<br />
<br />
psi_sign = 1<br />
if psi < 0: psi_sign = -1<br />
<br />
# Compute phi,psi bins<br />
phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)<br />
if phi_digit >= 5: phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)<br />
<br />
psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)<br />
if psi_digit >= 5: psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)<br />
<br />
print "Given "+at.resn+":"+at.resi+" PHI,PSI ("+str(phi)+","+str(psi)+") : bin ("+str(phi_bin)+","+str(psi_bin)+")"<br />
<br />
<br />
# Get current chi angle measurements<br />
chi = []<br />
for i in range(len(CHIS[at.resn])):<br />
chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],<br />
residue_def + ' and name '+CHIS[at.resn][i][1],<br />
residue_def + ' and name '+CHIS[at.resn][i][2],<br />
residue_def + ' and name '+CHIS[at.resn][i][3]))<br />
print "CHIs: "+str(chi)<br />
if type == 'bins':<br />
return [at.resn, phi_bin,psi_bin]<br />
<br />
# Compute probabilities for given chi angles<br />
prob = 0<br />
prob_box = 22 <br />
for item in range(len(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)])):<br />
print "Rotamer from db: "+str(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item])<br />
if chi[0]:<br />
if chi[0] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) - (prob_box/2) and \<br />
chi[0] <= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) + (prob_box/2):<br />
if len(chi) == 1:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[1] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) - (prob_box/2) and \<br />
float(chi[1] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) + (prob_box/2):<br />
if len(chi) == 2:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[2] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) - (prob_box/2) and \<br />
float(chi[2] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) + (prob_box/2):<br />
if len(chi) == 3:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[3] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) - (prob_box/2) and \<br />
float(chi[3] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) + (prob_box/2):<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
<br />
<br />
print "PROB OF ROTAMER: "+str(prob)<br />
print "---------------------------"<br />
probs.append([residue_def, prob])<br />
<br />
except:<br />
# probs.append([residue_def, -1])<br />
print "Exception found"<br />
continue<br />
<br />
# Color according to rotamer probability<br />
rot_color(probs)<br />
<br />
<br />
<br />
<br />
# Create PDB files containing most probable rotamers<br />
def createRotamerPDBs(sel,ncutoff=10,pcutoff=0,prefix="ROTAMER"):<br />
<br />
# Get atoms from selection<br />
atoms = cmd.get_model("byres ("+sel+")")<br />
<br />
# Set up some variables..<br />
residues = ['dummy'] # Keep track of residues already done<br />
<br />
# Loop through atoms in selection<br />
for at in atoms.atom:<br />
if at.resn in ('GLY','ALA') or "%s:%s:%s" % (at.chain,at.resn,at.resi) in residues:<br />
continue<br />
<br />
# Add to residue list (keep track of which ones we've done)<br />
residues.append("%s:%s:%s" % (at.chain,at.resn,at.resi))<br />
<br />
# Check for a null chain id (some PDBs contain this)<br />
unit_select = ""<br />
if not at.chain == "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue <br />
residue_def = unit_select+'resi '+str(at.resi)<br />
<br />
# Get bin (phi,psi) definitions for this residue<br />
bin = doRotamers(residue_def, type='bins')<br />
<br />
# Store crystal angle<br />
crystal_angles = [0.0,0.0,0.0,0.0]<br />
for angle in range(3):<br />
try:<br />
crystal_angles[angle] = bin[3][angle]<br />
except IndexError:<br />
break<br />
<br />
# Retreive list of rotamers for this phi,psi bin + residue type<br />
match_rotamers = rotdat["%s:%s:%s" % (bin[0],str(bin[1]),str(bin[2]))]<br />
<br />
count = 0<br />
for item in range(len(match_rotamers)):<br />
<br />
# Store probablity<br />
prob = match_rotamers[item][0]<br />
<br />
# Check cutoffs<br />
if float(prob) <= float(pcutoff):<br />
continue<br />
<br />
if float(count) >= float(ncutoff):<br />
break<br />
<br />
# Increment count<br />
count += 1<br />
<br />
# Output to screen ...<br />
print "Residue %s%s, rotamer %i, prob %s" % (str(at.resn),str(at.resi),int(item),str(prob))<br />
<br />
# Set to new rotamer<br />
set_rotamer(residue_def,match_rotamers[item][1],match_rotamers[item][2],match_rotamers[item][3],match_rotamers[item][4]) <br />
<br />
# Store in PDB file<br />
cmd.save("%s_%s%s_%i_%s.pdb" % (prefix,str(at.resn),str(at.resi),int(item),str(prob)))<br />
<br />
# Reset crystal angle<br />
set_rotamer(residue_def,crystal_angles[0],crystal_angles[1],crystal_angles[2],crystal_angles[3])<br />
<br />
# Uncommenting this is nice because it loads rotamer library upon startup<br />
# however, it slows the PyMOL loading process a lot<br />
# instead I've put this call into the menuing code..<br />
# readRotLib()<br />
<br />
cmd.extend('set_phipsi',set_phipsi)<br />
cmd.extend('set_rotamer',set_rotamer)<br />
cmd.extend('colorRotamers',colorRotamers)<br />
cmd.extend('createRotamerPDBs',createRotamerPDBs)<br />
</source><br />
<br />
MyMenu.py<br />
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<br />
<br />
1. In the "pick_option(title,s,object=0)" function of menu.py add the following code after the first "result =" statement<br />
<source lang="python"><br />
# Edit dwkulp 6/11/05 , add a rotamer menu to residue menu<br />
if title == 'Residue':<br />
result.extend([[ 1, 'rotamers' , rotamer_menu(s)]])<br />
</source><br />
<br />
2. At the end of the file add this:<br />
<source lang="python"><br />
###############################################<br />
# Dan Kulp<br />
# Added Rotamer list to residue menu..<br />
# rotamer.py must be importable (I placed it in <br />
# the same directory as menu.py)<br />
###############################################<br />
<br />
import rotamers<br />
<br />
<br />
def rotamer_menu(s):<br />
# Check for rotamer library being loaded<br />
if not rotamers.rotdat:<br />
rotamers.readRotLib()<br />
# return [ [2, "Must run rotamers.py first",'']]<br />
<br />
# Check for valid rotamer residue..<br />
res = cmd.get_model("byres ("+s+")").atom[0].resn<br />
if not res in rotamers.CHIS.keys():<br />
return [ [2, "Residue: "+res+" not known sidechain or does not have rotamers", '']]<br />
<br />
# Get PHI,PSI bins for rotamer (also prints out current phi,psi, chi1,chi2,chi3,chi4)<br />
bins = rotamers.doRotamers(s,type='bins')<br />
<br />
# Add a title to the menu<br />
result = [ [2, bins[0]+' Rotamers in bin ('+str(bins[1])+','+str(bins[2])+')','' ], [1, ':::PROB,CHI1,CHI2,CHI3,CHI4:::','']]<br />
<br />
# Grab the entries for this residue and phi,psi bins<br />
match_rotamers = rotamers.rotdat[bins[0]+":"+str(bins[1])+":"+str(bins[2])]<br />
<br />
# Set max number of rotamers to display (probably should be somewhere 'higher up' in the code)<br />
max_rotamers = min(10, len(match_rotamers))<br />
<br />
# Create menu entry for each possible rotamer<br />
for item in range(max_rotamers):<br />
result.append( [ 1, str(match_rotamers[item]), 'rotamers.set_rotamer("'+s+'","'\<br />
+str(match_rotamers[item][1])+'","'\<br />
+str(match_rotamers[item][2])+'","'\<br />
+str(match_rotamers[item][3])+'","'\<br />
+str(match_rotamers[item][4])+'")'])<br />
return result<br />
<br />
<br />
</source><br />
<br />
<br />
[[Category:Script_Library|Rotamer Toggle]]<br />
<br />
[[Category:Structural_Biology_Scripts|Rotamer Toggle]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Modevectors&diff=8053Modevectors2010-02-14T19:11:30Z<p>Cowsandmilk: /* PYMOL API */</p>
<hr />
<div>[[Image:Modevectors.png|right|thumb|250px|Example showing modevectors in action. (See Examples below).]]<br />
<br />
===DESCRIPTION=== <br />
'''modevectors.py''' is a PyMol script that was originally written to visualize results obtained from Normal Mode Analysis (NMA) by drawing arrows or vectors from a starting structure to a final structure. However, this script can be used to visualize the direction of motion between two specified states (e.g. targeted MD, comparing open and closed structures, etc). The strength of this script is that the arrows are highly customizable with numerous options to choose from (see script below). It is important to note that the two states MUST be identical except for the X, Y, and Z coordinates. That is, you cannot draw vectors between homologous structures. The default settings sets the background to white and displays the arrows along with the first object frame (in cartoon representation).<br />
<br />
<br />
Note: Ray tracing these CGO arrows appears to be a memory intensive process so please save a session before ray tracing and use "pymol -qc" where necessary. If anybody can come up with a method to improve this please e-mail me (see address in script).<br />
<br />
Update: A new way of drawing the arrows has been implemented for PyMOL v.1.1 and has been updated in this code (which automatically detects the version that you are using). The new method uses the built in cone primitive rather than concentric circles decreasing in size. Thus, the new method is much less memory intensive and is a significant improvement over the old method. Additionally, you may want to turn off [[ray shadow]] depending on the [[scene]] that you are viewing as shadows can be confusing to others when seen in publications.<br />
<br />
===USAGE===<br />
<br />
load the script using the [[run]] command<br />
<br />
<source lang="python"><br />
modevectors first_obj_frame, last_obj_frame [,outname=modevectors [,head=1.0 [,tail=0.3 \<br />
[,head_length=1.5 [,headrgb=(1.0,1.0,1.0) [,tailrgb=(1.0,1.0,1.0) [,cutoff=4.0 [,skip=0 \<br />
[,cut=0.5 [,atom=CA [,stat=show [,factor=1.0]]]]]]]]]]]<br />
</source><br />
<br />
Please see the script comments for further custom options. Once the script completes, it will generate a new object called "modevectors" (which can be changed through the options).<br />
<br />
<br />
===EXAMPLES===<br />
<source lang="python"><br />
modevectors 1E3M, 1W7A<br />
modevectors 1E3M, 1W7A, outname="arrows"<br />
modevectors 1E3M, 1W7A, atom="P"<br />
</source><br />
<br />
Copy/paste the following code to see an example of modevectors. This uses a multistate protein and the arrows are connected between the first and last states.<br />
<source lang="python"><br />
# load the code<br />
run modevectors.py<br />
# fetch the PDBs from pdb.org<br />
fetch 1c3y, finish=1, multiplex=0<br />
# separate the first and last states of the NMR ensemble to individual objects<br />
split_states 1c3y, 1, 1<br />
split_states 1c3y, 23, 23<br />
hide<br />
# run the modevectors code<br />
modevectors 1c3y_0001, 1c3y_0023<br />
# just setup a nice representation<br />
as cartoon, 1c3y_0001 or 1c3y_0023<br />
show cgo, modevectors<br />
color marine, 1c3y_0001<br />
color purpleblue, 1c3y_0023<br />
</source><br />
<br />
The following set of examples will illustrate the power of each optional argument. Each example should be compared to the default figure in the table below.<br />
<br />
{|<br />
|[[Image:mv_default.png|thumb|300px|left|Fig.1 - Default Settings]]<br />
||[[Image:mv_fig2.png|thumb|300px|left|Fig.2 - Arrow direction drawn from CA to CA]]<br />
||[[Image:mv_fig3.png|thumb|300px|left|Fig.3 - Arrow head radius]]<br />
|-<br />
|[[Image:mv_fig4.png|thumb|300px|left|Fig.4 - Arrow tail radius]]<br />
||[[Image:mv_fig5.png|thumb|300px|left|Fig.5 - Arrow head length]]<br />
||[[Image:mv_fig6.png|thumb|300px|left|Fig.6 - Arrow head RGB]]<br />
|-<br />
|[[Image:mv_fig7.png|thumb|300px|left|Fig.7 - Arrow tail RGB]]<br />
||[[Image:mv_fig8.png|thumb|300px|left|Fig.8 - Arrow length cutoff]]<br />
||[[Image:mv_fig9.png|thumb|300px|left|Fig.9 - Skip every other arrow]]<br />
|-<br />
|[[Image:mv_fig10.png|thumb|300px|left|Fig.10 - Subtract value from vector length]]<br />
||[[Image:mv_fig11.png|thumb|300px|left|Fig.11 - Draw arrows from CB atoms]]<br />
||[[Image:mv_fig12.png|thumb|300px|left|Fig.12 - Shorten by 50%]]<br />
|-<br />
|||[[Image:mv_fig13.png|thumb|300px|left|Fig.13 - Multiple options being used (see final example below)]]<br />
<br />
|}<br />
<br />
<source lang="python"><br />
fetch 1c3y<br />
split_states 1c3y, 1, 1<br />
split_states 1c3y, 23, 23<br />
hide<br />
<br />
#This is the default setting (Fig.1)<br />
modevectors 1c3y_0001, 1c3y_0023<br />
<br />
#This is shows that the direction of the arrows is drawn from the 1c3y_0001 towards 1c3y_0023 (Fig.2)<br />
show cartoon, 1c3y_0023<br />
color red, 1c3y_0023<br />
<br />
#This controls the base radius of the cone/arrow head in angstroms (Fig.3)<br />
modevectors 1c3y_0001, 1c3y_0023, head=2.5<br />
<br />
#This controls the radius of the cylinders/arrow tails in angstroms (Fig.4)<br />
modevectors 1c3y_0001, 1c3y_0023, tail=0.75<br />
<br />
#This controls the length of the cone/arrow head in angstroms (Fig.5)<br />
#Note that this option does NOT increase the vector length but simply changes the tail length<br />
modevectors 1c3y_0001, 1c3y_0023, head_length=3.0<br />
<br />
#This controls the colour of the cone/arrow head using RGB values (Fig.6)<br />
modevectors 1c3y_0001, 1c3y_0023, headrgb=(1.0,0.0,0.0)<br />
<br />
#This controls the colour of the cylinder/arrow tails using RGB values (Fig.7)<br />
modevectors 1c3y_0001, 1c3y_0023, tailrgb=(1.0,0.0,0.0)<br />
<br />
#This controls the which vectors to show based on a specific cutoff value in angstroms. Vector lengths that are less <br />
#than the cutoff value will not be displayed (Fig.8)<br />
modevectors 1c3y_0001, 1c3y_0023, cutoff=30.0<br />
<br />
#This controls how many vectors to skip (integer value) and is useful when there are too many vectors showing. <br />
#Skip=1 will show every other arrow (Fig.9)<br />
modevectors 1c3y_0001, 1c3y_0023, skip=1<br />
<br />
#This controls how much to cut from each vector (in angstroms). Note that arrows will point in the opposite directions <br />
#when too much is cutoff (resulting in a negative vector length) (Fig.10) and should be used with caution!<br />
modevectors 1c3y_0001, 1c3y_0023, cut=15.0<br />
<br />
#This controls which atom to draw a vector from (Fig.11). Note that this is case-sensitive and is really only useful <br />
#when atom=CA or when atom=P (for DNA backbones)<br />
modevectors 1c3y_0001, 1c3y_0023, atom=CB<br />
<br />
#This controls how much to multiple the length of each vector by (percentage increase/decrease) (Fig.12)<br />
#This example halves the length of each vector (50%)<br />
modevectors 1c3y_0001, 1c3y_0023, factor=0.5<br />
<br />
#This hides the statistics which count atoms skipped, atoms counted (number of arrows showing), and number of atoms <br />
#that did not meet the cutoff and are not shown<br />
modevectors 1c3y_0001, 1c3y_0023, stat=hide<br />
<br />
#Finally, this example shows multiple options being used (Fig.13)<br />
modevectors 1c3y_0001, 1c3y_0023, head=2.0, tail=1.0, head_length=2.0, headrgb=(1.0,0.0,0.0), tailrgb=(0.0,0.0,1.0),<br />
cutoff=0.0,skip=0,cut=0,atom=CA,factor=0.8<br />
<br />
</source><br />
<br />
===PYMOL API===<br />
<source lang=python><br />
from pymol.cgo import * # get constants<br />
from math import *<br />
from pymol import cmd<br />
<br />
def modevectors( first_obj_frame, last_obj_frame, outname="modevectors", head=1.0,tail=0.3, head_length=1.5, headrgb="1.0,1.0,1.0",tailrgb="1.0,1.0,1.0",cutoff=4.0,skip=0,cut=0.5,atom="CA",stat="show",factor=1.0):<br />
"""<br />
Authors Sean Law & Srinivasa<br />
Michigan State University<br />
slaw_(at)_msu_dot_edu<br />
<br />
Editor Sacha Yee<br />
<br />
USAGE<br />
<br />
While in PyMOL<br />
<br />
Parameter Preset Type Description<br />
first_obj_frame Undefined String Object name of the first structure. The mode vector will propagate from this structure. Defined by user.<br />
last_obj_frame Undefined String Object name of the last structure. The mode vector (arrow head) will end at this structure. Defined by user.<br />
outname modevectors String Name of object to store mode vectors in.<br />
head 1.0 Float Radius for the circular base of the arrow head (cone)<br />
tail 0.3 Float Radius for the cylinder of the arrow tail (cylinder)<br />
head_length 1.5 Float Length of the arrow head (from the base of the cone to the tip of cone)<br />
head_rgb 1.0,1.0,1.0 String RGB colour for the arrow head.<br />
tail_rgb 1.0,1.0,1.0 String RGB colour for the arrow tail.<br />
cutoff 4.0 Float Skips mode vectors that do not meet the cutoff distance (in Angstroms).<br />
skip 0 Integer Denotes how many atoms to skip. No arrows will be created for skipped atoms.<br />
cut 0.0 Float Truncates all arrow tail lengths (without disturbing the arrow head) (in Angstroms).<br />
atom CA String Designates the atom to derive mode vectors from.<br />
stat show String Keeps track and prints statistics (total modevectors, skipped, cutoff).<br />
factor 1.0 Float Multiplies each mode vector length by a specified factor.<br />
Values between 0 and 1 will decrease the relative mode vector length.<br />
Values greater than 1 will increase the relative mode vector length.<br />
<br />
"""<br />
<br />
framefirst=cmd.get_model(first_obj_frame)<br />
framelast=cmd.get_model(last_obj_frame)<br />
objectname=outname<br />
factor=float(factor)<br />
arrow_head_radius=float(head)<br />
arrow_tail_radius=float(tail)<br />
arrow_head_length=float(head_length)<br />
cutoff=float(cutoff)<br />
skip=int(skip)<br />
cut=float(cut)<br />
atomtype=atom.strip('"[]()')<br />
<br />
headrgb=headrgb.strip('" []()')<br />
tailrgb=tailrgb.strip('" []()')<br />
hr,hg,hb=map(float,headrgb.split(','))<br />
tr,tg,tb=map(float,tailrgb.split(','))<br />
<br />
version=cmd.get_version()<br />
arrow=[]<br />
arrowhead = []<br />
arrowtail = []<br />
x1 = []<br />
y1 = []<br />
z1 = []<br />
x2 = []<br />
y2 = []<br />
z2 = []<br />
exit_flag=False<br />
<br />
##############################################################<br />
# #<br />
# Define an object called "tail" and store the tail and a #<br />
# circular base of the triangle in this object. #<br />
# #<br />
##############################################################<br />
<br />
skipcount=0<br />
skipcounter=0<br />
keepcounter=0<br />
atom_lookup={}<br />
for atom in framefirst.atom:<br />
if atom.name == atomtype:<br />
if skipcount == skip:<br />
x1.append(atom.coord[0])<br />
y1.append(atom.coord[1])<br />
z1.append(atom.coord[2])<br />
<br />
##########################################<br />
# #<br />
# Set atom_lookup for a specific atom #<br />
# equal to ONE for the first input set. #<br />
# This dictionary will be used as a #<br />
# reference for the second set. #<br />
# #<br />
##########################################<br />
<br />
current_atom="CHAIN "+atom.chain+" RESID "\<br />
+atom.resi+" RESTYPE "\<br />
+atom.resn+\<br />
" ATMNUM "+str(atom.index)<br />
# print current_atom<br />
atom_lookup['current_atom']=1<br />
<br />
skipcount=0<br />
keepcounter+=1<br />
else:<br />
# print skipcount<br />
skipcount+=1<br />
skipcounter+=1<br />
<br />
skipcount=0<br />
for atom in framelast.atom:<br />
if atom.name == atomtype:<br />
if skipcount == skip:<br />
x2.append(atom.coord[0])<br />
y2.append(atom.coord[1])<br />
z2.append(atom.coord[2])<br />
<br />
#########################################<br />
# #<br />
# Get atom information from second set #<br />
# and compare with first set. All #<br />
# atoms from this second set MUST be #<br />
# found in the first set! Otherwise, #<br />
# the script will exit with an error #<br />
# since modevectors can only be created #<br />
# by calculating values from identical #<br />
# sources. #<br />
# #<br />
#########################################<br />
<br />
current_atom="CHAIN "+atom.chain+" RESID "\<br />
+atom.resi+" RESTYPE "\<br />
+atom.resn+\<br />
" ATMNUM "+str(atom.index)<br />
# print current_atom<br />
if 'current_at' not in atom_lookup:<br />
print "\nError: "+current_atom+" from \""\<br />
+last_obj_frame+\<br />
" \"is not found in \""+first_obj_frame+"\"."<br />
print "\nPlease check your input and/or selections and try again."<br />
exit_flag=True<br />
break<br />
<br />
skipcount=0<br />
else:<br />
skipcount+=1<br />
<br />
if exit_flag == 1:<br />
###########################################<br />
# #<br />
# Exit script because an atom cannot be #<br />
# found in both input files #<br />
# #<br />
###########################################<br />
return<br />
<br />
cutoff_counter=0 # Track number of atoms failing to meet the cutoff<br />
<br />
###################################################<br />
# #<br />
# Check that the two selections/PDB files contain #<br />
# the same number of atoms. #<br />
# #<br />
###################################################<br />
<br />
if len(x2) != len(x1):<br />
print "\nError: \""+first_obj_frame+\<br />
"\" and \""+last_obj_frame+\<br />
"\" contain different number of residue/atoms."<br />
print "\nPlease check your input and/or selections and try again."<br />
return<br />
else:<br />
#Continue with representing modevectors!<br />
#########################################<br />
# #<br />
# Delete old selection or object if it #<br />
# exists so that it can be overwritten #<br />
# #<br />
#########################################<br />
save_view=cmd.get_view(output=1,quiet=1)<br />
cmd.delete(name=outname)<br />
cmd.hide(representation="everything",selection=first_obj_frame)<br />
cmd.hide(representation="everything",selection=last_obj_frame)<br />
<br />
<br />
<br />
###################################################<br />
# #<br />
# Begin drawing arrow tails #<br />
# #<br />
###################################################<br />
<br />
arrowtail = []<br />
for mv in range(len(x1)):<br />
vectorx=x2[mv]-x1[mv]<br />
vectory=y2[mv]-y1[mv]<br />
vectorz=z2[mv]-z1[mv]<br />
length=sqrt(vectorx**2+vectory**2+vectorz**2)<br />
if length < cutoff:<br />
cutoff_counter+=1<br />
continue<br />
t=1.0-(cut/length)<br />
x2[mv]=x1[mv]+factor*t*vectorx<br />
y2[mv]=y1[mv]+factor*t*vectory<br />
z2[mv]=z1[mv]+factor*t*vectorz<br />
vectorx=x2[mv]-x1[mv]<br />
vectory=y2[mv]-y1[mv]<br />
vectorz=z2[mv]-z1[mv]<br />
length=sqrt(vectorx**2+vectory**2+vectorz**2)<br />
d=arrow_head_length # Distance from arrow tip to arrow base<br />
t=1.0-(d/length)<br />
tail = [<br />
# Tail of cylinder<br />
CYLINDER, x1[mv],y1[mv],z1[mv]\<br />
,x1[mv]+(t+0.01)*vectorx,y1[mv]+(t+0.01)*vectory,z1[mv]+(t+0.01)*vectorz\<br />
,arrow_tail_radius,tr,tg,tb,tr,tg,tb # Radius and RGB for each cylinder tail<br />
]<br />
arrow.extend(tail)<br />
<br />
x=x1[mv]+t*vectorx<br />
y=y1[mv]+t*vectory<br />
z=z1[mv]+t*vectorz<br />
dx=x2[mv]-x<br />
dy=y2[mv]-y<br />
dz=z2[mv]-z<br />
seg=d/100<br />
intfactor=int(factor)<br />
if version < 1.1: #Version >= 1.1 has cone primitive<br />
for i in range (100,0,-1): #i=100 is tip of cone<br />
print i<br />
t1=seg*i<br />
t2=seg*(i+1)<br />
radius=arrow_head_radius*(1.0-i/(100.0)) #Radius of each disc that forms cone<br />
head=[<br />
CYLINDER, x+t2*dx,y+t2*dy,z+t2*dz\<br />
,x+t1*dx,y+t1*dy,z+t1*dz\<br />
,radius,hr,hg,hb,hr,hg,hb # Radius and RGB for slice of arrow head<br />
]<br />
arrow.extend(head)<br />
else:<br />
head=[<br />
CONE, x, y ,z, x+d*dx, y+d*dy, z+d*dz, arrow_head_radius, 0.0, hr, hg, hb, hr, hg, hb, 1.0, 1.0 ]<br />
arrow.extend(head)<br />
<br />
##############################################################<br />
# #<br />
# Load the entire object into PyMOL #<br />
# #<br />
# Print statistics if requested by user #<br />
# #<br />
##############################################################<br />
<br />
if stat == "show":<br />
natoms=skipcounter+keepcounter<br />
print "\nTotal number of atoms = "+str(natoms)<br />
print "Atoms skipped = "+str(skipcounter)<br />
if keepcounter-cutoff_counter > 0:<br />
print "Atoms counted = "+str(keepcounter-cutoff_counter)+" (see PyMOL object \""+outname+"\")"<br />
else:<br />
print "Atoms counted = "+str(keepcounter-cutoff_counter)+" (Empty CGO object not loaded)" <br />
print "Atoms cutoff = "+str(cutoff_counter) #Note that cutoff occurs AFTER skipping!<br />
if keepcounter-cutoff_counter > 0:<br />
cmd.load_cgo(arrow,objectname) #Ray tracing an empty object will cause a segmentation fault. No arrows = Do not display in PyMOL!!!<br />
cmd.show(representation="cartoon",selection=first_obj_frame)<br />
cmd.cartoon("tube")<br />
cmd.show(representation="cartoon",selection=last_obj_frame)<br />
cmd.hide(representation="cartoon",selection=last_obj_frame)<br />
cmd.bg_color(color="white")<br />
cmd.set_view(save_view)<br />
return<br />
<br />
cmd.extend("modevectors",modevectors)<br />
</source><br />
[[Category:Script_Library]]<br />
[[Category:Math_Scripts]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Modevectors&diff=8052Modevectors2010-02-14T19:10:36Z<p>Cowsandmilk: Undo revision 8035 by Cowsandmilk (Talk)</p>
<hr />
<div>[[Image:Modevectors.png|right|thumb|250px|Example showing modevectors in action. (See Examples below).]]<br />
<br />
===DESCRIPTION=== <br />
'''modevectors.py''' is a PyMol script that was originally written to visualize results obtained from Normal Mode Analysis (NMA) by drawing arrows or vectors from a starting structure to a final structure. However, this script can be used to visualize the direction of motion between two specified states (e.g. targeted MD, comparing open and closed structures, etc). The strength of this script is that the arrows are highly customizable with numerous options to choose from (see script below). It is important to note that the two states MUST be identical except for the X, Y, and Z coordinates. That is, you cannot draw vectors between homologous structures. The default settings sets the background to white and displays the arrows along with the first object frame (in cartoon representation).<br />
<br />
<br />
Note: Ray tracing these CGO arrows appears to be a memory intensive process so please save a session before ray tracing and use "pymol -qc" where necessary. If anybody can come up with a method to improve this please e-mail me (see address in script).<br />
<br />
Update: A new way of drawing the arrows has been implemented for PyMOL v.1.1 and has been updated in this code (which automatically detects the version that you are using). The new method uses the built in cone primitive rather than concentric circles decreasing in size. Thus, the new method is much less memory intensive and is a significant improvement over the old method. Additionally, you may want to turn off [[ray shadow]] depending on the [[scene]] that you are viewing as shadows can be confusing to others when seen in publications.<br />
<br />
===USAGE===<br />
<br />
load the script using the [[run]] command<br />
<br />
<source lang="python"><br />
modevectors first_obj_frame, last_obj_frame [,outname=modevectors [,head=1.0 [,tail=0.3 \<br />
[,head_length=1.5 [,headrgb=(1.0,1.0,1.0) [,tailrgb=(1.0,1.0,1.0) [,cutoff=4.0 [,skip=0 \<br />
[,cut=0.5 [,atom=CA [,stat=show [,factor=1.0]]]]]]]]]]]<br />
</source><br />
<br />
Please see the script comments for further custom options. Once the script completes, it will generate a new object called "modevectors" (which can be changed through the options).<br />
<br />
<br />
===EXAMPLES===<br />
<source lang="python"><br />
modevectors 1E3M, 1W7A<br />
modevectors 1E3M, 1W7A, outname="arrows"<br />
modevectors 1E3M, 1W7A, atom="P"<br />
</source><br />
<br />
Copy/paste the following code to see an example of modevectors. This uses a multistate protein and the arrows are connected between the first and last states.<br />
<source lang="python"><br />
# load the code<br />
run modevectors.py<br />
# fetch the PDBs from pdb.org<br />
fetch 1c3y, finish=1, multiplex=0<br />
# separate the first and last states of the NMR ensemble to individual objects<br />
split_states 1c3y, 1, 1<br />
split_states 1c3y, 23, 23<br />
hide<br />
# run the modevectors code<br />
modevectors 1c3y_0001, 1c3y_0023<br />
# just setup a nice representation<br />
as cartoon, 1c3y_0001 or 1c3y_0023<br />
show cgo, modevectors<br />
color marine, 1c3y_0001<br />
color purpleblue, 1c3y_0023<br />
</source><br />
<br />
The following set of examples will illustrate the power of each optional argument. Each example should be compared to the default figure in the table below.<br />
<br />
{|<br />
|[[Image:mv_default.png|thumb|300px|left|Fig.1 - Default Settings]]<br />
||[[Image:mv_fig2.png|thumb|300px|left|Fig.2 - Arrow direction drawn from CA to CA]]<br />
||[[Image:mv_fig3.png|thumb|300px|left|Fig.3 - Arrow head radius]]<br />
|-<br />
|[[Image:mv_fig4.png|thumb|300px|left|Fig.4 - Arrow tail radius]]<br />
||[[Image:mv_fig5.png|thumb|300px|left|Fig.5 - Arrow head length]]<br />
||[[Image:mv_fig6.png|thumb|300px|left|Fig.6 - Arrow head RGB]]<br />
|-<br />
|[[Image:mv_fig7.png|thumb|300px|left|Fig.7 - Arrow tail RGB]]<br />
||[[Image:mv_fig8.png|thumb|300px|left|Fig.8 - Arrow length cutoff]]<br />
||[[Image:mv_fig9.png|thumb|300px|left|Fig.9 - Skip every other arrow]]<br />
|-<br />
|[[Image:mv_fig10.png|thumb|300px|left|Fig.10 - Subtract value from vector length]]<br />
||[[Image:mv_fig11.png|thumb|300px|left|Fig.11 - Draw arrows from CB atoms]]<br />
||[[Image:mv_fig12.png|thumb|300px|left|Fig.12 - Shorten by 50%]]<br />
|-<br />
|||[[Image:mv_fig13.png|thumb|300px|left|Fig.13 - Multiple options being used (see final example below)]]<br />
<br />
|}<br />
<br />
<source lang="python"><br />
fetch 1c3y<br />
split_states 1c3y, 1, 1<br />
split_states 1c3y, 23, 23<br />
hide<br />
<br />
#This is the default setting (Fig.1)<br />
modevectors 1c3y_0001, 1c3y_0023<br />
<br />
#This is shows that the direction of the arrows is drawn from the 1c3y_0001 towards 1c3y_0023 (Fig.2)<br />
show cartoon, 1c3y_0023<br />
color red, 1c3y_0023<br />
<br />
#This controls the base radius of the cone/arrow head in angstroms (Fig.3)<br />
modevectors 1c3y_0001, 1c3y_0023, head=2.5<br />
<br />
#This controls the radius of the cylinders/arrow tails in angstroms (Fig.4)<br />
modevectors 1c3y_0001, 1c3y_0023, tail=0.75<br />
<br />
#This controls the length of the cone/arrow head in angstroms (Fig.5)<br />
#Note that this option does NOT increase the vector length but simply changes the tail length<br />
modevectors 1c3y_0001, 1c3y_0023, head_length=3.0<br />
<br />
#This controls the colour of the cone/arrow head using RGB values (Fig.6)<br />
modevectors 1c3y_0001, 1c3y_0023, headrgb=(1.0,0.0,0.0)<br />
<br />
#This controls the colour of the cylinder/arrow tails using RGB values (Fig.7)<br />
modevectors 1c3y_0001, 1c3y_0023, tailrgb=(1.0,0.0,0.0)<br />
<br />
#This controls the which vectors to show based on a specific cutoff value in angstroms. Vector lengths that are less <br />
#than the cutoff value will not be displayed (Fig.8)<br />
modevectors 1c3y_0001, 1c3y_0023, cutoff=30.0<br />
<br />
#This controls how many vectors to skip (integer value) and is useful when there are too many vectors showing. <br />
#Skip=1 will show every other arrow (Fig.9)<br />
modevectors 1c3y_0001, 1c3y_0023, skip=1<br />
<br />
#This controls how much to cut from each vector (in angstroms). Note that arrows will point in the opposite directions <br />
#when too much is cutoff (resulting in a negative vector length) (Fig.10) and should be used with caution!<br />
modevectors 1c3y_0001, 1c3y_0023, cut=15.0<br />
<br />
#This controls which atom to draw a vector from (Fig.11). Note that this is case-sensitive and is really only useful <br />
#when atom=CA or when atom=P (for DNA backbones)<br />
modevectors 1c3y_0001, 1c3y_0023, atom=CB<br />
<br />
#This controls how much to multiple the length of each vector by (percentage increase/decrease) (Fig.12)<br />
#This example halves the length of each vector (50%)<br />
modevectors 1c3y_0001, 1c3y_0023, factor=0.5<br />
<br />
#This hides the statistics which count atoms skipped, atoms counted (number of arrows showing), and number of atoms <br />
#that did not meet the cutoff and are not shown<br />
modevectors 1c3y_0001, 1c3y_0023, stat=hide<br />
<br />
#Finally, this example shows multiple options being used (Fig.13)<br />
modevectors 1c3y_0001, 1c3y_0023, head=2.0, tail=1.0, head_length=2.0, headrgb=(1.0,0.0,0.0), tailrgb=(0.0,0.0,1.0),<br />
cutoff=0.0,skip=0,cut=0,atom=CA,factor=0.8<br />
<br />
</source><br />
<br />
===PYMOL API===<br />
<source lang=python><br />
from pymol.cgo import * # get constants<br />
from math import *<br />
from pymol import cmd<br />
<br />
def modevectors( first_obj_frame, last_obj_frame, outname="modevectors", head=1.0,tail=0.3, head_length=1.5, headrgb="1.0,1.0,1.0",tailrgb="1.0,1.0,1.0",cutoff=4.0,skip=0,cut=0.5,atom="CA",stat="show",factor=1.0):<br />
"""<br />
Authors Sean Law & Srinivasa<br />
Michigan State University<br />
slaw_(at)_msu_dot_edu<br />
<br />
Editor Sacha Yee<br />
<br />
USAGE<br />
<br />
While in PyMOL<br />
<br />
Parameter Preset Type Description<br />
first_obj_frame Undefined String Object name of the first structure. The mode vector will propagate from this structure. Defined by user.<br />
last_obj_frame Undefined String Object name of the last structure. The mode vector (arrow head) will end at this structure. Defined by user.<br />
outname modevectors String Name of object to store mode vectors in.<br />
head 1.0 Float Radius for the circular base of the arrow head (cone)<br />
tail 0.3 Float Radius for the cylinder of the arrow tail (cylinder)<br />
head_length 1.5 Float Length of the arrow head (from the base of the cone to the tip of cone)<br />
head_rgb 1.0,1.0,1.0 String RGB colour for the arrow head.<br />
tail_rgb 1.0,1.0,1.0 String RGB colour for the arrow tail.<br />
cutoff 4.0 Float Skips mode vectors that do not meet the cutoff distance (in Angstroms).<br />
skip 0 Integer Denotes how many atoms to skip. No arrows will be created for skipped atoms.<br />
cut 0.0 Float Truncates all arrow tail lengths (without disturbing the arrow head) (in Angstroms).<br />
atom CA String Designates the atom to derive mode vectors from.<br />
stat show String Keeps track and prints statistics (total modevectors, skipped, cutoff).<br />
factor 1.0 Float Multiplies each mode vector length by a specified factor.<br />
Values between 0 and 1 will decrease the relative mode vector length.<br />
Values greater than 1 will increase the relative mode vector length.<br />
<br />
"""<br />
<br />
framefirst=cmd.get_model(first_obj_frame)<br />
framelast=cmd.get_model(last_obj_frame)<br />
objectname=outname<br />
factor=float(factor)<br />
arrow_head_radius=float(head)<br />
arrow_tail_radius=float(tail)<br />
arrow_head_length=float(head_length)<br />
cutoff=float(cutoff)<br />
skip=int(skip)<br />
cut=float(cut)<br />
atomtype=atom.strip('"[]()')<br />
<br />
headrgb=headrgb.strip('" []()')<br />
tailrgb=tailrgb.strip('" []()')<br />
hr,hg,hb=map(float,headrgb.split(','))<br />
tr,tg,tb=map(float,tailrgb.split(','))<br />
<br />
version=cmd.get_version()<br />
arrow=[]<br />
arrowhead = []<br />
arrowtail = []<br />
x1 = []<br />
y1 = []<br />
z1 = []<br />
x2 = []<br />
y2 = []<br />
z2 = []<br />
exit_flag=False<br />
<br />
##############################################################<br />
# #<br />
# Define an object called "tail" and store the tail and a #<br />
# circular base of the triangle in this object. #<br />
# #<br />
##############################################################<br />
<br />
skipcount=0<br />
skipcounter=0<br />
keepcounter=0<br />
atom_lookup={}<br />
for atom in framefirst.atom:<br />
if atom.name == atomtype:<br />
if skipcount == skip:<br />
x1.append(atom.coord[0])<br />
y1.append(atom.coord[1])<br />
z1.append(atom.coord[2])<br />
<br />
##########################################<br />
# #<br />
# Set atom_lookup for a specific atom #<br />
# equal to ONE for the first input set. #<br />
# This dictionary will be used as a #<br />
# reference for the second set. #<br />
# #<br />
##########################################<br />
<br />
current_atom="CHAIN "+atom.chain+" RESID "\<br />
+atom.resi+" RESTYPE "\<br />
+atom.resn+\<br />
" ATMNUM "+str(atom.index)<br />
# print current_atom<br />
atom_lookup['current_atom']=1<br />
<br />
skipcount=0<br />
keepcounter+=1<br />
else:<br />
# print skipcount<br />
skipcount+=1<br />
skipcounter+=1<br />
<br />
skipcount=0<br />
for atom in framelast.atom:<br />
if atom.name == atomtype:<br />
if skipcount == skip:<br />
x2.append(atom.coord[0])<br />
y2.append(atom.coord[1])<br />
z2.append(atom.coord[2])<br />
<br />
#########################################<br />
# #<br />
# Get atom information from second set #<br />
# and compare with first set. All #<br />
# atoms from this second set MUST be #<br />
# found in the first set! Otherwise, #<br />
# the script will exit with an error #<br />
# since modevectors can only be created #<br />
# by calculating values from identical #<br />
# sources. #<br />
# #<br />
#########################################<br />
<br />
current_atom="CHAIN "+atom.chain+" RESID "\<br />
+atom.resi+" RESTYPE "\<br />
+atom.resn+\<br />
" ATMNUM "+str(atom.index)<br />
# print current_atom<br />
if 'current_atom' not in atom_lookup:<br />
print "\nError: "+current_atom+" from \""\<br />
+last_obj_frame+\<br />
" \"is not found in \""+first_obj_frame+"\"."<br />
print "\nPlease check your input and/or selections and try again."<br />
exit_flag=True<br />
break<br />
<br />
skipcount=0<br />
else:<br />
skipcount+=1<br />
<br />
if exit_flag:<br />
###########################################<br />
# #<br />
# Exit script because an atom cannot be #<br />
# found in both input files #<br />
# #<br />
###########################################<br />
return<br />
<br />
cutoff_counter=0 # Track number of atoms failing to meet the cutoff<br />
<br />
###################################################<br />
# #<br />
# Check that the two selections/PDB files contain #<br />
# the same number of atoms. #<br />
# #<br />
###################################################<br />
<br />
if len(x2) != len(x1):<br />
print "\nError: \""+first_obj_frame+\<br />
"\" and \""+last_obj_frame+\<br />
"\" contain different number of residue/atoms."<br />
print "\nPlease check your input and/or selections and try again."<br />
return<br />
else:<br />
#Continue with representing modevectors!<br />
#########################################<br />
# #<br />
# Delete old selection or object if it #<br />
# exists so that it can be overwritten #<br />
# #<br />
#########################################<br />
save_view=cmd.get_view(output=1,quiet=1)<br />
cmd.delete(name=outname)<br />
cmd.hide(representation="everything",selection=first_obj_frame)<br />
cmd.hide(representation="everything",selection=last_obj_frame)<br />
<br />
<br />
<br />
###################################################<br />
# #<br />
# Begin drawing arrow tails #<br />
# #<br />
###################################################<br />
<br />
arrowtail = []<br />
for mv in range(len(x1)):<br />
vectorx=x2[mv]-x1[mv]<br />
vectory=y2[mv]-y1[mv]<br />
vectorz=z2[mv]-z1[mv]<br />
length=sqrt(vectorx**2+vectory**2+vectorz**2)<br />
if length < cutoff:<br />
cutoff_counter+=1<br />
continue<br />
t=1.0-(cut/length)<br />
x2[mv]=x1[mv]+factor*t*vectorx<br />
y2[mv]=y1[mv]+factor*t*vectory<br />
z2[mv]=z1[mv]+factor*t*vectorz<br />
vectorx=x2[mv]-x1[mv]<br />
vectory=y2[mv]-y1[mv]<br />
vectorz=z2[mv]-z1[mv]<br />
length=sqrt(vectorx**2+vectory**2+vectorz**2)<br />
d=arrow_head_length # Distance from arrow tip to arrow base<br />
t=1.0-(d/length)<br />
tail = [<br />
# Tail of cylinder<br />
CYLINDER, x1[mv],y1[mv],z1[mv]\<br />
,x1[mv]+(t+0.01)*vectorx,y1[mv]+(t+0.01)*vectory,z1[mv]+(t+0.01)*vectorz\<br />
,arrow_tail_radius,tr,tg,tb,tr,tg,tb # Radius and RGB for each cylinder tail<br />
]<br />
arrow.extend(tail)<br />
<br />
x=x1[mv]+t*vectorx<br />
y=y1[mv]+t*vectory<br />
z=z1[mv]+t*vectorz<br />
dx=x2[mv]-x<br />
dy=y2[mv]-y<br />
dz=z2[mv]-z<br />
seg=d/100<br />
intfactor=int(factor)<br />
if version < 1.1: #Version >= 1.1 has cone primitive<br />
for i in range (100,0,-1): #i=100 is tip of cone<br />
print i<br />
t1=seg*i<br />
t2=seg*(i+1)<br />
radius=arrow_head_radius*(1.0-i/(100.0)) #Radius of each disc that forms cone<br />
head=[<br />
CYLINDER, x+t2*dx,y+t2*dy,z+t2*dz\<br />
,x+t1*dx,y+t1*dy,z+t1*dz\<br />
,radius,hr,hg,hb,hr,hg,hb # Radius and RGB for slice of arrow head<br />
]<br />
arrow.extend(head)<br />
else:<br />
head=[<br />
CONE, x, y ,z, x+d*dx, y+d*dy, z+d*dz, arrow_head_radius, 0.0, hr, hg, hb, hr, hg, hb, 1.0, 1.0 ]<br />
arrow.extend(head)<br />
<br />
##############################################################<br />
# #<br />
# Load the entire object into PyMOL #<br />
# #<br />
# Print statistics if requested by user #<br />
# #<br />
##############################################################<br />
<br />
if stat == "show":<br />
natoms=skipcounter+keepcounter<br />
print "\nTotal number of atoms = "+str(natoms)<br />
print "Atoms skipped = "+str(skipcounter)<br />
if keepcounter-cutoff_counter > 0:<br />
print "Atoms counted = "+str(keepcounter-cutoff_counter)+" (see PyMOL object \""+outname+"\")"<br />
else:<br />
print "Atoms counted = "+str(keepcounter-cutoff_counter)+" (Empty CGO object not loaded)" <br />
print "Atoms cutoff = "+str(cutoff_counter) #Note that cutoff occurs AFTER skipping!<br />
if keepcounter-cutoff_counter > 0:<br />
cmd.load_cgo(arrow,objectname) #Ray tracing an empty object will cause a segmentation fault. No arrows = Do not display in PyMOL!!!<br />
cmd.show(representation="cartoon",selection=first_obj_frame)<br />
cmd.cartoon("tube")<br />
cmd.show(representation="cartoon",selection=last_obj_frame)<br />
cmd.hide(representation="cartoon",selection=last_obj_frame)<br />
cmd.bg_color(color="white")<br />
cmd.set_view(save_view)<br />
return<br />
<br />
cmd.extend("modevectors",modevectors)<br />
</source><br />
[[Category:Script_Library]]<br />
[[Category:Math_Scripts]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Wfmesh&diff=8051Wfmesh2010-02-14T19:10:01Z<p>Cowsandmilk: /* SCRIPTS (WFMesh.py) */</p>
<hr />
<div>===DESCRIPTION===<br />
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->Insert->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. <br />
<br />
*createWFMesh - create a mesh object from Wavefront (*.obj) formated file<br />
<br />
===IMAGES===<br />
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]<br />
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
[[Category:ThirdParty_Scripts]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
===SETUP===<br />
Simply "run WFMesh.py"<br />
<br />
===NOTES / STATUS===<br />
*Tested on Pymolv0.97, Windows platform, should work on linux as well.<br />
*Coloring is fixed for grey and sections of mesh are stored, but not used.<br />
*Simple opengl calls; not optimized (display lists, etc) or anything.<br />
*Vertex Normal code is broken, so normals are per polygon right now.<br />
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu<br />
<br />
<br />
===USAGE===<br />
createWFObj file, name [,translate=[0,0,0]] [,flip=0]<br />
<br />
===EXAMPLES===<br />
createWFObj "ship.obj" "Ship"<br />
createWFObj "torus.obj" "Torus" flip=1 # Flip = 1, if OBJ created by openFX, crossroads3D combination<br />
createWFObj "torus.obj" "Torus" translate=[10,10,0] flip=1 <br />
<br />
===REFERENCES===<br />
[http://www.openfx.org OpenFX]<br />
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]<br />
<br />
===SCRIPTS (WFMesh.py)===<br />
WFMesh.py<br />
<source lang="python"><br />
###############################################<br />
# File: WFObj.py<br />
# Author: Dan Kulp<br />
# Creation Date: 5/13/05<br />
#<br />
# Notes:<br />
# Create openGL objects from a wavefront (obj) file<br />
###############################################<br />
<br />
import os<br />
import re<br />
import math<br />
from pymol.opengl.gl import *<br />
from pymol.callback import Callback<br />
<br />
<br />
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)<br />
def createWFObj(file, name,translate=[0,0,0],flip=0):<br />
obj = WFMesh(file,translate,flip)<br />
cmd.load_callback(obj,name)<br />
<br />
<br />
# Class for Wavefront Mesh<br />
class WFMesh(Callback):<br />
<br />
verts = [] # list of vertices<br />
polys = [] # list of poylgons<br />
pnorms = [] # list of polynomal normals<br />
vnorms = {} # dict. of vertex normals<br />
vavenorms = [] # list of vertex normals, redundant -- I'm far froma python pro.<br />
sections = {} # list of sections of mesh<br />
<br />
# Read mesh into memory<br />
def readOBJ(self,file):<br />
if os.path.exists(file):<br />
input = open(file,'r')<br />
for line in input:<br />
dat = re.split("\s+", line)<br />
<br />
# Find vertex line<br />
if line[0] == 'v' and line[1] != 't' and line[1] != 'n': self.verts.append([dat[1],dat[2],dat[3]])<br />
<br />
# Find polygon line<br />
if line[0] == 'f': self.polys.append([dat[1],dat[2],dat[3]])<br />
<br />
# Find section line<br />
if line[0] == 'g': self.sections[len(self.polys)] = dat[1] <br />
<br />
<br />
# Compute the normals for each polygon and each vertex <br />
def computeNorms(self):<br />
<br />
# Compute norms for each polygon<br />
for p in self.polys:<br />
v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\<br />
float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\<br />
float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \<br />
]<br />
<br />
v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\<br />
float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\<br />
float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \<br />
] <br />
<br />
# Compute poly normal<br />
polynorm = self.cross(v12,v13) <br />
norm = self.normalize(polynorm)<br />
<br />
<br />
# Files created by OpenFX, Crossroads combination need have their normals flipped <br />
if self.flip:<br />
norm[0] = -norm[0]<br />
norm[1] = -norm[1]<br />
norm[2] = -norm[2]<br />
<br />
# Append poly norm to polygonal norm array<br />
self.pnorms.append(norm)<br />
<br />
# Add norm to each vertexes norm..<br />
try:<br />
self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[0])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[0])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
try: <br />
self.vnorms[int(p[1])-1] = [float(self.vnorms[int(p[1])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[1])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[1])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
try:<br />
self.vnorms[int(p[2])-1] = [float(self.vnorms[int(p[1])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[1])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[1])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
<br />
# Average out each vnorm..<br />
index = 0<br />
for v in self.vnorms.values():<br />
self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4]) <br />
index += 1<br />
<br />
# Utility function to normalize a given vector<br />
def normalize(self,v):<br />
mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]<br />
if mag <= 0:<br />
mag = 1<br />
else:<br />
mag = math.sqrt(mag)<br />
<br />
return [v[0]/mag, v[1]/mag,v[2]/mag]<br />
<br />
# Utility cross product function<br />
def cross(self,v1,v2):<br />
x = 0<br />
y = 1<br />
z = 2<br />
<br />
return [v1[y]*v2[z] - v1[z]*v2[y],\<br />
v1[z]*v2[x] - v1[x]*v2[z],\<br />
v1[x]*v2[y] - v1[y]*v2[x]<br />
]<br />
<br />
# Constructor<br />
def __init__(self, file,translate=[0,0,0],flip=0):<br />
self.verts = []<br />
self.polys = [] <br />
self.pnorms = []<br />
self.vnorms = {}<br />
self.vavenorms = []<br />
self.translate = translate<br />
self.flip = flip <br />
<br />
print "Read in file: "+str(file)<br />
self.readOBJ(file)<br />
print "Done reading in WFMesh, now compute norms"<br />
self.computeNorms()<br />
print "Done computing norms, now display WFMesh"<br />
<br />
# Draw Function<br />
def __call__(self):<br />
<br />
glColorMaterial(GL_FRONT, GL_DIFFUSE); <br />
glEnable(GL_COLOR_MATERIAL);<br />
glShadeModel(GL_SMOOTH);<br />
<br />
# Color Everything grey<br />
glColor3f(0.5,0.5,0.5);<br />
<br />
index = 0<br />
glPushMatrix()<br />
glTranslated(self.translate[0],self.translate[1],self.translate[2])<br />
for p in self.polys:<br />
glBegin(GL_POLYGON)<br />
glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))<br />
<br />
for i in range(0,len(p)):<br />
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]))<br />
<br />
# Vertex Normals - not computed correctly, so commented out for now<br />
# norm = self.vnorms[int(p[i])-1]<br />
# glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))<br />
glEnd()<br />
index += 1<br />
glPopMatrix()<br />
<br />
<br />
<br />
<br />
<br />
cmd.extend("createWFObj", createWFObj)<br />
</source><br />
<br />
===ADDITIONAL RESOURCES===<br />
Torus.obj<br />
[http://pymolwiki.org/images/9/98/Torus.zip Torus.zip]<br />
<br />
<br />
[[Category:Script_Library|WFMesh]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Wfmesh&diff=8050Wfmesh2010-02-14T19:09:27Z<p>Cowsandmilk: Undo revision 8034 by Cowsandmilk (Talk)</p>
<hr />
<div>===DESCRIPTION===<br />
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->Insert->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. <br />
<br />
*createWFMesh - create a mesh object from Wavefront (*.obj) formated file<br />
<br />
===IMAGES===<br />
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]<br />
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
[[Category:ThirdParty_Scripts]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
===SETUP===<br />
Simply "run WFMesh.py"<br />
<br />
===NOTES / STATUS===<br />
*Tested on Pymolv0.97, Windows platform, should work on linux as well.<br />
*Coloring is fixed for grey and sections of mesh are stored, but not used.<br />
*Simple opengl calls; not optimized (display lists, etc) or anything.<br />
*Vertex Normal code is broken, so normals are per polygon right now.<br />
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu<br />
<br />
<br />
===USAGE===<br />
createWFObj file, name [,translate=[0,0,0]] [,flip=0]<br />
<br />
===EXAMPLES===<br />
createWFObj "ship.obj" "Ship"<br />
createWFObj "torus.obj" "Torus" flip=1 # Flip = 1, if OBJ created by openFX, crossroads3D combination<br />
createWFObj "torus.obj" "Torus" translate=[10,10,0] flip=1 <br />
<br />
===REFERENCES===<br />
[http://www.openfx.org OpenFX]<br />
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]<br />
<br />
===SCRIPTS (WFMesh.py)===<br />
WFMesh.py<br />
<source lang="python"><br />
###############################################<br />
# File: WFObj.py<br />
# Author: Dan Kulp<br />
# Creation Date: 5/13/05<br />
#<br />
# Notes:<br />
# Create openGL objects from a wavefront (obj) file<br />
###############################################<br />
<br />
import os<br />
import re<br />
import math<br />
from pymol.opengl.gl import *<br />
from pymol.callback import Callback<br />
<br />
<br />
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)<br />
def createWFObj(file, name,translate=[0,0,0],flip=0):<br />
obj = WFMesh(file,translate,flip)<br />
cmd.load_callback(obj,name)<br />
<br />
<br />
# Class for Wavefront Mesh<br />
class WFMesh(Callback):<br />
<br />
verts = [] # list of vertices<br />
polys = [] # list of poylgons<br />
pnorms = [] # list of polynomal normals<br />
vnorms = {} # dict. of vertex normals<br />
vavenorms = [] # list of vertex normals, redundant -- I'm far froma python pro.<br />
sections = {} # list of sections of mesh<br />
<br />
# Read mesh into memory<br />
def readOBJ(self,file):<br />
if os.path.exists(file):<br />
input = open(file,'r')<br />
for line in input:<br />
dat = re.split("\s+", line)<br />
<br />
# Find vertex line<br />
if line[0] == 'v' and line[1] != 't' and line[1] != 'n': self.verts.append([dat[1],dat[2],dat[3]])<br />
<br />
# Find polygon line<br />
if line[0] == 'f': self.polys.append([dat[1],dat[2],dat[3]])<br />
<br />
# Find section line<br />
if line[0] == 'g': self.sections[len(self.polys)] = dat[1] <br />
<br />
<br />
# Compute the normals for each polygon and each vertex <br />
def computeNorms(self):<br />
<br />
# Compute norms for each polygon<br />
for p in self.polys:<br />
v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\<br />
float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\<br />
float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \<br />
]<br />
<br />
v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\<br />
float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\<br />
float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \<br />
] <br />
<br />
# Compute poly normal<br />
polynorm = self.cross(v12,v13) <br />
norm = self.normalize(polynorm)<br />
<br />
<br />
# Files created by OpenFX, Crossroads combination need have their normals flipped <br />
if self.flip:<br />
norm[0] = -norm[0]<br />
norm[1] = -norm[1]<br />
norm[2] = -norm[2]<br />
<br />
# Append poly norm to polygonal norm array<br />
self.pnorms.append(norm)<br />
<br />
# Add norm to each vertexes norm..<br />
try:<br />
self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[0])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[0])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
try: <br />
self.vnorms[int(p[1])-1] = [float(self.vnorms[int(p[1])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[1])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[1])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
try:<br />
self.vnorms[int(p[2])-1] = [float(self.vnorms[int(p[1])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[1])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[1])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
<br />
# Average out each vnorm..<br />
index = 0<br />
for v in self.vnorms.values():<br />
self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4]) <br />
index += 1<br />
<br />
# Utility function to normalize a given vector<br />
def normalize(self,v):<br />
mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]<br />
if mag <= 0:<br />
mag = 1<br />
else:<br />
mag = math.sqrt(mag)<br />
<br />
return [v[0]/mag, v[1]/mag,v[2]/mag]<br />
<br />
# Utility cross product function<br />
def cross(self,v1,v2):<br />
x = 0<br />
y = 1<br />
z = 2<br />
<br />
return [v1[y]*v2[z] - v1[z]*v2[y],\<br />
v1[z]*v2[x] - v1[x]*v2[z],\<br />
v1[x]*v2[y] - v1[y]*v2[x]<br />
]<br />
<br />
# Constructor<br />
def __init__(self, file,translate=[0,0,0],flip=0):<br />
self.verts = []<br />
self.polys = [] <br />
self.pnorms = []<br />
self.vnorms = {}<br />
self.vavenorms = []<br />
self.translate = translate<br />
self.flip = flip <br />
<br />
print "Read in file: "+str(file)<br />
self.readOBJ(file)<br />
print "Done reading in WFMesh, now compute norms"<br />
self.computeNorms()<br />
print "Done computing norms, now display WFMesh"<br />
<br />
# Draw Function<br />
def __call__(self):<br />
<br />
glColorMaterial(GL_FRONT, GL_DIFFUSE); <br />
glEnable(GL_COLOR_MATERIAL);<br />
glShadeModel(GL_SMOOTH);<br />
<br />
# Color Everything grey<br />
glColor3f(0.5,0.5,0.5);<br />
<br />
index = 0<br />
glPushMatrix()<br />
glTranslated(self.translate[0],self.translate[1],self.translate[2])<br />
for p in self.polys:<br />
glBegin(GL_POLYGON)<br />
glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))<br />
<br />
for i in range(0,len(p)):<br />
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]))<br />
<br />
# Vertex Normals - not computed correctly, so commented out for now<br />
# norm = self.vnorms[int(p[i])-1]<br />
# glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))<br />
glEnd()<br />
index += 1<br />
glPopMatrix()<br />
<br />
<br />
<br />
<br />
<br />
cmd.extend("createWFObj", createWFObj)<br />
<br />
</source><br />
<br />
===ADDITIONAL RESOURCES===<br />
Torus.obj<br />
[http://pymolwiki.org/images/9/98/Torus.zip Torus.zip]<br />
<br />
<br />
[[Category:Script_Library|WFMesh]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=DynoPlot&diff=8049DynoPlot2010-02-14T19:08:37Z<p>Cowsandmilk: /* SCRIPTS (DynoPlot.py) */</p>
<hr />
<div>===DESCRIPTION===<br />
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.<br />
<br />
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).<br />
<br />
===IMAGES===<br />
<gallery><br />
Image:RamaPlotInitComposite.png|Initial Ramachandran plot of 1ENV<br />
Image:RamaPlotBentComposite.png|Modified pose and plot of 1ENV<br />
</gallery><br />
<br />
===SETUP===<br />
place the DynoPlot.py script into the appropriate startup directory then restart PyMol<br />
<br />
==== LINUX old-style installation ====<br />
<br />
$PYMOL_PATH/modules/pmg_tk/startup/<br />
<br />
==== LINUX distutils installation ====<br />
<br />
/usr/lib/pythonX.X/site-packages/pmg_tk/startup/<br />
<br />
==== Windows ====<br />
<br />
PYMOL_PATH/modules/pmg_tk/startup/ , where PYMOL_PATH on Windows is defaulted to C:/Program Files/DeLano Scientific/PyMol/start/<br />
<br />
===NOTES / STATUS===<br />
*Tested on Windows, PyMol version 0.97<br />
*This is an initial version, which needs some work. <br />
*Left, Right mouse buttons do different things; Right = identify data point, Left = drag data point around<br />
*Post comments/questions or send them to: dwkulp@mail.med.upenn.edu<br />
<br />
===USAGE===<br />
rama SELECTION<br />
<br />
===EXAMPLES=== <br />
*load pdb file 1ENV (download it or use the PDB loader plugin)<br />
*select resi 129-136<br />
*rama sel01<br />
*rock # the object needs to be moving in order for the angles to be updated.<br />
<br />
===REFERENCES===<br />
<br />
===SCRIPTS (DynoPlot.py)===<br />
DynoPlot.py<br />
<source lang="python"><br />
#!/usr/bin/env python<br />
###############################################<br />
# File: DynoPlot.py<br />
# Author: Dan Kulp<br />
# Creation Date: 8/29/05<br />
#<br />
# Notes:<br />
# Draw plots that display interactive data.<br />
# Phi,Psi plot shown.<br />
###############################################<br />
<br />
<br />
from __future__ import division<br />
from __future__ import generators<br />
<br />
import os,math<br />
import Tkinter<br />
from Tkinter import *<br />
import Pmw<br />
import distutils.spawn # used for find_executable<br />
import random<br />
from pymol import cmd<br />
<br />
try:<br />
import pymol<br />
REAL_PYMOL = True<br />
except ImportError:<br />
print "Nope"<br />
<br />
canvas = None<br />
rootframe = None<br />
init = 0<br />
<br />
class SimplePlot(Tkinter.Canvas):<br />
<br />
# Class variables<br />
mark = 'Oval' # Only 'Oval' for now..<br />
mark_size = 5<br />
xlabels = [] # axis labels<br />
ylabels = []<br />
spacingx = 0 # spacing in x direction<br />
spacingy = 0<br />
xmin = 0 # min value from each axis<br />
ymin = 0<br />
lastx = 0 # previous x,y pos of mouse<br />
lasty = 0<br />
down = 0 # flag for mouse pressed<br />
item = (0,) # items array used for clickable events<br />
shapes = {} # store plot data, x,y etc..<br />
<br />
def axis(self,xmin=40,xmax=300,ymin=10,ymax=290,xint=290,yint=40,xlabels=[],ylabels=[]):<br />
<br />
# Store variables in self object<br />
self.xlabels = xlabels<br />
self.ylabels = ylabels<br />
self.spacingx = (xmax-xmin) / (len(xlabels) - 1)<br />
self.spacingy = (ymax-ymin) / (len(ylabels) - 1)<br />
self.xmin = xmin<br />
self.ymin = ymin<br />
<br />
# Create axis lines<br />
self.create_line((xmin,xint,xmax,xint),fill="black",width=3)<br />
self.create_line((yint,ymin,yint,ymax),fill="black",width=3)<br />
<br />
# Create tick marks and labels<br />
nextspot = xmin<br />
for label in xlabels:<br />
self.create_line((nextspot, xint+5,nextspot, xint-5),fill="black",width=2)<br />
self.create_text(nextspot, xint-15, text=label)<br />
if len(xlabels) == 1:<br />
nextspot = xmax<br />
else:<br />
nextspot += (xmax - xmin)/ (len(xlabels) - 1)<br />
<br />
<br />
nextspot = ymax<br />
for label in ylabels:<br />
self.create_line((yint+5,nextspot,yint-5,nextspot),fill="black",width=2)<br />
self.create_text(yint-20,nextspot,text=label)<br />
if len(ylabels) == 1:<br />
nextspot = ymin<br />
else:<br />
nextspot -= (ymax - ymin)/ (len(ylabels) - 1)<br />
<br />
<br />
# Plot a point<br />
def plot(self,xp,yp,meta):<br />
<br />
# Convert from 'label' space to 'pixel' space<br />
x = self.convertToPixel("X",xp)<br />
y = self.convertToPixel("Y",yp)<br />
<br />
if self.mark == "Oval":<br />
oval = self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline="black",fill="SkyBlue2")<br />
<br />
self.shapes[oval] = [x,y,0,xp,yp,meta]<br />
<br />
<br />
# Repaint all points<br />
def repaint(self):<br />
for value in self.shapes.values():<br />
x = value[0]<br />
y = value[1]<br />
self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline="black",fill="SkyBlue2")<br />
<br />
# Convert from pixel space to label space<br />
def convertToLabel(self,axis, value):<br />
<br />
# Defaultly use X-axis info<br />
label0 = self.xlabels[0]<br />
label1 = self.xlabels[1]<br />
spacing = self.spacingx<br />
min = self.xmin<br />
<br />
# Set info for Y-axis use<br />
if axis == "Y":<br />
label0 = self.ylabels[0]<br />
label1 = self.ylabels[1]<br />
spacing = self.spacingy<br />
min = self.ymin<br />
<br />
pixel = value - min<br />
label = pixel / spacing<br />
label = label0 + label * abs(label1 - label0)<br />
<br />
if axis == "Y":<br />
label = - label<br />
<br />
return label<br />
<br />
# Converts value from 'label' space to 'pixel' space<br />
def convertToPixel(self,axis, value):<br />
<br />
# Defaultly use X-axis info<br />
label0 = self.xlabels[0]<br />
label1 = self.xlabels[1]<br />
spacing = self.spacingx<br />
min = self.xmin<br />
<br />
# Set info for Y-axis use<br />
if axis == "Y":<br />
label0 = self.ylabels[0]<br />
label1 = self.ylabels[1]<br />
spacing = self.spacingy<br />
min = self.ymin <br />
<br />
<br />
# Get axis increment in 'label' space<br />
inc = abs(label1 - label0)<br />
<br />
# 'Label' difference from value and smallest label (label0)<br />
diff = float(value - label0)<br />
<br />
# Get whole number in 'label' space<br />
whole = int(diff / inc)<br />
<br />
# Get fraction number in 'label' space<br />
part = float(float(diff/inc) - whole)<br />
<br />
# Return 'pixel' position value<br />
pixel = whole * spacing + part * spacing<br />
<br />
# print "Pixel: %f * %f + %f * %f = %f" % (whole, spacing, part, spacing,pixel)<br />
<br />
# Reverse number by subtracting total number of pixels - value pixels<br />
if axis == "Y":<br />
tot_label_diff = float(self.ylabels[len(self.ylabels)- 1] - label0)<br />
tot_label_whole = int(tot_label_diff / inc)<br />
tot_label_part = float(float(tot_label_diff / inc) - tot_label_whole)<br />
tot_label_pix = tot_label_whole * spacing + tot_label_part *spacing<br />
<br />
pixel = tot_label_pix - pixel<br />
<br />
# Add min edge pixels<br />
pixel = pixel + min<br />
<br />
return pixel<br />
<br />
<br />
# Print out which data point you just clicked on..<br />
def pickWhich(self,event):<br />
<br />
# Find closest data point <br />
x = event.widget.canvasx(event.x)<br />
y = event.widget.canvasx(event.y)<br />
spot = event.widget.find_closest(x,y)<br />
<br />
# Print the shape's meta information corresponding with the shape that was picked<br />
if spot[0] in self.shapes:<br />
print "Residue(Ca): %s\n" % self.shapes[spot[0]][5][2]<br />
<br />
<br />
# Mouse Down Event<br />
def down(self,event):<br />
<br />
# Store x,y position<br />
self.lastx = event.x<br />
self.lasty = event.y<br />
<br />
# Find the currently selected item<br />
x = event.widget.canvasx(event.x)<br />
y = event.widget.canvasx(event.y)<br />
self.item = event.widget.find_closest(x,y)<br />
<br />
# Identify that the mouse is down<br />
self.down = 1<br />
<br />
# Mouse Up Event<br />
def up(self,event):<br />
<br />
# Get label space version of x,y<br />
labelx = self.convertToLabel("X",event.x)<br />
labely = self.convertToLabel("Y",event.y)<br />
<br />
# Convert new position into label space..<br />
if self.item[0] in self.shapes:<br />
self.shapes[self.item[0]][0] = event.x<br />
self.shapes[self.item[0]][1] = event.y<br />
self.shapes[self.item[0]][2] = 1<br />
self.shapes[self.item[0]][3] = labelx<br />
self.shapes[self.item[0]][4] = labely<br />
<br />
# Reset Flags<br />
self.item = (0,)<br />
self.down = 0<br />
<br />
<br />
# Mouse Drag(Move) Event<br />
def drag(self,event):<br />
<br />
# Check that mouse is down and item clicked is a valid data point<br />
if self.down and self.item[0] in self.shapes:<br />
<br />
self.move(self.item, event.x - self.lastx, event.y - self.lasty)<br />
<br />
self.lastx = event.x<br />
self.lasty = event.y<br />
<br />
<br />
def __init__(self):<br />
<br />
self.menuBar.addcascademenu('Plugin', 'PlotTools', 'Plot Tools',<br />
label='Plot Tools')<br />
self.menuBar.addmenuitem('PlotTools', 'command',<br />
'Launch Rama Plot',<br />
label='Rama Plot',<br />
command = lambda s=self: ramaplot())<br />
<br />
<br />
def ramaplot(x=0,y=0,meta=[],clear=0):<br />
global canvas<br />
global rootframe<br />
global init<br />
<br />
# If no window is open<br />
if init == 0:<br />
rootframe=Tk()<br />
rootframe.title(' Dynamic Angle Plotting ')<br />
rootframe.protocol("WM_DELETE_WINDOW", close_callback)<br />
<br />
canvas = SimplePlot(rootframe,width=320,height=320)<br />
canvas.bind("<Button-2>",canvas.pickWhich)<br />
canvas.bind("<Button-3>",canvas.pickWhich)<br />
canvas.bind("<ButtonPress-1>",canvas.down)<br />
canvas.bind("<ButtonRelease-1>",canvas.up)<br />
canvas.bind("<Motion>",canvas.drag)<br />
canvas.pack(side=Tkinter.LEFT,fill="both",expand=1)<br />
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])<br />
canvas.update()<br />
init = 1<br />
else:<br />
canvas.plot(int(x), int(y),meta)<br />
<br />
def close_callback():<br />
global init<br />
global rootframe<br />
init = 0<br />
rootframe.destroy()<br />
<br />
<br />
# New Callback object, so that we can update the structure when phi,psi points are moved.<br />
class DynoRamaObject:<br />
global canvas<br />
<br />
def start(self,sel):<br />
<br />
# Get selection model<br />
model = cmd.get_model(sel)<br />
residues = ['dummy']<br />
resnames = ['dummy']<br />
phi = []<br />
psi = []<br />
dummy = []<br />
i = 0<br />
<br />
# Loop through each atom<br />
for at in model.atom:<br />
<br />
# Only plot once per residue<br />
if at.chain+":"+at.resn+":"+at.resi not in residues:<br />
residues.append(at.chain+":"+at.resn+":"+at.resi)<br />
resnames.append(at.resn+at.resi)<br />
dummy.append(i)<br />
i += 1<br />
<br />
# Check for a null chain id (some PDBs contain this)<br />
unit_select = ""<br />
if at.chain != "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue i-1, i and i+1<br />
residue_def = unit_select+'resi '+str(at.resi)<br />
residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)<br />
residue_def_next = unit_select+'resi '+str(int(at.resi)+1)<br />
<br />
try:<br />
# Store phi,psi residue definitions to pass on to plot routine<br />
phi_psi = [<br />
# Phi angles<br />
residue_def_prev+' and name C',<br />
residue_def+' and name N',<br />
residue_def+' and name CA',<br />
residue_def+' and name C',<br />
# Psi angles<br />
residue_def+' and name N',<br />
residue_def+' and name CA',<br />
residue_def+' and name C',<br />
residue_def_next+' and name N']<br />
<br />
# Compute phi/psi angle<br />
phi = cmd.get_dihedral(phi_psi[0],phi_psi[1],phi_psi[2],phi_psi[3])<br />
psi = cmd.get_dihedral(phi_psi[4],phi_psi[5],phi_psi[6],phi_psi[7])<br />
<br />
print "Plotting Phi,Psi: "+str(phi)+","+str(psi)<br />
ramaplot(phi,psi,meta=phi_psi)<br />
except:<br />
continue<br />
<br />
<br />
def __call__(self):<br />
<br />
# Loop through each item on plot to see if updated<br />
for key,value in canvas.shapes.items():<br />
dihedrals = value[5]<br />
<br />
# Look for update flag...<br />
if value[2]:<br />
<br />
# Set residue's phi,psi to new values<br />
print "Re-setting Phi,Psi: %s,%s" % (value[3],value[4])<br />
cmd.set_dihedral(dihedrals[0],dihedrals[1],dihedrals[2],dihedrals[3],value[3])<br />
cmd.set_dihedral(dihedrals[4],dihedrals[5],dihedrals[6],dihedrals[7],value[4])<br />
<br />
value[2] = 0<br />
<br />
<br />
<br />
# The wrapper function, used to create the Ploting window and the PyMol callback object <br />
def rama(sel):<br />
rama = DynoRamaObject()<br />
rama.start(sel)<br />
cmd.load_callback(rama, "DynoRamaObject")<br />
cmd.zoom("all")<br />
<br />
<br />
# Extend these commands<br />
cmd.extend('rama',rama)<br />
cmd.extend('ramaplot',ramaplot)<br />
</source><br />
<br />
===ADDITIONAL RESOURCES===<br />
<br />
<br />
<br />
[[Category:Script_Library|DynoPlot]]<br />
[[Category:Structural_Biology_Scripts|DynoPlot]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=DynoPlot&diff=8048DynoPlot2010-02-14T19:07:09Z<p>Cowsandmilk: Undo revision 8032 by Cowsandmilk (Talk)</p>
<hr />
<div>===DESCRIPTION===<br />
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.<br />
<br />
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).<br />
<br />
===IMAGES===<br />
<gallery><br />
Image:RamaPlotInitComposite.png|Initial Ramachandran plot of 1ENV<br />
Image:RamaPlotBentComposite.png|Modified pose and plot of 1ENV<br />
</gallery><br />
<br />
===SETUP===<br />
place the DynoPlot.py script into the appropriate startup directory then restart PyMol<br />
<br />
==== LINUX old-style installation ====<br />
<br />
$PYMOL_PATH/modules/pmg_tk/startup/<br />
<br />
==== LINUX distutils installation ====<br />
<br />
/usr/lib/pythonX.X/site-packages/pmg_tk/startup/<br />
<br />
==== Windows ====<br />
<br />
PYMOL_PATH/modules/pmg_tk/startup/ , where PYMOL_PATH on Windows is defaulted to C:/Program Files/DeLano Scientific/PyMol/start/<br />
<br />
===NOTES / STATUS===<br />
*Tested on Windows, PyMol version 0.97<br />
*This is an initial version, which needs some work. <br />
*Left, Right mouse buttons do different things; Right = identify data point, Left = drag data point around<br />
*Post comments/questions or send them to: dwkulp@mail.med.upenn.edu<br />
<br />
===USAGE===<br />
rama SELECTION<br />
<br />
===EXAMPLES=== <br />
*load pdb file 1ENV (download it or use the PDB loader plugin)<br />
*select resi 129-136<br />
*rama sel01<br />
*rock # the object needs to be moving in order for the angles to be updated.<br />
<br />
===REFERENCES===<br />
<br />
===SCRIPTS (DynoPlot.py)===<br />
DynoPlot.py<br />
<source lang="python"><br />
#!/usr/bin/env python<br />
###############################################<br />
# File: DynoPlot.py<br />
# Author: Dan Kulp<br />
# Creation Date: 8/29/05<br />
#<br />
# Notes:<br />
# Draw plots that display interactive data. <br />
# Phi,Psi plot shown.<br />
###############################################<br />
<br />
<br />
from __future__ import division<br />
from __future__ import generators<br />
<br />
import os,math<br />
import Tkinter<br />
from Tkinter import *<br />
import Pmw<br />
import distutils.spawn # used for find_executable<br />
import random<br />
from pymol import cmd<br />
<br />
try:<br />
import pymol<br />
REAL_PYMOL = True<br />
except ImportError:<br />
print "Nope"<br />
<br />
canvas = None<br />
init = 0<br />
<br />
class SimplePlot(Tkinter.Canvas):<br />
<br />
# Class variables<br />
mark = 'Oval' # Only 'Oval' for now..<br />
mark_size = 5<br />
xlabels = [] # axis labels<br />
ylabels = []<br />
spacingx = 0 # spacing in x direction<br />
spacingy = 0 <br />
xmin = 0 # min value from each axis<br />
ymin = 0<br />
lastx = 0 # previous x,y pos of mouse <br />
lasty = 0<br />
down = 0 # flag for mouse pressed<br />
item = (0,) # items array used for clickable events<br />
shapes = {} # store plot data, x,y etc..<br />
<br />
def axis(self,xmin=40,xmax=300,ymin=10,ymax=290,xint=290,yint=40,xlabels=[],ylabels=[]):<br />
<br />
# Store variables in self object<br />
self.xlabels = xlabels<br />
self.ylabels = ylabels<br />
self.spacingx = (xmax-xmin) / (len(xlabels) - 1)<br />
self.spacingy = (ymax-ymin) / (len(ylabels) - 1)<br />
self.xmin = xmin<br />
self.ymin = ymin<br />
<br />
# Create axis lines<br />
self.create_line((xmin,xint,xmax,xint),fill="black",width=3)<br />
self.create_line((yint,ymin,yint,ymax),fill="black",width=3)<br />
<br />
# Create tick marks and labels<br />
nextspot = xmin<br />
for label in xlabels:<br />
self.create_line((nextspot, xint+5,nextspot, xint-5),fill="black",width=2)<br />
self.create_text(nextspot, xint-15, text=label)<br />
if len(xlabels) == 1:<br />
nextspot = xmax<br />
else:<br />
nextspot += (xmax - xmin)/ (len(xlabels) - 1)<br />
<br />
<br />
nextspot = ymax<br />
for label in ylabels:<br />
self.create_line((yint+5,nextspot,yint-5,nextspot),fill="black",width=2)<br />
self.create_text(yint-20,nextspot,text=label)<br />
if len(ylabels) == 1:<br />
nextspot = ymin<br />
else:<br />
nextspot -= (ymax - ymin)/ (len(ylabels) - 1)<br />
<br />
<br />
# Plot a point<br />
def plot(self,xp,yp,meta):<br />
<br />
# Convert from 'label' space to 'pixel' space<br />
x = self.convertToPixel("X",xp)<br />
y = self.convertToPixel("Y",yp)<br />
<br />
if self.mark == "Oval":<br />
oval = self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline="black",fill="SkyBlue2")<br />
<br />
self.shapes[oval] = [x,y,0,xp,yp,meta]<br />
<br />
<br />
# Repaint all points <br />
def repaint(self):<br />
for value in self.shapes.values():<br />
x = value[0]<br />
y = value[1]<br />
self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline="black",fill="SkyBlue2")<br />
<br />
# Convert from pixel space to label space<br />
def convertToLabel(self,axis, value):<br />
<br />
# Defaultly use X-axis info<br />
label0 = self.xlabels[0]<br />
label1 = self.xlabels[1]<br />
spacing = self.spacingx<br />
min = self.xmin<br />
<br />
# Set info for Y-axis use<br />
if axis == "Y":<br />
label0 = self.ylabels[0]<br />
label1 = self.ylabels[1]<br />
spacing = self.spacingy<br />
min = self.ymin <br />
<br />
pixel = value - min<br />
label = pixel / spacing<br />
label = label0 + label * abs(label1 - label0)<br />
<br />
if axis == "Y":<br />
label = - label<br />
<br />
return label<br />
<br />
# Converts value from 'label' space to 'pixel' space<br />
def convertToPixel(self,axis, value):<br />
<br />
# Defaultly use X-axis info<br />
label0 = self.xlabels[0]<br />
label1 = self.xlabels[1]<br />
spacing = self.spacingx<br />
min = self.xmin<br />
<br />
# Set info for Y-axis use<br />
if axis == "Y":<br />
label0 = self.ylabels[0]<br />
label1 = self.ylabels[1]<br />
spacing = self.spacingy<br />
min = self.ymin <br />
<br />
<br />
# Get axis increment in 'label' space<br />
inc = abs(label1 - label0)<br />
<br />
# 'Label' difference from value and smallest label (label0)<br />
diff = float(value - label0)<br />
<br />
# Get whole number in 'label' space<br />
whole = int(diff / inc)<br />
<br />
# Get fraction number in 'label' space<br />
part = float(float(diff/inc) - whole)<br />
<br />
# Return 'pixel' position value<br />
pixel = whole * spacing + part * spacing<br />
<br />
# print "Pixel: %f * %f + %f * %f = %f" % (whole, spacing, part, spacing,pixel)<br />
<br />
# Reverse number by subtracting total number of pixels - value pixels<br />
if axis == "Y":<br />
tot_label_diff = float(self.ylabels[len(self.ylabels)- 1] - label0)<br />
tot_label_whole = int(tot_label_diff / inc)<br />
tot_label_part = float(float(tot_label_diff / inc) - tot_label_whole)<br />
tot_label_pix = tot_label_whole * spacing + tot_label_part *spacing<br />
<br />
pixel = tot_label_pix - pixel<br />
<br />
# Add min edge pixels<br />
pixel = pixel + min<br />
<br />
return pixel<br />
<br />
<br />
# Print out which data point you just clicked on..<br />
def pickWhich(self,event):<br />
<br />
# Find closest data point <br />
x = event.widget.canvasx(event.x)<br />
y = event.widget.canvasx(event.y)<br />
spot = event.widget.find_closest(x,y)<br />
<br />
# Print the shape's meta information corresponding with the shape that was picked<br />
if spot[0] in self.shapes:<br />
print "Residue(Ca): %s\n" % self.shapes[spot[0]][5][2]<br />
<br />
<br />
# Mouse Down Event<br />
def down(self,event):<br />
<br />
# Store x,y position<br />
self.lastx = event.x<br />
self.lasty = event.y<br />
<br />
# Find the currently selected item<br />
x = event.widget.canvasx(event.x)<br />
y = event.widget.canvasx(event.y)<br />
self.item = event.widget.find_closest(x,y)<br />
<br />
# Identify that the mouse is down<br />
self.down = 1<br />
<br />
# Mouse Up Event<br />
def up(self,event):<br />
<br />
# Get label space version of x,y<br />
labelx = self.convertToLabel("X",event.x)<br />
labely = self.convertToLabel("Y",event.y)<br />
<br />
# Convert new position into label space..<br />
if self.item[0] in self.shapes:<br />
self.shapes[self.item[0]][0] = event.x<br />
self.shapes[self.item[0]][1] = event.y<br />
self.shapes[self.item[0]][2] = 1<br />
self.shapes[self.item[0]][3] = labelx<br />
self.shapes[self.item[0]][4] = labely<br />
<br />
# Reset Flags<br />
self.item = (0,)<br />
self.down = 0<br />
<br />
<br />
# Mouse Drag(Move) Event<br />
def drag(self,event):<br />
<br />
# Check that mouse is down and item clicked is a valid data point<br />
if self.down and self.item[0] in self.shapes:<br />
<br />
self.move(self.item, event.x - self.lastx, event.y - self.lasty)<br />
<br />
self.lastx = event.x<br />
self.lasty = event.y<br />
<br />
<br />
def __init__(self):<br />
<br />
self.menuBar.addcascademenu('Plugin', 'PlotTools', 'Plot Tools',<br />
label='Plot Tools')<br />
self.menuBar.addmenuitem('PlotTools', 'command',<br />
'Launch Rama Plot',<br />
label='Rama Plot',<br />
command = lambda s=self: ramaplot())<br />
<br />
<br />
def ramaplot(x=0,y=0,meta=[],clear=0):<br />
global canvas<br />
global init<br />
<br />
# If no window is open<br />
if init == 0:<br />
rootframe=Tk()<br />
rootframe.title(' Dynamic Angle Plotting ')<br />
<br />
canvas = SimplePlot(rootframe,width=320,height=320)<br />
canvas.bind("<Button-2>",canvas.pickWhich)<br />
canvas.bind("<Button-3>",canvas.pickWhich)<br />
canvas.bind("<ButtonPress-1>",canvas.down)<br />
canvas.bind("<ButtonRelease-1>",canvas.up)<br />
canvas.bind("<Motion>",canvas.drag)<br />
canvas.pack(side=Tkinter.LEFT,fill="both",expand=1)<br />
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])<br />
canvas.update()<br />
init = 1<br />
else:<br />
canvas.plot(int(x), int(y),meta)<br />
<br />
<br />
# New Callback object, so that we can update the structure when phi,psi points are moved.<br />
class DynoRamaObject:<br />
global canvas<br />
<br />
def start(self,sel):<br />
<br />
# Get selection model<br />
model = cmd.get_model(sel)<br />
residues = ['dummy']<br />
resnames = ['dummy']<br />
phi = []<br />
psi = []<br />
dummy = []<br />
i = 0<br />
<br />
# Loop through each atom<br />
for at in model.atom:<br />
<br />
# Only plot once per residue<br />
if at.chain+":"+at.resn+":"+at.resi not in residues:<br />
residues.append(at.chain+":"+at.resn+":"+at.resi)<br />
resnames.append(at.resn+at.resi)<br />
dummy.append(i)<br />
i += 1<br />
<br />
# Check for a null chain id (some PDBs contain this) <br />
unit_select = ""<br />
if at.chain != "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue i-1, i and i+1 <br />
residue_def = unit_select+'resi '+str(at.resi)<br />
residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)<br />
residue_def_next = unit_select+'resi '+str(int(at.resi)+1)<br />
<br />
try:<br />
# Store phi,psi residue definitions to pass on to plot routine<br />
phi_psi = [<br />
# Phi angles<br />
residue_def_prev+' and name C',<br />
residue_def+' and name N',<br />
residue_def+' and name CA',<br />
residue_def+' and name C',<br />
# Psi angles<br />
residue_def+' and name N',<br />
residue_def+' and name CA',<br />
residue_def+' and name C',<br />
residue_def_next+' and name N']<br />
<br />
# Compute phi/psi angle<br />
phi = cmd.get_dihedral(phi_psi[0],phi_psi[1],phi_psi[2],phi_psi[3])<br />
psi = cmd.get_dihedral(phi_psi[4],phi_psi[5],phi_psi[6],phi_psi[7])<br />
<br />
print "Plotting Phi,Psi: "+str(phi)+","+str(psi) <br />
ramaplot(phi,psi,meta=phi_psi)<br />
except:<br />
continue<br />
<br />
<br />
def __call__(self):<br />
<br />
# Loop through each item on plot to see if updated<br />
for key,value in canvas.shapes.items():<br />
dihedrals = value[5]<br />
<br />
# Look for update flag...<br />
if value[2]:<br />
<br />
# Set residue's phi,psi to new values<br />
print "Re-setting Phi,Psi: %s,%s" % (value[3],value[4]) <br />
cmd.set_dihedral(dihedrals[0],dihedrals[1],dihedrals[2],dihedrals[3],value[3]) <br />
cmd.set_dihedral(dihedrals[4],dihedrals[5],dihedrals[6],dihedrals[7],value[4]) <br />
<br />
value[2] = 0<br />
<br />
<br />
<br />
# The wrapper function, used to create the Ploting window and the PyMol callback object <br />
def rama(sel):<br />
rama = DynoRamaObject()<br />
rama.start(sel)<br />
cmd.load_callback(rama, "DynoRamaObject")<br />
cmd.zoom("all")<br />
<br />
<br />
# Extend these commands<br />
cmd.extend('rama',rama) <br />
cmd.extend('ramaplot',ramaplot)<br />
<br />
</source><br />
<br />
===ADDITIONAL RESOURCES===<br />
<br />
<br />
<br />
[[Category:Script_Library|DynoPlot]]<br />
[[Category:Structural_Biology_Scripts|DynoPlot]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Rotamer_Toggle&diff=8047Rotamer Toggle2010-02-14T18:56:09Z<p>Cowsandmilk: Undo revision 8036 by Cowsandmilk (Talk)</p>
<hr />
<div>===DESCRIPTION===<br />
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.<br />
*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<br />
*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).<br />
*set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles<br />
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)<br />
*createRotamerPDBs - create pdb for each rotamer of given selection ; filter by rotamer-probability<br />
<br />
===IMAGES===<br />
<gallery><br />
Image:RotamerMenu.png|Rotamer Menu for a GLN residue<br />
Image:GLURotamerComparison5.png|Rotamer Comparison of crystal structure and most common for GLU; just as an example<br />
</gallery><br />
<br />
Print out while selecting most common rotamer from above-left image (GLN residue):<br />
Given GLN:40 PHI,PSI (-171.626373291,-96.0500335693) : bin (-170,-100)<br />
CHIs: [179.18069458007812, 72.539344787597656, -47.217315673828125]<br />
Setting Chi1 to -176.9<br />
Setting Chi2 to 177.4<br />
Setting Chi3 to 0.7<br />
<br />
===SETUP===<br />
run "rotamers.py" and use functions from commandline.<br />
<br />
or<br />
<br />
To setup a rotamer menu inside the residue menu (default windows pymol installation):<br />
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py<br />
*copy mymenu.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)<br />
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)<br />
This is only one possible way to do this, I am sure there are many others. I'm not going to post the bbdep, but there is a link in the References section to Dunbrack's download page (get the "sorted" lib)<br />
<br />
===NOTES / STATUS===<br />
*Tested on Pymolv0.97, Windows platform, Red Hat Linux 9.0 and Fedora Core 4. Will test v0.98 and MacOSX later on.<br />
*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.<br />
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu<br />
<br />
TASKS TODO:<br />
*Rotamer Movie, using mset, etc create movie to watch cycle through rotamers<br />
*Code could be organized a bit better; due to time constraints this is good for now..<br />
<br />
TASKS DONE:<br />
*Store crystal structure in rotamer menu, so you can go back to original orientation<br />
<br />
===USAGE===<br />
colorRotamers selection<br />
set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]<br />
set_phipsi selection phi_angle, psi_angle<br />
createRotamerPBDs selection [,ncutoff] [,pcutoff] [,prefix]<br />
<br />
===EXAMPLES===<br />
colorRotamers chain A<br />
set_rotamer resi 40, -60,-40 (only set chi1,chi2 angles)<br />
set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)<br />
createRotamerPDBs resi 10-12, ncutoff=3 (create 9 PDBs; each with one of the 3 most probable rotamers for resi 10,11,12)<br />
createRotamerPDBs resi 14, pcutoff=0.4 (create a pdb file for each rotamer of residue 14 with probablity > 0.4)<br />
<br />
===REFERENCES===<br />
Dunbrack and Cohen. Protein Science 1997<br />
<br />
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]<br />
<br />
===SCRIPTS (Rotamers.py ; MyMenu.py)===<br />
Rotamers.py <br />
<source lang="python"><br />
##################################################################<br />
# File: Rotamers.py<br />
# Author: Dan Kulp<br />
# Creation Date: 6/8/05<br />
# Contact: dwkulp@mail.med.upenn.edu<br />
#<br />
# Notes:<br />
# Incorporation of Rotamer library<br />
# readRotLib() - fills rotdat; <br />
# indexed by "RES:PHI_BIN:PSI_BIN".<br />
#<br />
# Three main functions:<br />
# 1. colorRotamers - colors according<br />
# to rotamer probablitity<br />
# 2. getBins(sel)<br />
# phi,psi bin for rotamer<br />
# 3. set_rotamer - set a side-chain <br />
# to a specific rotamer <br />
#<br />
# To setup a rotamer menu in the <br />
# right click, under "Residue"<br />
# 1. cp mymenu.py modules/pymol/menu.py<br />
# 2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)<br />
#<br />
# Requirements:<br />
# set ROTLIB to path for rotamer library<br />
# Reference: <br />
# Dunbrack and Cohen. Protein Science 1997<br />
####################################################################<br />
<br />
import colorsys,sys<br />
import re<br />
import editing<br />
import os<br />
import cmd<br />
import math<br />
<br />
# Path for library<br />
ROTLIB=os.environ['PYMOL_PATH']+"/modules/pymol/bbdep02.May.sortlib"<br />
<br />
# Place for library in memory..<br />
rotdat = {}<br />
<br />
def readRotLib(): <br />
# Column indexes in rotamer library..<br />
RES = 0<br />
PHI = 1<br />
PSI = 2<br />
PROB = 8<br />
CHI1 = 9<br />
CHI2 = 10<br />
CHI3 = 11<br />
CHI4 = 12<br />
<br />
if os.path.exists(ROTLIB):<br />
print "File exists: "+ROTLIB<br />
input = open(ROTLIB, 'r')<br />
for line in input:<br />
<br />
# Parse by whitespace (I believe format is white space and not fixed-width columns)<br />
dat = re.split("\s+",line)<br />
<br />
# Add to rotamer library in memory : <br />
# key format RES:PHI_BIN:PSI_BIN<br />
# value format PROB, CHI1, CHI2, CHI3, CHI4<br />
key = dat[RES]+":"+dat[PHI]+":"+dat[PSI]<br />
if key in rotdat:<br />
rotdat[key].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])<br />
else:<br />
rotdat[key] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]<br />
<br />
<br />
else:<br />
print "Couldn't find Rotamer library"<br />
<br />
<br />
# Atoms for each side-chain angle for each residue<br />
CHIS = {}<br />
CHIS["ARG"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","NE" ],<br />
["CG","CD","NE","CZ" ]<br />
]<br />
<br />
CHIS["ASN"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","OD2" ]<br />
]<br />
<br />
CHIS["ASP"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","OD1" ]<br />
]<br />
CHIS["CYS"] = [ ["N","CA","CB","SG" ]<br />
]<br />
CHIS["GLN"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","OE1"]<br />
]<br />
<br />
CHIS["GLU"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","OE1"]<br />
]<br />
<br />
CHIS["HIS"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","ND1"]<br />
]<br />
<br />
CHIS["ILE"] = [ ["N","CA","CB","CG1" ],<br />
["CA","CB","CG1","CD1" ]<br />
]<br />
<br />
CHIS["LEU"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["LYS"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","CE"],<br />
["CG","CD","CE","NZ"]<br />
]<br />
<br />
CHIS["MET"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","SD" ],<br />
["CB","CG","SD","CE"]<br />
]<br />
<br />
CHIS["PHE"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["PRO"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ]<br />
]<br />
<br />
CHIS["SER"] = [ ["N","CA","CB","OG" ]<br />
]<br />
<br />
CHIS["THR"] = [ ["N","CA","CB","OG1" ]<br />
]<br />
<br />
CHIS["TRP"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1"]<br />
]<br />
<br />
CHIS["TYR"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["VAL"] = [ ["N","CA","CB","CG1" ]<br />
]<br />
<br />
# Color Rotamer by side-chain angle position<br />
# 'bin' side-chain angles into closest<br />
def colorRotamers(sel):<br />
doRotamers(sel)<br />
<br />
# Utility function, to set phi,psi angles for a given selection<br />
# Note: Cartoon, Ribbon functionality will not display correctly after this<br />
def set_phipsi(sel, phi,psi):<br />
doRotamers(sel,angles=[phi,psi],type="set")<br />
<br />
# Set a rotamer, based on a selection, a restype and chi angles<br />
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):<br />
at = cmd.get_model("byres ("+sel+")").atom[0]<br />
<br />
list = [chi1,chi2,chi3,chi4]<br />
for i in range(len(CHIS[at.resn])):<br />
print "Setting Chi"+str(i+1)+" to "+str(list[i])<br />
editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0], <br />
sel + ' and name '+CHIS[at.resn][i][1], <br />
sel + ' and name '+CHIS[at.resn][i][2], <br />
sel + ' and name '+CHIS[at.resn][i][3], str(list[i])) <br />
<br />
# Remove some objects that got created<br />
cmd.delete("pk1")<br />
cmd.delete("pk2")<br />
cmd.delete("pkmol")<br />
<br />
# Get Phi,Psi bins for given selection<br />
# WARNING: assume selection is single residue (will only return first residue bins)<br />
def getBins(sel):<br />
return doRotamers(sel, type="bins")<br />
<br />
# Color Ramp...<br />
def rot_color(vals): <br />
nbins = 10<br />
vals.sort(key=lambda x: x[1])<br />
# print "End sort: "+str(len(vals))+" : "+str(nbins)<br />
<br />
<br />
# Coloring scheme...<br />
j = 0<br />
rgb = [0.0,0.0,0.0]<br />
sel_str = ""<br />
for i in range(len(vals)):<br />
if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:<br />
hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)<br />
<br />
#convert to rgb and append to color list<br />
rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])<br />
if j < nbins-1:<br />
j += 1 <br />
<br />
cmd.set_color("RotProbColor"+str(i), rgb)<br />
cmd.color("RotProbColor"+str(i), str(vals[i][0]))<br />
<br />
<br />
# Main function <br />
def doRotamers(sel,angles=[], type="color"): <br />
<br />
# Read in Rotamer library if not already done<br />
if len(rotdat) == 0:<br />
readRotLib()<br />
<br />
# Set up some variables..<br />
residues = ['dummy'] # Keep track of residues already done<br />
probs = [] # probability of each residue conformation<br />
phi = 0 # phi,psi angles of current residue<br />
psi = 0<br />
<br />
# Get atoms from selection<br />
atoms = cmd.get_model("byres ("+sel+")")<br />
<br />
# Loop through atoms in selection <br />
for at in atoms.atom:<br />
try:<br />
# Don't process Glycines or Alanines<br />
if not (at.resn == 'GLY' or at.resn == 'ALA'):<br />
if at.chain+":"+at.resn+":"+at.resi not in residues:<br />
residues.append(at.chain+":"+at.resn+":"+at.resi)<br />
<br />
# Check for a null chain id (some PDBs contain this) <br />
unit_select = ""<br />
if at.chain != "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue i-1, i and i+1 <br />
residue_def = unit_select+'resi '+str(at.resi)<br />
residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)<br />
residue_def_next = unit_select+'resi '+str(int(at.resi)+1)<br />
<br />
# Compute phi/psi angle<br />
<br />
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')<br />
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')<br />
if type == "set":<br />
print "Changing "+at.resn+str(at.resi)+" from "+str(phi)+","+str(psi)+" to "+str(angles[0])+","+str(angles[1])<br />
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])<br />
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])<br />
continue<br />
<br />
# Find correct 10x10 degree bin <br />
phi_digit = abs(int(phi)) - abs(int(phi/10)*10)<br />
psi_digit = abs(int(psi)) - abs(int(psi/10)*10)<br />
<br />
# Remember sign of phi,psi angles<br />
phi_sign = 1<br />
if phi < 0: phi_sign = -1<br />
<br />
psi_sign = 1<br />
if psi < 0: psi_sign = -1<br />
<br />
# Compute phi,psi bins<br />
phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)<br />
if phi_digit >= 5: phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)<br />
<br />
psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)<br />
if psi_digit >= 5: psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)<br />
<br />
print "Given "+at.resn+":"+at.resi+" PHI,PSI ("+str(phi)+","+str(psi)+") : bin ("+str(phi_bin)+","+str(psi_bin)+")"<br />
<br />
<br />
# Get current chi angle measurements<br />
chi = []<br />
for i in range(len(CHIS[at.resn])):<br />
chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0], <br />
residue_def + ' and name '+CHIS[at.resn][i][1], <br />
residue_def + ' and name '+CHIS[at.resn][i][2], <br />
residue_def + ' and name '+CHIS[at.resn][i][3])) <br />
print "CHIs: "+str(chi)<br />
if type == 'bins':<br />
return [at.resn, phi_bin,psi_bin]<br />
<br />
# Compute probabilities for given chi angles<br />
prob = 0<br />
prob_box = 22 <br />
for item in range(len(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)])):<br />
print "Rotamer from db: "+str(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item])<br />
if chi[0]:<br />
if chi[0] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) - (prob_box/2) and \<br />
chi[0] <= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) + (prob_box/2):<br />
if len(chi) == 1:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[1] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) - (prob_box/2) and \<br />
float(chi[1] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) + (prob_box/2):<br />
if len(chi) == 2:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[2] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) - (prob_box/2) and \<br />
float(chi[2] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) + (prob_box/2):<br />
if len(chi) == 3:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[3] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) - (prob_box/2) and \<br />
float(chi[3] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) + (prob_box/2):<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
<br />
<br />
print "PROB OF ROTAMER: "+str(prob)<br />
print "---------------------------"<br />
probs.append([residue_def, prob])<br />
<br />
except:<br />
# probs.append([residue_def, -1])<br />
print "Exception found"<br />
continue<br />
<br />
# Color according to rotamer probability<br />
rot_color(probs) <br />
<br />
<br />
<br />
<br />
# Create PDB files containing most probable rotamers<br />
def createRotamerPDBs(sel,ncutoff=10,pcutoff=0,prefix="ROTAMER"):<br />
<br />
# Get atoms from selection<br />
atoms = cmd.get_model("byres ("+sel+")")<br />
<br />
# Set up some variables..<br />
residues = ['dummy'] # Keep track of residues already done<br />
<br />
# Loop through atoms in selection <br />
for at in atoms.atom:<br />
if at.resn in ('GLY', 'ALA') or "%s:%s:%s" % (at.chain,at.resn,at.resi) in residues:<br />
continue<br />
<br />
# Add to residue list (keep track of which ones we've done)<br />
residues.append("%s:%s:%s" % (at.chain,at.resn,at.resi))<br />
<br />
# Check for a null chain id (some PDBs contain this) <br />
unit_select = ""<br />
if at.chain != "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue <br />
residue_def = unit_select+'resi '+str(at.resi)<br />
<br />
# Get bin (phi,psi) definitions for this residue<br />
bin = doRotamers(residue_def, type='bins')<br />
<br />
# Store crystal angle<br />
crystal_angles = [0.0,0.0,0.0,0.0]<br />
for angle in range(3):<br />
try:<br />
crystal_angles[angle] = bin[3][angle]<br />
except IndexError:<br />
break<br />
<br />
# Retreive list of rotamers for this phi,psi bin + residue type<br />
match_rotamers = rotdat["%s:%s:%s" % (bin[0],str(bin[1]),str(bin[2]))]<br />
<br />
count = 0<br />
for item in range(len(match_rotamers)):<br />
<br />
# Store probablity<br />
prob = match_rotamers[item][0]<br />
<br />
# Check cutoffs<br />
if float(prob) <= float(pcutoff):<br />
continue<br />
<br />
if float(count) >= float(ncutoff):<br />
break<br />
<br />
# Increment count<br />
count += 1<br />
<br />
# Output to screen ...<br />
print "Residue %s%s, rotamer %i, prob %s" % (at.resn,at.resi,item,prob)<br />
<br />
# Set to new rotamer<br />
set_rotamer(residue_def,match_rotamers[item][1],match_rotamers[item][2],match_rotamers[item][3],match_rotamers[item][4]) <br />
<br />
# Store in PDB file<br />
cmd.save("%s_%s%s_%i_%s.pdb" % (prefix,str(at.resn),str(at.resi),int(item),str(prob)))<br />
<br />
# Reset crystal angle<br />
set_rotamer(residue_def,crystal_angles[0],crystal_angles[1],crystal_angles[2],crystal_angles[3])<br />
<br />
# Uncommenting this is nice because it loads rotamer library upon startup<br />
# however, it slows the PyMOL loading process a lot<br />
# instead I've put this call into the menuing code..<br />
# readRotLib()<br />
<br />
cmd.extend('set_phipsi',set_phipsi)<br />
cmd.extend('set_rotamer',set_rotamer)<br />
cmd.extend('colorRotamers',colorRotamers)<br />
cmd.extend('createRotamerPDBs',createRotamerPDBs)<br />
<br />
</source><br />
<br />
MyMenu.py<br />
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<br />
<br />
1. In the "pick_option(title,s,object=0)" function of menu.py add the following code after the first "result =" statement<br />
<source lang="python"><br />
# Edit dwkulp 6/11/05 , add a rotamer menu to residue menu<br />
if title == 'Residue':<br />
result.extend([[ 1, 'rotamers' , rotamer_menu(s)]])<br />
</source><br />
<br />
2. At the end of the file add this:<br />
<source lang="python"><br />
###############################################<br />
# Dan Kulp<br />
# Added Rotamer list to residue menu..<br />
# rotamer.py must be importable (I placed it in <br />
# the same directory as menu.py)<br />
###############################################<br />
<br />
import rotamers<br />
<br />
<br />
def rotamer_menu(s):<br />
# Check for rotamer library being loaded<br />
if not rotamers.rotdat:<br />
rotamers.readRotLib()<br />
# return [ [2, "Must run rotamers.py first",'']]<br />
<br />
# Check for valid rotamer residue..<br />
res = cmd.get_model("byres ("+s+")").atom[0].resn<br />
if not res in rotamers.CHIS.keys():<br />
return [ [2, "Residue: "+res+" not known sidechain or does not have rotamers", '']]<br />
<br />
# Get PHI,PSI bins for rotamer (also prints out current phi,psi, chi1,chi2,chi3,chi4)<br />
bins = rotamers.doRotamers(s,type='bins')<br />
<br />
# Add a title to the menu<br />
result = [ [2, bins[0]+' Rotamers in bin ('+str(bins[1])+','+str(bins[2])+')','' ], [1, ':::PROB,CHI1,CHI2,CHI3,CHI4:::','']]<br />
<br />
# Grab the entries for this residue and phi,psi bins<br />
match_rotamers = rotamers.rotdat[bins[0]+":"+str(bins[1])+":"+str(bins[2])]<br />
<br />
# Set max number of rotamers to display (probably should be somewhere 'higher up' in the code)<br />
max_rotamers = min(10, len(match_rotamers))<br />
<br />
# Create menu entry for each possible rotamer<br />
for item in range(max_rotamers):<br />
result.append( [ 1, str(match_rotamers[item]), 'rotamers.set_rotamer("'+s+'","'\<br />
+str(match_rotamers[item][1])+'","'\<br />
+str(match_rotamers[item][2])+'","'\<br />
+str(match_rotamers[item][3])+'","'\<br />
+str(match_rotamers[item][4])+'")'])<br />
return result<br />
<br />
<br />
</source><br />
<br />
<br />
[[Category:Script_Library|Rotamer Toggle]]<br />
<br />
[[Category:Structural_Biology_Scripts|Rotamer Toggle]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Rotamer_Toggle&diff=8036Rotamer Toggle2010-02-02T13:03:30Z<p>Cowsandmilk: </p>
<hr />
<div>===DESCRIPTION===<br />
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.<br />
*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<br />
*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).<br />
*set_rotamer - routine called by above menu, but can be called manually to set a specific residues side-chain angles<br />
*set_phipsi - set all phi,psi angles of given selection to given angles (useful for creating secondary structures)<br />
*createRotamerPDBs - create pdb for each rotamer of given selection ; filter by rotamer-probability<br />
<br />
===IMAGES===<br />
<gallery><br />
Image:RotamerMenu.png|Rotamer Menu for a GLN residue<br />
Image:GLURotamerComparison5.png|Rotamer Comparison of crystal structure and most common for GLU; just as an example<br />
</gallery><br />
<br />
Print out while selecting most common rotamer from above-left image (GLN residue):<br />
Given GLN:40 PHI,PSI (-171.626373291,-96.0500335693) : bin (-170,-100)<br />
CHIs: [179.18069458007812, 72.539344787597656, -47.217315673828125]<br />
Setting Chi1 to -176.9<br />
Setting Chi2 to 177.4<br />
Setting Chi3 to 0.7<br />
<br />
===SETUP===<br />
run "rotamers.py" and use functions from commandline.<br />
<br />
or<br />
<br />
To setup a rotamer menu inside the residue menu (default windows pymol installation):<br />
*copy rotamers.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/rotamers.py<br />
*copy mymenu.py to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/menu.py (WARNING : overwrites default menu.py - use at your own risk)<br />
*copy bbdep02.May.sortlib to C:/Program Files/DeLano Scientific/PyMol/modules/pymol/bbdep02.May.sortlib (or newer version of sorted bbdep)<br />
This is only one possible way to do this, I am sure there are many others. I'm not going to post the bbdep, but there is a link in the References section to Dunbrack's download page (get the "sorted" lib)<br />
<br />
===NOTES / STATUS===<br />
*Tested on Pymolv0.97, Windows platform, Red Hat Linux 9.0 and Fedora Core 4. Will test v0.98 and MacOSX later on.<br />
*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.<br />
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu<br />
<br />
TASKS TODO:<br />
*Rotamer Movie, using mset, etc create movie to watch cycle through rotamers<br />
*Code could be organized a bit better; due to time constraints this is good for now..<br />
<br />
TASKS DONE:<br />
*Store crystal structure in rotamer menu, so you can go back to original orientation<br />
<br />
===USAGE===<br />
colorRotamers selection<br />
set_rotamer selection, chi1_angle [,chi2_angle] [,chi3_angle] [,chi4_angle]<br />
set_phipsi selection phi_angle, psi_angle<br />
createRotamerPBDs selection [,ncutoff] [,pcutoff] [,prefix]<br />
<br />
===EXAMPLES===<br />
colorRotamers chain A<br />
set_rotamer resi 40, -60,-40 (only set chi1,chi2 angles)<br />
set_phipsi resi 10-40, -60,-60 (create an alpha-helical-like section)<br />
createRotamerPDBs resi 10-12, ncutoff=3 (create 9 PDBs; each with one of the 3 most probable rotamers for resi 10,11,12)<br />
createRotamerPDBs resi 14, pcutoff=0.4 (create a pdb file for each rotamer of residue 14 with probablity > 0.4)<br />
<br />
===REFERENCES===<br />
Dunbrack and Cohen. Protein Science 1997<br />
<br />
[http://dunbrack.fccc.edu/bbdep/index.php Dunbrack Lab Page (Contains backbone-dependent library)]<br />
<br />
===SCRIPTS (Rotamers.py ; MyMenu.py)===<br />
Rotamers.py <br />
<source lang="python"><br />
##################################################################<br />
# File: Rotamers.py<br />
# Author: Dan Kulp<br />
# Creation Date: 6/8/05<br />
# Contact: dwkulp@mail.med.upenn.edu<br />
#<br />
# Notes:<br />
# Incorporation of Rotamer library<br />
# readRotLib() - fills rotdat; <br />
# indexed by "RES:PHI_BIN:PSI_BIN".<br />
#<br />
# Three main functions:<br />
# 1. colorRotamers - colors according<br />
# to rotamer probablitity<br />
# 2. getBins(sel)<br />
# phi,psi bin for rotamer<br />
# 3. set_rotamer - set a side-chain <br />
# to a specific rotamer<br />
#<br />
# To setup a rotamer menu in the <br />
# right click, under "Residue"<br />
# 1. cp mymenu.py modules/pymol/menu.py<br />
# 2. cp rotamers.py modules/pymol/rotamers.py (update ROTLIB)<br />
#<br />
# Requirements:<br />
# set ROTLIB to path for rotamer library<br />
# Reference: <br />
# Dunbrack and Cohen. Protein Science 1997<br />
####################################################################<br />
<br />
import colorsys,sys<br />
import string<br />
import re<br />
import editing<br />
import os<br />
import cmd<br />
import math<br />
<br />
# Path for library<br />
ROTLIB=os.environ['PYMOL_PATH']+"/modules/pymol/bbdep02.May.sortlib"<br />
<br />
# Place for library in memory..<br />
rotdat = {}<br />
<br />
def readRotLib():<br />
# Column indexes in rotamer library..<br />
RES = 0<br />
PHI = 1<br />
PSI = 2<br />
PROB = 8<br />
CHI1 = 9<br />
CHI2 = 10<br />
CHI3 = 11<br />
CHI4 = 12<br />
<br />
if os.path.exists(ROTLIB):<br />
print "File exists: "+ROTLIB<br />
input = open(ROTLIB, 'r')<br />
for line in input:<br />
<br />
# Parse by whitespace (I believe format is white space and not fixed-width columns)<br />
dat = re.split("\s+",line)<br />
<br />
# Add to rotamer library in memory : <br />
# key format RES:PHI_BIN:PSI_BIN<br />
# value format PROB, CHI1, CHI2, CHI3, CHI4<br />
try:<br />
rotdat[dat[RES]+":"+dat[PHI]+":"+dat[PSI]].append([ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ])<br />
except KeyError:<br />
rotdat[dat[RES]+":"+dat[PHI]+":"+dat[PSI]] = [ [ dat[PROB], dat[CHI1], dat[CHI2], dat[CHI3], dat[CHI4] ] ]<br />
<br />
<br />
else:<br />
print "Couldn't find Rotamer library"<br />
<br />
<br />
# Atoms for each side-chain angle for each residue<br />
CHIS = {}<br />
CHIS["ARG"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","NE" ],<br />
["CG","CD","NE","CZ" ]<br />
]<br />
<br />
CHIS["ASN"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","OD2" ]<br />
]<br />
<br />
CHIS["ASP"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","OD1" ]<br />
]<br />
CHIS["CYS"] = [ ["N","CA","CB","SG" ]<br />
]<br />
<br />
CHIS["GLN"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","OE1"]<br />
]<br />
<br />
CHIS["GLU"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","OE1"]<br />
]<br />
<br />
CHIS["HIS"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","ND1"]<br />
]<br />
<br />
CHIS["ILE"] = [ ["N","CA","CB","CG1" ],<br />
["CA","CB","CG1","CD1" ]<br />
]<br />
<br />
CHIS["LEU"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["LYS"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ],<br />
["CB","CG","CD","CE"],<br />
["CG","CD","CE","NZ"]<br />
]<br />
<br />
CHIS["MET"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","SD" ],<br />
["CB","CG","SD","CE"]<br />
]<br />
<br />
CHIS["PHE"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["PRO"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD" ]<br />
]<br />
<br />
CHIS["SER"] = [ ["N","CA","CB","OG" ]<br />
]<br />
<br />
CHIS["THR"] = [ ["N","CA","CB","OG1" ]<br />
]<br />
<br />
CHIS["TRP"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1"]<br />
]<br />
<br />
CHIS["TYR"] = [ ["N","CA","CB","CG" ],<br />
["CA","CB","CG","CD1" ]<br />
]<br />
<br />
CHIS["VAL"] = [ ["N","CA","CB","CG1" ]<br />
]<br />
<br />
# Color Rotamer by side-chain angle position<br />
# 'bin' side-chain angles into closest<br />
def colorRotamers(sel):<br />
doRotamers(sel)<br />
<br />
# Utility function, to set phi,psi angles for a given selection<br />
# Note: Cartoon, Ribbon functionality will not display correctly after this<br />
def set_phipsi(sel, phi,psi):<br />
doRotamers(sel,angles=[phi,psi],type="set")<br />
<br />
# Set a rotamer, based on a selection, a restype and chi angles<br />
def set_rotamer(sel, chi1, chi2=0,chi3=0,chi4=0):<br />
at = cmd.get_model("byres ("+sel+")").atom[0]<br />
<br />
list = [chi1,chi2,chi3,chi4]<br />
for i in range(0,len(CHIS[at.resn])):<br />
print "Setting Chi"+str(i+1)+" to "+str(list[i])<br />
editing.set_dihedral(sel + ' and name '+CHIS[at.resn][i][0],<br />
sel + ' and name '+CHIS[at.resn][i][1],<br />
sel + ' and name '+CHIS[at.resn][i][2],<br />
sel + ' and name '+CHIS[at.resn][i][3], str(list[i]))<br />
<br />
# Remove some objects that got created<br />
cmd.delete("pk1")<br />
cmd.delete("pk2")<br />
cmd.delete("pkmol")<br />
<br />
# Get Phi,Psi bins for given selection<br />
# WARNING: assume selection is single residue (will only return first residue bins)<br />
def getBins(sel):<br />
return doRotamers(sel, type="bins")<br />
<br />
# Specific comparison operator for rotamer prob data <br />
def mycmp(first, second):<br />
return cmp( first[1], second[1])<br />
<br />
# Color Ramp...<br />
def rot_color(vals): <br />
nbins = 10<br />
vals.sort(mycmp)<br />
# print "End sort: "+str(len(vals))+" : "+str(nbins)<br />
<br />
<br />
# Coloring scheme...<br />
i = 0<br />
j = 0<br />
rgb = [0.0,0.0,0.0]<br />
sel_str = ""<br />
while i < len(vals):<br />
if int(len(vals)/nbins) == 0 or i % int(len(vals)/nbins) == 0:<br />
hsv = (colorsys.TWO_THIRD - colorsys.TWO_THIRD * float(j) / (nbins-1), 1.0, 1.0)<br />
<br />
#convert to rgb and append to color list<br />
rgb = colorsys.hsv_to_rgb(hsv[0],hsv[1],hsv[2])<br />
if j < nbins-1:<br />
j += 1<br />
<br />
cmd.set_color("RotProbColor"+str(i), rgb)<br />
cmd.color("RotProbColor"+str(i), str(vals[i][0]))<br />
i += 1<br />
<br />
<br />
# Main function<br />
def doRotamers(sel,angles=[], type="color"):<br />
<br />
# Read in Rotamer library if not already done<br />
if len(rotdat) == 0:<br />
readRotLib()<br />
<br />
# Set up some variables..<br />
residues = ['dummy'] # Keep track of residues already done<br />
probs = [] # probability of each residue conformation<br />
phi = 0 # phi,psi angles of current residue<br />
psi = 0<br />
<br />
# Get atoms from selection<br />
atoms = cmd.get_model("byres ("+sel+")")<br />
<br />
# Loop through atoms in selection<br />
for at in atoms.atom:<br />
try:<br />
# Don't process Glycines or Alanines<br />
if not (at.resn == 'GLY' or at.resn == 'ALA'):<br />
if not at.chain+":"+at.resn+":"+at.resi in residues:<br />
residues.append(at.chain+":"+at.resn+":"+at.resi)<br />
<br />
# Check for a null chain id (some PDBs contain this) <br />
unit_select = ""<br />
if not at.chain == "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue i-1, i and i+1<br />
residue_def = unit_select+'resi '+str(at.resi)<br />
residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)<br />
residue_def_next = unit_select+'resi '+str(int(at.resi)+1)<br />
<br />
# Compute phi/psi angle<br />
<br />
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')<br />
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')<br />
if type == "set":<br />
print "Changing "+at.resn+str(at.resi)+" from "+str(phi)+","+str(psi)+" to "+str(angles[0])+","+str(angles[1])<br />
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])<br />
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])<br />
continue<br />
<br />
# Find correct 10x10 degree bin <br />
phi_digit = abs(int(phi)) - abs(int(phi/10)*10)<br />
psi_digit = abs(int(psi)) - abs(int(psi/10)*10)<br />
<br />
# Remember sign of phi,psi angles<br />
phi_sign = 1<br />
if phi < 0: phi_sign = -1<br />
<br />
psi_sign = 1<br />
if psi < 0: psi_sign = -1<br />
<br />
# Compute phi,psi bins<br />
phi_bin = int(math.floor(abs(phi/10))*10*phi_sign)<br />
if phi_digit >= 5: phi_bin = int(math.ceil(abs(phi/10))*10*phi_sign)<br />
<br />
psi_bin = int(math.floor(abs(psi/10))*10*psi_sign)<br />
if psi_digit >= 5: psi_bin = int(math.ceil(abs(psi/10))*10*psi_sign)<br />
<br />
print "Given "+at.resn+":"+at.resi+" PHI,PSI ("+str(phi)+","+str(psi)+") : bin ("+str(phi_bin)+","+str(psi_bin)+")"<br />
<br />
<br />
# Get current chi angle measurements<br />
chi = []<br />
for i in range(0,len(CHIS[at.resn])):<br />
chi.append(cmd.get_dihedral(residue_def + ' and name '+CHIS[at.resn][i][0],<br />
residue_def + ' and name '+CHIS[at.resn][i][1],<br />
residue_def + ' and name '+CHIS[at.resn][i][2],<br />
residue_def + ' and name '+CHIS[at.resn][i][3]))<br />
print "CHIs: "+str(chi)<br />
if type == 'bins':<br />
return [at.resn, phi_bin,psi_bin]<br />
<br />
# Compute probabilities for given chi angles<br />
prob = 0<br />
prob_box = 22 <br />
for item in range(0,len(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)])):<br />
print "Rotamer from db: "+str(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item])<br />
if chi[0]:<br />
if chi[0] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) - (prob_box/2) and \<br />
chi[0] <= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][1]) + (prob_box/2):<br />
if len(chi) == 1:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[1] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) - (prob_box/2) and \<br />
float(chi[1] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][2]) + (prob_box/2):<br />
if len(chi) == 2:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[2] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) - (prob_box/2) and \<br />
float(chi[2] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][3]) + (prob_box/2):<br />
if len(chi) == 3:<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
if chi[3] >= float(rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) - (prob_box/2) and \<br />
float(chi[3] <= rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][4]) + (prob_box/2):<br />
prob = rotdat[at.resn+":"+str(phi_bin)+":"+str(psi_bin)][item][0]<br />
break<br />
<br />
<br />
print "PROB OF ROTAMER: "+str(prob)<br />
print "---------------------------"<br />
probs.append([residue_def, prob])<br />
<br />
except:<br />
# probs.append([residue_def, -1])<br />
print "Exception found"<br />
continue<br />
<br />
# Color according to rotamer probability<br />
rot_color(probs)<br />
<br />
<br />
<br />
<br />
# Create PDB files containing most probable rotamers<br />
def createRotamerPDBs(sel,ncutoff=10,pcutoff=0,prefix="ROTAMER"):<br />
<br />
# Get atoms from selection<br />
atoms = cmd.get_model("byres ("+sel+")")<br />
<br />
# Set up some variables..<br />
residues = ['dummy'] # Keep track of residues already done<br />
<br />
# Loop through atoms in selection<br />
for at in atoms.atom:<br />
if at.resn == 'GLY' or at.resn == 'ALA' or "%s:%s:%s" % (at.chain,at.resn,at.resi) in residues:<br />
continue<br />
<br />
# Add to residue list (keep track of which ones we've done)<br />
residues.append("%s:%s:%s" % (at.chain,at.resn,at.resi))<br />
<br />
# Check for a null chain id (some PDBs contain this)<br />
unit_select = ""<br />
if not at.chain == "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue <br />
residue_def = unit_select+'resi '+str(at.resi)<br />
<br />
# Get bin (phi,psi) definitions for this residue<br />
bin = doRotamers(residue_def, type='bins')<br />
<br />
# Store crystal angle<br />
crystal_angles = [0.0,0.0,0.0,0.0]<br />
for angle in range(0,3):<br />
try:<br />
crystal_angles[angle] = bin[3][angle]<br />
except IndexError:<br />
break<br />
<br />
# Retreive list of rotamers for this phi,psi bin + residue type<br />
match_rotamers = rotdat["%s:%s:%s" % (bin[0],str(bin[1]),str(bin[2]))]<br />
<br />
count = 0<br />
for item in range(0, len(match_rotamers)):<br />
<br />
# Store probablity<br />
prob = match_rotamers[item][0]<br />
<br />
# Check cutoffs<br />
if float(prob) <= float(pcutoff):<br />
continue<br />
<br />
if float(count) >= float(ncutoff):<br />
break<br />
<br />
# Increment count<br />
count += 1<br />
<br />
# Output to screen ...<br />
print "Residue %s%s, rotamer %i, prob %s" % (str(at.resn),str(at.resi),int(item),str(prob))<br />
<br />
# Set to new rotamer<br />
set_rotamer(residue_def,match_rotamers[item][1],match_rotamers[item][2],match_rotamers[item][3],match_rotamers[item][4]) <br />
<br />
# Store in PDB file<br />
cmd.save("%s_%s%s_%i_%s.pdb" % (prefix,str(at.resn),str(at.resi),int(item),str(prob)))<br />
<br />
# Reset crystal angle<br />
set_rotamer(residue_def,crystal_angles[0],crystal_angles[1],crystal_angles[2],crystal_angles[3])<br />
<br />
# Uncommenting this is nice because it loads rotamer library upon startup<br />
# however, it slows the PyMOL loading process a lot<br />
# instead I've put this call into the menuing code..<br />
# readRotLib()<br />
<br />
cmd.extend('set_phipsi',set_phipsi)<br />
cmd.extend('set_rotamer',set_rotamer)<br />
cmd.extend('colorRotamers',colorRotamers)<br />
cmd.extend('createRotamerPDBs',createRotamerPDBs)<br />
</source><br />
<br />
<br />
[[Category:Script_Library|Rotamer Toggle]]<br />
<br />
[[Category:Structural_Biology_Scripts|Rotamer Toggle]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Modevectors&diff=8035Modevectors2010-02-02T13:00:32Z<p>Cowsandmilk: </p>
<hr />
<div>[[Image:Modevectors.png|right|thumb|250px|Example showing modevectors in action. (See Examples below).]]<br />
<br />
===DESCRIPTION=== <br />
'''modevectors.py''' is a PyMol script that was originally written to visualize results obtained from Normal Mode Analysis (NMA) by drawing arrows or vectors from a starting structure to a final structure. However, this script can be used to visualize the direction of motion between two specified states (e.g. targeted MD, comparing open and closed structures, etc). The strength of this script is that the arrows are highly customizable with numerous options to choose from (see script below). It is important to note that the two states MUST be identical except for the X, Y, and Z coordinates. That is, you cannot draw vectors between homologous structures. The default settings sets the background to white and displays the arrows along with the first object frame (in cartoon representation).<br />
<br />
<br />
Note: Ray tracing these CGO arrows appears to be a memory intensive process so please save a session before ray tracing and use "pymol -qc" where necessary. If anybody can come up with a method to improve this please e-mail me (see address in script).<br />
<br />
Update: A new way of drawing the arrows has been implemented for PyMOL v.1.1 and has been updated in this code (which automatically detects the version that you are using). The new method uses the built in cone primitive rather than concentric circles decreasing in size. Thus, the new method is much less memory intensive and is a significant improvement over the old method. Additionally, you may want to turn off [[ray shadow]] depending on the [[scene]] that you are viewing as shadows can be confusing to others when seen in publications.<br />
<br />
===USAGE===<br />
<br />
load the script using the [[run]] command<br />
<br />
<source lang="python"><br />
modevectors first_obj_frame, last_obj_frame [,outname=modevectors [,head=1.0 [,tail=0.3 \<br />
[,head_length=1.5 [,headrgb=(1.0,1.0,1.0) [,tailrgb=(1.0,1.0,1.0) [,cutoff=4.0 [,skip=0 \<br />
[,cut=0.5 [,atom=CA [,stat=show [,factor=1.0]]]]]]]]]]]<br />
</source><br />
<br />
Please see the script comments for further custom options. Once the script completes, it will generate a new object called "modevectors" (which can be changed through the options).<br />
<br />
<br />
===EXAMPLES===<br />
<source lang="python"><br />
modevectors 1E3M, 1W7A<br />
modevectors 1E3M, 1W7A, outname="arrows"<br />
modevectors 1E3M, 1W7A, atom="P"<br />
</source><br />
<br />
Copy/paste the following code to see an example of modevectors. This uses a multistate protein and the arrows are connected between the first and last states.<br />
<source lang="python"><br />
# load the code<br />
run modevectors.py<br />
# fetch the PDBs from pdb.org<br />
fetch 1c3y, finish=1, multiplex=0<br />
# separate the first and last states of the NMR ensemble to individual objects<br />
split_states 1c3y, 1, 1<br />
split_states 1c3y, 23, 23<br />
hide<br />
# run the modevectors code<br />
modevectors 1c3y_0001, 1c3y_0023<br />
# just setup a nice representation<br />
as cartoon, 1c3y_0001 or 1c3y_0023<br />
show cgo, modevectors<br />
color marine, 1c3y_0001<br />
color purpleblue, 1c3y_0023<br />
</source><br />
<br />
The following set of examples will illustrate the power of each optional argument. Each example should be compared to the default figure in the table below.<br />
<br />
{|<br />
|[[Image:mv_default.png|thumb|300px|left|Fig.1 - Default Settings]]<br />
||[[Image:mv_fig2.png|thumb|300px|left|Fig.2 - Arrow direction drawn from CA to CA]]<br />
||[[Image:mv_fig3.png|thumb|300px|left|Fig.3 - Arrow head radius]]<br />
|-<br />
|[[Image:mv_fig4.png|thumb|300px|left|Fig.4 - Arrow tail radius]]<br />
||[[Image:mv_fig5.png|thumb|300px|left|Fig.5 - Arrow head length]]<br />
||[[Image:mv_fig6.png|thumb|300px|left|Fig.6 - Arrow head RGB]]<br />
|-<br />
|[[Image:mv_fig7.png|thumb|300px|left|Fig.7 - Arrow tail RGB]]<br />
||[[Image:mv_fig8.png|thumb|300px|left|Fig.8 - Arrow length cutoff]]<br />
||[[Image:mv_fig9.png|thumb|300px|left|Fig.9 - Skip every other arrow]]<br />
|-<br />
|[[Image:mv_fig10.png|thumb|300px|left|Fig.10 - Subtract value from vector length]]<br />
||[[Image:mv_fig11.png|thumb|300px|left|Fig.11 - Draw arrows from CB atoms]]<br />
||[[Image:mv_fig12.png|thumb|300px|left|Fig.12 - Shorten by 50%]]<br />
|-<br />
|||[[Image:mv_fig13.png|thumb|300px|left|Fig.13 - Multiple options being used (see final example below)]]<br />
<br />
|}<br />
<br />
<source lang="python"><br />
fetch 1c3y<br />
split_states 1c3y, 1, 1<br />
split_states 1c3y, 23, 23<br />
hide<br />
<br />
#This is the default setting (Fig.1)<br />
modevectors 1c3y_0001, 1c3y_0023<br />
<br />
#This is shows that the direction of the arrows is drawn from the 1c3y_0001 towards 1c3y_0023 (Fig.2)<br />
show cartoon, 1c3y_0023<br />
color red, 1c3y_0023<br />
<br />
#This controls the base radius of the cone/arrow head in angstroms (Fig.3)<br />
modevectors 1c3y_0001, 1c3y_0023, head=2.5<br />
<br />
#This controls the radius of the cylinders/arrow tails in angstroms (Fig.4)<br />
modevectors 1c3y_0001, 1c3y_0023, tail=0.75<br />
<br />
#This controls the length of the cone/arrow head in angstroms (Fig.5)<br />
#Note that this option does NOT increase the vector length but simply changes the tail length<br />
modevectors 1c3y_0001, 1c3y_0023, head_length=3.0<br />
<br />
#This controls the colour of the cone/arrow head using RGB values (Fig.6)<br />
modevectors 1c3y_0001, 1c3y_0023, headrgb=(1.0,0.0,0.0)<br />
<br />
#This controls the colour of the cylinder/arrow tails using RGB values (Fig.7)<br />
modevectors 1c3y_0001, 1c3y_0023, tailrgb=(1.0,0.0,0.0)<br />
<br />
#This controls the which vectors to show based on a specific cutoff value in angstroms. Vector lengths that are less <br />
#than the cutoff value will not be displayed (Fig.8)<br />
modevectors 1c3y_0001, 1c3y_0023, cutoff=30.0<br />
<br />
#This controls how many vectors to skip (integer value) and is useful when there are too many vectors showing. <br />
#Skip=1 will show every other arrow (Fig.9)<br />
modevectors 1c3y_0001, 1c3y_0023, skip=1<br />
<br />
#This controls how much to cut from each vector (in angstroms). Note that arrows will point in the opposite directions <br />
#when too much is cutoff (resulting in a negative vector length) (Fig.10) and should be used with caution!<br />
modevectors 1c3y_0001, 1c3y_0023, cut=15.0<br />
<br />
#This controls which atom to draw a vector from (Fig.11). Note that this is case-sensitive and is really only useful <br />
#when atom=CA or when atom=P (for DNA backbones)<br />
modevectors 1c3y_0001, 1c3y_0023, atom=CB<br />
<br />
#This controls how much to multiple the length of each vector by (percentage increase/decrease) (Fig.12)<br />
#This example halves the length of each vector (50%)<br />
modevectors 1c3y_0001, 1c3y_0023, factor=0.5<br />
<br />
#This hides the statistics which count atoms skipped, atoms counted (number of arrows showing), and number of atoms <br />
#that did not meet the cutoff and are not shown<br />
modevectors 1c3y_0001, 1c3y_0023, stat=hide<br />
<br />
#Finally, this example shows multiple options being used (Fig.13)<br />
modevectors 1c3y_0001, 1c3y_0023, head=2.0, tail=1.0, head_length=2.0, headrgb=(1.0,0.0,0.0), tailrgb=(0.0,0.0,1.0),<br />
cutoff=0.0,skip=0,cut=0,atom=CA,factor=0.8<br />
<br />
</source><br />
<br />
===PYMOL API===<br />
<source lang=python><br />
from pymol.cgo import * # get constants<br />
from math import *<br />
from pymol import cmd<br />
<br />
def modevectors( first_obj_frame, last_obj_frame, outname="modevectors", head=1.0,tail=0.3, head_length=1.5, headrgb="1.0,1.0,1.0",tailrgb="1.0,1.0,1.0",cutoff=4.0,skip=0,cut=0.5,atom="CA",stat="show",factor=1.0):<br />
"""<br />
Authors Sean Law & Srinivasa<br />
Michigan State University<br />
slaw_(at)_msu_dot_edu<br />
<br />
Editor Sacha Yee<br />
<br />
USAGE<br />
<br />
While in PyMOL<br />
<br />
Parameter Preset Type Description<br />
first_obj_frame Undefined String Object name of the first structure. The mode vector will propagate from this structure. Defined by user.<br />
last_obj_frame Undefined String Object name of the last structure. The mode vector (arrow head) will end at this structure. Defined by user.<br />
outname modevectors String Name of object to store mode vectors in.<br />
head 1.0 Float Radius for the circular base of the arrow head (cone)<br />
tail 0.3 Float Radius for the cylinder of the arrow tail (cylinder)<br />
head_length 1.5 Float Length of the arrow head (from the base of the cone to the tip of cone)<br />
head_rgb 1.0,1.0,1.0 String RGB colour for the arrow head.<br />
tail_rgb 1.0,1.0,1.0 String RGB colour for the arrow tail.<br />
cutoff 4.0 Float Skips mode vectors that do not meet the cutoff distance (in Angstroms).<br />
skip 0 Integer Denotes how many atoms to skip. No arrows will be created for skipped atoms.<br />
cut 0.0 Float Truncates all arrow tail lengths (without disturbing the arrow head) (in Angstroms).<br />
atom CA String Designates the atom to derive mode vectors from.<br />
stat show String Keeps track and prints statistics (total modevectors, skipped, cutoff).<br />
factor 1.0 Float Multiplies each mode vector length by a specified factor.<br />
Values between 0 and 1 will decrease the relative mode vector length.<br />
Values greater than 1 will increase the relative mode vector length.<br />
<br />
"""<br />
<br />
framefirst=cmd.get_model(first_obj_frame)<br />
framelast=cmd.get_model(last_obj_frame)<br />
objectname=outname<br />
factor=float(factor)<br />
arrow_head_radius=float(head)<br />
arrow_tail_radius=float(tail)<br />
arrow_head_length=float(head_length)<br />
cutoff=float(cutoff)<br />
skip=int(skip)<br />
cut=float(cut)<br />
atomtype=atom.strip('"[]()')<br />
<br />
headrgb=headrgb.strip('" []()')<br />
tailrgb=tailrgb.strip('" []()')<br />
hr,hg,hb=map(float,headrgb.split(','))<br />
tr,tg,tb=map(float,tailrgb.split(','))<br />
<br />
version=cmd.get_version()<br />
pi=4*atan2(1,1)<br />
arrow=[]<br />
arrowhead = []<br />
arrowtail = []<br />
x1 = []<br />
y1 = []<br />
z1 = []<br />
x2 = []<br />
y2 = []<br />
z2 = []<br />
exit_flag=0<br />
<br />
##############################################################<br />
# #<br />
# Define an object called "tail" and store the tail and a #<br />
# circular base of the triangle in this object. #<br />
# #<br />
##############################################################<br />
<br />
skipcount=0<br />
skipcounter=0<br />
keepcounter=0<br />
atom_lookup={}<br />
for atom in framefirst.atom:<br />
if atom.name == atomtype:<br />
if skipcount == skip:<br />
x1.append(atom.coord[0])<br />
y1.append(atom.coord[1])<br />
z1.append(atom.coord[2])<br />
<br />
##########################################<br />
# #<br />
# Set atom_lookup for a specific atom #<br />
# equal to ONE for the first input set. #<br />
# This dictionary will be used as a #<br />
# reference for the second set. #<br />
# #<br />
##########################################<br />
<br />
current_atom="CHAIN "+atom.chain+" RESID "\<br />
+atom.resi+" RESTYPE "\<br />
+atom.resn+\<br />
" ATMNUM "+str(atom.index)<br />
# print current_atom<br />
atom_lookup['current_atom']=1<br />
<br />
skipcount=0<br />
keepcounter=keepcounter+1<br />
else:<br />
# print skipcount<br />
skipcount=skipcount+1<br />
skipcounter=skipcounter+1<br />
<br />
skipcount=0<br />
for atom in framelast.atom:<br />
if atom.name == atomtype:<br />
if skipcount == skip:<br />
x2.append(atom.coord[0])<br />
y2.append(atom.coord[1])<br />
z2.append(atom.coord[2])<br />
<br />
#########################################<br />
# #<br />
# Get atom information from second set #<br />
# and compare with first set. All #<br />
# atoms from this second set MUST be #<br />
# found in the first set! Otherwise, #<br />
# the script will exit with an error #<br />
# since modevectors can only be created #<br />
# by calculating values from identical #<br />
# sources. #<br />
# #<br />
#########################################<br />
<br />
current_atom="CHAIN "+atom.chain+" RESID "\<br />
+atom.resi+" RESTYPE "\<br />
+atom.resn+\<br />
" ATMNUM "+str(atom.index)<br />
# print current_atom<br />
if atom_lookup.has_key('current_atom') != 1:<br />
print "\nError: "+current_atom+" from \""\<br />
+last_obj_frame+\<br />
" \"is not found in \""+first_obj_frame+"\"."<br />
print "\nPlease check your input and/or selections and try again."<br />
exit_flag=1<br />
break<br />
<br />
skipcount=0<br />
else:<br />
skipcount=skipcount+1<br />
<br />
if exit_flag == 1:<br />
###########################################<br />
# #<br />
# Exit script because an atom cannot be #<br />
# found in both input files #<br />
# #<br />
###########################################<br />
return<br />
<br />
cutoff_counter=0 # Track number of atoms failing to meet the cutoff<br />
<br />
###################################################<br />
# #<br />
# Check that the two selections/PDB files contain #<br />
# the same number of atoms. #<br />
# #<br />
###################################################<br />
<br />
if len(x2) != len(x1):<br />
print "\nError: \""+first_obj_frame+\<br />
"\" and \""+last_obj_frame+\<br />
"\" contain different number of residue/atoms."<br />
print "\nPlease check your input and/or selections and try again."<br />
return<br />
else:<br />
#Continue with representing modevectors!<br />
#########################################<br />
# #<br />
# Delete old selection or object if it #<br />
# exists so that it can be overwritten #<br />
# #<br />
#########################################<br />
save_view=cmd.get_view(output=1,quiet=1)<br />
cmd.delete(name=outname)<br />
cmd.hide(representation="everything",selection=first_obj_frame)<br />
cmd.hide(representation="everything",selection=last_obj_frame)<br />
<br />
<br />
<br />
###################################################<br />
# #<br />
# Begin drawing arrow tails #<br />
# #<br />
###################################################<br />
<br />
arrowtail = []<br />
for mv in range(len(x1)):<br />
vectorx=x2[mv]-x1[mv]<br />
vectory=y2[mv]-y1[mv]<br />
vectorz=z2[mv]-z1[mv]<br />
length=sqrt(vectorx**2+vectory**2+vectorz**2)<br />
if length < cutoff:<br />
cutoff_counter=cutoff_counter+1<br />
continue<br />
t=1.0-(cut/length)<br />
x2[mv]=x1[mv]+factor*t*vectorx<br />
y2[mv]=y1[mv]+factor*t*vectory<br />
z2[mv]=z1[mv]+factor*t*vectorz<br />
vectorx=x2[mv]-x1[mv]<br />
vectory=y2[mv]-y1[mv]<br />
vectorz=z2[mv]-z1[mv]<br />
length=sqrt(vectorx**2+vectory**2+vectorz**2)<br />
d=arrow_head_length # Distance from arrow tip to arrow base<br />
t=1.0-(d/length)<br />
tail = [<br />
# Tail of cylinder<br />
CYLINDER, x1[mv],y1[mv],z1[mv]\<br />
,x1[mv]+(t+0.01)*vectorx,y1[mv]+(t+0.01)*vectory,z1[mv]+(t+0.01)*vectorz\<br />
,arrow_tail_radius,tr,tg,tb,tr,tg,tb # Radius and RGB for each cylinder tail<br />
]<br />
arrow.extend(tail)<br />
<br />
x=x1[mv]+t*vectorx<br />
y=y1[mv]+t*vectory<br />
z=z1[mv]+t*vectorz<br />
dx=x2[mv]-x<br />
dy=y2[mv]-y<br />
dz=z2[mv]-z<br />
seg=d/100<br />
intfactor=int(factor)<br />
if (version < 1.1): #Version >= 1.1 has cone primitive<br />
for i in range (100,0,-1): #i=100 is tip of cone<br />
print i<br />
t1=seg*i<br />
t2=seg*(i+1)<br />
radius=arrow_head_radius*(1.0-i/(100.0)) #Radius of each disc that forms cone<br />
head=[<br />
CYLINDER, x+t2*dx,y+t2*dy,z+t2*dz\<br />
,x+t1*dx,y+t1*dy,z+t1*dz\<br />
,radius,hr,hg,hb,hr,hg,hb # Radius and RGB for slice of arrow head<br />
]<br />
arrow.extend(head)<br />
else:<br />
head=[<br />
CONE, x, y ,z, x+d*dx, y+d*dy, z+d*dz, arrow_head_radius, 0.0, hr, hg, hb, hr, hg, hb, 1.0, 1.0 ]<br />
arrow.extend(head)<br />
<br />
##############################################################<br />
# #<br />
# Load the entire object into PyMOL #<br />
# #<br />
# Print statistics if requested by user #<br />
# #<br />
##############################################################<br />
<br />
if stat == "show":<br />
natoms=skipcounter+keepcounter<br />
print "\nTotal number of atoms = "+str(natoms)<br />
print "Atoms skipped = "+str(skipcounter)<br />
if keepcounter-cutoff_counter > 0:<br />
print "Atoms counted = "+str(keepcounter-cutoff_counter)+" (see PyMOL object \""+outname+"\")"<br />
else:<br />
print "Atoms counted = "+str(keepcounter-cutoff_counter)+" (Empty CGO object not loaded)" <br />
print "Atoms cutoff = "+str(cutoff_counter) #Note that cutoff occurs AFTER skipping!<br />
if keepcounter-cutoff_counter > 0:<br />
cmd.load_cgo(arrow,objectname) #Ray tracing an empty object will cause a segmentation fault. No arrows = Do not display in PyMOL!!!<br />
cmd.show(representation="cartoon",selection=first_obj_frame)<br />
cmd.cartoon("tube")<br />
cmd.show(representation="cartoon",selection=last_obj_frame)<br />
cmd.hide(representation="cartoon",selection=last_obj_frame)<br />
cmd.bg_color(color="white")<br />
cmd.set_view(save_view)<br />
return<br />
<br />
cmd.extend("modevectors",modevectors)<br />
</source><br />
[[Category:Script_Library]]<br />
[[Category:Math_Scripts]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Wfmesh&diff=8034Wfmesh2010-02-02T12:58:28Z<p>Cowsandmilk: </p>
<hr />
<div>===DESCRIPTION===<br />
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->Insert->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. <br />
<br />
*createWFMesh - create a mesh object from Wavefront (*.obj) formated file<br />
<br />
===IMAGES===<br />
[[Image:Starwars_pymol.png|thumb|left|Star Wars Anyone?]]<br />
[[Image:Torus_pymol.png|thumb|left|A Torus, as an example shape you could do. Notice polygon normals are being used...need smoothing!]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
[[Category:ThirdParty_Scripts]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
===SETUP===<br />
Simply "run WFMesh.py"<br />
<br />
===NOTES / STATUS===<br />
*Tested on Pymolv0.97, Windows platform, should work on linux as well.<br />
*Coloring is fixed for grey and sections of mesh are stored, but not used.<br />
*Simple opengl calls; not optimized (display lists, etc) or anything.<br />
*Vertex Normal code is broken, so normals are per polygon right now.<br />
*Post problems in the discussion page, on 'my talk' page or just email me : dwkulp@mail.med.upenn.edu<br />
<br />
<br />
===USAGE===<br />
createWFObj file, name [,translate=[0,0,0]] [,flip=0]<br />
<br />
===EXAMPLES===<br />
createWFObj "ship.obj" "Ship"<br />
createWFObj "torus.obj" "Torus" flip=1 # Flip = 1, if OBJ created by openFX, crossroads3D combination<br />
createWFObj "torus.obj" "Torus" translate=[10,10,0] flip=1 <br />
<br />
===REFERENCES===<br />
[http://www.openfx.org OpenFX]<br />
[http://synapses.mcg.edu/tools/xroads/xroads.stm Crossroads3D]<br />
<br />
===SCRIPTS (WFMesh.py)===<br />
WFMesh.py<br />
<source lang="python"><br />
###############################################<br />
# File: WFObj.py<br />
# Author: Dan Kulp<br />
# Creation Date: 5/13/05<br />
#<br />
# Notes:<br />
# Create openGL objects from a wavefront (obj) file<br />
###############################################<br />
<br />
import os<br />
import string<br />
import re<br />
import math<br />
from pymol.opengl.gl import *<br />
from pymol.callback import Callback<br />
<br />
<br />
# Wrapper Function, to create a given WFObj with a specific name (flip = 1 if OpenFX + Crossroads used)<br />
def createWFObj(file, name,translate=[0,0,0],flip=0):<br />
obj = WFMesh(file,translate,flip)<br />
cmd.load_callback(obj,name)<br />
<br />
<br />
# Class for Wavefront Mesh<br />
class WFMesh(Callback):<br />
<br />
verts = [] # list of vertices<br />
polys = [] # list of poylgons<br />
pnorms = [] # list of polynomal normals<br />
vnorms = {} # dict. of vertex normals<br />
vavenorms = [] # list of vertex normals, redundant -- I'm far froma python pro.<br />
sections = {} # list of sections of mesh<br />
<br />
# Read mesh into memory<br />
def readOBJ(self,file):<br />
if os.path.exists(file):<br />
input = open(file,'r')<br />
for line in input:<br />
dat = re.split("\s+", line)<br />
<br />
# Find vertex line<br />
if line[0] == 'v' and line[1] != 't' and line[1] != 'n': self.verts.append([dat[1],dat[2],dat[3]])<br />
<br />
# Find polygon line<br />
if line[0] == 'f': self.polys.append([dat[1],dat[2],dat[3]])<br />
<br />
# Find section line<br />
if line[0] == 'g': self.sections[len(self.polys)] = dat[1] <br />
<br />
<br />
# Compute the normals for each polygon and each vertex <br />
def computeNorms(self):<br />
<br />
# Compute norms for each polygon<br />
for p in self.polys:<br />
v12 = [float(self.verts[int(p[1])-1][0]) - float(self.verts[int(p[0])-1][0]),\<br />
float(self.verts[int(p[1])-1][1]) - float(self.verts[int(p[0])-1][1]),\<br />
float(self.verts[int(p[1])-1][2]) - float(self.verts[int(p[0])-1][2]) \<br />
]<br />
<br />
v13 = [float(self.verts[int(p[2])-1][0]) - float(self.verts[int(p[0])-1][0]),\<br />
float(self.verts[int(p[2])-1][1]) - float(self.verts[int(p[0])-1][1]),\<br />
float(self.verts[int(p[2])-1][2]) - float(self.verts[int(p[0])-1][2]) \<br />
] <br />
<br />
# Compute poly normal<br />
polynorm = self.cross(v12,v13) <br />
norm = self.normalize(polynorm)<br />
<br />
<br />
# Files created by OpenFX, Crossroads combination need have their normals flipped <br />
if self.flip:<br />
norm[0] = -norm[0]<br />
norm[1] = -norm[1]<br />
norm[2] = -norm[2]<br />
<br />
# Append poly norm to polygonal norm array<br />
self.pnorms.append(norm)<br />
<br />
# Add norm to each vertexes norm..<br />
try:<br />
self.vnorms[int(p[0])-1] = [float(self.vnorms[int(p[0])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[0])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[0])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[0])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
try: <br />
self.vnorms[int(p[1])-1] = [float(self.vnorms[int(p[1])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[1])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[1])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[1])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
try:<br />
self.vnorms[int(p[2])-1] = [float(self.vnorms[int(p[1])-1][0]) + norm[0],<br />
float(self.vnorms[int(p[1])-1][1]) + norm[1],<br />
float(self.vnorms[int(p[1])-1][2]) + norm[2]<br />
]<br />
except:<br />
self.vnorms[int(p[2])-1] = [norm[0],norm[1],norm[2]]<br />
<br />
<br />
# Average out each vnorm..<br />
index = 0<br />
for v in self.vnorms.values():<br />
self.vavenorms.append([v[0]/4, v[1]/4, v[2]/4]) <br />
index += 1<br />
<br />
# Utility function to normalize a given vector<br />
def normalize(self,v):<br />
mag = v[0]*v[0]+v[1]*v[1]+v[2]*v[2]<br />
if mag <= 0:<br />
mag = 1<br />
else:<br />
mag = math.sqrt(mag)<br />
<br />
return [v[0]/mag, v[1]/mag,v[2]/mag]<br />
<br />
# Utility cross product function<br />
def cross(self,v1,v2):<br />
x = 0<br />
y = 1<br />
z = 2<br />
<br />
return [v1[y]*v2[z] - v1[z]*v2[y],\<br />
v1[z]*v2[x] - v1[x]*v2[z],\<br />
v1[x]*v2[y] - v1[y]*v2[x]<br />
]<br />
<br />
# Constructor<br />
def __init__(self, file,translate=[0,0,0],flip=0):<br />
self.verts = []<br />
self.polys = [] <br />
self.pnorms = []<br />
self.vnorms = {}<br />
self.vavenorms = []<br />
self.translate = translate<br />
self.flip = flip <br />
<br />
print "Read in file: "+str(file)<br />
self.readOBJ(file)<br />
print "Done reading in WFMesh, now compute norms"<br />
self.computeNorms()<br />
print "Done computing norms, now display WFMesh"<br />
<br />
# Draw Function<br />
def __call__(self):<br />
<br />
glColorMaterial(GL_FRONT, GL_DIFFUSE); <br />
glEnable(GL_COLOR_MATERIAL);<br />
glShadeModel(GL_SMOOTH);<br />
<br />
# Color Everything grey<br />
glColor3f(0.5,0.5,0.5);<br />
<br />
index = 0<br />
glPushMatrix()<br />
glTranslated(self.translate[0],self.translate[1],self.translate[2])<br />
for p in self.polys:<br />
glBegin(GL_POLYGON)<br />
glNormal3f(float(self.pnorms[index][0]),float(self.pnorms[index][1]),float(self.pnorms[index][2]))<br />
<br />
for i in range(0,len(p)):<br />
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]))<br />
<br />
# Vertex Normals - not computed correctly, so commented out for now<br />
# norm = self.vnorms[int(p[i])-1]<br />
# glNormal3f(float(norm[0]),float(norm[1]),float(norm[2]))<br />
glEnd()<br />
index += 1<br />
glPopMatrix()<br />
<br />
<br />
<br />
<br />
<br />
cmd.extend("createWFObj", createWFObj)<br />
<br />
</source><br />
<br />
===ADDITIONAL RESOURCES===<br />
Torus.obj<br />
[http://pymolwiki.org/images/9/98/Torus.zip Torus.zip]<br />
<br />
<br />
[[Category:Script_Library|WFMesh]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Color_Objects&diff=8033Color Objects2010-02-02T12:56:42Z<p>Cowsandmilk: </p>
<hr />
<div><source lang="python"><br />
#####################################################################<br />
#<br />
# Colour by object<br />
#<br />
#####################################################################<br />
<br />
def color_obj(rainbow=0):<br />
<br />
"""<br />
<br />
AUTHOR <br />
<br />
Gareth Stockwell<br />
<br />
USAGE<br />
<br />
color_obj(rainbow=0)<br />
<br />
This function colours each object currently in the PyMOL heirarchy<br />
with a different colour. Colours used are either the 22 named<br />
colours used by PyMOL (in which case the 23rd object, if it exists,<br />
gets the same colour as the first), or are the colours of the rainbow<br />
<br />
"""<br />
<br />
# Process arguments<br />
rainbow = int(rainbow)<br />
<br />
# Get names of all PyMOL objects<br />
obj_list = cmd.get_names('models')<br />
<br />
if rainbow:<br />
<br />
print "\nColouring objects as rainbow\n"<br />
<br />
nobj = len(obj_list)<br />
<br />
# Create colours starting at blue(240) to red(0), using intervals<br />
# of 240/(nobj-1)<br />
for j in range(nobj):<br />
hsv = (240-j*240/(nobj-1), 1, 1)<br />
# Convert to RGB<br />
rgb = hsv_to_rgb(hsv)<br />
# Define the new colour<br />
cmd.set_color("col" + str(j), rgb)<br />
print obj_list[j], rgb<br />
# Colour the object<br />
cmd.color("col" + str(j), obj_list[j])<br />
<br />
else:<br />
<br />
print "\nColouring objects using PyMOL defined colours\n"<br />
<br />
# List of available colours<br />
colours = ['red', 'green', 'blue', 'yellow', 'violet', 'cyan', \<br />
'salmon', 'lime', 'pink', 'slate', 'magenta', 'orange', 'marine', \<br />
'olive', 'purple', 'teal', 'forest', 'firebrick', 'chocolate', \<br />
'wheat', 'white', 'grey' ]<br />
ncolours = len(colours)<br />
<br />
# Loop over objects<br />
i = 0<br />
for obj in obj_list:<br />
print " ", obj, colours[i]<br />
cmd.color(colours[i], obj)<br />
i = i+1<br />
if(i == ncolours):<br />
i = 0<br />
<br />
<br />
# HSV to RGB routine taken from Robert L. Campbell's color_b.py script<br />
# See http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/<br />
# Original algorithm from: http://www.cs.rit.edu/~ncs/color/t_convert.html<br />
def hsv_to_rgb(hsv):<br />
<br />
h = float(hsv[0])<br />
s = float(hsv[1])<br />
v = float(hsv[2])<br />
<br />
if( s == 0 ) :<br />
#achromatic (grey)<br />
r = g = b = v<br />
<br />
else:<br />
# sector 0 to 5<br />
h = h/60. <br />
i = int(h)<br />
f = h - i # factorial part of h<br />
#print h,i,f<br />
p = v * ( 1 - s )<br />
q = v * ( 1 - s * f )<br />
t = v * ( 1 - s * ( 1 - f ) )<br />
<br />
if i == 0:<br />
(r,g,b) = (v,t,p)<br />
elif i == 1:<br />
(r,g,b) = (q,v,p)<br />
elif i == 2:<br />
(r,g,b) = (p,v,t)<br />
elif i == 3:<br />
(r,g,b) = (p,q,v)<br />
elif i == 4:<br />
(r,g,b) = (t,p,v)<br />
elif i == 5:<br />
(r,g,b) = (v,p,q)<br />
else:<br />
(r,g,b) = (v,v,v)<br />
print "error, i not equal 1-5"<br />
<br />
return [r,g,b]<br />
<br />
<br />
<br />
# Add color_obj to the PyMOL command list <br />
cmd.extend("color_obj",color_obj)<br />
<br />
</source><br />
<br />
[[Category:Script_Library|Color Objects]]<br />
[[Category:Coloring]]<br />
[[Category:ObjSel_Scripts]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=DynoPlot&diff=8032DynoPlot2010-02-02T12:55:55Z<p>Cowsandmilk: </p>
<hr />
<div>===DESCRIPTION===<br />
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.<br />
<br />
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).<br />
<br />
===IMAGES===<br />
<gallery><br />
Image:RamaPlotInitComposite.png|Initial Ramachandran plot of 1ENV<br />
Image:RamaPlotBentComposite.png|Modified pose and plot of 1ENV<br />
</gallery><br />
<br />
===SETUP===<br />
place the DynoPlot.py script into the appropriate startup directory then restart PyMol<br />
<br />
==== LINUX old-style installation ====<br />
<br />
$PYMOL_PATH/modules/pmg_tk/startup/<br />
<br />
==== LINUX distutils installation ====<br />
<br />
/usr/lib/pythonX.X/site-packages/pmg_tk/startup/<br />
<br />
==== Windows ====<br />
<br />
PYMOL_PATH/modules/pmg_tk/startup/ , where PYMOL_PATH on Windows is defaulted to C:/Program Files/DeLano Scientific/PyMol/start/<br />
<br />
===NOTES / STATUS===<br />
*Tested on Windows, PyMol version 0.97<br />
*This is an initial version, which needs some work. <br />
*Left, Right mouse buttons do different things; Right = identify data point, Left = drag data point around<br />
*Post comments/questions or send them to: dwkulp@mail.med.upenn.edu<br />
<br />
===USAGE===<br />
rama SELECTION<br />
<br />
===EXAMPLES=== <br />
*load pdb file 1ENV (download it or use the PDB loader plugin)<br />
*select resi 129-136<br />
*rama sel01<br />
*rock # the object needs to be moving in order for the angles to be updated.<br />
<br />
===REFERENCES===<br />
<br />
===SCRIPTS (DynoPlot.py)===<br />
DynoPlot.py<br />
<source lang="python"><br />
#!/usr/bin/env python<br />
###############################################<br />
# File: DynoPlot.py<br />
# Author: Dan Kulp<br />
# Creation Date: 8/29/05<br />
#<br />
# Notes:<br />
# Draw plots that display interactive data. <br />
# Phi,Psi plot shown.<br />
###############################################<br />
<br />
<br />
from __future__ import division<br />
from __future__ import generators<br />
<br />
import os,math<br />
import Tkinter<br />
from Tkinter import *<br />
import Pmw<br />
import distutils.spawn # used for find_executable<br />
import random<br />
from pymol import cmd<br />
<br />
try:<br />
import pymol<br />
REAL_PYMOL = True<br />
except ImportError:<br />
print "Nope"<br />
<br />
canvas = None<br />
rootframe = None<br />
init = 0<br />
<br />
class SimplePlot(Tkinter.Canvas):<br />
<br />
# Class variables<br />
mark = 'Oval' # Only 'Oval' for now..<br />
mark_size = 5<br />
xlabels = [] # axis labels<br />
ylabels = []<br />
spacingx = 0 # spacing in x direction<br />
spacingy = 0 <br />
xmin = 0 # min value from each axis<br />
ymin = 0<br />
lastx = 0 # previous x,y pos of mouse <br />
lasty = 0<br />
down = 0 # flag for mouse pressed<br />
item = (0,) # items array used for clickable events<br />
shapes = {} # store plot data, x,y etc..<br />
<br />
def axis(self,xmin=40,xmax=300,ymin=10,ymax=290,xint=290,yint=40,xlabels=[],ylabels=[]):<br />
<br />
# Store variables in self object<br />
self.xlabels = xlabels<br />
self.ylabels = ylabels<br />
self.spacingx = (xmax-xmin) / (len(xlabels) - 1)<br />
self.spacingy = (ymax-ymin) / (len(ylabels) - 1)<br />
self.xmin = xmin<br />
self.ymin = ymin<br />
<br />
# Create axis lines<br />
self.create_line((xmin,xint,xmax,xint),fill="black",width=3)<br />
self.create_line((yint,ymin,yint,ymax),fill="black",width=3)<br />
<br />
# Create tick marks and labels<br />
nextspot = xmin<br />
for label in xlabels:<br />
self.create_line((nextspot, xint+5,nextspot, xint-5),fill="black",width=2)<br />
self.create_text(nextspot, xint-15, text=label)<br />
if len(xlabels) == 1:<br />
nextspot = xmax<br />
else:<br />
nextspot = nextspot + (xmax - xmin)/ (len(xlabels) - 1)<br />
<br />
<br />
nextspot = ymax<br />
for label in ylabels:<br />
self.create_line((yint+5,nextspot,yint-5,nextspot),fill="black",width=2)<br />
self.create_text(yint-20,nextspot,text=label)<br />
if len(ylabels) == 1:<br />
nextspot = ymin<br />
else:<br />
nextspot = nextspot - (ymax - ymin)/ (len(ylabels) - 1)<br />
<br />
<br />
# Plot a point<br />
def plot(self,xp,yp,meta):<br />
<br />
# Convert from 'label' space to 'pixel' space<br />
x = self.convertToPixel("X",xp)<br />
y = self.convertToPixel("Y",yp)<br />
<br />
if self.mark == "Oval":<br />
oval = self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline="black",fill="SkyBlue2")<br />
<br />
self.shapes[oval] = [x,y,0,xp,yp,meta]<br />
<br />
<br />
# Repaint all points <br />
def repaint(self):<br />
for key,value in self.shapes.items():<br />
x = value[0]<br />
y = value[1]<br />
self.create_oval(x-self.mark_size,y-self.mark_size,x+self.mark_size,y+self.mark_size,width=1,outline="black",fill="SkyBlue2")<br />
<br />
# Convert from pixel space to label space<br />
def convertToLabel(self,axis, value):<br />
<br />
# Defaultly use X-axis info<br />
label0 = self.xlabels[0]<br />
label1 = self.xlabels[1]<br />
spacing = self.spacingx<br />
min = self.xmin<br />
<br />
# Set info for Y-axis use<br />
if axis == "Y":<br />
label0 = self.ylabels[0]<br />
label1 = self.ylabels[1]<br />
spacing = self.spacingy<br />
min = self.ymin <br />
<br />
pixel = value - min<br />
label = pixel / spacing<br />
label = label0 + label * abs(label1 - label0)<br />
<br />
if axis == "Y":<br />
label = - label<br />
<br />
return label<br />
<br />
# Converts value from 'label' space to 'pixel' space<br />
def convertToPixel(self,axis, value):<br />
<br />
# Defaultly use X-axis info<br />
label0 = self.xlabels[0]<br />
label1 = self.xlabels[1]<br />
spacing = self.spacingx<br />
min = self.xmin<br />
<br />
# Set info for Y-axis use<br />
if axis == "Y":<br />
label0 = self.ylabels[0]<br />
label1 = self.ylabels[1]<br />
spacing = self.spacingy<br />
min = self.ymin <br />
<br />
<br />
# Get axis increment in 'label' space<br />
inc = abs(label1 - label0)<br />
<br />
# 'Label' difference from value and smallest label (label0)<br />
diff = float(value - label0)<br />
<br />
# Get whole number in 'label' space<br />
whole = int(diff / inc)<br />
<br />
# Get fraction number in 'label' space<br />
part = float(float(diff/inc) - whole)<br />
<br />
# Return 'pixel' position value<br />
pixel = whole * spacing + part * spacing<br />
<br />
# print "Pixel: %f * %f + %f * %f = %f" % (whole, spacing, part, spacing,pixel)<br />
<br />
# Reverse number by subtracting total number of pixels - value pixels<br />
if axis == "Y":<br />
tot_label_diff = float(self.ylabels[len(self.ylabels)- 1] - label0)<br />
tot_label_whole = int(tot_label_diff / inc)<br />
tot_label_part = float(float(tot_label_diff / inc) - tot_label_whole)<br />
tot_label_pix = tot_label_whole * spacing + tot_label_part *spacing<br />
<br />
pixel = tot_label_pix - pixel<br />
<br />
# Add min edge pixels<br />
pixel = pixel + min<br />
<br />
return pixel<br />
<br />
<br />
# Print out which data point you just clicked on..<br />
def pickWhich(self,event):<br />
<br />
# Find closest data point <br />
x = event.widget.canvasx(event.x)<br />
y = event.widget.canvasx(event.y)<br />
spot = event.widget.find_closest(x,y)<br />
<br />
# Print the shape's meta information corresponding with the shape that was picked<br />
if self.shapes.has_key(spot[0]):<br />
print "Residue(Ca): %s\n" % str(self.shapes[spot[0]][5][2])<br />
<br />
<br />
# Mouse Down Event<br />
def down(self,event):<br />
<br />
# Store x,y position<br />
self.lastx = event.x<br />
self.lasty = event.y<br />
<br />
# Find the currently selected item<br />
x = event.widget.canvasx(event.x)<br />
y = event.widget.canvasx(event.y)<br />
self.item = event.widget.find_closest(x,y)<br />
<br />
# Identify that the mouse is down<br />
self.down = 1<br />
<br />
# Mouse Up Event<br />
def up(self,event):<br />
<br />
# Get label space version of x,y<br />
labelx = self.convertToLabel("X",event.x)<br />
labely = self.convertToLabel("Y",event.y)<br />
<br />
# Convert new position into label space..<br />
if self.shapes.has_key(self.item[0]):<br />
self.shapes[self.item[0]][0] = event.x<br />
self.shapes[self.item[0]][1] = event.y<br />
self.shapes[self.item[0]][2] = 1<br />
self.shapes[self.item[0]][3] = labelx<br />
self.shapes[self.item[0]][4] = labely<br />
<br />
# Reset Flags<br />
self.item = (0,)<br />
self.down = 0<br />
<br />
<br />
# Mouse Drag(Move) Event<br />
def drag(self,event):<br />
<br />
# Check that mouse is down and item clicked is a valid data point<br />
if self.down and self.shapes.has_key(self.item[0]):<br />
<br />
self.move(self.item, event.x - self.lastx, event.y - self.lasty)<br />
<br />
self.lastx = event.x<br />
self.lasty = event.y<br />
<br />
<br />
def __init__(self):<br />
<br />
self.menuBar.addcascademenu('Plugin', 'PlotTools', 'Plot Tools',<br />
label='Plot Tools')<br />
self.menuBar.addmenuitem('PlotTools', 'command',<br />
'Launch Rama Plot',<br />
label='Rama Plot',<br />
command = lambda s=self: ramaplot())<br />
<br />
<br />
def ramaplot(x=0,y=0,meta=[],clear=0):<br />
global canvas<br />
global rootframe<br />
global init<br />
<br />
# If no window is open<br />
if init == 0:<br />
rootframe=Tk()<br />
rootframe.title(' Dynamic Angle Plotting ')<br />
rootframe.protocol("WM_DELETE_WINDOW", close_callback)<br />
<br />
canvas = SimplePlot(rootframe,width=320,height=320)<br />
canvas.bind("<Button-2>",canvas.pickWhich)<br />
canvas.bind("<Button-3>",canvas.pickWhich)<br />
canvas.bind("<ButtonPress-1>",canvas.down)<br />
canvas.bind("<ButtonRelease-1>",canvas.up)<br />
canvas.bind("<Motion>",canvas.drag)<br />
canvas.pack(side=Tkinter.LEFT,fill="both",expand=1)<br />
canvas.axis(xint=150,xlabels=range(-180,181,30),ylabels=range(-180,181, 30))<br />
canvas.update()<br />
init = 1<br />
else:<br />
canvas.plot(int(x), int(y),meta)<br />
<br />
def close_callback():<br />
global init<br />
global rootframe<br />
init=0<br />
rootframe.destroy()<br />
<br />
<br />
<br />
# New Callback object, so that we can update the structure when phi,psi points are moved.<br />
class DynoRamaObject:<br />
global canvas<br />
<br />
def start(self,sel):<br />
<br />
# Get selection model<br />
model = cmd.get_model(sel)<br />
residues = ['dummy']<br />
resnames = ['dummy']<br />
phi = []<br />
psi = []<br />
dummy = []<br />
i = 0<br />
<br />
# Loop through each atom<br />
for at in model.atom:<br />
<br />
# Only plot once per residue<br />
if not at.chain+":"+at.resn+":"+at.resi in residues:<br />
residues.append(at.chain+":"+at.resn+":"+at.resi)<br />
resnames.append(at.resn+at.resi)<br />
dummy.append(i)<br />
i += 1<br />
<br />
# Check for a null chain id (some PDBs contain this) <br />
unit_select = ""<br />
if not at.chain == "":<br />
unit_select = "chain "+str(at.chain)+" and "<br />
<br />
# Define selections for residue i-1, i and i+1 <br />
residue_def = unit_select+'resi '+str(at.resi)<br />
residue_def_prev = unit_select+'resi '+str(int(at.resi)-1)<br />
residue_def_next = unit_select+'resi '+str(int(at.resi)+1)<br />
<br />
try:<br />
# Store phi,psi residue definitions to pass on to plot routine<br />
phi_psi = [<br />
# Phi angles<br />
residue_def_prev+' and name C',<br />
residue_def+' and name N',<br />
residue_def+' and name CA',<br />
residue_def+' and name C',<br />
# Psi angles<br />
residue_def+' and name N',<br />
residue_def+' and name CA',<br />
residue_def+' and name C',<br />
residue_def_next+' and name N']<br />
<br />
# Compute phi/psi angle<br />
phi = cmd.get_dihedral(phi_psi[0],phi_psi[1],phi_psi[2],phi_psi[3])<br />
psi = cmd.get_dihedral(phi_psi[4],phi_psi[5],phi_psi[6],phi_psi[7])<br />
<br />
print "Plotting Phi,Psi: "+str(phi)+","+str(psi) <br />
ramaplot(phi,psi,meta=phi_psi)<br />
except:<br />
continue<br />
<br />
<br />
def __call__(self):<br />
<br />
# Loop through each item on plot to see if updated<br />
for key,value in canvas.shapes.items():<br />
dihedrals = value[5]<br />
<br />
# Look for update flag...<br />
if value[2]:<br />
<br />
# Set residue's phi,psi to new values<br />
print "Re-setting Phi,Psi: "+str(value[3])+","+str(value[4]) <br />
cmd.set_dihedral(dihedrals[0],dihedrals[1],dihedrals[2],dihedrals[3],value[3]) <br />
cmd.set_dihedral(dihedrals[4],dihedrals[5],dihedrals[6],dihedrals[7],value[4]) <br />
<br />
value[2] = 0<br />
<br />
<br />
<br />
# The wrapper function, used to create the Ploting window and the PyMol callback object <br />
def rama(sel):<br />
rama = DynoRamaObject()<br />
rama.start(sel)<br />
cmd.load_callback(rama, "DynoRamaObject")<br />
cmd.zoom("all")<br />
<br />
<br />
# Extend these commands<br />
cmd.extend('rama',rama) <br />
cmd.extend('ramaplot',ramaplot)<br />
</source><br />
<br />
===ADDITIONAL RESOURCES===<br />
<br />
<br />
<br />
[[Category:Script_Library|DynoPlot]]<br />
[[Category:Structural_Biology_Scripts|DynoPlot]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Process_All_Files_In_Directory&diff=8031Process All Files In Directory2010-02-02T12:54:19Z<p>Cowsandmilk: </p>
<hr />
<div>=Explanation=<br />
For a given directory with PDB files in it, the following code will output, for each PDB, the bound disulfide bond lengths like this:<br />
<pre><br />
1alk.pdb<br />
A CYS 168 SG<br />
A CYS 178 SG<br />
1.975<br />
A CYS 286 SG<br />
A CYS 336 SG<br />
1.995<br />
B CYS 168 SG<br />
B CYS 178 SG<br />
1.996<br />
B CYS 286 SG<br />
B CYS 336 SG<br />
2.032<br />
1btu.pdb<br />
CYS 42 SG<br />
CYS 58 SG<br />
2.039<br />
CYS 136 SG<br />
CYS 201 SG<br />
2.031<br />
CYS 168 SG<br />
CYS 182 SG<br />
2.001<br />
CYS 191 SG<br />
CYS 220 SG<br />
2.019<br />
...<br />
</pre><br />
<br />
=Bound Disulfides=<br />
<source lang="python"><br />
from pymol import cmd<br />
from glob import glob<br />
<br />
for file in glob("*.pdb"):<br />
print file<br />
cmd.load(file,'prot')<br />
for a in cmd.index("elem s and bound_to elem s"):<br />
if cmd.select("s1","%s`%d"%a) and \<br />
cmd.select("s2","elem s and bound_to %s`%d"%a):<br />
if cmd.select("(s1|s2) and not ?skip"):<br />
cmd.iterate("s1|s2","print ' ',chain,resn,resi,name")<br />
print ' ',round(cmd.dist("tmp","s1","s2"),3)<br />
cmd.select("skip","s1|s2|?skip")<br />
cmd.delete("all")<br />
</source><br />
<br />
=All Sulfur Distances=<br />
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:<br />
<pre><br />
1alk.pdb<br />
A CYS 168 SG<br />
A CYS 178 SG<br />
1.975<br />
A CYS 168 SG<br />
A CYS 286 SG<br />
35.845<br />
A CYS 168 SG<br />
A CYS 336 SG<br />
35.029<br />
A CYS 168 SG<br />
B CYS 168 SG<br />
63.64<br />
A CYS 168 SG<br />
B CYS 178 SG<br />
63.775<br />
A CYS 168 SG<br />
B CYS 286 SG<br />
39.02<br />
A CYS 168 SG<br />
B CYS 336 SG<br />
39.314<br />
1btu.pdb<br />
CYS 42 SG<br />
CYS 58 SG<br />
2.039<br />
CYS 42 SG<br />
CYS 136 SG<br />
</pre><br />
<br />
<source lang="python"><br />
from pymol import cmd<br />
from glob import glob<br />
<br />
for file in glob("*.pdb"):<br />
print file<br />
cmd.load(file,'prot')<br />
for a in cmd.index("CYS/SG"):<br />
for b in cmd.index("CYS/SG"):<br />
if a[1]<b[1]:<br />
cmd.select("s1","%s`%d"%a)<br />
cmd.select("s2","%s`%d"%b)<br />
if cmd.select("(s1|s2) and not ?skip"):<br />
cmd.iterate("s1|s2","print ' ',chain,resn,resi,name")<br />
print ' ',round(cmd.dist("tmp","s1","s2"),3)<br />
cmd.select("skip","s1|s2|?skip")<br />
cmd.delete("all")<br />
</source><br />
<br />
[[Category:Script_Library|Processing All File in Directory]]<br />
[[Category:System_Scripts]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Perp_maker&diff=8030Perp maker2010-02-02T12:52:58Z<p>Cowsandmilk: </p>
<hr />
<div><source lang="python"><br />
####################################################################################<br />
#<br />
# perp_maker.py: Creates perpendicular planes.<br />
# =============<br />
#<br />
# Nothing to do with cops. Given a simple PyMol scene, attempts to<br />
# create a CGO background triangle perpendicular to the vector created - which is<br />
# parallel to the line segment drawn through the camera point and current center of<br />
# mass - as obtained by "get_position," or "get_view."<br />
#<br />
# @COPYRIGHT: Jason Vertrees (C), 2005-2007<br />
# @LICENSE: Released under GPL:<br />
# This program is free software; you can redistribute it and/or modify<br />
# it under the terms of the GNU General Public License as published by<br />
# the Free Software Foundation; either version 2 of the License, or<br />
# (at your option) any later version.<br />
# This program is distributed in the hope that it will be useful, but WITHOUT<br />
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS<br />
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.<br />
#<br />
# You should have received a copy of the GNU General Public License along with<br />
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin<br />
# Street, Fifth Floor, Boston, MA 02110-1301, USA <br />
#<br />
#<br />
#<br />
<br />
#<br />
# To use: Load your scene. Orient the scene as you wish. Run the script.<br />
# Could it be any simpler?!<br />
#<br />
<br />
# The TTT Matrix has to be the identity, do achieve this result. So,<br />
# run the following:<br />
# -- 'reset'<br />
# -- then orient your molecule as desired using the EDITING features!<br />
# -- before running this script, make sure 'get_view' shows the identity<br />
# -- matrix for the first 9 elements.<br />
# -- then run the script<br />
#<br />
<br />
import pymol<br />
import math<br />
import sys<br />
import random<br />
from pymol.cgo import *<br />
from pymol.vfont import plain<br />
<br />
############################################################<br />
#<br />
# Methods<br />
#<br />
############################################################<br />
<br />
#<br />
# Given the viewVector and center, creates a random sized plane<br />
# perpendicular to the viewVector through the origin. It is then<br />
# the next step's responsibility to move the plane back some so<br />
# it dosen't cut the molecule/scene in half.<br />
#<br />
def getPPlane( viewVector, center, side_length=100 ):<br />
"""Returns a 3-tuple of 3D points representing the perp. plane."""<br />
<br />
# for reproduceable testing<br />
#random.seed(10)<br />
#<br />
# The formula for a plane with our chacteristics is defined by<br />
#<br />
# A(x - x') + B(y - y') + C(y - y') + D = 0, where<br />
# A, B and C are not all zero coefficients in the vector<br />
# Ai + Bj + Ck such that the plane is perpendicular to this<br />
# vector; x, y, and z are points on the plane; x', y', and z'<br />
# are the coordiates through which the plane shall run.<br />
#<br />
<br />
# This is fool-ass. Gotta' be a better way to do this.<br />
# Declaring that rVal is a 3-Tuple.<br />
rVal = [ [], [], [], [], [], [] ]<br />
<br />
# Compose two triangles into a square.<br />
# Never learned any GFX coding, so I'm sure there's something<br />
# better than this; but, this works.<br />
for i in range(0, 6):<br />
if ( i == 0 ) or ( i == 5 ):<br />
x = -side_length + center[0]<br />
y = -side_length + center[1]<br />
elif (i == 1):<br />
x = -side_length + center[0]<br />
y = side_length + center[1]<br />
elif ( i == 2 ) or ( i == 3 ):<br />
x = side_length + center[0]<br />
y = side_length + center[1]<br />
elif ( i == 4):<br />
x = side_length + center[0]<br />
y = -side_length + center[1]<br />
<br />
if ( viewVector[2] != 0 ):<br />
z = -(((viewVector[0]*(x - center[0])) - (viewVector[1]*(y - center[1]))) /<br />
viewVector[2]) + center[2]<br />
<br />
else:<br />
print "Z-component of viewVector is zero. Now, I need a nonzero value here \<br />
so I'm just making one up. :)"<br />
z = random.randint(-200, 200)<br />
<br />
rVal[i] = [x, y, z]<br />
<br />
return rVal<br />
<br />
############################################################<br />
#<br />
# End methods<br />
#<br />
############################################################<br />
#<br />
# First, get the center and camera locations<br />
#<br />
view = cmd.get_view()<br />
camera = [ view[9], view[10], view[11] ]<br />
center = [ view[12], view[13], view[14] ]<br />
<br />
#<br />
# Sanity check<br />
<br />
#<br />
print "Camera is: " + str(camera)<br />
print "Center is: " + str(center)<br />
<br />
<br />
#<br />
# Create the vector through the two points directed<br />
# from the camera to the center - the viewVector<br />
#<br />
viewVector = [ center[0] - camera[0],<br />
center[1] - camera[1],<br />
center[2] - camera[2] ]<br />
<br />
print "ViewVector is: " + str(viewVector)<br />
<br />
#<br />
# Create the plane perpendicular to the viewVector<br />
# running through the origin<br />
#<br />
<br />
<br />
pPlane = getPPlane( viewVector, center, side_length=100 )<br />
print "Plane points calculated as: " + str(pPlane)<br />
<br />
#<br />
# Now translate the plane down away from the camera along the viewVector axis<br />
#<br />
<br />
<br />
# now create the CGO and load from the points<br />
obj = [<br />
BEGIN, TRIANGLES,<br />
COLOR, 0.2, 0.4, 1,<br />
<br />
VERTEX, pPlane[0][0], pPlane[0][1], pPlane[0][2],<br />
VERTEX, pPlane[1][0], pPlane[1][1], pPlane[1][2],<br />
VERTEX, pPlane[2][0], pPlane[2][1], pPlane[2][2],<br />
<br />
VERTEX, pPlane[3][0], pPlane[3][1], pPlane[3][2],<br />
VERTEX, pPlane[4][0], pPlane[4][1], pPlane[4][2],<br />
VERTEX, pPlane[5][0], pPlane[5][1], pPlane[5][2],<br />
<br />
END<br />
]<br />
<br />
<br />
cmd.load_cgo( obj, 'pPlane')<br />
cmd.set_view( view )<br />
</source><br />
<br />
<br />
[[Category:Script_Library]]<br />
[[Category:Math_Scripts]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=MovieSchool_1&diff=7989MovieSchool 12010-01-24T21:18:53Z<p>Cowsandmilk: </p>
<hr />
<div>== Movie Making ==<br />
While PyMOL's capability to produce static images is quite powerful, there are some stories that are better told through movies, than static images alone. This little page will provide the necessary ideas, links, code and examples for making movies in PyMOL.<br />
<br />
== Your First Movie ==<br />
Movies can be very simple, for example, animating an NMR ensemble:<br />
<source lang="python"><br />
# Your first movie.<br />
fetch 1nmr<br />
mplay<br />
<br />
# to stop the movie when you're ready<br />
# type 'mstop'.<br />
</source><br />
<br />
What PyMOL did here was to [[fetch]] the file from the PDB and load it into an object with 20 states. Somewhere between then and issuing [[mplay]] PyMOL created 20 frames for your object and assigned one state to each frame. This created the animated effect as we scroll through the frames.<br />
<br />
<br />
== Movie Making for the Impatient ==<br />
If you don't have time to or care to make more complex movies and want a movie ''now'' then read this section. It mostly involves the GUI for making movies, so get your mouse ready.<br />
<br />
=== Simple Camera Motions ===<br />
==== Simple 360 Scene Rotation ====<br />
To make a movie that simply rotates around your scene 360 degrees, in the menu click on:<br />
:: '''Movie->Program->Camera->X-Roll->N Seconds'''<br />
for an N-second movie rolling over the X-axis. Chose <br />
:: '''Movie->Program->Camera->Y-Roll->N Seconds'''<br />
for the Y-axis roll.<br />
<br />
Done! Press '''play'''.<br />
<br />
==== Simple 30, 60, 90, 120, 180, Scene Rocking ====<br />
This will show up to a 30, 60, 90, 120 or 180 rocking 'wedge' of the scene. If you don't want to rotate all the way around, use this.<br />
:: '''Movie->Program->Camera->X-Rock->X-Degrees over N-Seconds'''<br />
<br />
Done! Press '''play'''.<br />
<br />
==== Nutate ====<br />
Nutating is like a wiggle-rock; try it and see.<br />
:: '''Movie->Program->Camera->X-Rock->X-Degrees over N-Seconds'''<br />
<br />
Done! Press '''play'''.<br />
<br />
==== Zooming Around an Object ====<br />
This is also known as camera movement. Let's make a simple program that just zooms in and out on a some atom.<br />
:: '''Build->Residue->Tryptophan'''<br />
:: '''Scene->Store->F1'''<br />
:: ''Click any atom and zoom on it''<br />
:: '''Scene-Store->F2'''<br />
:: '''Movie->Program->Scene Loop->''' and if you want to nutate while at the scene choose '''Nutate''' otherwise choose '''Y-Rock'''.<br />
<br />
Done! Press '''play'''.<br />
<br />
* ''Hint'': Make multiple scenes, making sure to store each one. Then use the Scene Loop to automatically program a movie for you!<br />
<br />
==== Real-world Example ====<br />
First load the tutorial PDB:<br />
<source lang="python"><br />
load $TUT/1hpv.pdb<br />
</source><br />
:: '''Action->Preset->Technical''' (on the object in the viewer gui)<br />
:: '''Scene->Store->F1'''<br />
:: Type ''zoom i. 200'' to zoom on the ligand<br />
:: '''Scene->Store->F2'''<br />
:: '''Movie->Program->Scene Loop->Y-Rock->4 Seconds Each'''<br />
<br />
Done! Press '''play'''.<br />
<br />
[[MovieSchool| &larr; MovieSchool Home]] [[MovieSchool_2| Next Lesson &rarr;]]<br />
<br />
[[Category:Movies]]<br />
[[Category:Tutorials]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Ideas&diff=7988Ideas2010-01-24T20:08:10Z<p>Cowsandmilk: /* High-Level Enhancement Ideas (Mostly Python-oriented) */</p>
<hr />
<div>=== Ideas for PyMOL Development ===<br />
<br />
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.<br />
<br />
== Where to Start ==<br />
<br />
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. <br />
<br />
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.<br />
<br />
== Choosing a Topic ==<br />
<br />
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!<br />
<br />
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.<br />
<br />
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.<br />
<br />
== Integration Ideas (Linking Out to Useful Open-Source Tools) ==<br />
<br />
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.<br />
<br />
* APBS (electrostatics calculations): Improve the existing plugin. Michael Lerner is currently leading this effort. See [[APBS]]<br />
:: yea ([[User:Inchoate|Tree]] [[User:Jedgold|Jedgold]]"[[User:Vcpmartin|Vcpmartin]]") / nay (0)<br />
* 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]<br />
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)<br />
* GIMP (image manipulation): Streamline & document the process of exporting images from PyMOL into GIMP and preparing them for submission to scientific Journals.<br />
:: yea (0) / nay (0)<br />
* Jmol (publishing visualizations inside of web pages): Liason between PyMOL & Jmol projects to develop a shared molecular visualization data model compatible with both applications.<br />
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Firefox (plugin): Develop an PyMOL plugin compatible with Firefox.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* MMTK (molecular mechanics -- Python/flexible): Develop the ability to round-trip molecular systems from PyMOL, into MMTK, and back.<br />
:: yea (0) / nay (0)<br />
* 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]<br />
:: yea ([[User:Jedgold|Jedgold]] [[User:Mglerner|Michael Lerner]]) / nay (0)<br />
* OpenOffice (escape Microsoft hegemony): Develop an PyMOL plugin.<br />
:: yea (0) / nay (0)<br />
* IPython integration (interactive shell): a robust alternative to the PyMOL command line?<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* R (statistics): PyMOL a 3D viewer environment for visualizating & manipulating large statistical data sets?<br />
:: yea (0) / nay (0)<br />
<br />
Are there other key open-source packages we might specifically target for integration with PyMOL, either through GSoC or beyond?<br />
<br />
== High-Level Enhancement Ideas (Mostly Python-oriented) ==<br />
<br />
* Work on [[#More Ideas (Please add your own!)| MolViz]]<br />
:: yea (0) / nay (0)<br />
* Develop new plugins which automate routine tasks.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Improve the Python API documentation.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Flesh out the new "from pymol2 import PyMOL" instance-based PyMOL API.<br />
:: yea (0) / nay (0)<br />
* Develop alternate Tkinter "skins" (for custom OEM-like applications).<br />
:: yea (0) / nay (0)<br />
* Develop a Tkinter/TOGL widget which holds a PyMOL viewer instance.<br />
:: yea (0) / nay (0)<br />
* Develop a PyQt widget which holds a PyMOL viewer instance.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* 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.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Add a plugin for a GUI window with the same functionality as the "Control Panel" window in SwissPDB Viewer.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Extend and modify the PyMOL command language so as to be compatible with existing RasMol and/or Jmol scripts.<br />
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Enhance the Mutagenesis Wizard in order to support Nucleic acids and/or Sugars.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Better tab completion for commands<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) /nay(0)<br />
<br />
== Low-Level Enhancement Ideas (Mostly C-oriented) ==<br />
<br />
* Enable editing of displayed sequence alignments.<br />
:: yea ([[User:Jedgold|Jedgold]], [[User:Aschreyer|Aschreyer]], [[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
::: Would this then feed back to the structural alignment? [[User:Jedgold|Jedgold]]<br />
* Add multi-line textual annotations<br />
:: yea (0) / nay (0)<br />
* Support additional annotation object including: arrow, lines, and blobs.<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Vvostri|Vvostri]]) / nay (0)<br />
* Add display of secondary structure into the sequence viewer.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Enable per-object Z clipping (especially in the ray tracer)<br />
:: yea ([[User:Gregori|Gregori]], [[User:Xevi|Xevi]], [[User:Johnm|Johnm]]) / nay (0)<br />
::: I would go a step further with fully customizable selection-based clipping planes (XYZ, color and transparency) ([[User:Gregori|Gregori]])<br />
* Highlight H-bonds, salt bridges, Pi-stacking, Pi-cations, etc.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Build in a simple forcefield and energy minimizer suitable for use with Mutagenesis.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Incorporate a suite of standard NMR visualizations (restraint violations, per-residue RMS, etc.)<br />
:: yea ([[User:Vvostri|Vvostri]]"[[User:Vcpmartin|Vcpmartin]]") / nay (0)<br />
* Enumeration and display of low-energy conformers.<br />
:: yea ([[User:Jedgold|Jedgold]]) / nay (0)<br />
::: This could be done by integrating RDKit, I think. [[User:Aschreyer|Aschreyer]]<br />
* Automated structure grafting (poor-man's homology modeling).<br />
:: yea (0) / nay ([[User:Jedgold|Jedgold]], [[User:Cowsandmilk|Cowsandmilk]])<br />
::: Perhaps a plugin to Modeller instead? ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]])<br />
* Import of alignment files.<br />
:: yea ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Implement IMD (Interactive Molecular Dynamics) Interface, see http://www.ks.uiuc.edu/Research/vmd/imd/<br />
:: yea (0) / nay (0)<br />
* Add buttons for '''Set ChainID''' and '''Renumber Residues From...''' to Edit menu or Actions (wrapper around Alter command)<br />
:: yea ([[User:Sheehanj|Sheehanj]]) / nay (0)<br />
<br />
== Difficult C-level Code Refactoring Ideas ==<br />
<br />
* Assemble a test suite which thoroughly exercises the existing code (a prerequisite to major refactoring).<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Catch & handle memory-allocation failures gracefully (instead of crashing).<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Replace PyMOL's memory management & custom containers with a simple runtime object model.<br />
:: yea (0) / nay (0)<br />
* Separate the View and the Controllers from the Model so that they can all run asynchronously (on multiple cores).<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Enable generalized undo of changes made to the Model.<br />
:: yea ([[User:Vvostri|Vvostri]]"[[User:Vcpmartin|Vcpmartin]], [[User:Lucajovine|Luca Jovine]]", [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Clean up the internal matrix handling code.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
<br />
== Ideas Involving Proprietary APIs ==<br />
<br />
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.<br />
<br />
* Create a Windows port with "native" look & feel. <- Could this be done in PyQT or PyGTK?. Then it would look "native", but be cross-platform and not proprietary.<br />
:: yea (0) / nay (0)<br />
* Integrate directly via Mathematica via MathLink.<br />
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])<br />
* Further enhance JyMOL (Java-JNI/wrapped PyMOL)<br />
:: yea ([[User:Inchoate|Tree]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Integrate with Matlab.<br />
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])<br />
* Quicklook Plugin on the Mac<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
<br />
== More Ideas (Please add your own!) ==<br />
* [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:<br />
** Improving the existing [[ImmersiveViz]] PyMol plugin for more precise control of the environment.<br />
** Developing new input drivers for the Wiimote form of control. This would require some bluetooth hacking.<br />
** 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).<br />
:: yea (0) / nay (0)<br />
* Provide a 2D chemical depiction of the current 3D view.<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
::: RDKit?<br />
* Spreadsheet view with additional information (e.g. IC50's).<br />
:: yea ([[User:Aschreyer|Aschreyer]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Create additional documentation, screen casts, & tutorials.<br />
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)<br />
* Export 3D PDF images.<br />
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* <strike>Add extra "Single Word Selectors" like "nucleic", "protein", "water", "ions", "backbone" (for nucleic acids or proteins), "mainchain", "sidechain"</strike><br />
:: yea (0) / nay (0)<br />
* Add functionality that allows you to select atoms based on their location (i.e. select (x_coordinate < 10) and (z_coordinate > 0))<br />
:: yea (0) / nay (0)<br />
* 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.<br />
:: yea ([[User:Aschreyer|Aschreyer]]) / nay (0)<br />
* 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<br />
:: yea (0) / nay (0)<br />
* 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)<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* I see a lot of "can pymol do this" threads - any ideas of a good UI for a page of "things PyMOL can do?"<br />
:: yea (0) / nay (0)<br />
* 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?<br />
:: yea (0) / nay (0)<br />
* iPhone / Nexus One app(s)<br />
:: yea (0) / nay (0)<br />
* single-color bonds between nonidentical or any spherical atoms colored specifically<br />
:: yea (0) / nay (0)<br />
* double bonds as two parallel cylinders<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* export scenes as [http://www.khronos.org/webgl/ WebGL] / Could make mobile apps, presentation plugins obsolete<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* export images in vector format<br />
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]]) / nay (0)<br />
* Keynote plugin<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Electron density contour sliders<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Automatic electron density map generation from PDB mmcif files or user-supplied MTZ files<br />
:: yea ([[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]], [[User:Johnm|Johnm]]) / nay (0)<br />
* Display of crystallographic symmetry and NCS axes, with possibility of showing symbols indicating what kind of axes they are<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Automatic symmetry expansion to show overall crystal packing; automatic generation of scenes showing crystal packing interface details<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Ideas&diff=7987Ideas2010-01-24T20:06:20Z<p>Cowsandmilk: /* Ideas Involving Proprietary APIs */</p>
<hr />
<div>=== Ideas for PyMOL Development ===<br />
<br />
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.<br />
<br />
== Where to Start ==<br />
<br />
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. <br />
<br />
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.<br />
<br />
== Choosing a Topic ==<br />
<br />
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!<br />
<br />
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.<br />
<br />
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.<br />
<br />
== Integration Ideas (Linking Out to Useful Open-Source Tools) ==<br />
<br />
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.<br />
<br />
* APBS (electrostatics calculations): Improve the existing plugin. Michael Lerner is currently leading this effort. See [[APBS]]<br />
:: yea ([[User:Inchoate|Tree]] [[User:Jedgold|Jedgold]]"[[User:Vcpmartin|Vcpmartin]]") / nay (0)<br />
* 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]<br />
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)<br />
* GIMP (image manipulation): Streamline & document the process of exporting images from PyMOL into GIMP and preparing them for submission to scientific Journals.<br />
:: yea (0) / nay (0)<br />
* Jmol (publishing visualizations inside of web pages): Liason between PyMOL & Jmol projects to develop a shared molecular visualization data model compatible with both applications.<br />
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Firefox (plugin): Develop an PyMOL plugin compatible with Firefox.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* MMTK (molecular mechanics -- Python/flexible): Develop the ability to round-trip molecular systems from PyMOL, into MMTK, and back.<br />
:: yea (0) / nay (0)<br />
* 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]<br />
:: yea ([[User:Jedgold|Jedgold]] [[User:Mglerner|Michael Lerner]]) / nay (0)<br />
* OpenOffice (escape Microsoft hegemony): Develop an PyMOL plugin.<br />
:: yea (0) / nay (0)<br />
* IPython integration (interactive shell): a robust alternative to the PyMOL command line?<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* R (statistics): PyMOL a 3D viewer environment for visualizating & manipulating large statistical data sets?<br />
:: yea (0) / nay (0)<br />
<br />
Are there other key open-source packages we might specifically target for integration with PyMOL, either through GSoC or beyond?<br />
<br />
== High-Level Enhancement Ideas (Mostly Python-oriented) ==<br />
<br />
* Work on [[#More Ideas (Please add your own!)| MolViz]]<br />
:: yea (0) / nay (0)<br />
* Develop new plugins which automate routine tasks.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Improve the Python API documentation.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Flesh out the new "from pymol2 import PyMOL" instance-based PyMOL API.<br />
:: yea (0) / nay (0)<br />
* Develop alternate Tkinter "skins" (for custom OEM-like applications).<br />
:: yea (0) / nay (0)<br />
* Develop a Tkinter/TOGL widget which holds a PyMOL viewer instance.<br />
:: yea (0) / nay (0)<br />
* Develop a PyQt widget which holds a PyMOL viewer instance.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* 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.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Add a plugin for a GUI window with the same functionality as the "Control Panel" window in SwissPDB Viewer.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Extend and modify the PyMOL command language so as to be compatible with existing RasMol and/or Jmol scripts.<br />
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Enhance the Mutagenesis Wizard in order to support Nucleic acids and/or Sugars.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
<br />
== Low-Level Enhancement Ideas (Mostly C-oriented) ==<br />
<br />
* Enable editing of displayed sequence alignments.<br />
:: yea ([[User:Jedgold|Jedgold]], [[User:Aschreyer|Aschreyer]], [[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
::: Would this then feed back to the structural alignment? [[User:Jedgold|Jedgold]]<br />
* Add multi-line textual annotations<br />
:: yea (0) / nay (0)<br />
* Support additional annotation object including: arrow, lines, and blobs.<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Vvostri|Vvostri]]) / nay (0)<br />
* Add display of secondary structure into the sequence viewer.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Enable per-object Z clipping (especially in the ray tracer)<br />
:: yea ([[User:Gregori|Gregori]], [[User:Xevi|Xevi]], [[User:Johnm|Johnm]]) / nay (0)<br />
::: I would go a step further with fully customizable selection-based clipping planes (XYZ, color and transparency) ([[User:Gregori|Gregori]])<br />
* Highlight H-bonds, salt bridges, Pi-stacking, Pi-cations, etc.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Build in a simple forcefield and energy minimizer suitable for use with Mutagenesis.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Incorporate a suite of standard NMR visualizations (restraint violations, per-residue RMS, etc.)<br />
:: yea ([[User:Vvostri|Vvostri]]"[[User:Vcpmartin|Vcpmartin]]") / nay (0)<br />
* Enumeration and display of low-energy conformers.<br />
:: yea ([[User:Jedgold|Jedgold]]) / nay (0)<br />
::: This could be done by integrating RDKit, I think. [[User:Aschreyer|Aschreyer]]<br />
* Automated structure grafting (poor-man's homology modeling).<br />
:: yea (0) / nay ([[User:Jedgold|Jedgold]], [[User:Cowsandmilk|Cowsandmilk]])<br />
::: Perhaps a plugin to Modeller instead? ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]])<br />
* Import of alignment files.<br />
:: yea ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Implement IMD (Interactive Molecular Dynamics) Interface, see http://www.ks.uiuc.edu/Research/vmd/imd/<br />
:: yea (0) / nay (0)<br />
* Add buttons for '''Set ChainID''' and '''Renumber Residues From...''' to Edit menu or Actions (wrapper around Alter command)<br />
:: yea ([[User:Sheehanj|Sheehanj]]) / nay (0)<br />
<br />
== Difficult C-level Code Refactoring Ideas ==<br />
<br />
* Assemble a test suite which thoroughly exercises the existing code (a prerequisite to major refactoring).<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Catch & handle memory-allocation failures gracefully (instead of crashing).<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Replace PyMOL's memory management & custom containers with a simple runtime object model.<br />
:: yea (0) / nay (0)<br />
* Separate the View and the Controllers from the Model so that they can all run asynchronously (on multiple cores).<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Enable generalized undo of changes made to the Model.<br />
:: yea ([[User:Vvostri|Vvostri]]"[[User:Vcpmartin|Vcpmartin]], [[User:Lucajovine|Luca Jovine]]", [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Clean up the internal matrix handling code.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
<br />
== Ideas Involving Proprietary APIs ==<br />
<br />
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.<br />
<br />
* Create a Windows port with "native" look & feel. <- Could this be done in PyQT or PyGTK?. Then it would look "native", but be cross-platform and not proprietary.<br />
:: yea (0) / nay (0)<br />
* Integrate directly via Mathematica via MathLink.<br />
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])<br />
* Further enhance JyMOL (Java-JNI/wrapped PyMOL)<br />
:: yea ([[User:Inchoate|Tree]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Integrate with Matlab.<br />
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])<br />
* Quicklook Plugin on the Mac<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
<br />
== More Ideas (Please add your own!) ==<br />
* [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:<br />
** Improving the existing [[ImmersiveViz]] PyMol plugin for more precise control of the environment.<br />
** Developing new input drivers for the Wiimote form of control. This would require some bluetooth hacking.<br />
** 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).<br />
:: yea (0) / nay (0)<br />
* Provide a 2D chemical depiction of the current 3D view.<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
::: RDKit?<br />
* Spreadsheet view with additional information (e.g. IC50's).<br />
:: yea ([[User:Aschreyer|Aschreyer]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Create additional documentation, screen casts, & tutorials.<br />
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)<br />
* Export 3D PDF images.<br />
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* <strike>Add extra "Single Word Selectors" like "nucleic", "protein", "water", "ions", "backbone" (for nucleic acids or proteins), "mainchain", "sidechain"</strike><br />
:: yea (0) / nay (0)<br />
* Add functionality that allows you to select atoms based on their location (i.e. select (x_coordinate < 10) and (z_coordinate > 0))<br />
:: yea (0) / nay (0)<br />
* 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.<br />
:: yea ([[User:Aschreyer|Aschreyer]]) / nay (0)<br />
* 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<br />
:: yea (0) / nay (0)<br />
* 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)<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* I see a lot of "can pymol do this" threads - any ideas of a good UI for a page of "things PyMOL can do?"<br />
:: yea (0) / nay (0)<br />
* 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?<br />
:: yea (0) / nay (0)<br />
* iPhone / Nexus One app(s)<br />
:: yea (0) / nay (0)<br />
* single-color bonds between nonidentical or any spherical atoms colored specifically<br />
:: yea (0) / nay (0)<br />
* double bonds as two parallel cylinders<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* export scenes as [http://www.khronos.org/webgl/ WebGL] / Could make mobile apps, presentation plugins obsolete<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* export images in vector format<br />
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]]) / nay (0)<br />
* Keynote plugin<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Electron density contour sliders<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Automatic electron density map generation from PDB mmcif files or user-supplied MTZ files<br />
:: yea ([[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]], [[User:Johnm|Johnm]]) / nay (0)<br />
* Display of crystallographic symmetry and NCS axes, with possibility of showing symbols indicating what kind of axes they are<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Automatic symmetry expansion to show overall crystal packing; automatic generation of scenes showing crystal packing interface details<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Ideas&diff=7986Ideas2010-01-24T19:54:38Z<p>Cowsandmilk: </p>
<hr />
<div>=== Ideas for PyMOL Development ===<br />
<br />
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.<br />
<br />
== Where to Start ==<br />
<br />
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. <br />
<br />
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.<br />
<br />
== Choosing a Topic ==<br />
<br />
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!<br />
<br />
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.<br />
<br />
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.<br />
<br />
== Integration Ideas (Linking Out to Useful Open-Source Tools) ==<br />
<br />
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.<br />
<br />
* APBS (electrostatics calculations): Improve the existing plugin. Michael Lerner is currently leading this effort. See [[APBS]]<br />
:: yea ([[User:Inchoate|Tree]] [[User:Jedgold|Jedgold]]"[[User:Vcpmartin|Vcpmartin]]") / nay (0)<br />
* 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]<br />
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)<br />
* GIMP (image manipulation): Streamline & document the process of exporting images from PyMOL into GIMP and preparing them for submission to scientific Journals.<br />
:: yea (0) / nay (0)<br />
* Jmol (publishing visualizations inside of web pages): Liason between PyMOL & Jmol projects to develop a shared molecular visualization data model compatible with both applications.<br />
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Firefox (plugin): Develop an PyMOL plugin compatible with Firefox.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* MMTK (molecular mechanics -- Python/flexible): Develop the ability to round-trip molecular systems from PyMOL, into MMTK, and back.<br />
:: yea (0) / nay (0)<br />
* 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]<br />
:: yea ([[User:Jedgold|Jedgold]] [[User:Mglerner|Michael Lerner]]) / nay (0)<br />
* OpenOffice (escape Microsoft hegemony): Develop an PyMOL plugin.<br />
:: yea (0) / nay (0)<br />
* IPython integration (interactive shell): a robust alternative to the PyMOL command line?<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* R (statistics): PyMOL a 3D viewer environment for visualizating & manipulating large statistical data sets?<br />
:: yea (0) / nay (0)<br />
<br />
Are there other key open-source packages we might specifically target for integration with PyMOL, either through GSoC or beyond?<br />
<br />
== High-Level Enhancement Ideas (Mostly Python-oriented) ==<br />
<br />
* Work on [[#More Ideas (Please add your own!)| MolViz]]<br />
:: yea (0) / nay (0)<br />
* Develop new plugins which automate routine tasks.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Improve the Python API documentation.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Flesh out the new "from pymol2 import PyMOL" instance-based PyMOL API.<br />
:: yea (0) / nay (0)<br />
* Develop alternate Tkinter "skins" (for custom OEM-like applications).<br />
:: yea (0) / nay (0)<br />
* Develop a Tkinter/TOGL widget which holds a PyMOL viewer instance.<br />
:: yea (0) / nay (0)<br />
* Develop a PyQt widget which holds a PyMOL viewer instance.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* 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.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Add a plugin for a GUI window with the same functionality as the "Control Panel" window in SwissPDB Viewer.<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Extend and modify the PyMOL command language so as to be compatible with existing RasMol and/or Jmol scripts.<br />
:: yea (0) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Enhance the Mutagenesis Wizard in order to support Nucleic acids and/or Sugars.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
<br />
== Low-Level Enhancement Ideas (Mostly C-oriented) ==<br />
<br />
* Enable editing of displayed sequence alignments.<br />
:: yea ([[User:Jedgold|Jedgold]], [[User:Aschreyer|Aschreyer]], [[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
::: Would this then feed back to the structural alignment? [[User:Jedgold|Jedgold]]<br />
* Add multi-line textual annotations<br />
:: yea (0) / nay (0)<br />
* Support additional annotation object including: arrow, lines, and blobs.<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Vvostri|Vvostri]]) / nay (0)<br />
* Add display of secondary structure into the sequence viewer.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Enable per-object Z clipping (especially in the ray tracer)<br />
:: yea ([[User:Gregori|Gregori]], [[User:Xevi|Xevi]], [[User:Johnm|Johnm]]) / nay (0)<br />
::: I would go a step further with fully customizable selection-based clipping planes (XYZ, color and transparency) ([[User:Gregori|Gregori]])<br />
* Highlight H-bonds, salt bridges, Pi-stacking, Pi-cations, etc.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Build in a simple forcefield and energy minimizer suitable for use with Mutagenesis.<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Incorporate a suite of standard NMR visualizations (restraint violations, per-residue RMS, etc.)<br />
:: yea ([[User:Vvostri|Vvostri]]"[[User:Vcpmartin|Vcpmartin]]") / nay (0)<br />
* Enumeration and display of low-energy conformers.<br />
:: yea ([[User:Jedgold|Jedgold]]) / nay (0)<br />
::: This could be done by integrating RDKit, I think. [[User:Aschreyer|Aschreyer]]<br />
* Automated structure grafting (poor-man's homology modeling).<br />
:: yea (0) / nay ([[User:Jedgold|Jedgold]], [[User:Cowsandmilk|Cowsandmilk]])<br />
::: Perhaps a plugin to Modeller instead? ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]])<br />
* Import of alignment files.<br />
:: yea ([[User:Jedgold|Jedgold]], [[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Implement IMD (Interactive Molecular Dynamics) Interface, see http://www.ks.uiuc.edu/Research/vmd/imd/<br />
:: yea (0) / nay (0)<br />
* Add buttons for '''Set ChainID''' and '''Renumber Residues From...''' to Edit menu or Actions (wrapper around Alter command)<br />
:: yea ([[User:Sheehanj|Sheehanj]]) / nay (0)<br />
<br />
== Difficult C-level Code Refactoring Ideas ==<br />
<br />
* Assemble a test suite which thoroughly exercises the existing code (a prerequisite to major refactoring).<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Catch & handle memory-allocation failures gracefully (instead of crashing).<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Replace PyMOL's memory management & custom containers with a simple runtime object model.<br />
:: yea (0) / nay (0)<br />
* Separate the View and the Controllers from the Model so that they can all run asynchronously (on multiple cores).<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* Enable generalized undo of changes made to the Model.<br />
:: yea ([[User:Vvostri|Vvostri]]"[[User:Vcpmartin|Vcpmartin]], [[User:Lucajovine|Luca Jovine]]", [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Clean up the internal matrix handling code.<br />
:: yea ([[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
<br />
== Ideas Involving Proprietary APIs ==<br />
<br />
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.<br />
<br />
* Create a Windows port with "native" look & feel. <- Could this be done in PyQT or PyGTK?. Then it would look "native", but be cross-platform and not proprietary.<br />
:: yea (0) / nay (0)<br />
* Integrate directly via Mathematica via MathLink.<br />
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])<br />
* Further enhance JyMOL (Java-JNI/wrapped PyMOL)<br />
:: yea ([[User:Inchoate|Tree]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* Integrate with Matlab.<br />
:: yea (0) / nay ([[User:Aschreyer|Aschreyer]])<br />
<br />
== More Ideas (Please add your own!) ==<br />
* [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:<br />
** Improving the existing [[ImmersiveViz]] PyMol plugin for more precise control of the environment.<br />
** Developing new input drivers for the Wiimote form of control. This would require some bluetooth hacking.<br />
** 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).<br />
:: yea (0) / nay (0)<br />
* Provide a 2D chemical depiction of the current 3D view.<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
::: RDKit?<br />
* Spreadsheet view with additional information (e.g. IC50's).<br />
:: yea ([[User:Aschreyer|Aschreyer]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* Create additional documentation, screen casts, & tutorials.<br />
:: yea ([[User:Markvanraaij|Markvanraaij]]) / nay (0)<br />
* Export 3D PDF images.<br />
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]]) / nay ([[User:Cowsandmilk|Cowsandmilk]])<br />
* <strike>Add extra "Single Word Selectors" like "nucleic", "protein", "water", "ions", "backbone" (for nucleic acids or proteins), "mainchain", "sidechain"</strike><br />
:: yea (0) / nay (0)<br />
* Add functionality that allows you to select atoms based on their location (i.e. select (x_coordinate < 10) and (z_coordinate > 0))<br />
:: yea (0) / nay (0)<br />
* 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.<br />
:: yea ([[User:Aschreyer|Aschreyer]]) / nay (0)<br />
* 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<br />
:: yea (0) / nay (0)<br />
* 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)<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* I see a lot of "can pymol do this" threads - any ideas of a good UI for a page of "things PyMOL can do?"<br />
:: yea (0) / nay (0)<br />
* 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?<br />
:: yea (0) / nay (0)<br />
* iPhone / Nexus One app(s)<br />
:: yea (0) / nay (0)<br />
* single-color bonds between nonidentical or any spherical atoms colored specifically<br />
:: yea (0) / nay (0)<br />
* double bonds as two parallel cylinders<br />
:: yea ([[User:Vvostri|Vvostri]]) / nay (0)<br />
* export scenes as [http://www.khronos.org/webgl/ WebGL] / Could make mobile apps, presentation plugins obsolete<br />
:: yea ([[User:Aschreyer|Aschreyer]], [[User:Cowsandmilk|Cowsandmilk]]) / nay (0)<br />
* export images in vector format<br />
:: yea ([[User:Vvostri|Vvostri]], [[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]]) / nay (0)<br />
* Keynote plugin<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Electron density contour sliders<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Automatic electron density map generation from PDB mmcif files or user-supplied MTZ files<br />
:: yea ([[User:Lucajovine|Luca Jovine]], [[User:Aschreyer|Aschreyer]], [[User:Johnm|Johnm]]) / nay (0)<br />
* Display of crystallographic symmetry and NCS axes, with possibility of showing symbols indicating what kind of axes they are<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)<br />
* Automatic symmetry expansion to show overall crystal packing; automatic generation of scenes showing crystal packing interface details<br />
:: yea ([[User:Lucajovine|Luca Jovine]]) / nay (0)</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Get_object_matrix&diff=7652Get object matrix2009-11-22T19:22:54Z<p>Cowsandmilk: /* Overview */</p>
<hr />
<div>=Overview=<br />
Pymol stores a transformation matrix for each object relative to it's initial position when loaded in. '''get_object_matrix''' will return a list of floats with that matrix for a named object.<br />
<br />
The matrix is 4X4, with the upper left 3x3 forming a rotation matrix, the fourth column and row representing pre-rotation and post-rotation translation vectors respectively, and the 16th element always being 1.0.<br />
<br />
According the pymol source code, this is an "unsupported command".<br />
<br />
=Syntax=<br />
<source lang="python"><br />
cmd.get_object_matrix(object, state=1)<br />
</source><br />
<br />
=Example=<br />
<source lang="python"><br />
cmd.load("prot1.pdb", "prot1")<br />
cmd.load("prot2.pdb", "prot2")<br />
cmd.super("prot1", "prot2") #align prot1 to prot 2<br />
transformation = cmd.get_object_matrix("prot1") #translation and rotation to align the two proteins<br />
</source><br />
<br />
== See Also ==<br />
[[Transform_selection]] [[Transform_odb]] [[Matrix_copy]]<br />
<br />
[[Category:Commands|Get Object Matrix]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Get_object_matrix&diff=7651Get object matrix2009-11-22T19:16:13Z<p>Cowsandmilk: Created page with '=Overview= Pymol stores a transformation matrix for each object relative to it's initial position when loaded in. '''get_object_matrix''' will return a list of floats with that …'</p>
<hr />
<div>=Overview=<br />
Pymol stores a transformation matrix for each object relative to it's initial position when loaded in. '''get_object_matrix''' will return a list of floats with that matrix for a named object.<br />
<br />
The matrix is 4X4, with the upper left 3x3 forming a rotation matrix, the fourth column and row representing pre- and post-translation vectors respectively, and the 16th element always being 1.0.<br />
<br />
According the pymol source code, this is an "unsupported command".<br />
<br />
=Syntax=<br />
<source lang="python"><br />
cmd.get_object_matrix(object, state=1)<br />
</source><br />
<br />
=Example=<br />
<source lang="python"><br />
cmd.load("prot1.pdb", "prot1")<br />
cmd.load("prot2.pdb", "prot2")<br />
cmd.super("prot1", "prot2") #align prot1 to prot 2<br />
transformation = cmd.get_object_matrix("prot1") #translation and rotation to align the two proteins<br />
</source><br />
<br />
== See Also ==<br />
[[Transform_selection]] [[Transform_odb]] [[Matrix_copy]]<br />
<br />
[[Category:Commands|Get Object Matrix]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Plugins_Tutorial&diff=5098Plugins Tutorial2008-07-29T17:21:45Z<p>Cowsandmilk: mediawiki formatted the code with a space on the left side, which makes copying and pasting the code annoying</p>
<hr />
<div>==Learn By Example==<br />
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.<br />
<br />
===Registering your Plugin===<br />
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.<br />
<br />
<source lang="python"><br />
def __init__(self):<br />
self.menuBar.addmenuitem('Plugin', 'command',<br />
'PDB Loader Service',<br />
label = 'PDB Loader Service',<br />
command = lambda s=self : fetchPDBDialog(s))<br />
</source><br />
<br />
===Adding Functionality===<br />
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.<br />
<br />
<source lang="python"><br />
def remote(pdbCode):<br />
pdbCode = pdbCode.upper()<br />
try:<br />
pdbFile = urllib2.urlopen('<nowiki>http://www.rcsb.org/pdb/cgi/export.cgi/</nowiki>' +<br />
pdbCode + '.pdb.gz?format=PDB&pdbId=' +<br />
pdbCode + '&compression=gz')<br />
cmd.read_pdbstr(zlib.decompress(pdbFile.read()[22:], -zlib.MAX_WBITS), pdbCode)<br />
except:<br />
print "Unexpected error:", sys.exc_info()[0]<br />
tkMessageBox.showerror('Invalid Code',<br />
'You entered an invalid pdb code:' + pdbCode)<br />
</source><br />
<br />
===Creating the Interface===<br />
Now we need to write the callback method, ''fetchPDBDialog'', which creates the interface.<br />
<br />
<source lang="python"><br />
def fetchPDBDialog(app):<br />
pdbCode = tkSimpleDialog.askstring('PDB Loader Service',<br />
'Please enter a 4-digit pdb code:',<br />
parent=app.root)<br />
remote(pdbCode)<br />
</source><br />
<br />
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.<br />
<br />
===Extending Plugins to the Command Line===<br />
Opening the dialog can be tedious, so let's add a command line callback to make use of this new functionality.<br />
<br />
<source lang="python"><br />
cmd.extend('remote', remote)<br />
</source><br />
<br />
Now you can type ''remote 1di9'', for example, to load the the corresponding pdb.<br />
<br />
==Full Source==<br />
Here is the complete example. You can save this file and load it into PyMol with the ''Plugin -> Install Plugin...'' menu item. I also include the sample license that Warren provides for plugin developers. It is optional, of course.<br />
<br />
<source lang="python"><br />
# Copyright Notice<br />
# ================<br />
# <br />
# The PyMOL Plugin source code in this file is copyrighted, but you can<br />
# freely use and copy it as long as you don't change or remove any of<br />
# the copyright notices.<br />
# <br />
# ----------------------------------------------------------------------<br />
# This PyMOL Plugin is Copyright (C) 2004 by Charles Moad <cmoad@indiana.edu><br />
# <br />
# All Rights Reserved<br />
# <br />
# Permission to use, copy, modify, distribute, and distribute modified<br />
# versions of this software and its documentation for any purpose and<br />
# without fee is hereby granted, provided that the above copyright<br />
# notice appear in all copies and that both the copyright notice and<br />
# this permission notice appear in supporting documentation, and that<br />
# the name(s) of the author(s) not be used in advertising or publicity<br />
# pertaining to distribution of the software without specific, written<br />
# prior permission.<br />
# <br />
# THE AUTHOR(S) DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,<br />
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN<br />
# NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR<br />
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF<br />
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR<br />
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR<br />
# PERFORMANCE OF THIS SOFTWARE.<br />
# ----------------------------------------------------------------------<br />
<br />
import tkSimpleDialog<br />
import tkMessageBox<br />
from pymol import cmd<br />
import sys, urllib2, zlib<br />
<br />
def __init__(self):<br />
self.menuBar.addmenuitem('Plugin', 'command',<br />
'PDB Loader Service',<br />
label = 'PDB Loader Service',<br />
command = lambda s=self : fetchPDBDialog(s))<br />
<br />
def remote(pdbCode):<br />
pdbCode = pdbCode.upper()<br />
try:<br />
pdbFile = urllib2.urlopen('http://www.rcsb.org/pdb/cgi/export.cgi/' +<br />
pdbCode + '.pdb.gz?format=PDB&pdbId=' +<br />
pdbCode + '&compression=gz')<br />
cmd.read_pdbstr(zlib.decompress(pdbFile.read()[22:], -zlib.MAX_WBITS), pdbCode)<br />
except:<br />
print "Unexpected error:", sys.exc_info()[0]<br />
tkMessageBox.showerror('Invalid Code',<br />
'You entered an invalid pdb code:' + pdbCode)<br />
<br />
def fetchPDBDialog(app):<br />
pdbCode = tkSimpleDialog.askstring('PDB Loader Service',<br />
'Please enter a 4-digit pdb code:',<br />
parent=app.root)<br />
<br />
remote(pdbCode)<br />
<br />
cmd.extend('remote', remote)<br />
</source><br />
<br />
[[Category:Developers|Plugins_Tutorial]]<br />
[[Category:Plugins|Plugins_Tutorial]]<br />
[[Category:Tutorials]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Label&diff=5091Label2008-07-11T22:27:29Z<p>Cowsandmilk: /* UTF8 Fonts */ fix typo of setting</p>
<hr />
<div>[[Image:Label_pre.png|thumb|PyMol Labels]]<br />
===DESCRIPTION===<br />
'''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:<br />
* '''name''', the atom name<br />
* '''resn''', the residue name<br />
*'''resi''', the residue number/identifier<br />
*'''chain''', the chain name<br />
*'''q''',<br />
*'''b''', the occupancy/b-factor<br />
*'''segi''', the segment identifier<br />
*'''type''' ''(ATOM,HETATM)'', the type of atom<br />
*'''formal_charge''', the formal charge<br />
*'''partial_charge''', the partial charge<br />
*'''numeric_type''', the numeric type<br />
*'''text_type''', the text type<br />
<br />
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 ''.<br />
<br />
===USAGE===<br />
label (selection),expression<br />
<br />
<br />
===SETTINGS===<br />
====FONT====<br />
There are 10 different scalable fonts.<br />
<source lang="python">set label_font_id, number</source><br />
where number is 5 through 14.<br />
=====UTF8 Fonts=====<br />
<br />
[[Image:New_fonts.jpeg|thumb|New fonts in PyMol. Notice the alpha and beta characters.]]<br />
<br />
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.)<br />
<br />
Here's some example code for the image at right:<br />
<source lang="python"><br />
# roman<br />
set label_font_id, 15<br />
set label_shadow_mode, 3<br />
label 5/CA, "\316\261-Helix"<br />
label 10/CA, "\316\262-Sheet"<br />
<br />
# italic<br />
set label_font_id, 16<br />
<br />
# make bigger<br />
set label_size, 50<br />
</source><br />
<br />
====SIZE====<br />
The font size can be adjusted<br />
<source lang="python">set label_size, number</source><br />
where number is the point size (or -number for Angstroms)<br />
<br />
====COLOR====<br />
Set a label's color by<br />
set label_color, color<br />
where color is a valid PyMol color.<br />
<br />
====EXPRESSION====<br />
To set what the label reads (see above)<br />
<source lang="python">label selection, expression</source><br />
For example<br />
<source lang="python"><br />
label all, name<br />
label resi 10, b<br />
</source><br />
<br />
====POSITION====<br />
To position labels<br />
edit_mode<br />
then<br />
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.)<br />
<br />
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.)<br />
<br />
===EXAMPLES===<br />
label (chain A),chain<br />
label (n;ca),"%s-%s" % (resn,resi)<br />
label (resi 200),"%1.3f" % partial_charge<br />
<br />
The following image was created with<br />
<source lang="python"><br />
label (resi 200),"%1.3f" % b<br />
set label_font_id, 10<br />
set label_size, 10<br />
</source><br />
and finally, some labels were moved around in '''edit_mode'''.<br />
[[Image:Label_ex.png|thumb|Labels.]]<br />
<br />
===Users Comments===<br />
====Labels Using ID Numbers====<br />
The following commnent,<br />
label SELECTION, " %s" % ID <br />
labels the SELECTION with atom ID numbers.<br />
<br />
You can make more complicated selections/lables such as<br />
label SELECTION, " %s:%s %s" % (resi, resn, name)<br />
which will give you something like "GLU:139 CG"<br />
<br />
====Labels Using One Letter Abbreviations====<br />
* First, Add this to your $HOME/.pymolrc file:<br />
<source lang="python"><br />
# start $HOME/.pymolrc modification<br />
one_letter ={'VAL':'V', 'ILE':'I', 'LEU':'L', 'GLU':'E', 'GLN':'Q', \<br />
'ASP':'D', 'ASN':'N', 'HIS':'H', 'TRP':'W', 'PHE':'F', 'TYR':'Y', \<br />
'ARG':'R', 'LYS':'K', 'SER':'S', 'THR':'T', 'MET':'M', 'ALA':'A', \<br />
'GLY':'G', 'PRO':'P', 'CYS':'C'}<br />
# end modification<br />
</source><br />
<br />
*. Second, instead of:<br />
label n. ca, resn<br />
use:<br />
label n. ca, one_letter[resn]<br />
<br />
[[Category:Commands|label]]</div>Cowsandmilkhttps://pymolwiki.org/index.php?title=Gallery&diff=5058Gallery2008-06-08T03:52:25Z<p>Cowsandmilk: Link Grid Mode to the correct page</p>
<hr />
<div>{| align="center"<br />
|+ style="width: 90%; font-size:190%; font-weight: bold; color:#038; text-align:center; padding: 5px; margin-bottom: 15px; colspan:4" | PyMOLWiki Gallery<br />
|- style="text-align:center; font-weight: bold; font-size:120%; color:#333;"<br />
| Cool PyMOL-generated Images and their Scripts.<br/><br/>''[[Talk:Gallery#Adding|Add Your Own]]''<br />
|}<br />
<br />
{{GalleryImage<br />
|image=Gm2.png|size=200px|title=Grid Mode|description=This image shows [[Grid mode|Grid Mode]] in action.<br />
|cmdString=<source lang="python"><br />
fetch 1cll 1sra 1ggz 5pnt 1rlw 1cdy;<br />
set grid_mode<br />
</source><br />
|seeAlso=<br />
*[[Fetch]]<br />
*[[Set]]<br />
*[[grid_mode]]<br />
}}<br />
<br />
{{GalleryImage<br />
|image=Fov60.png|size=200px|title=Cool Perspective|description=This image shows a perspective through [[Field_Of_View]].<br />
|cmdString=<source lang="python"><br />
load prot.pdb;<br />
zoom i. 46-49 and n. CA<br />
set field_of_view, 60<br />
ray<br />
</source><br />
|seeAlso=<br />
*[[Load]]<br />
*[[Ray]]<br />
*[[Zoom]]<br />
*[[Set]]<br />
}}<br />
<br />
{{GalleryImage<br />
|image=Pocket.png|size=200px|title=Representing a binding pocket|description=This image shows a nice way to show binding surfaces<br />
|cmdString=<source lang="python"><br />
load $TUT/1hpv.pdb, tmp<br />
extract lig, organic<br />
extract prot, polymer<br />
delete tmp<br />
<br />
set surface_carve_cutoff, 4.5<br />
set surface_carve_selection, lig<br />
set surface_carve_normal_cutoff, -0.1<br />
<br />
show surface, prot within 8 of lig<br />
set two_sided_lighting<br />
set transparency, 0.5<br />
show sticks, lig<br />
orient lig<br />
<br />
set surface_color, white<br />
set surface_type, 2 # mesh<br />
unset ray_shadows<br />
</source><br />
|seeAlso=<br />
*[[extract]]<br />
*[[delete]]<br />
*[[show]]<br />
*[[set]]<br />
*[[orient]]<br />
*[[surface_carve_cutoff]]<br />
*[[surface_carve_selection]]<br />
*[[surface_carve_normal_cutoff]]<br />
*[[surface_color]]<br />
*[[surface_type]]<br />
}}</div>Cowsandmilk