Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

## Re: [PyMOL] you know what would be cool?

 Re: [PyMOL] you know what would be cool? From: Laurence Pearl - 2003-11-17 13:07:40 ```Well even this late in my career I still aspire to be cool, so here it is much as requested, a python routine to make the camera travel from place to place in your molecule. The arguments to the routine are : FIRST: frame number for start of the sequence NFRAMES : number of frames the sequence takes SEL : a valid PyMol atom selection, encased in quotes, which defines the view at the end of the sequence ZFLAG : a flag to indicate whether the final view should be 'zoomed' or not. ZLEVEL : the degree of zoom - exactly the same as the 'buffer' parameter in PyMol cmd.zoom The routine generates view matrices that interpolate between the current view and the view specified by the atom selection, updating the view as it finishes so it can be applied iteratively to travel from way-point to way-point. I've also included a little routine which applies camera_travel sequentially to each residue along a polypeptide chain - the movie is quite large, and when running fast on a Mac G5 can make you a little sea-sick, but it does illustrate the power of the routine. The major technical problem comes from the need to interpolate general rotation matrices, which is solved by using a quaternion representation. The code for this is adapted from an article in a magazine called GameDeveloper by Nick Bobick. I should add that I don't actually know how to program in python and have no idea how its 'tuples' work, so this is a very FORTRAN-like routine - feel free to improve it. # camera_travel - Laurence Pearl, November 2003 import cmd import math def camera_travel(first,nframes=30,sel='(all)',zflag=0,zlevel=2): # first - start frame # nframes - duration # sel - atom selection that defines the orientation at the end of the sequence new_view = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] old_view = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] nxt = [1,2,0] q = [0,0,0,1] first=int(first) nframes=int(nframes) ff=float(1.0/nframes) old_view = cmd.get_view(2) # print "view : (%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)" % (old_view) # print "oldtran : %8.3f %8.3f %8.3f" % (old_view[12], old_view[13], old_view[14]) # do orient operation on selection cmd.orient(sel,0) # if zoom to selection is required add this into view matrix if zflag != 0: cmd.zoom(sel,zlevel,0,1) # get new view new_view = cmd.get_view() # capture new zoom/clip parameters ozc1 = new_view[11] ozc2 = new_view[15] ozc3 = new_view[16] # calculate shift in zoom/clip parameters dzc1 = (ozc1 - old_view[11]) * ff dzc2 = (ozc2 - old_view[15]) * ff dzc3 = (ozc3 - old_view[16]) * ff ozc1 = old_view[11] ozc2 = old_view[15] ozc3 = old_view[16] # capture new translation vector component ox = new_view[12] oy = new_view[13] oz = new_view[14] # calculate shift vector dx = ox - old_view[12] dy = oy - old_view[13] dz = oz - old_view[14] dx = dx*ff dy = dy*ff dz = dz*ff ox = old_view[12] oy = old_view[13] oz = old_view[14] # capture old rotation matrix component # m[0][0] = v[0] m[0][1] = v[1] m[0][2] = v[2] # m[1][0] = v[3] m[1][1] = v[4] m[1][2] = v[5] # m[2][0] = v[6] m[2][1] = v[7] m[2][2] = v[8] # convert to quaternion form tr = old_view[0]+old_view[4]+old_view[8] if tr > 0.0 : s = math.sqrt(tr + 1.0) qw1 = s / 2.0 s = 0.5 / s qx1 = (old_view[5] - old_view[7]) * s qy1 = (old_view[6] - old_view[2]) * s qz1 = (old_view[1] - old_view[3]) * s else : i = 0 if (old_view[4] > old_view[0]): i = 1 if (old_view[8] > old_view[i+3*i]): i = 2 j = nxt[i] k = nxt[j] s = math.sqrt ((old_view[i+i*3] - (old_view[j+j*3] + old_view[k+k*3])) + 1.0) q[i] = s * 0.5 if (s != 0.0): s = 0.5 / s q[3] = (old_view[k+3*j] - old_view[j+3*k]) * s q[j] = (old_view[j+3*i] + old_view[i+3*j]) * s q[k] = (old_view[k+3*i] + old_view[i+3*k]) * s qx1 = q[0] qy1 = q[1] qz1 = q[2] qw1 = q[3] # capture new rotation matrix component # m[0][0] = v[0] m[0][1] = v[1] m[0][2] = v[2] # m[1][0] = v[3] m[1][1] = v[4] m[1][2] = v[5] # m[2][0] = v[6] m[2][1] = v[7] m[2][2] = v[8] # convert to quaternion form tr = new_view[0]+ new_view[4]+ new_view[8] if tr > 0.0 : s = math.sqrt(tr + 1.0) qw2 = s / 2.0 s = 0.5 / s qx2 = (new_view[5] - new_view[7]) * s qy2 = (new_view[6] - new_view[2]) * s qz2 = (new_view[1] - new_view[3]) * s else : i = 0 if (new_view[4] > new_view[0]): i = 1 if (new_view[8] > new_view[i+3*i]): i = 2 j = nxt[i] k = nxt[j] s = math.sqrt ((new_view[i+i*3] - (new_view[j+j*3] + new_view[k+k*3])) + 1.0) q[i] = s * 0.5 if (s != 0.0): s = 0.5 / s q[3] = (new_view[k+3*j] - new_view[j+3*k]) * s q[j] = (new_view[j+3*i] + new_view[i+3*j]) * s q[k] = (new_view[k+3*i] + new_view[i+3*k]) * s qx2 = q[0] qy2 = q[1] qz2 = q[2] qw2 = q[3] # calc cosine cosom = qx1 * qx2 + qy1 * qy2 + qz1 * qz2 + qw1 * qw2 # adjust signs if (cosom < 0.0): cosom = -cosom to0 = -qx2 to1 = -qy2 to2 = -qz2 to3 = -qw2 else: to0 = qx2 to1 = qy2 to2 = qz2 to3 = qw2 # calc coefficients omega = math.acos(cosom) sinom = math.sin(omega) # restore old view cmd.set_view("%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f" % (old_view[0],old_view[1],old_view[2],old_view[3],old_view[4],old_view[5] ,old_view[6],old_view[7],old_view[8],old_view[9],old_view[10],old_view[1 1],old_view[12],old_view[13],old_view[14],old_view[15],old_view[16],old_ view[17]) ) # loop interpolating over nframes generating interpolated quaternion a = 0 while a < (nframes+1) : scale0 = math.sin((1.0 - float(a*ff)) * omega) / sinom scale1 = math.sin(float(a*ff) * omega) / sinom rx = scale0 * qx1 + scale1 * to0; ry = scale0 * qy1 + scale1 * to1; rz = scale0 * qz1 + scale1 * to2; rw = scale0 * qw1 + scale1 * to3; # convert back to matrix x2 = rx + rx y2 = ry + ry z2 = rz + rz xx = rx * x2 xy = rx * y2 xz = rx * z2 yy = ry * y2 yz = ry * z2 zz = rz * z2 wx = rw * x2 wy = rw * y2 wz = rw * z2 nv0 = 1.0 - (yy + zz) nv3 = xy - wz nv6 = xz + wy nv1 = xy + wz nv4 = 1.0 - (xx + zz) nv7 = yz - wx nv2 = xz - wy nv5 = yz + wx nv8 = 1.0 - (xx + yy) # update translation vector ox = ox + dx oy = oy + dy oz = oz + dz # update zoom/clip parameters if required if zflag != 0: ozc1 = ozc1 + dzc1 ozc2 = ozc2 + dzc2 ozc3 = ozc3 + dzc3 cmd.mdo("%d" % (first),"set_view (%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)" % (nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,ox,oy ,oz,ozc2,ozc3,old_view[17])) a = a + 1 first = first + 1 cmd.set_view("%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f" % (nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,ox,oy ,oz,ozc2,ozc3,old_view[17])) # SEQUENCE VISITOR ires = 1 fr=1 res=" " while ires < 215: res = "resi %d" % (ires) camera_travel(fr,9,res,1,2) cmd.mdo("%d" % (fr+10),"show sticks,(resi %d and not n;c,n,o)" % (ires)) fr = fr + 15 ires = ires + 1 On Thursday, November 13, 2003, at 09:24 PM, classen wrote: > When making a movie It would be cool if you could set way-points to > create a > sophisticated "tour" > of your molecule. > > Each way-point would be a different view of your molecule. > > Then you could specify the number of frames between any two way-points > (views). Each frame > would be a specified amount of time and by changing the number of > frames you > would change the > timing for that particular section of the movie. > > Press the play button and voila your tour begins.... zooming in, > rotating, > zooming back out, etc. > > Would this be difficult to implement? > > Regards, > Scott Classen > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > Scott Classen, Ph.D. > ACS Postdoctoral Fellow > Department of Molecular & Cell Biology > University of California, Berkeley > 237 Hildebrand Hall #3206 > Berkeley, CA 94720-3206 > LAB 510.643.9491 > FAX 510.643.9290 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > ------------------------------------------------------- > This SF.Net email sponsored by: ApacheCon 2003, > 16-19 November in Las Vegas. Learn firsthand the latest > developments in Apache, PHP, Perl, XML, Java, MySQL, > WebDAV, and more! http://www.apachecon.com/ > _______________________________________________ > PyMOL-users mailing list > PyMOL-users@... > https://lists.sourceforge.net/lists/listinfo/pymol-users > ------------------------------------------------------------------------ -- Laurence H. Pearl Section of Structural Biology, Institute of Cancer Research Chester Beatty Laboratories, 237 Fulham Road, London SW3 6JB, UK Phone +44-207-970 6045 : Secretary +44-207-970 6046 FAX +44-207-970 6051 : E-Mail Laurence.Pearl@... ------------------------------------------------------------------------ -- " Live Simply and do Serious Things .. " - Dorothy Crowfoot Hodgkin ------------------------------------------------------------------------ -- ```

 [PyMOL] you know what would be cool? From: classen - 2003-11-13 21:24:27 ```When making a movie It would be cool if you could set way-points to create a sophisticated "tour" of your molecule. Each way-point would be a different view of your molecule. Then you could specify the number of frames between any two way-points (views). Each frame would be a specified amount of time and by changing the number of frames you would change the timing for that particular section of the movie. Press the play button and voila your tour begins.... zooming in, rotating, zooming back out, etc. Would this be difficult to implement? Regards, Scott Classen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Scott Classen, Ph.D. ACS Postdoctoral Fellow Department of Molecular & Cell Biology University of California, Berkeley 237 Hildebrand Hall #3206 Berkeley, CA 94720-3206 LAB 510.643.9491 FAX 510.643.9290 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ```
 Re: [PyMOL] you know what would be cool? From: Laurence Pearl - 2003-11-17 13:07:40 ```Well even this late in my career I still aspire to be cool, so here it is much as requested, a python routine to make the camera travel from place to place in your molecule. The arguments to the routine are : FIRST: frame number for start of the sequence NFRAMES : number of frames the sequence takes SEL : a valid PyMol atom selection, encased in quotes, which defines the view at the end of the sequence ZFLAG : a flag to indicate whether the final view should be 'zoomed' or not. ZLEVEL : the degree of zoom - exactly the same as the 'buffer' parameter in PyMol cmd.zoom The routine generates view matrices that interpolate between the current view and the view specified by the atom selection, updating the view as it finishes so it can be applied iteratively to travel from way-point to way-point. I've also included a little routine which applies camera_travel sequentially to each residue along a polypeptide chain - the movie is quite large, and when running fast on a Mac G5 can make you a little sea-sick, but it does illustrate the power of the routine. The major technical problem comes from the need to interpolate general rotation matrices, which is solved by using a quaternion representation. The code for this is adapted from an article in a magazine called GameDeveloper by Nick Bobick. I should add that I don't actually know how to program in python and have no idea how its 'tuples' work, so this is a very FORTRAN-like routine - feel free to improve it. # camera_travel - Laurence Pearl, November 2003 import cmd import math def camera_travel(first,nframes=30,sel='(all)',zflag=0,zlevel=2): # first - start frame # nframes - duration # sel - atom selection that defines the orientation at the end of the sequence new_view = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] old_view = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] nxt = [1,2,0] q = [0,0,0,1] first=int(first) nframes=int(nframes) ff=float(1.0/nframes) old_view = cmd.get_view(2) # print "view : (%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)" % (old_view) # print "oldtran : %8.3f %8.3f %8.3f" % (old_view[12], old_view[13], old_view[14]) # do orient operation on selection cmd.orient(sel,0) # if zoom to selection is required add this into view matrix if zflag != 0: cmd.zoom(sel,zlevel,0,1) # get new view new_view = cmd.get_view() # capture new zoom/clip parameters ozc1 = new_view[11] ozc2 = new_view[15] ozc3 = new_view[16] # calculate shift in zoom/clip parameters dzc1 = (ozc1 - old_view[11]) * ff dzc2 = (ozc2 - old_view[15]) * ff dzc3 = (ozc3 - old_view[16]) * ff ozc1 = old_view[11] ozc2 = old_view[15] ozc3 = old_view[16] # capture new translation vector component ox = new_view[12] oy = new_view[13] oz = new_view[14] # calculate shift vector dx = ox - old_view[12] dy = oy - old_view[13] dz = oz - old_view[14] dx = dx*ff dy = dy*ff dz = dz*ff ox = old_view[12] oy = old_view[13] oz = old_view[14] # capture old rotation matrix component # m[0][0] = v[0] m[0][1] = v[1] m[0][2] = v[2] # m[1][0] = v[3] m[1][1] = v[4] m[1][2] = v[5] # m[2][0] = v[6] m[2][1] = v[7] m[2][2] = v[8] # convert to quaternion form tr = old_view[0]+old_view[4]+old_view[8] if tr > 0.0 : s = math.sqrt(tr + 1.0) qw1 = s / 2.0 s = 0.5 / s qx1 = (old_view[5] - old_view[7]) * s qy1 = (old_view[6] - old_view[2]) * s qz1 = (old_view[1] - old_view[3]) * s else : i = 0 if (old_view[4] > old_view[0]): i = 1 if (old_view[8] > old_view[i+3*i]): i = 2 j = nxt[i] k = nxt[j] s = math.sqrt ((old_view[i+i*3] - (old_view[j+j*3] + old_view[k+k*3])) + 1.0) q[i] = s * 0.5 if (s != 0.0): s = 0.5 / s q[3] = (old_view[k+3*j] - old_view[j+3*k]) * s q[j] = (old_view[j+3*i] + old_view[i+3*j]) * s q[k] = (old_view[k+3*i] + old_view[i+3*k]) * s qx1 = q[0] qy1 = q[1] qz1 = q[2] qw1 = q[3] # capture new rotation matrix component # m[0][0] = v[0] m[0][1] = v[1] m[0][2] = v[2] # m[1][0] = v[3] m[1][1] = v[4] m[1][2] = v[5] # m[2][0] = v[6] m[2][1] = v[7] m[2][2] = v[8] # convert to quaternion form tr = new_view[0]+ new_view[4]+ new_view[8] if tr > 0.0 : s = math.sqrt(tr + 1.0) qw2 = s / 2.0 s = 0.5 / s qx2 = (new_view[5] - new_view[7]) * s qy2 = (new_view[6] - new_view[2]) * s qz2 = (new_view[1] - new_view[3]) * s else : i = 0 if (new_view[4] > new_view[0]): i = 1 if (new_view[8] > new_view[i+3*i]): i = 2 j = nxt[i] k = nxt[j] s = math.sqrt ((new_view[i+i*3] - (new_view[j+j*3] + new_view[k+k*3])) + 1.0) q[i] = s * 0.5 if (s != 0.0): s = 0.5 / s q[3] = (new_view[k+3*j] - new_view[j+3*k]) * s q[j] = (new_view[j+3*i] + new_view[i+3*j]) * s q[k] = (new_view[k+3*i] + new_view[i+3*k]) * s qx2 = q[0] qy2 = q[1] qz2 = q[2] qw2 = q[3] # calc cosine cosom = qx1 * qx2 + qy1 * qy2 + qz1 * qz2 + qw1 * qw2 # adjust signs if (cosom < 0.0): cosom = -cosom to0 = -qx2 to1 = -qy2 to2 = -qz2 to3 = -qw2 else: to0 = qx2 to1 = qy2 to2 = qz2 to3 = qw2 # calc coefficients omega = math.acos(cosom) sinom = math.sin(omega) # restore old view cmd.set_view("%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f" % (old_view[0],old_view[1],old_view[2],old_view[3],old_view[4],old_view[5] ,old_view[6],old_view[7],old_view[8],old_view[9],old_view[10],old_view[1 1],old_view[12],old_view[13],old_view[14],old_view[15],old_view[16],old_ view[17]) ) # loop interpolating over nframes generating interpolated quaternion a = 0 while a < (nframes+1) : scale0 = math.sin((1.0 - float(a*ff)) * omega) / sinom scale1 = math.sin(float(a*ff) * omega) / sinom rx = scale0 * qx1 + scale1 * to0; ry = scale0 * qy1 + scale1 * to1; rz = scale0 * qz1 + scale1 * to2; rw = scale0 * qw1 + scale1 * to3; # convert back to matrix x2 = rx + rx y2 = ry + ry z2 = rz + rz xx = rx * x2 xy = rx * y2 xz = rx * z2 yy = ry * y2 yz = ry * z2 zz = rz * z2 wx = rw * x2 wy = rw * y2 wz = rw * z2 nv0 = 1.0 - (yy + zz) nv3 = xy - wz nv6 = xz + wy nv1 = xy + wz nv4 = 1.0 - (xx + zz) nv7 = yz - wx nv2 = xz - wy nv5 = yz + wx nv8 = 1.0 - (xx + yy) # update translation vector ox = ox + dx oy = oy + dy oz = oz + dz # update zoom/clip parameters if required if zflag != 0: ozc1 = ozc1 + dzc1 ozc2 = ozc2 + dzc2 ozc3 = ozc3 + dzc3 cmd.mdo("%d" % (first),"set_view (%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f)" % (nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,ox,oy ,oz,ozc2,ozc3,old_view[17])) a = a + 1 first = first + 1 cmd.set_view("%8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f, %8.3f" % (nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,ox,oy ,oz,ozc2,ozc3,old_view[17])) # SEQUENCE VISITOR ires = 1 fr=1 res=" " while ires < 215: res = "resi %d" % (ires) camera_travel(fr,9,res,1,2) cmd.mdo("%d" % (fr+10),"show sticks,(resi %d and not n;c,n,o)" % (ires)) fr = fr + 15 ires = ires + 1 On Thursday, November 13, 2003, at 09:24 PM, classen wrote: > When making a movie It would be cool if you could set way-points to > create a > sophisticated "tour" > of your molecule. > > Each way-point would be a different view of your molecule. > > Then you could specify the number of frames between any two way-points > (views). Each frame > would be a specified amount of time and by changing the number of > frames you > would change the > timing for that particular section of the movie. > > Press the play button and voila your tour begins.... zooming in, > rotating, > zooming back out, etc. > > Would this be difficult to implement? > > Regards, > Scott Classen > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > Scott Classen, Ph.D. > ACS Postdoctoral Fellow > Department of Molecular & Cell Biology > University of California, Berkeley > 237 Hildebrand Hall #3206 > Berkeley, CA 94720-3206 > LAB 510.643.9491 > FAX 510.643.9290 > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > ------------------------------------------------------- > This SF.Net email sponsored by: ApacheCon 2003, > 16-19 November in Las Vegas. Learn firsthand the latest > developments in Apache, PHP, Perl, XML, Java, MySQL, > WebDAV, and more! http://www.apachecon.com/ > _______________________________________________ > PyMOL-users mailing list > PyMOL-users@... > https://lists.sourceforge.net/lists/listinfo/pymol-users > ------------------------------------------------------------------------ -- Laurence H. Pearl Section of Structural Biology, Institute of Cancer Research Chester Beatty Laboratories, 237 Fulham Road, London SW3 6JB, UK Phone +44-207-970 6045 : Secretary +44-207-970 6046 FAX +44-207-970 6051 : E-Mail Laurence.Pearl@... ------------------------------------------------------------------------ -- " Live Simply and do Serious Things .. " - Dorothy Crowfoot Hodgkin ------------------------------------------------------------------------ -- ```