I was wondering how the attachment would fare on the email list. Apparently, "not well" so I just include it in line below, but watch out for proper spacing/line returns in the process.

### Purpose: Get snapshots of each of several NCS-related molecules in identical position

### Usage: Line up your view on molecule 1 (i.e. chain A) and type "run NCS.py"

### Notes: Turn on any maps, cartoons, colorings, whatever it is that you want to examine
### Make sure you have NCS operators defined in a CNS-format file and that
### this file is appropriately called in this script (current default is ncs_matrices.list)
### Be careful that these operators are the ones to transform chain A
### onto chain X, rather than the inverse which CNS lists in the bottom half of
### its NCS matrices files
### Then type "run NCS.py", and Bob's your mother's brother, or at least a second cousin

### Output: The script writes .png snapshots for each NCS molecule, called molX.png where ### X is some number. Also, it will output each "set_view" command that it came up ### with so that if you want to go back and interactively look at mol4, for example, you ### can just type @mol4 in pymol (while the molecule is already loaded, etc.) and it
### will take you there by appropriately setting the view.

### If you have ImageMagick installed, you can uncomment the penultimate line
### about os.system call to montage.  The montage command takes the preceding
### mol*.png files produced of the views and makes a single png file with all
### of the panels represented.  The man page for montage has the options fully
### explained, but briefly the way I use it has -geometry with options for x and y ### pixels for each panel plus how wide of a buffer or border you want between panels ### (e.g. +5+5) and the -tiel 4x2 describes how you want the panels laid out, in this ### case 4 columns and 2 rows. These options are followed by the input file names ### (mol*.png) and the output (montage.png). You can, of course, also run it manually ### for only those cases that you want since it takes a little longer than the main ### part of the script. Also, if you want to ray trace each frame you need to uncomment
### the cmd.ray() line in the outview function.

### Caveats:  Um, basically, in python, I have no idea what I am doing.
### This is the first, and so far only, Python script I have ever written.
### I'm sure there are much, much better ways to do a lot of this, but I have
### just plowed ahead and spelled things out in a basic klunky style.
### Feel free to send me improvements or suggestions, like better, more flexible ways ### to get the NCS operators out of the file so it won't be so stringently tied to ### the CNS file format. It would probably be best to have pymol extract the NCS ### relationshiops itself, for example. Also, I have only used this on one case ### (8 NCS copies, though, which is what motivated this script) but I think it will work
### generally.

### Overview Method:
### Get starting view for mol1
### Get NCS matrices from file for chain A->B, A->C, A->D, ... A->X
### Multiply rotation matrix of starting view (first 9) by NCS rotation matrix for each mol
### Get origin position from starting view (elements 12,13,14 of starting view
###                                   recalling that array begins at elemnt 0)
### Multiply by origin x,y,z by ncs rotation matrix as with view
### Additionally, add the x,y,z translations to the result to get the new origin position ### Note: Translations for inverse matrices sometimes, but not always, match those ### for the original matrices. I don't fully understand this, but that's ### probably just me. In any case, be careful about getting the right matrices. ### The new view is written out as a "set_view" command, saved in a file, also applied
###              and a png snapshot taken before going on to the next molecule.

### PyMOL's get/set_view matrix:
### Note that what I learned of pymol's set_view is that camera position (elements 9-11 of ### the set view matrix) is relative to the origin. Since we're moving the origin to the ### appropriate new location, we can just leave the relative camera position as it was. ### Same seems to go for the clipping planes (elements 15,16). The final element is the
### orthoscopic flag, and this too is simply copied over from the first view.

### This script has been hacked out (and I do mean hacked) by Seth Harris.
### shar...@msg.ucsf.edu for any suggestions/feedback/gratitude
###  Thanks to Warren DeLano for PyMOL!

from pymol import cmd
from Numeric import *
from LinearAlgebra import *
import re



### define function to put out set_view command for a given molecule
def outview (mol, n):

                        of=open('mol'+repr(mol),'w')
                        of.write('### for molecule '+repr(mol)+'\n')
                        of.write('set_view (\\\n')
of.write(repr(n[0])+', '+repr(n[1])+', '+repr(n[2])+',\\\n') of.write(repr(n[3])+', '+repr(n[4])+', '+repr(n[5])+',\\\n') of.write(repr(n[6])+', '+repr(n[7])+', '+repr(n[8])+',\\\n') of.write(repr(n[9])+', '+repr(n[10])+', '+repr(n[11])+',\\\n') of.write(repr(n[12])+', '+repr(n[13])+', '+repr(n[14])+',\\\n') of.write(repr(n[15])+', '+repr(n[16])+', '+repr(n[17])+')\n')
                        cmd.set_view(n)
#uncomment following if you want each snapshot ray traced
                        #cmd.ray()
                        cmd.png('mol'+repr(mol)+'.png')

#filename=input("File name for montage (e.g. residue name&number) [montage.png]: ")

# get starting view and put that out for molecule 1 unchanged
m = cmd.get_view(0)
mol=1
outview(mol, m)
start=array(((m[0],m[1],m[2]),(m[3],m[4],m[5]),(m[6],m[7],m[8])), Float)
origin=array(((m[12],m[13],m[14])), Float)
count=0
# search for matrix lines in ncs_matrices.list file
# note that these are all matrices for moving a->x, where x is the NCS copy
# this rotation matrix will be applied to the original view and to the
# original origin.  The resulting origin position will then be modified by
# adding the translation shift to give the final new origin
# Strangely, note that while the inverse operator works fine on the rotation
# matrix, the inverse translation that CNS comes up with is not simply the
# opposite sign of the original translation values.  Hmmm.
# Anyway, it almost killed me, but finally this seems to work correctly.
p=re.compile('.*matrix.*')
for rot in open('ncs_matrices.list'):
        p=re.compile('.*matrix.*')
        x = p.match(rot)
        if x or count>0:
                print 'Match found: ', rot
# search CNS-style file for three numbers separated by one or more spaces # between parentheses in each of these lines. Once found use count to
                # get 4 lines total for the whole matrix

        nums=re.compile(r'.*\(\s+([0-9.-]*)\s+([0-9.-]*)\s+([0-9.-]*).*\).*')
                y = nums.match(rot)
                index=count*3
                ncs=list((y.group(1), y.group(2), y.group(3)))
                if count==0:
                        nl=ncs
                else:
                        new=nl
                        nl[-1:]=nl[-1:]+ncs
                        nl=new
                count=count+1
                if count==4:
                        mol=mol+1
# get rotation matrix from ncslist (first nine elements) rotmat= array(((float(nl[0]),float(nl[1]),float(nl[2])),\

        (float(nl[3]),float(nl[4]),float(nl[5])),\

        (float(nl[6]),float(nl[7]),float(nl[8]))), Float)
                        #rotinv = inverse(rotmat)
                        print '\nstarting position matrix is:'
                        print start
                        print '\norigin is:'
                        print origin
                        print '\nncs rotation matrix is:'
                        print rotmat
                        p = matrixmultiply(rotmat,start)
                        print '\nproduct of matrixmultiply rotmat, start is'
                        print p
                        no = matrixmultiply(rotmat,origin)
print '\nproduct of matrixmultiply for origin, prior to translation is:'
                        print no
                        print '\ntranslation shift will be:'
                        print nl[9],nl[10],nl[11]
nopos = array(((no[0]+float(nl[9]),no[1]+float(nl[10]),no[2]+float(nl[11]))), Float) n = array((p[0][0],p[0][1],p[0][2],p[1][0],p[1][1],p[1][2],\

        p[2][0],p[2][1],p[2][2],m[9],m[10],m[11],\

        nopos[0],nopos[1],nopos[2],m[15],m[16],m[17]))
                        print 'Outputting view for molecule '+repr(mol)
                        outview (mol,n)
                        count=0

#os.system ("montage -geometry 640x480+5+5 -tile 4x2 mol*.png montage.png")
print 'All done'

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Seth F. Harris, PhD
Agard Laboratory
University of California, San Francisco
415-502-2930

Reply via email to