https://pymolwiki.org/api.php?action=feedcontributions&user=Pavel&feedformat=atomPyMOLWiki - User contributions [en]2024-03-28T16:39:58ZUser contributionsMediaWiki 1.35.7https://pymolwiki.org/index.php?title=Average_b&diff=13555Average b2023-04-26T17:55:48Z<p>Pavel: </p>
<hr />
<div>=average_b.py=<br />
<br />
*calculate the average B-factor of a selection.<br />
<br />
==usage==<br />
* copy code to text file and save as average_b.py<br />
* type "run average_b.py" in PyMOL<br />
* then type "average_b (selection)"<br />
<br />
==author==<br />
Gregor Hagelueken<br />
<br />
==code==<br />
<source lang="python"><br />
from pymol import cmd,stored<br />
def average_b(selection):<br />
stored.tempfactor = 0<br />
stored.atomnumber = 0<br />
cmd.iterate(selection, "stored.tempfactor = stored.tempfactor + b")<br />
cmd.iterate(selection, "stored.atomnumber = stored.atomnumber + 1")<br />
print("Your selection: %s" % selection)<br />
print("sum of B factors: %s" % stored.tempfactor)<br />
print("number of atoms: %s" % stored.atomnumber)<br />
averagetempfactor = stored.tempfactor / stored.atomnumber<br />
print("average B of '%s': %s" % (selection, averagetempfactor))<br />
cmd.extend("average_b", average_b)<br />
</source><br />
<br />
[[Category:Script_Library]]<br />
[[Category:Structural_Biology_Scripts]]<br />
[[Category:Biochemical_Scripts]]</div>Pavelhttps://pymolwiki.org/index.php?title=Connect_mode&diff=12747Connect mode2018-04-23T19:08:17Z<p>Pavel: </p>
<hr />
<div>= Overview =<br />
Sets how bonds are made when loading a file.<br />
<br />
Values:<br />
* 0 = distance-based (excluding HETATM to HETATM) and CONECT records (default)<br />
* 1 = CONECT records<br />
* 2 = distance-based, ignores CONECT records<br />
* 3 = distance-based (including HETATM to HETATM) and CONECT records<br />
* 4 = for loading mmCIF: use the [http://www.wwpdb.org/data/ccd chemical components dictionary] to look up bonds (''in PyMOL 1.7.4, '''components.cif''' needs to be present in the current directory, later versions have a subset of the dictionary bundled with PyMOL, and look up unknown residues from a web service'')<br />
<br />
= Syntax =<br />
<source lang="python"><br />
# ignore CONECT records<br />
set connect_mode, 2<br />
# show current setting<br />
get connect_mode<br />
<br />
</source><br />
<br />
= See Also =<br />
[[Load]], [[Connect_cutoff]], [[Connect_bonded]]<br />
<br />
[[Category:Settings]]</div>Pavelhttps://pymolwiki.org/index.php?title=Align&diff=12703Align2017-12-06T16:13:58Z<p>Pavel: /* RMSD */</p>
<hr />
<div>[[Image:after_alignment.png|400px|thumb|right|Two proteins after structure alignment]]<br />
<br />
'''align''' performs a sequence alignment followed by a structural superposition, and then carries out zero or more cycles of refinement in order to reject structural outliers found during the fit.<br />
[[align]] does a good job on proteins with decent sequence similarity (identity >30%).<br />
For comparing proteins with lower sequence identity, the [[super]] and [[cealign]] commands perform better.<br />
<br />
== Usage ==<br />
<br />
align mobile, target [, cutoff [, cycles<br />
[, gap [, extend [, max_gap [, object<br />
[, matrix [, mobile_state [, target_state<br />
[, quiet [, max_skip [, transform [, reset ]]]]]]]]]]]]]<br />
<br />
== Arguments ==<br />
<br />
* '''mobile''' = string: atom selection of mobile object<br />
* '''target''' = string: atom selection of target object<br />
* '''cutoff''' = float: outlier rejection cutoff in RMS {default: 2.0}<br />
* '''cycles''' = int: maximum number of outlier rejection cycles {default: 5}<br />
* '''gap, extend, max_gap''': sequence alignment parameters<br />
* '''object''' = string: name of alignment object to create {default: (no alignment object)}<br />
* '''matrix''' = string: file name of substitution matrix for sequence alignment {default: BLOSUM62}<br />
* '''mobile_state''' = int: object state of mobile selection {default: 0 = all states}<br />
* '''target_state''' = int: object state of target selection {default: 0 = all states}<br />
* '''quiet''' = 0/1: suppress output {default: 0 in command mode, 1 in API}<br />
* '''max_skip''' = ?<br />
* '''transform''' = 0/1: do superposition {default: 1}<br />
* '''reset''' = ?<br />
<br />
== Alignment Objects ==<br />
<br />
An alignment object can be created with the '''object='''''somename'' argument. An alignment object provides:<br />
<br />
* aligned [[seq_view|sequence viewer]]<br />
* graphical representation of aligned atom pairs as lines in the 3D viewer<br />
* can be [[save|saved]] to a clustalw sequence alignment file<br />
<br />
== RMSD ==<br />
<br />
The RMSD of the aligned atoms (after outlier rejection!) is reported in the text output. The '''all-atom RMSD''' can be obtained by setting '''cycles=0''' and thus not doing any outlier rejection. The RMSD can also be captured with a python script, see the [[#PyMOL API|API paragraph]] below. Note that the output prints "RMS" but it is in fact "RMSD" and the units are Angstroms.<br />
<br />
== Examples ==<br />
<br />
<syntaxhighlight lang="python"><br />
fetch 1oky 1t46, async=0<br />
<br />
# 1) default with outlier rejection<br />
align 1oky, 1t46<br />
<br />
# 2) with alignment object, save to clustalw file<br />
align 1oky, 1t46, object=alnobj<br />
save alignment.aln, alnobj<br />
<br />
# 3) all-atom RMSD (no outlier rejection) and without superposition<br />
align 1oky, 1t46, cycles=0, transform=0<br />
</syntaxhighlight><br />
<br />
== PyMOL API ==<br />
<source lang="python"><br />
cmd.align( string mobile, string target, float cutoff=2.0,<br />
int cycles=5, float gap=-10.0, float extend=-0.5,<br />
int max_gap=50, string object=None, string matrix='BLOSUM62',<br />
int mobile_state=0, int target_state=0, int quiet=1,<br />
int max_skip=0, int transform=1, int reset=0 )<br />
</source><br />
<br />
This returns a list with 7 items:<br />
<br />
# RMSD after refinement<br />
# Number of aligned atoms after refinement<br />
# Number of refinement cycles<br />
# RMSD before refinement<br />
# Number of aligned atoms before refinement<br />
# Raw alignment score<br />
# Number of residues aligned<br />
<br />
== Notes ==<br />
<br />
* The molecules you want to align need to be in '''two different objects'''. Else, PyMOL will answer with: ''ExecutiveAlign: invalid selections for alignment.'' You can skirt this problem by making a temporary object and aligning your original to the copy.<br />
* By defaults, '''all states''' (like in NMR structures or trajectories) are considered, this might yield a bad or suboptimal alignment for a single state. Use the '''mobile_state''' and '''target_state''' argument to be explicit in such cases.<br />
<br />
== See Also ==<br />
<br />
* [[super]], [[cealign]], [[fit]], [[pair_fit]]<br />
* [[rms]], [[rms_cur]], <br />
* [[intra_fit]], [[intra_rms]], [[intra_rms_cur]]<br />
* [[extra_fit]]<br />
* [http://pldserver1.biochem.queensu.ca/~rlc/work/pymol/ align_all.py and super_all.py]<br />
* [[tmalign]]<br />
* [[Color_by_conservation]]<br />
* [[Get_raw_alignment]]<br />
* [[mcsalign]] (psico)<br />
<br />
[[Category:Commands|Align]]<br />
[[Category:Structure_Alignment|Align]]</div>Pavelhttps://pymolwiki.org/index.php?title=MAC_Install&diff=12623MAC Install2017-08-17T19:07:02Z<p>Pavel: /* X11 Hybrid */</p>
<hr />
<div>This page describes how to install PyMOL on Mac OS X.<br />
<br />
== Incentive PyMOL ==<br />
<br />
=== MacPyMOL ===<br />
<br />
MacPyMOL is available exclusively to paying sponsors. [http://www.schrodinger.com Schrödinger] provides a DMG package which also includes ready-to-use [[APBS]], [[morph|RigiMOL]], an MPEG encoder for movie export, and a small molecule energy minimization engine.<br />
<br />
Download: http://pymol.org/download<br />
<br />
Installation: Drag '''MacPyMOL.app''' on the '''/Applications''' shortcut. (In principle, you could drag it into any Finder window and run it from there, it doesn’t have to live in /Applications).<br />
<br />
Uninstallation: Move '''/Applications/MacPyMOL.app''' to Trash<br />
<br />
=== Launching from Command Line ===<br />
<br />
The unix executable resides at '''/Applications/MacPyMOL.app/Contents/MacOS/MacPyMOL'''<br />
<br />
=== X11 Hybrid ===<br />
<br />
MacPyMOL can optionally run with the same two-window GUI which PyMOL uses on Windows and Linux. This GUI has some additional features, like the [[Plugins|Plugin]] menu and the [[Builder]].<br />
<br />
Requires [http://xquartz.macosforge.org/ XQuartz].<br />
<br />
There are two ways to launch the X11 interface:<br />
# Rename or copy/duplicate '''/Applications/MacPyMOL.app''' to '''/Applications/MacPyMOLX11Hybrid.app''' or to '''/Applications/PyMOLX11Hybrid.app'''<br />
# Launch the unix executable with the '''-m''' flag: '''/Applications/MacPyMOL.app/Contents/MacOS/MacPyMOL -m'''<br />
<br />
=== Stereo on Second Monitor ===<br />
The trick to getting MacPyMOL to work in stereo on the second monitor is to force it to initially open on that display by providing an appropriate "-X #" (and perhaps -Y #) option on launch. That way the OpenGL context will be created with stereo support.<br />
<source lang="python"><br />
./MacPyMOL.app/Contents/MacOS/MacPyMOL -X -1000<br />
./MacPyMOL.app/Contents/MacOS/MacPyMOL -X -1000 -Y 100<br />
</source><br />
<br />
'''Source:''' ''Warren DeLano; PyMOL Users Archive''<br />
<br />
== Open-Source PyMOL ==<br />
<br />
=== Pre-compiled ===<br />
<br />
Pre-compiled Open-Source PyMOL is available [https://sourceforge.net/p/pymol/code/HEAD/tree/trunk/pymol/LICENSE free of charge] with the [https://www.macports.org/ MacPorts], [http://www.finkproject.org/ Fink] and [http://brew.sh/ Homebrew] environments.<br />
<br />
<source lang="bash"><br />
# Fink<br />
fink install pymol-py27<br />
<br />
# MacPorts<br />
sudo port install pymol<br />
<br />
# Homebrew<br />
brew install homebrew/science/pymol<br />
</source><br />
<br />
Make sure that the dependencies are installed with the required flags:<br />
<br />
<source lang="bash"><br />
# MacPorts<br />
sudo port install tcl -corefoundation<br />
sudo port install tk -quartz<br />
<br />
# Homebrew<br />
brew install Caskroom/cask/xquartz<br />
brew install tcl-tk --with-threads --with-x11<br />
brew install python --with-tcl-tk<br />
</source><br />
<br />
If PyMOL complains that it wasn't able to find X11, try starting xquartz first, then run pymol from the console.<br />
<br />
=== Install from Source ===<br />
<br />
If you want the latest PyMOL code (warning: might include experimental changes), then follow the [[Linux_Install#Install_from_source|Linux installation instructions]]. You will need an environment like Fink, MacPorts or Homebrew to install the dependencies. Make sure you use the appropriate python interpreter (e.g. '''/sw/bin/python2.7''' when using Fink).<br />
<br />
=== Install APBS with Fink ===<br />
<br />
To use the electrostatics plugin, you will need [http://apbs.sourceforge.net/ APBS] and its dependencies. These are also available as Fink packages, and include [http://pdb.finkproject.org/pdb/package.php/apbs APBS], [http://pdb.finkproject.org/pdb/package.php/maloc maloc] and [http://pdb.finkproject.org/pdb/package.php/pdb2pqr pdb2pqr]. If you have multiple processors available, you might wish to install the [http://pdb.finkproject.org/pdb/package.php/apbs-mpi-openmpi MPI version of APBS].<br />
<br />
Issuing the command<br />
<br />
fink install apbs<br />
<br />
will install apbs and its required dependencies for you. The fink pymol package is already preconfigured to do the right thing to use apbs as a plugin.<br />
<br />
=== Stereo issues ===<br />
Some older Macs seem to crash with stereo graphics. If this happens to you, a workaround is to launch PyMOL explicitly in Mono mode with `pymol -M`. You can also set up an alias in your ~/.profile:<br />
<br />
alias pymol='pymol -M'<br />
<br />
== See Also ==<br />
<br />
* [[pymolrc]]<br />
* [[Linux Install]]<br />
* [[Windows Install]]<br />
* [[MovieSchool_6#Exporting_your_Movie|FreeMOL installation for MPEG movie export]]<br />
* [[User:Wgscott|Bill Scott’s]] [[MacOSX-specific .pymolrc file]] and his crystallographic software [http://xanana.ucsc.edu/~wgscott/xtal/wiki/index.php/Main_Page wiki] and [http://chemistry.ucsc.edu/~wgscott/xtal/ website], including instructions on [http://xanana.ucsc.edu/~wgscott/xtal/wiki/index.php/Getting_your_fink_installation_to_use_packages_that_I_have_pre-compiled how to install precompiled binary packages using fink].<br />
* [[Launching_PyMOL#MacOS_X]]<br />
<br />
[[Category:Installation|Mac]]<br />
[[Category:Nucleic_Acids|MAC Install]]<br />
[[Category:Technical Issues|MAC Install]]<br />
[[Category:Mac|MAC Install]]</div>Pavelhttps://pymolwiki.org/index.php?title=Talk:Label&diff=12387Talk:Label2016-05-27T15:50:26Z<p>Pavel: /* Unicdoe Fonts */</p>
<hr />
<div>== Fixes ==<br />
*Updates needed<br />
<br />
=New Page Content=<br />
==New Page Overview==<br />
This is the content for the new labels page.<br />
<br />
<br />
= Old Page =<br />
[[Image:Label_pre.png|200px|right|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 />
[[Label]] is great for labeling atoms, residues and objects. For a scene label, see [[Pseudoatom]].<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 />
=====Unicode Fonts=====<br />
[[Image:Font_ex.png|300px|thumb|right|Notice the Angstrom and superscript 2 characters. You can add other characters as well.]]<br />
<br />
PyMOL gives you the flexibility to use encoded unicode fonts. This allows us to insert various symbols, like the symbol used for Angstrom. Here are the steps to insert a character from the unicode character set.<br />
<br />
* Find the code for your character at [http://www.unicode.org/charts Unicode Charts]. The Angstrom character, <math>\textrm{\AA}</math> is u"\u00c5" and <math>\pm</math> is u"\u00b1".<br />
* Label the selection. For simple strings, just type the string in double quote, -- "like this" -- and append to the end of that .encode('utf-8') -- "like this".encode('utf-8'). A working example is shown here,<br />
<source lang="python"><br />
# label residue 30 with "4.1 Ang^2 +/- 0.65 Ang^2; see the image at right<br />
label i. 30, "4.1" + u"\u00c5\u00b2 \u00b1 0.65 \u00c5\u00b2 ".encode('utf-8')<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 />
If the coloring of the labels is not ''exactly'' the same as you'd expect (say black turns out grey, or red turns out pink), then try the following settings:<br />
<source lang="python"><br />
unset depth_cue<br />
unset ray_label_specular<br />
</source><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 />
==== Partial Charge ====<br />
<source lang="python"><br />
label (chain A),chain<br />
label (n;ca),"%s-%s" % (resn,resi)<br />
label (resi 200),"%1.3f" % partial_charge<br />
</source><br />
<br />
==== Example 2 ====<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 />
<br />
==== More Advanced ====<br />
This example shows how to label a selection with the XYZ coordinates of the atoms<br />
<source lang="python"><br />
from pymol import stored<br />
stored.pos = []<br />
<br />
# select the carbon atoms in my hetero atoms to label<br />
select nn, het and e. C<br />
<br />
# get the XYZ coordinates and put htem into stored.pos<br />
iterate_state 1, (nn), stored.pos.append((x,y,z))<br />
<br />
# label all N atoms. You need the pop() function or else<br />
# PyMOL will complain b/c you didn't provide enough coords.<br />
label nn, ("%5.5s, %5.5s, %5.5s") % stored.pos.pop()<br />
</source><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]]<br />
[[Category:Labeling|Label]]</div>Pavelhttps://pymolwiki.org/index.php?title=BiologicalUnit/Quat&diff=12286BiologicalUnit/Quat2016-02-04T18:27:19Z<p>Pavel: /* The Code */</p>
<hr />
<div>This script does more or less the same as [[BiologicalUnit]]. It creates the '''quat'''ernary structure (BIOMOLECULE 1 assembly) from the REMARK 350 header.<br />
<br />
This script is convenient to use because it searches automatically for the PDB file in the current directory, in [[Fetch_Path|fetch_path]] and (if available) in your local PDB mirror.<br />
<br />
= Example Usage =<br />
<source lang="python"><br />
fetch 3bw1, type=pdb<br />
quat 3bw1<br />
as cartoon<br />
</source><br />
<br />
= The Code =<br />
<source lang="python"><br />
'''<br />
(c) 2010-2011 Thomas Holder, MPI for Developmental Biology<br />
<br />
Module for reading REMARK records from PDB files and in particular<br />
generate quaterny structure from REMARK 350.<br />
'''<br />
<br />
import sys, os<br />
from pymol import cmd, stored<br />
<br />
local_mirror_divided = '/mnt/bio/db/pdb.divided'<br />
<br />
def pdbremarks(filename):<br />
'''<br />
Read REMARK lines from PDB file. Return dictionary with remarkNum as key<br />
and list of lines as value.<br />
'''<br />
remarks = dict()<br />
if not isinstance(filename, basestring):<br />
f = filename<br />
elif filename[-3:] == '.gz':<br />
import gzip<br />
f = gzip.open(filename)<br />
else:<br />
f = open(filename)<br />
for line in f:<br />
recname = line[0:6]<br />
if recname == 'REMARK':<br />
num = int(line[7:10])<br />
lstring = line[11:]<br />
remarks.setdefault(num, []).append(lstring)<br />
return remarks<br />
<br />
def quat350(rem350):<br />
'''<br />
Get transformation matrices for biomolecule 1 from REMARK 350.<br />
'''<br />
biomt = dict()<br />
chains = tuple()<br />
seenbiomolecule = False<br />
for line in rem350:<br />
if line.startswith('BIOMOLECULE:'):<br />
if seenbiomolecule:<br />
break<br />
seenbiomolecule = True<br />
elif line.startswith('APPLY THE FOLLOWING TO CHAINS:'):<br />
chains = tuple(chain.strip() for chain in line[30:].split(','))<br />
elif line.startswith(' AND CHAINS:'):<br />
chains += tuple(chain.strip() for chain in line[30:].split(','))<br />
elif line.startswith(' BIOMT'):<br />
row = int(line[7])<br />
num = int(line[8:12])<br />
vec = line[12:].split()<br />
vec = map(float, vec)<br />
biomt.setdefault(chains, dict()).setdefault(num, []).extend(vec)<br />
return biomt<br />
<br />
def quat(name=None, filename=None, prefix=None, quiet=0):<br />
'''<br />
DESCRIPTION<br />
<br />
Read REMARK 350 from `filename` and create biological unit<br />
(quaternary structure)<br />
<br />
USAGE<br />
<br />
quat [name [, filename [, prefix]]]<br />
<br />
ARGUMENTS<br />
<br />
name = string: name of object and basename of PDB file, if<br />
filename is not given {default: first loaded object}<br />
<br />
filename = string: file path {default: <name>.pdb}<br />
<br />
prefix = string: prefix for new objects {default: <name>}<br />
<br />
EXAMPLE<br />
<br />
fetch 1rmv, type=pdb<br />
quat 1rmv<br />
'''<br />
quiet = int(quiet)<br />
if name is None:<br />
name = cmd.get_object_list()[0]<br />
if prefix is None:<br />
prefix = name<br />
if filename is None:<br />
candidates = [<br />
'%s.pdb' % (name),<br />
'%s/%s.pdb' % (cmd.get('fetch_path'), name),<br />
'%s/%s/pdb%s.ent.gz' % (local_mirror_divided, name[1:3], name),<br />
]<br />
for filename in candidates:<br />
if os.path.exists(filename):<br />
break<br />
else:<br />
print 'please provide filename'<br />
return<br />
if not quiet:<br />
print 'loading from %s' % (filename)<br />
remarks = pdbremarks(filename)<br />
if 350 not in remarks:<br />
print 'There is no REMARK 350 in', filename<br />
return<br />
quat = quat350(remarks[350])<br />
for chains in quat:<br />
matrices = quat[chains]<br />
for num in matrices:<br />
mat = matrices[num][0:12]<br />
mat.extend([0,0,0,1])<br />
copy = '%s_%d' % (prefix, num)<br />
if not quiet:<br />
print 'creating %s' % (copy)<br />
cmd.create(copy, '/%s//%s' % (name, '+'.join(chains)))<br />
cmd.alter(copy, 'segi="%d"' % (num))<br />
cmd.transform_object(copy, mat)<br />
cmd.disable(name)<br />
cmd.group('%s_quat' % (prefix), '%s_*' % (prefix))<br />
<br />
cmd.extend('quat', quat)<br />
<br />
# vi:expandtab:smarttab<br />
</source><br />
<br />
= See Also =<br />
*[[BiologicalUnit]]<br />
*[[Supercell]]<br />
<br />
[[Category:Script_Library]]<br />
[[Category:Math_Scripts]]<br />
[[Category:Structural_Biology_Scripts]]</div>Pavelhttps://pymolwiki.org/index.php?title=BiologicalUnit/Quat&diff=12285BiologicalUnit/Quat2016-02-04T18:26:53Z<p>Pavel: /* Example Usage */</p>
<hr />
<div>This script does more or less the same as [[BiologicalUnit]]. It creates the '''quat'''ernary structure (BIOMOLECULE 1 assembly) from the REMARK 350 header.<br />
<br />
This script is convenient to use because it searches automatically for the PDB file in the current directory, in [[Fetch_Path|fetch_path]] and (if available) in your local PDB mirror.<br />
<br />
= Example Usage =<br />
<source lang="python"><br />
fetch 3bw1, type=pdb<br />
quat 3bw1<br />
as cartoon<br />
</source><br />
<br />
= The Code =<br />
<source lang="python"><br />
'''<br />
(c) 2010-2011 Thomas Holder, MPI for Developmental Biology<br />
<br />
Module for reading REMARK records from PDB files and in particular<br />
generate quaterny structure from REMARK 350.<br />
'''<br />
<br />
import sys, os<br />
from pymol import cmd, stored<br />
<br />
local_mirror_divided = '/mnt/bio/db/pdb.divided'<br />
<br />
def pdbremarks(filename):<br />
'''<br />
Read REMARK lines from PDB file. Return dictionary with remarkNum as key<br />
and list of lines as value.<br />
'''<br />
remarks = dict()<br />
if not isinstance(filename, basestring):<br />
f = filename<br />
elif filename[-3:] == '.gz':<br />
import gzip<br />
f = gzip.open(filename)<br />
else:<br />
f = open(filename)<br />
for line in f:<br />
recname = line[0:6]<br />
if recname == 'REMARK':<br />
num = int(line[7:10])<br />
lstring = line[11:]<br />
remarks.setdefault(num, []).append(lstring)<br />
return remarks<br />
<br />
def quat350(rem350):<br />
'''<br />
Get transformation matrices for biomolecule 1 from REMARK 350.<br />
'''<br />
biomt = dict()<br />
chains = tuple()<br />
seenbiomolecule = False<br />
for line in rem350:<br />
if line.startswith('BIOMOLECULE:'):<br />
if seenbiomolecule:<br />
break<br />
seenbiomolecule = True<br />
elif line.startswith('APPLY THE FOLLOWING TO CHAINS:'):<br />
chains = tuple(chain.strip() for chain in line[30:].split(','))<br />
elif line.startswith(' AND CHAINS:'):<br />
chains += tuple(chain.strip() for chain in line[30:].split(','))<br />
elif line.startswith(' BIOMT'):<br />
row = int(line[7])<br />
num = int(line[8:12])<br />
vec = line[12:].split()<br />
vec = map(float, vec)<br />
biomt.setdefault(chains, dict()).setdefault(num, []).extend(vec)<br />
return biomt<br />
<br />
def quat(name=None, filename=None, prefix=None, quiet=0):<br />
'''<br />
DESCRIPTION<br />
<br />
Read REMARK 350 from `filename` and create biological unit<br />
(quaternary structure)<br />
<br />
USAGE<br />
<br />
quat [name [, filename [, prefix]]]<br />
<br />
ARGUMENTS<br />
<br />
name = string: name of object and basename of PDB file, if<br />
filename is not given {default: first loaded object}<br />
<br />
filename = string: file path {default: <name>.pdb}<br />
<br />
prefix = string: prefix for new objects {default: <name>}<br />
<br />
EXAMPLE<br />
<br />
fetch 1rmv<br />
quat 1rmv<br />
'''<br />
quiet = int(quiet)<br />
if name is None:<br />
name = cmd.get_object_list()[0]<br />
if prefix is None:<br />
prefix = name<br />
if filename is None:<br />
candidates = [<br />
'%s.pdb' % (name),<br />
'%s/%s.pdb' % (cmd.get('fetch_path'), name),<br />
'%s/%s/pdb%s.ent.gz' % (local_mirror_divided, name[1:3], name),<br />
]<br />
for filename in candidates:<br />
if os.path.exists(filename):<br />
break<br />
else:<br />
print 'please provide filename'<br />
return<br />
if not quiet:<br />
print 'loading from %s' % (filename)<br />
remarks = pdbremarks(filename)<br />
if 350 not in remarks:<br />
print 'There is no REMARK 350 in', filename<br />
return<br />
quat = quat350(remarks[350])<br />
for chains in quat:<br />
matrices = quat[chains]<br />
for num in matrices:<br />
mat = matrices[num][0:12]<br />
mat.extend([0,0,0,1])<br />
copy = '%s_%d' % (prefix, num)<br />
if not quiet:<br />
print 'creating %s' % (copy)<br />
cmd.create(copy, '/%s//%s' % (name, '+'.join(chains)))<br />
cmd.alter(copy, 'segi="%d"' % (num))<br />
cmd.transform_object(copy, mat)<br />
cmd.disable(name)<br />
cmd.group('%s_quat' % (prefix), '%s_*' % (prefix))<br />
<br />
cmd.extend('quat', quat)<br />
<br />
# vi:expandtab:smarttab<br />
</source><br />
<br />
= See Also =<br />
*[[BiologicalUnit]]<br />
*[[Supercell]]<br />
<br />
[[Category:Script_Library]]<br />
[[Category:Math_Scripts]]<br />
[[Category:Structural_Biology_Scripts]]</div>Pavelhttps://pymolwiki.org/index.php?title=Scene&diff=12266Scene2016-01-08T21:25:29Z<p>Pavel: /* Examples */</p>
<hr />
<div>'''scene''' makes it possible to save and restore multiple scenes scene within a single session. A scene consists of the view, all object activity information, all atom-wise visibility, color, representations, and the global frame index.<br />
<br />
== Usage ==<br />
<br />
scene [ key [, action [, message [, view [, color [, active [, rep<br />
[, frame [, animate [, new_key ]]]]]]]]]]<br />
<br />
=== Arguments ===<br />
* '''key''' = string, new, auto, or *: use new for an automatically numbered new scene, use auto for the current scene (if one exists), and use * for all scenes (clear and recall actions only).<br />
* '''action''' = store, recall, insert_after, insert_before, next, previous, update, rename, clear or append: (default = recall). If rename, then a new_key argument must be explicitly defined.<br />
* '''message''' = string: a text message to display with the scene.<br />
* '''view''' = 1 or 0: controls whether the view is stored {default: 1}<br />
* '''color''' = 1 or 0: controls whether colors are stored {default: 1}<br />
* '''active''' = 1 or 0: controls whether activity (objects enabled/disabled) is stored {default: 1}<br />
* '''rep''' = 1 or 0: controls whether the representations are stored {default: 1}<br />
* '''frame''' = 1 or 0: controls whether the frame is stored {default: 1}<br />
* '''animate''' = float: animation duration in seconds {default: ''scene_animation_duration''}<br />
* '''new_key''' = string: the new name for the scene<br />
<br />
== Using Scene ==<br />
The [[Scene]] command has quite a few actions/options that can be enabled by using the mouse and the keyboard through the usual [[Scene]] command or hot-keys. Also, you can shift the scenes around using the new [[Scene_buttons]] and just dragging the scene names.<br />
<br />
=== Storing scenes ===<br />
<source lang="python"><br />
# store this scene in the next spot, giving it the default name.<br />
scene auto, store<br />
</source><br />
has the hot-key equivalent of '''CTRL-PageDown''' (FN+CTRL+DownArrow on the Mac). Try turning on [[Scene_Buttons]] and then doing CTRL-PageDown; see the scene buttons popping up?<br />
<br />
=== Scenes as Movies ===<br />
If you desire to make a movie that only has camera changes or representation changes, then scenes are your friend. Simply setup each view and then when ready you can do Scene->Store from the PyMOL menus (or ''scene auto, store'' on the command line or the third method Ctrl+PgDn (Fn+Ctrl+DownArrow on the Mac)). Do this for each view you setup. Once done, you can scroll through your scenes by pushing PgUp/PgDn. PyMOL automatically interpolates when you use the PgUp/PgDn buttons, so you get the desired smooth transitions. Mix this with [http://www.pymol.org/ax/ AxPyMOL] and you have movies in PowerPoint with very little work.<br />
<br />
=== Auto-play through Scenes ===<br />
With this simple trick you can auto-play through scenes. This is similar to "Movie > Program > Scene Loop" but uses only a single frame.<br />
<syntaxhighlight lang="python"><br />
cmd.mset('1x1')<br />
cmd.set('scene_loop')<br />
cmd.set('movie_fps', 1.0 / 5.0)<br />
cmd.mdo(1, 'scene auto, next')<br />
cmd.mplay()<br />
</syntaxhighlight><br />
<br />
== Examples ==<br />
Simple Examples.<br />
<source lang="python"><br />
scene F1, store<br />
scene F2, store, This view shows you the critical hydrogen bond.<br />
<br />
scene F1<br />
scene F2<br />
<br />
scene *<br />
</source><br />
<br />
This example shows how to use scenes in a movie!<br />
<source lang="python"><br />
# SUMMARY<br />
#<br />
<br />
# This script demonstrates one way of creating a movie from scenes.<br />
# It assumes that we have three scenes, each running for 10 seconds<br />
# (300 frames apiece) including 2-second transitions.<br />
<br />
# 1) Load or create content for three scenes (this could just as easily<br />
# come from a session file).<br />
<br />
load $TUT/1hpv.pdb<br />
util.cbc<br />
turn x,180<br />
orient<br />
as cartoon<br />
scene 001, store<br />
<br />
show sticks, organic<br />
orient organic<br />
scene 002, store<br />
<br />
hide cartoon<br />
show lines, byres organic expand 5<br />
turn x,45<br />
turn y,45<br />
scene 003, store<br />
<br />
# 2) Specify a 30-second movie -- state 1, 900 frames at 30 frames per second.<br />
<br />
mset 1 x900<br />
<br />
# 3) Program scene matrices as movie views at appopriate frames<br />
# and also add y-axis rocking between scenes.<br />
<br />
scene 001, animate=0<br />
mview store, 1<br />
mview store, 240<br />
<br />
turn y,-30<br />
mview store, 70<br />
turn y,60<br />
mview store, 170<br />
<br />
scene 002, animate=0<br />
mview store, 300<br />
mview store, 540<br />
<br />
turn y,-30<br />
mview store, 370<br />
turn y,60<br />
mview store, 470<br />
<br />
scene 003, animate=0<br />
mview store, 600<br />
mview store, 840<br />
<br />
turn y,-30<br />
mview store, 670<br />
turn y,60<br />
mview store, 770<br />
<br />
# 4) Now interpolate the movie camera.<br />
<br />
mview interpolate<br />
mview smooth<br />
mview smooth<br />
<br />
# 5) Activate scene content at the appropriate movie frames.<br />
<br />
mdo 1: scene 001, view=0, quiet=1<br />
mdo 240: scene 002, view=0, quiet=1<br />
mdo 540: scene 003, view=0, quiet=1<br />
mdo 840: scene 001, view=0, quiet=1<br />
<br />
# 6) Force frame 1 content to load.<br />
<br />
rewind<br />
<br />
# 6) And play the movie.<br />
<br />
mplay<br />
</source><br />
<br />
== PyMOL API ==<br />
<source lang="python"><br />
cmd.scene(str key='auto', str action='recall', str-or-list message=None, bool view=1, bool color=1,<br />
bool active=1, bool rep=1, bool frame=1, float animate=-1, str new_key=None)<br />
</source><br />
<br />
== Notes ==<br />
* To scroll through your frames, as in a presentation, just use the PG-UP and PG-DN keys. Very handy.<br />
*Scenes F1 through F12 are automatically bound to function keys provided that "set_key" hasn't been used to redefine the behaviour of the respective key.<br />
*If you have a script that modifies the representation of the molecules and stores them, quickly, then the stored frames may not be up to date. I suggest calling "refresh" between the commands.<br />
<br />
== See Also ==<br />
[[View]], [[Set_View]], [[Get_View]], [[Movie_from_scenes]]<br />
<br />
==DEVELOPMENT TO DO==<br />
Add support for save/restore of a certain global and object-and-state specific settings, such as: state, surface_color, ribbon_color, stick_color, transparency, sphere_transparency, etc. This would probably best be done by defining a class of "scene" settings which are treated in this manner. The current workaround is to create separate objects which are enabled/disabled differentially.<br />
<br />
[[Category:Scenes]]<br />
[[Category:States]]</div>Pavelhttps://pymolwiki.org/index.php?title=Ray&diff=11725Ray2014-10-17T22:35:00Z<p>Pavel: /* Renderer */</p>
<hr />
<div>'''ray''' creates a ray-traced image of the current frame. <br />
[[Image:Gslike.png|right|350px|thumb|Varying settings to play with rendering options]]<br />
<br />
=Details= <br />
This command is used to make high-resolution photos fit for publication and formal movies. Please note, the '''ray''' command can take some time (up to several minutes, depending on image complexity and size).<br />
<br />
For those who are making movies with PyMOL, '''Ray''' is one of the most commonly used last steps before stitching the frames together to compile the movie. '''Ray''' has many powerful features such as setting the size of the image -- and it still works even if the [[Viewport]] or screen is smaller than the requested output file dimensions.<br />
<br />
[[Image:No_ray_trace.png|Image, not ray traced.|thumb|200px]] [[Image:ray_traced.png|Image, ray traced.|thumb|200px]]<br />
<br />
==Usage==<br />
ray [width,height [,renderer [,angle [,shift ]]]<br />
'''angle''' and '''shift''' can be used to generate matched stereo pairs<br />
<br />
'''width''' and '''height''' can be set to any non-negative integer. If both are set to zero than the current window size is used and is equivalent to just using '''ray''' with no arguments. If one is set to zero (or missing) while the other is a positive integer, then the argument set to zero (or missing) will be scaled to preserve the current aspect ratio.<br />
<br />
==PyMol API==<br />
<source lang="python">cmd.ray(int width,int height,int renderer=-1,float shift=0)</source><br />
<br />
==Settings==<br />
===Modes===<br />
Setting the '''[[Ray_trace_mode]]''' variable in PyMOL changes the way PyMOL's internal renderer represents proteins in the final output. New modes were recently added to give the user more options of molecular representation. New modes are: normal rendering, but with a black outline (nice for presentations); black and white only; quantized color with black outline (also, very nice for presentations; more of a ''cartoony'' appearance). <br />
<br />
'''Note:''' Mode 3, the quantized color one, sort of '''burns''' the background if you're using this setting. This will make a pure white background somewhat "offwhite"; thus, a poster would look poor because you could see the border for the image. If you'll be using this mode, try the [[ray_opaque_background]] setting.<br />
<br />
<source lang="python"><br />
# normal color<br />
set ray_trace_mode, 0<br />
<br />
# normal color + black outline<br />
set ray_trace_mode, 1<br />
<br />
# black outline only<br />
set ray_trace_mode, 2<br />
<br />
# quantized color + black outline<br />
set ray_trace_mode, 3<br />
<br />
set ray_trace_mode, 1 # (or 2 or 3; best with "bg_color white;set antialias,2")<br />
# These two new modes -- 2 and 3 -- are cool cartoon looking modes.<br />
<br />
# change the color of the outline to a named color, or a hex-code<br />
set ray_trace_color, magenta<br />
set ray_trace_color, 0x0033ff<br />
</source><br />
<br />
Here are the example images for the new modes<br />
<gallery><br />
Image:Ray_mode_1_ex.png|set ray_trace_mode,1<br />
Image:Ray_mode_2_ex.png|set ray_trace_mode,2<br />
Image:Ray_mode_3_ex.png|set ray_trace_mode,3<br />
</gallery><br />
<br />
===Perspective===<br />
====Perspective Example Images====<br />
<gallery><br />
Image:No_persp.png|Example with Perspective Turned Off<br />
Image:Persp1.png|Example with Perspective Turned On<br />
Image:Persp2.png|Example with Perspective Turned On and Field of View Set High (70).<br />
</gallery><br />
<br />
=====Notes=====<br />
PyMol 0.97 and prior used '''orthoscopic''' rendering -- that is, no perspective. Upon the arrival of 0.98 and later, we get perspective based rendering at a cost of a 4x decrease in render speed. If you want perspective<br />
set orthoscopic, off<br />
Otherwise<br />
set orthoscopic, on<br />
To magnify the effect of perspective on the scene,<br />
set field_of_view, X<br />
where 50<X<70. Default is 20. 50-70 gives a very strong perspective effect. Nb. the field of view is in Y, not X as one would expect.<br />
<br />
<br />
<br />
===Renderer===<br />
'''renderer = -1''' is default (use value in ray_default_renderer)<br />
<br />
'''renderer = 0''' uses PyMOL's internal renderer<br />
<br />
'''renderer = 1''' uses PovRay's renderer. This is Unix-only and you must have "povray" in your path. It utilizes two temporary files: "tmp_pymol.pov" and "tmp_pymol.png". Also works on Mac via Povray37UnofficialMacCmd but it needs to be in your path as "povray".<br />
<br />
==Performance==<br />
*The ray performance depends on distance between camera and molecule.<br />
If the distance is big rendering takes much time. If the distance is too small distant parts of molecule dissolve.<br />
<gallery><br />
Image:Close_ray.png|Too close to molecule<br />
Image:Middle_ray.png|Normal distance<br />
</gallery><br />
* Tip: If you have a rather complicated scene that is zoomed into only a part of the molecule, you can speed up the ray tracing by hiding everything else outside of a certain range of the zoomed-on point. For example, if I have a large molecule and I'm looking only at the 30-atom ligand bound to it, then I can do something like the following:<br />
<source lang="python"><br />
# setup your complex scene<br />
...<br />
<br />
# zoom on the hetero atom (ligand and not water) within 5 Angstroms<br />
select hh, het and not resn HOH<br />
zoom hh, 5<br />
<br />
# turn on depth cueing<br />
set depth_cue, 1<br />
<br />
# now, select stuff to hide; we select everything that is <br />
# farther than 8 Ang from our main selection<br />
select th, (all) and not ( (all) within 8 of hh) )<br />
<br />
hide everything, th<br />
<br />
# any additional commands you want<br />
...<br />
<br />
ray<br />
</source><br />
As an example of the efficacy of this method, I ray traced a rather complex scene with all the atoms visible here's the output of ray:<br />
<source lang="bash"><br />
PyMOL>ray<br />
Ray: render time: 24.50 sec. = 146.9 frames/hour (941.88 sec. accum.).<br />
</source><br />
and here is the result when I soft-clipped everything else using the above method:<br />
<source lang="bash"><br />
PyMOL>ray<br />
Ray: render time: 47.93 sec. = 75.1 frames/hour (989.80 sec. accum.).<br />
</source><br />
The two images in the following gallery show the results of the rendering.<br />
<gallery><br />
Image:Ray_method_off.png|normal ray tracing. This took twice as long to make as the image to the right. Same size, and DPI.<br />
Image:Ray_method_on.png|manually hiding things you won't see anyway. This took 1/2 the time to render as compared to the same sized & DPId image at left.<br />
</gallery><br />
<br />
===Memory===<br />
If memory is an issue for you in PyMOL, try executing your rendering from a script rather than a PyMOL session file. An unfortunate unavoidable consequence of the fact that we use Python's portable, platform-independent "pickle" machinery for PyMOL session files. Packing or unpacking a Session or Scene file thus requires that there be two simultanous copies of the information to reside in RAM simultaneously: one native and a second in Python itself.<br />
<br />
So when memory is a limiting factor, scripts are recommended over sessions.<br />
<br />
==Examples==<br />
===Simple===<br />
<source lang="python"><br />
# ray trace the current scene using the default size of the viewport<br />
ray<br />
</source><br />
<br />
===Specify Image Size===<br />
<source lang="python"><br />
# ray trace the current scene, but scaled to 1024x768 pixels<br />
ray 1024,768<br />
</source><br />
<br />
===Specify Renderer===<br />
<source lang="python"><br />
# ray trace with an external renderer.<br />
ray renderer=0<br />
</source><br />
<br />
===High Quality B&W Rendering===<br />
[[Image:1l9l.png|thumb|center|Black and White (ray_trace_mode,2); click to see full image]]<br />
<source lang="python"><br />
# Black and White Script<br />
load /tmp/3fib.pdb;<br />
show cartoon;<br />
set ray_trace_mode, 2; # black and white cartoon<br />
bg_color white;<br />
set antialias, 2;<br />
ray 600,600<br />
png /tmp/1l9l.png<br />
</source><br />
<br />
===High Quality Color===<br />
[[Image:1l9l_2.png|thumb|center|Color mode (ray_trace_mode,3); click to see full image]]<br />
<source lang="python"><br />
# Color Script<br />
load /tmp/thy_model/1l9l.pdb;<br />
hide lines;<br />
show cartoon;<br />
set ray_trace_mode, 3; # color<br />
bg_color white;<br />
set antialias, 2;<br />
remove resn HOH<br />
remove resn HET<br />
ray 600,600<br />
png /tmp/1l9l.png<br />
</source><br />
<br />
===Ray Tracing Stereo Images===<br />
:''See [[Stereo_Ray]]''<br />
<br />
==See also==<br />
# "help faster" for optimization tips with the builtin renderer. "help povray" for how to use PovRay instead of PyMOL's built-in ray-tracing engine. For high-quality photos, please also see the [[Antialias]] command. [[Ray shadows]] for controlling shadows.<br />
# See also [[Ray Tracing]].<br />
# [http://www.gimp.org/tutorials/Color2BW Desaturation Tutorial] -- A good resource for making nice B&W images from color images (desaturation).<br />
#[[Ray Trace Gain]]<br />
<br />
==User comments==<br />
;How do I ray trace a publication-ready (~300dpi) image using PyMol?<br />
:This answer is in the [[:Category:Advanced_Issues|Advanced Issues]] (Image Manipulation Section).<br />
<br />
[[Category:Commands|Ray]]<br />
[[Category:Publication_Quality|Ray]]<br />
[[Category:Performance|Ray]]<br />
[[Category:Movies|Ray]]</div>Pavelhttps://pymolwiki.org/index.php?title=Ray&diff=11724Ray2014-10-17T22:33:10Z<p>Pavel: /* Renderer */</p>
<hr />
<div>'''ray''' creates a ray-traced image of the current frame. <br />
[[Image:Gslike.png|right|350px|thumb|Varying settings to play with rendering options]]<br />
<br />
=Details= <br />
This command is used to make high-resolution photos fit for publication and formal movies. Please note, the '''ray''' command can take some time (up to several minutes, depending on image complexity and size).<br />
<br />
For those who are making movies with PyMOL, '''Ray''' is one of the most commonly used last steps before stitching the frames together to compile the movie. '''Ray''' has many powerful features such as setting the size of the image -- and it still works even if the [[Viewport]] or screen is smaller than the requested output file dimensions.<br />
<br />
[[Image:No_ray_trace.png|Image, not ray traced.|thumb|200px]] [[Image:ray_traced.png|Image, ray traced.|thumb|200px]]<br />
<br />
==Usage==<br />
ray [width,height [,renderer [,angle [,shift ]]]<br />
'''angle''' and '''shift''' can be used to generate matched stereo pairs<br />
<br />
'''width''' and '''height''' can be set to any non-negative integer. If both are set to zero than the current window size is used and is equivalent to just using '''ray''' with no arguments. If one is set to zero (or missing) while the other is a positive integer, then the argument set to zero (or missing) will be scaled to preserve the current aspect ratio.<br />
<br />
==PyMol API==<br />
<source lang="python">cmd.ray(int width,int height,int renderer=-1,float shift=0)</source><br />
<br />
==Settings==<br />
===Modes===<br />
Setting the '''[[Ray_trace_mode]]''' variable in PyMOL changes the way PyMOL's internal renderer represents proteins in the final output. New modes were recently added to give the user more options of molecular representation. New modes are: normal rendering, but with a black outline (nice for presentations); black and white only; quantized color with black outline (also, very nice for presentations; more of a ''cartoony'' appearance). <br />
<br />
'''Note:''' Mode 3, the quantized color one, sort of '''burns''' the background if you're using this setting. This will make a pure white background somewhat "offwhite"; thus, a poster would look poor because you could see the border for the image. If you'll be using this mode, try the [[ray_opaque_background]] setting.<br />
<br />
<source lang="python"><br />
# normal color<br />
set ray_trace_mode, 0<br />
<br />
# normal color + black outline<br />
set ray_trace_mode, 1<br />
<br />
# black outline only<br />
set ray_trace_mode, 2<br />
<br />
# quantized color + black outline<br />
set ray_trace_mode, 3<br />
<br />
set ray_trace_mode, 1 # (or 2 or 3; best with "bg_color white;set antialias,2")<br />
# These two new modes -- 2 and 3 -- are cool cartoon looking modes.<br />
<br />
# change the color of the outline to a named color, or a hex-code<br />
set ray_trace_color, magenta<br />
set ray_trace_color, 0x0033ff<br />
</source><br />
<br />
Here are the example images for the new modes<br />
<gallery><br />
Image:Ray_mode_1_ex.png|set ray_trace_mode,1<br />
Image:Ray_mode_2_ex.png|set ray_trace_mode,2<br />
Image:Ray_mode_3_ex.png|set ray_trace_mode,3<br />
</gallery><br />
<br />
===Perspective===<br />
====Perspective Example Images====<br />
<gallery><br />
Image:No_persp.png|Example with Perspective Turned Off<br />
Image:Persp1.png|Example with Perspective Turned On<br />
Image:Persp2.png|Example with Perspective Turned On and Field of View Set High (70).<br />
</gallery><br />
<br />
=====Notes=====<br />
PyMol 0.97 and prior used '''orthoscopic''' rendering -- that is, no perspective. Upon the arrival of 0.98 and later, we get perspective based rendering at a cost of a 4x decrease in render speed. If you want perspective<br />
set orthoscopic, off<br />
Otherwise<br />
set orthoscopic, on<br />
To magnify the effect of perspective on the scene,<br />
set field_of_view, X<br />
where 50<X<70. Default is 20. 50-70 gives a very strong perspective effect. Nb. the field of view is in Y, not X as one would expect.<br />
<br />
<br />
<br />
===Renderer===<br />
'''renderer = -1''' is default (use value in ray_default_renderer)<br />
<br />
'''renderer = 0''' uses PyMOL's internal renderer<br />
<br />
'''renderer = 1''' uses PovRay's renderer. This is Unix-only and you must have "povray" in your path. It utilizes two temporary files: "tmp_pymol.pov" and "tmp_pymol.png". Can also work on Mac via Povray37UnofficialMacCmd but it needs to be in your path as "povray".<br />
<br />
==Performance==<br />
*The ray performance depends on distance between camera and molecule.<br />
If the distance is big rendering takes much time. If the distance is too small distant parts of molecule dissolve.<br />
<gallery><br />
Image:Close_ray.png|Too close to molecule<br />
Image:Middle_ray.png|Normal distance<br />
</gallery><br />
* Tip: If you have a rather complicated scene that is zoomed into only a part of the molecule, you can speed up the ray tracing by hiding everything else outside of a certain range of the zoomed-on point. For example, if I have a large molecule and I'm looking only at the 30-atom ligand bound to it, then I can do something like the following:<br />
<source lang="python"><br />
# setup your complex scene<br />
...<br />
<br />
# zoom on the hetero atom (ligand and not water) within 5 Angstroms<br />
select hh, het and not resn HOH<br />
zoom hh, 5<br />
<br />
# turn on depth cueing<br />
set depth_cue, 1<br />
<br />
# now, select stuff to hide; we select everything that is <br />
# farther than 8 Ang from our main selection<br />
select th, (all) and not ( (all) within 8 of hh) )<br />
<br />
hide everything, th<br />
<br />
# any additional commands you want<br />
...<br />
<br />
ray<br />
</source><br />
As an example of the efficacy of this method, I ray traced a rather complex scene with all the atoms visible here's the output of ray:<br />
<source lang="bash"><br />
PyMOL>ray<br />
Ray: render time: 24.50 sec. = 146.9 frames/hour (941.88 sec. accum.).<br />
</source><br />
and here is the result when I soft-clipped everything else using the above method:<br />
<source lang="bash"><br />
PyMOL>ray<br />
Ray: render time: 47.93 sec. = 75.1 frames/hour (989.80 sec. accum.).<br />
</source><br />
The two images in the following gallery show the results of the rendering.<br />
<gallery><br />
Image:Ray_method_off.png|normal ray tracing. This took twice as long to make as the image to the right. Same size, and DPI.<br />
Image:Ray_method_on.png|manually hiding things you won't see anyway. This took 1/2 the time to render as compared to the same sized & DPId image at left.<br />
</gallery><br />
<br />
===Memory===<br />
If memory is an issue for you in PyMOL, try executing your rendering from a script rather than a PyMOL session file. An unfortunate unavoidable consequence of the fact that we use Python's portable, platform-independent "pickle" machinery for PyMOL session files. Packing or unpacking a Session or Scene file thus requires that there be two simultanous copies of the information to reside in RAM simultaneously: one native and a second in Python itself.<br />
<br />
So when memory is a limiting factor, scripts are recommended over sessions.<br />
<br />
==Examples==<br />
===Simple===<br />
<source lang="python"><br />
# ray trace the current scene using the default size of the viewport<br />
ray<br />
</source><br />
<br />
===Specify Image Size===<br />
<source lang="python"><br />
# ray trace the current scene, but scaled to 1024x768 pixels<br />
ray 1024,768<br />
</source><br />
<br />
===Specify Renderer===<br />
<source lang="python"><br />
# ray trace with an external renderer.<br />
ray renderer=0<br />
</source><br />
<br />
===High Quality B&W Rendering===<br />
[[Image:1l9l.png|thumb|center|Black and White (ray_trace_mode,2); click to see full image]]<br />
<source lang="python"><br />
# Black and White Script<br />
load /tmp/3fib.pdb;<br />
show cartoon;<br />
set ray_trace_mode, 2; # black and white cartoon<br />
bg_color white;<br />
set antialias, 2;<br />
ray 600,600<br />
png /tmp/1l9l.png<br />
</source><br />
<br />
===High Quality Color===<br />
[[Image:1l9l_2.png|thumb|center|Color mode (ray_trace_mode,3); click to see full image]]<br />
<source lang="python"><br />
# Color Script<br />
load /tmp/thy_model/1l9l.pdb;<br />
hide lines;<br />
show cartoon;<br />
set ray_trace_mode, 3; # color<br />
bg_color white;<br />
set antialias, 2;<br />
remove resn HOH<br />
remove resn HET<br />
ray 600,600<br />
png /tmp/1l9l.png<br />
</source><br />
<br />
===Ray Tracing Stereo Images===<br />
:''See [[Stereo_Ray]]''<br />
<br />
==See also==<br />
# "help faster" for optimization tips with the builtin renderer. "help povray" for how to use PovRay instead of PyMOL's built-in ray-tracing engine. For high-quality photos, please also see the [[Antialias]] command. [[Ray shadows]] for controlling shadows.<br />
# See also [[Ray Tracing]].<br />
# [http://www.gimp.org/tutorials/Color2BW Desaturation Tutorial] -- A good resource for making nice B&W images from color images (desaturation).<br />
#[[Ray Trace Gain]]<br />
<br />
==User comments==<br />
;How do I ray trace a publication-ready (~300dpi) image using PyMol?<br />
:This answer is in the [[:Category:Advanced_Issues|Advanced Issues]] (Image Manipulation Section).<br />
<br />
[[Category:Commands|Ray]]<br />
[[Category:Publication_Quality|Ray]]<br />
[[Category:Performance|Ray]]<br />
[[Category:Movies|Ray]]</div>Pavelhttps://pymolwiki.org/index.php?title=Ray&diff=11552Ray2014-05-02T17:31:32Z<p>Pavel: /* Renderer */</p>
<hr />
<div>'''ray''' creates a ray-traced image of the current frame. <br />
[[Image:Gslike.png|right|350px|thumb|Varying settings to play with rendering options]]<br />
<br />
=Details= <br />
This command is used to make high-resolution photos fit for publication and formal movies. Please note, the '''ray''' command can take some time (up to several minutes, depending on image complexity and size).<br />
<br />
For those who are making movies with PyMOL, '''Ray''' is one of the most commonly used last steps before stitching the frames together to compile the movie. '''Ray''' has many powerful features such as setting the size of the image -- and it still works even if the [[Viewport]] or screen is smaller than the requested output file dimensions.<br />
<br />
[[Image:No_ray_trace.png|Image, not ray traced.|thumb|200px]] [[Image:ray_traced.png|Image, ray traced.|thumb|200px]]<br />
<br />
==Usage==<br />
ray [width,height [,renderer [,angle [,shift ]]]<br />
'''angle''' and '''shift''' can be used to generate matched stereo pairs<br />
<br />
'''width''' and '''height''' can be set to any non-negative integer. If both are set to zero than the current window size is used and is equivalent to just using '''ray''' with no arguments. If one is set to zero (or missing) while the other is a positive integer, then the argument set to zero (or missing) will be scaled to preserve the current aspect ratio.<br />
<br />
==PyMol API==<br />
<source lang="python">cmd.ray(int width,int height,int renderer=-1,float shift=0)</source><br />
<br />
==Settings==<br />
===Modes===<br />
Setting the '''[[Ray_trace_mode]]''' variable in PyMOL changes the way PyMOL's internal renderer represents proteins in the final output. New modes were recently added to give the user more options of molecular representation. New modes are: normal rendering, but with a black outline (nice for presentations); black and white only; quantized color with black outline (also, very nice for presentations; more of a ''cartoony'' appearance). <br />
<br />
'''Note:''' Mode 3, the quantized color one, sort of '''burns''' the background if you're using this setting. This will make a pure white background somewhat "offwhite"; thus, a poster would look poor because you could see the border for the image. If you'll be using this mode, try the [[ray_opaque_background]] setting.<br />
<br />
<source lang="python"><br />
# normal color<br />
set ray_trace_mode, 0<br />
<br />
# normal color + black outline<br />
set ray_trace_mode, 1<br />
<br />
# black outline only<br />
set ray_trace_mode, 2<br />
<br />
# quantized color + black outline<br />
set ray_trace_mode, 3<br />
<br />
set ray_trace_mode, 1 # (or 2 or 3; best with "bg_color white;set antialias,2")<br />
# These two new modes -- 2 and 3 -- are cool cartoon looking modes.<br />
<br />
# change the color of the outline to a named color, or a hex-code<br />
set ray_trace_color, magenta<br />
set ray_trace_color, 0x0033ff<br />
</source><br />
<br />
Here are the example images for the new modes<br />
<gallery><br />
Image:Ray_mode_1_ex.png|set ray_trace_mode,1<br />
Image:Ray_mode_2_ex.png|set ray_trace_mode,2<br />
Image:Ray_mode_3_ex.png|set ray_trace_mode,3<br />
</gallery><br />
<br />
===Perspective===<br />
====Perspective Example Images====<br />
<gallery><br />
Image:No_persp.png|Example with Perspective Turned Off<br />
Image:Persp1.png|Example with Perspective Turned On<br />
Image:Persp2.png|Example with Perspective Turned On and Field of View Set High (70).<br />
</gallery><br />
<br />
=====Notes=====<br />
PyMol 0.97 and prior used '''orthoscopic''' rendering -- that is, no perspective. Upon the arrival of 0.98 and later, we get perspective based rendering at a cost of a 4x decrease in render speed. If you want perspective<br />
set orthoscopic, off<br />
Otherwise<br />
set orthoscopic, on<br />
To magnify the effect of perspective on the scene,<br />
set field_of_view, X<br />
where 50<X<70. Default is 20. 50-70 gives a very strong perspective effect. Nb. the field of view is in Y, not X as one would expect.<br />
<br />
<br />
<br />
===Renderer===<br />
'''renderer = -1''' is default (use value in ray_default_renderer)<br />
<br />
'''renderer = 0''' uses PyMOL's internal renderer<br />
<br />
'''renderer = 1''' uses PovRay's renderer. This is Unix-only and you must have "povray" in your path. It utilizes two temporary files: "tmp_pymol.pov" and "tmp_pymol.png".<br />
<br />
==Performance==<br />
*The ray performance depends on distance between camera and molecule.<br />
If the distance is big rendering takes much time. If the distance is too small distant parts of molecule dissolve.<br />
<gallery><br />
Image:Close_ray.png|Too close to molecule<br />
Image:Middle_ray.png|Normal distance<br />
</gallery><br />
* Tip: If you have a rather complicated scene that is zoomed into only a part of the molecule, you can speed up the ray tracing by hiding everything else outside of a certain range of the zoomed-on point. For example, if I have a large molecule and I'm looking only at the 30-atom ligand bound to it, then I can do something like the following:<br />
<source lang="python"><br />
# setup your complex scene<br />
...<br />
<br />
# zoom on the hetero atom (ligand and not water) within 5 Angstroms<br />
select hh, het and not resn HOH<br />
zoom hh, 5<br />
<br />
# turn on depth cueing<br />
set depth_cue, 1<br />
<br />
# now, select stuff to hide; we select everything that is <br />
# farther than 8 Ang from our main selection<br />
select th, (all) and not ( (all) within 8 of hh) )<br />
<br />
hide everything, th<br />
<br />
# any additional commands you want<br />
...<br />
<br />
ray<br />
</source><br />
As an example of the efficacy of this method, I ray traced a rather complex scene with all the atoms visible here's the output of ray:<br />
<source lang="bash"><br />
PyMOL>ray<br />
Ray: render time: 24.50 sec. = 146.9 frames/hour (941.88 sec. accum.).<br />
</source><br />
and here is the result when I soft-clipped everything else using the above method:<br />
<source lang="bash"><br />
PyMOL>ray<br />
Ray: render time: 47.93 sec. = 75.1 frames/hour (989.80 sec. accum.).<br />
</source><br />
The two images in the following gallery show the results of the rendering.<br />
<gallery><br />
Image:Ray_method_off.png|normal ray tracing. This took twice as long to make as the image to the right. Same size, and DPI.<br />
Image:Ray_method_on.png|manually hiding things you won't see anyway. This took 1/2 the time to render as compared to the same sized & DPId image at left.<br />
</gallery><br />
<br />
===Memory===<br />
If memory is an issue for you in PyMOL, try executing your rendering from a script rather than a PyMOL session file. An unfortunate unavoidable consequence of the fact that we use Python's portable, platform-independent "pickle" machinery for PyMOL session files. Packing or unpacking a Session or Scene file thus requires that there be two simultanous copies of the information to reside in RAM simultaneously: one native and a second in Python itself.<br />
<br />
So when memory is a limiting factor, scripts are recommended over sessions.<br />
<br />
==Examples==<br />
===Simple===<br />
<source lang="python"><br />
# ray trace the current scene using the default size of the viewport<br />
ray<br />
</source><br />
<br />
===Specify Image Size===<br />
<source lang="python"><br />
# ray trace the current scene, but scaled to 1024x768 pixels<br />
ray 1024,768<br />
</source><br />
<br />
===Specify Renderer===<br />
<source lang="python"><br />
# ray trace with an external renderer.<br />
ray renderer=0<br />
</source><br />
<br />
===High Quality B&W Rendering===<br />
[[Image:1l9l.png|thumb|center|Black and White (ray_trace_mode,2); click to see full image]]<br />
<source lang="python"><br />
# Black and White Script<br />
load /tmp/3fib.pdb;<br />
show cartoon;<br />
set ray_trace_mode, 2; # black and white cartoon<br />
bg_color white;<br />
set antialias, 2;<br />
ray 600,600<br />
png /tmp/1l9l.png<br />
</source><br />
<br />
===High Quality Color===<br />
[[Image:1l9l_2.png|thumb|center|Color mode (ray_trace_mode,3); click to see full image]]<br />
<source lang="python"><br />
# Color Script<br />
load /tmp/thy_model/1l9l.pdb;<br />
hide lines;<br />
show cartoon;<br />
set ray_trace_mode, 3; # color<br />
bg_color white;<br />
set antialias, 2;<br />
remove resn HOH<br />
remove resn HET<br />
ray 600,600<br />
png /tmp/1l9l.png<br />
</source><br />
<br />
===Ray Tracing Stereo Images===<br />
:''See [[Stereo_Ray]]''<br />
<br />
==See also==<br />
# "help faster" for optimization tips with the builtin renderer. "help povray" for how to use PovRay instead of PyMOL's built-in ray-tracing engine. For high-quality photos, please also see the [[Antialias]] command. [[Ray shadows]] for controlling shadows.<br />
# See also [[Ray Tracing]].<br />
# [http://www.gimp.org/tutorials/Color2BW Desaturation Tutorial] -- A good resource for making nice B&W images from color images (desaturation).<br />
#[[Ray Trace Gain]]<br />
<br />
==User comments==<br />
;How do I ray trace a publication-ready (~300dpi) image using PyMol?<br />
:This answer is in the [[:Category:Advanced_Issues|Advanced Issues]] (Image Manipulation Section).<br />
<br />
[[Category:Commands|Ray]]<br />
[[Category:Publication_Quality|Ray]]<br />
[[Category:Performance|Ray]]<br />
[[Category:Movies|Ray]]</div>Pavelhttps://pymolwiki.org/index.php?title=Stick_transparency&diff=11498Stick transparency2014-01-09T21:33:53Z<p>Pavel: /* Usage */</p>
<hr />
<div>== Overview ==<br />
<br />
The setting "stick_transparency" allows one to set the degree of transparency for stick objects, independent of all other objects. Allowable values range from 0 (fully opaque) to 1 (fully transparent, i.e. invisible).<br />
<br />
==Usage==<br />
<source lang="python"><br />
set stick_transparency, F, objectame<br />
set_bond stick_transparency, F, selection<br />
</source><br />
where '''F''' is a floating point number in the range ''[0.0 - 1.0]'', and '''objectname''' is the object to apply the changes to. If ObjectName is omitted, then the transparency of all stick representations will be changed.<br />
<br />
To apply this setting to a selection, use "set_bond" syntax<br />
<source lang="python"><br />
set_bond stick_transparency, 0.7, */n+c+ca+o<br />
</source><br />
<br />
For the value of ''F''=1.0 sticks will be completely transparent/invisible and for ''F''=0.0 sticks are solid/opaque.<br />
<br />
== Examples ==<br />
<br />
<source lang="python"><br />
set stick_transparency, 0.50 # Makes sticks 50-percent transparent<br />
</source><br />
<br />
Open the images to actually see the details!<br />
<gallery><br />
Image:Stick_trans_zero.png|sticks with no transparency<br />
Image:Stick_trans_50.png|sticks with 0.5 transparency<br />
Image:Stick_trans_90.png|sticks with 0.9 transparency<br />
</gallery><br />
<br />
== Note ==<br />
<br />
Stick transparency works best with "unilayer" transparency (Setting menu > transparency > Unilayer) rather than "multilayer", which leads to odd artifacts where the sticks join.<br />
<br />
<gallery><br />
Image:Stick_trans_50-multi.png|sticks with 0.5 transparency and multilayer transparency<br />
</gallery><br />
<br />
[[Category:Settings|Stick transparency]]<br />
[[Category:Sticks]]</div>Pavelhttps://pymolwiki.org/index.php?title=Cartoon_transparency&diff=11485Cartoon transparency2013-12-02T22:11:11Z<p>Pavel: /* Syntax */</p>
<hr />
<div>== Overview ==<br />
This setting changes the transparency of the cartoon representation.<br />
<br />
== Syntax ==<br />
<source lang="python"><br />
set cartoon_transparency, 0.5, <object> # 50% transparent, the object name is optional<br />
</source><br />
Valid values range from 0.0 - 1.0<br />
<br />
== Examples ==<br />
<gallery><br />
Image:Ctt.png|Cartoon Transparency<br />
</gallery><br />
<br />
== See Also == <br />
[[cartoon]]<br />
<br />
[[Category:Settings|Cartoon transparency]]</div>Pavelhttps://pymolwiki.org/index.php?title=Enable&diff=11393Enable2013-08-28T17:51:36Z<p>Pavel: /* EXAMPLE */</p>
<hr />
<div><br />
'''enable''' enable display of an object and all currently visible representations.<br />
<br />
===USAGE===<br />
enable name<br />
enable all <br />
name = object or selection name<br />
<br />
===PYMOL API===<br />
<source lang="python"><br />
cmd.enable( string object-name )<br />
</source> <br />
<br />
===EXAMPLE===<br />
enable my_object<br />
enable my_object, parents=1<br />
<br />
===SEE ALSO===<br />
[[Show]], [[Hide]], [[Disable]]<br />
<br />
[[Category:Commands|Enable]]<br />
[[Category:View Module|Enable]]</div>Pavelhttps://pymolwiki.org/index.php?title=Key_Wait&diff=11390Key Wait2013-08-15T21:29:19Z<p>Pavel: </p>
<hr />
<div><source lang="python"><br />
#use "spawn spawn_demo.py, local" to invoke this<br />
#python script from within PyMOL<br />
<br />
wait=""<br />
i=0<br />
while i < 12 and wait!="x":<br />
cmd.turn("y", 30)<br />
print "Press enter key to continue or x + enter to terminate"<br />
wait=raw_input()<br />
i=i+1<br />
print "Done"<br />
</source><br />
<br />
''Note: this approach only works when you have a console window open.''<br />
[[Category:Script_Library|Key Wait]]<br />
[[Category:UI_Scripts]]</div>Pavelhttps://pymolwiki.org/index.php?title=Label&diff=11311Label2013-06-27T18:10:47Z<p>Pavel: /* Settings */</p>
<hr />
<div>[[Image:Pl.png|right|500px]]<br />
<br />
The [[Label]] command controls how PyMOL draws text labels for PyMOL objects.<br />
<br />
= Details =<br />
Labeling is important so there are many options for your fine tuning needs. You can change the [[Label_size|label size]], [[Label_color|label color]], positioning, [[Label_font_id|font]], the [[Label_outline_color|label outline color]] that masks the font and much, much more.<br />
<br />
You can have PyMOL label atoms by properties or arbitrary strings as you want; you can even use Unicode fonts for special symbols like, <math>\alpha, \beta, \pm, \textrm{\AA}</math>, etc.<br />
<br />
The following gallery shows some examples of how extensible the [[Label]] command is. <br />
<gallery heights="180px" widths="200px" align="center" perrow="3"><br />
Image:Label_pre.png|Simple label<br />
Image:New_fonts.jpeg|Example showing usage of Unicode fonts for special characters, see [[label_font_id]].<br />
Image:Font_ex.png|Another example with Unicode fonts<br />
Image:Label_ex.png|Example label<br />
Image:Ls0.png|Label shadows turned off<br />
Image:Ls2.png|Label shadows turned on<br />
</gallery><br />
<br />
==Built-in Object Properties==<br />
Aside from arbitrary string labels, like "This is the catalytic residue" for an atom/residue you can also use the following built-in molecular properties:<br />
* '''name''', the atom name<br />
* '''resn''', the residue name<br />
*'''resi''', the residue number/identifier<br />
*'''chain''', the chain name<br />
*'''q''', charge<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 />
You can use one of these properties as:<br />
<source lang="python"><br />
# simple example: label residue 22's atoms with their names<br />
label i. 22, name<br />
<br />
# Label residue #44's alpha carbon with it's residue name, residue number and B-factor.<br />
label n. CA and i. 44, "(%s, %s, %s") % (resn, resi, b)<br />
</source><br />
<br />
See the syntax and examples below for more info.<br />
<br />
=Syntax=<br />
To use the label command follow this syntax:<br />
<source lang="python"><br />
# labeling syntax<br />
label [ selection[, expression]]<br />
</source><br />
where '''selection''' is some object/selection you want to label and '''expression''' is some string (or set of strings) which PyMOL is to use to label the given selection.<br />
<br />
We have plenty of examples. See [[#Examples|the examples]] below.<br />
<br />
=Settings=<br />
Here are all the label settings and their general effect. For each label setting, see the respective web page for more details.<br />
<br />
'''[[label_angle_digits]]'''<br />
:: sets the number of decimals in angle label.<br />
'''[[label_distance_digits]]'''<br />
:: sets the number of decimals in distance label.<br />
'''[[label_shadow_mode]]'''<br />
:: sets whether or not PyMOL will ray trace shadows for your label text. Eg: <source lang="python">set label_shadow_mode, 2</source><br />
'''[[label_color]]'''<br />
:: sets the color of the label text. Note that you can have labels of different colors for different objects or selections. Some examples:<br />
<source lang="python"><br />
# per-object:<br />
set label_color, color-name, object-name #eg, set label-color, magenta, /protein<br />
<br />
# per-atom:<br />
set label_color, color-name, selection #eg, set label-color, marine, /protein/A/A/23/CA<br />
<br />
# another example<br />
fragment arg<br />
label all, name<br />
set label_color, yellow, arg<br />
set label_color, red, elem c<br />
</source><br />
<br />
'''[[label_font_id]]'''<br />
:: sets the font to render your label. There are 12 different fonts from 5&mdash;16. Numbers 15 and 16 are special for unicode. Eg: <source lang="python">set label_font_id, 12</source>. See the [[label_font_id]] page for explicit examples on how to use unicode characters in PyMOL labels.<br />
'''[[label_size]]'''<br />
:: sets the size of the text. You can use positive numbers 2, 3, 4, etc for point sizes, or negative numbers for Angstrom-based sizes. Default is 14 points. Labels in Angstrom-size scale with the distance from the front plane, labels in point-size don't. Eg: <source lang="python">set label_size, -2 #results in a size of 2 Angstroms</source><br />
'''[[label_digits]]'''<br />
:: sets the number of decimals in label. It affects all digits only if label_distance_digits or label_dihedral_digits or label_angle_digits are set to -1.<br />
'''[[label_outline_color]]'''<br />
:: each label is outlined (so you can do white-on-white labels, for example). This options sets the color of the label outline. Eg. <source lang="python">set label_outline_color, orange</source><br />
'''[[label_dihedral_digits]]'''<br />
:: sets the number of decimals in dihedral label.<br />
'''[[label_position]]'''<br />
:: sets any offset from the original X,Y,Z coordinates for the label. If you like to use the mouse, you can enter [[edit_mode]] and '''ctrl-left_click''' to drag labels around; '''ctrl-shift-left_click''' will let you move the labels in the z-direction. '''"Save labels"-workaround''' If you want to save the position of your labels, the best way might be to create a new object and move the atoms in this object. Since the labels are positioned from the atom positions this is an indirect way of moving the labels and being able to save them.<br />
<br />
=Examples=<br />
<source lang="python"><br />
#1.<br />
# make a very simple label on the 14th alpha carbon.<br />
label n. CA and i. 14, "This is carbon 14."<br />
<br />
#2.<br />
# make a fake scene label; use this to label entire scenes, not just atoms/bonds.<br />
pseudoatom foo<br />
label foo, "Once upon a time..."<br />
<br />
#3.<br />
# make a huge label<br />
set label_size, -5<br />
pseudoatom foo<br />
label foo, "This is large text"<br />
<br />
#4. Partial Charge<br />
label (chain A),chain<br />
label (n;ca),"%s-%s" % (resn,resi)<br />
label (resi 200),"%1.3f" % partial_charge<br />
<br />
<br />
#5. The gallery image above Label_ex.png was created with this code<br />
# and finally, some labels were moved around in '''edit_mode'''.<br />
label (resi 200),"%1.3f" % b<br />
set label_font_id, 10<br />
set label_size, 10<br />
<br />
#6. This example shows how to label a selection with the <br />
# XYZ coordinates of the atoms <br />
from pymol import stored<br />
stored.pos = []<br />
# select the carbon atoms in my hetero atoms to label<br />
select nn, het and e. C<br />
# get the XYZ coordinates and put htem into stored.pos<br />
iterate_state 1, (nn), stored.pos.append((x,y,z))<br />
# label all N atoms. You need the pop() function or else<br />
# PyMOL will complain b/c you didn't provide enough coords.<br />
label nn, ("%5.5s, %5.5s, %5.5s") % stored.pos.pop()<br />
</source><br />
<br />
= User Comments =<br />
==Labels Using ID Numbers==<br />
The following commnent,<br />
<source lang="python"><br />
label SELECTION, " %s" % ID <br />
</source><br />
labels the SELECTION with atom ID numbers.<br />
<br />
You can make more complicated selections/lables such as<br />
<source lang="python"><br />
label SELECTION, " %s:%s %s" % (resi, resn, name)<br />
</source><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 />
<source lang="python"><br />
label n. ca, resn<br />
</source><br />
use:<br />
<source lang="python"><br />
label n. ca, one_letter[resn]<br />
</source><br />
or: ( to get something like D85)<br />
<source lang="python"><br />
label n. ca, "%s%s" %(one_letter[resn],resi)<br />
</source><br />
<br />
==Labels and defer_builds_mode==<br />
If You have a weak video card, You might want to set<br />
<source lang="python"><br />
set defer_builds_mode, 5<br />
</source><br />
It helps a lot but breaks labels rendering. You can use<br />
<source lang="python"><br />
set defer_builds_mode, 4<br />
</source><br />
instead.<br />
<br />
=See Also=<br />
[[:Category:Labeling]]<br />
<br />
All the settings posted above.<br />
<br />
[[Category:Labeling|Label]]<br />
[[Category:Commands|Label]]</div>Pavelhttps://pymolwiki.org/index.php?title=Advanced_Scripting&diff=11231Advanced Scripting2013-05-08T20:47:23Z<p>Pavel: /* More Complex Unpacking */</p>
<hr />
<div>On this page, we discuss more complex scripting. Python is great, but it is much slower at mathematics than C/C++/Java/FORTRAN. For that reason, you may find it more useful to export your data to another language, operate on it there and then import the results back into PyMOL. We discuss the Python API and the general operating procedure for successfully writing your own scripts.<br />
<br />
= Advanced Scripting =<br />
Python while incredibly useful, is much slower at math than some other strictly typed languages and sometimes we have libraries built in other languages. It's faster, for complicated problems to package your data, send it to C, do some math, and pass the results back to Python than to just do everything in Python. The beauty of the Python API, is that we can do just that.<br />
<br />
This is more advanced scripting, and requires some knowledge of the [http://docs.python.org/api/api.html Python API], and some outside language. The example shown here is in C. The C++ extensions are very similar.<br />
<br />
<br />
=== Python, PyMOL and C ===<br />
Here, I will show you how to write a C-module that plugs into Python and talks nicely with PyMOL. The example actually shows how to make a generic C-function and use it in Python.<br />
<br />
First, let's assume that we want to call a function, let's call it '''funName'''. Let's assume '''funName''' will take a Python list of lists and return a list---for example passing the C++ program the XYZ coordinates of each atom, and returning a list of certain atoms with some property. I will also assume we have '''funName.h''' and '''funName.c''' for C code files. I have provided this, a more complex example, to show a real-world problem. If you were just sending an integer or float instead of packaged lists, the code is simpler; if you understand unpacking the lists then you'll certainly understand unpacking a simple scalar.<br />
<br />
===== C++ =====<br />
If you tell Python that you're using C++ code (see the setup below) then it'll automatically call the C++ compiler instead of the C compiler. There are [http://docs.python.org/ext/cplusplus.html warnings] you may want to be aware of though.<br />
<br />
My experience with this has been pretty easy. I simple renamed my ".c" files to ".cpp", caught the few errors (darn it, I didn't typecast a few pointers from malloc) and the code compiled fine. My experience with this is also quite limited, YMMV.<br />
<br />
==== Calling the External Function ====<br />
So, to start, let's look at the Python code that will call the C-function:<br />
<source lang="python"><br />
#<br />
# -- in someCode.py<br />
#<br />
# Call funName. Pass it a list () of lists. (sel1 and sel2 are lists.)<br />
# Get the return value into rValFromC.<br />
#<br />
rValFromC = funName( (sel1, sel2) );<br />
</source><br />
where '''sel1''' and '''sel2''' could be any list of atom coordinates, say, from PyMOL. (See above.)<br />
<br />
Ok, this isn't hard. Now, we need to see what the code that receives this function call in C, looks like. Well, first we need to let C know we're integrating with Python. So, in your [http://docs.python.org/api/includes.html header file] of '''funName.h''' we put:<br />
<source lang="c"><br />
// in funName.h<br />
#include <Python.h><br />
</source><br />
<br />
Next, by default your C-function's name is '''funName_funName''' (and that needs to be setup, I'll show how, later). So, let's define funName:<br />
<source lang="c"><br />
static PyObject*<br />
funName_funName(PyObject* self, PyObject* args)<br />
{<br />
...more code...<br />
</source><br />
This is the generic call. '''funName''' is taking two pointers to [http://docs.python.org/api/common-structs.html PyObjects]. It also returns a PyObject. This is how you get the Python data into and out of C. It shows up in "[http://docs.python.org/api/arg-parsing.html args]" array of packaged Python objects and we then unpack it into C, using some [http://docs.python.org/api/arg-parsing.html helper methods]. Upon completion of unpacking, we perform our C/C++ procedure with the data, package up the results using the [http://docs.python.org/api/api.html Python API], and send the results back to Python/PyMOL.<br />
<br />
==== Unpacking the Data ====<br />
Let's unpack the data in '''args'''. Remember, '''args''' has a Python [http://docs.python.org/lib/typesseq.html list of lists]. So, to unpack that we do the following inside of funName:<br />
<br />
<source lang="c"><br />
static PyObject*<br />
funName_funName(PyObject* self, PyObject* args)<br />
{<br />
PyObject *listA, *listB;<br />
<br />
if ( ! PyArg_ParseTuple(args, "(OO)", &listA, &listB) ) {<br />
printf("Could not unparse objects\n");<br />
return NULL;<br />
}<br />
<br />
// let Python know we made two lists<br />
Py_INCREF(listA);<br />
Py_INCREF(listB);<br />
... more code ...<br />
</source><br />
<br />
Line 4 creates the two C objects that we will unpack the lists into. They are pointers to PyObjects.<br />
Line 6 is where the magic happens. We call, '''[http://docs.python.org/api/arg-parsing.html PyArg_ParseTuple]''' passing it the args we got from Python. The '''(OO)''' is Python's code for ''I'm expecting two <u>O</u>bjects inside a list <u>()</u>''. Were it three objects, then '''(OOO)'''. The first object will be put into '''&listA''' and the second into '''&listB'''. The exact [http://docs.python.org/api/arg-parsing.html argument building specifications] are very useful.<br />
<br />
==== Reference Counting ====<br />
Next, we check for success. Unpacking could fail. If it does, complain and quit. Else, '''listA''' and '''listB''' now have data in them. To avoid memory leaks we need to [http://docs.python.org/api/countingRefs.html manually keep track of PyObjects] we're tooling around with. That is, I can create PyObjects in C (being sneaky and not telling Python) and then when Python quits later on, it'll not know it was supposed to clean up after those objects (making a leak). To, we let Python know about each list with '''Py_INCREF(listA)''' and '''Py_INCREF(listB)'''. This is [http://docs.python.org/api/countingRefs.html reference counting].<br />
<br />
Now, just for safety, let's check the lists to make sure they actually were passed something. A tricky user could have given us empty lists, looking to hose the program. So, we do:<br />
<source lang="c"><br />
// handle empty selections (should probably do this in Python, it's easier)<br />
const int lenA = PyList_Size(listA);<br />
if ( lenA < 1 ) {<br />
printf("ERROR: First selection didn't have any atoms. Please check your selection.\n");<br />
// let Python remove the lists<br />
Py_DECREF(listA);<br />
Py_DECREF(listB);<br />
return NULL;<br />
}<br />
</source><br />
We check the list size with, '''[http://docs.python.org/api/listObjects.html PyList_Size]''' and if it's 0 -- we quit. But, before quitting we give control of the lists back to Python so it can clean up after itself. We do that with '''Py_DECREF'''.<br />
<br />
==== More Complex Unpacking ====<br />
If you're dealing with simple scalars, then you might be able to skip this portion.<br />
<br />
Now, we should have access to the data the user sent us, in '''listA''' and '''listB,''' and it should be there and be clean. But, not forgetting that '''listA''' and '''listB''' are list of 3D coordinates, let's unpack them further into sets of coordinates. Because we know the length of the lists, we can do something like the following:<br />
<br />
<source lang="c"><br />
// make space for the current coords; pcePoint is just a float[3]<br />
pcePoint coords = (pcePoint) malloc(sizeof(cePoint)*length);<br />
<br />
// loop through the arguments, pulling out the<br />
// XYZ coordinates.<br />
int i;<br />
for ( i = 0; i < length; i++ ) {<br />
PyObject* curCoord = PyList_GetItem(listA,i);<br />
Py_INCREF(curCoord);<br />
<br />
PyObject* curVal = PyList_GetItem(curCoord,0);<br />
Py_INCREF(curVal);<br />
coords[i].x = PyFloat_AsDouble(curVal);<br />
Py_DECREF(curVal);<br />
<br />
curVal = PyList_GetItem(curCoord,1);<br />
Py_INCREF(curVal);<br />
coords[i].y = PyFloat_AsDouble(curVal);<br />
Py_DECREF(curVal);<br />
<br />
curVal = PyList_GetItem(curCoord,2);<br />
Py_INCREF(curVal);<br />
coords[i].z = PyFloat_AsDouble(curVal);<br />
Py_DECREF(curVal);<br />
<br />
Py_DECREF(curCoord);<br />
}<br />
<br />
... more code ...<br />
</source><br />
<br />
Where, '''pcePoint''' is just a float[3]. Line 2 just gets some memory ready for the 3xlenght list of coordinates. Then, for each item for 1..length, we unpack the list using '''[http://docs.python.org/api/listObjects.html PyList_GetItem]''', into '''curCoord'''. This then gets further unpacked into the float[3], '''coords'''.<br />
<br />
We now have the data in C++/C data structures that the user passed from PyMOL. Now, perform your task in C/C++ and then return the data to PyMOL.<br />
<br />
=== Sending the Results back to Python/PyMOL ===<br />
Once you're done with your calculations and want to send your data back to PyMOL, you need to package it up into a Python object, using the Python API, and then return it. You should be aware of the expected return value and how you're packaging the results. If you user calls,<br />
<source lang="python"><br />
(results1,results2) = someCFunction(parameters1,parameters2)<br />
</source><br />
then you need to package a list with two values. To build values for returning to PyMOL, use '''[http://www.python.org/doc/1.5.2p2/ext/buildValue.html Py_BuildValue]'''. Py_BuildValue takes a string indicating the type, and then a list of values. [http://docs.python.org/ext/buildValue.html Building values] for return has been documented very well. Consider an example: if I want to package an array of integers, the type specifier for two ints for Py_BuildValue is, "[i,i]", so my call could be:<br />
<source lang="c"><br />
# Package the two ints into a Python pair of ints.<br />
PyObject* thePair = Py_BuildValue( "[i,i]", int1, in2 );<br />
<br />
# Don't forget to tell Python about the object.<br />
Py_INCREF(thePair);<br />
</source><br />
<br />
If you need to make a list of things to return, you iterate through a list and make a bunch of '''thePairs''' and add them to a Python list as follows:<br />
<source lang="c"><br />
# Make the python list<br />
PyObject* theList = PyList_New(0);<br />
# Tell Python about it<br />
Py_INCREF(theList);<br />
<br />
for ( int i = 0; i < someLim; i++ ) {<br />
PyObject* thePair = Py_BuildValue( "[i,i]", int1, in2 );<br />
Py_INCREF(thePair);<br />
PyList_Append(theList,thePair);<br />
</source><br />
To add a list of lists, just make an outer list, <source lang="c">PyObject* outerList = PyList_New(0);</source> and iteratively add to it your inner lists:<br />
<source lang="c"><br />
PyObject* outerList = PyList_New(0);<br />
Py_INCREF(outerList);<br />
<br />
for ( int i = 0; i < someLim; i++ ) {<br />
// make the inner list, called curList;<br />
curList = PyObject* curList = PyList_New(0);<br />
Py_INCREF(curList);<br />
<br />
// fill the inner list, using PyList_Append with some data, shown above<br />
...<br />
<br />
PyList_Append(outerList,curList);<br />
</source><br />
<br />
Great, now we can extract data from Python, use it in C/C++, and package it back up for returning to Python. Now, we need to learn about the minimal baggage needed for C to operate with Python. Keep reading; almost done.<br />
<br />
=== Initialization ===<br />
We need to discuss how our functions will be called from Python. First, we need to create a [http://docs.python.org/ext/methodTable.html method table].<br />
<source lang="c"><br />
static PyMethodDef CEMethods[] = {<br />
{"ccealign", ccealign_ccealign, METH_VARARGS, "Align two proteins using the CE Algorithm."},<br />
{NULL, NULL, 0, NULL} /* Always use this as the last line in your table. */<br />
};<br />
</source><br />
'''[http://docs.python.org/ext/methodTable.html METH_VARARGS]''' can also be '''METH_KEYWORDS''', where the former tells C that it should expect a simple tuple or list which we will unpack with '''PyArg_ParseTuple''', and the latter tells C that it should expect to unpack the variables by name<br />
with the '''PyArg_ParseTupleAndKeywords'''. When using '''METH_KEYWORDS''' your function needs to accept a third parameter, a '''Py_Object*''' that is the dictionary of names for unpacking. For more information check out the [http://docs.python.org/ext/methodTable.html Python method table docs].<br />
<br />
Each module undergoes initialization. By default the modules initialization function is: '''initNAME()'''. So, in our example above, '''initccealign()". During this initialization step, we need to call [http://docs.python.org/ext/methodTable.html Py_InitModule]. For or above example, we'd have,<br />
<source lang="c"><br />
PyMODINIT_FUNC<br />
initccealign(void)<br />
{<br />
(void) Py_InitModule("ccealign", CEMethods);<br />
}<br />
</source><br />
<br />
Finally, the main function that starts the whole shebang should look something like:<br />
<source lang="c"><br />
int<br />
main(int argc, char* argv[])<br />
{<br />
Py_SetProgramName(argv[0]);<br />
Py_Initialize();<br />
initccealign();<br />
return(EXIT_SUCCESS);<br />
}<br />
</source><br />
<br />
At this point, you should have a fully functioning program in C/C++ intergrated with PyMOL/Python.<br />
<br />
=== Installing Your Module ===<br />
==== Overview ====<br />
The [http://www.python.org/doc/2.2.3/ext/distributing.html Python distutils pacakge] is a great method for distributing your modules over various platforms. It handles platform specific issues as well as simplifying the overall install process. For us, those module-builders, we need to create the distuils' setup.py script, and given the above -- that's the last step.<br />
<br />
More detailed information can be found one the Python documentation page for [http://docs.python.org/ext/building.html installing C/C++ modules]. There is also information on [http://www.python.org/doc/2.2.3/ext/distributing.html how to build source and binary distribution packages]. <br />
<br />
For example of how powerful disutils is, I have [cealign] setup to install as simply as:<br />
<source lang="bash"><br />
python setup.py build cealign<br />
python setup.py install cealign<br />
</source><br />
<br />
PyMOL also uses distutils for it's source-install. If more people understood distutils, I think they would install PyMOL from source since you get all the latest features.<br />
<br />
==== Setup.py ====<br />
The setup file needs to know the following (at the very least): what source files comprise the project, what include directories to scan, the project name. You can also add more metadata such as version number, author, author_email, url, etc. For this example, let's assume we have the following directory structure,<br />
<source lang="bash"><br />
.<br />
|-- build<br />
|-- dist<br />
|-- doc<br />
| `-- funName<br />
|-- src<br />
| |-- etc<br />
| | `-- tnt<br />
| | |-- doxygen<br />
| | | `-- html<br />
| | `-- html<br />
| `-- tnt<br />
</source><br />
and we want to include all the ''.cpp'' files from the '''src''' directory, and all the include files in '''tnt'''. We start setup.py as follows,<br />
<source lang="python"><br />
#<br />
# -- setup.py -- your module's install file<br />
#<br />
<br />
# import distutils<br />
from distutils.core import setup, Extension<br />
# for pasting together file lists<br />
from glob import glob<br />
# for handling path names in a os independent way<br />
from os.path import join;<br />
<br />
# grab all of the .h and .cpp files in src/ and src/tnt<br />
srcList = [ x for x in glob(join("src", "*.cpp")) ]<br />
# set the include directories<br />
incDirs = [ join( "src", "tnt") ]<br />
</source><br />
<br />
Ok, now Python knows which files to include. Now we need to create a new [http://docs.python.org/dist/module-distutils.extension.html Extension]. We can simply call,<br />
<source lang="python"><br />
# create the extension given the function name, ''funName,'' the souce list and include directories.<br />
ccealignMods = Extension( 'funName', sources=srcList, include_dirs=incDirs )<br />
</source><br />
<br />
Lastly, all we have to do is call the final setup function, with the extension we just created and some metadata (if we want):<br />
<source lang="python"><br />
setup( name="funName",<br />
version="0.1-alpha",<br />
description="funName: A simple example to show users how to make C/C++ modules for PyMOL",<br />
author="Your Name Here",<br />
author_email="Your Email Goes Here",<br />
url="The URL of your work",<br />
ext_modules=[ccealignMods]<br />
)<br />
</source><br />
<br />
And voila -- we're done. The users should now be able to execute,<br />
<source lang="bash"><br />
python setup.py build<br />
# remove the brackets if you need to be root to install, see [Linux_Install#Installing_a_Script_Without_Superuser_Access Installing PyMOL w/o Superuser access] for an example.<br />
[sudo] python setup.py install<br />
</source><br />
<br />
== Notes ==<br />
* discuss the pains of debugging<br />
<br />
== Conclusion ==<br />
I hope you found this helpful and will spur you to actually write some PyMOL modules or help you overcome the speed limitations inherent in Python's math (in comparison to other strictly-typed languages).<br />
<br />
I'm happy to hear any comments or questions you may have. [[User:Inchoate|Tree]] 09:14, 19 May 2008 (CDT)<br />
<br />
== Example ==<br />
See the source code for [[cealign]].<br />
<br />
<br />
== See Also ==<br />
[[stored]], [[iterate_state]], [[identify]].<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
[[Category:Scripting|Advanced_Scripting]]<br />
[[Category:Development|Advanced_Scripting]]<br />
[[Category:Tutorials|Advanced_Scripting]]</div>Pavelhttps://pymolwiki.org/index.php?title=Advanced_Scripting&diff=11230Advanced Scripting2013-05-08T20:46:44Z<p>Pavel: /* Unpacking the Data */</p>
<hr />
<div>On this page, we discuss more complex scripting. Python is great, but it is much slower at mathematics than C/C++/Java/FORTRAN. For that reason, you may find it more useful to export your data to another language, operate on it there and then import the results back into PyMOL. We discuss the Python API and the general operating procedure for successfully writing your own scripts.<br />
<br />
= Advanced Scripting =<br />
Python while incredibly useful, is much slower at math than some other strictly typed languages and sometimes we have libraries built in other languages. It's faster, for complicated problems to package your data, send it to C, do some math, and pass the results back to Python than to just do everything in Python. The beauty of the Python API, is that we can do just that.<br />
<br />
This is more advanced scripting, and requires some knowledge of the [http://docs.python.org/api/api.html Python API], and some outside language. The example shown here is in C. The C++ extensions are very similar.<br />
<br />
<br />
=== Python, PyMOL and C ===<br />
Here, I will show you how to write a C-module that plugs into Python and talks nicely with PyMOL. The example actually shows how to make a generic C-function and use it in Python.<br />
<br />
First, let's assume that we want to call a function, let's call it '''funName'''. Let's assume '''funName''' will take a Python list of lists and return a list---for example passing the C++ program the XYZ coordinates of each atom, and returning a list of certain atoms with some property. I will also assume we have '''funName.h''' and '''funName.c''' for C code files. I have provided this, a more complex example, to show a real-world problem. If you were just sending an integer or float instead of packaged lists, the code is simpler; if you understand unpacking the lists then you'll certainly understand unpacking a simple scalar.<br />
<br />
===== C++ =====<br />
If you tell Python that you're using C++ code (see the setup below) then it'll automatically call the C++ compiler instead of the C compiler. There are [http://docs.python.org/ext/cplusplus.html warnings] you may want to be aware of though.<br />
<br />
My experience with this has been pretty easy. I simple renamed my ".c" files to ".cpp", caught the few errors (darn it, I didn't typecast a few pointers from malloc) and the code compiled fine. My experience with this is also quite limited, YMMV.<br />
<br />
==== Calling the External Function ====<br />
So, to start, let's look at the Python code that will call the C-function:<br />
<source lang="python"><br />
#<br />
# -- in someCode.py<br />
#<br />
# Call funName. Pass it a list () of lists. (sel1 and sel2 are lists.)<br />
# Get the return value into rValFromC.<br />
#<br />
rValFromC = funName( (sel1, sel2) );<br />
</source><br />
where '''sel1''' and '''sel2''' could be any list of atom coordinates, say, from PyMOL. (See above.)<br />
<br />
Ok, this isn't hard. Now, we need to see what the code that receives this function call in C, looks like. Well, first we need to let C know we're integrating with Python. So, in your [http://docs.python.org/api/includes.html header file] of '''funName.h''' we put:<br />
<source lang="c"><br />
// in funName.h<br />
#include <Python.h><br />
</source><br />
<br />
Next, by default your C-function's name is '''funName_funName''' (and that needs to be setup, I'll show how, later). So, let's define funName:<br />
<source lang="c"><br />
static PyObject*<br />
funName_funName(PyObject* self, PyObject* args)<br />
{<br />
...more code...<br />
</source><br />
This is the generic call. '''funName''' is taking two pointers to [http://docs.python.org/api/common-structs.html PyObjects]. It also returns a PyObject. This is how you get the Python data into and out of C. It shows up in "[http://docs.python.org/api/arg-parsing.html args]" array of packaged Python objects and we then unpack it into C, using some [http://docs.python.org/api/arg-parsing.html helper methods]. Upon completion of unpacking, we perform our C/C++ procedure with the data, package up the results using the [http://docs.python.org/api/api.html Python API], and send the results back to Python/PyMOL.<br />
<br />
==== Unpacking the Data ====<br />
Let's unpack the data in '''args'''. Remember, '''args''' has a Python [http://docs.python.org/lib/typesseq.html list of lists]. So, to unpack that we do the following inside of funName:<br />
<br />
<source lang="c"><br />
static PyObject*<br />
funName_funName(PyObject* self, PyObject* args)<br />
{<br />
PyObject *listA, *listB;<br />
<br />
if ( ! PyArg_ParseTuple(args, "(OO)", &listA, &listB) ) {<br />
printf("Could not unparse objects\n");<br />
return NULL;<br />
}<br />
<br />
// let Python know we made two lists<br />
Py_INCREF(listA);<br />
Py_INCREF(listB);<br />
... more code ...<br />
</source><br />
<br />
Line 4 creates the two C objects that we will unpack the lists into. They are pointers to PyObjects.<br />
Line 6 is where the magic happens. We call, '''[http://docs.python.org/api/arg-parsing.html PyArg_ParseTuple]''' passing it the args we got from Python. The '''(OO)''' is Python's code for ''I'm expecting two <u>O</u>bjects inside a list <u>()</u>''. Were it three objects, then '''(OOO)'''. The first object will be put into '''&listA''' and the second into '''&listB'''. The exact [http://docs.python.org/api/arg-parsing.html argument building specifications] are very useful.<br />
<br />
==== Reference Counting ====<br />
Next, we check for success. Unpacking could fail. If it does, complain and quit. Else, '''listA''' and '''listB''' now have data in them. To avoid memory leaks we need to [http://docs.python.org/api/countingRefs.html manually keep track of PyObjects] we're tooling around with. That is, I can create PyObjects in C (being sneaky and not telling Python) and then when Python quits later on, it'll not know it was supposed to clean up after those objects (making a leak). To, we let Python know about each list with '''Py_INCREF(listA)''' and '''Py_INCREF(listB)'''. This is [http://docs.python.org/api/countingRefs.html reference counting].<br />
<br />
Now, just for safety, let's check the lists to make sure they actually were passed something. A tricky user could have given us empty lists, looking to hose the program. So, we do:<br />
<source lang="c"><br />
// handle empty selections (should probably do this in Python, it's easier)<br />
const int lenA = PyList_Size(listA);<br />
if ( lenA < 1 ) {<br />
printf("ERROR: First selection didn't have any atoms. Please check your selection.\n");<br />
// let Python remove the lists<br />
Py_DECREF(listA);<br />
Py_DECREF(listB);<br />
return NULL;<br />
}<br />
</source><br />
We check the list size with, '''[http://docs.python.org/api/listObjects.html PyList_Size]''' and if it's 0 -- we quit. But, before quitting we give control of the lists back to Python so it can clean up after itself. We do that with '''Py_DECREF'''.<br />
<br />
==== More Complex Unpacking ====<br />
If you're dealing with simple scalars, then you might be able to skip this portion.<br />
<br />
Now, we should have access to the data the user sent us, in '''listA''' and '''listB,''' and it should be there and be clean. But, not forgetting that '''listA''' and '''listB''' are list of 3D coordinates, let's unpack them further into sets of coordinates. Because we know the length of the lists, we can do something like the following:<br />
<source lang="c" line="1"><br />
// make space for the current coords; pcePoint is just a float[3]<br />
pcePoint coords = (pcePoint) malloc(sizeof(cePoint)*length);<br />
<br />
// loop through the arguments, pulling out the<br />
// XYZ coordinates.<br />
int i;<br />
for ( i = 0; i < length; i++ ) {<br />
PyObject* curCoord = PyList_GetItem(listA,i);<br />
Py_INCREF(curCoord);<br />
<br />
PyObject* curVal = PyList_GetItem(curCoord,0);<br />
Py_INCREF(curVal);<br />
coords[i].x = PyFloat_AsDouble(curVal);<br />
Py_DECREF(curVal);<br />
<br />
curVal = PyList_GetItem(curCoord,1);<br />
Py_INCREF(curVal);<br />
coords[i].y = PyFloat_AsDouble(curVal);<br />
Py_DECREF(curVal);<br />
<br />
curVal = PyList_GetItem(curCoord,2);<br />
Py_INCREF(curVal);<br />
coords[i].z = PyFloat_AsDouble(curVal);<br />
Py_DECREF(curVal);<br />
<br />
Py_DECREF(curCoord);<br />
}<br />
<br />
... more code ...<br />
</source><br />
Where, '''pcePoint''' is just a float[3]. Line 2 just gets some memory ready for the 3xlenght list of coordinates. Then, for each item for 1..length, we unpack the list using '''[http://docs.python.org/api/listObjects.html PyList_GetItem]''', into '''curCoord'''. This then gets further unpacked into the float[3], '''coords'''.<br />
<br />
We now have the data in C++/C data structures that the user passed from PyMOL. Now, perform your task in C/C++ and then return the data to PyMOL.<br />
<br />
=== Sending the Results back to Python/PyMOL ===<br />
Once you're done with your calculations and want to send your data back to PyMOL, you need to package it up into a Python object, using the Python API, and then return it. You should be aware of the expected return value and how you're packaging the results. If you user calls,<br />
<source lang="python"><br />
(results1,results2) = someCFunction(parameters1,parameters2)<br />
</source><br />
then you need to package a list with two values. To build values for returning to PyMOL, use '''[http://www.python.org/doc/1.5.2p2/ext/buildValue.html Py_BuildValue]'''. Py_BuildValue takes a string indicating the type, and then a list of values. [http://docs.python.org/ext/buildValue.html Building values] for return has been documented very well. Consider an example: if I want to package an array of integers, the type specifier for two ints for Py_BuildValue is, "[i,i]", so my call could be:<br />
<source lang="c"><br />
# Package the two ints into a Python pair of ints.<br />
PyObject* thePair = Py_BuildValue( "[i,i]", int1, in2 );<br />
<br />
# Don't forget to tell Python about the object.<br />
Py_INCREF(thePair);<br />
</source><br />
<br />
If you need to make a list of things to return, you iterate through a list and make a bunch of '''thePairs''' and add them to a Python list as follows:<br />
<source lang="c"><br />
# Make the python list<br />
PyObject* theList = PyList_New(0);<br />
# Tell Python about it<br />
Py_INCREF(theList);<br />
<br />
for ( int i = 0; i < someLim; i++ ) {<br />
PyObject* thePair = Py_BuildValue( "[i,i]", int1, in2 );<br />
Py_INCREF(thePair);<br />
PyList_Append(theList,thePair);<br />
</source><br />
To add a list of lists, just make an outer list, <source lang="c">PyObject* outerList = PyList_New(0);</source> and iteratively add to it your inner lists:<br />
<source lang="c"><br />
PyObject* outerList = PyList_New(0);<br />
Py_INCREF(outerList);<br />
<br />
for ( int i = 0; i < someLim; i++ ) {<br />
// make the inner list, called curList;<br />
curList = PyObject* curList = PyList_New(0);<br />
Py_INCREF(curList);<br />
<br />
// fill the inner list, using PyList_Append with some data, shown above<br />
...<br />
<br />
PyList_Append(outerList,curList);<br />
</source><br />
<br />
Great, now we can extract data from Python, use it in C/C++, and package it back up for returning to Python. Now, we need to learn about the minimal baggage needed for C to operate with Python. Keep reading; almost done.<br />
<br />
=== Initialization ===<br />
We need to discuss how our functions will be called from Python. First, we need to create a [http://docs.python.org/ext/methodTable.html method table].<br />
<source lang="c"><br />
static PyMethodDef CEMethods[] = {<br />
{"ccealign", ccealign_ccealign, METH_VARARGS, "Align two proteins using the CE Algorithm."},<br />
{NULL, NULL, 0, NULL} /* Always use this as the last line in your table. */<br />
};<br />
</source><br />
'''[http://docs.python.org/ext/methodTable.html METH_VARARGS]''' can also be '''METH_KEYWORDS''', where the former tells C that it should expect a simple tuple or list which we will unpack with '''PyArg_ParseTuple''', and the latter tells C that it should expect to unpack the variables by name<br />
with the '''PyArg_ParseTupleAndKeywords'''. When using '''METH_KEYWORDS''' your function needs to accept a third parameter, a '''Py_Object*''' that is the dictionary of names for unpacking. For more information check out the [http://docs.python.org/ext/methodTable.html Python method table docs].<br />
<br />
Each module undergoes initialization. By default the modules initialization function is: '''initNAME()'''. So, in our example above, '''initccealign()". During this initialization step, we need to call [http://docs.python.org/ext/methodTable.html Py_InitModule]. For or above example, we'd have,<br />
<source lang="c"><br />
PyMODINIT_FUNC<br />
initccealign(void)<br />
{<br />
(void) Py_InitModule("ccealign", CEMethods);<br />
}<br />
</source><br />
<br />
Finally, the main function that starts the whole shebang should look something like:<br />
<source lang="c"><br />
int<br />
main(int argc, char* argv[])<br />
{<br />
Py_SetProgramName(argv[0]);<br />
Py_Initialize();<br />
initccealign();<br />
return(EXIT_SUCCESS);<br />
}<br />
</source><br />
<br />
At this point, you should have a fully functioning program in C/C++ intergrated with PyMOL/Python.<br />
<br />
=== Installing Your Module ===<br />
==== Overview ====<br />
The [http://www.python.org/doc/2.2.3/ext/distributing.html Python distutils pacakge] is a great method for distributing your modules over various platforms. It handles platform specific issues as well as simplifying the overall install process. For us, those module-builders, we need to create the distuils' setup.py script, and given the above -- that's the last step.<br />
<br />
More detailed information can be found one the Python documentation page for [http://docs.python.org/ext/building.html installing C/C++ modules]. There is also information on [http://www.python.org/doc/2.2.3/ext/distributing.html how to build source and binary distribution packages]. <br />
<br />
For example of how powerful disutils is, I have [cealign] setup to install as simply as:<br />
<source lang="bash"><br />
python setup.py build cealign<br />
python setup.py install cealign<br />
</source><br />
<br />
PyMOL also uses distutils for it's source-install. If more people understood distutils, I think they would install PyMOL from source since you get all the latest features.<br />
<br />
==== Setup.py ====<br />
The setup file needs to know the following (at the very least): what source files comprise the project, what include directories to scan, the project name. You can also add more metadata such as version number, author, author_email, url, etc. For this example, let's assume we have the following directory structure,<br />
<source lang="bash"><br />
.<br />
|-- build<br />
|-- dist<br />
|-- doc<br />
| `-- funName<br />
|-- src<br />
| |-- etc<br />
| | `-- tnt<br />
| | |-- doxygen<br />
| | | `-- html<br />
| | `-- html<br />
| `-- tnt<br />
</source><br />
and we want to include all the ''.cpp'' files from the '''src''' directory, and all the include files in '''tnt'''. We start setup.py as follows,<br />
<source lang="python"><br />
#<br />
# -- setup.py -- your module's install file<br />
#<br />
<br />
# import distutils<br />
from distutils.core import setup, Extension<br />
# for pasting together file lists<br />
from glob import glob<br />
# for handling path names in a os independent way<br />
from os.path import join;<br />
<br />
# grab all of the .h and .cpp files in src/ and src/tnt<br />
srcList = [ x for x in glob(join("src", "*.cpp")) ]<br />
# set the include directories<br />
incDirs = [ join( "src", "tnt") ]<br />
</source><br />
<br />
Ok, now Python knows which files to include. Now we need to create a new [http://docs.python.org/dist/module-distutils.extension.html Extension]. We can simply call,<br />
<source lang="python"><br />
# create the extension given the function name, ''funName,'' the souce list and include directories.<br />
ccealignMods = Extension( 'funName', sources=srcList, include_dirs=incDirs )<br />
</source><br />
<br />
Lastly, all we have to do is call the final setup function, with the extension we just created and some metadata (if we want):<br />
<source lang="python"><br />
setup( name="funName",<br />
version="0.1-alpha",<br />
description="funName: A simple example to show users how to make C/C++ modules for PyMOL",<br />
author="Your Name Here",<br />
author_email="Your Email Goes Here",<br />
url="The URL of your work",<br />
ext_modules=[ccealignMods]<br />
)<br />
</source><br />
<br />
And voila -- we're done. The users should now be able to execute,<br />
<source lang="bash"><br />
python setup.py build<br />
# remove the brackets if you need to be root to install, see [Linux_Install#Installing_a_Script_Without_Superuser_Access Installing PyMOL w/o Superuser access] for an example.<br />
[sudo] python setup.py install<br />
</source><br />
<br />
== Notes ==<br />
* discuss the pains of debugging<br />
<br />
== Conclusion ==<br />
I hope you found this helpful and will spur you to actually write some PyMOL modules or help you overcome the speed limitations inherent in Python's math (in comparison to other strictly-typed languages).<br />
<br />
I'm happy to hear any comments or questions you may have. [[User:Inchoate|Tree]] 09:14, 19 May 2008 (CDT)<br />
<br />
== Example ==<br />
See the source code for [[cealign]].<br />
<br />
<br />
== See Also ==<br />
[[stored]], [[iterate_state]], [[identify]].<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
[[Category:Scripting|Advanced_Scripting]]<br />
[[Category:Development|Advanced_Scripting]]<br />
[[Category:Tutorials|Advanced_Scripting]]</div>Pavel