File: rods.f

package info (click to toggle)
raster3d 3.0-3-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 4,916 kB
  • ctags: 1,557
  • sloc: fortran: 9,536; ansic: 1,060; makefile: 318; sh: 250; csh: 15
file content (507 lines) | stat: -rw-r--r-- 15,018 bytes parent folder | download | duplicates (5)
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
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
      PROGRAM RODS
*------------------------------------------------------------------------------
*       Program to set up input for RENDER with CYLINDERs drawn between
*	each pair of atoms lying closer than 0.6 * (sum of VanderWaals radii). 
*	This program is the same as SETUP, except for what is generated.
*	Input matrix or angles are taken from setup.matrix or setup.angles
*	(NB: same files as setup)
*
* Eric Swanson   Oct 1991
*	Modified to generate cylinders with half bond colors, where needed.
* EAM Feb 1997
*	-radius XX to set cylinder radius
* EAM Sep 1997
*	-default colors; option for coloring by B-value
*	-more generous output formats (FORMATs 130 and 140)
* EAM Jun 1999
*	-brad XX to set ball radius as fraction of Van der Waals radius
* EAM Jul 1999
*	don't draw bonds across alternate chain locations
*
*------------------------------------------------------------------------------
      INCLUDE 'VERSION.incl'
*
*     I/O units for colour/co-ordinate input, specs output, user output
      INTEGER INPUT, OUTPUT, NOISE
      PARAMETER (INPUT=5, OUTPUT=6, NOISE=0)
      PARAMETER (MAXCOL=5000, MAXATM=100000)
      REAL RGB(3,MAXCOL),VDW(MAXCOL)
      REAL SPAM(6,MAXATM)
      REAL CEN(3)
      CHARACTER*24 MASK(MAXCOL),TEST
      CHARACTER*80 ATOM(MAXATM),CARD
      LOGICAL MATCH
C
C	flags include 
C		-b (ball and stick)
C		-h (suppress header records in output)
C		-radius XX (set cylinder radius)
C		-brad XX (set ball radius as fraction of VdW)
C
      character*64 options
      logical      bflag, hflag, bcflag, brflag
      real	   cylrad, ballrad
c
c	Read in 3x3 view matrix from file setup.matrix.  
c	Matrix is applied before finding translation, center, and scale.  
c	Afterwards the input matrix to RENDER is therefore the identity matrix.
C                                                     
	common /matrix/ matrix, coords
	real		matrix(3,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
	bflag  = .FALSE.
	bcflag = .FALSE.
	hflag  = .FALSE.
	brflag = .FALSE.
	cylrad = 0.2
	ballrad= 0.2
	narg  = iargc()
	i = 1
  500	continue
            call getarg( i, options )
            if (options(1:2) .eq. '-h') hflag = .true.
            if (options(1:5) .eq. '-Bcol') then
                bcflag = .true.
                i = i + 1
                if (i.gt.narg) goto 701
                call getarg( i, options )
                read (options,*,err=701) Bmin
                i = i + 1
                if (i.gt.narg) goto 701
                call getarg( i, options )
                read (options,*,err=701) Bmax
            endif
            if (options(1:2) .eq. '-b') bflag = .true.
	    if (options(1:2) .eq. '-r') then
		i = i + 1
		if (i.gt.narg) goto 701
		call getarg( i, options )
		read (options,*,err=701) cylrad
		if (cylrad.le.0) stop 'illegal radius value'
	    end if
	    if (options(1:3) .eq. '-br') then
		i = i + 1
		if (i.gt.narg) goto 701
		call getarg( i, options )
		read (options,*,err=701) ballrad
		if (ballrad.le.0) stop 'illegal ball radius value'
		bflag = .true.
	    end if
	i = i + 1
	if (i.le.narg) goto 500
c
	goto 799
  701	write (noise,'(A)')
     &	'syntax: rods [-h] [-b] [-Bcolor Bmin Bmax] [-radius R]'
	call exit(-1)
  799	continue
c
      write (noise,*) 'Raster3D rods program ',VERSION
      if (bcflag) then
        write (noise,*) 'Atom colors will be assigned based on Biso'
        write (noise,*) '    from dark blue = Bmin =', Bmin
        write (noise,*) '      to light red = Bmax =', Bmax
      endif
c
C
	do i=1,3
	do j=1,3
	    matrix(i,j)=0.
	enddo
	matrix(i,i)=1.
	enddo
	call view_matrix
c
      if (.not. hflag) then
	WRITE(OUTPUT,'(A,A)') 'rods ',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'
	WRITE(OUTPUT,'(A)') '0 0 0     black background'
	WRITE(OUTPUT,'(A)') 'F         no, shadowed rods look funny'
	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)',ERR=49) 
     &	       MASK(NCOL), (RGB(I,NCOL),I=1,3),VDW(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
*     Problems reading input record
49	continue
	write(noise,*) 'rods: Cannot parse input record ',CARD
	call exit(-1)
*     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), VDW(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)',err=49) X,Y,Z
c EAM Oct88
            READ(CARD,'(30X,3F8.3,6X,F8.2)',err=49) coords, Biso
		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 = VDW(ICOL)
            SPAM(1,IATM) = X
            SPAM(2,IATM) = Y
            SPAM(3,IATM) = Z
            SPAM(4,IATM) = RAD
            SPAM(5,IATM) = ICOL
	    SPAM(6,IATM) = Biso
            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
C	Here's the real loop.  
C	Look for pairs closer to each other than 0.60 times the
C	sum of the vanderWaals radii.
C	Draw all cylinders with 0.2A cylindrical radius.
C	For ball and stick pictures, shrink vanderWaals radius
C	of balls by 0.20
C	If two atoms of different colors are bonded, make half-bond
C	cylinders with each color.
C
      CLOSE = 1.6 * 1.6
C
      IF (BFLAG) THEN
      DO 135 IATM=1,NATM
	RAD  = SPAM(4,IATM) * ballrad
	ICOL = SPAM(5,IATM)
	if (bcflag) then
	    call B2RGB( SPAM(6,IATM), Bmin, Bmax, RED, GREEN, BLUE )
	    RED   = RED*RED
	    GREEN = GREEN*GREEN
	    BLUE  = BLUE*BLUE
	else
	    RED   = RGB(1,ICOL)
	    GREEN = RGB(2,ICOL)
	    BLUE  = RGB(3,ICOL)
	endif
	WRITE(OUTPUT,130)
     2         SPAM(1,IATM),SPAM(2,IATM),SPAM(3,IATM),RAD,
     3         RED,GREEN,BLUE
C130	FORMAT(1H2,/,7f8.3)
130	FORMAT(1H2,/,7(1X,F8.3))
135   CONTINUE
      ENDIF
C
      DO 160 IATM=1,NATM
      DO 150 JATM=IATM+1,NATM
	DX = SPAM(1,IATM) - SPAM(1,JATM)
	DY = SPAM(2,IATM) - SPAM(2,JATM)
	DZ = SPAM(3,IATM) - SPAM(3,JATM)
	DIST  = DX*DX + DY*DY + DZ*DZ
	CLOSE = 0.6 * (SPAM(4,IATM) + SPAM(4,JATM)) 
	CLOSE = CLOSE**2
	IF (ATOM(IATM)(17:17).NE.' ' .AND. ATOM(JATM)(17:17).NE.' '
     &     .AND. ATOM(IATM)(17:17).NE.ATOM(JATM)(17:17)) GOTO 150
c
c 4-Feb-2000	also force chain ID's to be the same
c
	IF (ATOM(IATM)(22:22).NE.' ' .AND. ATOM(JATM)(22:22).NE.' '
     &     .AND. ATOM(IATM)(22:22).NE.ATOM(JATM)(22:22)) GOTO 150
	IF (DIST .LE. CLOSE) THEN
	  if (bcflag) then
	    ICOL = 1
	    JCOL = 2
	    call B2RGB( SPAM(6,IATM), Bmin, Bmax, RED, GREEN, BLUE )
	    RGB(1,ICOL) = RED*RED
	    RGB(2,ICOL) = GREEN*GREEN
	    RGB(3,ICOL) = BLUE*BLUE
	    call B2RGB( SPAM(6,JATM), Bmin, Bmax, RED, GREEN, BLUE )
	    RGB(1,JCOL) = RED*RED
	    RGB(2,JCOL) = GREEN*GREEN
	    RGB(3,JCOL) = BLUE*BLUE
	  else
	    ICOL = SPAM(5,IATM)
	    JCOL = SPAM(5,JATM)
	  endif
	  IF(ICOL.EQ.JCOL) THEN
	    WRITE(OUTPUT,140)
     1         SPAM(1,IATM),SPAM(2,IATM),SPAM(3,IATM),CYLRAD,
     2         SPAM(1,JATM),SPAM(2,JATM),SPAM(3,JATM),CYLRAD,
     3         RGB(1,ICOL),RGB(2,ICOL),RGB(3,ICOL)
     	  else if (bcflag) then
	    write(output,140)
     1         SPAM(1,IATM),SPAM(2,IATM),SPAM(3,IATM),CYLRAD,
     2         SPAM(1,JATM),SPAM(2,JATM),SPAM(3,JATM),CYLRAD,
     3         RGB(1,ICOL),RGB(2,ICOL),RGB(3,ICOL)
     	    write(output,141)
     1	       RGB(1,ICOL),RGB(2,ICOL),RGB(3,ICOL),
     2	       RGB(1,JCOL),RGB(2,JCOL),RGB(3,JCOL),
     3         0, 0, 0
	  ELSE
	    DO 136 K=1,3
136	    CEN(K) = (SPAM(K,IATM)+SPAM(K,JATM))/2
	    WRITE(OUTPUT,140)
     1         SPAM(1,IATM),SPAM(2,IATM),SPAM(3,IATM),CYLRAD,
     2         CEN(1),CEN(2),CEN(3),CYLRAD,
     3         RGB(1,ICOL),RGB(2,ICOL),RGB(3,ICOL)
	    WRITE(OUTPUT,140)
     1         CEN(1),CEN(2),CEN(3),CYLRAD,
     2         SPAM(1,JATM),SPAM(2,JATM),SPAM(3,JATM),CYLRAD,
     3         RGB(1,JCOL),RGB(2,JCOL),RGB(3,JCOL)
	  ENDIF
	ENDIF

C140   FORMAT(1H3,/,11f8.3)
140   FORMAT(1H3,/,2(1X,F8.3,1X,F8.3,1X,F8.3,1X,F7.3),3F7.3)
141   format(2H17,/3(1X,3F6.3))
150   CONTINUE
160   CONTINUE
C
C
C
	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, coords
	real		matrix(3,3), coords(3)
c
	real		phiX, phiY, phiZ
	integer    noise
	parameter (noise = 0)
	parameter (R2D = 180./3.1415927)

	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
		close (3)
		write (noise,2) phiZ, phiY, phiX
		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)

    	write (noise,*) ' No view matrix or angles provided'
	return
	end

CCC     Return RGB triple that runs from dark blue at Bmin
CC      to light red at Bmax
C
	subroutine B2RGB( Biso, Bmin, Bmax, R, G, B )
	real              Biso, Bmin, Bmax, R, G, B
c
	real fraction, h, s, v
c
	fraction = (Biso-Bmin) / (Bmax-Bmin)
	if (fraction.lt.0.) fraction = 0.
	if (fraction.gt.1.) fraction = 1.
        h = 240. * (1.-fraction)
        s = 0.8
        v = 0.5 + fraction/2.
        call hsv2rgb( h, s, v, r, g, b )
        return
	end


CCC	Color format conversion from Hue/Saturation/Value to Red/Green/Blue
CC	minimal (i.e. NO) error checking
C
	subroutine hsv2rgb( h, s, v, r, g, b )
	real                h, s, v, r, g, b
c
	real    f, p, q, t
	integer i
c
	i = h /60.
	f = h/60. - float(i)
	p = v * (1. - s)
	q = v * (1. - s*f)
	t = v * (1. - s*(1. - f))
	if (i.eq.5) then
	    r = v
	    g = p
	    b = q
	else if (i.eq.4) then
	    r = t
	    g = p
	    b = v
	else if (i.eq.3) then
	    r = p
	    g = q
	    b = v
	else if (i.eq.2) then
	    r = p
	    g = v
	    b = t
	else if (i.eq.1) then
	    r = q
	    g = v
	    b = p
	else
	    r = v
	    g = t
	    b = p
	endif
	return 
	end