Dear PyMOLers,
I've revised the B-factor colouring script that I published on this list
back on May 24th. The function now allows you to choose the style of
colour ramp (blue-magenta-red or rainbow), the way in which the B-value
ranges are chosen (histogram or smooth ramp) plus the number of colours
to use (nbins). I include it here as an attachment. The documentation at
the top of the file says:
USAGE
color_b(selection='sel',ramp=0 or 1, rainbow=0 or 1, nbins=10)
or
color_b selection='sel',ramp=0 or 1, rainbow=0 or 1, nbins=10
This function allows coloring of a selection as a function of B-value,
either in a range of hues from blue through magenta to red (rainbow=0,
the default) or in the colors of the rainbow (rainbow=1). The division
of B-value ranges can either be as a histogram (equal-sized B-value
increments leading to unequal numbers of atoms in each bin: ramp=0)
or as a ramp of B-value ranges with an equal number of atoms in each
group (ramp=1).
The module must first be imported into PyMOL, either by including it
in the contrib.py module in the modules/pymol directory of your pymol
distribution, or by importing it from another directory or by using the
"run color_b.py" command. If you then just say "color_b", it will color
all of your molecular objects with ten colors ranging from blue to red
(via magenta).
Because I included the line:
cmd.extend("color_b",color_b)
Then you don't need the parentheses around the arguments, but if you
"import" the color_b.py module, then you'll need to say, for example:
color_b.color_b(arguments...)
or just
color_b arguments...
One question for the gurus. Is pymol/modules/pymol/contrib.py the
accepted place to put new (or personal) functions? I noticed that if I
include my function within the contrib.py module, it is ready for use
as soon as I start up PyMOL (i.e. I don't have to explicitly "import"
it or "run" it (although with parenthese, it needs to be called as
"contrib.color_b(...)"). I couldn't find any other python module that
imports from contrib.py, so I wasn't sure.
Cheers and happy colo(u)ring,
Robert
--
Robert L. Campbell, Ph.D. http://biophysics.med.jhmi.edu/rlc
[email protected] phone: 410-614-6313
Research Specialist/X-ray Facility Manager
HHMI/Dept. of Biophysics & Biophysical Chem., The Johns Hopkins University
PGP Fingerprint: 9B49 3D3F A489 05DC B35C 8E33 F238 A8F5 F635 C0E2
# rlc color_b.py version 4.0
from pymol import cmd
def color_b(selection="all",ramp=0,rainbow=0,nbins=10):
"""
AUTHOR
Robert L. Campbell
USAGE
color_b(selection='sel',ramp=0 or 1, rainbow=0 or 1, nbins=10)
This function allows coloring of a selection as a function
of B-value, either in a range of hues from blue through magenta
to red (rainbow=0, the default) or in the colors of the rainbow
(rainbow=1). The division of B-value ranges can either be as a
histogram (equal-sized B-value increments leading to unequal numbers
of atoms in each bin: ramp=0) or as a ramp of B-value ranges with an
equal number of atoms in each group (ramp=1).
"""
ramp=int(ramp)
rainbow=int(rainbow)
nbins=float(nbins)
if nbins == 1:
print "\nWARNING: You specified nbins=1, which doesn't make
sense...resetting nbins=10\n"
nbins=10.
print "RAMP, RAINBOW, NBINS,", ramp,rainbow, nbins
m = cmd.get_model(selection)
sel = []
b_list = []
if len(m.atom) == 0:
print "No atoms selected"
else:
for i in range(len(m.atom)):
b_list.append(m.atom[i].b)
# create list of b-limits (bottom limit of bin)
b_lim=[]
max_b = max(b_list)
min_b = min(b_list)
print "Minimum and Maximum B-values: ", min_b, max_b
if ramp:
# color in bins of equal numbers of atoms
b_list.sort()
# subtract 0.1 from the lowest B in order to ensure
that the single
# atom with the lowest B value doesn't get omitted
b_list[0] = b_list[0] - 0.1
bin_num = int(len(b_list)/nbins)
for j in range(nbins):
sel.append(selection + " and b > " +
str(b_list[j*bin_num]))
#print "Color select: ",sel[j]
else:
# color in bins of equal B-value ranges
# subtract 0.1 from the lowest B in order to ensure
that the single
# atom with the lowest B value doesn't get omitted
min_b = min_b - 0.1
bin_width = (max_b - min_b)/nbins
for j in range(nbins):
sel.append(selection + " and b > " + str(min_b
+ j*bin_width))
#print "Color select: ",sel[j]
if rainbow:
col=[]
coldesc=[]
for j in range(nbins):
# must append the str(sel[j]) to the color name
so that it is unique
# for the selection
coldesc.append('col' + str(sel[j]) + str(j))
# create colors using hsv scale starting at
blue(240) through red(0)
# in intervals of 240/(nbins-1) (the "nbins-1"
ensures that the last
# color is in fact red (0)
#convert to rgb
hsv = (240-j*240/(nbins-1),1.,1.)
#print "HSV: ",hsv
#convert to rgb and append to color list
rgb = hsv_to_rgb(hsv)
#print "RGB: ",rgb
col.append(rgb)
cmd.set_color("col" + str(sel[j]) +
str(j),col[j])
#print coldesc[j],col[j]
else:
col=[]
coldesc=[]
for j in range(nbins):
coldesc.append('col' + str(sel[j]) + str(j))
# create colors in a ramp from blue through
magenta to red
rgb = [min(1.0, j*2/nbins), 0.0, min(1.0,
(nbins-j-1)*2/nbins)]
col.append(rgb)
cmd.set_color("col" + str(sel[j]) +
str(j),col[j])
#print coldesc[j],col[j]
for j in range(nbins):
#print "Color select: ",sel[j]
cmd.color(coldesc[j],sel[j])
# allow calling without parentheses: color_hist_b <selection=>, <ramp=
>,<rainbow= >,<nbins= >
cmd.extend("color_b",color_b)
def hsv_to_rgb(hsv):
# algorithm found at: http://www.cs.rit.edu/~ncs/color/t_convert.html
h = float(hsv[0])
s = float(hsv[1])
v = float(hsv[2])
if( s == 0 ) :
#achromatic (grey)
r = g = b = v
else:
# sector 0 to 5
h = h/60.
i = int(h)
f = h - i # factorial part of h
#print h,i,f
p = v * ( 1 - s )
q = v * ( 1 - s * f )
t = v * ( 1 - s * ( 1 - f ) )
if i == 0:
(r,g,b) = (v,t,p)
elif i == 1:
(r,g,b) = (q,v,p)
elif i == 2:
(r,g,b) = (p,v,t)
elif i == 3:
(r,g,b) = (p,q,v)
elif i == 4:
(r,g,b) = (t,p,v)
elif i == 5:
(r,g,b) = (v,p,q)
else:
(r,g,b) = (v,v,v)
print "error, i not equal 1-5"
return [r,g,b]