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 r...@k2.med.jhmi.edu 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]