Raster3D_2.9-2/ 0000755 0004727 0004727 00000000000 11350020110 012173 5 ustar champ champ Raster3D_2.9-2/quadric.f 0000644 0004727 0004727 00000035352 11327673235 014034 0 ustar champ champ ************************************************************************ * Support routines for quadric surfaces * ************************************************************************ * EAM Jun 1997 - initial version, supports version 2.4(alpha) of render * EAM May 1998 - additional error checking to go with Parvati/rastep * EAM Jan 1999 - version 2.4i * EAM Mar 2008 - Gfortran optimization breaks the object accounting. * No real solution yet. Move qinp.f into separate file ************************************************************************ * * Quadric surfaces include spheres, cones, ellipsoids, paraboloids, and * hyperboloids. The motivation for this code was to allow rendering * thermal ellipsoids for atoms, so the other shapes have not been * extensively tested. * A quadric surface is described by 10 parameters (A ... J). * For efficiency during rendering it is also useful to know the center and * a bounding sphere. So a QUADRIC descriptor to render has 17 parameters: * 14 (object type QUADRIC) * X Y Z RADLIM RED GRN BLU * A B C D E F G H I J * * The surface itself is the set of points for which Q(x,y,z) = 0 * where * Q(x,y,z) = A*x^2 + B*y^2 + C*z^2 * + 2D*x*y + 2E*y*z + 2F*z*x * + 2G*x + 2H*y + 2I*z * + J * * It is convenient to store this information in a matrix QQ * | QA QD QF QG | QA = A QB = B QC = C * QQ = | QD QB QE QH | QD = D QE = E QF = F * | QF QE QC QI | QG = G QH = H QI = I * | QG QH QI QJ | QJ = J * * Then Q(x,y,x) = XT*QQ*X where X = (x,y,z,1) * The point of this is that a 4x4 homogeneous transformation T can be * applied to QQ by matrix multiplication: QQ' = TinvT * QQ * Tinv * * The surface normal is easily found by taking the partial derivatives * of Q(x,y,z) at the point of interest. ************************************************************************ * TO DO: * - can we distinguish an ellipsoid from other quadrics? Do we care? ************************************************************************ CCC Calculate the matrices for quadric transformation CC QQ' = TINVT * QQ * TINV (TINV is inverse of transposed TMAT) C subroutine qsetup * COMMON /MATRICES/ XCENT, YCENT, SCALE, EYEPOS, SXCENT, SYCENT, & TMAT, TINV, TINVT, SROT, SRTINV, SRTINVT & ,RAFTER, TAFTER REAL XCENT, YCENT, SCALE, EYEPOS, SXCENT, SYCENT REAL TMAT(4,4), TINV(4,4), TINVT(4,4) REAL SROT(4,4), SRTINV(4,4), SRTINVT(4,4) REAL RAFTER(4,4), TAFTER(3) * COMMON /ASSCOM/ noise, verbose integer noise logical verbose * real TRAN(4,4), POST(4,4), det * * TMAT is a post-multiplier matrix, but unfortunately the * quadric surface math was worked out for pre-multipliers * So the quadric math uses the transpose of TMAT call trnsp4( TRAN, TMAT ) * * Remove translation component from TMAT. * I had to make a choice whether the X,Y,Z "center" of the quadric * is implicitly coded into the coefficients, or whether it is to be * maintained explicitly. Since all other object types do the latter, * I have chosen to keep all translation components out of the quadric * coefficients tran(1,4) = 0.0 tran(2,4) = 0.0 tran(3,4) = 0.0 * * July 1999 - Allow post-hoc rotation matrix also call tmul4( POST, RAFTER, TRAN ) * det = tinv4( TINV, POST ) / TMAT(4,4) call trnsp4( TINVT, TINV ) * * While we're at it, check for legality of rotation matrix if (abs(1. - abs(det)) .gt. 0.02) then write (noise,901) abs(det) 901 format('>>> Warning: Determinant of rotation matrix =', & F7.3,' <<<') endif if (TMAT(1,4).ne.0.or.TMAT(2,4).ne.0.or.TMAT(3,4).ne.0) then write (noise,902) 902 format('>>> Warning: Non-zero cross terms in 4th column of', & ' TMAT <<<') endif * * Same thing again for shadow rotation matrix call trnsp4( TRAN, SROT ) det = tinv4( SRTINV, TRAN ) call trnsp4( SRTINVT, SRTINV ) if (abs(1. - abs(det)) .gt. 0.02) then write (noise,903) abs(det) 903 format('>>> Warning: Determinant of shadow matrix =', & F7.3,' <<<') endif * return end ************************************************************************ * This routine does the exact test for pixel impingement of a quadric * * in both pixel and shadow space. * * Find Z coordinate of point on quadric surface with given X, Y * * Also return surface normal at that point * ************************************************************************ CCC CC C function qtest( center, coeffs, xp, yp, zp, qnorm, shadowspace, & backside ) IMPLICIT NONE logical qtest, shadowspace logical backside real center(3), coeffs(10), xp, yp, zp, qnorm(3) * COMMON /MATRICES/ XCENT, YCENT, SCALE, EYEPOS, SXCENT, SYCENT, & TMAT, TINV, TINVT, SROT, SRTINV, SRTINVT & ,RAFTER, TAFTER REAL XCENT, YCENT, SCALE, EYEPOS, SXCENT, SYCENT REAL TMAT(4,4), TINV(4,4), TINVT(4,4) REAL SROT(4,4), SRTINV(4,4), SRTINVT(4,4) REAL RAFTER(4,4), TAFTER(3) * real QA,QB,QC,QD,QE,QF,QG,QH,QI,QJ real AA,BB,CC,DD,EE real x,y,z * QA = coeffs(1) QB = coeffs(2) QC = coeffs(3) QD = coeffs(4) QE = coeffs(5) QF = coeffs(6) QG = coeffs(7) QH = coeffs(8) QI = coeffs(9) QJ = coeffs(10) * * xp and yp are in pixel coordinates, rather than in normalized ones * First displace center of quadric surface from the implicit origin * to the point specified by center(3), then convert to pixel coords * x = (xp - center(1)) / scale y = (yp - center(2)) / scale * AA = QC BB = 2.0 * (QF*x + QE*y + QI) CC = QA*x*x + QB*y*y + 2.0*(QD*x*y + QG*x + QH*y) + QJ DD = BB*BB - 4*AA*CC if (DD.LT.0) then qtest = .false. return else qtest = .true. EE = sqrt(DD) endif if (AA .eq. 0.) then CDEBUG Can this happen???? z = 9999. else if (backside) then if (AA .le. 0.) then z = (-BB + EE) / (2*AA) else z = (-BB - EE) / (2*AA) endif else if (AA .gt. 0.) then z = (-BB + EE) / (2*AA) else z = (-BB - EE) / (2*AA) endif endif zp = z * scale zp = zp + center(3) * * Surface normal comes from partial derivatives at this point if (.not. shadowspace) then qnorm(1) = QA*x + QD*y + QF*z + QG qnorm(2) = QB*y + QD*x + QE*z + QH qnorm(3) = QC*z + QF*x + QE*y + QI endif * return end CCC Convert ANISOU description of anisotropic displacement parameters CC into quadric surface enclosing a given probability volume C Returns -1 if the Uij are non-positive definite, 1 otherwise C function anitoquad( ANISOU, PROB, QUADRIC, EIGENS, EVECS) implicit NONE integer anitoquad real ANISOU(6), PROB, QUADRIC(10) real EIGENS(3), EVECS(4,4) c COMMON /ASSCOM/ noise, verbose integer noise logical verbose c real UU(4,4), UINV(4,4) integer i c real tinv4, det c c Save FPU traps later by checking that ANISOU is non-zero do i = 1,3 EIGENS(i) = 0.0 end do if (ANISOU(1).eq.0.and.ANISOU(2).eq.0.and.ANISOU(3).eq.0 .and. & ANISOU(4).eq.0.and.ANISOU(5).eq.0.and.ANISOU(6).eq.0) then anitoquad = -2 return end if c c Build matrix from Uij coefficients and invert it UU(1,1) = ANISOU(1) UU(2,2) = ANISOU(2) UU(3,3) = ANISOU(3) UU(4,4) = -(1/PROB**2) UU(1,2) = ANISOU(4) UU(2,1) = ANISOU(4) UU(2,3) = ANISOU(6) UU(3,2) = ANISOU(6) UU(1,3) = ANISOU(5) UU(3,1) = ANISOU(5) UU(1,4) = 0.0 UU(4,1) = 0.0 UU(2,4) = 0.0 UU(4,2) = 0.0 UU(3,4) = 0.0 UU(4,3) = 0.0 det = tinv4( UINV, UU ) c c and from that we extract the coefficients of the surface QUADRIC(1) = UINV(1,1) QUADRIC(2) = UINV(2,2) QUADRIC(3) = UINV(3,3) QUADRIC(4) = UINV(1,2) QUADRIC(5) = UINV(2,3) QUADRIC(6) = UINV(1,3) QUADRIC(7) = UINV(1,4) QUADRIC(8) = UINV(2,4) QUADRIC(9) = UINV(3,4) QUADRIC(10) = UINV(4,4) c c Find eigenvalues of the ellipsoid call jacobi( UU, 3, 4, EIGENS, EVECS ) c c Units of this matrix are A**2; we want values in A anitoquad = 1 do i = 1,3 if (EIGENS(i).gt.0.) then EIGENS(i) = sqrt(EIGENS(i)) else C write (noise,*) 'Non-positive definite ellipsoid!' EIGENS(i) = 0. anitoquad = -1 endif enddo c return end CCC Matrix manipulation routines for 4x4 homogeneous transformations CC C subroutine tmul4( C, A, B ) real C(4,4), A(4,4), B(4,4) integer i,j do i = 1,4 do j = 1,4 C(i,j) = A(i,1)*B(1,j) + A(i,2)*B(2,j) & + A(i,3)*B(3,j) + A(i,4)*B(4,j) enddo enddo return end subroutine trnsp4( B, A ) real B(4,4), A(4,4) integer i,j do i=1,4 do j=1,4 B(i,j) = A(j,i) enddo enddo return end CCC Matrix inversion for a 4x4 matrix A CC C function tinv4( AI, A ) real tinv4 real AI(4,4), A(4,4) c real TMP(4,4), D integer index(4) c do i=1,4 do j=1,4 TMP(i,j) = A(i,j) AI(i,j) = 0. enddo AI(i,i) = 1. enddo call ludcmp( TMP, 4, index, D ) tinv4 = D * TMP(1,1)*TMP(2,2)*TMP(3,3)*TMP(4,4) do j=1,4 call lubksb( TMP, 4, index, AI(1,j) ) enddo return end ************************************************************************ * Matrix inversion via LU decomposition * * adapted from Numerical Recipes in Fortran (1986) * ************************************************************************ * CCC input NxN matrix A is replaced by its LU decomposition CC output index(N) records row permutation due to pivoting C output D is parity of row permutations c subroutine ludcmp( A, n, index, D ) implicit NONE integer n,index(n) real A(n,n) real D c integer i,imax,j,k real aamax,dum,sum integer NMAX parameter (NMAX=10) real vv(NMAX) c d = 1. do i=1,n aamax = 0. do j=1,n if (abs(A(i,j)).gt.aamax) aamax = abs(A(i,j)) enddo call assert(aamax.ne.0.,'Singular matrix') vv(i) = 1. / aamax enddo c imax = 1 do j=1,n if (j.gt.1) then do i=1,j-1 sum = A(i,j) if (i.gt.1) then do k=1,i-1 sum = sum - A(i,k)*A(k,j) enddo A(i,j) = sum endif enddo endif aamax = 0. do i=j,n sum = A(i,j) if (j.gt.1) then do k=1,j-1 sum = sum - A(i,k)*A(k,j) enddo A(i,j) = sum endif dum = vv(i) * abs(sum) if (dum.ge.aamax) then imax = i aamax = dum endif enddo if (j.ne.imax) then do k=1,n dum = A(imax,k) A(imax,k) = A(j,k) A(j,k) = dum enddo d = -d vv(imax) = vv(j) endif index(j) = imax call assert(A(j,j).ne.0.,'Singular matrix') if (j.ne.n) then dum = 1. / A(j,j) do i=j+1,n A(i,j) = A(i,j) * dum enddo endif enddo return end CCC corresponding back-substitution routine CC C subroutine lubksb( A, N, index, B ) implicit NONE integer n, index(n) real A(n,n), B(n) c integer i,ii,j,ll real sum c ii = 0 do i=1,n ll = index(i) sum = B(ll) B(ll) = B(i) if (ii.ne.0) then do j=ii,i-1 sum = sum - A(i,j)*B(j) enddo else if (sum.ne.0.) then ii = i endif B(i) = sum enddo c do i=n,1,-1 sum = B(i) if (i.lt.n) then do j=i+1,n sum = sum - A(i,j)*B(j) enddo endif B(i) = sum / A(i,i) enddo return end ************************************************************************ * Find eigenvalues and eigenvectors of nxn symmetric matrix using * * cyclic Jacobi method. NP is (Fortran) physical storage dimension. * * On return A is destroyed, D contains eigenvalues,and each column of * * V is a normalized eigenvector * * Adapted from Numerical Recipes in Fortran (1986) * * We only need it for 3x3 symmetric matrices, so it's overkill. * ************************************************************************ CCC CC C subroutine jacobi( A, n, np, D, V ) PARAMETER (NMAX=4) c Machine dependent! (converge when off-diagonal sum is less than this) PARAMETER (TINY = 1.e-37) real A(np,np), D(n), V(np,np) real B(NMAX), Z(NMAX) c call assert(n.le.NMAX,'Matrix too big for eigenvector routine') c c Initialize V to identity matrix, B and D to diagonal of A do ip = 1,n do iq = 1,n V(ip,iq) = 0.0 enddo V(ip,ip) = 1.0 B(ip) = A(ip,ip) D(ip) = B(ip) Z(ip) = 0.0 enddo nrot = 0 c c 50 sweeps is never expected to happen; Press et al (1986) claim c 6 to 10 are typical for moderate matrix sizes c Empirical trials of rastep show 6 sweeps, 8-10 rotations do i = 1,50 sm = 0.0 do ip = 1,n-1 do iq = ip+1,n sm = sm+abs(A(ip,iq)) enddo enddo if (sm .lt. TINY) return c After 4 sweeps skip rotation if the off-diagonal is small if (i .lt. 4) then thresh = 0.2*sm/(n*n) else thresh = 0.0 endif do ip = 1,n-1 do iq = ip+1,n g = 100. * abs(A(ip,iq)) if ((i.gt.4) .and. & (abs(D(ip)) + g .eq. abs(D(ip))) .and. & (abs(D(iq)) + g .eq. abs(D(iq)))) then A(ip,iq) = 0.0 else if (abs(A(ip,iq)).gt.thresh) then h = D(iq) - D(ip) if (abs(h) + g .eq. abs(h)) then t = A(ip,iq) / h else theta = 0.5 * h / A(ip,iq) t = 1. / (abs(theta) + sqrt(1.+theta*theta)) if (theta.lt.0.) t = -t endif c = 1./sqrt(1.+t*t) s = t * c tau = s/(1.+c) h = t * A(ip,iq) Z(ip) = Z(ip) - h Z(iq) = Z(iq) + h D(ip) = D(ip) - h D(iq) = D(iq) + h A(ip,iq) = 0.0 do j = 1,ip-1 g = A(j,ip) h = A(j,iq) A(j,ip) = g - s*(h+g*tau) A(j,iq) = h + s*(g-h*tau) enddo do j = ip+1,iq-1 g = A(ip,j) h = A(j, iq) A(ip,j) = g - s*(h+g*tau) A(j,iq) = h + s*(g-h*tau) enddo do j = iq+1,n g = A(ip,j) h = A(iq,j) A(ip,j) = g - s*(h+g*tau) A(iq,j) = h + s*(g-h*tau) enddo do j = 1,n g = V(j,ip) h = V(j,iq) V(j,ip) = g - s*(h+g*tau) V(j,iq) = h + s*(g-h*tau) enddo nrot = nrot + 1 endif enddo enddo c c Update D with sum and reinitialize Z do ip = 1,n B(ip) = B(ip) + Z(ip) D(ip) = B(ip) Z(ip) = 0.0 enddo enddo c call assert(.false.,'Failed to find eigenvectors') return end c C This one really has nothing to do with quadrics per se, C but since it's invoked by qinp, both render and rastep C need to be able to see it. C Should really be in separate file of support routines C FUNCTION PERSP( Z ) REAL PERSP, Z COMMON /MATRICES/ XCENT, YCENT, SCALE, EYEPOS, SXCENT, SYCENT, & TMAT, TINV, TINVT, SROT, SRTINV, SRTINVT & ,RAFTER, TAFTER REAL XCENT, YCENT, SCALE, EYEPOS, SXCENT, SYCENT REAL TMAT(4,4), TINV(4,4), TINVT(4,4) REAL SROT(4,4), SRTINV(4,4), SRTINVT(4,4) REAL RAFTER(4,4), TAFTER(3) IF (Z/EYEPOS .GT. 0.999) THEN PERSP = 1000. ELSE PERSP = 1. / (1. - Z/EYEPOS) ENDIF RETURN END Raster3D_2.9-2/ribbon.f 0000644 0004727 0004727 00000012306 11327673235 013651 0 ustar champ champ C === RIBBON === C (extracted from frodo.tlb in CCP program package) C SUBROUTINE RIBBON(NRIB,RIBWID,NCHORD,OFFSET,NATOM) C ================================================== C C Generate guide points for protein ribbon, based on ideas on C Carson & Bugg, J.Molec.Graphics 4,121-122 (1986) C C Guide points for Bspline are generated along a line passing C through each CA and along the average of the two peptide planes C C NRIB number of strands in ribbon (maximum=MAXRIB=15) C RIBWID total ribbon width C NCHORD number of chords/residue C OFFSET amount to offset guide points away from CA positions C NATOM number of atoms stored in arrays C PARAMETER (MAXRIB=5,MAXRES=1500) PARAMETER (NOISE=0) DIMENSION GUIDE(4,MAXRES,MAXRIB) DIMENSION XCA(3,2),XO(3,2),A(3),B(3),C(3),D(3),E(3),F(3), . G(3),H(3),P(3) C C Maximum CA-CA distance **2 PARAMETER (DISMAX=6.**2) C IF(NATOM.LE.0) THEN WRITE(NOISE,1005) 1005 FORMAT(' No atoms selected') RETURN ENDIF C IF(NRIB.GT.MAXRIB) THEN WRITE(NOISE,1001) NRIB,MAXRIB 1001 FORMAT(' Too many ribbon strands',I6,' reset to ',I6) NRIB=MAXRIB ENDIF C WRITE(NOISE,1002) NRIB,RIBWID,NCHORD,OFFSET 1002 FORMAT(' Ribbon drawn with',I4,' strands, width ',F6.2, . 'A'/' Number of chords =',I3,', offset = ',F6.2,'A') C C Strand separation DRIB=0. IF(NRIB.GT.1) DRIB=RIBWID/(NRIB-1) RIB2=FLOAT(NRIB+1)/2. C NAT=1 C C Get first CA and O 1 CALL GETCAO(XCA(1,1),XO(1,1),NAT,NATOM,IERR) CEAM IF(NAT.LE.0) RETURN CEAM IF(IERR.NE.0) GO TO 1 IF(IERR.NE.0) RETURN I=0 C C Loop for residues 10 I=I+1 C Get CA and O for residue I+1 CALL GETCAO(XCA(1,2),XO(1,2),NAT,NATOM,IERR) C Set LEND = 1 for end of chain under 3 conditions: C (a) all atoms done; (b) one fo CA or O missing; (c) break in chain IF(NAT.LT.0.OR.IERR.NE.0) THEN LEND=1 ELSE LEND=0 ENDIF C IF(LEND.EQ.0) THEN C Not last one unless CA-CA distance too large C A is vector CAi to Ci+1 CALL VDIF(A,XCA(1,2),XCA(1,1)) IF(DOT(A,A).GT.DISMAX) LEND=1 ENDIF IF(LEND.EQ.0) THEN C Not last one C B is vector CAi to Oi CALL VDIF(B,XO(1,1),XCA(1,1)) C C = A x B; D = C x A CALL CROSS(A,B,C) CALL CROSS(C,A,D) CALL UNIT(D) C IF(I.EQ.1) THEN C First peptide, no previous one to average with CALL VSET(E,D) C No offset for first CA CALL ZEROI(P,3) ELSE C Not first, ribbon cross vector is average of peptide plane C with previous one CALL SCALEV(B,SIGN(1.,DOT(D,G)),D) CALL VSUM(E,G,B) C Offset is along bisector of CA-CA-CA vectors A (H is Ai-1) CALL VDIF(P,H,A) CALL UNIT(P) ENDIF ELSE C Last one, just use last plane CALL VSET(E,G) C No offset for last CA CALL ZEROI(P,3) ENDIF C Normalise vector E CALL UNIT(E) C WRITE(NOISE,1003) I,G,D,B,E C1003 FORMAT(' I,G,D,B,E',I4,4(3X,3F8.2)/) C C C Generate guide points CALL SCALEV(P,OFFSET,P) CALL VSUM(P,XCA(1,1),P) C DO 20,J=1,NRIB FR=(FLOAT(J)-RIB2)*DRIB CALL SCALEV(F,FR,E) CALL VSUM(GUIDE(1,I,J),P,F) C EAM - Maybe should be NAT-2 ?? guide(4,i,j) = NAT - 3 20 CONTINUE C C Store things for next residue CALL VSET(XCA(1,1),XCA(1,2)) CALL VSET(XO(1,1),XO(1,2)) CALL VSET(G,E) CALL VSET(H,A) C IF(LEND.EQ.0) GO TO 10 C NPT=I CALL RIBDRW(GUIDE,NRIB,MAXRES,NPT,NCHORD) C C Loop chains if required CEAM IF(NAT.GT.0) GO TO 1 IF (IERR.EQ.0) GOTO 1 C RETURN END C C SUBROUTINE pdb_GETCAO(XCA,XO,NAT,NATOM,IERR) C ======================================== C C Get coordinates of CA in XCA, O in XO, C Modified to read sequential CA and O records in PDB format from file C C On exit: NAT next atom C IERR =0 if succesfull, else = 1 C DIMENSION XCA(3),XO(3) C integer PDBFILE parameter (PDBFILE = 1) character*1 a1, rescode(2) character*3 resname(2) character*4 reclabel, atname integer resno(2) C ierr=0 read (pdbfile,2,end=100) reclabel, nat, atname, a1, resname(1), 1 a1, resno(1), rescode(1), xca(1), xca(2), xca(3) read (pdbfile,2,end=100) reclabel, nat, atname, a1, resname(2), 1 a1, resno(2), rescode(2), xo(1), xo(2), xo(3) 2 format(a4,2x,i5,1x,a4,a1,a3,1x,a1,i4,a1,3x,5f8.3,2f6.2,1x,i3) if (resname(1) .ne. resname(2)) ierr = 1 if (resno(1) .ne. resno(2)) ierr = 1 if (rescode(1) .ne. rescode(2)) ierr = 1 return 100 continue ierr = 1 nat = -1 return end SUBROUTINE GETCAO(XCA,XO,NAT,NATOM,IERR) C ======================================== C C Get coordinates of CA in XCA, O in XO, C modified to get coords from common /SPAM/ C C On exit: NAT next atom C IERR =0 if succesfull, else = 1 C DIMENSION XCA(3),XO(3) C parameter (MAXATOM=10000) common /SPAM/ natm, SPAM(4,MAXATOM), SCAM(MAXATOM) integer SCAM c if ((nat .gt. natm) .or. (nat .gt. natom-1)) then ierr = 1 CEAM nat = -1 return end if do i=1,3 xca(i) = spam(i,nat) xo(i) = spam(i,nat+1) end do nat = nat + 2 ierr = 0 return end subroutine zeroi( a, nwords ) integer*4 a(nwords) do i = 1,nwords a(i) = 0 end do return end Raster3D_2.9-2/html/ 0000755 0004727 0004727 00000000000 11350016745 013162 5 ustar champ champ Raster3D_2.9-2/html/rgbtext.html 0000644 0004727 0004727 00000000415 11327673235 015536 0 ustar champ champ
Click on a coloured ball to see its X11 and Raster3D RGB values.rings3d [-bases] [-protein] [-sugars] < infile.pdb > outfile.r3drings3d matches residue types from an internal list of residue and atom names. It will fail to find residues not in its list, and fail to recognize atoms with non-standard names.
cat $R3D_LIB/dna.colours dna.pdb | rods -radius 0.05 > temp.1 rings3d -bases < dna.pdb > temp.2 cat temp.1 temp.2 | render -tiff dna.tiff
label3d [-png [outfile.png]] < infile.r3d [ > outfile.png ] label3d -tiff [outfile.tiff < infile.r3d [ > outfile.tiff ]
The syntax of the label3d command in version 2.6d has been changed to match that of the render command. Input is from stdin, output is to stdout unless given explicitly as a parameter to the -tiff or -png switches.
Unfortunately, the Raster3D render program cannot process labels. To overcome this lack, earlier Raster3D distributions included an auxilliary program r3dtops that complements render in that it can process the labels but not the graphics objects. The r3dtops code is now part of the render program itself, and is invoked if the -labels command line switch is present. In this case the labels are converted to PostScript commands and placed in a file label3d.ps. The label3d script automates the process of rendering the image, running the resulting PostScript file through ghostscript, and then recombining the two component images into a single TIFF or PNG image containing both the molecular graphics objects and the associated labels.
The label3d script requires the ImageMagick image processing package, and ghostscript.
! ! File "animate.mol" ! MOLSCRIPT V1.4 description file for an animation ! plot window 100. ; slab 100. ; ! ! Read in protein coordinates, center and rotate to desired viewpoint ! read PROTEIN "protein.pdb"; transform atom * by centre position atom * by rotation z 5.0 by rotation x 33.0 @frame_rotation.mol ; ! ! Secondary structure ! set planecolour hsb 0.52 0.8 1.0 ; set plane2colour hsb 0.52 0.9 0.6 ; set linecolour hsb 0.52 1.0 0.9 ; strand from A4 to A9 ; turn from A9 to A13 ; helix from A13 to A19 ; coil from A19 to A41 ; [and so on and so forth]
Your picture may look very beautiful when it fills the whole screen, but remember that most people looking at your animation will be using a machine+viewer combination that is very slow. It is best not to make your animated image large than, say, 256x256 pixels. Size is somewhat less of a problem for MPEG animations than for animated GIF images.
#!/usr/local/bin/perl # # open (STDERR, ">animate.log"); # Frame: for ($i = 0.0; $i < 360.0; $i += 3.0) { open(ROTATION, "> frame_rotation.mol"); printf ROTATION "by rotation y %6.1f \n", $i; close(ROTATION); $outfile = sprintf( "frame_%3.3d.jpeg", $i ) ; $molscript = '/usr/local/bin/molscript -r' ; $render = '/usr/local/bin/render -jpeg' ; $command = "$molscript < animate.mol | $render > $outfile" ; system '/bin/echo', $command ; system "/bin/csh", "-c", "$command" ; }
convert -delay 15 -loop 0 frame_*.jpeg movie.gifThe -delay parameter sets a minimum display time per frame in 0.01 seconds. The -loop 0 sets a flag requesting a display program to loop over the frames repeatedly.
mpeg_encode mpeg_encoding.datThe mpeg_encode program is available from the Berkeley Multimedia Research Center. The entire process, including input file names, encoding parameters, output file name, etc, etc, is all specified in the *.dat file. Here is one that worked for me, but I don't guarantee that the parameters are at all optimal!
# # file "mpeg_encoding.dat" # INPUT_DIR . INPUT frame_*.jpeg [000-360+3] END_INPUT OUTPUT movie.mpeg BASE_FILE_FORMAT JPEG INPUT_CONVERT * PATTERN IBPBB FORCE_ENCODE_LAST_FRAME SLICES_PER_FRAME 1 GOP_SIZE 10 PIXEL HALF RANGE 2 IQSCALE 5 PQSCALE 10 BQSCALE 15 REFERENCE_FRAME DECODED PSEARCH_ALG LOGARITHMIC BSEARCH_ALG CROSS2
animate movie.gifor
mpeg_play -quiet -dither color movie.mpegNetscape is capable of displaying animated GIF files also, but the performance is much slower than the ImageMagick animate command. (Actually the animate command also is slow during the first couple of loops through the movie, but once all the frames are in local cache memory it whips right along. Netscape rereads the file each time, so it never speeds up due to repetition). You can configure Netscape to trigger mpeg_play as a helper application.
This approach works nicely with file indirection in the render input file. One could, for example, fade a surface in or out by gradually changing its degree of transparency. To do this you would describe the surface in the main input file as
@transparent.r3d @surface.r3d 9 End transparentAnd successive iterations of the animation script would overwrite the degree of transparency sepecified in "transparent.r3d" in much the same way that the rotation angle was changed in the example listed above.
Before getting too fancy you might want to look into molecular graphics packages specifically designed for animation, for example the GRAMPS language by TJ O'Donnell and AJ Olson (1981) [Computer Graphics 15:133-142]. The perl+Raster3D combination is probably sufficient for animations simple enough to view via the web, however.
- Ethan A Merritt, Sept 1997
Back to top
Raster3D homepage
Raster3D_2.9-2/html/r3d_stereo7.jpeg 0000644 0004727 0004727 00000066301 11327673235 016206 0 ustar champ champ JFIF ,, C
C
" B !1"AQR2aq#Bb$3 CS%4 9 !1AQaq"2RBb#$3r ? )\Ifb[9'`rNϐ9
1L$L+}5q]"cZa!.ZN);U.
/&McaYo}վHm
Vp-oG;}s_WrN]ڇQn/c!+K\ ߎuV)SX~E-.Cr5qY+LhV) zlZQJ;(ZŽ3aX*H.%17-9q