angepapa commited on
Commit
fb5cccc
·
verified ·
1 Parent(s): 5814589

Upload 42 files

Browse files
dms/GNUmakefile ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LIBDIR is the directory where a 'dms' subdirectory will be created,
2
+ # in which the server binary (dmsd) and various support files will be installed
3
+ LIBDIR = /usr/local/lib
4
+
5
+ # BINDIR is the directory where the dms binary will be installed
6
+ BINDIR = /usr/local/bin
7
+
8
+ # PDBINC is the directory where the 'pdb.h' file from the UCSF PDB-reading
9
+ # library got installed. 'pdb.h' is not installed by default by that
10
+ # distribution, so you will have to install it by hand into PDBINC
11
+ PDBINC = libpdb
12
+
13
+ # PDBLIB is the directory where libpdb.a from the UCSF PDB-reading library
14
+ # got installed.
15
+ PDBLIB = libpdb
16
+
17
+ # MANDIR is the directory where the dms.1 manual page will be installed
18
+ MANDIR = /usr/local/man/man1
19
+
20
+ ifeq ($(shell test -e /bin/cygwin1.dll && echo found),found)
21
+ PROG = dms.exe
22
+ else
23
+ PROG = dms
24
+ endif
25
+
26
+ # you should not need to modify any of the following
27
+ DESTLIB = ${LIBDIR}/dms/
28
+ SERVER = ${DESTLIB}dmsd
29
+ DEFS = -DDESTLIB=\"${DESTLIB}\" -DSERVER_PATH=\"$(SERVER)\"
30
+ OPT = -O
31
+ CFLAGS = ${DEFS} -I${PDBINC} ${OPT}
32
+
33
+ OBJS = compute.o fwritev.o input.o ms.o output.o emalloc.o tokenize.o
34
+
35
+ all: ${PROG}
36
+ cd dmsd ; ${MAKE} LIBDIR=${LIBDIR} OPT="${OPT}"
37
+
38
+ ${PROG}: pdb ${OBJS}
39
+ ${CC} -L${PDBLIB} -o ${PROG} ${OBJS} -lpdb
40
+
41
+ pdb:
42
+ cd libpdb ; ${MAKE} OPT="${OPT}"
43
+
44
+ install: ${PROG} maninstall afterinstall
45
+ afterinstall: realinstall
46
+ realinstall: beforeinstall
47
+ cp ${PROG} ${BINDIR}
48
+ -strip ${BINDIR}/${PROG}
49
+
50
+ maninstall:
51
+ -rm -f ${MANDIR}/dms.1
52
+ cp dms.1 ${MANDIR}
53
+
54
+ beforeinstall:
55
+ if [ -d ${DESTLIB} ]; then true ; else mkdir ${DESTLIB}; fi
56
+ cd dmsd ; ${MAKE} LIBDIR=${LIBDIR} install
57
+
58
+ afterinstall:
59
+ cp radii.proto ${DESTLIB}radii
60
+
61
+ clean:
62
+ /bin/rm -f ${OBJS}
63
+ cd libpdb ; ${MAKE} clean
64
+ cd dmsd ; ${MAKE} clean
65
+
66
+ spotless:
67
+ /bin/rm -f ${OBJS} ${PROG}
68
+ cd libpdb ; ${MAKE} spotless
69
+ cd dmsd ; ${MAKE} spotless
dms/README ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Description:
2
+
3
+ DMS is "Distributed MS", a version of the solvent-accessible
4
+ surface computation program. This version splits the
5
+ computation into independent units and executes each unit on a
6
+ dms server which runs somewhere on the local area network.
7
+
8
+ Dms is distributed as open source, subject to the legal
9
+ restrictions noted at the end of this file.
10
+
11
+ Consult the dms manual page (dms.1) for details on usage.
12
+
13
+ Prerequisites:
14
+
15
+ You need GNU make and a C compiler to build this software.
16
+ When we refer to the "make" command below, you should use
17
+ the actual GNU make executable file name. On Linux and
18
+ Cygwin, the GNU make executable is called "make". On IRIX,
19
+ the GNU make executable is part of the free software installed
20
+ in /usr/freeware/bin and is called "gmake".
21
+
22
+ This software has been built on Red Hat Enterprise Linux
23
+ and on Windows XP Professional with Cygwin.
24
+
25
+ Installation:
26
+
27
+ Edit "GNUmakefile" and change LIBDIR and BINDIR to the
28
+ appropriate location for your system.
29
+
30
+ At this point, you could get away with typing "make install"
31
+ and be done. You may or may not want to do the following
32
+ before that:
33
+
34
+ Edit the file "dms_param.h" and set the appropriate
35
+ parameters to the desired values. You may need to twiddle with
36
+ the last few parameters if you want to get the optimal performance.
37
+
38
+ By default, dms runs on the local host only, instead of running
39
+ in parallel on multiple hosts. If this behavior is sufficient
40
+ for your needs, type "make install" and stop here. Otherwise...
41
+
42
+ Edit the file "dms_servers.proto" to contain a list of hosts that
43
+ will run dms servers. All machines participating in a single dms
44
+ calculation must be binary compatible with the machine initiating
45
+ the calculation. For sites with multiple machine architectures,
46
+ this may mean that there are several distinct "pools" of dms
47
+ servers, for calculations initiated by a machine within a pool.
48
+ Now type "make install".
49
+
50
+ Dms must be installed as above on each server machine, and on each
51
+ such machine the following steps must be performed as root:
52
+
53
+ 1) Register the 'dms' service on the host. On most UNIX systems
54
+ this is done by editing /etc/services and adding the following
55
+ line:
56
+ dms 14148/tcp
57
+
58
+ On Mac OS X systems, instead execute the following command:
59
+
60
+ echo dms 14148/tcp | niload services .
61
+
62
+ 2) Add this line to /etc/inetd.conf:
63
+
64
+ dms stream tcp nowait daemon dmsd_location dmsd
65
+
66
+ where 'dmsd_location' is where dmsd is installed. (If you
67
+ didn't change the Makefile at all, then the location is
68
+ /usr/local/lib/dms/dmsd)
69
+
70
+ 3) Make the inetd daemon reread the inetd.conf file. This is
71
+ accomplished by sending the inetd process a HUP signal. In
72
+ order to send the signal, you need to know inetd's process ID.
73
+ The process ID can be found by examining the output of 'ps agx'
74
+ or 'ps -e' (depending on your system). The rightmost column
75
+ contains the process name, so look for the line that includes
76
+ 'inetd' somewhere in the righthand column. On that line, in
77
+ the 'PID' column, is inetd's process ID. The signal is then
78
+ sent with the command:
79
+
80
+ kill -HUP process_ID
81
+
82
+ After performing the above steps on all servers, you should
83
+ verify that dms is indeed performing distributed computations
84
+ as expected. To do this, you need to have a PDB file available
85
+ to use as a test input (preferably a small one). Once you do,
86
+ run the command:
87
+
88
+ dms your_PDB_file -v -o /dev/null
89
+
90
+ If you have correctly installed dms for distributed computation,
91
+ the output will contain a line of the form:
92
+
93
+ Server request count:
94
+
95
+ followed by a list of hosts that dms ran on to do the calculation,
96
+ and the amount of calculation that each host performed. If the
97
+ list of servers is what you expect, and no calculation count is
98
+ zero, then you have installed dms correctly. If one or more
99
+ calculation counts are zero then you did not install dms correctly
100
+ on those hosts. For those problem hosts you should verify that
101
+ the above steps were carried out correctly as well as insuring
102
+ that dmsd is installed in the correct location and is executable.
103
+ If your list of server hosts is not what you expect and is simply
104
+ 'localhost' instead, the you have not correctly completed step (1)
105
+ on the local machine.
106
+
107
+
108
+ Legal Restrictions:
109
+
110
+ Copyright (c) <2002> The Regents of the University of California.
111
+ All rights reserved.
112
+
113
+ Redistribution and use in source and binary forms, with or without
114
+ modification, are permitted provided that the following conditions
115
+ are met:
116
+ 1. Redistributions of source code must retain the above copyright
117
+ notice, this list of conditions, and the following disclaimer.
118
+ 2. Redistributions in binary form must reproduce the above
119
+ copyright notice, this list of conditions, and the following
120
+ disclaimer in the documentation and/or other materials provided
121
+ with the distribution.
122
+ 3. Redistributions must acknowledge that this software was
123
+ originally developed by the UCSF Computer Graphics Laboratory
124
+ under support by the NIH National Center for Research Resources,
125
+ grant P41-RR01081.
126
+
127
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
128
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
129
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
130
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
131
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
132
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
133
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
134
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
135
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
136
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
137
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
138
+
dms/atoms.h ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #ifndef __ATOM__
34
+ #define __ATOM__
35
+
36
+ #define TREENTRANT 0
37
+ #define SREENTRANT 1
38
+ #define CONTACT 2
39
+
40
+ typedef struct point_def {
41
+ double coord[3];
42
+ } POINT;
43
+
44
+ typedef struct surface_def {
45
+ struct surface_def *next;
46
+ int npoint;
47
+ POINT *position;
48
+ POINT *normal;
49
+ double area;
50
+ int type;
51
+ } SURFACE;
52
+
53
+ #define AN_LEN 6
54
+ #define RN_LEN 9
55
+ #define RT_LEN 6
56
+
57
+ typedef struct atom_def {
58
+ struct atom_def *next;
59
+ double coord[3];
60
+ char atname[AN_LEN];
61
+ char resseq[RN_LEN];
62
+ char restype[RT_LEN];
63
+ double radius;
64
+ int wanted, resindex;
65
+ SURFACE *surface;
66
+ } ATOM;
67
+
68
+ typedef int AINDEX;
69
+
70
+ typedef struct neighbor_def {
71
+ int nneighbor;
72
+ AINDEX *neighbor;
73
+ } NEIGHBOR;
74
+
75
+ typedef struct probe_def {
76
+ struct probe_def *next;
77
+ AINDEX atom[3];
78
+ double coord[3];
79
+ int real;
80
+ } PROBE;
81
+
82
+ #define ATOM_IS(ap,aname,rname) \
83
+ (strcmp((ap)->atname, aname) == 0 && strcmp((ap)->resseq, rname) == 0)
84
+
85
+ #endif
dms/compute.c ADDED
@@ -0,0 +1,1460 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <string.h>
35
+ #include <ctype.h>
36
+ #include <errno.h>
37
+ #include <netdb.h>
38
+ #include <sys/types.h>
39
+ #ifndef FD_SET
40
+ #ifndef linux
41
+ #include <sys/select.h>
42
+ #endif
43
+ #endif
44
+ #include <sys/socket.h>
45
+ #include <netinet/in.h>
46
+ #include <sys/time.h>
47
+ #include <sys/uio.h>
48
+ #include "dms_param.h"
49
+ #include "atoms.h"
50
+ #include "wanted.h"
51
+ #include "protocol.h"
52
+
53
+ extern void *emalloc();
54
+
55
+ #ifndef FD_SET
56
+ #define FD_SET(n, p) ((p)->fds_bits[0] |= (1 << (n)))
57
+ #define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1 << (n)))
58
+ #define FD_ISSET(n, p) ((p)->fds_bits[0] & (1 << n))
59
+ #define FD_ZERO(p) ((p)->fds_bits[0] = 0)
60
+ #define FD_ISZERO(p) ((p)->fds_bits[0] == 0)
61
+ #endif
62
+
63
+ #ifndef DEBUG
64
+ #define STATIC static
65
+ #else
66
+ #define STATIC
67
+ #endif
68
+
69
+ #ifndef TRUE
70
+ #define TRUE 1
71
+ #define FALSE 0
72
+ #endif
73
+
74
+ typedef struct server_def {
75
+ struct server_def *next;
76
+ char *host;
77
+ FILE *in_fd, *out_fd;
78
+ int state;
79
+ void (*reply)();
80
+ void (*retry)();
81
+ int arg1, arg2;
82
+ int nrequest;
83
+ } SERVER;
84
+
85
+ #define EXECUTING 0
86
+ #define AVAILABLE 1
87
+ #define DEAD 2
88
+ #define IDLE 3
89
+ #define STOPPED 4
90
+
91
+ STATIC NEIGHBOR *neighbor;
92
+ STATIC PROBE *probe;
93
+ STATIC SERVER *server;
94
+ STATIC ATOM **alist;
95
+ STATIC int natom;
96
+
97
+ STATIC void read_radii();
98
+ STATIC void assign_radius();
99
+ STATIC void print_astat();
100
+ STATIC int compute_comp();
101
+ STATIC void start_servers();
102
+ STATIC int try_host();
103
+ STATIC void stop_servers();
104
+ STATIC SERVER *get_server();
105
+ STATIC void wait_for_server();
106
+ STATIC void print_sstat();
107
+ STATIC void param_info();
108
+ STATIC void pi_reply();
109
+ STATIC void atom_info();
110
+ STATIC void ai_reply();
111
+ STATIC void ni_reply();
112
+ STATIC void probe_info();
113
+ STATIC void pri_reply();
114
+ STATIC void neighbors();
115
+ STATIC void c_reply();
116
+ STATIC void probes();
117
+ STATIC void p_reply();
118
+ STATIC void contact_surface();
119
+ STATIC void torus_surface();
120
+ STATIC void probe_surface();
121
+ STATIC void surface_reply();
122
+ STATIC void collapse_probes();
123
+ STATIC void cross();
124
+
125
+ extern char (*resseqs)[RN_LEN];
126
+ extern int numresseq;
127
+
128
+ /*
129
+ * neighbor_info:
130
+ * Send neighbor information to all servers
131
+ */
132
+ void neighbor_info(nlist, natom)
133
+ NEIGHBOR *nlist;
134
+ int natom;
135
+ {
136
+ register SERVER *sp;
137
+ register NEIGHBOR *np, *endnp;
138
+ register struct iovec *ip;
139
+ register int n;
140
+ struct iovec *countv, *datav;
141
+ char buf[BUFSIZ];
142
+
143
+ endnp = nlist + natom;
144
+ n = 0;
145
+ countv = (struct iovec *) emalloc(natom * sizeof (struct iovec));
146
+ for (np = nlist, ip = countv; np < endnp; np++, ip++) {
147
+ ip->iov_base = (caddr_t) &np->nneighbor;
148
+ ip->iov_len = sizeof (int);
149
+ if (np->nneighbor > 0)
150
+ n++;
151
+ }
152
+ if (n > 0) {
153
+ datav = (struct iovec *) emalloc(n * sizeof (struct iovec));
154
+ ip = datav;
155
+ for (np = nlist; np < endnp; np++) {
156
+ if (np->nneighbor <= 0)
157
+ continue;
158
+ ip->iov_base = (caddr_t) np->neighbor;
159
+ ip->iov_len = np->nneighbor * sizeof (AINDEX);
160
+ ip++;
161
+ }
162
+ }
163
+ (void) sprintf(buf, NI_COMMAND, natom);
164
+ for (sp = server; sp != NULL; sp = sp->next) {
165
+ if (sp->state == DEAD)
166
+ continue;
167
+ fputs(buf, sp->out_fd);
168
+ fwritev(sp->out_fd, countv, natom);
169
+ if (n > 0)
170
+ fwritev(sp->out_fd, datav, n);
171
+ (void) fflush(sp->out_fd);
172
+ sp->state = EXECUTING;
173
+ sp->reply = ni_reply;
174
+ sp->retry = NULL;
175
+ }
176
+ wait_for_server();
177
+ (void) free((char *) countv);
178
+ if (n > 0)
179
+ (void) free((char *) datav);
180
+ }
181
+
182
+ /*
183
+ * compute_ms:
184
+ * Compute the molecular surface
185
+ */
186
+ void compute_ms(aarray, nat, radius, density, want_normal, verbose)
187
+ ATOM **aarray;
188
+ int nat;
189
+ double radius, density;
190
+ int want_normal;
191
+ int verbose;
192
+ {
193
+ register ATOM **app, **endap;
194
+ register PROBE *pp;
195
+ register int i, j, k;
196
+
197
+ /*
198
+ * Store the parameters so reply() routines can get at them
199
+ */
200
+ alist = aarray;
201
+ natom = nat;
202
+ endap = alist + natom;
203
+
204
+ /*
205
+ * Assign a radius for each atom
206
+ */
207
+ read_radii();
208
+ for (app = alist; app < endap; app++) {
209
+ assign_radius(*app);
210
+ (*app)->surface = NULL;
211
+ }
212
+ if (verbose)
213
+ print_astat();
214
+
215
+ /*
216
+ * Sort the atoms by coordinate so we can look just at slices
217
+ * instead of all atoms when looking for neighbors
218
+ */
219
+ qsort((char *) alist, natom, sizeof (ATOM *), compute_comp);
220
+
221
+ /*
222
+ * Start up servers on all the machines that we can reach
223
+ * and hand them the necessary parameters as well as atomic
224
+ * coordinates
225
+ */
226
+ start_servers();
227
+ param_info(radius, density, want_normal);
228
+ atom_info(alist, natom);
229
+ if (verbose)
230
+ fputs("Servers initialized\n", stderr);
231
+
232
+ /*
233
+ * Loop through the atom list and assign selected atoms to
234
+ * available servers (this should give us a list of neighbors).
235
+ * We then pass out the neighbor information to all the compute
236
+ * servers in preparation for surface computation.
237
+ */
238
+ neighbor = (NEIGHBOR *) emalloc(natom * sizeof (NEIGHBOR));
239
+ for (app = alist; app < endap; app++)
240
+ neighbors(app - alist);
241
+ wait_for_server();
242
+ neighbor_info(neighbor, natom);
243
+ if (verbose)
244
+ fputs("Neighbors computed\n", stderr);
245
+
246
+ /*
247
+ * Loop through the neighbor list and ask for probes which
248
+ * contact both neighbor simultaneously. We then pass the
249
+ * probe information to all the compute servers as well.
250
+ */
251
+ for (i = 0; i < natom; i++)
252
+ for (j = 0; j < neighbor[i].nneighbor; j++)
253
+ if (neighbor[i].neighbor[j] > i)
254
+ probes(i, neighbor[i].neighbor[j]);
255
+ wait_for_server();
256
+ probe_info(probe);
257
+ if (verbose)
258
+ fputs("Probes computed\n", stderr);
259
+
260
+ /*
261
+ * Now we clean up the neighbor info and send it out again
262
+ */
263
+ for (i = 0; i < natom; i++) {
264
+ for (j = 0, k = 0; j < neighbor[i].nneighbor; j++)
265
+ if (neighbor[i].neighbor[j] >= 0)
266
+ neighbor[i].neighbor[k++] =
267
+ neighbor[i].neighbor[j];
268
+ neighbor[i].nneighbor = k;
269
+ }
270
+ #ifdef RETRANS_NB
271
+ neighbor_info(neighbor, natom);
272
+ if (verbose)
273
+ fputs("Neighbors sent\n", stderr);
274
+ #endif
275
+
276
+ /*
277
+ * Generate surface points
278
+ * First the contact, then the toroid reentrant,
279
+ * and finally spherical reentrant
280
+ */
281
+ for (app = alist; app < endap; app++)
282
+ if ((*app)->wanted)
283
+ contact_surface(app - alist);
284
+ for (i = 0; i < natom; i++)
285
+ for (j = 0; j < neighbor[i].nneighbor; j++)
286
+ if (neighbor[i].neighbor[j] > i) {
287
+ if (!alist[i]->wanted
288
+ && !alist[neighbor[i].neighbor[j]]->wanted)
289
+ continue;
290
+ torus_surface(i, neighbor[i].neighbor[j]);
291
+ }
292
+
293
+ /*
294
+ * Collapse near-coincident probes and then compute surface area
295
+ */
296
+ collapse_probes();
297
+ for (pp = probe, i = 0; pp != NULL; pp = pp->next, i++) {
298
+ if (!alist[pp->atom[0]]->wanted
299
+ && !alist[pp->atom[1]]->wanted
300
+ && !alist[pp->atom[2]]->wanted)
301
+ continue;
302
+ if (pp->real)
303
+ probe_surface(i);
304
+ }
305
+ wait_for_server();
306
+ if (verbose)
307
+ fputs("Surface computed\n", stderr);
308
+
309
+ /*
310
+ * Ah...we're done. Terminate the servers and return
311
+ */
312
+ if (verbose)
313
+ print_sstat();
314
+ stop_servers();
315
+ }
316
+
317
+ typedef struct radius_def {
318
+ struct radius_def *next;
319
+ char *name;
320
+ char namelen;
321
+ double radius;
322
+ int natom;
323
+ } RADIUS;
324
+
325
+ static RADIUS *radius, *def_radius;
326
+
327
+ /*
328
+ * read_radii:
329
+ * Get radii from radii file
330
+ */
331
+ STATIC
332
+ void
333
+ read_radii()
334
+ {
335
+ register RADIUS *rp;
336
+ register FILE *fp;
337
+ char buf[BUFSIZ], name[10];
338
+ double length;
339
+
340
+ if ((fp = fopen(RADII_FILE, "r")) == NULL) {
341
+ if ((fp = fopen(DEF_RADII_FILE, "r")) == NULL) {
342
+ perror(DEF_RADII_FILE);
343
+ exit(1);
344
+ }
345
+ }
346
+ while (fgets(buf, sizeof buf, fp) != NULL) {
347
+ if (buf[0] == '#')
348
+ continue;
349
+ if (sscanf(buf, "%s%lf", name, &length) != 2) {
350
+ fputs("Syntax error in radii file\n", stderr);
351
+ fputs(buf, stderr);
352
+ continue;
353
+ }
354
+ if (strcmp(name, "default") == 0) {
355
+ def_radius = (RADIUS *) emalloc(sizeof (RADIUS));
356
+ def_radius->next = NULL;
357
+ def_radius->name = NULL;
358
+ def_radius->namelen = 0;
359
+ def_radius->radius = length;
360
+ def_radius->natom = 0;
361
+ }
362
+ else {
363
+ rp = (RADIUS *) emalloc(sizeof (RADIUS));
364
+ rp->next = radius;
365
+ rp->namelen = strlen(name);
366
+ rp->name = emalloc(rp->namelen + 1);
367
+ (void) strcpy(rp->name, name);
368
+ rp->radius = length;
369
+ rp->natom = 0;
370
+ radius = rp;
371
+ }
372
+ }
373
+ (void) fclose(fp);
374
+ }
375
+
376
+ /*
377
+ * assign_radius:
378
+ * Assign a van der Waals radius to this atom
379
+ */
380
+ STATIC
381
+ void
382
+ assign_radius(ap)
383
+ ATOM *ap;
384
+ {
385
+ register RADIUS *rp;
386
+
387
+ for (rp = radius; rp != NULL; rp = rp->next)
388
+ if (strncmp(rp->name, ap->atname, rp->namelen) == 0)
389
+ break;
390
+ if (rp == NULL) {
391
+ if (def_radius == NULL) {
392
+ fprintf(stderr, "Unknown atom type %s\n", ap->atname);
393
+ exit(1);
394
+ }
395
+ else
396
+ rp = def_radius;
397
+ }
398
+ ap->radius = rp->radius;
399
+ rp->natom++;
400
+ }
401
+
402
+ /*
403
+ * print_astat:
404
+ * Print atom type statistics
405
+ */
406
+ STATIC
407
+ void
408
+ print_astat()
409
+ {
410
+ register struct radius_def *rp;
411
+
412
+ for (rp = radius; rp != NULL; rp = rp->next)
413
+ if (rp->natom > 0)
414
+ fprintf(stderr, "\t%s\t%d\n", rp->name, rp->natom);
415
+ /*
416
+ * The last entry is the default
417
+ */
418
+ if (def_radius != NULL && def_radius->natom > 0)
419
+ fprintf(stderr, "\t???\t%d\n", def_radius->natom);
420
+ }
421
+
422
+ /*
423
+ * compute_comp:
424
+ * Compare atoms based on coordinates
425
+ */
426
+ STATIC
427
+ int
428
+ compute_comp(a1, a2)
429
+ ATOM **a1, **a2;
430
+ {
431
+ register ATOM *t1, *t2;
432
+
433
+ t1 = *a1;
434
+ t2 = *a2;
435
+ if (t1->coord[0] < t2->coord[0])
436
+ return -1;
437
+ else if (t1->coord[0] > t2->coord[0])
438
+ return 1;
439
+ if (t1->coord[1] < t2->coord[1])
440
+ return -1;
441
+ else if (t1->coord[1] > t2->coord[1])
442
+ return 1;
443
+ if (t1->coord[2] < t2->coord[2])
444
+ return -1;
445
+ else if (t1->coord[2] > t2->coord[2])
446
+ return 1;
447
+ return 0;
448
+ }
449
+
450
+ /*
451
+ * start_servers:
452
+ * Start up servers on all available machines
453
+ * For the first pass implementation, we will try to contact
454
+ * known hosts only once and just use that set. If hosts die,
455
+ * they get marked as down and are no longer used. No attempts
456
+ * at retrying to connect to any host will be made.
457
+ */
458
+ STATIC
459
+ void
460
+ start_servers()
461
+ {
462
+ struct servent *servp;
463
+
464
+ if ((servp = getservbyname("dms", "tcp")) == NULL) {
465
+ /* service entry not found, run in standalone mode */
466
+ int pid, toserver[2], fromserver[2];
467
+
468
+ server = (SERVER *) emalloc(sizeof (SERVER));
469
+ server->nrequest = 0;
470
+ server->retry = NULL;
471
+ server->host = "localhost";
472
+ if (pipe(toserver) < 0 || pipe(fromserver) < 0) {
473
+ perror("Cannot create pipe");
474
+ exit(1);
475
+ }
476
+ if ((pid = fork()) < 0) {
477
+ perror("Cannot fork");
478
+ exit(1);
479
+ }
480
+ if (pid == 0) {
481
+ close(0);
482
+ close(1);
483
+ dup2(toserver[0], 0);
484
+ dup2(fromserver[1], 1);
485
+ close(toserver[0]);
486
+ close(toserver[1]);
487
+ close(fromserver[0]);
488
+ close(fromserver[1]);
489
+ execl(SERVER_PATH, "dmsd", NULL);
490
+ perror("execl");
491
+ exit(1);
492
+ }
493
+ server->in_fd = fdopen(fromserver[0], "r");
494
+ server->out_fd = fdopen(toserver[1], "w");
495
+ close(fromserver[1]);
496
+ close(toserver[0]);
497
+ if (server->in_fd == NULL || server->out_fd == NULL) {
498
+ fprintf(stderr, "Cannot open file descriptor.\n");
499
+ exit(1);
500
+ }
501
+ setlinebuf(server->out_fd);
502
+ server->state = AVAILABLE;
503
+ server->next = NULL;
504
+ } else {
505
+ /* service entry found, run in distributed processing mode */
506
+ register SERVER *sp;
507
+ register FILE *fp;
508
+ register char *cp;
509
+ char buf[BUFSIZ];
510
+
511
+ if ((fp = fopen(SERVER_FILE, "r")) == NULL) {
512
+ if ((fp = fopen(DEF_SERVER_FILE, "r")) == NULL) {
513
+ perror(DEF_SERVER_FILE);
514
+ exit(1);
515
+ }
516
+ }
517
+ sethostent(TRUE);
518
+ while (fgets(buf, sizeof buf, fp) != NULL) {
519
+ if ((cp = strchr(buf, '\n')) != NULL)
520
+ *cp = '\0';
521
+ sp = (SERVER *) emalloc(sizeof (SERVER));
522
+ sp->host = emalloc(strlen(buf) + 1);
523
+ sp->nrequest = 0;
524
+ sp->retry = NULL;
525
+ (void) strcpy(sp->host, buf);
526
+ if (try_host(buf, sp, servp->s_port) < 0)
527
+ (void) free((char *) sp);
528
+ else {
529
+ sp->next = server;
530
+ server = sp;
531
+ }
532
+ }
533
+ endhostent();
534
+ (void) fclose(fp);
535
+ }
536
+ }
537
+
538
+ /*
539
+ * try_host:
540
+ * Try to contact a host.
541
+ */
542
+ STATIC
543
+ int
544
+ try_host(host, sp, port)
545
+ char *host;
546
+ SERVER *sp;
547
+ int port;
548
+ {
549
+ struct hostent *hostp;
550
+ struct sockaddr_in addr;
551
+ int fd;
552
+ int newfd;
553
+ extern int errno;
554
+
555
+ if ((hostp = gethostbyname(host)) == NULL) {
556
+ fprintf(stderr, "%s: no such host\n", host);
557
+ return -1;
558
+ }
559
+ if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
560
+ perror("socket");
561
+ return -1;
562
+ }
563
+ addr.sin_family = PF_INET;
564
+ addr.sin_addr = *((struct in_addr *) hostp->h_addr);
565
+ addr.sin_port = port;
566
+ if (connect(fd, (struct sockaddr *) &addr, sizeof addr) < 0) {
567
+ perror(host);
568
+ if (errno != ETIMEDOUT) {
569
+ (void) close(fd);
570
+ return -1;
571
+ }
572
+ else {
573
+ (void) close(fd);
574
+ sp->state = DEAD;
575
+ return 0;
576
+ }
577
+ }
578
+
579
+ if ((sp->in_fd = fdopen(fd, "r")) == NULL) {
580
+ perror("fdopen");
581
+ (void) close(fd);
582
+ sp->state = DEAD;
583
+ return 0;
584
+ }
585
+
586
+ #ifdef BSD
587
+ newfd = fd;
588
+ #else
589
+ newfd = dup(fd);
590
+ #endif
591
+ if ((sp->out_fd = fdopen(newfd, "w")) == NULL) {
592
+ perror("fdopen");
593
+ (void) close(fd);
594
+ sp->state = DEAD;
595
+ return 0;
596
+ }
597
+
598
+ sp->state = AVAILABLE;
599
+ return 0;
600
+ }
601
+
602
+ /*
603
+ * stop_servers:
604
+ * Terminate all servers that are currently active
605
+ */
606
+ STATIC
607
+ void
608
+ stop_servers()
609
+ {
610
+ register SERVER *sp, *nextsp;
611
+
612
+ for (sp = server; sp != NULL; sp = nextsp) {
613
+ nextsp = sp->next;
614
+ if (sp->state != DEAD) {
615
+ (void) fclose(sp->in_fd);
616
+ (void) fclose(sp->out_fd);
617
+ }
618
+ (void) free((char *) sp);
619
+ }
620
+ }
621
+
622
+ /*
623
+ * get_server:
624
+ * Get an available server. Bomb out if all servers are dead.
625
+ */
626
+ STATIC
627
+ SERVER *
628
+ get_server()
629
+ {
630
+ register SERVER *sp;
631
+ register int max_fd, any_live, n;
632
+ fd_set mask, save_mask;
633
+
634
+ max_fd = 0; /* In case _file is declared unsigned */
635
+ any_live = FALSE;
636
+ FD_ZERO(&save_mask);
637
+ n = 0;
638
+
639
+ /*
640
+ * If there is an available server, return it. Otherwise,
641
+ * keep track of the list of currently executing servers
642
+ */
643
+ for (sp = server; sp != NULL; sp = sp->next) {
644
+ switch (sp->state) {
645
+ case AVAILABLE:
646
+ sp->nrequest++;
647
+ return sp;
648
+ case EXECUTING:
649
+ case STOPPED:
650
+ FD_SET(fileno(sp->in_fd), &save_mask);
651
+ n++;
652
+ if (fileno(sp->in_fd) > max_fd)
653
+ max_fd = fileno(sp->in_fd);
654
+ any_live = TRUE;
655
+ break;
656
+ case IDLE:
657
+ any_live = TRUE;
658
+ break;
659
+ case DEAD:
660
+ break;
661
+ }
662
+ }
663
+
664
+ if (!any_live) {
665
+ fputs("All servers died!\n", stderr);
666
+ exit(1);
667
+ }
668
+ if (n <= 0)
669
+ return NULL;
670
+ max_fd++;
671
+
672
+ again:
673
+ mask = save_mask;
674
+ /*
675
+ * Wait for a server to come back (either respond or die)
676
+ */
677
+ if (select(max_fd, &mask, (fd_set *) NULL, (fd_set *) NULL,
678
+ (struct timeval *) NULL) <= 0) {
679
+ perror("select");
680
+ exit(1);
681
+ }
682
+ for (sp = server; sp != NULL; sp = sp->next) {
683
+ if (sp->state != EXECUTING && sp->state != STOPPED)
684
+ continue;
685
+ if (!FD_ISSET(fileno(sp->in_fd), &mask))
686
+ continue;
687
+ (*sp->reply)(sp);
688
+ switch (sp->state) {
689
+ case AVAILABLE:
690
+ sp->nrequest++;
691
+ return sp;
692
+ case EXECUTING:
693
+ case STOPPED:
694
+ break;
695
+ default:
696
+ FD_CLR(fileno(sp->in_fd), &save_mask);
697
+ n--;
698
+ break;
699
+ }
700
+ }
701
+ if (n <= 0) {
702
+ fputs("All servers died!\n", stderr);
703
+ exit(1);
704
+ }
705
+ goto again;
706
+ }
707
+
708
+ /*
709
+ * wait_for_server:
710
+ * Wait for all servers to become idle.
711
+ * If there are servers that died while handling requests that
712
+ * need to be retried, handle that as well. Since servers normally
713
+ * do not die, we are willing to take a performance penalty to handle
714
+ * the special case.
715
+ */
716
+ STATIC
717
+ void
718
+ wait_for_server()
719
+ {
720
+ register SERVER *sp;
721
+ register int n;
722
+
723
+ again:
724
+ /*
725
+ * Wait for all active servers to finish
726
+ */
727
+ while ((sp = get_server()) != NULL) {
728
+ sp->state = IDLE;
729
+ continue;
730
+ }
731
+ for (sp = server; sp != NULL; sp = sp->next)
732
+ if (sp->state == IDLE)
733
+ sp->state = AVAILABLE;
734
+
735
+ /*
736
+ * Check for servers that died in action. If they need to
737
+ * be retried, start them up and go back to the waiting stage
738
+ */
739
+ n = 0;
740
+ for (sp = server; sp != NULL; sp = sp->next)
741
+ if (sp->state == DEAD && sp->retry != NULL) {
742
+ (*sp->retry)(sp->arg1, sp->arg2);
743
+ sp->retry = NULL;
744
+ #ifdef DEBUG
745
+ fprintf(stderr, "Retrying after %s died\n", sp->host);
746
+ #endif
747
+ n++;
748
+ }
749
+ if (n > 0)
750
+ goto again;
751
+ }
752
+
753
+ /*
754
+ * print_sstat:
755
+ * Print server statistics
756
+ */
757
+ STATIC
758
+ void
759
+ print_sstat()
760
+ {
761
+ register SERVER *sp;
762
+
763
+ fputs("Server request count:\n", stderr);
764
+ for (sp = server; sp != NULL; sp = sp->next)
765
+ fprintf(stderr, "\t%-8s\t%d\n", sp->host, sp->nrequest);
766
+ }
767
+
768
+ /*
769
+ * wanted:
770
+ * Determine whether the given atom is in the "wanted list"
771
+ * We "know" we are called with non-null arguments
772
+ */
773
+ int
774
+ wanted(ATOM *ap, WANTED *wlist)
775
+ {
776
+ register WANTED *wp;
777
+ int from, to, at;
778
+
779
+ at = ap->resindex;
780
+ for (wp = wlist; wp != NULL; wp = wp->next)
781
+ switch (wp->type) {
782
+ case W_RANGE:
783
+ from = wp->startres;
784
+ to = wp->w.endres;
785
+ if (from < 0 || to < 0)
786
+ continue;
787
+ if (from <= at && at <= to)
788
+ return TRUE;
789
+ break;
790
+ case W_ANY:
791
+ if (at == wp->startres)
792
+ return TRUE;
793
+ break;
794
+ case W_ATOM:
795
+ if (at != wp->startres)
796
+ continue;
797
+ if (strcmp(ap->atname, wp->w.atom) == 0)
798
+ return TRUE;
799
+ break;
800
+ }
801
+ return FALSE;
802
+ }
803
+
804
+ /*
805
+ * locres:
806
+ * return the numeric index of the given resseq in the array of
807
+ * all resseqs (which should be in the same order as the PDB file).
808
+ * Returns -1 if not found.
809
+ */
810
+ int
811
+ locres(seq)
812
+ char *seq;
813
+ {
814
+ register int i;
815
+ int index;
816
+
817
+ index = -1;
818
+ for (i = 0; i < numresseq; i++) {
819
+ if (strcmp(resseqs[i], seq) == 0) {
820
+ index = i;
821
+ break;
822
+ }
823
+ }
824
+ return index;
825
+ }
826
+
827
+ /*
828
+ * param_info:
829
+ * Pass parameter (probe radius and whether we need normals)
830
+ * to servers
831
+ */
832
+ STATIC
833
+ void
834
+ param_info(radius, density, want_normal)
835
+ double radius, density;
836
+ int want_normal;
837
+ {
838
+ register SERVER *sp;
839
+ char buf[BUFSIZ];
840
+
841
+ (void) sprintf(buf, PI_COMMAND, radius, density, want_normal);
842
+ for (sp = server; sp != NULL; sp = sp->next) {
843
+ if (sp->state == DEAD)
844
+ continue;
845
+ fputs(buf, sp->out_fd);
846
+ (void) fflush(sp->out_fd);
847
+ sp->state = EXECUTING;
848
+ sp->reply = pi_reply;
849
+ sp->retry = NULL;
850
+ }
851
+ wait_for_server();
852
+ }
853
+
854
+ /*
855
+ * pi_reply:
856
+ * Wait for response to param info command
857
+ */
858
+ STATIC
859
+ void
860
+ pi_reply(sp)
861
+ SERVER *sp;
862
+ {
863
+ char buf[BUFSIZ];
864
+
865
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
866
+ fputs("server died\n", stderr);
867
+ sp->state = DEAD;
868
+ (void) fclose(sp->in_fd);
869
+ (void) fclose(sp->out_fd);
870
+ return;
871
+ }
872
+ if (strcmp(buf, PI_RESPONSE) != 0) {
873
+ fputs("pi_reply: unexpected response from server\n", stderr);
874
+ fputs(buf, stderr);
875
+ sp->state = DEAD;
876
+ (void) fclose(sp->in_fd);
877
+ (void) fclose(sp->out_fd);
878
+ return;
879
+ }
880
+ sp->state = AVAILABLE;
881
+ }
882
+
883
+ /*
884
+ * atom_info:
885
+ * Pass atom information out to all servers
886
+ */
887
+ STATIC
888
+ void
889
+ atom_info(alist, natom)
890
+ ATOM **alist;
891
+ int natom;
892
+ {
893
+ register SERVER *sp;
894
+ register ATOM **app;
895
+ struct iovec *iov, *ip, *endip;
896
+ char buf[BUFSIZ];
897
+
898
+ iov = (struct iovec *) emalloc(natom * sizeof (struct iovec));
899
+ endip = iov + natom;
900
+ app = alist;
901
+ for (ip = iov; ip < endip; ip++) {
902
+ ip->iov_base = (caddr_t) *app++;
903
+ ip->iov_len = sizeof (ATOM);
904
+ }
905
+ (void) sprintf(buf, AI_COMMAND, natom);
906
+ for (sp = server; sp != NULL; sp = sp->next) {
907
+ if (sp->state == DEAD)
908
+ continue;
909
+ (void) fputs(buf, sp->out_fd);
910
+ fwritev(sp->out_fd, iov, natom);
911
+ (void) fflush(sp->out_fd);
912
+ sp->state = EXECUTING;
913
+ sp->reply = ai_reply;
914
+ sp->retry = NULL;
915
+ }
916
+ wait_for_server();
917
+ (void) free((char *) iov);
918
+ }
919
+
920
+ /*
921
+ * ai_reply:
922
+ * Read a reply from a server that just received atom info
923
+ */
924
+ STATIC
925
+ void
926
+ ai_reply(sp)
927
+ SERVER *sp;
928
+ {
929
+ char buf[BUFSIZ];
930
+
931
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
932
+ fputs("ai_reply: server died\n", stderr);
933
+ goto bad;
934
+ }
935
+ if (strcmp(buf, AI_RESPONSE) != 0) {
936
+ fputs("ai_reply: unexpected response from server\n", stderr);
937
+ fputs(buf, stderr);
938
+ goto bad;
939
+ }
940
+ sp->state = AVAILABLE;
941
+ return;
942
+ bad:
943
+ sp->state = DEAD;
944
+ (void) fclose(sp->in_fd);
945
+ (void) fclose(sp->out_fd);
946
+ return;
947
+ }
948
+
949
+ /*
950
+ * ni_reply:
951
+ * Read a reply from a server that just received neighbor info
952
+ */
953
+ STATIC
954
+ void
955
+ ni_reply(sp)
956
+ SERVER *sp;
957
+ {
958
+ char buf[BUFSIZ];
959
+
960
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
961
+ fputs("ni_reply: server died\n", stderr);
962
+ goto bad;
963
+ }
964
+ if (strcmp(buf, NI_RESPONSE) != 0) {
965
+ fputs("ni_reply: unexpected response from server\n", stderr);
966
+ fputs(buf, stderr);
967
+ goto bad;
968
+ }
969
+ sp->state = AVAILABLE;
970
+ return;
971
+ bad:
972
+ sp->state = DEAD;
973
+ (void) fclose(sp->in_fd);
974
+ (void) fclose(sp->out_fd);
975
+ return;
976
+ }
977
+
978
+
979
+ /*
980
+ * probe_info:
981
+ * Send probe information to all servers
982
+ */
983
+ STATIC
984
+ void
985
+ probe_info(plist)
986
+ PROBE *plist;
987
+ {
988
+ register SERVER *sp;
989
+ register PROBE *pp;
990
+ register int n;
991
+ register struct iovec *ip;
992
+ struct iovec *iov, *endip;
993
+ char buf[BUFSIZ];
994
+
995
+ /*
996
+ * Count up the number of probes and allocate
997
+ * data structure for sending it down the line
998
+ */
999
+ n = 0;
1000
+ for (pp = probe; pp != NULL; pp = pp->next)
1001
+ n++;
1002
+ if (n > 0) {
1003
+ iov = (struct iovec *) emalloc(n * sizeof (struct iovec));
1004
+ endip = iov + n;
1005
+ for (ip = iov, pp = plist; ip < endip; ip++, pp = pp->next) {
1006
+ ip->iov_base = (caddr_t) pp;
1007
+ ip->iov_len = sizeof (PROBE);
1008
+ }
1009
+ }
1010
+
1011
+ (void) sprintf(buf, PRI_COMMAND, n);
1012
+ for (sp = server; sp != NULL; sp = sp->next) {
1013
+ if (sp->state == DEAD)
1014
+ continue;
1015
+ fputs(buf, sp->out_fd);
1016
+ if (n > 0)
1017
+ fwritev(sp->out_fd, iov, n);
1018
+ (void) fflush(sp->out_fd);
1019
+ sp->state = EXECUTING;
1020
+ sp->reply = pri_reply;
1021
+ sp->retry = NULL;
1022
+ }
1023
+ wait_for_server();
1024
+ if (n > 0)
1025
+ (void) free((char *) iov);
1026
+ }
1027
+
1028
+ /*
1029
+ * pri_reply:
1030
+ * Read a reply from a server that just received probe info
1031
+ */
1032
+ STATIC
1033
+ void
1034
+ pri_reply(sp)
1035
+ SERVER *sp;
1036
+ {
1037
+ char buf[BUFSIZ];
1038
+
1039
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
1040
+ fputs("pri_reply: server died\n", stderr);
1041
+ goto bad;
1042
+ }
1043
+ if (strcmp(buf, PRI_RESPONSE) != 0) {
1044
+ fputs("pri_reply: unexpected response from server\n", stderr);
1045
+ fputs(buf, stderr);
1046
+ goto bad;
1047
+ }
1048
+ sp->state = AVAILABLE;
1049
+ return;
1050
+ bad:
1051
+ sp->state = DEAD;
1052
+ (void) fclose(sp->in_fd);
1053
+ (void) fclose(sp->out_fd);
1054
+ return;
1055
+ }
1056
+
1057
+ /*
1058
+ * neighbors:
1059
+ * Send contact computation request for atom "n" in "alist"
1060
+ * out to an available server. If none is available, wait for one.
1061
+ */
1062
+ STATIC
1063
+ void
1064
+ neighbors(n)
1065
+ int n;
1066
+ {
1067
+ register SERVER *sp;
1068
+
1069
+ if ((sp = get_server()) == NULL) {
1070
+ fputs("neighbors: servers idling!\n", stderr);
1071
+ exit(1);
1072
+ }
1073
+ fprintf(sp->out_fd, C_COMMAND, n);
1074
+ (void) fflush(sp->out_fd);
1075
+ sp->state = EXECUTING;
1076
+ sp->reply = c_reply;
1077
+ sp->retry = neighbors;
1078
+ sp->arg1 = n;
1079
+ }
1080
+
1081
+ /*
1082
+ * c_reply:
1083
+ * Read the output of a server which completed a contact
1084
+ * computation. Reset the server state when we are done.
1085
+ */
1086
+ STATIC
1087
+ void
1088
+ c_reply(sp)
1089
+ SERVER *sp;
1090
+ {
1091
+ char buf[BUFSIZ];
1092
+ int n, nn;
1093
+
1094
+ /*
1095
+ * Read the computed neighbors
1096
+ */
1097
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
1098
+ fputs("c_reply: server died\n", stderr);
1099
+ goto bad;
1100
+ }
1101
+ if (sscanf(buf, C_RESPONSE, &n, &nn) != 2) {
1102
+ fputs("c_reply: unexpected response from server\n", stderr);
1103
+ fputs(buf, stderr);
1104
+ goto bad;
1105
+ }
1106
+ neighbor[n].nneighbor = nn;
1107
+ if (nn > 0) {
1108
+ neighbor[n].neighbor = (AINDEX *) emalloc(nn * sizeof (AINDEX));
1109
+ if (fread((char *) neighbor[n].neighbor, sizeof (AINDEX), nn,
1110
+ sp->in_fd) != nn) {
1111
+ fputs("c_reply: unexpected EOF from server\n", stderr);
1112
+ goto bad;
1113
+ }
1114
+ }
1115
+ else
1116
+ neighbor[n].neighbor = NULL;
1117
+
1118
+ /*
1119
+ * Reset the server state and return
1120
+ */
1121
+ sp->state = AVAILABLE;
1122
+ return;
1123
+
1124
+ bad:
1125
+ /*
1126
+ * Mark the server as dead and return
1127
+ */
1128
+ sp->state = DEAD;
1129
+ (void) fclose(sp->in_fd);
1130
+ (void) fclose(sp->out_fd);
1131
+ return;
1132
+ }
1133
+
1134
+ /*
1135
+ * probes:
1136
+ * Send contact computation request for atom "n" in "alist"
1137
+ * out to an available server. If none is available, wait for one.
1138
+ */
1139
+ STATIC
1140
+ void
1141
+ probes(n, m)
1142
+ int n;
1143
+ AINDEX m;
1144
+ {
1145
+ register SERVER *sp;
1146
+
1147
+ if ((sp = get_server()) == NULL) {
1148
+ fputs("neighbors: servers idling!\n", stderr);
1149
+ exit(1);
1150
+ }
1151
+ fprintf(sp->out_fd, P_COMMAND, n, m);
1152
+ (void) fflush(sp->out_fd);
1153
+ sp->state = EXECUTING;
1154
+ sp->reply = p_reply;
1155
+ sp->retry = probes;
1156
+ sp->arg1 = n;
1157
+ sp->arg2 = m;
1158
+ }
1159
+
1160
+ /*
1161
+ * p_reply:
1162
+ * Read the output of a server which completed a probe
1163
+ * computation. Reset the server state when we are done.
1164
+ */
1165
+ STATIC
1166
+ void
1167
+ p_reply(sp)
1168
+ SERVER *sp;
1169
+ {
1170
+ register int i;
1171
+ register PROBE *pp;
1172
+ char buf[BUFSIZ];
1173
+ int n, m, np;
1174
+
1175
+ for (;;) {
1176
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
1177
+ fputs("p_reply: server died\n", stderr);
1178
+ goto bad;
1179
+ }
1180
+ if (sscanf(buf, P_BADNB, &n, &m) != 2)
1181
+ break;
1182
+ /*
1183
+ * These atoms are not real neighbors! We should go and
1184
+ * remove the neighbor markings on them.
1185
+ */
1186
+ for (i = 0; i < neighbor[n].nneighbor; i++)
1187
+ if (neighbor[n].neighbor[i] == m)
1188
+ neighbor[n].neighbor[i] = -1;
1189
+ for (i = 0; i < neighbor[m].nneighbor; i++)
1190
+ if (neighbor[m].neighbor[i] == n)
1191
+ neighbor[m].neighbor[i] = -1;
1192
+ }
1193
+ if (sscanf(buf, P_RESPONSE, &np) != 1) {
1194
+ fputs("p_reply: unexpected response from server\n",
1195
+ stderr);
1196
+ fputs(buf, stderr);
1197
+ goto bad;
1198
+ }
1199
+ if (np > 0) {
1200
+ pp = (PROBE *) emalloc(np * sizeof (PROBE));
1201
+ if (fread((char *) pp, sizeof (PROBE), np, sp->in_fd) != np) {
1202
+ fputs("p_reply: unexpected EOF from server\n", stderr);
1203
+ goto bad;
1204
+ }
1205
+ for (i = 1; i < np; i++)
1206
+ pp[i - 1].next = &pp[i];
1207
+ pp[np - 1].next = probe;
1208
+ probe = pp;
1209
+ }
1210
+
1211
+ /*
1212
+ * Reset the server state and return
1213
+ */
1214
+ sp->state = AVAILABLE;
1215
+ return;
1216
+
1217
+ bad:
1218
+ /*
1219
+ * Mark the server as dead and return
1220
+ */
1221
+ sp->state = DEAD;
1222
+ (void) fclose(sp->in_fd);
1223
+ (void) fclose(sp->out_fd);
1224
+ return;
1225
+ }
1226
+
1227
+ /*
1228
+ * contact_surface:
1229
+ * Start a server on computing the contact surface for atom `n'
1230
+ */
1231
+ STATIC
1232
+ void
1233
+ contact_surface(n)
1234
+ int n;
1235
+ {
1236
+ register SERVER *sp;
1237
+
1238
+ if ((sp = get_server()) == NULL) {
1239
+ fputs("contact_surface: servers idling!\n", stderr);
1240
+ exit(1);
1241
+ }
1242
+ fprintf(sp->out_fd, CS_COMMAND, n);
1243
+ (void) fflush(sp->out_fd);
1244
+ sp->state = EXECUTING;
1245
+ sp->reply = surface_reply;
1246
+ sp->retry = contact_surface;
1247
+ sp->arg1 = n;
1248
+ }
1249
+
1250
+ /*
1251
+ * torus_surface:
1252
+ * Start a server on computing the toroid reentrant surface between
1253
+ * atoms `n' and `m'
1254
+ */
1255
+ STATIC
1256
+ void
1257
+ torus_surface(n, m)
1258
+ int n, m;
1259
+ {
1260
+ register SERVER *sp;
1261
+
1262
+ if ((sp = get_server()) == NULL) {
1263
+ fputs("torus_surface: servers idling!\n", stderr);
1264
+ exit(1);
1265
+ }
1266
+ fprintf(sp->out_fd, TS_COMMAND, n, m);
1267
+ (void) fflush(sp->out_fd);
1268
+ sp->state = EXECUTING;
1269
+ sp->reply = surface_reply;
1270
+ sp->retry = torus_surface;
1271
+ sp->arg1 = n;
1272
+ sp->arg2 = m;
1273
+ }
1274
+
1275
+ /*
1276
+ * probe_surface:
1277
+ * Start a server on computing the probe reentrant surface
1278
+ * for probe `pp'
1279
+ */
1280
+ STATIC
1281
+ void
1282
+ probe_surface(n)
1283
+ int n;
1284
+ {
1285
+ register SERVER *sp;
1286
+
1287
+ if ((sp = get_server()) == NULL) {
1288
+ fputs("probe_surface: servers idling!\n", stderr);
1289
+ exit(1);
1290
+ }
1291
+ fprintf(sp->out_fd, PS_COMMAND, n);
1292
+ (void) fflush(sp->out_fd);
1293
+ sp->state = EXECUTING;
1294
+ sp->reply = surface_reply;
1295
+ sp->retry = probe_surface;
1296
+ sp->arg1 = n;
1297
+ }
1298
+
1299
+ /*
1300
+ * surface_reply:
1301
+ * This routine is used by all surface computation requests.
1302
+ * We read surface data until we get an "END" message
1303
+ */
1304
+ STATIC
1305
+ void
1306
+ surface_reply(sp)
1307
+ SERVER *sp;
1308
+ {
1309
+ register SURFACE *surfp;
1310
+ register int cc;
1311
+ char buf[BUFSIZ];
1312
+ int n, nn, type, have_normal;
1313
+ double area;
1314
+
1315
+ for (;;) {
1316
+ if (fgets(buf, sizeof buf, sp->in_fd) == NULL) {
1317
+ fputs("surface_reply: server died\n", stderr);
1318
+ goto bad;
1319
+ }
1320
+ if (strcmp(buf, SURFACE_END) == 0)
1321
+ break;
1322
+ if (sscanf(buf, SURFACE_RESPONSE, &n, &nn, &type, &area,
1323
+ &have_normal) != 5) {
1324
+ fputs("surface_reply: bad response from server\n",
1325
+ stderr);
1326
+ fputs(buf, stderr);
1327
+ goto bad;
1328
+ }
1329
+ if (nn <= 0)
1330
+ continue;
1331
+ surfp = (SURFACE *) emalloc(sizeof (SURFACE));
1332
+ surfp->next = alist[n]->surface;
1333
+ alist[n]->surface = surfp;
1334
+ surfp->type = type;
1335
+ surfp->area = area;
1336
+ surfp->npoint = nn;
1337
+ surfp->position = (POINT *) emalloc(nn * sizeof (POINT));
1338
+ if ((cc = fread((char *) surfp->position, sizeof (POINT), nn,
1339
+ sp->in_fd)) != nn) {
1340
+ fprintf(stderr,
1341
+ "surface_reply: Read %d points, wanted %d\n",
1342
+ cc, nn);
1343
+ surfp->npoint = 0;
1344
+ goto bad;
1345
+ }
1346
+ if (!have_normal) {
1347
+ surfp->normal = NULL;
1348
+ continue;
1349
+ }
1350
+ surfp->normal = (POINT *) emalloc(nn * sizeof (POINT));
1351
+ if (fread((char *) surfp->normal, sizeof (POINT), nn,
1352
+ sp->in_fd) != nn) {
1353
+ fputs("surface_reply: EOF from server\n", stderr);
1354
+ surfp->npoint = 0;
1355
+ goto bad;
1356
+ }
1357
+ }
1358
+
1359
+ /*
1360
+ * Got all data, just reset state and return
1361
+ */
1362
+ sp->state = AVAILABLE;
1363
+ return;
1364
+
1365
+ bad:
1366
+ /*
1367
+ * Mark the server as dead and return
1368
+ */
1369
+ sp->state = DEAD;
1370
+ (void) fclose(sp->in_fd);
1371
+ (void) fclose(sp->out_fd);
1372
+ return;
1373
+ }
1374
+
1375
+ /*
1376
+ * collapse_probes:
1377
+ * Check for near-coincident probes and remove redundant
1378
+ * surface coverage
1379
+ */
1380
+ STATIC
1381
+ void
1382
+ collapse_probes()
1383
+ {
1384
+ int i, j;
1385
+ PROBE *pp, *npp;
1386
+ double delta, distsq;
1387
+ ATOM *shared[3];
1388
+ int nshared;
1389
+ double plane[4];
1390
+ double v1[3], v2[3];
1391
+ double pside, npside;
1392
+ #define EPSILON 1e-8
1393
+
1394
+ for (pp = probe; pp != NULL; pp = pp->next) {
1395
+ if (!pp->real)
1396
+ continue;
1397
+ for (npp = pp->next; npp != NULL; npp = npp->next) {
1398
+ distsq = 0;
1399
+ for (i = 0; i < 3; i++) {
1400
+ delta = pp->coord[i] - npp->coord[i];
1401
+ distsq += delta * delta;
1402
+ }
1403
+ if (distsq > EPSILON)
1404
+ continue;
1405
+ nshared = 0;
1406
+ for (i = 0; i < 3; i++)
1407
+ for (j = 0; j < 3; j++)
1408
+ if (pp->atom[i] == npp->atom[j]) {
1409
+ shared[nshared++] =
1410
+ alist[pp->atom[i]];
1411
+ break;
1412
+ }
1413
+ if (nshared != 2)
1414
+ continue;
1415
+ for (i = 0; i < 3; i++) {
1416
+ v1[i] = shared[0]->coord[i] - pp->coord[i];
1417
+ v2[i] = shared[1]->coord[i] - pp->coord[i];
1418
+ }
1419
+ cross(v1, v2, plane);
1420
+ plane[3] = 0;
1421
+ for (i = 0; i < 3; i++)
1422
+ plane[3] -= plane[i] * pp->coord[i];
1423
+ for (i = 0; i < 3; i++) {
1424
+ if (alist[pp->atom[i]] != shared[0]
1425
+ && alist[pp->atom[i]] != shared[1]) {
1426
+ pside = plane[3];
1427
+ for (j = 0; j < 3; j++)
1428
+ pside += alist[pp->atom[i]]
1429
+ ->coord[j] * plane[j];
1430
+ }
1431
+ if (alist[npp->atom[i]] != shared[0]
1432
+ && alist[npp->atom[i]] != shared[1]) {
1433
+ npside = plane[3];
1434
+ for (j = 0; j < 3; j++)
1435
+ npside += alist[npp->atom[i]]
1436
+ ->coord[j] * plane[j];
1437
+ }
1438
+ }
1439
+ if ((npside < 0 && pside < 0)
1440
+ || (npside > 0 && pside > 0))
1441
+ npp->real = 0;
1442
+ }
1443
+ }
1444
+ }
1445
+
1446
+ /*
1447
+ * cross:
1448
+ * Take cross product of a and b
1449
+ */
1450
+ STATIC
1451
+ void
1452
+ cross(a, b, result)
1453
+ double a[3];
1454
+ double b[3];
1455
+ double result[3];
1456
+ {
1457
+ result[0] = a[1] * b[2] - b[1] * a[2];
1458
+ result[1] = a[2] * b[0] - b[2] * a[0];
1459
+ result[2] = a[0] * b[1] - b[0] * a[1];
1460
+ }
dms/dms.1 ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .TH DMS 1 "" "\fBAPPENDIX 6\fP" "\fBUCSF MidasPlus\fP"
2
+ .iX zd start
3
+ .SH NAME
4
+ dms \- calculate a solvent-accessible molecular surface
5
+ .SH SYNOPSIS
6
+ .B dms
7
+ \fIfile\fR [
8
+ .B \-a
9
+ ] [
10
+ .B \-d
11
+ \fIdensity\fR] [
12
+ .B \-g
13
+ \fIfile\fR] [
14
+ .B \-i
15
+ \fIfile\fR] [\fB\-n\fR] [\fB\-w
16
+ \fIradius\fR] [\fB\-v\fR] \fB\-o\fI file\fR
17
+ .SH DESCRIPTION
18
+ .I Dms
19
+ calculates the molecular surface of a molecule.
20
+ The molecular surface resembles the van der Waals
21
+ surface of a molecule,
22
+ except that crevices between atoms are smoothed over
23
+ and interstices too small
24
+ to accommodate the probe are eliminated.
25
+ The surface includes cavities in the interior
26
+ of the molecule,
27
+ even if they are not accessible to a solvent molecule
28
+ coming from the outside.
29
+ .LP
30
+ The molecular surface
31
+ calculated is that defined by
32
+ F. M. Richards (1977,
33
+ .I "Ann. Rev. Biophys. Bioeng."
34
+ ).
35
+ In particular,
36
+ the calculated molecular surface is that traced out by the \fIsurface\fP
37
+ of the probe sphere rather that the probe sphere's \fIcenter\fP.
38
+ According to Richards' definition
39
+ the molecular surface consists of two parts:
40
+ .I "contact surface"
41
+ and
42
+ .I "reentrant surface."
43
+ The contact surface is
44
+ made up of
45
+ ``those parts of the molecular van der Waals
46
+ surface that can actually be in contact
47
+ with the surface of the probe.''
48
+ The reentrant surface is defined by
49
+ ``the interior-facing part of the probe
50
+ when it is simultaneously
51
+ in contact with more than one atom.''
52
+ .I Dms
53
+ reports the amounts of contact and reentrant surface area,
54
+ and the combined total surface area on the standard error output
55
+ (see the \fB\-g\fP flag below).
56
+ .LP
57
+ .I File
58
+ is an input file of coordinates.
59
+ The input file must be in the Protein Data Bank format.
60
+ The first letter or first two letters
61
+ of the atom name is used
62
+ to determine the element type.
63
+ By default, implicit hydrogens are
64
+ included for carbon,
65
+ nitrogen and oxygen atoms,
66
+ thus aromatic carbons
67
+ and nitrogens
68
+ will have van der Waals radii
69
+ that are somewhat too big.
70
+ Note that
71
+ only amino acid and nucleic acid residues
72
+ will be included unless \fB\-a\fR is also specified.
73
+ .LP
74
+ .SL
75
+ .I Dms
76
+ can be set up to run on multiple machines
77
+ simultaneously for increased performance.
78
+ By default, it only runs on the local host.
79
+ The
80
+ .SM UCSF
81
+ MidasPlus Installation Guide
82
+ that came with the MidasPlus
83
+ .SM CD-ROM
84
+ contains instructions
85
+ on how to configure
86
+ .I dms
87
+ to use multiple machines.
88
+ .EL
89
+ .LP
90
+ .SL
91
+ If it is desired to simply visualize a small molecular surface
92
+ from within
93
+ .SM MIDAS\c
94
+ , it may be easier to use the \fImakems\fP(1) delegate,
95
+ rather than run \fIdms\fP directly.
96
+ Consult the \fImakems\fP manual page for further details.
97
+ .EL
98
+ .SH OPTIONS
99
+ The flags may be in any order.
100
+ The meanings of the flags are described below:
101
+ .IP \fB\-a\fR
102
+ Include all atoms,
103
+ not just those in amino acid and nucleic acid residues.
104
+ .IP \fB\-d\fR
105
+ Change the density of points on the surface.
106
+ .I Density
107
+ is a factor affecting
108
+ the density of points on the surface;
109
+ the default of 1.0 produces about 5 points
110
+ per square angstrom.
111
+ Only values between 0.1 and 10.0 are permitted.
112
+ For large proteins,
113
+ a density of 0.5 is recommended.
114
+ .IP \fB\-g\fR
115
+ Write all the informative messages to
116
+ .I file,
117
+ instead of the standard error output.
118
+ Genuine errors still go to the standard error output.
119
+ This file is not rewound at any time,
120
+ so messages from several runs may be accumulated.
121
+ .IP \fB\-i\fR
122
+ .iX 36
123
+ Calculate the molecular surface
124
+ only for those residues and atoms
125
+ specified in
126
+ .I file,
127
+ but keeping the rest of the molecule
128
+ for collision checks.
129
+ The file consists of a series of lines
130
+ such as the following:
131
+ .nf
132
+ ASP 205 CA
133
+ TYR 13 *
134
+ GLY 116 FRM
135
+ HIS 178 TO
136
+ .fi
137
+ .IP
138
+ The asterisk means all atoms of the residue
139
+ and the ``FRM'' and ``TO'' mean all residues
140
+ from 116 to 178 inclusive.
141
+ The sequence number may contain letters,
142
+ and if the
143
+ .SM PDB
144
+ input file contains chain identifiers,
145
+ then those should be appended on the right of the sequence number.
146
+ Residue insertion codes (if any) should be placed between
147
+ the sequence number and any chain identifier.
148
+ Residues contained in \fCHETATM\fP records should have
149
+ an asterisk appended to the end of the residue identifier.
150
+ The surface generated using the \fB\-i\fR flag
151
+ is not always the same as the surface
152
+ generated by running the entire molecule
153
+ and afterwards selecting out the desired atoms.
154
+ The first surface will not include
155
+ reentrant surface lying between
156
+ an atom in the \fB\-i\fR file and atoms not in the file.
157
+ .iX bd
158
+ The
159
+ .IR pdb2site (1)
160
+ utility may be useful for generating site files.
161
+ Consult the
162
+ .I pdb2site
163
+ manual page for further details.
164
+ .IP \fB\-n\fR
165
+ Include the unit normals
166
+ to the surface with
167
+ each surface point record.
168
+ .IP \fB\-v\fR
169
+ Produce more verbose output.
170
+ .I Dms
171
+ will announce each computation phase as it is entered
172
+ as well as a count of the atom types in the molecule
173
+ and the number of computation requests handled by each
174
+ host that participated in the
175
+ .I dms
176
+ calculation.
177
+ .IP \fB\-o\fR
178
+ The output is written to
179
+ .I file.
180
+ This flag is not optional.
181
+ .IP \fB\-w\fR
182
+ Change the water probe radius from the default
183
+ radius of 1.4 angstroms.
184
+ This parameter must be between
185
+ 1.0 and 201.0.
186
+ .LP
187
+ The output consists of
188
+ a series of atom and surface point records,
189
+ with the same format for the
190
+ first six fields.
191
+ Each atom is followed by
192
+ the surface points (if any)
193
+ which belong to it.
194
+ These first six fields
195
+ are in the following format:
196
+ residue name,
197
+ sequence number,
198
+ atom name,
199
+ x coordinate,
200
+ y coordinate,
201
+ z coordinate.
202
+ For an atom record,
203
+ the seventh field is ``A.''
204
+ For a surface point record,
205
+ the seventh field begins
206
+ with an ``S,''
207
+ followed by a ``C,'' ``R,'' or ``S''
208
+ according to whether
209
+ the point is part of
210
+ contact, reentrant, or ``saddle'' surface
211
+ (``saddle'' is a type of reentrant surface
212
+ where the probe is in contact with exactly
213
+ two atoms).
214
+ This is followed a digit
215
+ used for depicting
216
+ different density levels.
217
+ The eighth field is the
218
+ molecular surface area associated
219
+ with the point in
220
+ square angstroms.
221
+ If the \fB\-n\fR flag is specified,
222
+ the next three fields are
223
+ the unit normal vector
224
+ pointing outward from the surface.
225
+ Informative messages and errors are
226
+ written to the standard error output
227
+ unless a \fB\-g\fR file is specified.
228
+ .LP
229
+ .iX 27 start
230
+ The chemical elements and radii
231
+ that the program handles are detailed
232
+ in the table below.
233
+ The program gets these values from the file
234
+ .IR /usr/local/midas/resource/dms/radii .
235
+ If there is a file in the current directory called
236
+ .IR radii ,
237
+ then
238
+ .I dms
239
+ will use that file instead.
240
+ So in order to add uncommon elements or
241
+ use different radii, one should copy the
242
+ default file and modify it.
243
+ The file format is documented in the file itself.
244
+ .sp
245
+ .RS 1i
246
+ .TS
247
+ box;
248
+ c c
249
+ a n.
250
+ Element Radius
251
+ _ _
252
+ H 1.20
253
+ C 1.90
254
+ N 1.50
255
+ O 1.40
256
+ F 1.35
257
+ P 1.90
258
+ S 1.85
259
+ Cl 1.8
260
+ Fe 0.64
261
+ Cu 1.28
262
+ Zn 1.38
263
+ Br 1.95
264
+ I 2.15
265
+ Other 1.90
266
+ .TE
267
+ .RE
268
+ .SH "SEE ALSO"
269
+ .SL
270
+ pdb2site(1),
271
+ The UCSF MidasPlus Installation Guide
272
+ .EL
273
+ .SH "AUTHOR"
274
+ Conrad Huang
275
+ .br
276
+ University of California, San Francisco
277
+ .SH FILES
278
+ /usr/local/midas/resource/dms/radii default atomic radii
279
+ .iX 27 stop
280
+ .br
281
+ .SH DIAGNOSTICS
282
+ Many and varied.
283
+ .iX 37
284
+ Be sure to examine the \fB\-g\fR file before you leave
285
+ a background job running overnight.
286
+ .iX zd stop
dms/dms.html ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <title>dms</title>
4
+ </head>
5
+ <body>
6
+ <h4>NAME</h4>
7
+ <h3>dms - calculate a molecular surface</h3>
8
+
9
+ <h4>SYNOPSIS</h4>
10
+ <h3><b>dms</b> <i>pdbfile</i> [ -a ] [ -d <i>density</i>] [ -g <i>logfile</i> ]
11
+ [ -i <i>sitefile</i> ] [-n] [-w <i>radius</i> ] [-v] -o <i>outfile</i>
12
+ </h3>
13
+
14
+ <h4>DESCRIPTION</h4>
15
+ <p>
16
+ <b>Dms</b> calculates the molecular surface of a molecule.
17
+ The molecular surface
18
+ resembles the van der Waals surface of a molecule, except that crevices
19
+ between atoms are smoothed over and interstices too small to accommodate
20
+ the probe are eliminated. The surface includes cavities in the interior of
21
+ the molecule, even if they are not accessible to a solvent molecule coming
22
+ from the outside.
23
+ </p><p>
24
+ The molecular surface calculated is that defined by Richards (see
25
+ the <a href="#ref">reference</a> below).
26
+ In particular, the calculated molecular surface is that traced out by
27
+ the surface of the probe sphere rather that the
28
+ probe sphere's center. According to Richards' definition, the molecular
29
+ surface consists of two parts: contact surface and reentrant surface. The
30
+ contact surface is made up of "those parts of the molecular van der Waals
31
+ surface that can actually be in contact with the surface of the probe."
32
+ The reentrant surface is defined by "the interior-facing part of the probe
33
+ when it is simultaneously in contact with more than one atom." <b>Dms</b>
34
+ reports the amounts of contact and reentrant surface area, and the combined
35
+ total surface area on the standard error output (see <a href="#gflag">
36
+ <b>-g</b></a>).
37
+ </p><p>
38
+ <i>Pdbfile</i> is an input file of coordinates.
39
+ The input file must be in the Protein Data Bank format.
40
+ The first part of each atom
41
+ name is used to determine the element type. By default, implicit hydrogens
42
+ are included for carbon, nitrogen and oxygen atoms; thus, aromatic carbons
43
+ and nitrogens will have van der Waals radii that are somewhat too big.
44
+ Note that only amino acid and nucleic acid residues will be included unless
45
+ <a href="#aflag"><b>-a</b></a> is also specified.
46
+ </p>
47
+
48
+ <h4>COMMAND-LINE ARGUMENTS</h4>
49
+
50
+ <blockquote>
51
+ <a name="aflag">
52
+ <tt><b>-a</b></tt>
53
+ </a>
54
+ <br>Include all atoms, not just those in amino acid and nucleic acid residues.
55
+ </blockquote>
56
+
57
+ <blockquote>
58
+ <tt><b>-d</b> <i>density</i></tt>
59
+ <br> <i>Density</i> is a factor affecting the density of points
60
+ on the surface; the default of <b>1.0</b>
61
+ produces about 5 points per square angstrom. Only values between
62
+ <b>0.1</b> and <b>10.0</b> are permitted.
63
+ A density of <b>0.5</b> is recommended for large molecules.
64
+ </blockquote>
65
+
66
+ <blockquote>
67
+ <a name="gflag">
68
+ <tt><b>-g</b> <i>logfile</i></tt>
69
+ </a>
70
+ <br> Write all the informative messages to <i>logfile</i> instead of the
71
+ standard error output. Genuine errors still go to the standard error
72
+ output. New log information is appended to <i>logfile</i> rather than
73
+ overwriting it, and thus messages from several runs may be accumulated.
74
+ </blockquote>
75
+
76
+ <blockquote>
77
+ <a name="iflag">
78
+ <tt><b>-i</b> <i>sitefile</i></tt>
79
+ </a>
80
+ <br> Calculate the molecular surface only for those residues and atoms
81
+ specified in <i>sitefile</i>,
82
+ keeping the rest of the molecule for collision checks.
83
+ <i>Sitefile</i> consists of lines such as the following:
84
+ <blockquote><tt>
85
+ <table>
86
+ <tr>
87
+ <td>ASP</td> <td align="right">205</td> <td>CA</td>
88
+ </tr><tr>
89
+ <td>TYR</td> <td align="right">13</td> <td>*</td>
90
+ </tr><tr>
91
+ <td>GLY</td> <td align="right">116</td> <td>FRM</td>
92
+ </tr><tr>
93
+ <td>HIS</td> <td align="right">178</td> <td>TO</td>
94
+ </tr>
95
+ </table>
96
+ </tt></blockquote>
97
+ The asterisk, <b>*</b>, means all atoms of the residue, and the
98
+ "FRM" and "TO" lines mean all residues from 116 to 178 inclusive.
99
+ The sequence number may
100
+ contain letters, and if the PDB input file contains chain identifiers,
101
+ then those should be appended on the right of the sequence number.
102
+ Residue insertion codes (if any) should be placed between the sequence
103
+ number and any chain identifier. Residues contained in HETATM records
104
+ should have an asterisk appended to the end of the residue identifier.
105
+ The surface generated using <a href="#iflag"><b>-i</b></a>
106
+ is not always the same as the
107
+ surface generated by running the entire molecule and afterwards
108
+ selecting the desired atoms. The first surface will not include
109
+ reentrant surface lying between an atom in <i>sitefile</i> and atoms not
110
+ in the file.
111
+ </blockquote>
112
+
113
+ <blockquote>
114
+ <a name="nflag">
115
+ <tt><b>-n</b></tt>
116
+ </a>
117
+ <br> Include the unit normals to the surface with each surface point record.
118
+ </blockquote>
119
+
120
+ <blockquote>
121
+ <tt><b>-w</b> <i>radius</i></tt>
122
+ <br> Change the "water" probe <i>radius</i> from the default of <b>1.4</b>
123
+ angstroms. <i>Radius</i> must be between <b>1.0</b> and <b>201.0</b>.
124
+ </blockquote>
125
+
126
+ <blockquote>
127
+ <tt><b>-v</b></tt>
128
+ <br> Produce more verbose output. <b>Dms</b>
129
+ will announce each computation phase
130
+ as it is entered as well as a count of the atom types in the molecule
131
+ and the number of computation requests handled by each host that
132
+ participated in the calculation.
133
+ </blockquote>
134
+
135
+ <blockquote>
136
+ <tt><b>-o</b> <i>outfile</i></tt>
137
+ <br> The output surface is written to <i>outfile</i>.
138
+ This flag is not optional.
139
+ </blockquote>
140
+
141
+ <p>
142
+ The output consists of a series of atom and surface point records, with the
143
+ same format for the first six fields. Each atom is followed by the surface
144
+ points (if any) which belong to it. These first six fields are in the
145
+ following format: residue name, sequence number, atom name, x coordinate,
146
+ y coordinate, z coordinate. For an atom record, the seventh field is "A."
147
+ For a surface point record, the seventh field begins with an "S,"
148
+ followed by a "C," "R," or "S" according to whether the point is part of
149
+ contact, reentrant, or saddle surface (saddle is a type of reentrant
150
+ surface where the probe is in contact with exactly two atoms). This
151
+ is followed a digit used for depicting different density levels. The
152
+ eighth field is the molecular surface area associated with the point in
153
+ square angstroms. If <a href="#nflag"><b>-n</b></a> is specified, the
154
+ next three fields are
155
+ the unit normal vector pointing outward from the surface.
156
+ Messages and errors are written to the standard error output
157
+ unless a separate log file has been
158
+ specified with <a href="#gflag"><b>-g</b></a>.
159
+ </p><p>
160
+ <b>Dms</b> reads the elements and radii from a file named <b>radii</b>.
161
+ If there is a file in the current
162
+ directory called <b>radii</b>, then <b>dms</b> will use that file instead.
163
+ To add uncommon elements or use different radii, one should copy the
164
+ default radii file from the distribution and modify it.
165
+ The file format is documented in the file itself.
166
+ </p>
167
+
168
+ <h4>SEE ALSO</h4>
169
+ <p>
170
+ <a name="ref">
171
+ Richards, F.M.,</a>
172
+ "Areas, volumes, packing and protein structure,"
173
+ <i>Ann. Rev. Biophys. Bioeng.</i> <b>6</b>, 151-176 (1977).
174
+ </p>
175
+
176
+ <h4>AUTHOR</h4>
177
+ Conrad Huang
178
+ <br>University of California, San Francisco
179
+
180
+ <h4>DIAGNOSTICS</h4>
181
+ Many and varied. Be sure to examine the output messages (standard error
182
+ or <i>logfile</i>, if specified) before leaving a background job running.
183
+ </body></html>
dms/dms_param.h ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+
34
+ #define DEF_DIR(x) DESTLIB#x
35
+
36
+ /*
37
+ * SERVER_FILE contains a list of hosts that run dms servers (and are
38
+ * binary-compatible with the host running dms)
39
+ */
40
+ #define SERVER_FILE "dms_servers"
41
+ #define DEF_SERVER_FILE DEF_DIR(dms_servers)
42
+
43
+ /*
44
+ * RADII_FILE contains a list of radii
45
+ */
46
+ #define RADII_FILE "radii"
47
+ #define DEF_RADII_FILE DEF_DIR(radii)
48
+
49
+ /*
50
+ * LOCK_FILE is the name of the file that a dms server tries to lock.
51
+ * If the file exists and the lock fails, then the server will exit.
52
+ */
53
+ #define LOCK_FILE DEF_DIR(lockfile)
54
+
55
+ /*
56
+ * NICE_PRIORITY is the priority that a dms server sets itself to.
57
+ */
58
+ #define NICE_PRIORITY 15
59
+
60
+ /*
61
+ * The following #defines are for possible code options. The best
62
+ * combination for running on Suns is currently selected. Your mileage
63
+ * may vary with other (e.g. vectorizing) compilers.
64
+ */
65
+ #define SORTED_NB /* Neighbor list sorted by distance */
66
+ #undef ONE_OCCLUDE /* Only check occlusion after summing components */
67
+ #define KEEP_REAL /* Keep only non-hidden probes */
68
+ #define RETRANS_NB /* Retransmit shortened neighbor list to servers */
dms/dms_servers.proto ADDED
@@ -0,0 +1 @@
 
 
1
+ localhost
dms/dmsd/GNUmakefile ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ifeq ($(shell test -e /bin/cygwin1.dll && echo found),found)
2
+ PROG = dmsd.exe
3
+ else
4
+ PROG = dmsd
5
+ endif
6
+
7
+ DESTLIB = ${LIBDIR}/dms
8
+
9
+ DEFS = -DDESTLIB=\"${DESTLIB}\"
10
+
11
+ OBJS = server.o viewat.o lookat.o freadv.o emalloc.o
12
+ OPT = -g
13
+ CFLAGS = -I.. ${DEFS} ${OPT}
14
+
15
+ ${PROG}: ${OBJS}
16
+ ${CC} -o ${PROG} ${OBJS} -lm
17
+
18
+ beforeinstall:
19
+ -mkdir ${DESTLIB}
20
+
21
+ afterinstall:
22
+ cp ../dms_servers.proto ${DESTLIB}/dms_servers.proto
23
+
24
+ install: ${PROG} afterinstall
25
+ afterinstall: realinstall
26
+ realinstall: beforeinstall
27
+ cp ${PROG} ${DESTLIB}
28
+ -strip ${DESTLIB}/${PROG}
29
+
30
+ clean:
31
+ rm -f ${OBJS}
32
+
33
+ spotless:
34
+ rm -f ${OBJS} ${PROG}
dms/dmsd/emalloc.c ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <stdlib.h>
35
+
36
+ /*
37
+ * emalloc:
38
+ * Same as malloc but exits when failure occurs
39
+ */
40
+ char *
41
+ emalloc(size)
42
+ unsigned size;
43
+ {
44
+ register char *cp;
45
+
46
+ if ((cp = malloc(size)) == NULL) {
47
+ fprintf(stderr, "emalloc(%u) failed\n", size);
48
+ exit(1);
49
+ }
50
+ return cp;
51
+ }
52
+
53
+ /*
54
+ * erealloc:
55
+ * Same as realloc but exits when failure occurs
56
+ */
57
+ char *
58
+ erealloc(ptr, size)
59
+ char *ptr;
60
+ unsigned size;
61
+ {
62
+ register char *cp;
63
+
64
+ if ((cp = realloc(ptr, size)) == NULL) {
65
+ fprintf(stderr, "erealloc(ptr, %u) failed\n", size);
66
+ exit(1);
67
+ }
68
+ return cp;
69
+ }
70
+
71
+ /*
72
+ * ecalloc:
73
+ * Same as calloc but exits when failure occurs
74
+ */
75
+ char *
76
+ ecalloc(nelem, elsize)
77
+ unsigned nelem, elsize;
78
+ {
79
+ register char *cp;
80
+
81
+ if ((cp = calloc(nelem, elsize)) == NULL) {
82
+ fprintf(stderr, "calloc(%u, %u) failed\n", nelem, elsize);
83
+ exit(1);
84
+ }
85
+ return cp;
86
+ }
dms/dmsd/freadv.c ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <sys/types.h>
35
+ #include <sys/uio.h>
36
+
37
+ /*
38
+ * freadv:
39
+ * Like readv system call except we use stdio library
40
+ */
41
+ freadv(fp, iov, n)
42
+ FILE *fp;
43
+ struct iovec *iov;
44
+ int n;
45
+ {
46
+ register struct iovec *ip, *endip;
47
+ register int cc;
48
+
49
+ cc = 0;
50
+ endip = iov + n;
51
+ for (ip = iov; ip < endip; ip++)
52
+ cc += fread(ip->iov_base, sizeof (char), ip->iov_len, fp);
53
+ return cc;
54
+ }
dms/dmsd/lookat.c ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <math.h>
35
+
36
+ /*
37
+ * This function is like the one from the E & S library which produces
38
+ * a matrix to rotate a vector to the Z axis.
39
+ *
40
+ * This version is much enhanced over the Pic Sys original, in that
41
+ * you give it both ends of the bond to be rotated about and it
42
+ * returns both the "m_lookat" tensor and its inverse.
43
+ *
44
+ * Martin Pensak: 1977
45
+ *
46
+ * Stolen and hacked for the PS300 by Conrad Huang 24feb84
47
+ */
48
+ lookat(array, arrayinv, x, y)
49
+ double array[4][4]; /* the output array */
50
+ double arrayinv[4][4]; /* output array for the inverse of
51
+ * the main output */
52
+ double x[3], y[3]; /* the vectors */
53
+ {
54
+ register int j, k;
55
+ double a, b, c, l, d;
56
+ double m[4][4];
57
+
58
+ a = y[0] - x[0];
59
+ b = y[1] - x[1];
60
+ c = y[2] - x[2];
61
+ l = sqrt(a*a + c*c);
62
+ d = sqrt(l*l + b*b);
63
+ if (d == 0.0) {
64
+ fprintf(stderr, "Illegal value passed to m_lookat\n");
65
+ return;
66
+ }
67
+
68
+ m[0][0] = (l != 0) ? (c / l) : 1;
69
+ m[0][1] = (l != 0) ? (-(a * b)/(l * d)) : 0;
70
+ m[0][2] = a / d;
71
+ m[0][3] = 0;
72
+ m[1][0] = 0;
73
+ m[1][1] = l / d;
74
+ m[1][2] = b / d;
75
+ m[1][3] = 0;
76
+ m[2][0] = (l != 0) ? ( - a / l) : 0;
77
+ m[2][1] = (l != 0) ? ( -(b * c)/(l * d)) : 1;
78
+ m[2][2] = c / d;
79
+ m[2][3] = 0;
80
+ m[3][0] = m[3][1] = m[3][2] = 0;
81
+ m[3][3] = 1;
82
+
83
+ for (j = 0; j < 4; j++)
84
+ for (k = 0; k < 4; k++)
85
+ array[j][k] = arrayinv[k][j] = m[j][k];
86
+
87
+ /* now set up the translations */
88
+ a = x[0];
89
+ b = x[1];
90
+ c = x[2];
91
+ arrayinv[3][0] = a;
92
+ arrayinv[3][1] = b;
93
+ arrayinv[3][2] = c;
94
+
95
+ array[3][0] = -(a*m[0][0] + b*m[1][0] + c*m[2][0]);
96
+ array[3][1] = -(a*m[0][1] + b*m[1][1] + c*m[2][1]);
97
+ array[3][2] = -(a*m[0][2] + b*m[1][2] + c*m[2][2]);
98
+ }
dms/dmsd/server.c ADDED
@@ -0,0 +1,1834 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <math.h>
35
+ #include <sys/types.h>
36
+ #include <sys/uio.h>
37
+ #include <sys/file.h>
38
+ #include <sys/time.h>
39
+ #include <sys/resource.h>
40
+ #include "dms_param.h"
41
+ #include "atoms.h"
42
+ #include "protocol.h"
43
+
44
+ #ifndef TRUE
45
+ #define TRUE 1
46
+ #define FALSE 0
47
+ #endif
48
+
49
+ #ifndef PI
50
+ #define PI 3.141592
51
+ #endif
52
+
53
+ #define ROUND(x) ((int) ((x) + 0.5))
54
+ #define ABS(x) ((x) < 0 ? -(x) : (x))
55
+
56
+ #define LOG /* Log input and output */
57
+
58
+ #ifndef DEBUG
59
+ #undef LOG
60
+ #endif
61
+
62
+ static void execute(char *cp);
63
+ static void paramdata(double f1, double f2, int n);
64
+ static void atomdata(int n);
65
+ static void neighbordata(int n);
66
+ static void probedata(int n);
67
+ static void contacts(int n);
68
+ static void s_probes(int n, int m);
69
+ static void csurface(int n);
70
+ static void tsurface(int n, int m);
71
+ static void psurface(int n);
72
+
73
+ extern char *sbrk(unsigned long);
74
+ extern char *emalloc(unsigned int);
75
+
76
+ /*
77
+ * SERVER:
78
+ * Compute server for MS.
79
+ * This server is started via inetd so the input comes from stdin
80
+ * and output goes to stdout.
81
+ */
82
+ main()
83
+ {
84
+ char buf[BUFSIZ];
85
+ int lockfd;
86
+
87
+ (void) chdir("/tmp");
88
+ #ifdef DEBUG
89
+ (void) freopen("/tmp/dmsdlog", "w", stderr);
90
+ #ifdef BSD
91
+ (void) setlinebuf(stderr);
92
+ #endif
93
+ fprintf(stderr, "server started\n");
94
+ #endif
95
+
96
+ /*
97
+ * Try locking the lock file. If we fail, another dms
98
+ * server is already running so we just exit. If the file
99
+ * doesn't exist, then we just assume that it's okay to run.
100
+ */
101
+ lockfd = open(LOCK_FILE, 0);
102
+ if (lockfd >= 0 && flock(lockfd, LOCK_EX) < 0) {
103
+ printf("Go away, I'm busy.\n");
104
+ exit(0);
105
+ }
106
+
107
+ /*
108
+ * Now we nice ourselves down to background priority so
109
+ * normal jobs will still get the CPU
110
+ */
111
+ #ifdef BSD
112
+ (void) setpriority(PRIO_PROCESS, 0, NICE_PRIORITY);
113
+ #else
114
+ (void) nice(NICE_PRIORITY);
115
+ #endif
116
+
117
+ /*
118
+ * Read commands and execute them until we reach EOF
119
+ */
120
+ while (fgets(buf, sizeof buf, stdin) != NULL) {
121
+ #ifdef LOG
122
+ fprintf(stderr, "<-- %s", buf);
123
+ #endif
124
+ execute(buf);
125
+ (void) fflush(stdout);
126
+ }
127
+
128
+ /*
129
+ * Cleanup and exit
130
+ */
131
+ #ifdef DEBUG
132
+ fprintf(stderr, "Memory high water mark: %d\n", sbrk(0));
133
+ #endif
134
+ exit(0);
135
+ }
136
+
137
+ typedef struct keyword_def {
138
+ char *string;
139
+ int length;
140
+ int type;
141
+ } KEYWORD;
142
+
143
+ #define C_PARAM 0
144
+ #define C_ATOM 1
145
+ #define C_NEIGHBOR 2
146
+ #define C_PROBEDATA 3
147
+ #define C_CONTACT 4
148
+ #define C_PROBE 5
149
+ #define C_CSURF 6
150
+ #define C_TSURF 7
151
+ #define C_PSURF 8
152
+
153
+ static KEYWORD keyword[] = {
154
+ { "paramdata", 9, C_PARAM, },
155
+ { "atomdata", 8, C_ATOM, },
156
+ { "neighbordata", 12, C_NEIGHBOR, },
157
+ { "probedata", 9, C_PROBEDATA, },
158
+ { "contacts", 8, C_CONTACT, },
159
+ { "probes", 6, C_PROBE, },
160
+ { "csurface", 8, C_CSURF, },
161
+ { "tsurface", 8, C_TSURF, },
162
+ { "psurface", 8, C_PSURF, },
163
+ };
164
+ #define NKEY (sizeof keyword / sizeof (KEYWORD))
165
+
166
+ /*
167
+ * execute:
168
+ * Parse the given command and call the appropriate handler
169
+ */
170
+ static
171
+ void
172
+ execute(char *cp)
173
+ {
174
+ register KEYWORD *kp, *endkp;
175
+ int n, m;
176
+ double f1, f2;
177
+
178
+ endkp = &keyword[NKEY];
179
+ for (kp = keyword; kp < endkp; kp++)
180
+ if (strncmp(cp, kp->string, kp->length) == 0)
181
+ break;
182
+ if (kp >= endkp) {
183
+ printf("Unknown command: %s", cp);
184
+ #ifdef DEBUG
185
+ fprintf(stderr, "Unknown command: %s", cp);
186
+ #endif
187
+ return;
188
+ }
189
+ switch (kp->type) {
190
+ case C_PARAM:
191
+ if (sscanf(cp, PI_COMMAND, &f1, &f2, &n) != 3)
192
+ goto bad;
193
+ paramdata(f1, f2, n);
194
+ break;
195
+ case C_ATOM:
196
+ if (sscanf(cp, AI_COMMAND, &n) != 1)
197
+ goto bad;
198
+ atomdata(n);
199
+ break;
200
+ case C_NEIGHBOR:
201
+ if (sscanf(cp, NI_COMMAND, &n) != 1)
202
+ goto bad;
203
+ neighbordata(n);
204
+ break;
205
+ case C_PROBEDATA:
206
+ if (sscanf(cp, PRI_COMMAND, &n) != 1)
207
+ goto bad;
208
+ probedata(n);
209
+ break;
210
+ case C_CONTACT:
211
+ if (sscanf(cp, C_COMMAND, &n) != 1)
212
+ goto bad;
213
+ contacts(n);
214
+ break;
215
+ case C_PROBE:
216
+ if (sscanf(cp, P_COMMAND, &n, &m) != 2)
217
+ goto bad;
218
+ s_probes(n, m);
219
+ break;
220
+ case C_CSURF:
221
+ if (sscanf(cp, CS_COMMAND, &n) != 1)
222
+ goto bad;
223
+ csurface(n);
224
+ break;
225
+ case C_TSURF:
226
+ if (sscanf(cp, TS_COMMAND, &n, &m) != 2)
227
+ goto bad;
228
+ tsurface(n, m);
229
+ break;
230
+ case C_PSURF:
231
+ if (sscanf(cp, PS_COMMAND, &n) != 1)
232
+ goto bad;
233
+ psurface(n);
234
+ break;
235
+ }
236
+ return;
237
+ bad:
238
+ printf("Malformed command: %s", cp);
239
+ #ifdef DEBUG
240
+ fprintf(stderr, "Malformed command: %s", cp);
241
+ #endif
242
+ return;
243
+ }
244
+
245
+ /*
246
+ * The remainder of this file consists of routines that correspond to
247
+ * commands. All necessary types and global variables are declared here.
248
+ */
249
+
250
+ typedef struct satom_def {
251
+ struct satom_def *next; /* Pointer to next neighbor */
252
+ ATOM atom; /* Atom information */
253
+ int nnb; /* Number of neighbors */
254
+ AINDEX *nb; /* Neighbor list */
255
+ int nprobe; /* Number of probes */
256
+ int *probe; /* Probe list */
257
+ int nused;
258
+ #ifdef SORTED_NB
259
+ double dist;
260
+ #endif
261
+ } SATOM;
262
+
263
+ typedef struct sphere_def {
264
+ struct sphere_def *next; /* Pointer to next sphere */
265
+ double radius; /* Radius */
266
+ double area; /* Area per point */
267
+ int npoint; /* Number of points */
268
+ POINT *point; /* Point list */
269
+ } SPHERE;
270
+
271
+ typedef struct snb_def {
272
+ double *coord; /* Coordinate of neighbor */
273
+ double dist; /* Distance between atoms */
274
+ double clip; /* Clipping distance */
275
+ } SNB;
276
+
277
+ typedef struct sangle_def {
278
+ struct sangle_def *next; /* Pointer to next angle */
279
+ double angle; /* Probe angle */
280
+ int start; /* Starting or ending? */
281
+ int real; /* This section truly exist */
282
+ } SANGLE;
283
+
284
+ double radius, density; /* Probe and surface parameters */
285
+ double arclength; /* Approximate arc length between points */
286
+ double root3; /* Square root of 3 */
287
+ int want_normal; /* Whether we should report normals */
288
+ int natom; /* Number of atoms */
289
+ SATOM *atom; /* Atom list */
290
+ int nprobe; /* Number of probes */
291
+ PROBE *probe; /* Probe list */
292
+ double maxrad; /* Maximum atomic radius */
293
+ SPHERE *sphere; /* List of prototype spheres */
294
+ int maxsurf; /* Size of surface list */
295
+ POINT *surface; /* Surface points list */
296
+ POINT *normal; /* Normal list (same size as surface) */
297
+
298
+ static SATOM *find_satom(double x);
299
+ static int touches(SATOM *s1, SATOM *s2, double *dp);
300
+ static int probe_position(SATOM *a0, SATOM *a1, SATOM *a2,
301
+ double ppos[2][3], int check_only);
302
+ static int hidden(SATOM *s0, SATOM *s1, SATOM *s2, double coord[3]);
303
+ static int occlude(SATOM *sap, double pos[3]);
304
+ static SPHERE *get_sphere(double r);
305
+ static int clipped(double coord[3], SNB *nlist, SNB *endsnp);
306
+ static SANGLE *compute_angles(SATOM *s1, SATOM *s2, double mat[4][4],
307
+ int *na);
308
+ static void draw_tsections(double invmat[4][4], double tradius,
309
+ double clip[2], int n, int m, SANGLE *alist);
310
+ static int torus_data(ATOM *a1, ATOM *a2, double tcenter[3],
311
+ double *tradius, double clip[2]);
312
+ static SANGLE *probe_angle(int pnum, double mat[4][4], int n, int m);
313
+ static SANGLE *insert_angle(SANGLE *head, SANGLE *new);
314
+ static void tsection(double invmat[4][4], double tradius, double clip[2],
315
+ double start, double end, int n, int m, int check);
316
+ static void send_points(POINT *plist, int np, AINDEX aindex, double area,
317
+ int type, POINT *nlist);
318
+ static void check_point(PROBE *prp, int at, int up, int side, int npoint,
319
+ POINT point[], short keep[]);
320
+
321
+ /*
322
+ * paramdata:
323
+ * Take the parameter data and put them in the right places
324
+ */
325
+ static
326
+ void
327
+ paramdata(double f1, double f2, int n)
328
+ {
329
+ radius = f1;
330
+ density = f2 * 2.75;
331
+ want_normal = n;
332
+ root3 = sqrt(3.0);
333
+
334
+ /*
335
+ * The approximation
336
+ * arclength = sqrt( sqrt(3) / (3 * density) )
337
+ * came from Eric Pettersen who approximated a sphere with a
338
+ * plane (an infinite sphere, you know).
339
+ */
340
+ arclength = 1.0 / sqrt(root3 * density);
341
+
342
+ fputs(PI_RESPONSE, stdout);
343
+ #ifdef LOG
344
+ fputs(PI_RESPONSE, stderr);
345
+ #endif
346
+ }
347
+
348
+ /*
349
+ * atomdata:
350
+ * Read in atomic data
351
+ */
352
+ static
353
+ void
354
+ atomdata(int n)
355
+ {
356
+ register int cc;
357
+ register SATOM *sap, *endsap;
358
+ register struct iovec *ip;
359
+ struct iovec *iov, *endip;
360
+
361
+ /*
362
+ * Update global variables
363
+ */
364
+ natom = n;
365
+ atom = (SATOM *) emalloc(n * sizeof (SATOM));
366
+ #ifdef DEBUG
367
+ fprintf(stderr, "Atom data = %d bytes\n", n * sizeof (SATOM));
368
+ #endif
369
+
370
+ /*
371
+ * Read in the data
372
+ */
373
+ iov = (struct iovec *) emalloc(n * sizeof (struct iovec));
374
+ endip = iov + n;
375
+ for (ip = iov, sap = atom; ip < endip; ip++, sap++) {
376
+ ip->iov_base = (caddr_t) &sap->atom;
377
+ ip->iov_len = sizeof (ATOM);
378
+ }
379
+ if ((cc = freadv(stdin, iov, n)) != n * sizeof (ATOM)) {
380
+ printf("atomdata: got %d bytes instead of %d.\n",
381
+ cc, n * sizeof (ATOM));
382
+ #ifdef DEBUG
383
+ fprintf(stderr, "atomdata: got %d bytes instead of %d.\n",
384
+ cc, n * sizeof (ATOM));
385
+ #endif
386
+ return;
387
+ }
388
+
389
+ /*
390
+ * Initialize data regarding spheres
391
+ */
392
+ maxrad = 0;
393
+ endsap = atom + n;
394
+ for (sap = atom; sap < endsap; sap++) {
395
+ if (sap->atom.radius > maxrad)
396
+ maxrad = sap->atom.radius;
397
+ sap->nb = NULL;
398
+ }
399
+
400
+ /*
401
+ * Cleanup and let caller know we've read things okay
402
+ */
403
+ (void) free((char *) iov);
404
+ fputs(AI_RESPONSE, stdout);
405
+ #ifdef LOG
406
+ fputs(AI_RESPONSE, stderr);
407
+ #endif
408
+ }
409
+
410
+ /*
411
+ * neighbordata:
412
+ * Read in neighbor data
413
+ */
414
+ static
415
+ void
416
+ neighbordata(int n)
417
+ {
418
+ register int cc, size, total;
419
+ register SATOM *sap, *endsap;
420
+ register struct iovec *ip;
421
+ struct iovec *iov;
422
+
423
+ /*
424
+ * Check for consistency
425
+ */
426
+ if (n != natom) {
427
+ printf("neighbordata: ncount(%d) != acount(%d)\n", n, natom);
428
+ #ifdef DEBUG
429
+ fprintf(stderr, "neighbordata: ncount(%d) != acount(%d)\n",
430
+ n, natom);
431
+ #endif
432
+ return;
433
+ }
434
+ endsap = atom + natom;
435
+
436
+ /*
437
+ * Read in the neighbor count for each atom
438
+ */
439
+ iov = (struct iovec *) emalloc(natom * sizeof (struct iovec));
440
+ for (sap = atom, ip = iov; sap < endsap; sap++, ip++) {
441
+ ip->iov_base = (caddr_t) &sap->nnb;
442
+ ip->iov_len = sizeof (int);
443
+ }
444
+ if ((cc = freadv(stdin, iov, n)) != n * sizeof (int)) {
445
+ printf("neighbordata: read %d bytes instead of %d.\n", cc,
446
+ n * sizeof (int));
447
+ #ifdef DEBUG
448
+ fprintf(stderr, "neighbordata: read %d bytes instead of %d.\n",
449
+ cc, n * sizeof (int));
450
+ #endif
451
+ return;
452
+ }
453
+
454
+ /*
455
+ * Read in the actual data for each atom
456
+ */
457
+ total = 0;
458
+ n = 0;
459
+ ip = iov;
460
+ for (sap = atom; sap < endsap; sap++) {
461
+ if (sap->nnb <= 0)
462
+ continue;
463
+ size = sap->nnb * sizeof (AINDEX);
464
+ if (sap->nb == NULL)
465
+ sap->nb = (AINDEX *) emalloc(size);
466
+ ip->iov_base = (caddr_t) sap->nb;
467
+ ip->iov_len = size;
468
+ total += size;
469
+ n++;
470
+ ip++;
471
+ }
472
+ if (n > 0 && (cc = freadv(stdin, iov, n)) != total) {
473
+ printf("neighbordata: read %d bytes instead of %d.\n", cc,
474
+ total);
475
+ #ifdef DEBUG
476
+ fprintf(stderr, "neighbordata: read %d bytes instead of %d.\n",
477
+ cc, total);
478
+ #endif
479
+ return;
480
+ }
481
+ #ifdef DEBUG
482
+ fprintf(stderr, "Neighbor data = %d bytes\n", total + n * sizeof (int));
483
+ #endif
484
+
485
+ /*
486
+ * Cleanup and let caller know we've read things okay
487
+ */
488
+ (void) free((char *) iov);
489
+ fputs(NI_RESPONSE, stdout);
490
+ #ifdef LOG
491
+ fputs(NI_RESPONSE, stderr);
492
+ #endif
493
+ }
494
+
495
+ /*
496
+ * probedata:
497
+ * Read in probe and update atom information regarding probes
498
+ */
499
+ static
500
+ void
501
+ probedata(int n)
502
+ {
503
+ register int i;
504
+ register SATOM *sap, *endsap;
505
+ register PROBE *pp, *endpp;
506
+ register int cc, size;
507
+
508
+ /*
509
+ * Update global variables
510
+ */
511
+ nprobe = n;
512
+ if (n <= 0) {
513
+ fputs(PRI_RESPONSE, stdout);
514
+ #ifdef LOG
515
+ fputs(PRI_RESPONSE, stderr);
516
+ #endif
517
+ return;
518
+ }
519
+ size = n * sizeof (PROBE);
520
+ probe = (PROBE *) emalloc(size);
521
+ #ifdef DEBUG
522
+ fprintf(stderr, "Probe data = %d bytes\n", size);
523
+ #endif
524
+
525
+ /*
526
+ * Read in the data
527
+ */
528
+ if ((cc = fread((char *) probe, sizeof (PROBE), n, stdin)) != n) {
529
+ printf("probedata: got %d probes instead of %d.\n", cc, n);
530
+ #ifdef DEBUG
531
+ fprintf(stderr, "probedata: got %d bytes instead of %d.\n",
532
+ cc, size);
533
+ #endif
534
+ return;
535
+ }
536
+
537
+ /*
538
+ * Now we update the atom data
539
+ */
540
+ endsap = atom + natom;
541
+ for (sap = atom; sap < endsap; sap++)
542
+ sap->nprobe = sap->nused = 0;
543
+ endpp = probe + nprobe;
544
+ for (pp = probe; pp < endpp; pp++)
545
+ for (i = 0; i < 3; i++)
546
+ atom[pp->atom[i]].nprobe++;
547
+ for (sap = atom; sap < endsap; sap++)
548
+ if (sap->nprobe > 0)
549
+ sap->probe = (int *) emalloc(sap->nprobe *
550
+ sizeof (int));
551
+ else
552
+ sap->probe = NULL;
553
+ for (pp = probe; pp < endpp; pp++)
554
+ for (i = 0; i < 3; i++) {
555
+ sap = &atom[pp->atom[i]];
556
+ sap->probe[sap->nused++] = pp - probe;
557
+ }
558
+
559
+ /*
560
+ * Cleanup and let caller know we've read things okay
561
+ */
562
+ fputs(PRI_RESPONSE, stdout);
563
+ #ifdef LOG
564
+ fputs(PRI_RESPONSE, stderr);
565
+ #endif
566
+ }
567
+
568
+ /*
569
+ * contacts:
570
+ * Compute the contacts for atom `n'
571
+ */
572
+ static
573
+ void
574
+ contacts(int n)
575
+ {
576
+ register int i, nn;
577
+ register SATOM *sp, *prevsp;
578
+ register SATOM *sap, *me, *nlist;
579
+ register SATOM *min, *max;
580
+ AINDEX *narray;
581
+ double distsq;
582
+
583
+ /*
584
+ * Initialize local variables
585
+ */
586
+ me = &atom[n];
587
+
588
+ /*
589
+ * Locate set of atoms within `maxrad' of the given atom in
590
+ * the X direction. This gives us a set of atoms which is
591
+ * guaranteed to include all neighbors but is still smaller
592
+ * than the set of ALL atoms. There are more efficient ways
593
+ * to locate smaller sets but this one is easy.
594
+ */
595
+ min = find_satom(me->atom.coord[0] - me->atom.radius
596
+ - 2 * radius - maxrad);
597
+ max = find_satom(me->atom.coord[0] + me->atom.radius
598
+ + 2 * radius + maxrad) + 1;
599
+
600
+ /*
601
+ * Loop through the set of atoms and locate neighbors
602
+ */
603
+ nlist = NULL;
604
+ nn = 0;
605
+ for (sap = min; sap < max; sap++) {
606
+ if (sap == me || !touches(me, sap, &distsq))
607
+ continue;
608
+ nn++;
609
+ #ifdef SORTED_NB
610
+ sap->dist = distsq;
611
+ prevsp = NULL;
612
+ for (sp = nlist; sp != NULL; sp = sp->next) {
613
+ if (sp->dist > distsq)
614
+ break;
615
+ prevsp = sp;
616
+ }
617
+ if (prevsp == NULL) {
618
+ sap->next = nlist;
619
+ nlist = sap;
620
+ }
621
+ else {
622
+ sap->next = prevsp->next;
623
+ prevsp->next = sap;
624
+ }
625
+ #else
626
+ sap->next = nlist;
627
+ nlist = sap;
628
+ #endif
629
+ }
630
+
631
+ /*
632
+ * Report the neighbor list
633
+ */
634
+ printf(C_RESPONSE, n, nn);
635
+ #ifdef LOG
636
+ fprintf(stderr, C_RESPONSE, n, nn);
637
+ #endif
638
+ if (nn > 0) {
639
+ narray = (AINDEX *) emalloc(nn * sizeof (AINDEX));
640
+ for (sap = nlist, i = 0; sap != NULL; sap = sap->next, i++)
641
+ narray[i] = sap - atom;
642
+ (void) fwrite((char *) narray, sizeof (AINDEX), nn, stdout);
643
+ (void) free((char *) narray);
644
+ }
645
+ }
646
+
647
+ /*
648
+ * find_satom:
649
+ * When given an X coordinate, find the first atom whose
650
+ * X coordinate is greater than or equal to the given one.
651
+ * Note that the atoms are sorted by X already so we can
652
+ * use a binary search.
653
+ */
654
+ static
655
+ SATOM *
656
+ find_satom(double x)
657
+ {
658
+ register int hi, lo, mid;
659
+
660
+ hi = natom;
661
+ lo = 0;
662
+ mid = (hi + lo) / 2;
663
+ while (mid > lo) {
664
+ if (atom[mid].atom.coord[0] < x)
665
+ lo = mid;
666
+ else
667
+ hi = mid;
668
+ mid = (hi + lo) / 2;
669
+ }
670
+ return &atom[mid];
671
+ }
672
+
673
+ /*
674
+ * touches:
675
+ * When given two atoms, determine whether they are neighbors
676
+ * (i.e. a probe will NOT fit between them).
677
+ */
678
+ static
679
+ int
680
+ touches(SATOM *s1, SATOM *s2, double *dp)
681
+ {
682
+ register int i;
683
+ double distsq, delta;
684
+ double maxdistsq;
685
+
686
+ /*
687
+ * Compute the maximum distance between these two atoms and
688
+ * still remain neighbors
689
+ */
690
+ delta = s1->atom.radius + s2->atom.radius + 2 * radius;
691
+ maxdistsq = delta * delta;
692
+
693
+ /*
694
+ * We determine the square of the distance between the two
695
+ * atoms and compare against `maxdistsq'. Note that we
696
+ * compute the distance in the order Z, Y, X since we know
697
+ * that X is probably okay and Z and Y will give quicker
698
+ * failure if there is one.
699
+ */
700
+ distsq = 0;
701
+ for (i = 2; i >= 0; i--) {
702
+ delta = s1->atom.coord[i] - s2->atom.coord[i];
703
+ distsq += delta * delta;
704
+ if (distsq >= maxdistsq)
705
+ return FALSE;
706
+ }
707
+ *dp = distsq;
708
+ return TRUE;
709
+ }
710
+
711
+ /*
712
+ * s_probes:
713
+ * Compute the probes that are adjacent to both given atoms
714
+ */
715
+ static
716
+ void
717
+ s_probes(int n, int m)
718
+ {
719
+ register int i, j, k;
720
+ register SATOM *s0, *s1, *s2;
721
+ register PROBE *plist, *pp;
722
+ register int np;
723
+ double ppos[2][3];
724
+ int wanted;
725
+
726
+ /*
727
+ * Initialize local variables
728
+ */
729
+ s0 = &atom[n];
730
+ s1 = &atom[m];
731
+ wanted = s0->atom.wanted || s1->atom.wanted;
732
+
733
+ /*
734
+ * Locate probes that may be in contact with the given
735
+ * atoms. We need not report any probe that involves any
736
+ * atom whose index is less than `m' because it will already
737
+ * have been computed
738
+ */
739
+ plist = NULL;
740
+ np = 0;
741
+ for (i = 0; i < s0->nnb; i++)
742
+ for (j = 0; j < s1->nnb; j++) {
743
+ if (s0->nb[i] != s1->nb[j])
744
+ continue;
745
+ s2 = &atom[s0->nb[i]];
746
+ if (!wanted && !s2->atom.wanted)
747
+ continue;
748
+ k = probe_position(s0, s1, s2, ppos, s0->nb[i] <= m);
749
+ if (k < 0) {
750
+ /*
751
+ * s2 is between s0 and s1. Just report that
752
+ * n and m cannot be neighbors and quit
753
+ */
754
+ printf(P_BADNB, n, m);
755
+ #ifdef LOG
756
+ fprintf(stderr, P_BADNB, n, m);
757
+ #endif
758
+ goto bad;
759
+ }
760
+ if (k == 0)
761
+ break;
762
+ for (k = 0; k < 2; k++) {
763
+ #ifdef KEEP_REAL
764
+ if (hidden(s0, s1, s2, ppos[k]))
765
+ continue;
766
+ #endif
767
+ np++;
768
+ pp = (PROBE *) emalloc(sizeof (PROBE));
769
+ pp->next = plist;
770
+ plist = pp;
771
+ pp->coord[0] = ppos[k][0];
772
+ pp->coord[1] = ppos[k][1];
773
+ pp->coord[2] = ppos[k][2];
774
+ pp->atom[0] = n;
775
+ pp->atom[1] = m;
776
+ pp->atom[2] = s0->nb[i];
777
+ #ifdef KEEP_REAL
778
+ pp->real = TRUE;
779
+ #else
780
+ pp->real = !hidden(s0, s1, s2, ppos[k]);
781
+ #endif
782
+ }
783
+ break;
784
+ }
785
+
786
+ /*
787
+ * Report data back to user
788
+ */
789
+ printf(P_RESPONSE, np);
790
+ #ifdef LOG
791
+ fprintf(stderr, P_RESPONSE, np);
792
+ #endif
793
+
794
+ /*
795
+ * Send the data, clean up and go home
796
+ */
797
+ for (pp = plist; pp != NULL; pp = plist) {
798
+ (void) fwrite((char *) pp, sizeof (PROBE), 1, stdout);
799
+ plist = pp->next;
800
+ free((char *) pp);
801
+ }
802
+ return;
803
+
804
+ bad:
805
+ /*
806
+ * We get here when we "know" that there can be no probes
807
+ * sitting against bot given atoms. Just report a zero
808
+ * and release data structures.
809
+ */
810
+ printf(P_RESPONSE, 0);
811
+ #ifdef LOG
812
+ fprintf(stderr, P_RESPONSE, 0);
813
+ #endif
814
+ for (pp = plist; pp != NULL; pp = plist) {
815
+ plist = pp->next;
816
+ free((char *) pp);
817
+ }
818
+ }
819
+
820
+ /*
821
+ * probe_position:
822
+ * When given three atoms, find the two possible probe positions.
823
+ * First we transform the coordinates such that a0 is at the origin,
824
+ * a1 is on the z axis, and a2 is in the y-z plane. This arrangement
825
+ * constrains the two probe positions of have the same y and z coordinates
826
+ * and complementary x coordinates.
827
+ * The three equations constraining distances are:
828
+ * sq(x) + sq(y) + sq(z) = sq(R0 + Rp)
829
+ * sq(x) + sq(y) + sq(z - z1) = sq(R1 + Rp)
830
+ * sq(x) + sq(y - y2) + sq(z - z2) = sq(R2 + Rp)
831
+ * from which we can solve for z, then y in terms of z, then x in
832
+ * terms of y and z.
833
+ *
834
+ * probe_position returns one of three values:
835
+ * 1 - where both probe positions have been found
836
+ * 0 - where no probe position is found but a0 and a1
837
+ * can still be neighbors
838
+ * -1 - where a0 and a1 cannot be neighbors because a2 is
839
+ * in the way
840
+ */
841
+ static
842
+ int
843
+ probe_position(SATOM *a0, SATOM *a1, SATOM *a2, double ppos[2][3], int check_only)
844
+ {
845
+ register int i, j;
846
+ double mat[4][4], invmat[4][4];
847
+ double r0, r1, r2, dz1, dz2;
848
+ double z1, y2, z2, t;
849
+ double dy, dz;
850
+ double c[3];
851
+
852
+ /*
853
+ * Convert to simple coordinate system
854
+ */
855
+ viewat(mat, invmat, a0->atom.coord, a1->atom.coord, a2->atom.coord);
856
+ z1 = a1->atom.coord[0] * mat[0][2] + a1->atom.coord[1] * mat[1][2] +
857
+ a1->atom.coord[2] * mat[2][2] + mat[3][2];
858
+ y2 = a2->atom.coord[0] * mat[0][1] + a2->atom.coord[1] * mat[1][1] +
859
+ a2->atom.coord[2] * mat[2][1] + mat[3][1];
860
+ z2 = a2->atom.coord[0] * mat[0][2] + a2->atom.coord[1] * mat[1][2] +
861
+ a2->atom.coord[2] * mat[2][2] + mat[3][2];
862
+
863
+ /*
864
+ * Solve in simple coordinate system.
865
+ */
866
+ r0 = a0->atom.radius + radius;
867
+ r1 = a1->atom.radius + radius;
868
+ c[2] = (r0 * r0 - r1 * r1 + z1 * z1) / (2 * z1);
869
+ r2 = a2->atom.radius + radius;
870
+ dz1 = c[2] - z1;
871
+ dz2 = c[2] - z2;
872
+ c[1] = (r1 * r1 - r2 * r2 - dz1 * dz1 + dz2 * dz2 + y2 * y2) / (2 * y2);
873
+ t = r0 * r0 - c[1] * c[1] - c[2] * c[2];
874
+
875
+ /*
876
+ * Now check whether the probe position is in "real" space. If
877
+ * not determine which atom is in between the others.
878
+ */
879
+ if (t <= 0) {
880
+ c[1] = -sqrt(r0 * r0 - c[2] * c[2]);
881
+ dy = y2 - c[1];
882
+ dz = z2 - c[2];
883
+ if (dy * dy + dz * dz <= r2 * r2)
884
+ return -1;
885
+ return 0;
886
+ }
887
+
888
+ /*
889
+ * Probe positions are valid, convert back to original
890
+ * coordinate system and return
891
+ */
892
+ if (check_only)
893
+ return 0;
894
+ c[0] = sqrt(t);
895
+ for (i = 0; i < 3; i++) {
896
+ ppos[0][i] = invmat[3][i];
897
+ for (j = 0; j < 3; j++)
898
+ ppos[0][i] += c[j] * invmat[j][i];
899
+ }
900
+ c[0] = -c[0];
901
+ for (i = 0; i < 3; i++) {
902
+ ppos[1][i] = invmat[3][i];
903
+ for (j = 0; j < 3; j++)
904
+ ppos[1][i] += c[j] * invmat[j][i];
905
+ }
906
+ return 1;
907
+ }
908
+
909
+ /*
910
+ * hidden:
911
+ * Determine whether the given coordinates is occluded by
912
+ * any of the neighbors of the given atoms
913
+ */
914
+ static
915
+ int
916
+ hidden(SATOM *s0, SATOM *s1, SATOM *s2, double coord[3])
917
+ {
918
+ register int i;
919
+
920
+ /*
921
+ * First we unmark all the atoms that need work.
922
+ * Then we mark the three that, by definition, cannot occlude
923
+ * the probe position.
924
+ */
925
+ for (i = 0; i < s0->nnb; i++)
926
+ atom[s0->nb[i]].nused = 0;
927
+ for (i = 0; i < s1->nnb; i++)
928
+ atom[s1->nb[i]].nused = 0;
929
+ for (i = 0; i < s2->nnb; i++)
930
+ atom[s2->nb[i]].nused = 0;
931
+ s0->nused = s1->nused = s2->nused = 1;
932
+
933
+ /*
934
+ * Now we loop through all the atoms and check
935
+ */
936
+ for (i = 0; i < s0->nnb; i++)
937
+ if (atom[s0->nb[i]].nused++ == 0)
938
+ if (occlude(&atom[s0->nb[i]], coord))
939
+ return TRUE;
940
+ for (i = 0; i < s1->nnb; i++)
941
+ if (atom[s1->nb[i]].nused++ == 0)
942
+ if (occlude(&atom[s1->nb[i]], coord))
943
+ return TRUE;
944
+ for (i = 0; i < s2->nnb; i++)
945
+ if (atom[s2->nb[i]].nused++ == 0)
946
+ if (occlude(&atom[s2->nb[i]], coord))
947
+ return TRUE;
948
+
949
+ /*
950
+ * Nobody blocked it. I guess it's okay
951
+ */
952
+ return FALSE;
953
+ }
954
+
955
+ /*
956
+ * occlude:
957
+ * Determine whether the given atom precludes placing a sphere
958
+ * at the given position
959
+ */
960
+ static
961
+ int
962
+ occlude(SATOM *sap, double pos[3])
963
+ {
964
+ register int i;
965
+ double delta, distsq;
966
+ #ifndef ONE_OCCLUDE
967
+ double minds;
968
+ #endif
969
+ #define EPSILON 1e-12
970
+
971
+ #ifndef ONE_OCCLUDE
972
+ delta = sap->atom.radius + radius;
973
+ minds = delta * delta;
974
+ #endif
975
+ distsq = EPSILON;
976
+ for (i = 0; i < 3; i++) {
977
+ delta = sap->atom.coord[i] - pos[i];
978
+ distsq += delta * delta;
979
+ #ifndef ONE_OCCLUDE
980
+ if (distsq > minds)
981
+ return FALSE;
982
+ #endif
983
+ }
984
+ #ifdef ONE_OCCLUDE
985
+ delta = sap->atom.radius + radius;
986
+ if (distsq > delta * delta)
987
+ return FALSE;
988
+ #endif
989
+ return TRUE;
990
+ }
991
+
992
+ /*
993
+ * csurface:
994
+ * Compute the contact surface of the given atom
995
+ */
996
+ static
997
+ void
998
+ csurface(int n)
999
+ {
1000
+ register POINT *pp, *endpp;
1001
+ register SATOM *sap, *me;
1002
+ register int i, j;
1003
+ register SNB *nlist, *snp, *endsnp;
1004
+ register SPHERE *sp;
1005
+ register POINT *savepp, *savenp;
1006
+ double delta, distsq, len, t;
1007
+ double r1p, r1psq, r2psq, r1sq;
1008
+ double coord[3];
1009
+
1010
+ /*
1011
+ * Initialize local variables
1012
+ */
1013
+ me = &atom[n];
1014
+ if (me->nnb > 0) {
1015
+ nlist = (SNB *) emalloc(me->nnb * sizeof (SNB));
1016
+ endsnp = nlist + me->nnb;
1017
+ }
1018
+ else
1019
+ nlist = NULL;
1020
+
1021
+ /*
1022
+ * Compute clipping distance for each neighbor
1023
+ */
1024
+ r1p = me->atom.radius + radius;
1025
+ r1psq = r1p * r1p;
1026
+ r1sq = me->atom.radius * me->atom.radius;
1027
+ for (i = 0; i < me->nnb; i++) {
1028
+ sap = &atom[me->nb[i]];
1029
+ snp = &nlist[i];
1030
+ snp->coord = sap->atom.coord;
1031
+ distsq = 0;
1032
+ for (j = 0; j < 3; j++) {
1033
+ delta = me->atom.coord[j] - sap->atom.coord[j];
1034
+ distsq += delta * delta;
1035
+ }
1036
+ snp->dist = sqrt(distsq);
1037
+ delta = sap->atom.radius + radius;
1038
+ r2psq = delta * delta;
1039
+ len = (r1psq - r2psq + distsq) / (2 * snp->dist);
1040
+ t = len * me->atom.radius / r1p;
1041
+ snp->clip = r1sq + distsq - 2 * snp->dist * t;
1042
+ }
1043
+
1044
+ /*
1045
+ * Now get a sphere and find all points which are not clipped
1046
+ * by any of the neighbors.
1047
+ */
1048
+ sp = get_sphere(me->atom.radius);
1049
+ endpp = sp->point + sp->npoint;
1050
+ if (sp->npoint > maxsurf) {
1051
+ if (surface != NULL) {
1052
+ (void) free((char *) surface);
1053
+ if (want_normal)
1054
+ (void) free((char *) normal);
1055
+ }
1056
+ maxsurf = sp->npoint;
1057
+ surface = (POINT *) emalloc(maxsurf * sizeof (POINT));
1058
+ if (want_normal)
1059
+ normal = (POINT *) emalloc(maxsurf * sizeof (POINT));
1060
+ }
1061
+ savepp = surface;
1062
+ savenp = normal;
1063
+ for (pp = sp->point; pp < endpp; pp++) {
1064
+ for (i = 0; i < 3; i++)
1065
+ coord[i] = me->atom.coord[i] + pp->coord[i];
1066
+ if (nlist != NULL && clipped(coord, nlist, endsnp))
1067
+ continue;
1068
+ for (i = 0; i < 3; i++)
1069
+ savepp->coord[i] = coord[i];
1070
+ savepp++;
1071
+ if (want_normal) {
1072
+ for (i = 0; i < 3; i++)
1073
+ savenp->coord[i] = pp->coord[i] / sp->radius;
1074
+ savenp++;
1075
+ }
1076
+ }
1077
+
1078
+ /*
1079
+ * Now that we have the points, just send them back to caller
1080
+ * and release the neighbor list
1081
+ */
1082
+ i = savepp - surface;
1083
+ printf(SURFACE_RESPONSE, n, i, CONTACT, sp->area, want_normal);
1084
+ #ifdef LOG
1085
+ fprintf(stderr, SURFACE_RESPONSE, n, i, CONTACT, sp->area, want_normal);
1086
+ #endif
1087
+ if (i > 0) {
1088
+ (void) fwrite((char *) surface, sizeof (POINT), i, stdout);
1089
+ if (want_normal) {
1090
+ (void) fwrite((char *) normal, sizeof (POINT), i,
1091
+ stdout);
1092
+ }
1093
+ }
1094
+ fputs(SURFACE_END, stdout);
1095
+ #ifdef LOG
1096
+ fputs(SURFACE_END, stderr);
1097
+ #endif
1098
+
1099
+ if (nlist != NULL)
1100
+ (void) free((char *) nlist);
1101
+ }
1102
+
1103
+ /*
1104
+ * get_sphere:
1105
+ * Return a prototype sphere of the given radius
1106
+ */
1107
+ static
1108
+ SPHERE *
1109
+ get_sphere(double r)
1110
+ {
1111
+ register SPHERE *sp;
1112
+ register int i, j;
1113
+ register POINT *pp;
1114
+ register int nlayer, npoint;
1115
+ double dphi, dtheta;
1116
+ double phi, theta, z, rsinphi;
1117
+
1118
+ /*
1119
+ * Look for one already on the list
1120
+ */
1121
+ for (sp = sphere; sp != NULL; sp = sp->next)
1122
+ if (sp->radius == r)
1123
+ return sp;
1124
+
1125
+ /*
1126
+ * Okay, it doesn't exist yet. Let's make one.
1127
+ */
1128
+ sp = (SPHERE *) emalloc(sizeof (SPHERE));
1129
+ sp->next = sphere;
1130
+ sphere = sp;
1131
+ sp->radius = r;
1132
+
1133
+ /*
1134
+ * Easy part is done. Now figure out how many points there
1135
+ * should be on the sphere.
1136
+ */
1137
+ dphi = arclength / r;
1138
+ nlayer = ROUND(PI / dphi) + 1;
1139
+ dphi = PI / nlayer;
1140
+ sp->npoint = 0;
1141
+ phi = 0;
1142
+ for (i = 0; i < nlayer; i++) {
1143
+ dtheta = (phi == 0) ? PI * 2 : arclength / (r * sin(phi));
1144
+ npoint = ROUND(PI * 2 / dtheta);
1145
+ if (npoint <= 0)
1146
+ npoint = 1;
1147
+ sp->npoint += npoint;
1148
+ phi += dphi;
1149
+ }
1150
+ sp->area = (4 * PI * r * r) / sp->npoint;
1151
+
1152
+ /*
1153
+ * Allocate space for the points and, possibly, angles
1154
+ */
1155
+ sp->point = (POINT *) emalloc(sp->npoint * sizeof (POINT));
1156
+
1157
+ /*
1158
+ * Now we actually generate the points
1159
+ */
1160
+ pp = sp->point;
1161
+ phi = 0;
1162
+ for (i = 0; i < nlayer; i++) {
1163
+ rsinphi = r * sin(phi);
1164
+ z = r * cos(phi);
1165
+ dtheta = (rsinphi == 0) ? PI * 2 : arclength / rsinphi;
1166
+ npoint = ROUND(PI * 2 / dtheta);
1167
+ if (npoint <= 0)
1168
+ npoint = 1;
1169
+ dtheta = PI * 2 / npoint;
1170
+ theta = (i % 2) ? 0 : PI;
1171
+ for (j = 0; j < npoint; j++) {
1172
+ pp->coord[0] = rsinphi * cos(theta);
1173
+ pp->coord[1] = rsinphi * sin(theta);
1174
+ pp->coord[2] = z;
1175
+ pp++;
1176
+ theta += dtheta;
1177
+ if (theta > PI * 2)
1178
+ theta -= PI * 2;
1179
+ }
1180
+ phi += dphi;
1181
+ }
1182
+
1183
+ return sp;
1184
+ }
1185
+
1186
+ /*
1187
+ * clipped:
1188
+ * Determine if the given coordinate is clipped by any
1189
+ * of the given neighbors
1190
+ */
1191
+ static
1192
+ int
1193
+ clipped(double coord[3], SNB *nlist, SNB *endsnp)
1194
+ {
1195
+ register SNB *snp;
1196
+ register int i;
1197
+ double delta, distsq;
1198
+
1199
+ for (snp = nlist; snp < endsnp; snp++) {
1200
+ distsq = 0;
1201
+ for (i = 0; i < 3; i++) {
1202
+ delta = snp->coord[i] - coord[i];
1203
+ distsq += delta * delta;
1204
+ }
1205
+ if (distsq < snp->clip)
1206
+ return TRUE;
1207
+ }
1208
+ return FALSE;
1209
+ }
1210
+
1211
+ /*
1212
+ * tsurface:
1213
+ * Compute torus surface for neighbor pair
1214
+ */
1215
+ static
1216
+ void
1217
+ tsurface(int n, int m)
1218
+ {
1219
+ register int i, j;
1220
+ register SATOM *s1, *s2;
1221
+ register SANGLE *ap, *anext;
1222
+ register SANGLE *alist;
1223
+ double tcenter[3], tradius, clip[2], coord[3];
1224
+ double mat[4][4], invmat[4][4];
1225
+ int na;
1226
+
1227
+ /*
1228
+ * Initialize local variables
1229
+ */
1230
+ s1 = &atom[n];
1231
+ s2 = &atom[m];
1232
+ if (!torus_data(&s1->atom, &s2->atom, tcenter, &tradius, clip)) {
1233
+ fputs(SURFACE_END, stdout);
1234
+ #ifdef LOG
1235
+ fputs(SURFACE_END, stderr);
1236
+ #endif
1237
+ return;
1238
+ }
1239
+ if (clip[0] > 0)
1240
+ lookat(mat, invmat, tcenter, s1->atom.coord);
1241
+ else {
1242
+ /* Note that we get the coordinates from s2 since clip[0]
1243
+ * may be zero which would result in division by zero if
1244
+ * we use coordinates from s1 */
1245
+ for (i = 0; i < 3; i++)
1246
+ coord[i] = tcenter[i] +
1247
+ (tcenter[i] - s2->atom.coord[i]);
1248
+ lookat(mat, invmat, tcenter, coord);
1249
+ }
1250
+
1251
+ alist = compute_angles(s1, s2, mat, &na);
1252
+ if (alist == NULL) {
1253
+ #ifdef KEEP_REAL
1254
+ na = 0;
1255
+ for (i = 0; i < s1->nnb; i++)
1256
+ for (j = 0; j < s2->nnb; j++) {
1257
+ if (s1->nb[i] != s2->nb[j])
1258
+ continue;
1259
+ na++;
1260
+ break;
1261
+ }
1262
+ #endif
1263
+ if (na == 0) {
1264
+ tsection(invmat, tradius, clip, 0.0, PI * 2,
1265
+ n, m, TRUE);
1266
+ }
1267
+ }
1268
+ else
1269
+ draw_tsections(invmat, tradius, clip, n, m, alist);
1270
+
1271
+ /*
1272
+ * Release the angle list and return to caller
1273
+ */
1274
+ for (ap = alist; ap != NULL; ap = anext) {
1275
+ anext = ap->next;
1276
+ (void) free((char *) ap);
1277
+ }
1278
+ fputs(SURFACE_END, stdout);
1279
+ #ifdef LOG
1280
+ fputs(SURFACE_END, stderr);
1281
+ #endif
1282
+ }
1283
+
1284
+ /*
1285
+ * compute_angles:
1286
+ * Loop through the probe list for each atom and find those
1287
+ * probes which are on both list.
1288
+ */
1289
+ #ifdef KEEP_REAL
1290
+ /*ARGSUSED*/
1291
+ #endif
1292
+ static
1293
+ SANGLE *
1294
+ compute_angles(SATOM *s1, SATOM *s2, double mat[4][4], int *na)
1295
+ {
1296
+ register int i, j;
1297
+ register PROBE *pp;
1298
+ register SANGLE *alist, *ap;
1299
+
1300
+ alist = NULL;
1301
+ j = s2 - atom;
1302
+ #ifndef KEEP_REAL
1303
+ *na = 0;
1304
+ #endif
1305
+ for (i = 0; i < s1->nprobe; i++) {
1306
+ pp = &probe[s1->probe[i]];
1307
+ if (pp->atom[0] != j && pp->atom[1] != j && pp->atom[2] != j)
1308
+ continue;
1309
+ #ifndef KEEP_REAL
1310
+ (*na)++;
1311
+ #endif
1312
+ ap = probe_angle(s1->probe[i], mat, s1 - atom, j);
1313
+ ap->real = pp->real;
1314
+ alist = insert_angle(alist, ap);
1315
+ }
1316
+ return alist;
1317
+ }
1318
+
1319
+ /*
1320
+ * draw_tsections:
1321
+ * Loop through the angle list and draw torus sections
1322
+ */
1323
+ static
1324
+ void
1325
+ draw_tsections(double invmat[4][4], double tradius, double clip[2], int n, int m, SANGLE *alist)
1326
+ {
1327
+ register SANGLE *ap, *anext;
1328
+
1329
+ for (ap = alist; ap != NULL; ap = ap->next) {
1330
+ if (!ap->start || !ap->real)
1331
+ continue;
1332
+ anext = (ap->next == NULL) ? alist : ap->next;
1333
+ tsection(invmat, tradius, clip, ap->angle,
1334
+ anext->angle, n, m, TRUE);
1335
+ }
1336
+ }
1337
+
1338
+ /*
1339
+ * torus_data:
1340
+ * Compute data regarding the torus (e.g. center, radius, etc.)
1341
+ */
1342
+ static
1343
+ int
1344
+ torus_data(ATOM *a1, ATOM *a2, double tcenter[3], double *tradius, double clip[2])
1345
+ {
1346
+ register int i;
1347
+ double distsq, dist;
1348
+ double r1p, r2p;
1349
+ double r1psq, r2psq, len;
1350
+ double lsq;
1351
+
1352
+ /*
1353
+ * Compute distance between atoms
1354
+ */
1355
+ distsq = 0;
1356
+ for (i = 0; i < 3; i++) {
1357
+ dist = a1->coord[i] - a2->coord[i];
1358
+ distsq += dist * dist;
1359
+ }
1360
+ dist = sqrt(distsq);
1361
+
1362
+ /*
1363
+ * Compute torus center and radius
1364
+ */
1365
+ r1p = a1->radius + radius;
1366
+ r1psq = r1p * r1p;
1367
+ r2p = a2->radius + radius;
1368
+ r2psq = r2p * r2p;
1369
+ len = (r1psq - r2psq + distsq) / (2 * dist);
1370
+ lsq = r1psq - len * len;
1371
+ if (lsq <= 0)
1372
+ return 0;
1373
+ *tradius = sqrt(lsq);
1374
+ for (i = 0; i < 3; i++)
1375
+ tcenter[i] = a1->coord[i] +
1376
+ (a2->coord[i] - a1->coord[i]) * len / dist;
1377
+
1378
+ /*
1379
+ * Now compute the clipping distance for the torus
1380
+ */
1381
+ clip[0] = len * (1.0 - a1->radius / r1p);
1382
+ clip[1] = (dist - len) * (1.0 - a2->radius / r2p);
1383
+ return 1;
1384
+ }
1385
+
1386
+ /*
1387
+ * probe_angle:
1388
+ * Determine the angle that the probe lies at
1389
+ */
1390
+ static
1391
+ SANGLE *
1392
+ probe_angle(int pnum, double mat[4][4], int n, int m)
1393
+ {
1394
+ register int i, j;
1395
+ register PROBE *pp;
1396
+ register SANGLE *sp;
1397
+ register ATOM *ap;
1398
+ double angle;
1399
+ double coord[3];
1400
+
1401
+ /*
1402
+ * Allocate space for angle structure
1403
+ */
1404
+ sp = (SANGLE *) emalloc(sizeof (SANGLE));
1405
+ sp->next = NULL;
1406
+ pp = &probe[pnum];
1407
+
1408
+ /*
1409
+ * Compute the polar coordinates of the probe
1410
+ */
1411
+ for (i = 0; i < 3; i++) {
1412
+ coord[i] = mat[3][i];
1413
+ for (j = 0; j < 3; j++)
1414
+ coord[i] += pp->coord[j] * mat[j][i];
1415
+ }
1416
+ sp->angle = atan2(coord[1], coord[0]);
1417
+
1418
+ /*
1419
+ * Compute the polar coordinates of the atom which
1420
+ * is adjacent to both given atoms
1421
+ */
1422
+ for (i = 0; i < 3; i++)
1423
+ if (pp->atom[i] != n && pp->atom[i] != m)
1424
+ break;
1425
+ ap = &atom[pp->atom[i]].atom;
1426
+ for (i = 0; i < 3; i++) {
1427
+ coord[i] = mat[3][i];
1428
+ for (j = 0; j < 3; j++)
1429
+ coord[i] += ap->coord[j] * mat[j][i];
1430
+ }
1431
+ angle = atan2(coord[1], coord[0]);
1432
+
1433
+ /*
1434
+ * Now determine whether the torus section should start or
1435
+ * end here
1436
+ */
1437
+ angle = angle - sp->angle;
1438
+ while (angle < 0)
1439
+ angle += PI * 2;
1440
+ sp->start = (angle >= PI);
1441
+ if (sp->angle < 0)
1442
+ sp->angle += PI * 2;
1443
+
1444
+ return sp;
1445
+ }
1446
+
1447
+ /*
1448
+ * insert_angle:
1449
+ * Insert an angle into a list and return the head of the list.
1450
+ * If there are two identical angles, we put the start before the end
1451
+ * to eliminate the surface since this mostly occurs near rings.
1452
+ */
1453
+ static
1454
+ SANGLE *
1455
+ insert_angle(SANGLE *head, SANGLE *new)
1456
+ {
1457
+ register SANGLE *ap;
1458
+
1459
+ /*
1460
+ * See if the new angle should be at the beginning
1461
+ */
1462
+ if (head == NULL || new->angle < head->angle
1463
+ || (new->angle == head->angle && !head->start)) {
1464
+ new->next = head;
1465
+ return new;
1466
+ }
1467
+
1468
+ /*
1469
+ * Find the angle whose successor is greater than the new angle.
1470
+ * Add the angle after this one and return the original head
1471
+ * of the list.
1472
+ */
1473
+ for (ap = head; ap->next != NULL; ap = ap->next) {
1474
+ if (ap->next->angle > new->angle
1475
+ || (ap->next->angle == new->angle && !ap->next->start))
1476
+ break;
1477
+ }
1478
+ new->next = ap->next;
1479
+ ap->next = new;
1480
+ return head;
1481
+ }
1482
+
1483
+ /*
1484
+ * tsection:
1485
+ * Generate a section of a torus
1486
+ *
1487
+ * The area of described by an arc swept through an angle is:
1488
+ * A = (integral) (integral) (r de) ds
1489
+ * where
1490
+ * r = Rt - Rs cos a
1491
+ * ds = Rs da
1492
+ * so
1493
+ * A = (i) (i) (Rt - Rs cos a) Rs da de
1494
+ * = e a Rt Rs - e Rs Rs (integral) cos a da
1495
+ * = e Rt a Rs - e Rs Rs sin a
1496
+ * Symbols are:
1497
+ * Rs = radius of arc
1498
+ * Rt = arc displacement from origin
1499
+ * a = angle of arc
1500
+ * e = angle swept through
1501
+ */
1502
+ static
1503
+ void
1504
+ tsection(double invmat[4][4], double tradius, double clip[2], double start, double end, int n, int m, int check)
1505
+ {
1506
+ register int i, j;
1507
+ register int npoint;
1508
+ register POINT *pp, *np;
1509
+ register int na, ne;
1510
+ POINT *plist, *nlist;
1511
+ double area;
1512
+ double mina, maxa;
1513
+ double aincr, eincr;
1514
+ double arange, erange;
1515
+ double e, a, mida;
1516
+ double nclip[2];
1517
+ int eoffset;
1518
+ int startm;
1519
+ double coord[3], xy;
1520
+ double cose, sine;
1521
+ double normal[3];
1522
+
1523
+ /*
1524
+ * First see whether the torus is really a torus.
1525
+ * If the probe extends below the center line between
1526
+ * the two atoms, only the portion which is above the center
1527
+ * line should be used for sweeping out the torus.
1528
+ */
1529
+ if (check && tradius < radius) {
1530
+ xy = sqrt(radius * radius - tradius * tradius);
1531
+ clip[1] = -clip[1];
1532
+ if (clip[1] < -xy && -xy < clip[0]) {
1533
+ nclip[0] = -xy;
1534
+ nclip[1] = -clip[1];
1535
+ tsection(invmat, tradius, nclip, start, end,
1536
+ n, m, FALSE);
1537
+ }
1538
+ if (clip[1] < xy && xy < clip[0]) {
1539
+ nclip[0] = clip[0];
1540
+ nclip[1] = -xy;
1541
+ tsection(invmat, tradius, nclip, start, end,
1542
+ n, m, FALSE);
1543
+ }
1544
+ return;
1545
+ }
1546
+
1547
+ /*
1548
+ * Figure out basic parameters
1549
+ */
1550
+ maxa = -acos(clip[0] / radius);
1551
+ mina = -acos(-clip[1] / radius);
1552
+ arange = maxa - mina;
1553
+ if (end < start)
1554
+ end += PI * 2;
1555
+ erange = end - start;
1556
+ area = erange * tradius * arange * radius -
1557
+ erange * radius * radius *
1558
+ (sin(maxa + PI / 2) + sin(-PI / 2 - mina));
1559
+
1560
+ /*
1561
+ * Now figure out the maximum number of points there might be
1562
+ * and allocate space for them
1563
+ */
1564
+ ne = ROUND(erange * tradius / arclength);
1565
+ if (ne <= 0)
1566
+ return;
1567
+ na = ROUND(arange * radius / (arclength * root3 / 2));
1568
+ if (na <= 0)
1569
+ return;
1570
+ npoint = na * ne;
1571
+ plist = (POINT *) emalloc(npoint * sizeof (POINT));
1572
+ if (want_normal)
1573
+ nlist = (POINT *) emalloc(npoint * sizeof (POINT));
1574
+ else
1575
+ nlist = NULL;
1576
+
1577
+ /*
1578
+ * Now loop through a and e and generate the points
1579
+ */
1580
+ pp = plist;
1581
+ np = nlist;
1582
+ eoffset = 0;
1583
+ mida = (mina + maxa) / 2;
1584
+ aincr = arange / na;
1585
+ a = mina + aincr / 2;
1586
+ startm = 0;
1587
+ while (na-- > 0) {
1588
+ /*
1589
+ * Compute things that only depend on a
1590
+ */
1591
+ coord[2] = radius * cos(a);
1592
+ if (want_normal)
1593
+ normal[2] = -coord[2] / radius;
1594
+ xy = radius * sin(a) + tradius;
1595
+
1596
+ /*
1597
+ * Loop through e and generate points
1598
+ */
1599
+ ne = ROUND(erange * xy / arclength);
1600
+ if (ne > 0) {
1601
+ eincr = erange / ne;
1602
+ e = start + eincr / 2 * (eoffset + 1);
1603
+ eoffset = 1 - eoffset;
1604
+ }
1605
+ while (ne-- > 0) {
1606
+ #ifdef DEBUG
1607
+ if (pp >= plist + npoint) {
1608
+ fprintf(stderr, "Point buffer overflow\n");
1609
+ abort();
1610
+ }
1611
+ #endif
1612
+ cose = cos(e);
1613
+ sine = sin(e);
1614
+ coord[0] = xy * cose;
1615
+ coord[1] = xy * sine;
1616
+ for (i = 0; i < 3; i++) {
1617
+ pp->coord[i] = invmat[3][i];
1618
+ for (j = 0; j < 3; j++)
1619
+ pp->coord[i] += coord[j] * invmat[j][i];
1620
+ }
1621
+ pp++;
1622
+ e += eincr;
1623
+ if (!want_normal)
1624
+ continue;
1625
+ normal[0] = (tradius * cose - coord[0]) / radius;
1626
+ normal[1] = (tradius * sine - coord[1]) / radius;
1627
+ for (i = 0; i < 3; i++) {
1628
+ np->coord[i] = 0; /* Just rotation */
1629
+ for (j = 0; j < 3; j++)
1630
+ np->coord[i] += normal[j] *
1631
+ invmat[j][i];
1632
+ }
1633
+ np++;
1634
+ }
1635
+
1636
+ /*
1637
+ * Increment a. If we pass the -PI/2 threshold, we will
1638
+ * start generating points on atom m.
1639
+ */
1640
+ a += aincr;
1641
+ if (a > mida && startm == 0)
1642
+ startm = pp - plist;
1643
+ }
1644
+
1645
+ /*
1646
+ * Send point data back to the caller and clean up
1647
+ */
1648
+ npoint = pp - plist;
1649
+ if (npoint > 0) {
1650
+ area = area / npoint;
1651
+ send_points(plist, startm, m, area, TREENTRANT, nlist);
1652
+ send_points(plist + startm, npoint - startm, n,
1653
+ area, TREENTRANT, nlist + startm);
1654
+ }
1655
+ (void) free((char *) plist);
1656
+ if (nlist != NULL)
1657
+ (void) free((char *) nlist);
1658
+ }
1659
+
1660
+ /*
1661
+ * send_points:
1662
+ * Send points back to caller
1663
+ */
1664
+ static
1665
+ void
1666
+ send_points(POINT *plist, int np, AINDEX aindex, double area, int type, POINT *nlist)
1667
+ {
1668
+ if (np <= 0)
1669
+ return;
1670
+ printf(SURFACE_RESPONSE, aindex, np, type, area, want_normal);
1671
+ #ifdef LOG
1672
+ fprintf(stderr, SURFACE_RESPONSE, aindex, np, type, area,
1673
+ want_normal);
1674
+ #endif
1675
+ (void) fwrite((char *) plist, sizeof (POINT), np, stdout);
1676
+ if (want_normal)
1677
+ (void) fwrite((char *) nlist, sizeof (POINT), np, stdout);
1678
+ }
1679
+
1680
+ /*
1681
+ * psurface:
1682
+ * Generate surface associated with a probe
1683
+ */
1684
+ static
1685
+ void
1686
+ psurface(int n)
1687
+ {
1688
+ register int i, j, k;
1689
+ register POINT *pp;
1690
+ register PROBE *prp;
1691
+ register SATOM *sap;
1692
+ register SPHERE *sp;
1693
+ int which;
1694
+ double minr, r, delta;
1695
+ POINT *point, *plist[3], *normal, *nlist[3];
1696
+ short *keep, np[3];
1697
+
1698
+ /*
1699
+ * Initialize local variables and allocate space
1700
+ */
1701
+ prp = &probe[n];
1702
+ sp = get_sphere(radius);
1703
+ for (i = 0; i < 3; i++) {
1704
+ np[i] = 0;
1705
+ plist[i] = (POINT *) emalloc(sp->npoint * sizeof (POINT));
1706
+ }
1707
+ point = (POINT *) emalloc(sp->npoint * sizeof (POINT));
1708
+ keep = (short *) emalloc(sp->npoint * sizeof (short));
1709
+ for (i = 0; i < sp->npoint; i++) {
1710
+ keep[i] = TRUE;
1711
+ pp = &point[i];
1712
+ for (j = 0; j < 3; j++)
1713
+ pp->coord[j] = sp->point[i].coord[j] + prp->coord[j];
1714
+ }
1715
+ if (want_normal) {
1716
+ normal = (POINT *) emalloc(sp->npoint * sizeof (POINT));
1717
+ for (i = 0; i < sp->npoint; i++) {
1718
+ pp = &normal[i];
1719
+ for (j = 0; j < 3; j++)
1720
+ pp->coord[j] = -sp->point[i].coord[j] / radius;
1721
+ }
1722
+ for (i = 0; i < 3; i++)
1723
+ nlist[i] = (POINT *) emalloc(sp->npoint *
1724
+ sizeof (POINT));
1725
+ }
1726
+ else {
1727
+ normal = NULL;
1728
+ nlist[0] = nlist[1] = nlist[2] = NULL;
1729
+ }
1730
+
1731
+ /*
1732
+ * Now we eliminate those points which do not fall within the
1733
+ * spherical triangle formed by the three specified atoms.
1734
+ * The way we do this is by defining a plane for each pair of
1735
+ * atoms and the probe center. The plane divides space into two
1736
+ * half-spaces, one of which contains the third atom not used in
1737
+ * defining the plane. If a point does not fall in the same
1738
+ * half-space as the third atom, then it is eliminated. Only
1739
+ * the wanted points will remain after all three planes have been
1740
+ * used.
1741
+ */
1742
+ for (i = 0; i < 3; i++)
1743
+ for (j = i + 1; j < 3; j++)
1744
+ check_point(prp, i, j, 3 - i - j,
1745
+ sp->npoint, point, keep);
1746
+
1747
+ /*
1748
+ * Now we divide the points up among the three atoms.
1749
+ */
1750
+ for (i = 0; i < sp->npoint; i++) {
1751
+ if (!keep[i])
1752
+ continue;
1753
+ pp = &point[i];
1754
+ which = -1;
1755
+ #ifdef lint
1756
+ minr = 0;
1757
+ #endif
1758
+ for (j = 0; j < 3; j++) {
1759
+ sap = &atom[prp->atom[j]];
1760
+ r = 0;
1761
+ for (k = 0; k < 3; k++) {
1762
+ delta = pp->coord[k] - sap->atom.coord[k];
1763
+ r += delta * delta;
1764
+ }
1765
+ if (which == -1 || r < minr) {
1766
+ minr = r;
1767
+ which = j;
1768
+ }
1769
+ }
1770
+ if (want_normal)
1771
+ nlist[which][np[which]] = normal[i];
1772
+ plist[which][np[which]++] = *pp;
1773
+ }
1774
+
1775
+ /*
1776
+ * Send the points back to caller and clean up
1777
+ */
1778
+ for (i = 0; i < 3; i++) {
1779
+ send_points(plist[i], np[i], prp->atom[i], sp->area,
1780
+ SREENTRANT, nlist[i]);
1781
+ (void) free((char *) plist[i]);
1782
+ if (want_normal)
1783
+ (void) free((char *) nlist[i]);
1784
+ }
1785
+ fputs(SURFACE_END, stdout);
1786
+ #ifdef LOG
1787
+ fputs(SURFACE_END, stderr);
1788
+ #endif
1789
+ (void) free((char *) point);
1790
+ (void) free((char *) keep);
1791
+ if (want_normal)
1792
+ (void) free((char *) normal);
1793
+ }
1794
+
1795
+ /*
1796
+ * check_point:
1797
+ * Determine which of the given points should be kept
1798
+ */
1799
+ static
1800
+ void
1801
+ check_point(PROBE *prp, int at, int up, int side, int npoint, POINT point[], short keep[])
1802
+ {
1803
+ register int i, sign;
1804
+ double mat[4][4], invmat[4][4];
1805
+ double x;
1806
+ double *dp;
1807
+ double *fp;
1808
+
1809
+ /*
1810
+ * Construct a matrix which transforms the probe center to
1811
+ * the origin, the at atom to the z-axis, and the up atom
1812
+ * into the y-z plane. Then transform the side atom to determine
1813
+ * the sign of the x-component of the half-space to keep.
1814
+ */
1815
+ viewat(mat, invmat, prp->coord, atom[prp->atom[at]].atom.coord,
1816
+ atom[prp->atom[up]].atom.coord);
1817
+ dp = atom[prp->atom[side]].atom.coord;
1818
+ x = dp[0] * mat[0][0] + dp[1] * mat[1][0] + dp[2] * mat[2][0]
1819
+ + mat[3][0];
1820
+ sign = (x < 0) ? -1 : 1;
1821
+
1822
+ /*
1823
+ * Now we loop through the points and check each one
1824
+ */
1825
+ for (i = 0; i < npoint; i++) {
1826
+ if (!keep[i])
1827
+ continue;
1828
+ fp = point[i].coord;
1829
+ x = fp[0] * mat[0][0] + fp[1] * mat[1][0] + fp[2] * mat[2][0]
1830
+ + mat[3][0];
1831
+ if ((sign < 0 && x > 0) || (sign > 0 && x < 0))
1832
+ keep[i] = FALSE;
1833
+ }
1834
+ }
dms/dmsd/test.pdb ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ USER PDBRUN 6
2
+ USER EYEPOS 25.740 21.520 200.737
3
+ USER ATPOS 25.740 21.520 10.132
4
+ USER WINDOW -29.271 29.271 -39.849 39.849 162.687 221.229
5
+ USER FOCUS 190.606
6
+ USER VIEWPORT 0.000 523.000 0.000 712.000
7
+ USER BGCOLOR 0.000 0.000 0.000
8
+ USER FILE 0 1gcn
9
+ USER COLOR 1.000 1.000 1.000 0
10
+ USER RADIUS 1.400
11
+ ATOM 2 OX1 CYX 1 2.114 20.456 22.080 1.00 16.00
12
+ USER RADIUS 1.800
13
+ ATOM 1 CX2 CYX 1 1.819 20.541 22.411 1.00 25.00
14
+ END
dms/dmsd/viewat.c ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <math.h>
35
+
36
+ static void nmcrosprod();
37
+
38
+ void viewat(M, invM, P1, P2, P3)
39
+ double M[4][4], invM[4][4];
40
+ double P1[3], P2[3], P3[3];
41
+ {
42
+ double d12;
43
+ double P12X, P12Y, P12Z, P13X, P13Y, P13Z;
44
+ double lm[3][3];
45
+ register int i, j;
46
+
47
+ P12X = P2[0] - P1[0];
48
+ P12Y = P2[1] - P1[1];
49
+ P12Z = P2[2] - P1[2];
50
+ P13X = P3[0] - P1[0];
51
+ P13Y = P3[1] - P1[1];
52
+ P13Z = P3[2] - P1[2];
53
+
54
+ d12 = sqrt((P12X)*(P12X) + (P12Y)*(P12Y) + (P12Z)*(P12Z));
55
+ lm[0][2] = (P12X) / d12;
56
+ lm[1][2] = (P12Y) / d12;
57
+ lm[2][2] = (P12Z) / d12;
58
+ nmcrosprod(P13X, P13Y, P13Z, P12X, P12Y, P12Z,
59
+ &lm[0][0], &lm[1][0], &lm[2][0]);
60
+ nmcrosprod(lm[0][2], lm[1][2], lm[2][2],
61
+ lm[0][0], lm[1][0], lm[2][0],
62
+ &lm[0][1], &lm[1][1], &lm[2][1]);
63
+
64
+ for (i = 0; i < 3; i++) {
65
+ invM[3][i] = P1[i];
66
+ M[i][3] = invM[i][3] = 0;
67
+ for (j = 0; j < 3; j++) {
68
+ M[i][j] = lm[i][j];
69
+ invM[j][i] = M[i][j];
70
+ }
71
+ }
72
+ M[3][0] = -P1[0]*M[0][0] - P1[1]*M[1][0] - P1[2]*M[2][0];
73
+ M[3][1] = -P1[0]*M[0][1] - P1[1]*M[1][1] - P1[2]*M[2][1];
74
+ M[3][2] = -P1[0]*M[0][2] - P1[1]*M[1][2] - P1[2]*M[2][2];
75
+ M[3][3] = invM[3][3] = 1;
76
+ }
77
+
78
+ static
79
+ void
80
+ nmcrosprod(x1, y1, z1, x2, y2, z2, x3, y3, z3)
81
+ double x1, y1, z1, x2, y2, z2; /* r1 cross r2 */
82
+ double *x3, *y3, *z3; /* Normalized crossproduct */
83
+ {
84
+ double dis; /* length of crossproduct vector r1 x r2 */
85
+ double x,y,z;
86
+
87
+ x = y1*z2 - y2*z1;
88
+ y = z1*x2 - z2*x1;
89
+ z = x1*y2 - x2*y1;
90
+
91
+ dis = sqrt((x*x) + (y*y) + (z*z));
92
+
93
+ *x3 = x / dis;
94
+ *y3 = y / dis;
95
+ *z3 = z / dis;
96
+ }
dms/emalloc.c ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <stdlib.h>
35
+
36
+ /*
37
+ * emalloc:
38
+ * Same as malloc but exits when failure occurs
39
+ */
40
+ char *
41
+ emalloc(size)
42
+ unsigned size;
43
+ {
44
+ register char *cp;
45
+
46
+ if ((cp = malloc(size)) == NULL) {
47
+ fprintf(stderr, "emalloc(%u) failed\n", size);
48
+ exit(1);
49
+ }
50
+ return cp;
51
+ }
52
+
53
+ /*
54
+ * erealloc:
55
+ * Same as realloc but exits when failure occurs
56
+ */
57
+ char *
58
+ erealloc(ptr, size)
59
+ char *ptr;
60
+ unsigned size;
61
+ {
62
+ register char *cp;
63
+
64
+ if ((cp = realloc(ptr, size)) == NULL) {
65
+ fprintf(stderr, "erealloc(ptr, %u) failed\n", size);
66
+ exit(1);
67
+ }
68
+ return cp;
69
+ }
70
+
71
+ /*
72
+ * ecalloc:
73
+ * Same as calloc but exits when failure occurs
74
+ */
75
+ char *
76
+ ecalloc(nelem, elsize)
77
+ unsigned nelem, elsize;
78
+ {
79
+ register char *cp;
80
+
81
+ if ((cp = calloc(nelem, elsize)) == NULL) {
82
+ fprintf(stderr, "calloc(%u, %u) failed\n", nelem, elsize);
83
+ exit(1);
84
+ }
85
+ return cp;
86
+ }
dms/fwritev.c ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <sys/types.h>
35
+ #include <sys/uio.h>
36
+
37
+ /*
38
+ * fwritev:
39
+ * Like writev system call except we use stdio library
40
+ */
41
+ void fwritev(fp, iov, n)
42
+ FILE *fp;
43
+ struct iovec *iov;
44
+ int n;
45
+ {
46
+ register struct iovec *ip, *endip;
47
+
48
+ endip = iov + n;
49
+ for (ip = iov; ip < endip; ip++)
50
+ (void) fwrite((char *) ip->iov_base, sizeof (char),
51
+ ip->iov_len, fp);
52
+ }
dms/input.c ADDED
@@ -0,0 +1,324 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <ctype.h>
35
+ #include <math.h>
36
+ #include <strings.h>
37
+ #include <pdb.h>
38
+ #include "dms_param.h"
39
+ #include "atoms.h"
40
+ #include "wanted.h"
41
+
42
+ #ifndef DEBUG
43
+ #define STATIC static
44
+ #else
45
+ #define STATIC
46
+ #endif
47
+
48
+ #ifndef TRUE
49
+ #define TRUE 1
50
+ #define FALSE 0
51
+ #endif
52
+
53
+ STATIC int is_aa();
54
+ void scopy(char*, char*, int);
55
+ char (*resseqs)[RN_LEN];
56
+ int numresseq;
57
+
58
+ /*
59
+ * read_pdb:
60
+ * Read the given pdb file and put all the atoms into a list.
61
+ */
62
+ ATOM *
63
+ read_pdb(file, all)
64
+ char *file;
65
+ int all;
66
+ {
67
+ register ATOM *cp;
68
+ FILE *fp;
69
+ ATOM *alist, *ap;
70
+ pdb_record r;
71
+ struct pdb_atom *atp;
72
+ pdb_residue *resp;
73
+ extern char *emalloc();
74
+ char prevresseq[RN_LEN];
75
+ int index;
76
+
77
+ if ((fp = fopen(file, "r")) == NULL) {
78
+ perror(file);
79
+ return NULL;
80
+ }
81
+ alist = NULL;
82
+ prevresseq[0] = '\0';
83
+ numresseq = 0;
84
+ do {
85
+ r = pdb_read_record(fp);
86
+ switch(r.record_type) {
87
+ case PDB_END:
88
+ case PDB_UNKNOWN:
89
+ case PDB_TER:
90
+ break;
91
+ case PDB_HETATM:
92
+ if (!all)
93
+ break;
94
+ /* FALLTHROUGH */
95
+ case PDB_ATOM:
96
+ atp = &r.pdb.atom;
97
+ resp = &atp->residue;
98
+ if (!all && !is_aa(resp->name))
99
+ break;
100
+ cp = (ATOM *) emalloc(sizeof (ATOM));
101
+ cp->coord[0] = r.pdb.atom.x;
102
+ cp->coord[1] = r.pdb.atom.y;
103
+ cp->coord[2] = r.pdb.atom.z;
104
+ scopy(cp->atname, atp->name, sizeof (atp->name));
105
+ scopy(cp->restype, resp->name, sizeof (resp->name));
106
+ /*
107
+ * The residue sequence is composed of the
108
+ * sequence number concatenated with the insertion
109
+ * code and chain identifier (if they exist)
110
+ */
111
+ (void) sprintf(cp->resseq, "%d", resp->seq_num);
112
+ if (isalnum(resp->insert_code))
113
+ (void) strncat(cp->resseq,
114
+ &resp->insert_code, 1);
115
+ if (isalnum(resp->chain_id))
116
+ (void) strncat(cp->resseq,
117
+ &resp->chain_id, 1);
118
+ if (r.record_type == PDB_HETATM)
119
+ (void) strncat(cp->resseq, "*", 1);
120
+ if (strcmp(cp->resseq, prevresseq) != 0) {
121
+ strcpy(prevresseq, cp->resseq);
122
+ numresseq++;
123
+ }
124
+ cp->resindex = numresseq-1;
125
+ cp->next = NULL;
126
+ if (alist == NULL)
127
+ alist = cp;
128
+ else
129
+ ap->next = cp;
130
+ ap = cp;
131
+ break;
132
+ default:
133
+ break;
134
+ }
135
+ } while (r.record_type != PDB_END);
136
+ (void) fclose(fp);
137
+ if (alist == NULL)
138
+ return alist;
139
+ resseqs = (char (*)[RN_LEN]) emalloc(numresseq * RN_LEN);
140
+ strcpy(resseqs[0], alist->resseq);
141
+ index = 0;
142
+ for (ap = alist->next; ap != NULL; ap = ap->next) {
143
+ if (strcmp(ap->resseq, resseqs[index]) != 0) {
144
+ index++;
145
+ strcpy(resseqs[index], ap->resseq);
146
+ }
147
+ }
148
+ if (index+1 != numresseq) {
149
+ fprintf(stderr,
150
+ "Internal error: residue ID numbering mismatch.\n");
151
+ exit(1);
152
+ }
153
+ return alist;
154
+ }
155
+
156
+ /*
157
+ * scopy:
158
+ * Copy strings without copying blanks
159
+ */
160
+ void scopy(to, from, max)
161
+ register char *to, *from;
162
+ register int max;
163
+ {
164
+ while (max-- > 0 && *from != '\0')
165
+ if (!isspace(*from))
166
+ *to++ = *from++;
167
+ else
168
+ from++;
169
+ *to = '\0';
170
+ }
171
+
172
+ /*
173
+ * read_kraut:
174
+ * Read the given kraut format file into an atom list
175
+ */
176
+ /* ARGSUSED */
177
+ ATOM *
178
+ read_kraut(file, all)
179
+ char *file;
180
+ int all;
181
+ {
182
+ /*
183
+ * Not implemented yet (maybe never). Just fake as if
184
+ * we had not seen any atoms.
185
+ */
186
+ fputs("-k is unimplemented\n", stderr);
187
+ return NULL;
188
+ }
189
+
190
+ /*
191
+ * read_midas:
192
+ * Read the given midas format file into an atom list
193
+ */
194
+ /* ARGSUSED */
195
+ ATOM *
196
+ read_midas(file, all)
197
+ char *file;
198
+ int all;
199
+ {
200
+ /*
201
+ * Not implemented yet (maybe never). Just fake as if
202
+ * we had not seen any atoms.
203
+ */
204
+ fputs("-m is unimplemented\n", stderr);
205
+ return NULL;
206
+ }
207
+
208
+ static char *aa[] = {
209
+ " A", " C", " G", " T", " U",
210
+ "ALA", "ARG", "ASN", "ASP", "CPR", "CYS", "CYX", "CYZ", "GLN",
211
+ "GLU", "GLY", "HIS", "ILE", "LEU", "LYS", "MET", "PHE", "PRO",
212
+ "SER", "THR", "TRP", "TYR", "VAL",
213
+ (char *) NULL
214
+ };
215
+
216
+ /*
217
+ * is_aa:
218
+ * Decide whether the given residue type is an amino acid
219
+ * or nucleic acid.
220
+ */
221
+ STATIC
222
+ int
223
+ is_aa(type)
224
+ char *type;
225
+ {
226
+ register int n;
227
+ register char **aap;
228
+
229
+ for (aap = aa; *aap != NULL; aap++) {
230
+ n = strcmp(type, *aap);
231
+ if (n == 0)
232
+ return TRUE;
233
+ else if (n < 0)
234
+ break;
235
+ }
236
+ return FALSE;
237
+ }
238
+
239
+ /*
240
+ * read_wanted:
241
+ * Read the "wanted list" of atoms from the given file
242
+ */
243
+ WANTED *
244
+ read_wanted(fp)
245
+ FILE *fp;
246
+ {
247
+ register WANTED *cp, *wp;
248
+ char buf[BUFSIZ], atname[AN_LEN];
249
+ char orig[BUFSIZ], orig2[BUFSIZ], *fields[4];
250
+ int numfields;
251
+ extern char *emalloc();
252
+ static char *errmsg = "Residues with chain IDs and/or insertion codes should have those appended\n\twith no spaces, e.g. residue 55 of chain E with insertion code A\n\twould be identified as 55AE.\n";
253
+ static char *errmsg2 = "Could not find residue '%s' in PDB file.\nThe residue was mentioned in site file line:\n%s\n";
254
+
255
+ if (fp == NULL)
256
+ return NULL;
257
+
258
+ wp = NULL;
259
+ while (fgets(buf, sizeof buf, fp) != NULL) {
260
+ strcpy(orig, buf);
261
+ if ((numfields = tokenize(buf, fields, 4)) != 3) {
262
+ if (numfields == 0)
263
+ /* don't penalize blank lines */
264
+ continue;
265
+ fputs("Illegal line in -i file:\n", stderr);
266
+ fputs(orig, stderr);
267
+ if (numfields > 3) {
268
+ fputs(errmsg, stderr);
269
+ }
270
+ exit(1);
271
+ }
272
+ strcpy(atname, fields[2]);
273
+ cp = (WANTED *) emalloc(sizeof (WANTED));
274
+ cp->startres = locres(fields[1]);
275
+ if (cp->startres < 0) {
276
+ /* no such residue */
277
+ fprintf(stderr, errmsg2, fields[1], orig);
278
+ exit(1);
279
+ }
280
+ if (strcmp(atname, "*") == 0) {
281
+ cp->type = W_ANY;
282
+ }
283
+ else if (strcmp(atname, "FRM") == 0) {
284
+ cp->type = W_RANGE;
285
+ if (fgets(buf, sizeof buf, fp) == NULL) {
286
+ fputs("Unexpected EOF in -i file\n", stderr);
287
+ (void) free((char *) cp);
288
+ break;
289
+ }
290
+ strcpy(orig2, buf);
291
+ numfields = tokenize(buf, fields, 4);
292
+ if (numfields == 0
293
+ || strcmp(fields[numfields-1], "TO") != 0) {
294
+ fputs("No TO after FRM in -i file\n", stderr);
295
+ fprintf(stderr, "FRM line was: %s\n", orig);
296
+ (void) free((char *) cp);
297
+ exit(1);
298
+ }
299
+ if (numfields > 3) {
300
+ fputs(errmsg, stderr);
301
+ exit(1);
302
+ }
303
+ cp->w.endres = locres(fields[1]);
304
+ if (cp->w.endres < 0) {
305
+ fprintf(stderr, errmsg2, fields[1], orig2);
306
+ exit(1);
307
+ }
308
+ if (cp->w.endres < cp->startres) {
309
+ fprintf(stderr,
310
+ "End of FRM/TO range before begining!\n");
311
+ fprintf(stderr, "FRM/TO lines were:%s%s\n",
312
+ orig, orig2);
313
+ exit(1);
314
+ }
315
+ }
316
+ else {
317
+ cp->type = W_ATOM;
318
+ (void) strcpy(cp->w.atom, atname);
319
+ }
320
+ cp->next = wp;
321
+ wp = cp;
322
+ }
323
+ return wp;
324
+ }
dms/libpdb/GNUmakefile ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ SHELL = /bin/sh
2
+ ifeq ($(shell test -e /usr/bin/ranlib && echo found),found)
3
+ RANLIB = ranlib
4
+ else
5
+ RANLIB = :
6
+ endif
7
+
8
+ OPT = -g
9
+ DEBUG =
10
+ CFLAGS = $(OPT) $(DEBUG)
11
+ LIBRARY = pdb
12
+
13
+ LIBDIR = /usr/local/lib
14
+ LIBARCH = lib$(LIBRARY).a
15
+ OBJS = pdb_read.o pdb_sprntf.o pdb_sscanf.o pdb_write.o pdbrun.o ms.o
16
+ SRCS = pdb_read.c pdb_sprntf.c pdb_sscanf.c pdb_write.c pdbrun.c ms.c
17
+
18
+ all: $(LIBARCH)
19
+
20
+ $(LIBARCH): $(OBJS)
21
+ ar cru $(LIBARCH) $(OBJS)
22
+ $(RANLIB) $(LIBARCH)
23
+
24
+ install: $(LIBARCH)
25
+ cp $(LIBARCH) $(LIBDIR)
26
+ $(RANLIB) $(LIBDIR)/$(LIBARCH)
27
+
28
+ clean:
29
+ rm -f $(OBJS)
30
+
31
+ spotless:
32
+ rm -f $(OBJS) $(LIBARCH)
33
+
34
+ tags: $(HDRS) $(SRCS); @ctags -w $(HDRS) $(SRCS)
dms/libpdb/ms.3 ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .\" Copyright (c) 1984,1989 by the Regents of the University of California.
2
+ .\" All Rights Reserved.
3
+ .\" $Id: ms.3,v 1.1 94/11/02 13:10:21 gregc Exp $
4
+ .TH MS 3 "14 Sept 1989"
5
+ .SH NAME
6
+ ms_read_record, ms_parse, ms_write_record \- read and write Molecular Surface (ms) records
7
+ .SH SYNOPSIS
8
+ .nf
9
+ .B #include <ms.h>
10
+ .PP
11
+ .B ms_record ms_read_record(f)
12
+ .B FILE *f;
13
+ .PP
14
+ .B ms_record ms_parse(line_buffer)
15
+ .B char *line_buffer;
16
+ .PP
17
+ .B void ms_write_record(f, m)
18
+ .B FILE *f;
19
+ .B ms_record *m;
20
+ .fi
21
+ .SH DESCRIPTION
22
+ The routines listed above
23
+ are subroutines for Molecular Surface record I/O
24
+ and are available in the pdb library, typically
25
+ .IR "-L/usr/local/lib/midas -lpdb" .
26
+ .PP
27
+ Although the header file is too long to reproduce here, it should be
28
+ perused before using any of the above routines.
29
+ It is typically found in
30
+ .IR /usr/local/midas/include .
31
+ .PP
32
+ \fBms_read_record\fP reads the next line of input from the file \fBf\fP,
33
+ and returns the contents parsed into a C structure.
34
+ \fBms_parse\fP parses the contents of the line buffer
35
+ and returns a C structure.
36
+ \fBms_write_record\fP writes the contents of the MS record (\fB*m\fP) to
37
+ the file \fBf\fP.
38
+ .SH "SEE ALSO"
39
+ dms(1)
40
+ .SH DIAGNOSTICS
41
+ Upon reaching the end of the file, \fBms_read_record\fP will return
42
+ a record with MS_END as its type.
43
+ .SH COPYRIGHT
44
+ Copyright \(co 1992 The Regents of the University of California.
45
+ All rights reserved.
46
+ .PP
47
+ Redistribution and use in source and binary forms are permitted
48
+ provided that the above copyright notice and this paragraph are
49
+ duplicated in all such forms and that any documentation,
50
+ advertising materials, and other materials related to such
51
+ distribution and use acknowledge that the software was developed
52
+ by the University of California, San Francisco. The name of the
53
+ University may not be used to endorse or promote products derived
54
+ from this software without specific prior written permission.
55
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
56
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
57
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
dms/libpdb/ms.c ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: ms.c,v 2.4 94/05/19 16:01:16 conrad Exp $
18
+ */
19
+
20
+ #include <stdio.h>
21
+ #include <ctype.h>
22
+ #include <string.h>
23
+ #include <math.h>
24
+ #include "pdb_int.h"
25
+ #include "ms.h"
26
+
27
+ #ifndef TRUE
28
+ #define TRUE 1
29
+ #define FALSE 0
30
+ #endif
31
+
32
+ /*
33
+ * ms_read_record:
34
+ * Read an ms record from a file and return the corresponding
35
+ * data structure
36
+ */
37
+ ms_record
38
+ #ifdef __STDC__
39
+ ms_read_record(FILE *fp)
40
+ #else
41
+ ms_read_record(fp)
42
+ FILE *fp;
43
+ #endif
44
+ {
45
+ char buf[MS_BUFSIZ];
46
+ char *cp;
47
+ int c;
48
+ ms_record record;
49
+
50
+ /*
51
+ * If at end of file, just set the record type and return
52
+ */
53
+ if (fgets(buf, sizeof buf, fp) == NULL) {
54
+ record.record_type = MS_END;
55
+ return record;
56
+ }
57
+
58
+ cp = strchr(buf, '\n');
59
+ if (cp != NULL)
60
+ *cp = '\0';
61
+ else
62
+ /* discard extra characters since line too long */
63
+ while ((c = getc(fp)) != '\n' && c != EOF)
64
+ continue;
65
+
66
+ return ms_read_string(buf);
67
+ }
68
+
69
+ #ifdef __STDC__
70
+ static void crunch(char *);
71
+ #else
72
+ static void crunch();
73
+ #endif
74
+
75
+ /*
76
+ * ms_read_string
77
+ * Construct the data structure corresponding to the given line
78
+ */
79
+ ms_record
80
+ #ifdef __STDC__
81
+ ms_read_string(const char *buf)
82
+ #else
83
+ ms_read_string(buf)
84
+ char *buf;
85
+ #endif
86
+ {
87
+ int i;
88
+ const char *cp;
89
+ char *sp;
90
+ int nfield;
91
+ double area, extra;
92
+ double coord[3], normal[3];
93
+ ms_record record;
94
+ ms_atom *map;
95
+ ms_surface *msp;
96
+ char type;
97
+ const char *atom_fmt, *surf_fmt;
98
+
99
+ /*
100
+ * If the head of the string is "user" (case-independently),
101
+ * we copy the buffer into the string and return
102
+ */
103
+ if (strncasecmp(buf, "user", 4) == 0) {
104
+ record.record_type = MS_USER;
105
+ for (cp = buf + 4; isspace(*cp); cp++)
106
+ continue;
107
+ sp = record.ms.user.string;
108
+ while (*cp != '\0' && *cp != '\n')
109
+ *sp++ = *cp++;
110
+ *sp = '\0';
111
+ return record;
112
+ }
113
+
114
+ /*
115
+ * This is either an atom line, surface line, or an error
116
+ */
117
+ if (strlen(buf) < 41) {
118
+ record.record_type = MS_UNKNOWN;
119
+ (void) strcpy(record.ms.unknown.string, buf);
120
+ return record;
121
+ }
122
+ type = buf[40];
123
+ atom_fmt = "%3s %4s %4s%8f %8f %8f A";
124
+ surf_fmt = "%3s %4s %4s%8f %8f %8f S%c%c %6f %6f %6f %6f %6f";
125
+ if (isspace(type)) {
126
+ type = buf[41];
127
+ atom_fmt = "%3s %5s %4s%8f %8f %8f A";
128
+ surf_fmt = "%3s %5s %4s%8f %8f %8f S%c%c %6f %6f %6f %6f %6f";
129
+ }
130
+ switch (type) {
131
+ case 'A':
132
+ record.record_type = MS_ATOM;
133
+ map = &record.ms.atom;
134
+ nfield = pdb_sscanf(buf, atom_fmt,
135
+ map->residue_type, map->residue_sequence,
136
+ map->atom_name, &coord[0], &coord[1], &coord[2]);
137
+ if (nfield == 6) {
138
+ for (i = 0; i < 3; i++)
139
+ map->coord[i] = coord[i];
140
+ crunch(map->residue_type);
141
+ crunch(map->residue_sequence);
142
+ crunch(map->atom_name);
143
+ return record;
144
+ }
145
+ break;
146
+ case 'S':
147
+ record.record_type = MS_SURFACE;
148
+ msp = &record.ms.surface;
149
+ nfield = pdb_sscanf(buf, surf_fmt,
150
+ msp->residue_type, msp->residue_sequence,
151
+ msp->atom_name, &coord[0], &coord[1], &coord[2],
152
+ &msp->type, &msp->level, &area,
153
+ &normal[0], &normal[1], &normal[2], &extra);
154
+ switch (nfield) {
155
+ case 9:
156
+ normal[0] = 0;
157
+ /* FALLTHROUGH */
158
+ case 10:
159
+ msp->has_normal = FALSE;
160
+ for (i = 0; i < 3; i++)
161
+ msp->coord[i] = coord[i];
162
+ msp->area = area;
163
+ msp->extra = normal[0];
164
+ crunch(msp->residue_type);
165
+ crunch(msp->residue_sequence);
166
+ crunch(msp->atom_name);
167
+ return record;
168
+ case 12:
169
+ extra = 0;
170
+ /* FALLTHROUGH */
171
+ case 13:
172
+ msp->has_normal = TRUE;
173
+ for (i = 0; i < 3; i++) {
174
+ msp->coord[i] = coord[i];
175
+ msp->normal[i] = normal[i];
176
+ }
177
+ msp->area = area;
178
+ msp->extra = extra;
179
+ crunch(msp->residue_type);
180
+ crunch(msp->residue_sequence);
181
+ crunch(msp->atom_name);
182
+ return record;
183
+ }
184
+ break;
185
+ }
186
+
187
+ /*
188
+ * Okay. We must not have recognized the record. Set the
189
+ * record type, copy the string into the string and return
190
+ */
191
+ record.record_type = MS_UNKNOWN;
192
+ (void) strcpy(record.ms.unknown.string, buf);
193
+ return record;
194
+ }
195
+
196
+ /*
197
+ * crunch:
198
+ * Remove blanks from a string
199
+ */
200
+ static
201
+ void
202
+ #ifdef __STDC__
203
+ crunch(char *s)
204
+ #else
205
+ crunch(s)
206
+ char *s;
207
+ #endif
208
+ {
209
+ char *last;
210
+
211
+ for (last = s; *s != '\0'; s++)
212
+ if (!isspace(*s))
213
+ *last++ = *s;
214
+ *last = '\0';
215
+ }
216
+
217
+ /*
218
+ * ms_write_record:
219
+ * Write an ms record to a file from the corresponding
220
+ * data structure
221
+ */
222
+ void
223
+ #ifdef __STDC__
224
+ ms_write_record(FILE *fp, const ms_record *mp)
225
+ #else
226
+ ms_write_record(fp, mp)
227
+ FILE *fp;
228
+ ms_record *mp;
229
+ #endif
230
+ {
231
+ char buffer[MS_RECLEN];
232
+
233
+ ms_write_string(buffer, mp);
234
+ fprintf(fp, "%s\n", buffer);
235
+ }
236
+
237
+ /*
238
+ * ms_write_string:
239
+ * Write an ms record to a string from the corresponding
240
+ * data structure
241
+ */
242
+ void
243
+ #ifdef __STDC__
244
+ ms_write_string(char *buffer, const ms_record *mp)
245
+ #else
246
+ ms_write_string(buffer, mp)
247
+ char *buffer;
248
+ ms_record *mp;
249
+ #endif
250
+ {
251
+ const ms_atom *map;
252
+ const ms_surface *msp;
253
+ char *cp;
254
+
255
+ switch (mp->record_type) {
256
+ case MS_ATOM:
257
+ map = &mp->ms.atom;
258
+ (void) sprintf(buffer, "%-3s %4s %4s %7.3f %7.3f %7.3f A",
259
+ map->residue_type, map->residue_sequence,
260
+ map->atom_name, map->coord[0], map->coord[1],
261
+ map->coord[2]);
262
+ break;
263
+ case MS_SURFACE:
264
+ msp = &mp->ms.surface;
265
+ (void) sprintf(buffer,
266
+ "%-3s %4s %4s %7.3f %7.3f %7.3f S%c%c %6.3f",
267
+ msp->residue_type, msp->residue_sequence,
268
+ msp->atom_name, msp->coord[0], msp->coord[1],
269
+ msp->coord[2], msp->type, msp->level, msp->area);
270
+ cp = strchr(buffer, '\0');
271
+ if (msp->has_normal) {
272
+ (void) sprintf(cp, " %6.3f %6.3f %6.3f",
273
+ msp->normal[0], msp->normal[1], msp->normal[2]);
274
+ cp = strchr(cp, '\0');
275
+ }
276
+ if (msp->extra != 0) {
277
+ if (msp->extra >= 1000 || msp->extra <= -100)
278
+ (void) sprintf(cp, " %6.1f", msp->extra);
279
+ else if (msp->extra >= 100 || msp->extra <= -10)
280
+ (void) sprintf(cp, " %6.2f", msp->extra);
281
+ else
282
+ (void) sprintf(cp, " %6.3f", msp->extra);
283
+ }
284
+ break;
285
+ case MS_USER:
286
+ (void) sprintf(buffer, "USER %s\n", mp->ms.user.string);
287
+ break;
288
+ }
289
+ }
dms/libpdb/ms.h ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: ms.h,v 2.2 94/01/27 12:41:26 gregc Exp $
18
+ */
19
+
20
+ #ifndef MS_H
21
+ #define MS_H
22
+
23
+ #include <stdio.h>
24
+
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
29
+ #define MS_RECLEN 128
30
+ #define MS_BUFSIZ (MS_RECLEN + 2)
31
+
32
+ #define MS_MAX_RESTYPE 8
33
+ #define MS_MAX_RESSEQ 8
34
+ #define MS_MAX_ATNAME 8
35
+
36
+ #define MS_UNKNOWN 0
37
+ #define MS_END 1
38
+ #define MS_ATOM 2
39
+ #define MS_SURFACE 3
40
+ #define MS_USER 4
41
+
42
+ #define MS_NUM_R 5
43
+
44
+ typedef struct ms_atom {
45
+ char residue_type[MS_MAX_RESTYPE];
46
+ char residue_sequence[MS_MAX_RESSEQ];
47
+ char atom_name[MS_MAX_ATNAME];
48
+ float coord[3];
49
+ } ms_atom;
50
+
51
+ typedef struct ms_surf {
52
+ char residue_type[MS_MAX_RESTYPE];
53
+ char residue_sequence[MS_MAX_RESSEQ];
54
+ char atom_name[MS_MAX_ATNAME];
55
+ float coord[3];
56
+ float normal[3];
57
+ float area;
58
+ float extra;
59
+ char has_normal;
60
+ char type;
61
+ char level;
62
+ } ms_surface;
63
+
64
+ typedef struct ms_user {
65
+ char string[MS_BUFSIZ];
66
+ } ms_user;
67
+
68
+ #define ms_unknown ms_user
69
+
70
+ typedef struct ms_record {
71
+ int record_type;
72
+ union {
73
+ ms_unknown unknown;
74
+ ms_atom atom;
75
+ ms_surface surface;
76
+ ms_user user;
77
+ } ms;
78
+ } ms_record;
79
+
80
+ #if defined(__STDC__) || defined(__cplusplus)
81
+ extern ms_record ms_read_record(FILE *);
82
+ extern ms_record ms_read_string(const char *);
83
+ extern void ms_write_record(FILE *, const ms_record *);
84
+ extern void ms_write_string(char *, const ms_record *);
85
+ #else
86
+ extern ms_record ms_read_record();
87
+ extern ms_record ms_read_string();
88
+ extern void ms_write_record();
89
+ extern void ms_write_string();
90
+ #endif
91
+
92
+ #ifdef __cplusplus
93
+ }
94
+ #endif
95
+ #endif
dms/libpdb/pdb.3 ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .\" Copyright (c) 1984,1989 by the Regents of the University of California.
2
+ .\" All Rights Reserved.
3
+ .\" $Id: pdb.3,v 1.16 94/11/06 19:55:29 gregc Exp $
4
+ .TH PDB 3 "14 Sept 1989"
5
+ .SH NAME
6
+ pdb_read_record, pdb_parse, pdb_write_record \- read and write Brookhaven Protein DataBank records
7
+ .SH SYNOPSIS
8
+ .nf
9
+ .B #include <pdb.h>
10
+ .PP
11
+ .B pdb_record pdb_read_record(f)
12
+ .B FILE *f;
13
+ .PP
14
+ .B pdb_record pdb_parse(line_buffer)
15
+ .B char *line_buffer;
16
+ .PP
17
+ .B "void pdb_write_record(f, r, name, line_num)"
18
+ .B FILE *f;
19
+ .B pdb_record *r;
20
+ .B char *name;
21
+ .B int line_num;
22
+ .fi
23
+ .SH DESCRIPTION
24
+ The routines listed above
25
+ are subroutines for Brookhaven Protein Data Bank record I/O
26
+ and are available in the pdb library, typically
27
+ .IR "-L/usr/local/lib/midas -lpdb" .
28
+ .PP
29
+ Although the header file is too long to reproduce here, it should be
30
+ perused before using any of the above routines.
31
+ It is typically found in
32
+ .IR /usr/local/midas/include .
33
+ \fBpdb_read_record\fP reads the next line of input from the file \fBf\fP,
34
+ and returns the contents parsed into a C structure.
35
+ \fBpdb_parse\fP parses the contents of the line buffer
36
+ and returns a C structure.
37
+ \fBpdb_write_record\fP writes the contents of the PDB record (\fB*r\fP) to
38
+ the file \fBf\fP. If the \fBname\fP is non-null, then it and the line
39
+ number given (\fBline_num\fP) are placed in columns 72 through 80 on the
40
+ line in standard PDB format.
41
+ .PP
42
+ \fBpdb_read_record\fP and \fBpdb_write_record\fP automatically
43
+ handle versions 5 and 6 of the UCSFCGL's PDB scene annotation records.
44
+ The version number is automatically changed when a USER PDBRUN record is read
45
+ or written.
46
+ Any other version number turns off the parsing of scene annotation records.
47
+ .SH "SEE ALSO"
48
+ ``Protein Data Bank Atomic Coordinate and Bibliographic Entry Format Description,'' Febuary 1992,
49
+ Brookhaven National Laboratory
50
+ (URL: ftp://ftp.pdb.bnl.gov/pub/format_desc.ps),
51
+ the January 1993 Protein Data Bank Quarterly Newsletter,
52
+ and Couch, \fIet. al\fP, ``Annotating PDB Files with Scene Information'',
53
+ (in press)
54
+ (URL: http://cgl.ucsf.edu/????).
55
+ .SH DIAGNOSTICS
56
+ Upon reaching the end of the file, \fBpdb_read_record\fP will return
57
+ a record with PDB_END as its type.
58
+ .SH NOTES
59
+ The subtype field of USERxx structure tells what the \fIxx\fP part was.
60
+ The rest of the line, up to the card sequence portion, is the text field.
61
+ .PP
62
+ Due to the way Brookhaven encodes their files,
63
+ atom names usually have leading blanks and sometimes have embedded blanks.
64
+ Residue names occasionally have leading blanks too.
65
+ To be entirely consistent with the PDB format, the programmer should put those
66
+ blanks in before using \fBpdb_write_record\fP.
67
+ .SH BUGS
68
+ Doesn't allow exact duplication of the PDB card image sorting field
69
+ (columns 73 through 80).
70
+ .PP
71
+ Routines are needed to convert to and from PDB typesetting conventions
72
+ in COMPND, SOURCE, AUTHOR, and JRNL records.
73
+ .SH COPYRIGHT
74
+ Copyright \(co 1989 The Regents of the University of California.
75
+ All rights reserved.
76
+ .PP
77
+ Redistribution and use in source and binary forms are permitted
78
+ provided that the above copyright notice and this paragraph are
79
+ duplicated in all such forms and that any documentation,
80
+ advertising materials, and other materials related to such
81
+ distribution and use acknowledge that the software was developed
82
+ by the University of California, San Francisco. The name of the
83
+ University may not be used to endorse or promote products derived
84
+ from this software without specific prior written permission.
85
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
86
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
87
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
dms/libpdb/pdb.h ADDED
@@ -0,0 +1,530 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdb.h,v 2.11 1995/01/20 01:20:36 gregc Exp $
18
+ *
19
+ * Based on Brookhaven National Laboratory Protein Data Bank, March 1989
20
+ *
21
+ * C structure declarations
22
+ */
23
+
24
+ #ifndef PDB_H
25
+ # define PDB_H
26
+
27
+ # include <stdio.h>
28
+
29
+ # ifdef __cplusplus
30
+ extern "C" {
31
+ # endif
32
+
33
+ # define PDB_RECLEN 80 /* PDB record length */
34
+ # define PDB_BUFSIZ PDB_RECLEN + 2 /* + '\n' + '\0' */
35
+
36
+ # define PDB_PDBRUN_VERSION 6
37
+
38
+ # define PDB_UNKNOWN 0
39
+
40
+ /* records originally in alphabetical order */
41
+
42
+ # define PDB_ANISOU 1
43
+ # define PDB_ATOM 2
44
+ # define PDB_AUTHOR 3
45
+ # define PDB_COMPND 4
46
+ # define PDB_CONECT 5
47
+ # define PDB_CRYST1 6
48
+ # define PDB_END 7
49
+ # define PDB_FORMUL 8
50
+ # define PDB_FTNOTE 9
51
+ # define PDB_HEADER 10
52
+ # define PDB_HELIX 11
53
+ # define PDB_HET 12
54
+ # define PDB_HETATM 13
55
+ # define PDB_JRNL 14
56
+ # define PDB_MASTER 15
57
+ # define PDB_MTRIX 16
58
+ # define PDB_OBSLTE 17
59
+ # define PDB_ORIGX 18
60
+ # define PDB_REMARK 19
61
+ # define PDB_REVDAT 20
62
+ # define PDB_SCALE 21
63
+ # define PDB_SEQRES 22
64
+ # define PDB_SHEET 23
65
+ # define PDB_SIGATM 24
66
+ # define PDB_SIGUIJ 25
67
+ # define PDB_SITE 26
68
+ # define PDB_SOURCE 27
69
+ # define PDB_SPRSDE 28
70
+ # define PDB_SSBOND 29
71
+ # define PDB_TER 30
72
+ # define PDB_TURN 31
73
+ # define PDB_TVECT 32
74
+ # define PDB_USER 33
75
+ # define PDB_MODEL 34
76
+ # define PDB_ENDMDL 35
77
+ # define PDB_EXPDTA 36
78
+ # define PDB_SYMDES 37
79
+ # define PDB_SYMOP 38
80
+ # define PDB_MTXDES 39
81
+ # define PDB_CMPDES 40
82
+ # define PDB_CMPONT 41
83
+ # define PDB_TRNSFM 42
84
+ # define PDB_AGRDES 43
85
+ # define PDB_AGGRGT 44
86
+
87
+ # define PDB_NUM_R 45
88
+
89
+ # define PDB_USER_PDBRUN 0x100
90
+ # define PDB_USER_EYEPOS 0x101
91
+ # define PDB_USER_ATPOS 0x102
92
+ # define PDB_USER_WINDOW 0x103
93
+ # define PDB_USER_FOCUS 0x104
94
+ # define PDB_USER_VIEWPORT 0x105
95
+ # define PDB_USER_BGCOLOR 0x106
96
+ # define PDB_USER_ANGLE 0x107
97
+ # define PDB_USER_DISTANCE 0x108
98
+ # define PDB_USER_FILE 0x109
99
+ # define PDB_USER_MARKNAME 0x10a
100
+ # define PDB_USER_MARK 0x10b
101
+ # define PDB_USER_CNAME 0x10c
102
+ # define PDB_USER_COLOR 0x10d
103
+ # define PDB_USER_RADIUS 0x10e
104
+ # define PDB_USER_OBJECT 0x10f
105
+ # define PDB_USER_ENDOBJ 0x110
106
+ # define PDB_USER_CHAIN 0x111
107
+ # define PDB_USER_GFX_BEGIN 0x112
108
+ # define PDB_USER_GFX_END 0x113
109
+ # define PDB_USER_GFX_COLOR 0x114
110
+ # define PDB_USER_GFX_NORMAL 0x115
111
+ # define PDB_USER_GFX_VERTEX 0x116
112
+ # define PDB_USER_GFX_FONT 0x117
113
+ # define PDB_USER_GFX_TEXTPOS 0x118
114
+ # define PDB_USER_GFX_LABEL 0x119
115
+ # define PDB_USER_GFX_MOVE 0x11a /* obsolete */
116
+ # define PDB_USER_GFX_DRAW 0x11b /* obsolete */
117
+ # define PDB_USER_GFX_MARKER 0x11c /* obsolete */
118
+ # define PDB_USER_GFX_POINT 0x11d /* obsolete */
119
+
120
+ # define PDB_NUM_USER_R (PDB_USER_GFX_POINT-PDB_USER_PDBRUN+1)
121
+
122
+ # define PDB_GFX_UNKNOWN 0x0
123
+ # define PDB_GFX_POINTS 0x1
124
+ # define PDB_GFX_MARKERS 0x2
125
+ # define PDB_GFX_LINES 0x3
126
+ # define PDB_GFX_LINE_STRIP 0x4
127
+ # define PDB_GFX_LINE_LOOP 0x5
128
+ # define PDB_GFX_TRIANGLES 0x6
129
+ # define PDB_GFX_TRIANGLE_STRIP 0x7
130
+ # define PDB_GFX_TRIANGLE_FAN 0x8
131
+ # define PDB_GFX_QUADS 0x9
132
+ # define PDB_GFX_QUAD_STRIP 0xa
133
+ # define PDB_GFX_POLYGON 0xb
134
+
135
+ typedef char pdb_date[10];
136
+ typedef char pdb_aname[5]; /* atom name - NO2* */
137
+ typedef char pdb_rname[5]; /* residue name - ALA */
138
+ typedef char pdb_pname[5]; /* pdb name - 9lyz */
139
+ typedef char pdb_id[4]; /* generic short id field */
140
+ typedef double pdb_float; /* size of floating point */
141
+
142
+ typedef struct { /* residue info */
143
+ pdb_rname name;
144
+ char chain_id;
145
+ int seq_num;
146
+ char insert_code;
147
+ } pdb_residue;
148
+
149
+ /*
150
+ * structures declarations for each record type
151
+ */
152
+
153
+ struct pdb_unknown {
154
+ char junk[81];
155
+ };
156
+ struct pdb_aggrgt {
157
+ int serial_num;
158
+ int num_components;
159
+ int cmpont_serial_nums[14];
160
+ };
161
+ # define pdb_agrdes pdb_ftnote
162
+ struct pdb_anisou {
163
+ int serial_num;
164
+ pdb_aname name;
165
+ char alt_loc;
166
+ pdb_residue residue;
167
+ int u[6];
168
+ };
169
+ struct pdb_atom {
170
+ int serial_num;
171
+ pdb_aname name;
172
+ char alt_loc;
173
+ pdb_residue residue;
174
+ pdb_float x, y, z;
175
+ pdb_float occupancy, temp_factor;
176
+ int ftnote_num;
177
+ };
178
+ struct pdb_author {
179
+ char data[61];
180
+ char continuation;
181
+ };
182
+ # define pdb_cmpdes pdb_ftnote
183
+ struct pdb_cmpont {
184
+ int seq_num;
185
+ pdb_residue residues[2];
186
+ };
187
+ # define pdb_compnd pdb_author
188
+ struct pdb_conect {
189
+ int serial_num;
190
+ int covalent[4];
191
+ struct {
192
+ int hydrogen[2];
193
+ int salt;
194
+ } bonds[2];
195
+ };
196
+ struct pdb_cryst1 {
197
+ pdb_float a, b, c;
198
+ pdb_float alpha, beta, gamma;
199
+ char space_grp[12];
200
+ int z;
201
+ };
202
+ /* no structure for PDB_END */
203
+ /* no structure for PDB_ENDMDL */
204
+ # define pdb_expdta pdb_author
205
+ struct pdb_formul {
206
+ int component;
207
+ pdb_rname het_id;
208
+ int continuation;
209
+ char exclude; /* * to exclude */
210
+ char formula[52];
211
+ };
212
+ struct pdb_ftnote {
213
+ int num;
214
+ char text[60];
215
+ };
216
+ struct pdb_header {
217
+ char class[41];
218
+ pdb_date date;
219
+ pdb_pname id;
220
+ char type;
221
+ };
222
+ struct pdb_helix {
223
+ int serial_num;
224
+ pdb_id id;
225
+ pdb_residue residues[2];
226
+ int class;
227
+ char comment[31];
228
+ };
229
+ struct pdb_het {
230
+ pdb_residue het_grp;
231
+ int num_atoms;
232
+ char text[41];
233
+ };
234
+ # define pdb_hetatm pdb_atom
235
+ # define pdb_jrnl pdb_author
236
+ struct pdb_master {
237
+ int num_remark;
238
+ int num_ftnote;
239
+ int num_het;
240
+ int num_helix;
241
+ int num_sheet;
242
+ int num_turn;
243
+ int num_site;
244
+ int num_transform;
245
+ int num_coordinate;
246
+ int num_ter;
247
+ int num_conect;
248
+ int num_seqres;
249
+ };
250
+ struct pdb_model {
251
+ int num;
252
+ };
253
+ struct pdb_mtrix {
254
+ int row_num;
255
+ int serial_num;
256
+ pdb_float m1, m2, m3, v;
257
+ int given;
258
+ };
259
+ # define pdb_mtxdes pdb_ftnote
260
+ struct pdb_obslte {
261
+ int continuation;
262
+ pdb_date date;
263
+ pdb_pname old_id;
264
+ pdb_pname id_map[8];
265
+ };
266
+ struct pdb_origx {
267
+ int row_num;
268
+ pdb_float o1, o2, o3, t;
269
+ };
270
+ # define pdb_remark pdb_ftnote
271
+ struct pdb_revdat {
272
+ int modification;
273
+ int continuation;
274
+ pdb_date date;
275
+ char id[8];
276
+ char mod_type;
277
+ char corrections[31];
278
+ };
279
+ struct pdb_scale {
280
+ int row_num;
281
+ pdb_float s1, s2, s3, u;
282
+ };
283
+ struct pdb_seqres {
284
+ int serial_num;
285
+ char chain_id;
286
+ int count;
287
+ pdb_rname names[13];
288
+ };
289
+ struct pdb_sheet {
290
+ int strand_num;
291
+ pdb_id id;
292
+ int count;
293
+ pdb_residue residues[2];
294
+ int sense;
295
+ struct {
296
+ pdb_aname name;
297
+ pdb_residue residue;
298
+ } atoms[2];
299
+ };
300
+ # define pdb_sigatm pdb_atom
301
+ # define pdb_siguij pdb_anisou
302
+ struct pdb_site {
303
+ int seq_num;
304
+ pdb_id id;
305
+ int count;
306
+ pdb_residue residues[4];
307
+ };
308
+ # define pdb_source pdb_author
309
+ struct pdb_sprsde {
310
+ int continuation;
311
+ pdb_date date;
312
+ pdb_pname id;
313
+ pdb_pname supersede[8];
314
+ };
315
+ struct pdb_ssbond {
316
+ int seq_num;
317
+ pdb_residue residues[2];
318
+ char comment[31];
319
+ };
320
+ # define pdb_symdes pdb_ftnote
321
+ struct pdb_symop {
322
+ int row_num;
323
+ int serial_num;
324
+ pdb_float s1, s2, s3, t;
325
+ };
326
+ struct pdb_ter {
327
+ int serial_num;
328
+ pdb_residue residue;
329
+ };
330
+ struct pdb_trnsfm {
331
+ int result_serial_num;
332
+ int apply_serial_num;
333
+ int source_serial_num;
334
+ };
335
+ struct pdb_turn {
336
+ int seq_num;
337
+ pdb_id id;
338
+ pdb_residue residues[2];
339
+ char comment[31];
340
+ };
341
+ struct pdb_tvect {
342
+ int serial_num;
343
+ pdb_float t1, t2, t3;
344
+ char comment[31];
345
+ };
346
+ struct pdb_user {
347
+ char subtype[3];
348
+ char text[67];
349
+ };
350
+ struct pdb_user_pdbrun {
351
+ int version;
352
+ };
353
+ struct pdb_user_eyepos {
354
+ pdb_float xyz[3];
355
+ };
356
+ # define pdb_user_atpos pdb_user_eyepos
357
+ struct pdb_user_window {
358
+ pdb_float left, right, bottom, top, hither, yon;
359
+ };
360
+ struct pdb_user_focus {
361
+ pdb_float focus;
362
+ };
363
+ struct pdb_user_viewport {
364
+ pdb_float xmin, xmax, ymin, ymax;
365
+ };
366
+ struct pdb_user_bgcolor {
367
+ pdb_float rgb[3];
368
+ };
369
+ struct pdb_user_angle {
370
+ int atom0, atom1, atom2, atom3;
371
+ pdb_float angle;
372
+ int which; /* version 5 -- obsolete */
373
+ };
374
+ struct pdb_user_distance {
375
+ int atom0, atom1;
376
+ pdb_float distance;
377
+ int which; /* version 5 -- obsolete */
378
+ };
379
+ struct pdb_user_file {
380
+ char filename[62]; /* 57 in version 6 */
381
+ int model; /* not in version 5 */
382
+ };
383
+ struct pdb_user_markname {
384
+ char markname[58];
385
+ };
386
+ # define pdb_user_mark pdb_user_markname
387
+ struct pdb_user_cname {
388
+ pdb_float rgb[3];
389
+ char name[39];
390
+ };
391
+ struct pdb_user_color {
392
+ pdb_float rgb[3];
393
+ char spec[39];
394
+ };
395
+ struct pdb_user_radius {
396
+ pdb_float radius;
397
+ };
398
+ struct pdb_user_object {
399
+ int model; /* version 5 -- obsolete */
400
+ };
401
+ struct pdb_user_endobj {
402
+ int model; /* version 5 -- obsolete */
403
+ };
404
+ struct pdb_user_chain {
405
+ int atom0, atom1;
406
+ };
407
+ struct pdb_user_gfx_begin { /* not in version 5 */
408
+ int primitive;
409
+ char unknown[33];
410
+ };
411
+ /* no structure for USER GFX END */
412
+ # define pdb_user_gfx_color pdb_user_color
413
+ struct pdb_user_gfx_normal {
414
+ pdb_float xyz[3];
415
+ };
416
+ # define pdb_user_gfx_vertex pdb_user_gfx_normal
417
+ struct pdb_user_gfx_font {
418
+ int size;
419
+ char name[54];
420
+ };
421
+ struct pdb_user_gfx_textpos { /* not in version 5 */
422
+ pdb_float xyz[3];
423
+ };
424
+ struct pdb_user_gfx_label {
425
+ pdb_float xyz[3]; /* version 5 -- obsolete */
426
+ char text[57]; /* 27 in version 5 */
427
+ };
428
+ struct pdb_user_gfx_move { /* version 5 -- obsolete */
429
+ pdb_float xyz[3];
430
+ };
431
+ # define pdb_user_gfx_draw pdb_user_gfx_move /* version 5 -- obsolete */
432
+ # define pdb_user_gfx_marker pdb_user_gfx_move /* "" */
433
+ # define pdb_user_gfx_point pdb_user_gfx_move /* "" */
434
+
435
+ typedef struct pdb_record {
436
+ int record_type;
437
+ union {
438
+ struct pdb_unknown unknown;
439
+ struct pdb_agrdes agrdes;
440
+ struct pdb_aggrgt aggrgt;
441
+ struct pdb_anisou anisou;
442
+ struct pdb_atom atom;
443
+ struct pdb_author author;
444
+ struct pdb_cmpdes cmpdes;
445
+ struct pdb_cmpont cmpont;
446
+ struct pdb_compnd compnd;
447
+ struct pdb_conect conect;
448
+ struct pdb_cryst1 cryst1;
449
+ /* no pdb_end structure */
450
+ /* no pdb_endmdl structure */
451
+ struct pdb_expdta expdta;
452
+ struct pdb_formul formul;
453
+ struct pdb_ftnote ftnote;
454
+ struct pdb_header header;
455
+ struct pdb_helix helix;
456
+ struct pdb_het het;
457
+ struct pdb_hetatm hetatm;
458
+ struct pdb_jrnl jrnl;
459
+ struct pdb_master master;
460
+ struct pdb_model model;
461
+ struct pdb_mtrix mtrix;
462
+ struct pdb_mtxdes mtxdes;
463
+ struct pdb_obslte obslte;
464
+ struct pdb_origx origx;
465
+ struct pdb_remark remark;
466
+ struct pdb_revdat revdat;
467
+ struct pdb_scale scale;
468
+ struct pdb_seqres seqres;
469
+ struct pdb_sheet sheet;
470
+ struct pdb_sigatm sigatm;
471
+ struct pdb_siguij siguij;
472
+ struct pdb_site site;
473
+ struct pdb_source source;
474
+ struct pdb_sprsde sprsde;
475
+ struct pdb_ssbond ssbond;
476
+ struct pdb_symdes symdes;
477
+ struct pdb_symop symop;
478
+ struct pdb_ter ter;
479
+ struct pdb_trnsfm trnsfm;
480
+ struct pdb_turn turn;
481
+ struct pdb_tvect tvect;
482
+ struct pdb_user user;
483
+ struct pdb_user_pdbrun user_pdbrun;
484
+ struct pdb_user_eyepos user_eyepos;
485
+ struct pdb_user_atpos user_atpos;
486
+ struct pdb_user_window user_window;
487
+ struct pdb_user_focus user_focus;
488
+ struct pdb_user_viewport user_viewport;
489
+ struct pdb_user_bgcolor user_bgcolor;
490
+ struct pdb_user_angle user_angle;
491
+ struct pdb_user_distance user_distance;
492
+ struct pdb_user_file user_file;
493
+ struct pdb_user_markname user_markname;
494
+ struct pdb_user_mark user_mark;
495
+ struct pdb_user_cname user_cname;
496
+ struct pdb_user_color user_color;
497
+ struct pdb_user_radius user_radius;
498
+ struct pdb_user_object user_object;
499
+ struct pdb_user_endobj user_endobj;
500
+ struct pdb_user_chain user_chain;
501
+ struct pdb_user_gfx_begin user_gfx_begin;
502
+ struct pdb_user_gfx_color user_gfx_color;
503
+ struct pdb_user_gfx_normal user_gfx_normal;
504
+ struct pdb_user_gfx_vertex user_gfx_vertex;
505
+ struct pdb_user_gfx_font user_gfx_font;
506
+ struct pdb_user_gfx_textpos user_gfx_textpos;
507
+ struct pdb_user_gfx_label user_gfx_label;
508
+ struct pdb_user_gfx_move user_gfx_move;
509
+ struct pdb_user_gfx_draw user_gfx_draw;
510
+ struct pdb_user_gfx_marker user_gfx_marker;
511
+ struct pdb_user_gfx_point user_gfx_point;
512
+ } pdb;
513
+ } pdb_record;
514
+
515
+ # if defined(__STDC__) || defined(__cplusplus)
516
+ extern pdb_record pdb_read_record(FILE *);
517
+ extern pdb_record pdb_read_string(const char *);
518
+ extern void pdb_write_record(FILE *, const pdb_record *, const char *, int);
519
+ extern void pdb_write_string(char *, const pdb_record *);
520
+ # else
521
+ extern pdb_record pdb_read_record();
522
+ extern pdb_record pdb_read_string();
523
+ extern void pdb_write_record();
524
+ extern void pdb_write_string();
525
+ # endif
526
+
527
+ # ifdef __cplusplus
528
+ }
529
+ # endif
530
+ #endif /* PDB_H */
dms/libpdb/pdb_int.h ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdb_int.h,v 2.4 1994/11/17 00:58:58 gregc Exp $
18
+ */
19
+
20
+ #include "pdb.h"
21
+
22
+ #ifndef __STDC__
23
+ # define const
24
+ #endif
25
+
26
+ extern int pdb_pdbrun_version;
27
+
28
+ #ifdef __STDC__
29
+ extern int pdb_sscanf(const char *, const char *, ...);
30
+ extern void pdb_sprintf(char *, const char *, ...);
31
+ extern const char *pdb_gfx_string(int i);
32
+ extern int pdb_gfx_type(const char *type);
33
+ #else
34
+ extern int pdb_sscanf();
35
+ extern void pdb_sprintf();
36
+ extern char *pdb_gfx_string();
37
+ extern int pdb_gfx_type();
38
+ #endif
dms/libpdb/pdb_read.c ADDED
@@ -0,0 +1,1143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdb_read.c,v 2.20 1995/07/22 02:03:18 gregc Exp $
18
+ *
19
+ * subroutine for reading PDB format files
20
+ *
21
+ */
22
+
23
+ /* LINTLIBRARY */
24
+
25
+ # include <stdio.h>
26
+ # include <ctype.h>
27
+ # include <string.h>
28
+ # include "pdb_int.h"
29
+
30
+ # ifndef _tolower
31
+ # define _tolower tolower
32
+ # endif
33
+
34
+ # define STREQN(a,b,n) (strncmp(a, b, n) == 0)
35
+
36
+ static const char * const pdb_record_format[PDB_NUM_R] = {
37
+ #include "read_format.i"
38
+ };
39
+
40
+ static char const * const pdbrun5[] = {
41
+ #include "pdbrun5_read.i"
42
+ };
43
+
44
+ static char const * const pdbrun6[] = {
45
+ #include "pdbrun6_read.i"
46
+ };
47
+
48
+ /*
49
+ * for each pdb record type there is a format reading in the
50
+ * record values and for printing them out.
51
+ *
52
+ * The actual format of a line written, is the print format
53
+ * followed by blank padding to 72 characters, followed by
54
+ * 8 characters of file and line information.
55
+ */
56
+
57
+ pdb_record
58
+ # ifdef __STDC__
59
+ pdb_read_record(FILE *f)
60
+ # else
61
+ pdb_read_record(f)
62
+ FILE *f;
63
+ # endif
64
+ {
65
+
66
+ char buffer[PDB_BUFSIZ];
67
+ char *cp;
68
+ int c;
69
+ static pdb_record r_end = { PDB_END };
70
+
71
+ if (fgets(buffer, PDB_BUFSIZ, f) == NULL) {
72
+ /* at eof or error - default to eof */
73
+ return r_end;
74
+ }
75
+
76
+ cp = strchr(buffer, '\n');
77
+ if (cp != NULL)
78
+ *cp = '\0';
79
+ else
80
+ /* discard extra characters since line too long */
81
+ while ((c = getc(f)) != '\n' && c != EOF)
82
+ continue;
83
+
84
+ return pdb_read_string(buffer);
85
+ }
86
+
87
+ static int
88
+ #ifdef __STDC__
89
+ pdbrun5_type(const char *buf)
90
+ #else
91
+ pdbrun5_type(buf)
92
+ char *buf;
93
+ #endif
94
+ {
95
+ switch (buf[0]) {
96
+ case 'A': case 'a':
97
+ if (strncasecmp(buf + 1, "NGLE ", 5) == 0)
98
+ return PDB_USER_ANGLE;
99
+ if (strncasecmp(buf + 1, "TPOS ", 5) == 0)
100
+ return PDB_USER_ATPOS;
101
+ break;
102
+ case 'B': case 'b':
103
+ if (strncasecmp(buf + 1, "GCOLOR ", 7) == 0)
104
+ return PDB_USER_BGCOLOR;
105
+ break;
106
+ case 'C': case 'c':
107
+ if (strncasecmp(buf + 1, "HAIN ", 5) == 0)
108
+ return PDB_USER_CHAIN;
109
+ if (strncasecmp(buf + 1, "NAME ", 5) == 0)
110
+ return PDB_USER_CNAME;
111
+ if (strncasecmp(buf + 1, "OLOR ", 5) == 0)
112
+ return PDB_USER_COLOR;
113
+ break;
114
+ case 'D': case 'd':
115
+ if (strncasecmp(buf + 1, "ISTANCE ", 8) == 0)
116
+ return PDB_USER_DISTANCE;
117
+ break;
118
+ case 'E': case 'e':
119
+ if (strncasecmp(buf + 1, "NDOBJ ", 6) == 0)
120
+ return PDB_USER_ENDOBJ;
121
+ if (strncasecmp(buf + 1, "YEPOS ", 6) == 0)
122
+ return PDB_USER_EYEPOS;
123
+ break;
124
+ case 'F': case 'f':
125
+ if (strncasecmp(buf + 1, "ILE ", 4) == 0)
126
+ return PDB_USER_FILE;
127
+ if (strncasecmp(buf + 1, "OCUS ", 5) == 0)
128
+ return PDB_USER_FOCUS;
129
+ break;
130
+ case 'G': case 'g':
131
+ if (strncasecmp(buf + 1, "FX ", 3) != 0)
132
+ break;
133
+ if (strncasecmp(buf + 4, "COLOR ", 6) == 0)
134
+ return PDB_USER_GFX_COLOR;
135
+ if (strncasecmp(buf + 4, "DRAW ", 5) == 0)
136
+ return PDB_USER_GFX_DRAW;
137
+ if (strncasecmp(buf + 4, "FONT ", 5) == 0)
138
+ return PDB_USER_GFX_FONT;
139
+ if (strncasecmp(buf + 4, "LABEL ", 6) == 0)
140
+ return PDB_USER_GFX_LABEL;
141
+ if (strncasecmp(buf + 4, "MARKER ", 7) == 0)
142
+ return PDB_USER_GFX_MARKER;
143
+ if (strncasecmp(buf + 4, "MOVE ", 5) == 0)
144
+ return PDB_USER_GFX_MOVE;
145
+ if (strncasecmp(buf + 4, "POINT ", 6) == 0)
146
+ return PDB_USER_GFX_POINT;
147
+ break;
148
+ case 'O': case 'o':
149
+ if (strncasecmp(buf + 1, "BJECT ", 6) == 0)
150
+ return PDB_USER_OBJECT;
151
+ break;
152
+ case 'P': case 'p':
153
+ if (strncasecmp(buf + 1, "DBRUN ", 6) == 0)
154
+ return PDB_USER_PDBRUN;
155
+ break;
156
+ case 'R': case 'r':
157
+ if (strncasecmp(buf + 1, "ADIUS ", 6) == 0)
158
+ return PDB_USER_RADIUS;
159
+ break;
160
+ case 'V': case 'v':
161
+ if (strncasecmp(buf + 1, "IEWPORT ", 8) == 0)
162
+ return PDB_USER_VIEWPORT;
163
+ break;
164
+ case 'W': case 'w':
165
+ if (strncasecmp(buf + 1, "INDOW ", 6) == 0)
166
+ return PDB_USER_WINDOW;
167
+ break;
168
+ }
169
+ return PDB_USER;
170
+ }
171
+
172
+ static int
173
+ #ifdef __STDC__
174
+ pdbrun6_type(const char *buf)
175
+ #else
176
+ pdbrun6_type(buf)
177
+ char *buf;
178
+ #endif
179
+ {
180
+ switch (buf[0]) {
181
+ case 'A': case 'a':
182
+ if (strncasecmp(buf + 1, "NGLE ", 5) == 0)
183
+ return PDB_USER_ANGLE;
184
+ if (strncasecmp(buf + 1, "TPOS ", 5) == 0)
185
+ return PDB_USER_ATPOS;
186
+ break;
187
+ case 'B': case 'b':
188
+ if (strncasecmp(buf + 1, "GCOLOR ", 7) == 0)
189
+ return PDB_USER_BGCOLOR;
190
+ break;
191
+ case 'C': case 'c':
192
+ if (strncasecmp(buf + 1, "HAIN ", 5) == 0)
193
+ return PDB_USER_CHAIN;
194
+ if (strncasecmp(buf + 1, "NAME ", 5) == 0)
195
+ return PDB_USER_CNAME;
196
+ if (strncasecmp(buf + 1, "OLOR ", 5) == 0)
197
+ return PDB_USER_COLOR;
198
+ break;
199
+ case 'D': case 'd':
200
+ if (strncasecmp(buf + 1, "ISTANCE ", 8) == 0)
201
+ return PDB_USER_DISTANCE;
202
+ break;
203
+ case 'E': case 'e':
204
+ if (strncasecmp(buf + 1, "NDOBJ", 5) == 0
205
+ && (buf[6] == '\0' || buf[6] == '\n' || buf[6] == ' '))
206
+ return PDB_USER_ENDOBJ;
207
+ if (strncasecmp(buf + 1, "YEPOS ", 6) == 0)
208
+ return PDB_USER_EYEPOS;
209
+ break;
210
+ case 'F': case 'f':
211
+ if (strncasecmp(buf + 1, "ILE ", 4) == 0)
212
+ return PDB_USER_FILE;
213
+ if (strncasecmp(buf + 1, "OCUS ", 5) == 0)
214
+ return PDB_USER_FOCUS;
215
+ break;
216
+ case 'G': case 'g':
217
+ if (buf[1] != 'F' || buf[2] != 'X' || buf[3] != ' ')
218
+ break;
219
+ switch (buf[4]) {
220
+ case 'B': case 'b':
221
+ if (strncasecmp(buf + 5, "EGIN ", 5) == 0)
222
+ return PDB_USER_GFX_BEGIN;
223
+ break;
224
+ case 'C': case 'c':
225
+ if (strncasecmp(buf + 5, "OLOR ", 5) == 0)
226
+ return PDB_USER_GFX_COLOR;
227
+ break;
228
+ case 'E': case 'e':
229
+ if (buf[5] == 'N' && buf[6] == 'D'
230
+ && (buf[7] == '\0' || buf[7] == '\n' || buf[7] == ' '))
231
+ return PDB_USER_GFX_END;
232
+ break;
233
+ case 'F': case 'f':
234
+ if (strncasecmp(buf + 5, "ONT ", 4) == 0)
235
+ return PDB_USER_GFX_FONT;
236
+ break;
237
+ case 'L': case 'l':
238
+ if (strncasecmp(buf + 5, "ABEL ", 5) == 0)
239
+ return PDB_USER_GFX_LABEL;
240
+ break;
241
+ case 'N': case 'n':
242
+ if (strncasecmp(buf + 5, "ORMAL ", 6) == 0)
243
+ return PDB_USER_GFX_NORMAL;
244
+ break;
245
+ case 'T': case 't':
246
+ if (strncasecmp(buf + 5, "EXTPOS ", 7) == 0)
247
+ return PDB_USER_GFX_TEXTPOS;
248
+ break;
249
+ case 'V': case 'v':
250
+ if (strncasecmp(buf + 5, "ERTEX ", 6) == 0)
251
+ return PDB_USER_GFX_VERTEX;
252
+ break;
253
+ }
254
+ break;
255
+ case 'M': case 'm':
256
+ if (strncasecmp(buf + 1, "ARK ", 4) == 0)
257
+ return PDB_USER_MARK;
258
+ if (strncasecmp(buf + 1, "ARKNAME ", 6) == 0)
259
+ return PDB_USER_MARKNAME;
260
+ break;
261
+ case 'O': case 'o':
262
+ if (strncasecmp(buf + 1, "BJECT", 5) == 0
263
+ && (buf[6] == '\0' || buf[6] == '\n' || buf[6] == ' '))
264
+ return PDB_USER_OBJECT;
265
+ break;
266
+ case 'P': case 'p':
267
+ if (strncasecmp(buf + 1, "DBRUN ", 6) == 0)
268
+ return PDB_USER_PDBRUN;
269
+ break;
270
+ case 'R': case 'r':
271
+ if (strncasecmp(buf + 1, "ADIUS ", 6) == 0)
272
+ return PDB_USER_RADIUS;
273
+ break;
274
+ case 'V': case 'v':
275
+ if (strncasecmp(buf + 1, "IEWPORT ", 6) == 0)
276
+ return PDB_USER_VIEWPORT;
277
+ break;
278
+ case 'W': case 'w':
279
+ if (strncasecmp(buf + 1, "INDOW ", 6) == 0)
280
+ return PDB_USER_WINDOW;
281
+ break;
282
+ }
283
+ return PDB_USER;
284
+ }
285
+
286
+ pdb_record
287
+ # ifdef __STDC__
288
+ pdb_read_string(const char *buffer)
289
+ # else
290
+ pdb_read_string(buffer)
291
+ char *buffer;
292
+ # endif
293
+ {
294
+
295
+ pdb_record r;
296
+ const char *fmt;
297
+ struct pdb_sheet *sh;
298
+ pdb_residue *sha0, *sha1;
299
+ char record_type[4];
300
+ int i;
301
+ char new_buffer[PDB_BUFSIZ];
302
+
303
+ # if defined(__STDC__) || defined(vms)
304
+ (void) memset(&r, 0, sizeof r);
305
+ # else
306
+ bzero((char *) &r, sizeof r);
307
+ # endif
308
+
309
+ # ifdef DEBUG
310
+ printf("%s", buffer);
311
+ # endif /* DEBUG */
312
+
313
+ /* convert pdb record to C structure */
314
+
315
+ for (i = 0; buffer[i] != '\0' && buffer[i] != '\n' && i < 4; i += 1) {
316
+ if (isupper(buffer[i]))
317
+ record_type[i] = _tolower(buffer[i]);
318
+ else
319
+ record_type[i] = buffer[i];
320
+ }
321
+ if (i < 4)
322
+ for (; i < 4; i += 1)
323
+ record_type[i] = ' ';
324
+
325
+ r.record_type = PDB_UNKNOWN;
326
+ switch (record_type[0]) {
327
+
328
+ case 'a':
329
+ if (STREQN(record_type + 1, "tom", 3))
330
+ r.record_type = PDB_ATOM;
331
+ else if (STREQN(record_type + 1, "uth", 3))
332
+ r.record_type = PDB_AUTHOR;
333
+ else if (STREQN(record_type + 1, "nis", 3))
334
+ r.record_type = PDB_ANISOU;
335
+ else if (STREQN(record_type + 1, "grd", 3))
336
+ r.record_type = PDB_AGRDES;
337
+ else if (STREQN(record_type + 1, "ggr", 3))
338
+ r.record_type = PDB_AGGRGT;
339
+ break;
340
+
341
+ case 'c':
342
+ if (STREQN(record_type + 1, "omp", 3))
343
+ r.record_type = PDB_COMPND;
344
+ else if (STREQN(record_type + 1, "rys", 3))
345
+ r.record_type = PDB_CRYST1;
346
+ else if (STREQN(record_type + 1, "one", 3))
347
+ r.record_type = PDB_CONECT;
348
+ else if (STREQN(record_type + 1, "mpd", 3))
349
+ r.record_type = PDB_CMPDES;
350
+ else if (STREQN(record_type + 1, "mpo", 3))
351
+ r.record_type = PDB_CMPONT;
352
+ break;
353
+
354
+ case 'e':
355
+ if (STREQN(record_type + 1, "nd ", 3))
356
+ r.record_type = PDB_END;
357
+ else if (STREQN(record_type + 1, "ndm", 3))
358
+ r.record_type = PDB_ENDMDL;
359
+ else if (STREQN(record_type + 1, "xpd", 3))
360
+ r.record_type = PDB_EXPDTA;
361
+ break;
362
+
363
+ case 'f':
364
+ if (STREQN(record_type + 1, "tno", 3))
365
+ r.record_type = PDB_FTNOTE;
366
+ else if (STREQN(record_type + 1, "orm", 3))
367
+ r.record_type = PDB_FORMUL;
368
+ break;
369
+
370
+ case 'h':
371
+ if (STREQN(record_type + 1, "eta", 3))
372
+ r.record_type = PDB_HETATM;
373
+ else if (STREQN(record_type + 1, "ead", 3))
374
+ r.record_type = PDB_HEADER;
375
+ else if (STREQN(record_type + 1, "et ", 3))
376
+ r.record_type = PDB_HET;
377
+ else if (STREQN(record_type + 1, "eli", 3))
378
+ r.record_type = PDB_HELIX;
379
+ break;
380
+
381
+ case 'j':
382
+ if (STREQN(record_type + 1, "rnl", 3))
383
+ r.record_type = PDB_JRNL;
384
+ break;
385
+
386
+ case 'm':
387
+ if (STREQN(record_type + 1, "tri", 3))
388
+ r.record_type = PDB_MTRIX;
389
+ else if (STREQN(record_type + 1, "ast", 3))
390
+ r.record_type = PDB_MASTER;
391
+ else if (STREQN(record_type + 1, "ode", 3))
392
+ r.record_type = PDB_MODEL;
393
+ else if (STREQN(record_type + 1, "txd", 3))
394
+ r.record_type = PDB_MTXDES;
395
+ break;
396
+
397
+ case 'o':
398
+ if (STREQN(record_type + 1, "bsl", 3))
399
+ r.record_type = PDB_OBSLTE;
400
+ else if (STREQN(record_type + 1, "rig", 3))
401
+ r.record_type = PDB_ORIGX;
402
+ break;
403
+
404
+ case 'r':
405
+ if (STREQN(record_type + 1, "ema", 3))
406
+ r.record_type = PDB_REMARK;
407
+ else if (STREQN(record_type + 1, "evd", 3))
408
+ r.record_type = PDB_REVDAT;
409
+ break;
410
+
411
+ case 's':
412
+ switch (record_type[1]) {
413
+
414
+ case 'c':
415
+ if (STREQN(record_type + 2, "al", 2))
416
+ r.record_type = PDB_SCALE;
417
+ break;
418
+
419
+ case 'e':
420
+ if (STREQN(record_type + 2, "qr", 2))
421
+ r.record_type = PDB_SEQRES;
422
+ break;
423
+
424
+ case 'h':
425
+ if (STREQN(record_type + 2, "ee", 2))
426
+ r.record_type = PDB_SHEET;
427
+ break;
428
+
429
+ case 'i':
430
+ if (STREQN(record_type + 2, "te", 2))
431
+ r.record_type = PDB_SITE;
432
+ else if (STREQN(record_type + 2, "ga", 2))
433
+ r.record_type = PDB_SIGATM;
434
+ else if (STREQN(record_type + 2, "gu", 2))
435
+ r.record_type = PDB_SIGUIJ;
436
+ break;
437
+
438
+ case 'o':
439
+ if (STREQN(record_type + 2, "ur", 2))
440
+ r.record_type = PDB_SOURCE;
441
+ break;
442
+
443
+ case 'p':
444
+ if (STREQN(record_type + 2, "rs", 2))
445
+ r.record_type = PDB_SPRSDE;
446
+ break;
447
+
448
+ case 's':
449
+ if (STREQN(record_type + 2, "bo", 2))
450
+ r.record_type = PDB_SSBOND;
451
+ break;
452
+
453
+ case 'y':
454
+ if (STREQN(record_type + 2, "md", 2))
455
+ r.record_type = PDB_SYMDES;
456
+ else if (STREQN(record_type + 2, "mo", 2))
457
+ r.record_type = PDB_SYMOP;
458
+ break;
459
+ }
460
+ break;
461
+
462
+ case 't':
463
+ if (STREQN(record_type + 1, "urn", 3))
464
+ r.record_type = PDB_TURN;
465
+ else if (STREQN(record_type + 1, "vec", 3))
466
+ r.record_type = PDB_TVECT;
467
+ else if (STREQN(record_type + 1, "er ", 3))
468
+ r.record_type = PDB_TER;
469
+ else if (STREQN(record_type + 1, "rns", 3))
470
+ r.record_type = PDB_TRNSFM;
471
+ break;
472
+
473
+ case 'u':
474
+ if (STREQN(record_type + 1, "ser", 3)) {
475
+ r.record_type = PDB_USER;
476
+ switch (pdb_pdbrun_version) {
477
+ case 1: case 2: case 3: case 4: case 5:
478
+ r.record_type = pdbrun5_type(buffer + 6);
479
+ break;
480
+ case 6:
481
+ r.record_type = pdbrun6_type(buffer + 6);
482
+ break;
483
+ default:
484
+ if (strncasecmp(buffer + 6, "PDBRUN ", 7) == 0)
485
+ r.record_type = PDB_USER_PDBRUN;
486
+ break;
487
+ }
488
+ }
489
+ break;
490
+ }
491
+
492
+ if (r.record_type < PDB_USER_PDBRUN)
493
+ fmt = pdb_record_format[r.record_type];
494
+ else if (pdb_pdbrun_version < 6)
495
+ fmt = pdbrun5[r.record_type - PDB_USER_PDBRUN];
496
+ else
497
+ fmt = pdbrun6[r.record_type - PDB_USER_PDBRUN];
498
+ switch (r.record_type) {
499
+
500
+ default:
501
+ case PDB_UNKNOWN:
502
+ unknown:
503
+ r.record_type = PDB_UNKNOWN; /* in case of goto */
504
+ (void) pdb_sscanf(buffer, "%72s", r.pdb.unknown.junk);
505
+ break;
506
+
507
+ case PDB_AGGRGT:
508
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.aggrgt.serial_num,
509
+ &r.pdb.aggrgt.num_components,
510
+ &r.pdb.aggrgt.cmpont_serial_nums[0],
511
+ &r.pdb.aggrgt.cmpont_serial_nums[1],
512
+ &r.pdb.aggrgt.cmpont_serial_nums[2],
513
+ &r.pdb.aggrgt.cmpont_serial_nums[3],
514
+ &r.pdb.aggrgt.cmpont_serial_nums[4],
515
+ &r.pdb.aggrgt.cmpont_serial_nums[5],
516
+ &r.pdb.aggrgt.cmpont_serial_nums[6],
517
+ &r.pdb.aggrgt.cmpont_serial_nums[7],
518
+ &r.pdb.aggrgt.cmpont_serial_nums[8],
519
+ &r.pdb.aggrgt.cmpont_serial_nums[9],
520
+ &r.pdb.aggrgt.cmpont_serial_nums[10],
521
+ &r.pdb.aggrgt.cmpont_serial_nums[11],
522
+ &r.pdb.aggrgt.cmpont_serial_nums[12],
523
+ &r.pdb.aggrgt.cmpont_serial_nums[13]))
524
+ goto unknown;
525
+ break;
526
+ case PDB_ANISOU:
527
+ case PDB_SIGUIJ:
528
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.anisou.serial_num,
529
+ r.pdb.anisou.name, &r.pdb.anisou.alt_loc,
530
+ r.pdb.anisou.residue.name,
531
+ &r.pdb.anisou.residue.chain_id,
532
+ &r.pdb.anisou.residue.seq_num,
533
+ &r.pdb.anisou.residue.insert_code,
534
+ &r.pdb.anisou.u[0], &r.pdb.anisou.u[1],
535
+ &r.pdb.anisou.u[2], &r.pdb.anisou.u[3],
536
+ &r.pdb.anisou.u[4], &r.pdb.anisou.u[5]))
537
+ goto unknown;
538
+ break;
539
+
540
+ case PDB_ATOM:
541
+ case PDB_HETATM:
542
+ case PDB_SIGATM:
543
+ if (0 <= pdb_sscanf(buffer, fmt, &r.pdb.atom.serial_num,
544
+ r.pdb.atom.name, &r.pdb.atom.alt_loc,
545
+ r.pdb.atom.residue.name,
546
+ &r.pdb.atom.residue.chain_id,
547
+ &r.pdb.atom.residue.seq_num,
548
+ &r.pdb.atom.residue.insert_code,
549
+ &r.pdb.atom.x, &r.pdb.atom.y, &r.pdb.atom.z,
550
+ &r.pdb.atom.occupancy, &r.pdb.atom.temp_factor,
551
+ &r.pdb.atom.ftnote_num))
552
+ break;
553
+ /* handle atom serial number overflows */
554
+ if (strncmp(&buffer[6], "*****", 5) != 0)
555
+ goto unknown;
556
+ strncpy(new_buffer, buffer, PDB_BUFSIZ);
557
+ strncpy(&new_buffer[6], "00000", 5);
558
+ if (0 <= pdb_sscanf(new_buffer, fmt, &r.pdb.atom.serial_num,
559
+ r.pdb.atom.name, &r.pdb.atom.alt_loc,
560
+ r.pdb.atom.residue.name,
561
+ &r.pdb.atom.residue.chain_id,
562
+ &r.pdb.atom.residue.seq_num,
563
+ &r.pdb.atom.residue.insert_code,
564
+ &r.pdb.atom.x, &r.pdb.atom.y, &r.pdb.atom.z,
565
+ &r.pdb.atom.occupancy, &r.pdb.atom.temp_factor,
566
+ &r.pdb.atom.ftnote_num)) {
567
+ static int atom_serial_number = 10000;
568
+ r.pdb.atom.serial_num = atom_serial_number++;
569
+ break;
570
+ }
571
+ goto unknown;
572
+
573
+ case PDB_AUTHOR:
574
+ case PDB_COMPND:
575
+ case PDB_JRNL:
576
+ case PDB_SOURCE:
577
+ case PDB_EXPDTA:
578
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.author.continuation,
579
+ r.pdb.author.data))
580
+ goto unknown;
581
+ break;
582
+
583
+ case PDB_CMPONT:
584
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.cmpont.seq_num,
585
+ r.pdb.cmpont.residues[0].name,
586
+ &r.pdb.cmpont.residues[0].chain_id,
587
+ &r.pdb.cmpont.residues[0].seq_num,
588
+ &r.pdb.cmpont.residues[0].insert_code,
589
+ r.pdb.cmpont.residues[1].name,
590
+ &r.pdb.cmpont.residues[1].chain_id,
591
+ &r.pdb.cmpont.residues[1].seq_num,
592
+ &r.pdb.cmpont.residues[1].insert_code))
593
+ goto unknown;
594
+ break;
595
+
596
+ case PDB_CONECT:
597
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.conect.serial_num,
598
+ &r.pdb.conect.covalent[0],
599
+ &r.pdb.conect.covalent[1],
600
+ &r.pdb.conect.covalent[2],
601
+ &r.pdb.conect.covalent[3],
602
+ &r.pdb.conect.bonds[0].hydrogen[0],
603
+ &r.pdb.conect.bonds[0].hydrogen[1],
604
+ &r.pdb.conect.bonds[0].salt,
605
+ &r.pdb.conect.bonds[1].hydrogen[0],
606
+ &r.pdb.conect.bonds[1].hydrogen[1],
607
+ &r.pdb.conect.bonds[1].salt))
608
+ goto unknown;
609
+ break;
610
+
611
+ case PDB_CRYST1:
612
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.cryst1.a,
613
+ &r.pdb.cryst1.b, &r.pdb.cryst1.c,
614
+ &r.pdb.cryst1.alpha, &r.pdb.cryst1.beta,
615
+ &r.pdb.cryst1.gamma, r.pdb.cryst1.space_grp,
616
+ &r.pdb.cryst1.z))
617
+ goto unknown;
618
+ break;
619
+
620
+ case PDB_END:
621
+ case PDB_ENDMDL:
622
+ break;
623
+
624
+ case PDB_FORMUL:
625
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.formul.component,
626
+ r.pdb.formul.het_id, &r.pdb.formul.continuation,
627
+ &r.pdb.formul.exclude, r.pdb.formul.formula))
628
+ goto unknown;
629
+ break;
630
+
631
+ case PDB_FTNOTE:
632
+ case PDB_REMARK:
633
+ case PDB_SYMDES:
634
+ case PDB_MTXDES:
635
+ case PDB_CMPDES:
636
+ case PDB_AGRDES:
637
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.ftnote.num,
638
+ r.pdb.ftnote.text))
639
+ goto unknown;
640
+ break;
641
+
642
+ case PDB_HEADER:
643
+ if (0 > pdb_sscanf(buffer, fmt, r.pdb.header.class,
644
+ r.pdb.header.date, &r.pdb.header.type,
645
+ r.pdb.header.id))
646
+ goto unknown;
647
+ break;
648
+
649
+ case PDB_HELIX:
650
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.helix.serial_num,
651
+ r.pdb.helix.id,
652
+ r.pdb.helix.residues[0].name,
653
+ &r.pdb.helix.residues[0].chain_id,
654
+ &r.pdb.helix.residues[0].seq_num,
655
+ &r.pdb.helix.residues[0].insert_code,
656
+ r.pdb.helix.residues[1].name,
657
+ &r.pdb.helix.residues[1].chain_id,
658
+ &r.pdb.helix.residues[1].seq_num,
659
+ &r.pdb.helix.residues[1].insert_code,
660
+ &r.pdb.helix.class, r.pdb.helix.comment))
661
+ goto unknown;
662
+ break;
663
+
664
+ case PDB_HET:
665
+ if (0 > pdb_sscanf(buffer, fmt, r.pdb.het.het_grp.name,
666
+ &r.pdb.het.het_grp.chain_id,
667
+ &r.pdb.het.het_grp.seq_num,
668
+ &r.pdb.het.het_grp.insert_code,
669
+ &r.pdb.het.num_atoms, r.pdb.het.text))
670
+ goto unknown;
671
+ break;
672
+
673
+ case PDB_MASTER:
674
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.master.num_remark,
675
+ &r.pdb.master.num_ftnote,
676
+ &r.pdb.master.num_het, &r.pdb.master.num_helix,
677
+ &r.pdb.master.num_sheet, &r.pdb.master.num_turn,
678
+ &r.pdb.master.num_site,
679
+ &r.pdb.master.num_transform,
680
+ &r.pdb.master.num_coordinate,
681
+ &r.pdb.master.num_ter, &r.pdb.master.num_conect,
682
+ &r.pdb.master.num_seqres))
683
+ goto unknown;
684
+ break;
685
+
686
+ case PDB_MODEL:
687
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.model.num))
688
+ goto unknown;
689
+ break;
690
+
691
+ case PDB_MTRIX:
692
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.mtrix.row_num,
693
+ &r.pdb.mtrix.serial_num, &r.pdb.mtrix.m1,
694
+ &r.pdb.mtrix.m2, &r.pdb.mtrix.m3,
695
+ &r.pdb.mtrix.v, &r.pdb.mtrix.given))
696
+ goto unknown;
697
+ break;
698
+
699
+ case PDB_OBSLTE:
700
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.obslte.continuation,
701
+ r.pdb.obslte.date, r.pdb.obslte.old_id,
702
+ r.pdb.obslte.id_map[0], r.pdb.obslte.id_map[1],
703
+ r.pdb.obslte.id_map[2], r.pdb.obslte.id_map[3],
704
+ r.pdb.obslte.id_map[4], r.pdb.obslte.id_map[2],
705
+ r.pdb.obslte.id_map[6], r.pdb.obslte.id_map[7]))
706
+ goto unknown;
707
+ break;
708
+
709
+ case PDB_ORIGX:
710
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.origx.row_num,
711
+ &r.pdb.origx.o1, &r.pdb.origx.o2,
712
+ &r.pdb.origx.o3, &r.pdb.origx.t))
713
+ goto unknown;
714
+ break;
715
+
716
+ case PDB_REVDAT:
717
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.revdat.modification,
718
+ &r.pdb.revdat.continuation, r.pdb.revdat.date,
719
+ r.pdb.revdat.id, &r.pdb.revdat.mod_type,
720
+ r.pdb.revdat.corrections))
721
+ goto unknown;
722
+ break;
723
+
724
+ case PDB_SCALE:
725
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.scale.row_num,
726
+ &r.pdb.scale.s1, &r.pdb.scale.s2,
727
+ &r.pdb.scale.s3, &r.pdb.scale.u))
728
+ goto unknown;
729
+ break;
730
+
731
+ case PDB_SEQRES:
732
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.seqres.serial_num,
733
+ &r.pdb.seqres.chain_id, &r.pdb.seqres.count,
734
+ r.pdb.seqres.names[0], r.pdb.seqres.names[1],
735
+ r.pdb.seqres.names[2], r.pdb.seqres.names[3],
736
+ r.pdb.seqres.names[4], r.pdb.seqres.names[5],
737
+ r.pdb.seqres.names[6], r.pdb.seqres.names[7],
738
+ r.pdb.seqres.names[8], r.pdb.seqres.names[9],
739
+ r.pdb.seqres.names[10], r.pdb.seqres.names[11],
740
+ r.pdb.seqres.names[12]))
741
+ goto unknown;
742
+ break;
743
+
744
+ case PDB_SHEET:
745
+ sh = &r.pdb.sheet;
746
+ sha0 = &sh->atoms[0].residue;
747
+ sha1 = &sh->atoms[1].residue;
748
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.sheet.strand_num,
749
+ sh->id, &r.pdb.sheet.count,
750
+ sh->residues[0].name, &sh->residues[0].chain_id,
751
+ &sh->residues[0].seq_num,
752
+ &sh->residues[0].insert_code,
753
+ sh->residues[1].name, &sh->residues[1].chain_id,
754
+ &sh->residues[1].seq_num,
755
+ &sh->residues[1].insert_code, &sh->sense,
756
+ sh->atoms[0].name, sha0->name, &sha0->chain_id,
757
+ &sha0->seq_num, &sha0->insert_code,
758
+ sh->atoms[1].name, sha1->name,
759
+ &sha1->chain_id, &sha1->seq_num,
760
+ &sha1->insert_code))
761
+ goto unknown;
762
+ break;
763
+
764
+ case PDB_SITE:
765
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.site.seq_num,
766
+ r.pdb.site.id, &r.pdb.site.count,
767
+ r.pdb.site.residues[0].name,
768
+ &r.pdb.site.residues[0].chain_id,
769
+ &r.pdb.site.residues[0].seq_num,
770
+ &r.pdb.site.residues[0].insert_code,
771
+ r.pdb.site.residues[1].name,
772
+ &r.pdb.site.residues[1].chain_id,
773
+ &r.pdb.site.residues[1].seq_num,
774
+ &r.pdb.site.residues[1].insert_code,
775
+ r.pdb.site.residues[2].name,
776
+ &r.pdb.site.residues[2].chain_id,
777
+ &r.pdb.site.residues[2].seq_num,
778
+ &r.pdb.site.residues[2].insert_code,
779
+ r.pdb.site.residues[3].name,
780
+ &r.pdb.site.residues[3].chain_id,
781
+ &r.pdb.site.residues[3].seq_num,
782
+ &r.pdb.site.residues[3].insert_code))
783
+ goto unknown;
784
+ break;
785
+
786
+ case PDB_SPRSDE:
787
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.sprsde.continuation,
788
+ r.pdb.sprsde.date, r.pdb.sprsde.id,
789
+ r.pdb.sprsde.supersede[0],
790
+ r.pdb.sprsde.supersede[1],
791
+ r.pdb.sprsde.supersede[2],
792
+ r.pdb.sprsde.supersede[3],
793
+ r.pdb.sprsde.supersede[4],
794
+ r.pdb.sprsde.supersede[5],
795
+ r.pdb.sprsde.supersede[6],
796
+ r.pdb.sprsde.supersede[7]))
797
+ goto unknown;
798
+ break;
799
+
800
+ case PDB_SSBOND:
801
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.ssbond.seq_num,
802
+ r.pdb.ssbond.residues[0].name,
803
+ &r.pdb.ssbond.residues[0].chain_id,
804
+ &r.pdb.ssbond.residues[0].seq_num,
805
+ &r.pdb.ssbond.residues[0].insert_code,
806
+ r.pdb.ssbond.residues[1].name,
807
+ &r.pdb.ssbond.residues[1].chain_id,
808
+ &r.pdb.ssbond.residues[1].seq_num,
809
+ &r.pdb.ssbond.residues[1].insert_code,
810
+ r.pdb.ssbond.comment))
811
+ goto unknown;
812
+ break;
813
+
814
+ case PDB_SYMOP:
815
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.symop.row_num,
816
+ &r.pdb.symop.serial_num, &r.pdb.symop.s1,
817
+ &r.pdb.symop.s2, &r.pdb.symop.s3,
818
+ &r.pdb.symop.t))
819
+ goto unknown;
820
+ break;
821
+
822
+ case PDB_TER:
823
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.ter.serial_num,
824
+ r.pdb.ter.residue.name,
825
+ &r.pdb.ter.residue.chain_id,
826
+ &r.pdb.ter.residue.seq_num,
827
+ &r.pdb.ter.residue.insert_code))
828
+ goto unknown;
829
+ break;
830
+
831
+ case PDB_TRNSFM:
832
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.trnsfm.result_serial_num,
833
+ &r.pdb.trnsfm.apply_serial_num,
834
+ &r.pdb.trnsfm.source_serial_num))
835
+ goto unknown;
836
+ break;
837
+
838
+ case PDB_TURN:
839
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.turn.seq_num,
840
+ r.pdb.turn.id, r.pdb.turn.residues[0].name,
841
+ &r.pdb.turn.residues[0].chain_id,
842
+ &r.pdb.turn.residues[0].seq_num,
843
+ &r.pdb.turn.residues[0].insert_code,
844
+ r.pdb.turn.residues[1].name,
845
+ &r.pdb.turn.residues[1].chain_id,
846
+ &r.pdb.turn.residues[1].seq_num,
847
+ &r.pdb.turn.residues[1].insert_code,
848
+ r.pdb.turn.comment))
849
+ goto unknown;
850
+ break;
851
+
852
+ case PDB_TVECT:
853
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.tvect.serial_num,
854
+ &r.pdb.tvect.t1, &r.pdb.tvect.t2,
855
+ &r.pdb.tvect.t3, r.pdb.tvect.comment))
856
+ goto unknown;
857
+ break;
858
+
859
+ user:
860
+ r.record_type = PDB_USER;
861
+ fmt = pdb_record_format[r.record_type];
862
+ case PDB_USER:
863
+ if (0 > pdb_sscanf(buffer, fmt, r.pdb.user.subtype,
864
+ r.pdb.user.text))
865
+ goto unknown;
866
+ break;
867
+
868
+ case PDB_USER_PDBRUN:
869
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_pdbrun.version))
870
+ goto user;
871
+ pdb_pdbrun_version = r.pdb.user_pdbrun.version;
872
+ break;
873
+
874
+ case PDB_USER_EYEPOS:
875
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_eyepos.xyz[0],
876
+ &r.pdb.user_eyepos.xyz[1],
877
+ &r.pdb.user_eyepos.xyz[2]))
878
+ goto user;
879
+ break;
880
+
881
+ case PDB_USER_ATPOS:
882
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_atpos.xyz[0],
883
+ &r.pdb.user_atpos.xyz[1],
884
+ &r.pdb.user_atpos.xyz[2]))
885
+ goto user;
886
+ break;
887
+
888
+ case PDB_USER_WINDOW:
889
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_window.left,
890
+ &r.pdb.user_window.right,
891
+ &r.pdb.user_window.bottom,
892
+ &r.pdb.user_window.top,
893
+ &r.pdb.user_window.hither,
894
+ &r.pdb.user_window.yon))
895
+ goto user;
896
+ break;
897
+
898
+ case PDB_USER_FOCUS:
899
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_focus.focus))
900
+ goto user;
901
+ break;
902
+
903
+ case PDB_USER_VIEWPORT:
904
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_viewport.xmin,
905
+ &r.pdb.user_viewport.xmax,
906
+ &r.pdb.user_viewport.ymin,
907
+ &r.pdb.user_viewport.ymax))
908
+ goto user;
909
+ break;
910
+
911
+ case PDB_USER_BGCOLOR:
912
+ if (pdb_pdbrun_version < 6) {
913
+ if (0 > sscanf(buffer, fmt, &r.pdb.user_bgcolor.rgb[0],
914
+ &r.pdb.user_bgcolor.rgb[1],
915
+ &r.pdb.user_bgcolor.rgb[2]))
916
+ goto user;
917
+ } else if (0 > pdb_sscanf(buffer, fmt,
918
+ &r.pdb.user_bgcolor.rgb[0],
919
+ &r.pdb.user_bgcolor.rgb[1],
920
+ &r.pdb.user_bgcolor.rgb[2]))
921
+ goto user;
922
+ break;
923
+
924
+ case PDB_USER_ANGLE:
925
+ if (pdb_pdbrun_version < 6) {
926
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_angle.which,
927
+ &r.pdb.user_angle.atom0,
928
+ &r.pdb.user_angle.atom1,
929
+ &r.pdb.user_angle.atom2,
930
+ &r.pdb.user_angle.atom3,
931
+ &r.pdb.user_angle.angle))
932
+ goto user;
933
+ } else if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_angle.atom0,
934
+ &r.pdb.user_angle.atom1,
935
+ &r.pdb.user_angle.atom2,
936
+ &r.pdb.user_angle.atom3,
937
+ &r.pdb.user_angle.angle))
938
+ goto user;
939
+ break;
940
+
941
+ case PDB_USER_DISTANCE:
942
+ if (pdb_pdbrun_version < 6) {
943
+ if (0 > pdb_sscanf(buffer, fmt,
944
+ &r.pdb.user_distance.which,
945
+ &r.pdb.user_distance.atom0,
946
+ &r.pdb.user_distance.atom1,
947
+ &r.pdb.user_distance.distance))
948
+ goto user;
949
+ } else if (0 > pdb_sscanf(buffer, fmt,
950
+ &r.pdb.user_distance.atom0,
951
+ &r.pdb.user_distance.atom1,
952
+ &r.pdb.user_distance.distance))
953
+ goto user;
954
+ break;
955
+
956
+ case PDB_USER_FILE:
957
+ if (pdb_pdbrun_version < 6) {
958
+ if (0 > pdb_sscanf(buffer, fmt,
959
+ r.pdb.user_file.filename))
960
+ goto user;
961
+ } else if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_file.model,
962
+ r.pdb.user_file.filename))
963
+ goto user;
964
+ break;
965
+
966
+ case PDB_USER_MARKNAME:
967
+ if (0 > pdb_sscanf(buffer, fmt, r.pdb.user_markname.markname))
968
+ goto user;
969
+ break;
970
+
971
+ case PDB_USER_MARK:
972
+ if (0 > pdb_sscanf(buffer, fmt, r.pdb.user_mark.markname))
973
+ goto user;
974
+ break;
975
+
976
+ case PDB_USER_CNAME:
977
+ if (pdb_pdbrun_version < 6) {
978
+ if (0 > sscanf(buffer, fmt, r.pdb.user_cname.name,
979
+ &r.pdb.user_cname.rgb[0],
980
+ &r.pdb.user_cname.rgb[1],
981
+ &r.pdb.user_cname.rgb[2]))
982
+ goto user;
983
+ } else if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_cname.rgb[0],
984
+ &r.pdb.user_cname.rgb[1],
985
+ &r.pdb.user_cname.rgb[2],
986
+ r.pdb.user_cname.name))
987
+ goto user;
988
+ break;
989
+
990
+ case PDB_USER_COLOR:
991
+ if (pdb_pdbrun_version < 6) {
992
+ if (0 > sscanf(buffer, fmt, r.pdb.user_color.spec,
993
+ &r.pdb.user_color.rgb[0],
994
+ &r.pdb.user_color.rgb[1],
995
+ &r.pdb.user_color.rgb[2]))
996
+ goto user;
997
+ } else if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_color.rgb[0],
998
+ &r.pdb.user_color.rgb[1],
999
+ &r.pdb.user_color.rgb[2],
1000
+ r.pdb.user_color.spec))
1001
+ goto user;
1002
+ break;
1003
+
1004
+ case PDB_USER_RADIUS:
1005
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_radius.radius))
1006
+ goto user;
1007
+ break;
1008
+
1009
+ case PDB_USER_OBJECT:
1010
+ if (pdb_pdbrun_version < 6) {
1011
+ if (0 > pdb_sscanf(buffer, fmt,
1012
+ &r.pdb.user_object.model))
1013
+ goto user;
1014
+ }
1015
+ break;
1016
+
1017
+ case PDB_USER_ENDOBJ:
1018
+ if (pdb_pdbrun_version < 6) {
1019
+ if (0 > pdb_sscanf(buffer, fmt,
1020
+ &r.pdb.user_endobj.model))
1021
+ goto user;
1022
+ }
1023
+ break;
1024
+
1025
+ case PDB_USER_CHAIN:
1026
+ if (pdb_pdbrun_version < 6) {
1027
+ if (0 > sscanf(buffer, fmt, &r.pdb.user_chain.atom0,
1028
+ &r.pdb.user_chain.atom1))
1029
+ goto user;
1030
+ } else if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_chain.atom0,
1031
+ &r.pdb.user_chain.atom1))
1032
+ goto user;
1033
+ break;
1034
+
1035
+ case PDB_USER_GFX_BEGIN:
1036
+ if (0 > pdb_sscanf(buffer, fmt, r.pdb.user_gfx_begin.unknown))
1037
+ goto user;
1038
+ r.pdb.user_gfx_begin.primitive
1039
+ = pdb_gfx_type(r.pdb.user_gfx_begin.unknown);
1040
+ break;
1041
+
1042
+ case PDB_USER_GFX_END:
1043
+ break;
1044
+
1045
+ case PDB_USER_GFX_COLOR:
1046
+ if (pdb_pdbrun_version < 6) {
1047
+ if (0 > sscanf(buffer, fmt, r.pdb.user_gfx_color.spec,
1048
+ &r.pdb.user_gfx_color.rgb[0],
1049
+ &r.pdb.user_gfx_color.rgb[1],
1050
+ &r.pdb.user_gfx_color.rgb[2]))
1051
+ goto user;
1052
+ } else if (0 > pdb_sscanf(buffer, fmt,
1053
+ &r.pdb.user_gfx_color.rgb[0],
1054
+ &r.pdb.user_gfx_color.rgb[1],
1055
+ &r.pdb.user_gfx_color.rgb[2],
1056
+ r.pdb.user_gfx_color.spec))
1057
+ goto user;
1058
+ break;
1059
+
1060
+ case PDB_USER_GFX_NORMAL:
1061
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_normal.xyz[0],
1062
+ &r.pdb.user_gfx_normal.xyz[1],
1063
+ &r.pdb.user_gfx_normal.xyz[2]))
1064
+ goto user;
1065
+ break;
1066
+
1067
+ case PDB_USER_GFX_VERTEX:
1068
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_vertex.xyz[0],
1069
+ &r.pdb.user_gfx_vertex.xyz[1],
1070
+ &r.pdb.user_gfx_vertex.xyz[2]))
1071
+ goto user;
1072
+ break;
1073
+
1074
+ case PDB_USER_GFX_FONT:
1075
+ if (pdb_pdbrun_version < 6) {
1076
+ if (0 > sscanf(buffer, fmt, r.pdb.user_gfx_font.name,
1077
+ &r.pdb.user_gfx_font.size))
1078
+ goto user;
1079
+ } else if (0 > pdb_sscanf(buffer, fmt,
1080
+ &r.pdb.user_gfx_font.size,
1081
+ r.pdb.user_gfx_font.name))
1082
+ goto user;
1083
+ break;
1084
+
1085
+ case PDB_USER_GFX_TEXTPOS:
1086
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_textpos.xyz[0],
1087
+ &r.pdb.user_gfx_textpos.xyz[1],
1088
+ &r.pdb.user_gfx_textpos.xyz[2]))
1089
+ goto user;
1090
+ break;
1091
+
1092
+ case PDB_USER_GFX_LABEL:
1093
+ if (pdb_pdbrun_version < 6) {
1094
+ if (0 > sscanf(buffer, fmt,
1095
+ &r.pdb.user_gfx_label.xyz[0],
1096
+ &r.pdb.user_gfx_label.xyz[1],
1097
+ &r.pdb.user_gfx_label.xyz[2],
1098
+ r.pdb.user_gfx_label.text))
1099
+ goto user;
1100
+ } else if (0 > pdb_sscanf(buffer, fmt,
1101
+ r.pdb.user_gfx_label.text))
1102
+ goto user;
1103
+ /* TODO: process text? */
1104
+ break;
1105
+
1106
+ case PDB_USER_GFX_MOVE:
1107
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_move.xyz[0],
1108
+ &r.pdb.user_gfx_move.xyz[1],
1109
+ &r.pdb.user_gfx_move.xyz[2]))
1110
+ goto user;
1111
+ break;
1112
+
1113
+ case PDB_USER_GFX_DRAW:
1114
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_draw.xyz[0],
1115
+ &r.pdb.user_gfx_draw.xyz[1],
1116
+ &r.pdb.user_gfx_draw.xyz[2]))
1117
+ goto user;
1118
+ break;
1119
+
1120
+ case PDB_USER_GFX_MARKER:
1121
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_marker.xyz[0],
1122
+ &r.pdb.user_gfx_marker.xyz[1],
1123
+ &r.pdb.user_gfx_marker.xyz[2]))
1124
+ goto user;
1125
+ break;
1126
+
1127
+ case PDB_USER_GFX_POINT:
1128
+ if (0 > pdb_sscanf(buffer, fmt, &r.pdb.user_gfx_point.xyz[0],
1129
+ &r.pdb.user_gfx_point.xyz[1],
1130
+ &r.pdb.user_gfx_point.xyz[2]))
1131
+ goto user;
1132
+ break;
1133
+ }
1134
+
1135
+ return r;
1136
+ }
1137
+
1138
+ # ifdef vms
1139
+ pdb_read_dummy()
1140
+ {
1141
+ pdb_fmt_dummy();
1142
+ }
1143
+ # endif
dms/libpdb/pdb_sprntf.c ADDED
@@ -0,0 +1,511 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdb_sprntf.c,v 2.4 1994/04/15 22:34:24 gregc Exp $
18
+ */
19
+
20
+ /* LINTLIBRARY */
21
+
22
+ # include <stdio.h>
23
+ # include <ctype.h>
24
+ # include <string.h>
25
+ # ifdef __STDC__
26
+ # include <stdarg.h>
27
+ # else
28
+ # include <varargs.h>
29
+ # endif
30
+
31
+ static char scratch[BUFSIZ];
32
+
33
+ # define OVERFLOW_CHAR '*'
34
+
35
+ # ifdef __STDC__
36
+ static char *outint(int, int, int, char, char, int, char *, char);
37
+ static char *outunsigned(unsigned int, int, char, int, char *);
38
+ static char *outstr(char *, int, int, char, int, char *);
39
+ static char *outfloat(double, int, int, char, int, char *);
40
+ static char *outexp(double, int, int, char, int, char *);
41
+ static char *e_out(int, char *);
42
+ # else
43
+ static char *outint(), *outunsigned(), *outstr(), *outfloat(), *outexp();
44
+ static char *e_out();
45
+ # endif
46
+
47
+ # ifdef __STDC__
48
+ void
49
+ pdb_sprintf(char *outbuf, const char *fmt, ...)
50
+ # else
51
+ /*VARARGS2*/
52
+ void
53
+ pdb_sprintf(outbuf, fmt, va_alist)
54
+ char *outbuf;
55
+ char *fmt;
56
+ va_dcl
57
+ # endif
58
+ {
59
+ va_list argv;
60
+ char *p;
61
+ const char *f;
62
+ int field1, field2;
63
+ char c, fill_char;
64
+ int inum;
65
+ unsigned unum;
66
+ double fnum;
67
+ int left_justify;
68
+
69
+ # ifdef __STDC__
70
+ va_start(argv, fmt);
71
+ # else
72
+ va_start(argv);
73
+ # endif
74
+ f = fmt;
75
+ p = outbuf;
76
+ while (*f) {
77
+ if (*f == '%') {
78
+ f++;
79
+ if (*f == '-')
80
+ left_justify = 1, f++;
81
+ else
82
+ left_justify = 0;
83
+
84
+ if (*f == '0')
85
+ fill_char = '0', f++;
86
+ else
87
+ fill_char = ' ';
88
+
89
+ if (isdigit(*f)) {
90
+ field1 = *f++ - '0';
91
+ while (isdigit(*f))
92
+ field1 = field1 * 10 + *f++ - '0';
93
+ }
94
+ else
95
+ field1 = -1;
96
+
97
+ if (*f == '.') {
98
+ f++;
99
+ field2 = 0;
100
+ while (isdigit(*f))
101
+ field2 = field2 * 10 + *f++ - '0';
102
+ }
103
+ else
104
+ field2 = -1;
105
+
106
+ if (*f == 'l' || *f == 'h')
107
+ f++;
108
+
109
+ while (isspace(*f))
110
+ f++;
111
+ switch (*f) {
112
+ case 'c':
113
+ c = (char) va_arg(argv, int);
114
+ if (c == '\0')
115
+ c = ' ';
116
+ if (left_justify)
117
+ *p++ = c;
118
+ while (--field1 > 0)
119
+ *p++ = fill_char;
120
+ if (!left_justify)
121
+ *p++ = c;
122
+ break;
123
+ case 'd':
124
+ case 'D':
125
+ inum = va_arg(argv, int);
126
+ p = outint(inum, field1, 10, fill_char, 'a',
127
+ left_justify, p, (*f == 'D') ? ' ':'0');
128
+ break;
129
+ case 'e':
130
+ fnum = va_arg(argv, double);
131
+ if (field2 < 0)
132
+ field2 = 6;
133
+ p = outexp(fnum, field1, field2, fill_char,
134
+ left_justify, p);
135
+ break;
136
+ case 'f':
137
+ fnum = va_arg(argv, double);
138
+ if (field2 < 0)
139
+ field2 = 6;
140
+ p = outfloat(fnum, field1, field2, fill_char,
141
+ left_justify, p);
142
+ break;
143
+ case 'o':
144
+ inum = va_arg(argv, int);
145
+ p = outint(inum, field1, 8, fill_char, 'a',
146
+ left_justify, p, '0');
147
+ break;
148
+ case 's':
149
+ p = outstr(va_arg(argv, char *), field1, field2,
150
+ fill_char, left_justify, p);
151
+ break;
152
+ case 'u':
153
+ unum = va_arg(argv, unsigned);
154
+ p = outunsigned(unum, field1, fill_char,
155
+ left_justify, p);
156
+ break;
157
+ case 'x':
158
+ inum = va_arg(argv, int);
159
+ p = outint(inum, field1, 16, fill_char, 'a',
160
+ left_justify, p, '0');
161
+ break;
162
+ case 'X':
163
+ inum = va_arg(argv, int);
164
+ p = outint(inum, field1, 16, fill_char, 'A',
165
+ left_justify, p, '0');
166
+ break;
167
+ default:
168
+ if (left_justify)
169
+ *p++ = *f;
170
+ while (--field1 > 0)
171
+ *p++ = fill_char;
172
+ if (!left_justify)
173
+ *p++ = *f;
174
+ break;
175
+ }
176
+ f++;
177
+ }
178
+ else if (*f == '\\') { /* Special character */
179
+ switch (*++f) {
180
+ case 'n':
181
+ *p++ = '\n';
182
+ break;
183
+ case 'r':
184
+ *p++ = '\r';
185
+ break;
186
+ case 'b':
187
+ *p++ = '\b';
188
+ break;
189
+ case 't':
190
+ *p++ = '\t';
191
+ break;
192
+ case 'f':
193
+ *p++ = '\f';
194
+ break;
195
+ case '0': case '1': case '2': case '3':
196
+ case '4': case '5': case '6': case '7':
197
+ inum = *f++ - '0';
198
+ if (*f >= '0' && *f <= '7') {
199
+ inum = inum * 8 + *f++ - '0';
200
+ if (*f >= '0' && *f <= '7')
201
+ inum = inum * 8 + *f++ - '0';
202
+ }
203
+ f--;
204
+ *p++ = (char) inum;
205
+ break;
206
+ default:
207
+ *p++ = *f;
208
+ }
209
+ f++;
210
+ }
211
+ else /* Normal character */
212
+ *p++ = *f++;
213
+ }
214
+ *p = '\0';
215
+ va_end(argv);
216
+ }
217
+
218
+ static char *
219
+ # ifdef __STDC__
220
+ e_out(int width, char *where)
221
+ # else
222
+ e_out(width, where)
223
+ int width;
224
+ char *where;
225
+ # endif
226
+ {
227
+ while (width-- > 0)
228
+ *where++ = OVERFLOW_CHAR;
229
+ return where;
230
+ }
231
+
232
+ static char *
233
+ # ifdef __STDC__
234
+ outint(int value, int width, int radix, char fill_char, char hex,
235
+ int left_justify, char *p, char zero)
236
+ # else
237
+ outint(value, width, radix, fill_char, hex, left_justify, p, zero)
238
+ int value, width;
239
+ int radix;
240
+ char fill_char;
241
+ char hex;
242
+ int left_justify;
243
+ char *p;
244
+ char zero;
245
+ # endif
246
+ {
247
+ char *s;
248
+ int n;
249
+ int negative;
250
+
251
+ if (value < 0)
252
+ negative = 1, value = -value, width--;
253
+ else
254
+ negative = 0;
255
+ s = scratch;
256
+ if (value)
257
+ do {
258
+ n = value % radix;
259
+ *s++ = n < 10 ? '0' + n : hex + n - 10;
260
+ value /= radix;
261
+ } while (value);
262
+ else
263
+ *s++ = zero;
264
+ n = s - scratch;
265
+ if (width != -1 && n > width)
266
+ return e_out(width + negative, p);
267
+
268
+ if (negative && fill_char == '0')
269
+ *p++ = '-';
270
+ if (!left_justify)
271
+ while (width-- > n)
272
+ *p++ = fill_char;
273
+ if (negative && fill_char == ' ')
274
+ *p++ = '-';
275
+ while (--s >= scratch)
276
+ *p++ = *s;
277
+ if (left_justify)
278
+ while (width-- > n)
279
+ *p++ = fill_char;
280
+ return p;
281
+ }
282
+
283
+ static char *
284
+ # ifdef __STDC__
285
+ outunsigned(unsigned int value, int width, char fill_char, int left_justify,
286
+ char *p)
287
+ # else
288
+ outunsigned(value, width, fill_char, left_justify, p)
289
+ unsigned int value;
290
+ int width;
291
+ char fill_char;
292
+ int left_justify;
293
+ char *p;
294
+ # endif
295
+ {
296
+ char *s;
297
+ int n;
298
+
299
+ s = scratch;
300
+ while (value) {
301
+ *s++ = value % 10 + '0';
302
+ value /= 10;
303
+ }
304
+ n = s - scratch;
305
+ if (n == 0)
306
+ *s++ = '0', n = 1;
307
+ if (width != -1 && n > width)
308
+ return e_out(width, p);
309
+
310
+ if (!left_justify)
311
+ while (width-- > n)
312
+ *p++ = fill_char;
313
+ while (--s >= scratch)
314
+ *p++ = *s;
315
+ if (left_justify)
316
+ while (width-- > n)
317
+ *p++ = fill_char;
318
+ return p;
319
+ }
320
+
321
+ static char *
322
+ # ifdef __STDC__
323
+ outstr(char *s, int width, int maxstr, char fill_char, int left_justify, char *p)
324
+ # else
325
+ outstr(s, width, maxstr, fill_char, left_justify, p)
326
+ char *s;
327
+ int width;
328
+ int maxstr;
329
+ char fill_char;
330
+ int left_justify;
331
+ char *p;
332
+ # endif
333
+ {
334
+ int len;
335
+
336
+ len = strlen(s);
337
+ if (maxstr >= 0 && len > maxstr)
338
+ len = maxstr;
339
+ if (width != -1 && len > width)
340
+ return e_out(width, p);
341
+
342
+ if (!left_justify)
343
+ while (width-- > len)
344
+ *p++ = fill_char;
345
+ else
346
+ width -= len;
347
+ while (len--)
348
+ *p++ = *s++;
349
+ if (left_justify)
350
+ while (width-- > 0)
351
+ *p++ = fill_char;
352
+ return p;
353
+ }
354
+
355
+ static char *
356
+ # ifdef __STDC__
357
+ outfloat(double value, int width, int nplace, char fill_char, int left_justify,
358
+ char *p)
359
+ # else
360
+ outfloat(value, width, nplace, fill_char, left_justify, p)
361
+ double value;
362
+ int width, nplace;
363
+ char fill_char;
364
+ int left_justify;
365
+ char *p;
366
+ # endif
367
+ {
368
+ int i, intval;
369
+ char *place, *to, *from;
370
+ int negative;
371
+
372
+ negative = value < 0.0 ? 1 : 0;
373
+
374
+ if (negative)
375
+ value = -value;
376
+
377
+ for (i = 0; i < nplace; i++)
378
+ value *= 10.0;
379
+
380
+ intval = value + 0.5;
381
+
382
+ if (width == -1)
383
+ width = nplace + 4; /* TODO: fix */
384
+ else if (nplace + (nplace == 0 ? 1 : 2) > width)
385
+ return e_out(width, p);
386
+
387
+ for (place = p + width - 1; place >= p + width - nplace; place--) {
388
+ *place = '0' + intval % 10;
389
+ intval /= 10;
390
+ }
391
+
392
+ if (nplace > 0)
393
+ *place-- = '.';
394
+
395
+ if (intval == 0)
396
+ *place-- = '0';
397
+
398
+ for (; place >= p; place--) {
399
+ if (intval == 0)
400
+ break;
401
+ else {
402
+ *place = '0' + intval % 10;
403
+ intval /= 10;
404
+ }
405
+ }
406
+
407
+ if (intval != 0)
408
+ return e_out(width, p);
409
+
410
+ if (place < p && negative)
411
+ return e_out(width, p);
412
+
413
+ if (left_justify) {
414
+ for (from = place + 1, to = (negative ? p + 1 : p);
415
+ from < p + width; from++, to++)
416
+ *to = *from;
417
+ for (; to < p + width; to++)
418
+ *to = fill_char;
419
+ if (negative)
420
+ *p = '-';
421
+ } else {
422
+ for (to = place; to >= p; to--)
423
+ *to = fill_char;
424
+ if (negative)
425
+ if (fill_char == ' ')
426
+ *place = '-';
427
+ else
428
+ *p = '-';
429
+ }
430
+
431
+ return p + width;
432
+ }
433
+
434
+ static char *
435
+ # ifdef __STDC__
436
+ outexp(double value, int width, int nplace, char fill_char, int left_justify,
437
+ char *p)
438
+ # else
439
+ outexp(value, width, nplace, fill_char, left_justify, p)
440
+ double value;
441
+ int width, nplace;
442
+ char *p;
443
+ char fill_char;
444
+ int left_justify;
445
+ # endif
446
+ {
447
+ int n;
448
+ char *s;
449
+ int negative;
450
+ double fraction;
451
+
452
+ if (value < 0)
453
+ negative = 1, value = -value, width--;
454
+ else
455
+ negative = 0;
456
+
457
+ n = 0;
458
+ while (value > 10)
459
+ n++, value /= 10;
460
+ if (value)
461
+ while (value < 1)
462
+ n--, value *= 10;
463
+
464
+ s = scratch;
465
+ if (n < 0) {
466
+ n = -n;
467
+ *s++ = n % 10 + '0';
468
+ *s++ = n / 10 + '0';
469
+ *s++ = '-';
470
+ }
471
+ else {
472
+ *s++ = n % 10 + '0';
473
+ *s++ = n / 10 + '0';
474
+ *s++ = '+';
475
+ }
476
+ *s = 'e';
477
+
478
+ s = scratch + nplace + 4; /* 4 == strlen("e+00") */
479
+ fraction = value - (int) value;
480
+ for (n = 0; n < nplace; n++) {
481
+ fraction *= 10.0;
482
+ *--s = '0' + (int) fraction;
483
+ fraction -= (int) fraction;
484
+ }
485
+
486
+ s = scratch + nplace + 4;
487
+ if (nplace)
488
+ *s++ = '.';
489
+ n = (int) value;
490
+ if (n)
491
+ *s++ = n % 10 + '0';
492
+ else
493
+ *s++ = '0';
494
+ n = s - scratch;
495
+ if (width != -1 && n > width)
496
+ return e_out(width + negative, p);
497
+
498
+ if (negative && fill_char == '0')
499
+ *p++ = '-';
500
+ if (!left_justify)
501
+ while (width-- > n)
502
+ *p++ = fill_char;
503
+ if (negative && fill_char == ' ')
504
+ *p++ = '-';
505
+ while (--s >= scratch)
506
+ *p++ = *s;
507
+ if (left_justify)
508
+ while (width-- > n)
509
+ *p++ = fill_char;
510
+ return p;
511
+ }
dms/libpdb/pdb_sscanf.c ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdb_sscanf.c,v 2.8 1994/04/15 22:34:24 gregc Exp $
18
+ */
19
+
20
+ /* LINTLIBRARY */
21
+
22
+ # include <stdio.h>
23
+ # include <ctype.h>
24
+ # ifdef __STDC__
25
+ # include <stdarg.h>
26
+ # include <stdlib.h>
27
+ # else
28
+ # include <varargs.h>
29
+
30
+ extern int atoi();
31
+ extern double atof();
32
+ # endif
33
+
34
+ /*
35
+ * pdb_sscanf performs similarly to sscanf, execept that fields are of
36
+ * fixed length and a complete line is always consumed. The field
37
+ * width defaults to one. If the line is shorter than expected then
38
+ * the default is returned.
39
+ *
40
+ * d get an integer. Default: 0.
41
+ * f get a floating point number (C double). Default: 0.0.
42
+ * (space) ignore characters within field
43
+ * s get a C string, leading and trailing spaces are
44
+ * stripped; the field width is used as a limit on
45
+ * the string length, the null character is appended
46
+ * to the end of the string. Default: empty string.
47
+ * c get a character(s); no stripping of spaces, nor is
48
+ * a null character appended. Default: space(s).
49
+ */
50
+
51
+ # define MAXFIELDSIZE 64
52
+
53
+ int
54
+ # ifdef __STDC__
55
+ pdb_sscanf(const char *buffer, const char *fmt, ...)
56
+ # else
57
+ /*VARARGS2*/
58
+ pdb_sscanf(buffer, fmt, va_alist)
59
+ char *buffer;
60
+ char *fmt;
61
+ va_dcl
62
+ # endif
63
+ {
64
+ va_list ap;
65
+ int i, field_width;
66
+ int nmatch;
67
+ char *s, *t;
68
+ char tmp[MAXFIELDSIZE];
69
+
70
+ # ifdef __STDC__
71
+ va_start(ap, fmt);
72
+ # else
73
+ va_start(ap);
74
+ # endif
75
+ nmatch = 0;
76
+ for (; *fmt != '\0'; fmt++) {
77
+ if (*fmt != '%') {
78
+ if (*buffer == *fmt)
79
+ buffer++;
80
+ else if (*buffer != '\0' && *buffer != '\n')
81
+ return -1;
82
+ continue;
83
+ }
84
+
85
+ /* calculate field_width */
86
+ field_width = 0;
87
+ for (++fmt; isdigit(*fmt); fmt++)
88
+ field_width = field_width * 10 + *fmt - '0';
89
+ if (field_width == 0)
90
+ field_width = 1; /* default */
91
+ if (*buffer != '\0' && *buffer != '\n')
92
+ nmatch++;
93
+
94
+ switch (*fmt) {
95
+
96
+ case 'd': /* integer */
97
+ /* if we've already seen the end of the buffer, don't
98
+ try to get anymore characters */
99
+ if (*buffer == '\0' || *buffer == '\n') {
100
+ *(va_arg(ap, int *)) = 0;
101
+ break;
102
+ }
103
+
104
+ s = tmp;
105
+ for (i = 0; i < field_width; i++) {
106
+ if (*buffer == '\0' || *buffer == '\n')
107
+ break;
108
+ *s++ = *buffer++;
109
+ }
110
+ *s = '\0';
111
+ #ifndef __STDC__
112
+ *(va_arg(ap, int *)) = atoi(tmp);
113
+ #else
114
+ /* remove trailing spaces */
115
+ while (s > tmp && isspace(*(s - 1)))
116
+ *--s = '\0';
117
+ *(va_arg(ap, int *)) = (int) strtol(tmp, &t, 10);
118
+ if (t != s)
119
+ return -1;
120
+ #endif
121
+ break;
122
+
123
+ case 'f': /* floating point */
124
+ /* if we've already seen the end of the buffer, don't
125
+ try to get anymore characters */
126
+ if (*buffer == '\0' || *buffer == '\n') {
127
+ *(va_arg(ap, double *)) = 0.0;
128
+ break;
129
+ }
130
+
131
+ s = tmp;
132
+ for (i = 0; i < field_width; i++) {
133
+ if (*buffer == '\0' || *buffer == '\n')
134
+ break;
135
+ *s++ = *buffer++;
136
+ }
137
+ *s = '\0';
138
+ #ifndef __STDC__
139
+ *(va_arg(ap, double *)) = atof(tmp);
140
+ #else
141
+ /* remove trailing spaces */
142
+ while (s > tmp && isspace(*(s - 1)))
143
+ *--s = '\0';
144
+ *(va_arg(ap, double *)) = strtod(tmp, &t);
145
+ if (t != s)
146
+ return -1;
147
+ #endif
148
+ break;
149
+
150
+ case 's': /* string */
151
+ /* if we've already seen the end of the buffer, don't
152
+ try to get anymore characters */
153
+ if (*buffer == '\0' || *buffer == '\n') {
154
+ *(va_arg(ap, char *)) = '\0';
155
+ break;
156
+ }
157
+
158
+ s = t = va_arg(ap, char *);
159
+ for (i = 0; i < field_width; i++) {
160
+ if (*buffer == '\0' || *buffer == '\n')
161
+ break;
162
+ *s++ = *buffer++;
163
+ }
164
+ *s = '\0';
165
+ /* remove trailing spaces */
166
+ while (s > t && isspace(*--s))
167
+ *s = '\0';
168
+ break;
169
+
170
+ case 'c': /* character(s) */
171
+ s = va_arg(ap, char *);
172
+ for (i = 0; i < field_width; i++)
173
+ s[i] = ' '; /* default */
174
+
175
+ /* if we've already seen the end of the buffer, don't
176
+ try to get anymore characters */
177
+ if (*buffer == '\0' || *buffer == '\n')
178
+ break;
179
+
180
+ for (i = 0; i < field_width; i++) {
181
+ if (*buffer == '\0' || *buffer == '\n')
182
+ break;
183
+ *s++ = *buffer++;
184
+ }
185
+ break;
186
+
187
+ case ' ': /* space (ignore) */
188
+ /* if we've already seen the end of the buffer, don't
189
+ try to get anymore characters */
190
+ if (*buffer == '\0' || *buffer == '\n')
191
+ break;
192
+
193
+ for (i = 0; i < field_width; i++, buffer++)
194
+ if (*buffer == '\0' || *buffer == '\n')
195
+ break;
196
+ break;
197
+
198
+ default:
199
+ fprintf(stderr, "bad format '%c' in pdb_sscanf\n",
200
+ *fmt);
201
+ va_end(ap);
202
+ return -1;
203
+ }
204
+ }
205
+ va_end(ap);
206
+ return nmatch;
207
+ }
dms/libpdb/pdb_write.c ADDED
@@ -0,0 +1,639 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1989 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdb_write.c,v 2.11 1995/01/20 01:20:36 gregc Exp $
18
+ *
19
+ * subroutine for writing PDB format files
20
+ *
21
+ */
22
+
23
+ /* LINTLIBRARY */
24
+
25
+ # include <stdio.h>
26
+ # include <ctype.h>
27
+ # include "pdb_int.h"
28
+
29
+ static const char * const pdb_record_format[PDB_NUM_R] = {
30
+ #include "write_format.i"
31
+ };
32
+
33
+ static char const * const pdbrun5[] = {
34
+ #include "pdbrun5_write.i"
35
+ };
36
+
37
+ static char const * const pdbrun6[] = {
38
+ #include "pdbrun6_write.i"
39
+ };
40
+
41
+ /*
42
+ * for each pdb record type there is a format reading in the
43
+ * record values and for printing them out.
44
+ *
45
+ * The actual format of a line written, is the print format
46
+ * followed by blank padding to 72 characters, followed by
47
+ * 8 characters of file and line information.
48
+ */
49
+
50
+ void
51
+ # ifdef __STDC__
52
+ pdb_write_record(FILE *f, const pdb_record *r, const char *name, int line_num)
53
+ # else
54
+ pdb_write_record(f, r, name, line_num)
55
+ FILE *f;
56
+ pdb_record *r;
57
+ char *name; /* if NULL, don't print */
58
+ int line_num; /* if name == NULL, don't print */
59
+ # endif
60
+ {
61
+ char buffer[PDB_BUFSIZ];
62
+
63
+ pdb_write_string(buffer, r);
64
+ if (name == NULL)
65
+ (void) fprintf(f, "%s\n", buffer);
66
+ else if (line_num >= 10000)
67
+ (void) fprintf(f, "%-72.72s%-4.4s%04d\n", buffer, name,
68
+ line_num % 10000);
69
+ else
70
+ (void) fprintf(f, "%-72.72s%-4.4s%4d\n", buffer, name,
71
+ line_num);
72
+ }
73
+
74
+ void
75
+ # ifdef __STDC__
76
+ pdb_write_string(char *buffer, const pdb_record *r)
77
+ # else
78
+ pdb_write_string(buffer, r)
79
+ char *buffer;
80
+ pdb_record *r;
81
+ # endif
82
+ {
83
+ const char *fmt;
84
+ const struct pdb_sheet *sh;
85
+ const pdb_residue *shr0, *shr1, *sha0, *sha1;
86
+ char *s, *t;
87
+
88
+ /* convert C structure to pdb record */
89
+
90
+
91
+ if (r->record_type < PDB_USER_PDBRUN)
92
+ fmt = pdb_record_format[r->record_type];
93
+ else if (pdb_pdbrun_version < 6)
94
+ fmt = pdbrun5[r->record_type - PDB_USER_PDBRUN];
95
+ else
96
+ fmt = pdbrun6[r->record_type - PDB_USER_PDBRUN];
97
+ switch (r->record_type) {
98
+
99
+ case PDB_UNKNOWN:
100
+ pdb_sprintf(buffer, fmt, r->pdb.unknown.junk);
101
+ break;
102
+
103
+ case PDB_AGGRGT:
104
+ pdb_sprintf(buffer, fmt, r->pdb.aggrgt.serial_num,
105
+ r->pdb.aggrgt.num_components,
106
+ r->pdb.aggrgt.cmpont_serial_nums[0],
107
+ r->pdb.aggrgt.cmpont_serial_nums[1],
108
+ r->pdb.aggrgt.cmpont_serial_nums[2],
109
+ r->pdb.aggrgt.cmpont_serial_nums[3],
110
+ r->pdb.aggrgt.cmpont_serial_nums[4],
111
+ r->pdb.aggrgt.cmpont_serial_nums[5],
112
+ r->pdb.aggrgt.cmpont_serial_nums[6],
113
+ r->pdb.aggrgt.cmpont_serial_nums[7],
114
+ r->pdb.aggrgt.cmpont_serial_nums[8],
115
+ r->pdb.aggrgt.cmpont_serial_nums[9],
116
+ r->pdb.aggrgt.cmpont_serial_nums[10],
117
+ r->pdb.aggrgt.cmpont_serial_nums[11],
118
+ r->pdb.aggrgt.cmpont_serial_nums[12],
119
+ r->pdb.aggrgt.cmpont_serial_nums[13]);
120
+ break;
121
+
122
+ case PDB_ANISOU:
123
+ case PDB_SIGUIJ:
124
+ pdb_sprintf(buffer, fmt, r->pdb.anisou.serial_num,
125
+ r->pdb.anisou.name, r->pdb.anisou.alt_loc,
126
+ r->pdb.anisou.residue.name,
127
+ r->pdb.anisou.residue.chain_id,
128
+ r->pdb.anisou.residue.seq_num,
129
+ r->pdb.anisou.residue.insert_code,
130
+ r->pdb.anisou.u[0], r->pdb.anisou.u[1],
131
+ r->pdb.anisou.u[2], r->pdb.anisou.u[3],
132
+ r->pdb.anisou.u[4], r->pdb.anisou.u[5]);
133
+ break;
134
+
135
+ case PDB_ATOM:
136
+ case PDB_HETATM:
137
+ case PDB_SIGATM:
138
+ pdb_sprintf(buffer, fmt, r->pdb.atom.serial_num,
139
+ r->pdb.atom.name, r->pdb.atom.alt_loc,
140
+ r->pdb.atom.residue.name,
141
+ r->pdb.atom.residue.chain_id,
142
+ r->pdb.atom.residue.seq_num,
143
+ r->pdb.atom.residue.insert_code,
144
+ r->pdb.atom.x, r->pdb.atom.y, r->pdb.atom.z,
145
+ r->pdb.atom.occupancy, r->pdb.atom.temp_factor,
146
+ r->pdb.atom.ftnote_num);
147
+ break;
148
+
149
+ case PDB_AUTHOR:
150
+ case PDB_COMPND:
151
+ case PDB_JRNL:
152
+ case PDB_SOURCE:
153
+ case PDB_EXPDTA:
154
+ pdb_sprintf(buffer, fmt, r->pdb.author.continuation,
155
+ r->pdb.author.data);
156
+ break;
157
+
158
+ case PDB_CONECT:
159
+ pdb_sprintf(buffer, fmt, r->pdb.conect.serial_num,
160
+ r->pdb.conect.covalent[0], r->pdb.conect.covalent[1],
161
+ r->pdb.conect.covalent[2], r->pdb.conect.covalent[3],
162
+ r->pdb.conect.bonds[0].hydrogen[0],
163
+ r->pdb.conect.bonds[0].hydrogen[1],
164
+ r->pdb.conect.bonds[0].salt,
165
+ r->pdb.conect.bonds[1].hydrogen[0],
166
+ r->pdb.conect.bonds[1].hydrogen[1],
167
+ r->pdb.conect.bonds[1].salt);
168
+ break;
169
+
170
+ case PDB_CMPONT:
171
+ pdb_sprintf(buffer, fmt, r->pdb.cmpont.seq_num,
172
+ r->pdb.cmpont.residues[0].name,
173
+ r->pdb.cmpont.residues[0].chain_id,
174
+ r->pdb.cmpont.residues[0].seq_num,
175
+ r->pdb.cmpont.residues[0].insert_code,
176
+ r->pdb.cmpont.residues[1].name,
177
+ r->pdb.cmpont.residues[1].chain_id,
178
+ r->pdb.cmpont.residues[1].seq_num,
179
+ r->pdb.cmpont.residues[1].insert_code);
180
+ break;
181
+
182
+ case PDB_CRYST1:
183
+ pdb_sprintf(buffer, fmt, r->pdb.cryst1.a, r->pdb.cryst1.b,
184
+ r->pdb.cryst1.c, r->pdb.cryst1.alpha,
185
+ r->pdb.cryst1.beta, r->pdb.cryst1.gamma,
186
+ r->pdb.cryst1.space_grp, r->pdb.cryst1.z);
187
+ break;
188
+
189
+ case PDB_END:
190
+ case PDB_ENDMDL:
191
+ pdb_sprintf(buffer, fmt);
192
+ break;
193
+
194
+ case PDB_FORMUL:
195
+ pdb_sprintf(buffer, fmt, r->pdb.formul.component,
196
+ r->pdb.formul.het_id, r->pdb.formul.continuation,
197
+ r->pdb.formul.exclude, r->pdb.formul.formula);
198
+ break;
199
+
200
+ case PDB_FTNOTE:
201
+ case PDB_REMARK:
202
+ case PDB_SYMDES:
203
+ case PDB_MTXDES:
204
+ case PDB_CMPDES:
205
+ case PDB_AGRDES:
206
+ pdb_sprintf(buffer, fmt, r->pdb.ftnote.num, r->pdb.ftnote.text);
207
+ break;
208
+
209
+ case PDB_HEADER:
210
+ pdb_sprintf(buffer, fmt, r->pdb.header.class,
211
+ r->pdb.header.date, r->pdb.header.type,
212
+ r->pdb.header.id);
213
+ break;
214
+
215
+ case PDB_HELIX:
216
+ pdb_sprintf(buffer, fmt, r->pdb.helix.serial_num,
217
+ r->pdb.helix.id,
218
+ r->pdb.helix.residues[0].name,
219
+ r->pdb.helix.residues[0].chain_id,
220
+ r->pdb.helix.residues[0].seq_num,
221
+ r->pdb.helix.residues[0].insert_code,
222
+ r->pdb.helix.residues[1].name,
223
+ r->pdb.helix.residues[1].chain_id,
224
+ r->pdb.helix.residues[1].seq_num,
225
+ r->pdb.helix.residues[1].insert_code,
226
+ r->pdb.helix.class, r->pdb.helix.comment);
227
+ break;
228
+
229
+ case PDB_HET:
230
+ pdb_sprintf(buffer, fmt, r->pdb.het.het_grp.name,
231
+ r->pdb.het.het_grp.chain_id, r->pdb.het.het_grp.seq_num,
232
+ r->pdb.het.het_grp.insert_code, r->pdb.het.num_atoms,
233
+ r->pdb.het.text);
234
+ break;
235
+
236
+ case PDB_MASTER:
237
+ pdb_sprintf(buffer, fmt, r->pdb.master.num_remark,
238
+ r->pdb.master.num_ftnote, r->pdb.master.num_het,
239
+ r->pdb.master.num_helix, r->pdb.master.num_sheet,
240
+ r->pdb.master.num_turn, r->pdb.master.num_site,
241
+ r->pdb.master.num_transform,
242
+ r->pdb.master.num_coordinate, r->pdb.master.num_ter,
243
+ r->pdb.master.num_conect, r->pdb.master.num_seqres);
244
+ break;
245
+
246
+ case PDB_MODEL:
247
+ pdb_sprintf(buffer, fmt, r->pdb.model.num);
248
+ break;
249
+
250
+ case PDB_MTRIX:
251
+ pdb_sprintf(buffer, fmt, r->pdb.mtrix.row_num,
252
+ r->pdb.mtrix.serial_num, r->pdb.mtrix.m1,
253
+ r->pdb.mtrix.m2, r->pdb.mtrix.m3, r->pdb.mtrix.v,
254
+ r->pdb.mtrix.given);
255
+ break;
256
+
257
+ case PDB_OBSLTE:
258
+ pdb_sprintf(buffer, fmt, r->pdb.obslte.continuation,
259
+ r->pdb.obslte.date, r->pdb.obslte.old_id,
260
+ r->pdb.obslte.id_map[0], r->pdb.obslte.id_map[1],
261
+ r->pdb.obslte.id_map[2], r->pdb.obslte.id_map[3],
262
+ r->pdb.obslte.id_map[4], r->pdb.obslte.id_map[2],
263
+ r->pdb.obslte.id_map[6], r->pdb.obslte.id_map[7]);
264
+ break;
265
+
266
+ case PDB_ORIGX:
267
+ pdb_sprintf(buffer, fmt, r->pdb.origx.row_num, r->pdb.origx.o1,
268
+ r->pdb.origx.o2, r->pdb.origx.o3, r->pdb.origx.t);
269
+ break;
270
+
271
+ case PDB_REVDAT:
272
+ pdb_sprintf(buffer, fmt, r->pdb.revdat.modification,
273
+ r->pdb.revdat.continuation, r->pdb.revdat.date,
274
+ r->pdb.revdat.id, r->pdb.revdat.mod_type,
275
+ r->pdb.revdat.corrections);
276
+ break;
277
+
278
+ case PDB_SCALE:
279
+ pdb_sprintf(buffer, fmt, r->pdb.scale.row_num, r->pdb.scale.s1,
280
+ r->pdb.scale.s2, r->pdb.scale.s3, r->pdb.scale.u);
281
+ break;
282
+
283
+ case PDB_SEQRES:
284
+ pdb_sprintf(buffer, fmt, r->pdb.seqres.serial_num,
285
+ r->pdb.seqres.chain_id, r->pdb.seqres.count,
286
+ r->pdb.seqres.names[0], r->pdb.seqres.names[1],
287
+ r->pdb.seqres.names[2], r->pdb.seqres.names[3],
288
+ r->pdb.seqres.names[4], r->pdb.seqres.names[5],
289
+ r->pdb.seqres.names[6], r->pdb.seqres.names[7],
290
+ r->pdb.seqres.names[8], r->pdb.seqres.names[9],
291
+ r->pdb.seqres.names[10], r->pdb.seqres.names[11],
292
+ r->pdb.seqres.names[12]);
293
+ break;
294
+
295
+ case PDB_SHEET:
296
+ sh = &r->pdb.sheet;
297
+ shr0 = &sh->residues[0];
298
+ shr1 = &sh->residues[1];
299
+ sha0 = &sh->atoms[0].residue;
300
+ sha1 = &sh->atoms[1].residue;
301
+ pdb_sprintf(buffer, fmt, sh->strand_num,
302
+ sh->id, sh->count,
303
+ shr0->name, shr0->chain_id, shr0->seq_num,
304
+ shr0->insert_code,
305
+ shr1->name, shr1->chain_id, shr1->seq_num,
306
+ shr1->insert_code,
307
+ sh->sense,
308
+ sh->atoms[0].name,
309
+ sha0->name, sha0->chain_id, sha0->seq_num,
310
+ sha0->insert_code,
311
+ sh->atoms[1].name,
312
+ sha1->name, sha1->chain_id, sha1->seq_num,
313
+ sha1->insert_code);
314
+ break;
315
+
316
+ case PDB_SITE:
317
+ shr0 = &r->pdb.site.residues[0];
318
+ shr1 = &r->pdb.site.residues[1];
319
+ sha0 = &r->pdb.site.residues[2];
320
+ sha1 = &r->pdb.site.residues[3];
321
+ pdb_sprintf(buffer, fmt, r->pdb.site.seq_num,
322
+ r->pdb.site.id, r->pdb.site.count,
323
+ shr0->name, shr0->chain_id, shr0->seq_num,
324
+ shr0->insert_code,
325
+ shr1->name, shr1->chain_id, shr1->seq_num,
326
+ shr1->insert_code,
327
+ sha0->name, sha0->chain_id, sha0->seq_num,
328
+ sha0->insert_code,
329
+ sha1->name, sha1->chain_id, sha1->seq_num,
330
+ sha1->insert_code);
331
+ break;
332
+
333
+ case PDB_SPRSDE:
334
+ pdb_sprintf(buffer, fmt, r->pdb.sprsde.continuation,
335
+ r->pdb.sprsde.date, r->pdb.sprsde.id,
336
+ r->pdb.sprsde.supersede[0], r->pdb.sprsde.supersede[1],
337
+ r->pdb.sprsde.supersede[2], r->pdb.sprsde.supersede[3],
338
+ r->pdb.sprsde.supersede[4], r->pdb.sprsde.supersede[5],
339
+ r->pdb.sprsde.supersede[6], r->pdb.sprsde.supersede[7]);
340
+ break;
341
+
342
+ case PDB_SSBOND:
343
+ pdb_sprintf(buffer, fmt, r->pdb.ssbond.seq_num,
344
+ r->pdb.ssbond.residues[0].name,
345
+ r->pdb.ssbond.residues[0].chain_id,
346
+ r->pdb.ssbond.residues[0].seq_num,
347
+ r->pdb.ssbond.residues[0].insert_code,
348
+ r->pdb.ssbond.residues[1].name,
349
+ r->pdb.ssbond.residues[1].chain_id,
350
+ r->pdb.ssbond.residues[1].seq_num,
351
+ r->pdb.ssbond.residues[1].insert_code,
352
+ r->pdb.ssbond.comment);
353
+ break;
354
+
355
+ case PDB_SYMOP:
356
+ pdb_sprintf(buffer, fmt, r->pdb.symop.row_num,
357
+ r->pdb.symop.serial_num, r->pdb.symop.s1,
358
+ r->pdb.symop.s2, r->pdb.symop.s3, r->pdb.symop.t);
359
+ break;
360
+
361
+ case PDB_TER:
362
+ pdb_sprintf(buffer, fmt, r->pdb.ter.serial_num,
363
+ r->pdb.ter.residue.name, r->pdb.ter.residue.chain_id,
364
+ r->pdb.ter.residue.seq_num,
365
+ r->pdb.ter.residue.insert_code);
366
+ break;
367
+
368
+ case PDB_TRNSFM:
369
+ pdb_sprintf(buffer, fmt, r->pdb.trnsfm.result_serial_num,
370
+ r->pdb.trnsfm.apply_serial_num,
371
+ r->pdb.trnsfm.source_serial_num);
372
+ break;
373
+
374
+ case PDB_TURN:
375
+ pdb_sprintf(buffer, fmt, r->pdb.turn.seq_num,
376
+ r->pdb.turn.id,
377
+ r->pdb.turn.residues[0].name,
378
+ r->pdb.turn.residues[0].chain_id,
379
+ r->pdb.turn.residues[0].seq_num,
380
+ r->pdb.turn.residues[0].insert_code,
381
+ r->pdb.turn.residues[1].name,
382
+ r->pdb.turn.residues[1].chain_id,
383
+ r->pdb.turn.residues[1].seq_num,
384
+ r->pdb.turn.residues[1].insert_code,
385
+ r->pdb.turn.comment);
386
+ break;
387
+
388
+ case PDB_TVECT:
389
+ pdb_sprintf(buffer, fmt, r->pdb.tvect.serial_num,
390
+ r->pdb.tvect.t1, r->pdb.tvect.t2, r->pdb.tvect.t3,
391
+ r->pdb.tvect.comment);
392
+ break;
393
+
394
+ case PDB_USER:
395
+ pdb_sprintf(buffer, fmt, r->pdb.user.subtype, r->pdb.user.text);
396
+ break;
397
+
398
+ case PDB_USER_PDBRUN:
399
+ pdb_sprintf(buffer, fmt, r->pdb.user_pdbrun.version);
400
+ pdb_pdbrun_version = r->pdb.user_pdbrun.version;
401
+ break;
402
+
403
+ case PDB_USER_EYEPOS:
404
+ pdb_sprintf(buffer, fmt, r->pdb.user_eyepos.xyz[0],
405
+ r->pdb.user_eyepos.xyz[1], r->pdb.user_eyepos.xyz[2]);
406
+ break;
407
+
408
+ case PDB_USER_ATPOS:
409
+ pdb_sprintf(buffer, fmt, r->pdb.user_atpos.xyz[0],
410
+ r->pdb.user_atpos.xyz[1], r->pdb.user_atpos.xyz[2]);
411
+ break;
412
+
413
+ case PDB_USER_WINDOW:
414
+ pdb_sprintf(buffer, fmt, r->pdb.user_window.left,
415
+ r->pdb.user_window.right, r->pdb.user_window.bottom,
416
+ r->pdb.user_window.top, r->pdb.user_window.hither,
417
+ r->pdb.user_window.yon);
418
+ break;
419
+
420
+ case PDB_USER_FOCUS:
421
+ pdb_sprintf(buffer, fmt, r->pdb.user_focus.focus);
422
+ break;
423
+
424
+ case PDB_USER_VIEWPORT:
425
+ pdb_sprintf(buffer, fmt, r->pdb.user_viewport.xmin,
426
+ r->pdb.user_viewport.xmax, r->pdb.user_viewport.ymin,
427
+ r->pdb.user_viewport.ymax);
428
+ break;
429
+
430
+ case PDB_USER_BGCOLOR:
431
+ if (pdb_pdbrun_version < 6)
432
+ sprintf(buffer, fmt, r->pdb.user_bgcolor.rgb[0],
433
+ r->pdb.user_bgcolor.rgb[1],
434
+ r->pdb.user_bgcolor.rgb[2]);
435
+ else
436
+ pdb_sprintf(buffer, fmt, r->pdb.user_bgcolor.rgb[0],
437
+ r->pdb.user_bgcolor.rgb[1],
438
+ r->pdb.user_bgcolor.rgb[2]);
439
+ break;
440
+
441
+ case PDB_USER_ANGLE:
442
+ if (pdb_pdbrun_version < 6)
443
+ pdb_sprintf(buffer, fmt, r->pdb.user_angle.which,
444
+ r->pdb.user_angle.atom0,
445
+ r->pdb.user_angle.atom1,
446
+ r->pdb.user_angle.atom2,
447
+ r->pdb.user_angle.atom3,
448
+ r->pdb.user_angle.angle);
449
+ else
450
+ pdb_sprintf(buffer, fmt, r->pdb.user_angle.atom0,
451
+ r->pdb.user_angle.atom1,
452
+ r->pdb.user_angle.atom2,
453
+ r->pdb.user_angle.atom3,
454
+ r->pdb.user_angle.angle);
455
+ break;
456
+
457
+ case PDB_USER_DISTANCE:
458
+ if (pdb_pdbrun_version < 6)
459
+ pdb_sprintf(buffer, fmt, r->pdb.user_distance.which,
460
+ r->pdb.user_distance.atom0,
461
+ r->pdb.user_distance.atom1,
462
+ r->pdb.user_distance.distance);
463
+ else
464
+ pdb_sprintf(buffer, fmt, r->pdb.user_distance.atom0,
465
+ r->pdb.user_distance.atom1,
466
+ r->pdb.user_distance.distance);
467
+ break;
468
+
469
+ case PDB_USER_FILE:
470
+ if (pdb_pdbrun_version < 6)
471
+ pdb_sprintf(buffer, fmt, r->pdb.user_file.filename);
472
+ else
473
+ pdb_sprintf(buffer, fmt, r->pdb.user_file.model,
474
+ r->pdb.user_file.filename);
475
+ break;
476
+
477
+ case PDB_USER_MARKNAME:
478
+ pdb_sprintf(buffer, fmt, r->pdb.user_markname.markname);
479
+ break;
480
+
481
+ case PDB_USER_MARK:
482
+ pdb_sprintf(buffer, fmt, r->pdb.user_mark.markname);
483
+ break;
484
+
485
+ case PDB_USER_CNAME:
486
+ if (pdb_pdbrun_version < 6)
487
+ sprintf(buffer, fmt, r->pdb.user_cname.name,
488
+ r->pdb.user_cname.rgb[0],
489
+ r->pdb.user_cname.rgb[1],
490
+ r->pdb.user_cname.rgb[2]);
491
+ else
492
+ pdb_sprintf(buffer, fmt, r->pdb.user_cname.rgb[0],
493
+ r->pdb.user_cname.rgb[1],
494
+ r->pdb.user_cname.rgb[2],
495
+ r->pdb.user_cname.name);
496
+ break;
497
+
498
+ case PDB_USER_COLOR:
499
+ if (pdb_pdbrun_version < 6)
500
+ sprintf(buffer, fmt, r->pdb.user_color.spec,
501
+ r->pdb.user_color.rgb[0],
502
+ r->pdb.user_color.rgb[1],
503
+ r->pdb.user_color.rgb[2]);
504
+ else
505
+ pdb_sprintf(buffer, fmt, r->pdb.user_color.rgb[0],
506
+ r->pdb.user_color.rgb[1],
507
+ r->pdb.user_color.rgb[2],
508
+ r->pdb.user_color.spec);
509
+ break;
510
+
511
+ case PDB_USER_RADIUS:
512
+ pdb_sprintf(buffer, fmt, r->pdb.user_radius.radius);
513
+ break;
514
+
515
+ case PDB_USER_OBJECT:
516
+ pdb_sprintf(buffer, fmt, r->pdb.user_object.model);
517
+ break;
518
+
519
+ case PDB_USER_ENDOBJ:
520
+ pdb_sprintf(buffer, fmt, r->pdb.user_endobj.model);
521
+ break;
522
+
523
+ case PDB_USER_CHAIN:
524
+ if (pdb_pdbrun_version < 6)
525
+ sprintf(buffer, fmt, r->pdb.user_chain.atom0,
526
+ r->pdb.user_chain.atom1);
527
+ else
528
+ pdb_sprintf(buffer, fmt, r->pdb.user_chain.atom0,
529
+ r->pdb.user_chain.atom1);
530
+ break;
531
+
532
+ case PDB_USER_GFX_BEGIN:
533
+ if (r->pdb.user_gfx_begin.primitive == PDB_GFX_UNKNOWN)
534
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_begin.unknown);
535
+ else
536
+ pdb_sprintf(buffer, fmt, pdb_gfx_string(
537
+ r->pdb.user_gfx_begin.primitive));
538
+ break;
539
+
540
+ case PDB_USER_GFX_END:
541
+ pdb_sprintf(buffer, fmt);
542
+ break;
543
+
544
+ case PDB_USER_GFX_COLOR:
545
+ if (pdb_pdbrun_version < 6)
546
+ sprintf(buffer, fmt, r->pdb.user_gfx_color.spec,
547
+ r->pdb.user_gfx_color.rgb[0],
548
+ r->pdb.user_gfx_color.rgb[1],
549
+ r->pdb.user_gfx_color.rgb[2]);
550
+ else
551
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_color.rgb[0],
552
+ r->pdb.user_gfx_color.rgb[1],
553
+ r->pdb.user_gfx_color.rgb[2],
554
+ r->pdb.user_gfx_color.spec);
555
+ break;
556
+
557
+ case PDB_USER_GFX_NORMAL:
558
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_normal.xyz[0],
559
+ r->pdb.user_gfx_normal.xyz[1],
560
+ r->pdb.user_gfx_normal.xyz[2]);
561
+ break;
562
+
563
+ case PDB_USER_GFX_VERTEX:
564
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_vertex.xyz[0],
565
+ r->pdb.user_gfx_vertex.xyz[1],
566
+ r->pdb.user_gfx_vertex.xyz[2]);
567
+ break;
568
+
569
+ case PDB_USER_GFX_FONT:
570
+ if (pdb_pdbrun_version < 6)
571
+ sprintf(buffer, fmt, r->pdb.user_gfx_font.name,
572
+ r->pdb.user_gfx_font.size);
573
+ else
574
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_font.size,
575
+ r->pdb.user_gfx_font.name);
576
+ break;
577
+
578
+ case PDB_USER_GFX_TEXTPOS:
579
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_textpos.xyz[0],
580
+ r->pdb.user_gfx_textpos.xyz[1],
581
+ r->pdb.user_gfx_textpos.xyz[2]);
582
+ break;
583
+
584
+ case PDB_USER_GFX_LABEL:
585
+ if (pdb_pdbrun_version < 6)
586
+ sprintf(buffer, fmt, r->pdb.user_gfx_label.xyz[0],
587
+ r->pdb.user_gfx_label.xyz[1],
588
+ r->pdb.user_gfx_label.xyz[2],
589
+ r->pdb.user_gfx_label.text);
590
+ else
591
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_label.text);
592
+ break;
593
+
594
+ case PDB_USER_GFX_MOVE:
595
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_move.xyz[0],
596
+ r->pdb.user_gfx_move.xyz[1],
597
+ r->pdb.user_gfx_move.xyz[2]);
598
+ break;
599
+
600
+ case PDB_USER_GFX_DRAW:
601
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_draw.xyz[0],
602
+ r->pdb.user_gfx_draw.xyz[1],
603
+ r->pdb.user_gfx_draw.xyz[2]);
604
+ break;
605
+
606
+ case PDB_USER_GFX_MARKER:
607
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_marker.xyz[0],
608
+ r->pdb.user_gfx_marker.xyz[1],
609
+ r->pdb.user_gfx_marker.xyz[2]);
610
+ break;
611
+
612
+ case PDB_USER_GFX_POINT:
613
+ pdb_sprintf(buffer, fmt, r->pdb.user_gfx_point.xyz[0],
614
+ r->pdb.user_gfx_point.xyz[1],
615
+ r->pdb.user_gfx_point.xyz[2]);
616
+ break;
617
+
618
+ default:
619
+ (void) sprintf(buffer, "unknown pdb record #%d",
620
+ r->record_type);
621
+ break;
622
+ }
623
+
624
+ /* find last non-blank in buffer, and shorten it */
625
+ t = NULL;
626
+ for (s = buffer; *s != '\0'; s++)
627
+ if (!isspace(*s))
628
+ t = s + 1;
629
+ if (t == NULL) /* this should never happen, but ... */
630
+ t = buffer;
631
+ *t = '\0';
632
+ }
633
+
634
+ # ifdef vms
635
+ pdb_write_dummy()
636
+ {
637
+ pdb_fmt_dummy();
638
+ }
639
+ # endif
dms/libpdb/pdbrun.c ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1994 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdbrun.c,v 1.4 1994/11/18 01:00:57 gregc Exp $
18
+ *
19
+ * subroutine for reading PDB format files
20
+ *
21
+ */
22
+
23
+ /* LINTLIBRARY */
24
+
25
+ # include "pdb_int.h"
26
+ # include <string.h>
27
+
28
+ int pdb_pdbrun_version = PDB_PDBRUN_VERSION;
29
+
30
+ #ifdef __STDC__
31
+ const char *
32
+ pdb_gfx_string(int i)
33
+ #else
34
+ char *
35
+ pdb_gfx_string(i)
36
+ int i;
37
+ #endif
38
+ {
39
+ switch (i) {
40
+ default: return "UNKNOWN";
41
+ case PDB_GFX_POINTS: return "POINTS";
42
+ case PDB_GFX_MARKERS: return "MARKERS";
43
+ case PDB_GFX_LINES: return "LINES";
44
+ case PDB_GFX_LINE_STRIP: return "LINE-STRIP";
45
+ case PDB_GFX_LINE_LOOP: return "LINE-LOOP";
46
+ case PDB_GFX_TRIANGLES: return "TRIANGLES";
47
+ case PDB_GFX_TRIANGLE_STRIP: return "TRIANGLE-STRIP";
48
+ case PDB_GFX_TRIANGLE_FAN: return "TRIANGLE-FAN";
49
+ case PDB_GFX_QUADS: return "QUADS";
50
+ case PDB_GFX_QUAD_STRIP: return "QUAD-STRIP";
51
+ case PDB_GFX_POLYGON: return "POLYGON";
52
+ }
53
+ }
54
+
55
+ #ifdef __STDC__
56
+ int
57
+ pdb_gfx_type(const char *type)
58
+ #else
59
+ int
60
+ pdb_gfx_type(type)
61
+ char *type;
62
+ #endif
63
+ {
64
+ switch (type[0]) {
65
+ case 'L':
66
+ if (strcmp(type + 1, "INE-LOOP") == 0)
67
+ return PDB_GFX_LINE_LOOP;
68
+ if (strcmp(type + 1, "INE-STRIP") == 0)
69
+ return PDB_GFX_LINE_STRIP;
70
+ if (strcmp(type + 1, "INES") == 0)
71
+ return PDB_GFX_LINES;
72
+ break;
73
+ case 'M':
74
+ if (strcmp(type + 1, "ARKERS") == 0)
75
+ return PDB_GFX_MARKERS;
76
+ break;
77
+ case 'P':
78
+ if (strcmp(type + 1, "OINTS") == 0)
79
+ return PDB_GFX_POINTS;
80
+ if (strcmp(type + 1, "OLYGON") == 0)
81
+ return PDB_GFX_POLYGON;
82
+ break;
83
+ case 'Q':
84
+ if (strcmp(type + 1, "UAD-STRIP") == 0)
85
+ return PDB_GFX_QUAD_STRIP;
86
+ if (strcmp(type + 1, "UADS") == 0)
87
+ return PDB_GFX_QUADS;
88
+ break;
89
+ case 'T':
90
+ if (strcmp(type + 1, "RIANGLE-FAN") == 0)
91
+ return PDB_GFX_TRIANGLE_FAN;
92
+ if (strcmp(type + 1, "RIANGLE-STRIP") == 0)
93
+ return PDB_GFX_TRIANGLE_STRIP;
94
+ if (strcmp(type + 1, "RIANGLES") == 0)
95
+ return PDB_GFX_TRIANGLES;
96
+ break;
97
+ }
98
+ return PDB_GFX_UNKNOWN;
99
+ }
dms/libpdb/pdbrun5_read.i ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1994 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdbrun5_read.i,v 1.4 1994/11/16 22:09:29 gregc Exp $
18
+ */
19
+ /* PDBRUN */ "%12 %2d",
20
+ /* EYEPOS */ "%12 %9f %9f %9f",
21
+ /* ATPOS */ "%11 %9f %9f %9f",
22
+ /* WINDOW */ "%12 %9f %9f %9f %9f %9f %9f",
23
+ /* FOCUS */ "%11 %9f",
24
+ /* VIEWPORT */ "%14 %9f %9f %9f %9f",
25
+ /* BGCOLOR */ "USER BGCOLOR %lf %lf %lf",
26
+ /* ANGLE */ "%11 %2d %6d %6d %6d %6d %8f",
27
+ /* DISTANCE */ "%14 %2d %6d %6d %8f",
28
+ /* FILE */ "%10 %61s",
29
+ /* MARKNAME */ NULL,
30
+ /* MARK */ NULL,
31
+ /* CNAME */ "USER CNAME %s %lf %lf %lf",
32
+ /* COLOR */ "USER COLOR %s %lf %lf %lf",
33
+ /* RADIUS */ "%12 %7f",
34
+ /* OBJECT */ "%12 %3d",
35
+ /* ENDOBJ */ "%12 %3d",
36
+ /* CHAIN */ "USER CHAIN %d %d",
37
+ /* GFX BEGIN */ NULL,
38
+ /* GFX END */ NULL,
39
+ /* GFX COLOR */ "USER GFX COLOR %s %lf %lf %lf",
40
+ /* GFX NORMAL */ NULL,
41
+ /* GFX VERTEX */ NULL,
42
+ /* GFX FONT */ "USER GFX FONT %s %d",
43
+ /* GFX TEXTPOS */ NULL,
44
+ /* GFX LABEL */ "USER GFX LABEL %lf %lf %lf %26[^\n]",
45
+ /* GFX MOVE */ "%14 %9f %9f %9f",
46
+ /* GFX DRAW */ "%14 %9f %9f %9f",
47
+ /* GFX MARKER */ "%16 %9f %9f %9f",
48
+ /* GFX POINT */ "%15 %9f %9f %9f",
dms/libpdb/pdbrun5_write.i ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1994 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdbrun5_write.i,v 1.2 1994/11/16 22:09:29 gregc Exp $
18
+ */
19
+ "USER PDBRUN %2d",
20
+ "USER EYEPOS %9.3f %9.3f %9.3f",
21
+ "USER ATPOS %9.3f %9.3f %9.3f",
22
+ "USER WINDOW %9.3f %9.3f %9.3f %9.3f %9.3f %9.3f",
23
+ "USER FOCUS %9.3f",
24
+ "USER VIEWPORT %9.3f %9.3f %9.3f %9.3f",
25
+ "USER BGCOLOR %.3f %.3f %.3f",
26
+ "USER ANGLE %2d %6d %6d %6d %6d %8.3f",
27
+ "USER DISTANCE %2d %6d %6d %8.3f",
28
+ "USER FILE %-61s",
29
+ NULL, /* USER MARKNAME */
30
+ NULL, /* USER MARK */
31
+ "USER CNAME %-.38s %.3f %.3f %.3f",
32
+ "USER COLOR %-.38s %5.3f %5.3f %5.3f",
33
+ "USER RADIUS %7.3f",
34
+ "USER OBJECT %3d",
35
+ "USER ENDOBJ %3d",
36
+ "USER CHAIN %d %d",
37
+ NULL, /* USER GFX BEGIN */
38
+ NULL, /* USER GFX END */
39
+ "USER GFX COLOR %-.38s %.3f %.3f %.3f",
40
+ NULL, /* USER GFX NORMAL */
41
+ NULL, /* USER GFX VERTEX */
42
+ "USER GFX FONT %-.53s %d",
43
+ NULL, /* USER GFX TEXTPOS */
44
+ "USER GFX LABEL %9.3f %9.3f %9.3f \"%-.24s\"",
45
+ "USER GFX MOVE %9.3f %9.3f %9.3f",
46
+ "USER GFX DRAW %9.3f %9.3f %9.3f",
47
+ "USER GFX MARKER %9.3f %9.3f %9.3f",
48
+ "USER GFX POINT %9.3f %9.3f %9.3f",
dms/libpdb/pdbrun6_read.i ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1994 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdbrun6_read.i,v 1.3 1995/01/20 01:20:36 gregc Exp $
18
+ */
19
+ /* PDBRUN */ "%12 %2d",
20
+ /* EYEPOS */ "%12 %9f %9f %9f",
21
+ /* ATPOS */ "%11 %9f %9f %9f",
22
+ /* WINDOW */ "%12 %9f %9f %9f %9f %9f %9f",
23
+ /* FOCUS */ "%11 %9f",
24
+ /* VIEWPORT */ "%14 %9f %9f %9f %9f",
25
+ /* BGCOLOR */ "%13 %5f %5f %5f",
26
+ /* ANGLE */ "%11 %6d %6d %6d %6d %9f",
27
+ /* DISTANCE */ "%14 %6d %6d %9f",
28
+ /* FILE */ "%10 %4d %56s",
29
+ /* MARKNAME */ "%14 %57s",
30
+ /* MARK */ "%10 %57s",
31
+ /* CNAME */ "%11 %5f %5f %5f %38s",
32
+ /* COLOR */ "%11 %5f %5f %5f %38s",
33
+ /* RADIUS */ "%12 %7f",
34
+ /* OBJECT */ "%12 ",
35
+ /* ENDOBJ */ "%12 ",
36
+ /* CHAIN */ "%11 %6d %6d",
37
+ /* GFX BEGIN */ "%15 %32s",
38
+ /* GFX END */ "%13 ",
39
+ /* GFX COLOR */ "%15 %5f %5f %5f %38s",
40
+ /* GFX NORMAL */ "%16 %9f %9f %9f",
41
+ /* GFX VERTEX */ "%16 %9f %9f %9f",
42
+ /* GFX FONT */ "%14 %3d %53s",
43
+ /* GFX TEXTPOS */ "%17 %9f %9f %9f",
44
+ /* GFX LABEL */ "%15 %56s",
45
+ /* GFX MOVE */ NULL,
46
+ /* GFX DRAW */ NULL,
47
+ /* GFX MARKER */ NULL,
48
+ /* GFX POINT */ NULL,
dms/libpdb/pdbrun6_write.i ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1994 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: pdbrun6_write.i,v 1.3 1995/01/20 01:20:36 gregc Exp $
18
+ */
19
+ "USER PDBRUN %2d",
20
+ "USER EYEPOS %9.3f %9.3f %9.3f",
21
+ "USER ATPOS %9.3f %9.3f %9.3f",
22
+ "USER WINDOW %9.3f %9.3f %9.3f %9.3f %9.3f %9.3f",
23
+ "USER FOCUS %9.3f",
24
+ "USER VIEWPORT %9.3f %9.3f %9.3f %9.3f",
25
+ "USER BGCOLOR %5.3f %5.3f %5.3f",
26
+ "USER ANGLE %6d %6d %6d %6d %9.3f",
27
+ "USER DISTANCE %6d %6d %9.3f",
28
+ "USER FILE %4d %-56s",
29
+ "USER MARKNAME %-57s",
30
+ "USER MARK %-57s",
31
+ "USER CNAME %5.3f %5.3f %5.3f %-42s",
32
+ "USER COLOR %5.3f %5.3f %5.3f %-42s",
33
+ "USER RADIUS %7.3f",
34
+ "USER OBJECT",
35
+ "USER ENDOBJ",
36
+ "USER CHAIN %6d %6d",
37
+ "USER GFX BEGIN %-32s",
38
+ "USER GFX END",
39
+ "USER GFX COLOR %5.3f %5.3f %5.3f %s",
40
+ "USER GFX NORMAL %9.3f %9.3f %9.3f",
41
+ "USER GFX VERTEX %9.3f %9.3f %9.3f",
42
+ "USER GFX FONT %3d %-53s",
43
+ "USER GFX TEXTPOS %9.3f %9.3f %9.3f",
44
+ "USER GFX LABEL %-56s",
45
+ NULL, /* USER GFX MOVE */
46
+ NULL, /* USER GFX DRAW */
47
+ NULL, /* USER GFX MARKER */
48
+ NULL, /* USER GFX POINT */
dms/libpdb/read_format.i ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1993 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: read_format.i,v 1.2 93/04/21 19:55:49 gregc Exp $
18
+ */
19
+ /* UNKNOWN */ NULL,
20
+ /* ANISOU */ "%6 %5d %4s%c%4s%c%4d%c %7d%7d%7d%7d%7d%7d", /* SIGUIJ */
21
+ /* ATOM */ "%6 %5d %4s%c%4s%c%4d%c %8f%8f%8f%6f%6f %3d", /* HETATM, SIGATM */
22
+ /* AUTHOR */ "%9 %c%60s", /* COMPND, EXPDTA, JRNL, SOURCE */
23
+ /* COMPND */ "%9 %c%60s", /* AUTHOR */
24
+ /* CONECT */ "%6 %5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d",
25
+ /* CRYST1 */ "%6 %9f%9f%9f%7f%7f%7f %11s%4d",
26
+ /* END */ NULL,
27
+ /* FORMUL */ "%8 %2d %4s%2d%c%51s",
28
+ /* FTNOTE */ "%7 %3d %59s", /* REMARK, SYMDES, MTXDES, CMPDES, AGRDES */
29
+ /* HEADER */ "%10 %40s%9s %c%4s",
30
+ /* HELIX */ "%7 %3d %3s %4s%c %4d%c %4s%c %4d%c%2d%30s",
31
+ /* HET */ "%7 %4s %c%4d%c %5d%5 %40s",
32
+ /* HETATM */ "%6 %5d %4s%c%4s%c%4d%c %8f%8f%8f%6f%6f %3d", /* ATOM */
33
+ /* JRNL */ "%9 %c%60s", /* AUTHOR */
34
+ /* MASTER */ "%10 %5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d",
35
+ /* MTRIX */ "%5 %d %3d%10f%10f%10f%5 %10f %2d",
36
+ /* OBSLTE */ "%8 %2d %9s %4s%6 %4s %4s %4s %4s %4s %4s %4s %4s",
37
+ /* ORIGX */ "%5 %d%4 %10f%10f%10f%5 %10f", /* SCALE */
38
+ /* REMARK */ "%7 %3d %59s", /* FTNOTE */
39
+ /* REVDAT */ "%7 %3d%2d %9s %7s %c%7 %31s",
40
+ /* SCALE */ "%5 %d%4 %10f%10f%10f%5 %10f",
41
+ /* SEQRES */ "%6 %4d %c %4d %4s%4s%4s%4s%4s%4s%4s%4s%4s%4s%4s%4s%4s",
42
+ /* SHEET */ "%6 %4d %3s%2d %4s%c%4d%c %4s%c%4d%c%2d %4s%4s%c%4d%c %4s%4s%c%4d%c",
43
+ /* SIGATM */ "%6 %5d %4s%c%4s%c%4d%c %8f%8f%8f%6f%6f %3d", /* ATOM */
44
+ /* SIGUIJ */ "%6 %5d %4s%c%4s%c%4d%c %7d%7d%7d%7d%7d%7d", /* ANISOU */
45
+ /* SITE */ "%7 %3d %3s %2d %4s%c%4d%c %4s%c%4d%c %4s%c%4d%c %4s%c%4d%c",
46
+ /* SOURCE */ "%9 %c%60s", /* AUTHOR */
47
+ /* SPRSDE */ "%8 %2d %9s %4s%6 %4s %4s %4s %4s %4s %4s %4s %4s",
48
+ /* SSBOND */ "%7 %3d %4s%c %4d%c %4s%c %4d%c%4 %30s",
49
+ /* TER */ "%6 %5d%6 %4s%c%4d%c",
50
+ /* TURN */ "%7 %3d %3s %4s%c%4d%c %4s%c%4d%c%4 %30s",
51
+ /* TVECT */ "%7 %3d%10f%10f%10f%30s",
52
+ /* USER */ "%4 %2s%66s",
53
+ /* MODEL */ "%9 %5d",
54
+ /* ENDMDL */ NULL,
55
+ /* EXPDTA */ "%9 %c%60s", /* AUTHOR */
56
+ /* SYMDES */ "%7 %3d %59s", /* FTNOTE */
57
+ /* SYMOP */ "%5 %d %3d%10f%10f%10f%5 %10f",
58
+ /* MTXDES */ "%7 %3d %59s", /* FTNOTE */
59
+ /* CMPDES */ "%7 %3d %59s", /* FTNOTE */
60
+ /* CMPONT */ "%7 %3d %4s%c %4d%c %4s%c %4d%c",
61
+ /* TRNSFM */ "%7 %3d %3d %3d",
62
+ /* AGRDES */ "%7 %3d %59s", /* FTNOTE */
63
+ /* AGGRGT */ "%7 %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d",
dms/libpdb/write_format.i ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright (c) 1993 The Regents of the University of California.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms are permitted
6
+ * provided that the above copyright notice and this paragraph are
7
+ * duplicated in all such forms and that any documentation,
8
+ * advertising materials, and other materials related to such
9
+ * distribution and use acknowledge that the software was developed
10
+ * by the University of California, San Francisco. The name of the
11
+ * University may not be used to endorse or promote products derived
12
+ * from this software without specific prior written permission.
13
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
+ *
17
+ * $Id: write_format.i,v 1.3 93/06/24 11:53:47 gregc Exp $
18
+ */
19
+ "UNKNOWN: ??%-6.6s??",
20
+ "ANISOU%5d %-4s%c%-4s%c%4d%c %7d%7d%7d%7d%7d%7d", /* SIGUIJ */
21
+ "ATOM %5d %-4s%c%-4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %3D", /* HETATM, SIGATM */
22
+ "AUTHOR %c%-60s", /* COMPND, EXPDTA, JRNL, SOURCE */
23
+ "COMPND %c%-60s", /* AUTHOR */
24
+ "CONECT%5d%5D%5D%5D%5D%5D%5D%5D%5D%5D%5D",
25
+ "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f %-11s%4d",
26
+ "END",
27
+ "FORMUL %2D %-4s%2D%c%-51s",
28
+ "FTNOTE %3D %-59s", /* REMARK */
29
+ "HEADER %-40s%-11s%c%-4s",
30
+ "HELIX %3D %3s %-4s%c %4d%c %-4s%c %4d%c%2D%-30s",
31
+ "HET %-4s %c%4d%c %5d %-40s",
32
+ "HETATM%5d %-4s%c%-4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %3D",
33
+ "JRNL %c%-60s", /* AUTHOR */
34
+ "MASTER %5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d%5d",
35
+ "MTRIX%1d %3d%10.6f%10.6f%10.6f %10.5f %2D",
36
+ "OBSLTE %2D %-9s %-10s%-5s%-5s%-5s%-5s%-5s%-5s%-5s%-4s",
37
+ "ORIGX%1d %10.6f%10.6f%10.6f %10.5f", /* SCALE */
38
+ "REMARK %3D %-59s",
39
+ "REVDAT %3D%2D %-9s %-7s %c %-31s",
40
+ "SCALE%1d %10.6f%10.6f%10.6f %10.5f", /* ORIGX */
41
+ "SEQRES%4d %c %4d %-4s%-4s%-4s%-4s%-4s%-4s%-4s%-4s%-4s%-4s%-4s%-4s%-4s",
42
+ "SHEET %4D %3s%2d %-4s%c%4d%c %-4s%c%4d%c%2d %-4s%-4s%c%4D%c %-4s%-4s%c%4D%c",
43
+ "SIGATM%5d %-4s%c%-4s%c%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %3D",
44
+ "SIGUIJ%5d %-4s%c%-4s%c%4d%c %7D%7D%7D%7D%7D%7D", /* ANISOU */
45
+ "SITE %3d %3s %2d %-4s%c%4D%c %-4s%c%4D%c %-4s%c%4D%c %-4s%c%4D%c",
46
+ "SOURCE %c%-60s", /* AUTHOR */
47
+ "SPRSDE %2D %-9s %-10s%-5s%-5s%-5s%-5s%-5s%-5s%-5s%-4s",
48
+ "SSBOND %3D %-4s%c %4d%c %-4s%c %4D%c %-30s",
49
+ "TER %5d %-4s%c%4d%c",
50
+ "TURN %3D %3s %-4s%c%4d%c %-4s%c%4d%c %-30s",
51
+ "TVECT %3D%10.5f%10.5f%10.5f%-30s",
52
+ "USER%-2s%-66s",
53
+ "MODEL %5d",
54
+ "ENDMDL",
55
+ "EXPDTA %c%-60s", /* AUTHOR */
56
+ "SYMDES %3d %59s", /* FTNOTE */
57
+ "SYMOP%1d %3d%10.6f%10.6f%10.6f %10.5f",
58
+ "MTXDES %3d %59s", /* FTNOTE */
59
+ "CMPDES %3d %59s", /* FTNOTE */
60
+ "CMPONT %3d %4s%c %4d%c %4s%c %4d%c",
61
+ "TRNSFM %3d %3d %3d",
62
+ "AGRDES %3d %59s", /* FTNOTE */
63
+ "AGGRGT %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d",
dms/ms.c ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include "dms_param.h"
35
+ #include "wanted.h"
36
+ #include "atoms.h"
37
+
38
+ #define DEF_DENSITY 1.0 /* Default surface density */
39
+ #define MIN_DENSITY 0.1
40
+ #define MAX_DENSITY 10.0
41
+ #define DEF_PROBE 1.4 /* Default probe radius */
42
+ #define MIN_PROBE 1.0
43
+ #define MAX_PROBE 201.0
44
+
45
+ #define MODE_PDB 0
46
+ #define MODE_MIDAS 1
47
+ #define MODE_KRAUT 2
48
+
49
+ #ifndef TRUE
50
+ #define TRUE 1
51
+ #define FALSE 0
52
+ #endif
53
+
54
+ void usage(char *);
55
+
56
+ /*
57
+ * MS:
58
+ * Compute the solvent accessible surface of a molecule
59
+ * as defined by Richards.
60
+ */
61
+ main(ac, av)
62
+ int ac;
63
+ char **av;
64
+ {
65
+ register int c;
66
+ register ATOM *ap;
67
+ int input_mode;
68
+ int aflg, nflg;
69
+ int natom;
70
+ int verbose;
71
+ int fd;
72
+ int any_wanted;
73
+ double density, probe;
74
+ char *in_file, *out_file;
75
+ FILE *out_fp;
76
+ FILE *wanted_fp;
77
+ WANTED *wanted_list;
78
+ ATOM *atom_list, **atom_array;
79
+ extern int optind;
80
+ extern char *optarg;
81
+ extern double atof();
82
+ WANTED *read_wanted();
83
+ ATOM *read_pdb(), *read_midas(), *read_kraut();
84
+ ATOM **make_array();
85
+
86
+ /*
87
+ * Initialize variables to default values which may be
88
+ * overridden by command line arguments
89
+ */
90
+ verbose = FALSE;
91
+ aflg = FALSE;
92
+ nflg = FALSE;
93
+ density = DEF_DENSITY;
94
+ probe = DEF_PROBE;
95
+ input_mode = MODE_PDB;
96
+ out_fp = NULL;
97
+ wanted_fp = NULL;
98
+
99
+ /*
100
+ * We process the arguments in a strange way because
101
+ * we want to be backwards compatible with the old ms
102
+ * program
103
+ */
104
+ if (ac < 4) {
105
+ usage(av[0]);
106
+ exit(1);
107
+ }
108
+ in_file = av[1];
109
+ av[1] = av[0];
110
+ ac--;
111
+ av++;
112
+ while ((c = getopt(ac, av, "ad:e:g:i:kpmnr:w:o:v")) != EOF)
113
+ switch (c) {
114
+ case 'a':
115
+ aflg = TRUE;
116
+ break;
117
+ case 'd':
118
+ density = atof(optarg);
119
+ if (density < MIN_DENSITY || density > MAX_DENSITY) {
120
+ fprintf(stderr,
121
+ "Density must be between %.2f and %.2f\n",
122
+ MIN_DENSITY, MAX_DENSITY);
123
+ exit(1);
124
+ }
125
+ break;
126
+ case 'g':
127
+ (void) fflush(stderr);
128
+ if ((fd = creat(optarg, 0666)) < 0) {
129
+ perror(optarg);
130
+ exit(1);
131
+ }
132
+ (void) dup2(fd, 2);
133
+ (void) close(fd);
134
+ break;
135
+ case 'i':
136
+ if ((wanted_fp = fopen(optarg, "r")) == NULL) {
137
+ perror(optarg);
138
+ exit(1);
139
+ }
140
+ break;
141
+ case 'p':
142
+ input_mode = MODE_PDB;
143
+ break;
144
+ case 'w':
145
+ probe = atof(optarg);
146
+ if (probe < MIN_PROBE || probe > MAX_PROBE) {
147
+ fprintf(stderr,
148
+ "Probe size must be between %.2f and %.2f\n",
149
+ MIN_PROBE, MAX_PROBE);
150
+ exit(1);
151
+ }
152
+ break;
153
+ case 'n':
154
+ nflg = TRUE;
155
+ break;
156
+ case 'o':
157
+ if ((out_fp = fopen(optarg, "w")) == NULL) {
158
+ perror(optarg);
159
+ exit(1);
160
+ }
161
+ out_file = optarg;
162
+ break;
163
+ case 'k':
164
+ input_mode = MODE_KRAUT;
165
+ break;
166
+ case 'm':
167
+ input_mode = MODE_MIDAS;
168
+ break;
169
+ case 'e':
170
+ case 'r':
171
+ fprintf(stderr, "-%c is not implemented\n", c);
172
+ exit(1);
173
+ case 'v':
174
+ verbose = TRUE;
175
+ break;
176
+ default:
177
+ fprintf(stderr, "-%c is not recognized\n", c);
178
+ usage(av[0]);
179
+ exit(1);
180
+ }
181
+ if (out_fp == NULL) {
182
+ fprintf(stderr, "missing -o option\n");
183
+ usage(av[0]);
184
+ exit(1);
185
+ }
186
+ #ifdef BSD
187
+ (void) setlinebuf(stderr);
188
+ #endif
189
+
190
+ /*
191
+ * Read in the atoms
192
+ */
193
+ switch (input_mode) {
194
+ case MODE_PDB:
195
+ atom_list = read_pdb(in_file, aflg);
196
+ break;
197
+ case MODE_KRAUT:
198
+ atom_list = read_kraut(in_file, aflg);
199
+ break;
200
+ case MODE_MIDAS:
201
+ atom_list = read_midas(in_file, aflg);
202
+ break;
203
+ }
204
+ if (atom_list == NULL) {
205
+ fprintf(stderr, "No atoms in input file!\n");
206
+ (void) fclose(out_fp);
207
+ (void) unlink(out_file);
208
+ exit(1);
209
+ }
210
+
211
+ /*
212
+ * Read in the "ignore" file so we know what constraints
213
+ * we have on input, and check them against atoms present
214
+ */
215
+ wanted_list = read_wanted(wanted_fp);
216
+ if (wanted_fp != NULL)
217
+ (void) fclose(wanted_fp);
218
+
219
+ any_wanted = 0;
220
+ for (ap = atom_list; ap != NULL; ap = ap->next) {
221
+ ap->wanted = (wanted_list == NULL || wanted(ap, wanted_list));
222
+ if (ap->wanted)
223
+ any_wanted = 1;
224
+ }
225
+ if (any_wanted == 0) {
226
+ fprintf(stderr, "No atoms selected by site file.\n");
227
+ (void) fclose(out_fp);
228
+ (void) unlink(out_file);
229
+ exit(1);
230
+ }
231
+ atom_array = make_array(atom_list, &natom);
232
+ fprintf(stderr, "%d atoms\n", natom);
233
+
234
+ /*
235
+ * Compute the surface
236
+ */
237
+ compute_ms(atom_array, natom, probe, density, nflg, verbose);
238
+
239
+ /*
240
+ * Output the surface in some appropriate format
241
+ */
242
+ print_ms(out_fp, atom_list, nflg);
243
+ (void) fclose(out_fp);
244
+
245
+ /*
246
+ * All done. Clean up.
247
+ */
248
+ exit(0);
249
+ }
250
+
251
+ /*
252
+ * usage:
253
+ * Print a usage message and a description of each argument
254
+ */
255
+ void usage(prog_name)
256
+ char *prog_name;
257
+ {
258
+ #if 0
259
+ fprintf(stderr, "Usage: %s input_file [-a] [-d density] [-e file] [-g file] [-i file] [-k] [-m] [-p] [-n] [-r b-e] [-w radius] -o file\n", prog_name);
260
+ #else
261
+ fprintf(stderr, "Usage: %s input_file [-a] [-d density] [-g file] [-i file] [-n] [-w radius] [-v] -o file\n", prog_name);
262
+ #endif
263
+ fputs("\t-a\tuse all atoms, not just amino acids\n", stderr);
264
+ fputs("\t-d\tchange density of points\n", stderr);
265
+ fputs("\t-g\tsend messages to file\n", stderr);
266
+ fputs("\t-i\tcalculate only surface for specified atoms\n", stderr);
267
+ #if 0
268
+ fputs("\t-e\tcalculate only surface within ellipsoid\n", stderr);
269
+ fputs("\t-k\tinput file is in Kraut format\n", stderr);
270
+ fputs("\t-m\tinput file is in Midas format\n", stderr);
271
+ fputs("\t-p\tinput file is in Protein Data Bank format\n", stderr);
272
+ fputs("\t-r\tuse only specified residues\n", stderr);
273
+ #endif
274
+ fputs("\t-n\tcalculate normals for surface points\n", stderr);
275
+ fputs("\t-w\tchange probe radius\n", stderr);
276
+ fputs("\t-v\tverbose\n", stderr);
277
+ fputs("\t-o\tspecify output file name (required)\n", stderr);
278
+ }
279
+
280
+ /*
281
+ * make_array:
282
+ * Create an array which points at elements of a list
283
+ */
284
+ ATOM **
285
+ make_array(alist, nel)
286
+ ATOM *alist;
287
+ int *nel;
288
+ {
289
+ register ATOM *ap, **app, **aarray;
290
+ register int n;
291
+ extern char *emalloc();
292
+
293
+ n = 0;
294
+ for (ap = alist; ap != NULL; ap = ap->next)
295
+ n++;
296
+ aarray = (ATOM **) emalloc(n * sizeof (ATOM *));
297
+ app = aarray;
298
+ for (ap = alist; ap != NULL; ap = ap->next)
299
+ *app++ = ap;
300
+ *nel = n;
301
+ return aarray;
302
+ }
dms/output.c ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <math.h>
35
+ #include "dms_param.h"
36
+ #include "atoms.h"
37
+
38
+ #ifdef BILD_OUTPUT
39
+ #define BYATOM /* Color by atom ownership */
40
+ #undef BYTYPE /* Color by type of surface */
41
+ #endif
42
+ #undef CHECKPT /* Make sure points are okay */
43
+
44
+ static double contact_area, reentrant_area;
45
+ static int contact_points, reentrant_points;
46
+
47
+ void print_atom();
48
+
49
+ /*
50
+ * print_ms:
51
+ * Print surface data in some format
52
+ */
53
+ void print_ms(fp, alist, have_normal)
54
+ FILE *fp;
55
+ ATOM *alist;
56
+ int have_normal;
57
+ {
58
+ register ATOM *ap;
59
+ #ifdef BILD_OUTPUT
60
+ double x, y, z;
61
+ #endif
62
+
63
+ #ifdef BILD_OUTPUT
64
+ x = y = z = 0;
65
+ for (ap = alist; ap != NULL; ap = ap->next) {
66
+ x += (*app)->coord[0];
67
+ y += (*app)->coord[1];
68
+ z += (*app)->coord[2];
69
+ }
70
+ fprintf(fp, ".tran %.3f %.3f %.3f\n",
71
+ -x / natom, -y / natom, -z / natom);
72
+ #endif
73
+ for (ap = alist; ap != NULL; ap = ap->next)
74
+ print_atom(fp, ap, have_normal, alist);
75
+
76
+ /*
77
+ * Report statistics
78
+ */
79
+ fprintf(stderr, "%d points\t(%d contact, %d reentrant)\n",
80
+ contact_points + reentrant_points, contact_points,
81
+ reentrant_points);
82
+ fprintf(stderr, "%.2f sq. A\t(%.2f contact, %.2f reentrant)\n",
83
+ contact_area + reentrant_area, contact_area,
84
+ reentrant_area);
85
+ fprintf(stderr, "%.2f pts/sq.A\t(%.2f contact, %.2f reentrant)\n",
86
+ (contact_points + reentrant_points) /
87
+ (contact_area + reentrant_area),
88
+ contact_points / contact_area,
89
+ reentrant_area == 0 ? 0.0 : reentrant_points / reentrant_area);
90
+ }
91
+
92
+ #ifndef BILD_OUTPUT
93
+ /* ARGSUSED */
94
+ #endif
95
+ /*
96
+ * print_atom:
97
+ * Print the atom and its associated surface points
98
+ */
99
+ void print_atom(fp, ap, have_normal, alist)
100
+ FILE *fp;
101
+ ATOM *ap;
102
+ int have_normal;
103
+ ATOM *alist;
104
+ {
105
+ register SURFACE *sp;
106
+ register POINT *pp, *endpp;
107
+ #ifndef BILD_OUTPUT
108
+ register char *typep;
109
+ register POINT *np;
110
+ #else
111
+ #ifdef BYATOM
112
+ static int color = 1;
113
+ #endif
114
+ #endif
115
+
116
+ #ifdef BILD_OUTPUT
117
+ #ifdef BYATOM
118
+ fprintf(fp, ".color %d\n", color);
119
+ color = color % 7 + 1;
120
+ #endif
121
+ fprintf(fp, ".cmov %.3f %.3f %.3f\n%s\n", ap->coord[0], ap->coord[1],
122
+ ap->coord[2], ap->atname);
123
+ #else
124
+ fprintf(fp, "%3s %4s %4.4s%8.3f %8.3f %8.3f A\n", ap->restype,
125
+ ap->resseq, ap->atname, ap->coord[0], ap->coord[1],
126
+ ap->coord[2]);
127
+ #endif
128
+ if (!ap->wanted)
129
+ return;
130
+ for (sp = ap->surface; sp != NULL; sp = sp->next) {
131
+ if (sp->type == CONTACT) {
132
+ contact_points += sp->npoint;
133
+ contact_area += sp->npoint * sp->area;
134
+ }
135
+ else {
136
+ reentrant_points += sp->npoint;
137
+ reentrant_area += sp->npoint * sp->area;
138
+ }
139
+ #ifndef BILD_OUTPUT
140
+ switch (sp->type) {
141
+ case CONTACT:
142
+ typep = "SC0";
143
+ break;
144
+ case TREENTRANT:
145
+ typep = "SS0";
146
+ break;
147
+ case SREENTRANT:
148
+ typep = "SR0";
149
+ break;
150
+ }
151
+ np = sp->normal;
152
+ #else
153
+ #ifdef BYTYPE
154
+ fprintf(fp, ".color %d\n", sp->type + 1);
155
+ #endif
156
+ #endif
157
+ endpp = sp->position + sp->npoint;
158
+ for (pp = sp->position; pp < endpp; pp++) {
159
+ #ifdef CHECKPT
160
+ verify_point(pp, alist);
161
+ #endif
162
+ #ifdef BILD_OUTPUT
163
+ fprintf(fp, ".dot %.3f %.3f %.3f\n", pp->coord[0],
164
+ pp->coord[1], pp->coord[2]);
165
+ #else
166
+ fprintf(fp, "%3s %4s %4.4s%8.3f %8.3f %8.3f %3s %6.3f",
167
+ ap->restype, ap->resseq, ap->atname,
168
+ pp->coord[0], pp->coord[1], pp->coord[2],
169
+ typep, sp->area);
170
+ if (have_normal) {
171
+ fprintf(fp, " %6.3f %6.3f %6.3f", np->coord[0],
172
+ np->coord[1], np->coord[2]);
173
+ np++;
174
+ }
175
+ (void) putc('\n', fp);
176
+ #endif
177
+ }
178
+ }
179
+ }
180
+
181
+ #ifdef CHECKPT
182
+ /*
183
+ * verify_point:
184
+ * Verify that the point is not inside any atom
185
+ */
186
+ verify_point(pp, alist)
187
+ register POINT *pp;
188
+ ATOM *alist;
189
+ {
190
+ register ATOM *ap;
191
+ register int i;
192
+ double delta, distsq;
193
+
194
+ for (ap = alist; ap != NULL; ap = ap->next) {
195
+ distsq = 0;
196
+ for (i = 0; i < 3; i++) {
197
+ delta = ap->coord[i] - pp->coord[i];
198
+ distsq += delta * delta;
199
+ }
200
+ if (distsq + 0.1 < ap->radius * ap->radius) {
201
+ fprintf(stderr, "Point too close to %s@%s\n",
202
+ ap->atname, ap->resseq);
203
+ break;
204
+ }
205
+ }
206
+ }
207
+ #endif
dms/protocol.h ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #define PI_COMMAND "paramdata radius %lf, density %lf, wantnormal %d\n"
34
+ #define PI_RESPONSE "received paramdata\n"
35
+
36
+ #define AI_COMMAND "atomdata %d\n"
37
+ #define AI_RESPONSE "received atomdata\n"
38
+
39
+ #define NI_COMMAND "neighbordata %d\n"
40
+ #define NI_RESPONSE "received neighbordata\n"
41
+
42
+ #define PRI_COMMAND "probedata %d\n"
43
+ #define PRI_RESPONSE "received probedata\n"
44
+
45
+ #define C_COMMAND "contacts %d\n"
46
+ #define C_RESPONSE "contactdata atom %d, %d neighbors\n"
47
+
48
+ #define P_COMMAND "probes %d %d\n"
49
+ #define P_BADNB "badneighbor %d %d\n"
50
+ #define P_RESPONSE "probedata %d probes\n"
51
+
52
+ #define CS_COMMAND "csurface %d\n"
53
+ #define TS_COMMAND "tsurface %d %d\n"
54
+ #define PS_COMMAND "psurface %d\n"
55
+
56
+ #define SURFACE_END "surfacedata end\n"
57
+ #define SURFACE_RESPONSE \
58
+ "surfacedata atom %d, %d points, type %d, area %lf, havenormal %d\n"
dms/radii.proto ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file contains the atom radii used by dms.
2
+ # The radii appears one per line, atom type followed by atom radius.
3
+ # Note that the more specific the type (i.e. contains more characters)
4
+ # the further down the list it appears. This is VERY important
5
+ # The default line is not required. If it is not present, then dms
6
+ # will quit when it encounters an atom of unknown type, otherwise
7
+ # it will use the default radius.
8
+ H 1.20
9
+ D 1.20
10
+ C 1.90
11
+ N 1.50
12
+ O 1.40
13
+ F 1.35
14
+ P 1.90
15
+ S 1.85
16
+ I 2.15
17
+ CL 1.80
18
+ FE 0.64
19
+ CU 1.28
20
+ ZN 1.38
21
+ BR 1.95
22
+ 1H 1.20
23
+ 2H 1.20
24
+ 3H 1.20
25
+ 4H 1.20
26
+ 1D 1.20
27
+ 2D 1.20
28
+ 3D 1.20
29
+ 4D 1.20
30
+ default 1.90
dms/tokenize.c ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #include <stdio.h>
34
+ #include <ctype.h>
35
+
36
+ /*
37
+ * tokenize:
38
+ * Break string into array of words at spaces, keeping strings
39
+ * intact and recognizing backslash escapes, returning number
40
+ * of words found or -1 if more than n found or -2 if non-printable
41
+ * character encountered or -3 if mismatched quotes.
42
+ */
43
+ int
44
+ tokenize(string, array, n)
45
+ char *string, /* string to be tokenized */
46
+ *array[]; /* returned array of pointers to tokens in string */
47
+ int n; /* maximum number of tokens to look for */
48
+ {
49
+ register int i;
50
+
51
+ for (i = 0; i < n; i++) {
52
+ while (isspace(*string))
53
+ string++;
54
+ if (*string == '"') {
55
+ *array++ = ++string;
56
+ while (isprint(*string) && *string != '"') {
57
+ if (*string == '\\') { /* backslash escapes */
58
+ strcpy(string, string+1);
59
+ switch (*string) {
60
+ case 't': /* tab */
61
+ *string = '\t';
62
+ break;
63
+ case 'b': /* backspace */
64
+ *string = '\b';
65
+ break;
66
+ case 'n': /* newline */
67
+ *string = '\n';
68
+ break;
69
+ case 'r': /* carriage return */
70
+ *string = '\r';
71
+ break;
72
+ case 'f': /* formfeed */
73
+ *string = '\f';
74
+ break;
75
+ default: /* treat as normal */
76
+ break;
77
+ }
78
+ }
79
+ string++;
80
+ }
81
+ if (*string == '\0')
82
+ return -3;
83
+ if (!isprint(*string))
84
+ return -2;
85
+ *string++ = '\0';
86
+ continue;
87
+ }
88
+ *array++ = string;
89
+ if (*string == '\0')
90
+ break;
91
+ if (!isprint(*string))
92
+ return -2;
93
+ while (!isspace(*string) && isprint(*string)) {
94
+ if (*string == '\\') { /* backslash escapes */
95
+ strcpy(string, string+1);
96
+ switch (*string) {
97
+ case 't': /* tab */
98
+ *string = '\t';
99
+ break;
100
+ case 'b': /* backspace */
101
+ *string = '\b';
102
+ break;
103
+ case 'n': /* newline */
104
+ *string = '\n';
105
+ break;
106
+ case 'r': /* carriage return */
107
+ *string = '\r';
108
+ break;
109
+ case 'f': /* formfeed */
110
+ *string = '\f';
111
+ break;
112
+ default: /* treat as normal */
113
+ break;
114
+ }
115
+ }
116
+ string++;
117
+ }
118
+ if (isspace(*string))
119
+ *string++ = '\0';
120
+ }
121
+ while (isspace(*string))
122
+ string++;
123
+ return *string == '\0' ? i : -1;
124
+ }
dms/wanted.h ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Copyright (c) <2002> The Regents of the University of California.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions, and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above
12
+ copyright notice, this list of conditions, and the following
13
+ disclaimer in the documentation and/or other materials provided
14
+ with the distribution.
15
+ 3. Redistributions must acknowledge that this software was
16
+ originally developed by the UCSF Computer Graphics Laboratory
17
+ under support by the NIH National Center for Research Resources,
18
+ grant P41-RR01081.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ */
33
+ #ifndef __WANTED__
34
+ #define __WANTED__
35
+
36
+ #include "atoms.h"
37
+
38
+ #define W_RANGE 0
39
+ #define W_ANY 1
40
+ #define W_ATOM 2
41
+
42
+ typedef struct wanted_def {
43
+ struct wanted_def *next;
44
+ int type;
45
+ int startres;
46
+ union {
47
+ int endres;
48
+ char atom[AN_LEN];
49
+ } w;
50
+ } WANTED;
51
+
52
+ extern int wanted(ATOM *ap, WANTED *wlist);
53
+
54
+ #endif