Warren,

Great - that's what I needed.  For those who are interested, I've
attached code below which draws a dashed line between two atoms, with an
arrow on it.  It's called with pretty much the same syntax as the
'distance' command.

Gareth


#------------------------------------------------------------------------

from pymol.cgo import *
from pymol import cmd
from math import *


#-------------------------------------------------
# Draw a hydrogen bond
#---------------------------------

def hbond(name,s1,s2,r=1.0,g=1.0,b=0.2):

      '''
DESCRIPTION

   "hbond" creates a dashed line between two selections, marked with an
arrow.

USAGE

   distance name, (selection1), (selection1) , [, r, [, g, [, b] ] ]

   name = name of distance object 
   selection1,selection2 = atom selections
   r, g, b = colour

   '''  


        # Convert arguments into floating point values
        rr = float(r)
        gg = float(g)
        bb = float(b)

        # Get dash length, gap length and dash radius from PyMOL
        # settings
        dl = float(cmd.get_setting_tuple("dash_length")[1][0])
        gl = float(cmd.get_setting_tuple("dash_gap")[1][0])
        dr = float(cmd.get_setting_tuple("dash_radius")[1][0])

        # Get tuple containing object and index of atoms in these
        # selections
        x1 = cmd.index(s1,1)    
        x2 = cmd.index(s2,1)

        # Get number of atoms in each selection 
        n1 = len(x1)
        n2 = len(x2)
        if(n1 < 1):
                print "Error: selection " + s1 + " has no atoms"
                return
        if(n2 < 1):
                print "Error: selection " + s2 + " has no atoms"
                return

        # Get objects and atom indices
        o1 = x1[0][0]
        i1 = x1[0][1]
        o2 = x2[0][0]
        i2 = x2[0][1]

        # Get ChemPy models
        m1 = cmd.get_model(o1)
        m2 = cmd.get_model(o2)

        # Get atoms
        a1 = m1.atom[i1-1]
        a2 = m2.atom[i2-1]

        # Get coords
        x1 = a1.coord[0]
        y1 = a1.coord[1]
        z1 = a1.coord[2]
        x2 = a2.coord[0]
        y2 = a2.coord[1]
        z2 = a2.coord[2]

        # Make some nice strings for user feedback
        s1 = o1 + "/" + a1.chain + "/" + a1.resn + "." + a1.resi + "/" 
                + a1.name
        print s1 + "(" + str(x1) + "," + str(y1) + "," + str(z1) + ")"
        s2 = o2 + "/" + a2.chain + "/" + a2.resn + "." + a2.resi + "/" 
                + a2.name
        print s2 + "(" + str(x2) + "," + str(y2) + "," + str(z2) + ")"

        # Calculate distances 
        dx = x2 - x1
        dy = y2 - y1
        dz = z2 - z1
        d  = math.sqrt((dx*dx) + (dy*dy) + (dz*dz))
        print "distance = " + str(d) + "A"

        # Work out how many times (dash_len + gap_len) fits into d
        dash_tot = dl + gl
        n_dash = math.floor(d / dash_tot)

        # Work out step lengths
        dx1 = (dl / dash_tot) * (dx / n_dash)
        dy1 = (dl / dash_tot) * (dy / n_dash)
        dz1 = (dl / dash_tot) * (dz / n_dash)
        dx2 = (dx / n_dash)
        dy2 = (dy / n_dash)
        dz2 = (dz / n_dash)


        # Empty CGO object
        obj = []


        # Generate dashes
        x = x1
        y = y1
        z = z1
        for i in range(n_dash):
                
                # Generate a dash cylinder
                obj.extend( [ CYLINDER, x, y, z, x+dx1, y+dy1, z+dz1,
                        dr, rr, gg, bb, rr, gg, bb ] )

                # Move to start of next dash
                x = x + dx2
                y = y + dy2
                z = z + dz2


        # Add an arrow half way along
        # Calculate midpoint
        xm = (x1 + x2) / 2      
        ym = (y1 + y2) / 2
        zm = (z1 + z2) / 2

        # Vector pointing along the bond
        xv = (3.5 * dr / d) * dx
        yv = (3.5 * dr / d) * dy
        zv = (3.5 * dr / d) * dz

        # Rotate step vector 90deg around X axis
        xxv = xv
        yyv = -1 * zv
        zzv = yv

        # Add lines
        obj.extend( [ CYLINDER, xm-xv-xxv, ym-yv-yyv, zm-zv-zzv,
                xm+xv, ym+yv, zm+zv, dr, rr, gg, bb, rr, gg, bb ] )
        obj.extend( [ CYLINDER, xm-xv+xxv, ym-yv+yyv, zm-zv+zzv,
                xm+xv, ym+yv, zm+zv, dr, rr, gg, bb, rr, gg, bb ] )


        # Load the object into PyMOL
        cmd.load_cgo(obj, name)


# Add to PyMOL API
cmd.extend("hbond",hbond)

#------------------------------------------------------------------------




On Fri, 2003-07-18 at 18:25, Warren L. DeLano wrote:
> Gareth,
> 
>       cmd.identify returns the input indexing, which will correspond
> to the PDB file.
> 
>       cmd.index returns the internal indexing, which will correspond
> to cmd.get_model
> 
> help identify
> help index
> 
> Cheers,
> Warren
> 
> 
> --
> mailto:war...@delanoscientific.com
> Warren L. DeLano, Ph.D.
> Principal Scientist
> DeLano Scientific LLC
> Voice (650)-346-1154 
> Fax   (650)-593-4020
> 
> > -----Original Message-----
> > From: Gareth Stockwell [mailto:gar...@ebi.ac.uk]
> > Sent: Friday, July 18, 2003 8:50 AM
> > To: Warren L. DeLano
> > Cc: 'pymol-users'
> > Subject: RE: [PyMOL] H-bond display
> > 
> > Warren,
> > 
> > I started having a look at this, but I am getting stuck with atom 
> > indices.  If I make two selections, (lb) and (rb), by clicking on 
> > atoms in an object called 'x', then I can get the indices and objects 
> > of those atoms by doing
> > 
> > x1 = cmd.identify("lb",1)
> > x2 = cmd.identify("rb",1)
> > 
> > In my example, printing out x1 and x2 gives the following: [('x', 2)]
> > [('x', 16)]
> > 
> > As I clicked on these atoms, the GUI told me that they were,
> > respectively:
> > VAL: /x/1ATP/E/15/CA
> > LYS: /x/1ATP/E/16/NZ
> > 
> > But now, if I dump out the contents of the model.atom array, using 
> > this
> > code:
> > 
> > m = cmd.get_model("x")
> >     i = 1
> >     for a in m.atom:
> >             print str(i) + " -> " + a.chain + "/" + a.resn + "." \
> >                      + a.resi + "/" + a.name
> >             i = i+1
> > 
> > Then I see the following
> > 1 -> E/VAL.15/N
> > 2 -> E/VAL.15/CA
> > 3 -> E/VAL.15/CB
> > 4 -> E/VAL.15/CG1
> > 5 -> E/VAL.15/CG2
> > 6 -> E/VAL.15/C
> > 7 -> E/VAL.15/O
> > 8 -> E/LYS.16/N
> > 9 -> E/LYS.16/CA
> > 10 -> E/LYS.16/CB
> > 11 -> E/LYS.16/CG
> > 12 -> E/LYS.16/CD
> > 13 -> E/LYS.16/CE
> > 14 -> E/LYS.16/NZ
> > 15 -> E/LYS.16/C
> > 16 -> E/LYS.16/O
> > 17 -> E/GLU.17/N
> > 18 -> E/GLU.17/CA
> > 19 -> E/GLU.17/C
> > 20 -> E/GLU.17/O
> > 
> > So atom number 2 is correct (VAL.15/CA), but in this array, atom 16 is
> 
> > the O, not NZ in LYS.16.  I presume that ChemPy is re-ordering the 
> > atoms some time during the get_model call - how do I resolve this?
> > 
> > Gareth
> > 
> > 
> > On Fri, 2003-07-18 at 16:36, Warren L. DeLano wrote:
> > > Gareth,
> > >
> > >   CGO is currently the way to go...
> > >
> > > Cheers,
> > > Warren
> > >
> > >
> > > --
> > > mailto:war...@delanoscientific.com
> > > Warren L. DeLano, Ph.D.
> > > Principal Scientist
> > > DeLano Scientific LLC
> > > Voice (650)-346-1154
> > > Fax   (650)-593-4020
> > >
> > > > -----Original Message-----
> > > > From: pymol-users-ad...@lists.sourceforge.net [mailto:pymol-users-
> 
> > > > ad...@lists.sourceforge.net] On Behalf Of Gareth Stockwell
> > > > Sent: Friday, July 18, 2003 2:46 AM
> > > > To: pymol-users
> > > > Subject: [PyMOL] H-bond display
> > > >
> > > >
> > > > I am using distance objects at the moment, to display h-bonding 
> > > > contacts.  My question is ... is there any easy way to display the
> 
> > > > direction of an h-bond using distances (i.e. putting a little 
> > > > arrow on the dashed line)?
> > > >
> > > > I am prepared to bash out some functions which do this using CGOs,
> 
> > > > but of course I won't if it's already implemented!
> > > >
> > > > Gareth
> > > >
> > > >
> > > > --
> > > > Gareth Stockwell <gar...@ebi.ac.uk>
> > > > European Bioinformatics Institute
> > > >
> > > >
> > > >
> > > > -------------------------------------------------------
> > > > This SF.net email is sponsored by: VM Ware
> > > > With VMware you can run multiple operating systems on a single
> > > machine.
> > > > WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines 
> > > > at
> > > the
> > > > same time. Free trial click here: 
> > > > http://www.vmware.com/wl/offer/345/0
> > > > _______________________________________________
> > > > PyMOL-users mailing list
> > > > PyMOL-users@lists.sourceforge.net
> > > > https://lists.sourceforge.net/lists/listinfo/pymol-users
> > >
> > >
> > >
> > > -------------------------------------------------------
> > > This SF.net email is sponsored by: VM Ware
> > > With VMware you can run multiple operating systems on a single 
> > > machine. WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual 
> > > machines at the same time. Free trial click here: 
> > > http://www.vmware.com/wl/offer/345/0
> > > _______________________________________________
> > > PyMOL-users mailing list
> > > PyMOL-users@lists.sourceforge.net
> > > https://lists.sourceforge.net/lists/listinfo/pymol-users
> > --
> > Gareth Stockwell <gar...@ebi.ac.uk>
> > European Bioinformatics Institute
> 
> 
> 
> -------------------------------------------------------
> This SF.net email is sponsored by: VM Ware
> With VMware you can run multiple operating systems on a single machine.
> WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the
> same time. Free trial click here: http://www.vmware.com/wl/offer/345/0
> _______________________________________________
> PyMOL-users mailing list
> PyMOL-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/pymol-users
-- 
Gareth Stockwell <gar...@ebi.ac.uk>
European Bioinformatics Institute


Reply via email to