1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
|
PROGRAM BALLS
*
* Program to set up input for RENDER
*
* This program takes a Brookhaven PDB-format file of atomic coordinates
* concatenated with a "colours" file that specifies the colouring and spherical
* radius of atoms according to atom type, residue type, or any other criterion,
* and produces a file that can be used directly as input to RENDER.
*
* Usage: cat colors.pdb protein.pdb | balls [-h] | render
*
* auxiliary files: setup.matrix optional file containing 3x3 view matrix
* setup.angles optional file defining view matrix
* in terms of 3 rotation angles
*
* I/O units for colour/co-ordinate input, specs output, user output
*
INCLUDE 'VERSION.incl'
*
INTEGER INPUT, OUTPUT, NOISE
PARAMETER (INPUT=5, OUTPUT=6, NOISE=0)
PARAMETER (MAXCOL=5000, MAXATM=300000)
REAL RGB(3,MAXCOL),RADIUS(MAXCOL)
REAL SPAM(7,MAXATM)
CHARACTER*24 MASK(MAXCOL),TEST
CHARACTER*80 ATOM(MAXATM),CARD
LOGICAL MATCH
logical hflag
character*80 flags
c
C Ethan Merritt Oct 1988
C Modified to read in 3x3 view matrix (e.g. from CCP FRODO view command)
C from file setup.matrix. Matrix is applied before
C finding translation, center, and scale. Afterwards the input matrix
C to RENDER is therefore the identity matrix.
C
common /matrix/ matrix, postrn, coords
real*4 matrix(3,3), postrn(3), coords(3)
C
C Default to CPK colors and VDW radii
character*60 defcol(7)
data defcol /
& 'COLOUR#######C################ 0.625 0.625 0.625 1.70',
& 'COLOUR#######N################ 0.125 0.125 1.000 1.60',
& 'COLOUR#######O################ 0.750 0.050 0.050 1.50',
& 'COLOUR#######S################ 1.000 1.000 0.025 1.85',
& 'COLOUR#######H################ 1.000 1.000 1.000 1.20',
& 'COLOUR#######P################ 0.400 1.000 0.400 1.80',
& 'COLOUR######################## 1.000 0.000 1.000 2.00'
& /
c
3 format(a,a)
c
do i=1,3
do j=1,3
matrix(i,j)=0.
enddo
matrix(i,i)=1.
enddo
call view_matrix
c
c Ethan Merritt Apr 1992
c -h option suppresses header records in output
c
hflag = .false.
narg = iargc()
do i = 1, narg
call getarg( i, flags )
if (flags(1:2) .eq. '-h') hflag = .true.
end do
c
if (.not. hflag) then
WRITE(OUTPUT,'(A,A)') 'balls - Raster3D ', VERSION
WRITE(OUTPUT,'(A)') '80 64 tiles in x,y'
WRITE(OUTPUT,'(A)') ' 8 8 pixels (x,y) per tile'
WRITE(OUTPUT,'(A)') '4 anti-aliasing 3x3 -> 2x2 pixels'
WRITE(OUTPUT,'(A)') '0 0 0 black background'
WRITE(OUTPUT,'(A)') 'T yes, I LIKE shadows!'
WRITE(OUTPUT,'(A)') '25 Phong power'
WRITE(OUTPUT,'(A)') '0.15 secondary light contribution'
WRITE(OUTPUT,'(A)') '0.05 ambient light contribution'
WRITE(OUTPUT,'(A)') '0.25 specular reflection component'
WRITE(OUTPUT,'(A)') '4.0 eye position'
WRITE(OUTPUT,'(A)') '1 1 1 main light source position'
end if
c
ASPECT = 1280./1024.
NCOL = 0
NATM = 0
10 CONTINUE
READ(INPUT,'(A80)',END=50) CARD
IF (CARD(1:4).EQ.'COLO') THEN
NCOL = NCOL + 1
IF (NCOL.GT.MAXCOL) THEN
WRITE(NOISE,*) 'Colour table overflow. Increase ',
& 'MAXCOL and recompile.'
STOP 10
ENDIF
READ(CARD,'(6X,A24,3F8.3,F6.2)') MASK(NCOL),
& (RGB(I,NCOL),I=1,3),RADIUS(NCOL)
ELSEIF (CARD(1:4).EQ.'ATOM'.OR.CARD(1:4).EQ.'HETA') THEN
NATM = NATM + 1
IF (NATM.GT.MAXATM) THEN
WRITE(NOISE,*) 'Atom array overflow. Increase ',
& 'MAXATM and recompile.'
STOP 20
ENDIF
ATOM(NATM) = CARD
ELSEIF (CARD(1:3).EQ.'END') THEN
GO TO 50
ENDIF
GO TO 10
* Come here when EOF or 'END' record is reached
50 CONTINUE
IF (NATM.EQ.0) THEN
WRITE(NOISE,*) 'No atoms in input.'
STOP 30
ENDIF
* Load default colors after any that were read in
IF (NCOL.LT.MAXCOL-8) THEN
DO i = 1,7
NCOL = NCOL + 1
READ(defcol(i),'(6X,A24,3F8.3,F6.2)') MASK(NCOL),
& (RGB(J,NCOL),J=1,3), RADIUS(NCOL)
ENDDO
ENDIF
*
IF (NCOL.EQ.0) THEN
WRITE(NOISE,*) 'No colours in input.'
STOP 40
ENDIF
XMAX = -1E20
XMIN = 1E20
YMAX = -1E20
YMIN = 1E20
ZMAX = -1E20
ZMIN = 1E20
DO 100 IATM=1,NATM
CARD = ATOM(IATM)
TEST = CARD(7:30)
DO 80 ICOL=1,NCOL
IF (MATCH(TEST,MASK(ICOL))) THEN
c READ(CARD,'(30X,3F8.3)') X,Y,Z
c EAM Oct88
READ(CARD,'(30X,3F8.3)') coords
x = coords(1)*matrix(1,1) + coords(2)*matrix(2,1)
1 + coords(3)*matrix(3,1)
y = coords(1)*matrix(1,2) + coords(2)*matrix(2,2)
1 + coords(3)*matrix(3,2)
z = coords(1)*matrix(1,3) + coords(2)*matrix(2,3)
1 + coords(3)*matrix(3,3)
c EAM Oct88
RAD = RADIUS(ICOL)
SPAM(1,IATM) = X
SPAM(2,IATM) = Y
SPAM(3,IATM) = Z
SPAM(4,IATM) = RAD
SPAM(5,IATM) = RGB(1,ICOL)
SPAM(6,IATM) = RGB(2,ICOL)
SPAM(7,IATM) = RGB(3,ICOL)
XMAX = MAX(XMAX,X+RAD)
XMIN = MIN(XMIN,X-RAD)
YMAX = MAX(YMAX,Y+RAD)
YMIN = MIN(YMIN,Y-RAD)
ZMAX = MAX(ZMAX,Z+RAD)
ZMIN = MIN(ZMIN,Z-RAD)
GO TO 100
ENDIF
80 CONTINUE
WRITE(NOISE,*) 'No colour table mask matches this atom:'
WRITE(NOISE,*) ATOM(IATM)
STOP 90
100 CONTINUE
XMID = (XMAX+XMIN)/2.
YMID = (YMAX+YMIN)/2.
ZMID = (ZMAX+ZMIN)/2.
TX = -XMID
TY = -YMID
TZ = -ZMID
IF (ASPECT.GE.1.) THEN
* The X direction is wider than the Y
XROOM = ASPECT
YROOM = 1.
ZROOM = 2.
ELSE
XROOM = 1.
YROOM = ASPECT
ZROOM = 2.
ENDIF
XSPAN = XMAX-XMIN
YSPAN = YMAX-YMIN
ZSPAN = ZMAX-ZMIN
SCALE = MAX(XSPAN/XROOM,YSPAN/YROOM,ZSPAN/ZROOM)
* Leave a little extra room as a border:
SCALE = SCALE / 0.90
c
if (.not. hflag) then
WRITE(OUTPUT,120) TX,TY,TZ,SCALE
120 FORMAT('1 0 0 0 input co-ordinate + radius transformation'/
& '0 1 0 0'/
& '0 0 1 0'/
& 4F10.3)
WRITE(OUTPUT,'(A)') '3 mixed object types'
WRITE(OUTPUT,'(A)') '*'
WRITE(OUTPUT,'(A)') '*'
WRITE(OUTPUT,'(A)') '*'
end if
c
DO 150 IATM=1,NATM
SPAM(1,IATM) = SPAM(1,IATM) + postrn(1)
SPAM(2,IATM) = SPAM(2,IATM) + postrn(2)
SPAM(3,IATM) = SPAM(3,IATM) + postrn(3)
WRITE(OUTPUT,140) (SPAM(I,IATM),I=1,7)
140 FORMAT(1H2,/,7(1X,F8.3))
150 CONTINUE
write (noise,'(/)')
write (noise,156) 'X min max:', XMIN, XMAX
write (noise,156) 'Y min max:', YMIN, YMAX
write (noise,156) 'Z min max:', ZMIN, ZMAX
write (noise,156) ' scale:', SCALE
156 format(1x,a,3f8.2)
END
LOGICAL FUNCTION MATCH (SUBJ, MASK)
CHARACTER*24 SUBJ,MASK
MATCH = .FALSE.
DO 10 I = 1, 24
IF (SUBJ(I:I).NE.MASK(I:I) .AND. MASK(I:I).NE.'#') RETURN
10 CONTINUE
MATCH = .TRUE.
RETURN
END
subroutine view_matrix
c
common /matrix/ matrix, postrn, coords
real*4 matrix(3,3), postrn(3), coords(3)
c
real*4 phiX, phiY, phiZ
integer noise
parameter (noise = 0)
parameter (R2D = 180./3.1415927)
postrn(1) = 0.
postrn(2) = 0.
postrn(3) = 0.
open (unit=3, file='setup.matrix', status='OLD', err=100)
read (3,*) ((matrix(i,j),i=1,3),j=1,3)
write (noise,'(1x,3f9.5)') ((matrix(i,j),i=1,3),j=1,3)
close (3)
det = matrix(1,1) * matrix(2,2) * matrix(3,3)
1 + matrix(1,2) * matrix(2,3) * matrix(3,1)
2 + matrix(2,1) * matrix(3,2) * matrix(1,3)
3 - matrix(1,3) * matrix(2,2) * matrix(3,1)
4 - matrix(1,2) * matrix(2,1) * matrix(3,3)
5 - matrix(1,1) * matrix(2,3) * matrix(3,2)
write (noise,'('' determinant ='',f8.3)') det
phiX = atan2( -matrix(3,2), matrix(3,3) )
phiY = atan2( matrix(3,1), matrix(3,3) / cos(phiX) )
phiZ = atan2( -matrix(2,1), matrix(1,1) )
write (noise,3) ' View Angles from matrix',' '
write (noise,2) phiZ*R2D, phiY*R2D, phiX*R2D
return
100 continue
open (unit=3, file='setup.angles', status='OLD', err=200)
read (3,*) phiZ, phiY, phiX
read (3,*,err=101,end=101) postrn(1), postrn(2), postrn(3)
101 continue
close (3)
write (noise,2) phiZ, phiY, phiX
write (noise,4) postrn(1), postrn(2), postrn(3)
cx = cos(phiX/R2D)
sx = sin(phiX/R2D)
cy = cos(phiY/R2D)
sy = sin(phiY/R2D)
cz = cos(phiZ/R2D)
sz = sin(phiZ/R2D)
matrix(1,1) = cz*cy
matrix(1,2) = sz*cx + cz*sy*sx
matrix(1,3) = sz*sx - cz*sy*cx
matrix(2,1) = -sz*cy
matrix(2,2) = cz*cx - sx*sy*sz
matrix(2,3) = cz*sx + sz*sy*cx
matrix(3,1) = sy
matrix(3,2) = -sx*cy
matrix(3,3) = cx*cy
write (noise,3) ' View Matrix from angles',' '
write (noise,'(1x,3f9.5)') ((matrix(i,j),i=1,3),j=1,3)
return
200 continue
2 format(1x,' phiZ =',f8.2,' phiY =',f8.2,' phiX =',f8.2)
3 format(/a,a)
4 format(1x,' tranX =',f8.2,' tranY =',f8.2,' tranZ =',f8.2)
write (noise,*) ' No view matrix or angles provided'
return
end
|