[med-svn] [probe] 01/02: Imported Upstream version 2.13.110909
Malihe Asemani
mali-guest at moszumanska.debian.org
Fri Aug 7 20:19:57 UTC 2015
This is an automated email from the git hooks/post-receive script.
mali-guest pushed a commit to branch master
in repository probe.
commit 652b7124134f255e7a40617bca0852ac0d30a534
Author: Malihe Asemani <ml.asemani at gmail.com>
Date: Fri Aug 7 20:07:43 2015 +0000
Imported Upstream version 2.13.110909
---
Makefile | 39 +
Makefile.dcrHack | 29 +
Makefile.linux | 38 +
Makefile.macOSX | 60 +
Makefile.sgi | 38 +
Makefile.sgiDebug | 38 +
Makefile.sgiold | 38 +
Makefile.sun | 38 +
Makefile.winxp-cygwin | 29 +
README.autobondrot.txt | 280 +++
README.probe.txt | 198 ++
SConscript | 27 +
abin.c | 131 ++
abin.h | 117 ++
atomprops.c | 393 ++++
atomprops.h | 251 +++
autobondrot.c | 1143 ++++++++++
autobondrot.h | 114 +
buildep | 1 +
command_line/probe.launch | 2 +
dots.c | 88 +
dots.h | 29 +
geom3d.c | 256 +++
geom3d.h | 56 +
hybrid_36_c.c | 301 +++
hybrid_36_c.h | 21 +
libtbx_refresh.py | 19 +
parse.c | 944 +++++++++
parse.h | 131 ++
probe.c | 5055 +++++++++++++++++++++++++++++++++++++++++++++
probe.h | 224 ++
readPDBrecs.c | 228 ++
readPDBrecs.h | 51 +
select.c | 671 ++++++
select.h | 35 +
stdconntable.c | 2811 +++++++++++++++++++++++++
stdconntable.h | 24 +
utility.c | 167 ++
utility.h | 45 +
39 files changed, 14160 insertions(+)
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9031bd0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,39 @@
+MACHINEFLAGS =
+CFLAGS = $(MACHINEFLAGS)
+LFLAGS = -static -lm $(MACHINEFLAGS)
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o hybrid_36_c.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h \
+ ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h \
+ ./parse.h ./probe.h ./readPDBrecs.h ./select.h \
+ ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h ./hybrid_36_c.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h \
+ ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+hybrid_36_c.o: ./hybrid_36_c.h hybrid_36_c.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.dcrHack b/Makefile.dcrHack
new file mode 100644
index 0000000..9bc28ca
--- /dev/null
+++ b/Makefile.dcrHack
@@ -0,0 +1,29 @@
+# probe Makefile hacked by dcr 060902
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+# I don't know what .c.o does, but it then invokes the probe: line
+# which has the unknown $@ --- so need more knowledge about make !!!!
+.c.o:
+ cc -c $*.c
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST)
+
+clean:
+ rm -f *.o
+
+# DO NOT DELETE THIS COMMENT LINE -- make depend uses it
+# Dependencies
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h ./parse.h ./probe.h ./readPDBrecs.h ./select.h ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS COMMENT LINE -- make depend uses it
diff --git a/Makefile.linux b/Makefile.linux
new file mode 100644
index 0000000..e6a740e
--- /dev/null
+++ b/Makefile.linux
@@ -0,0 +1,38 @@
+MACHINEFLAGS =
+CFLAGS = $(MACHINEFLAGS)
+LFLAGS = -lm $(MACHINEFLAGS)
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h \
+ ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h \
+ ./parse.h ./probe.h ./readPDBrecs.h ./select.h \
+ ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h \
+ ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.macOSX b/Makefile.macOSX
new file mode 100644
index 0000000..32855f3
--- /dev/null
+++ b/Makefile.macOSX
@@ -0,0 +1,60 @@
+# This Makefile for Probe was adopted from the gcc makefile, it will
+# generate a MACH-O file containing any mixture of MacOSX 32 bit
+# ( -arch i386 or -arch ppc) or MacOSX 64 bit ( -arch x86_64 or -arch ppc64 )
+# executables. It is up to the user of the makefile to choose which flags
+# are appropriate; but as a reminder, 10.7 is only intel 64 bit, 10.6 is only
+# intel.
+# When using a compiler from a later OS to compile against an earlier SDK,
+# minimum OS flag will need to be added after the arch flag(s). So for
+# compilation of a Snow Leopard ( 10.6 ) executable on a Lion ( 10.7 ) OS
+# computer, one should use the MacOSX10.6.sdk, the arch flag(s) i386 and/or
+# x86_64, AND a "MINOS = -mmacosx-version-min=10.6"
+
+
+ARCHFLAGi32 = -arch i386
+ARCHFLAGi64 = -arch x86_64
+ARCHFLAGp31 = -arch ppc
+ARCHFLAGp64 = -arch ppc64
+MINOS =
+# MINOS = -mmacosx-version-min=10.5
+# MINOS = -mmacosx-version-min=10.6
+
+CFLAGS = -isysroot /Developer/SDKs/MacOSX10.7.sdk $(ARCHFLAGi64) $(MINOS)
+LFLAGS = -lm -Wl,-syslibroot,/Developer/SDKs/MacOSX10.7.sdk $(ARCHFLAGi64) $(MINOS)
+
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o hybrid_36_c.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: abin.h geom3d.h utility.h abin.c
+atomprops.o: atomprops.h atomprops.c
+autobondrot.o: abin.h autobondrot.h geom3d.h readPDBrecs.h \
+ utility.h autobondrot.c
+dots.o: dots.h geom3d.h dots.c
+geom3d.o: geom3d.h geom3d.c
+parse.o: parse.h utility.h parse.c
+probe.o: abin.h atomprops.h autobondrot.h dots.h geom3d.h \
+ parse.h probe.h readPDBrecs.h select.h \
+ stdconntable.h utility.h probe.c
+readPDBrecs.o: geom3d.h readPDBrecs.h utility.h readPDBrecs.c
+select.o: abin.h atomprops.h geom3d.h parse.h select.h \
+ stdconntable.h utility.h select.c
+stdconntable.o: stdconntable.h stdconntable.c
+utility.o: utility.c
+hybrid_36_c.o: hybrid_36_c.h hybrid_36_c.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.sgi b/Makefile.sgi
new file mode 100644
index 0000000..fc14e66
--- /dev/null
+++ b/Makefile.sgi
@@ -0,0 +1,38 @@
+MACHINEFLAGS = -n32 -mips3
+CFLAGS = -O $(MACHINEFLAGS)
+LFLAGS = -lm $(MACHINEFLAGS)
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h \
+ ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h \
+ ./parse.h ./probe.h ./readPDBrecs.h ./select.h \
+ ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h \
+ ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.sgiDebug b/Makefile.sgiDebug
new file mode 100644
index 0000000..d779c68
--- /dev/null
+++ b/Makefile.sgiDebug
@@ -0,0 +1,38 @@
+MACHINEFLAGS = -g -n32 -mips3
+CFLAGS = $(MACHINEFLAGS)
+LFLAGS = -lmalloc_cv -lm $(MACHINEFLAGS)
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h \
+ ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h \
+ ./parse.h ./probe.h ./readPDBrecs.h ./select.h \
+ ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h \
+ ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.sgiold b/Makefile.sgiold
new file mode 100644
index 0000000..e6a740e
--- /dev/null
+++ b/Makefile.sgiold
@@ -0,0 +1,38 @@
+MACHINEFLAGS =
+CFLAGS = $(MACHINEFLAGS)
+LFLAGS = -lm $(MACHINEFLAGS)
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h \
+ ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h \
+ ./parse.h ./probe.h ./readPDBrecs.h ./select.h \
+ ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h \
+ ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.sun b/Makefile.sun
new file mode 100644
index 0000000..4c34595
--- /dev/null
+++ b/Makefile.sun
@@ -0,0 +1,38 @@
+MACHINEFLAGS =
+CFLAGS = -O $(MACHINEFLAGS)
+LFLAGS = -lm $(MACHINEFLAGS)
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+.c.o:
+ cc -c $*.c $(CFLAGS)
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o $(OBJLIST) $(LFLAGS)
+
+clean:
+ @rm -f *.o *.ckp
+
+install: probe
+ mv probe /local/bin
+
+installtest: probe
+ mv probe /local/bin/probeTest
+
+# DO NOT DELETE THIS LINE -- make depend uses it
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h \
+ ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h \
+ ./parse.h ./probe.h ./readPDBrecs.h ./select.h \
+ ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h \
+ ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS 2nd LINE -- make depend uses it
diff --git a/Makefile.winxp-cygwin b/Makefile.winxp-cygwin
new file mode 100644
index 0000000..f9a746f
--- /dev/null
+++ b/Makefile.winxp-cygwin
@@ -0,0 +1,29 @@
+# probe Makefile hacked by dcr 060902
+OBJLIST = dots.o abin.o readPDBrecs.o geom3d.o utility.o select.o \
+ parse.o atomprops.o stdconntable.o autobondrot.o
+
+# I don't know what .c.o does, but it then invokes the probe: line
+# which has the unknown $@ --- so need more knowledge about make !!!!
+.c.o:
+ cc -c -mno-cygwin $*.c
+
+probe: probe.o $(OBJLIST)
+ cc -o $@ probe.o -mno-cygwin $(OBJLIST)
+
+clean:
+ rm -f *.o
+
+# DO NOT DELETE THIS COMMENT LINE -- make depend uses it
+# Dependencies
+abin.o: ./abin.h ./geom3d.h ./utility.h abin.c
+atomprops.o: ./atomprops.h atomprops.c
+autobondrot.o: ./abin.h ./autobondrot.h ./geom3d.h ./readPDBrecs.h ./utility.h autobondrot.c
+dots.o: ./dots.h ./geom3d.h dots.c
+geom3d.o: ./geom3d.h geom3d.c
+parse.o: ./parse.h ./utility.h parse.c
+probe.o: ./abin.h ./atomprops.h ./autobondrot.h ./dots.h ./geom3d.h ./parse.h ./probe.h ./readPDBrecs.h ./select.h ./stdconntable.h ./utility.h probe.c
+readPDBrecs.o: ./geom3d.h ./readPDBrecs.h ./utility.h readPDBrecs.c
+select.o: ./abin.h ./atomprops.h ./geom3d.h ./parse.h ./select.h ./stdconntable.h ./utility.h select.c
+stdconntable.o: ./stdconntable.h stdconntable.c
+utility.o: utility.c
+# DO NOT DELETE THIS COMMENT LINE -- make depend uses it
diff --git a/README.autobondrot.txt b/README.autobondrot.txt
new file mode 100644
index 0000000..abfe984
--- /dev/null
+++ b/README.autobondrot.txt
@@ -0,0 +1,280 @@
+README on autobondrot JMW - 8/6/99
+
+Using the -autobondrot command line flag, probe can generate multiple
+molecular conformations by rotating atoms around defined dihedral axes
+and perform other transformations. To use this function you must construct an
+input script defining rotatable bonds, etc. Usually called .rotscr files
+they are quite similar to the @bondrot sections in a kinemage file. The
+probe command iterates over each conformation and generates a tabular output
+of the probe score and the conformation angles.
+
+Atomic coordinates for specific conformations (in PDB format) can be
+output.
+
+A simple example of how to use -autobondrot is to explore the range of
+probe scores for all conformations of a given amino acid sidechain
+to analyze how it interacts with itself and its static neighbors.
+
+HOW TO MAKE A SIDECHAIN CONFORMATION MAP IN UNIX OR LINUX
+
+First, take the PDB file (with hydrogens from reduce) and use
+prekin to make a rotatable group or mutation. In this example,
+tyrosine 61 in the PDB file 1ah7H is examined and prekin we used
+prekin to create "1ah7y61bondrot.kin".
+
+The script for sampling the scores is created with mkrotscr, which
+translates the @bondrot sections of the .kin file into the proper
+syntax for the .rotscr file.
+
+ mkrotscr 1ah7y61bondrot.kin 61 1ah7H > 1ah7y61.rotscr
+
+When running mkrotscr, the residue and PDB file are listed after the
+kinemage filename, so that mkrotscr can construct a plausible suggested
+command line for a sidechain rotation in the .rotscr file. Executing
+this command will invoke probe to calculate contacts and summarize the
+result as a probe score. The proposed probe command reads the autobondrot
+information until the END_OF_INPUT marker is seen. To make this file
+an executable UNIX shell script simply "chmod +x filename".
+
+When the residue numbers are unique, an alternative way to create
+this rotation script is to use pdb2rotscr, a simple command script
+which combines prekin and mkrotscr. In our example, the command
+would be as follows.
+
+ pdb2rotscr 1ah7H 61 tyr > 1ah7y61.rotscr
+
+This .rotscr file needed to be edited because mage wrote out a third
+rotatable bond (the OH) which we did not want to explore. In addition,
+we modified the bounds of the search of chi2 from 0-359 (by 5) to 0-179
+(by 10) because the phenyl ring is symmetric and it is not neccessary
+to scan chi2 as finely as chi1. To make the file more informative
+changed the rotation names from "rot1" and "rot2" to "chi1" and "chi2".
+We only want a torsional penalty applied to chi1 so we took out all but
+the first "cos" record.
+
+A duplicate copy of the atom record for C-zeta was deleted for neatness.
+Finally, since this residue does not have any branch points which require
+independent nested rotations we can safely delete the SAVE/RESTORE pair:
+"(" and ")". The final result is as follows:
+
+probe -q -stdbonds -3 -drop -once "file1" "file1 | file2 alta not water not(sc 61)" -auto - 1ah7H <<END_OF_INPUT
+atom 1 cb tyr 61 34.219 17.937 4.659 1.00 0.00
+bondrot:chi1:78.7: 0:359:5:33.138:18.517: 5.531:34.219:17.937: 4.659
+cos:-3:60:3:
+atom 1 1hb tyr 61 34.766 18.777 4.206 1.00 0.00
+atom 1 2hb tyr 61 34.927 17.409 5.315 1.00 0.00
+atom 1 cg tyr 61 33.836 16.989 3.546 1.00 0.00
+bondrot:chi2:-11.8: 0:179:10:34.219:17.937: 4.659:33.836:16.989: 3.546
+atom 1 cd1 tyr 61 32.578 16.433 3.418 1.00 0.00
+atom 1 cd2 tyr 61 34.803 16.657 2.603 1.00 0.00
+atom 1 ce1 tyr 61 32.294 15.554 2.393 1.00 0.00
+atom 1 ce2 tyr 61 34.520 15.798 1.551 1.00 0.00
+atom 1 cz tyr 61 33.249 15.259 1.456 1.00 0.00
+atom 1 hd1 tyr 61 31.793 16.694 4.142 1.00 0.00
+atom 1 hd2 tyr 61 35.813 17.084 2.693 1.00 0.00
+atom 1 he1 tyr 61 31.299 15.089 2.328 1.00 0.00
+atom 1 he2 tyr 61 35.291 15.550 0.807 1.00 0.00
+atom 1 oh tyr 61 32.991 14.372 0.421 1.00 0.00
+atom 1 hh tyr 61 33.803 14.287 -0.156 1.00 0.00
+END_OF_INPUT
+
+We make the script executable
+
+ chmod +x 1ah7y61.rotscr
+
+A table of scores is generated by running this rotation script, which
+feeds the records up to the END_OF_INPUT to probe after the -auto flag.
+This system makes use of the "<<LABEL ... LABEL" UNIX syntax for inline
+data. The run may take several minutes.
+
+ 1ah7y61.rotscr > 1ah7y61.map
+
+Finally, the scores can be contoured by kin2Dcont and viewed in mage.
+The range of contour levels can be customized as required.
+
+ kin2Dcont 1ah7y61.map -kin -group -sampled -wrap 0 360 0 180 \
+ -gxy 5 10 -sxy 4 8 -multi -200 -20 20 orange -6 -2 2 brown \
+ -level 0 grey -multi 2 50 2 sea > 1ah7y61.cont.kin
+
+ mage 1ah7y61.cont.kin
+
+A similar program, kin3Dcont, makes contours of 3 dimensional datasets.
+Our data is uniformly sampled (-sampled) and the data are cyclic so that
+360 deg is the same as 0 deg (-wrap # # # #). This is why we only
+sampled the data up to 355 and 175 degrees in the two dimensions.
+The -gxy 5 10 and -sxy 4 8 control the size of the sampling grid in each
+dimension (5 deg by 10 deg) and the size of the spot filter
+(sdev x = 4 deg, sdev y = 8 deg) used to smooth the data. If the grid
+spacing is the same in each dimension a combined setting may be used
+(-g# and -s#). The spot filter can be varied to either increase smoothing
+(-sxy 10 20) or eliminate any smoothing (-s0). For sampled data, setting
+the spot size about equal to the grid spacing seems to work well.
+
+THE ELEMENTS OF AN AUTOBONDROT SCRIPT
+
+The input script for autobondrot is composed of records of the following
+types-
+ three transformation types: BONDROT (aka ROT), TRANS, NULL
+ three function types: COS, POLY, CONST
+ the atomic coordinates: ATOM
+ branching control: SAVE, RESTORE aka "(" and ")"
+ orientation specifier: GO
+ include files: @
+ comments: #
+
+The information on each record (except ATOM) is separated by colons and must
+be all on one line. Any line beginning with a # is ignored, providing a
+convenient means of including comments in the script. For rotations, BONDROT
+and COS records head each section of ATOM records which are subject to the
+same rotation.
+
+*BONDROT - Both the current angle of the rotatable bond and the range
+of angles to be sampled are defined on the BONDROT record, along with the
+end points of the axis. It consists of eleven data fields: the axis name,
+current angle, beginning rotation angle, final rotation angle, the amount
+of rotation, and finally the x, y and z values of the beginning and end
+of the rotation axis.
+
+The axis name does not have to be a number (e.g., chi1 or phi).
+
+The current angle can be measured with the measures tool within mage.
+
+Any atoms listed before the first BONDROT will be output but their
+coordinates will not be altered. Subsequent BONDROT records are treated
+as nested rotations. Use SAVE and RESTORE records to control where these
+nested rotations begin and end.
+
+The nested chi1, chi2 rotations in our tyrosine example are:
+
+ bondrot:chi1: 78.7: 0:359:5: 33.138:18.517:5.531: 34.219:17.937:4.659
+ ... atoms rotate about chi1 ...
+ bondrot:chi2:-11.8: 0:179:5: 34.219:17.937:4.659: 33.836:16.989:3.546
+ ... atoms rotate about chi1 then chi2 ...
+
+Here the chi1 dihedral axis is defined by the C-alpha and C-beta atoms
+while chi2 is defined by C-beta and C-gamma.
+
+Note that the axis does not have to be along a bond. For example,
+an entire molecule could be rotated around the coordinate axes.
+
+*TRANS - Probe can also translate atoms. In this case, the axis defines
+the direction of the translation, and instead of angles we have angstroms.
+
+*NULL - A null transformation does not modify the position of any atoms.
+It has no data fields.
+
+*COS - after the transformation record (e.g., BONDROT) one or more records
+can be provided which define a bias function. The most generally useful
+is the COS record which is used to add a torsional penalty to probe scores
+as we rotate around a dihedral. It consists of up to four data fields:
+scalefactor, phase offset, frequency, and a seldom used offset which defaults
+to 1. In our example, we use a torsion only with chi1
+
+ cos:-3:60:3:
+
+This describes the following function: -3*(1 - cos(3*(x - 60)))/2,
+a cosine with three peaks with a value of 0.0 at -60, +60 and 180 and
+a value of -3.0 at 0, 120 and 240.
+
+More complicated functions may be built frome those provided by ganging-up
+more than one COS, POLY or CONST record.
+
+*POLY - A polynomial can be built from one or more POLY records. It has
+three data fields: a scalefactor, offset and degree.
+
+ poly:5.0:0.0:2:
+
+results in the following quadratic: 5.0*(x - 0.0)^2
+
+*CONST - a constant value can be added to the score. This record has
+one data field: the value.
+
+*ATOM - Rotations and other transformations operate on ATOM records, listing
+each atom which is subject to the bond rotation. ATOM records may also
+be supplied prior to any BONDROT record, in which case they are not
+subject to any rotation. All ATOM records are in PDB-atom record
+format.
+
+The critical data fields are the full atom name, residue name, residue
+number and x,y,z position. The format requires data to be in specific
+columns.
+
+ atom 1hb tyr 61 34.766 18.777 4.206 1.00 0.00
+
+*SAVE - Abbreivated "(", SAVE saves the current transformation on a stack.
+
+*RESTORE - Abbreivated ")", RESTORE backs up to the last previously saved
+transformation. Save and restore are used to organize transformations
+for branching groups. For example when rotating the all sidechain angles
+of an isoleucine (including the methyl groups) the following SAVE/RESTORE
+grouping is required:
+
+ bondrot:chi1: ...
+ ...
+ (
+ bondrot:chi2: ...
+ ...
+ bondrot:CD1 meth: ...
+ ...
+ )
+ bondrot:CG2 meth: ...
+ ...
+
+*GO - GO records are optional. If included, they consist of a set of angles,
+one for each BONDROT or TRANS, in the same order. Many GO records can be
+included in a single .rotscr file.
+
+If there are no GO records, autobondrot will generate all permutations
+of conformations defined on the BONDROT records. If one or more GO
+records are found, autobondrot will not grind through all these
+permutations but will instead run the command on the specific
+conformation listed. A series of GO records will sample a discrete
+set of conformations.
+
+ go: 60: 90:
+
+In the our example the above sets chi1 to 60 deg and chi2 to 90 deg.
+
+If the -verbose option (versus -quiet or -q) is used, probe will write
+atom records for the transformed coordinates to standard error, once
+for each GO record. This may be useful as a way of generating coordinates
+for a specific orientation. To capture this standard error output in
+a file along with standard output, UNIX provides the command line
+syntax "command >& outputfile".
+
+*Include files - These records are also optional. If a line begins with
+an at sign the following text is treated as a filename (@filename) and
+probe attempts to start reading autobondrot commands from this file, to
+the end, before continuing on with the current file. Include files can be
+nested. The most common use for includes is to add in pre-defined
+batches of go statements which sample set regions of conformation
+space for a residue type.
+
+REQUIRED SOFTWARE
+
+An ensemble of programs, available for UNIX or LINUX, are required
+to run probe with the -autobondrot flag.
+
+mkrotscr - an awk script (executable ascii text file)
+probe - version 2.0 or later, a C program (binary executable)
+reduce - version 2.12 or later, a C++ program (binary executable)
+
+maxv - optional awk script used when the maximum value must
+ be selected for certain ranges of conformations.
+ For example, to select the best OH angle for a serine
+ for each Chi1 angle.
+
+Each of these programs must be placed in a directory listed in your
+PATH. If the download process has not made the files executable,
+each must be made executable with the command: "chmod +x filename".
+
+Awk is a interpreted scripting language for processing text files which
+is available on almost all UNIX systems.
+
+Probe is used in the example above to calculate contact dot scores.
+
+Reduce is listed above because hydrogens are neccessary for successful
+use of probe. Add the hydrogens to the PDB file before running prekin
+and the rest of the operations listed above.
+
+Programs are available at http://kinemage.biochem.duke.edu
diff --git a/README.probe.txt b/README.probe.txt
new file mode 100644
index 0000000..720330a
--- /dev/null
+++ b/README.probe.txt
@@ -0,0 +1,198 @@
+README.probe JMW - 7/25/01
+
+The program "probe" generates "contact dots" at points on the van der Waals
+surface of atoms which are in close proximity to other atoms [1]; reading
+atomic coordinates in protein databank (PDB) format files and writing
+color-coded dot lists (spikes where atoms clash) for inclusion in a
+kinemage.
+
+Directly based on the "sp" program by Zalis and Richardson (following the
+work of Connolly), the approach is to place a small probe (typically of
+radius 0.25A) at points along the van der Waals surface of a selected set
+of atoms and determine if this probe also contacts atoms within a second
+"target" set. A flexible method for selecting the source and target atoms
+is available along with command line flags for altering the probe radius
+and dot density. Although probe can generate "surface dots" were there are
+no nearby atoms, its primary use is to analyze atomic packing. For packing
+analysis and structure validation, probe can generate contact surfaces
+within a set of atoms ("SELF dots").
+
+For meaningful use of probe in the study of molecular structures,
+coordinates for all hydrogen atoms must be included in the model. Modeling
+with "implicit hydrogens" is inadequate since the vast majority of steric
+interactions which constrain conformational choices take place among
+hydrogens. A program called reduce, also available from the Richardson lab,
+uses simple geometric considerations to add hydrogens to a PDB file and
+optimize their orientations [2].
+
+Probe has many options which modify the way output is formatted. Instead of
+kinemage format, it can write graphical information in O or XtalView format.
+It can calculate a table of dot information with contact score values and
+percent dot coverage. Finally, it can produce a detailed "unformatted"
+description of each dot, including source and target atom names, distances,
+atom types, and partial scores. Because probe is very flexible, it is
+helpful to develop a working knowledge of options and especially selection
+criteria.
+
+NEW FEATURES:
+v2.4 (7/11/01) - Buttons are no longer generated for each element type
+ by default. To generate these buttons use the -element flag.
+
+v2.5 (7/25/01) - Selections can now refer to negative residue numbers.
+ (Sometimes you need to include extra parentheses or a
+ space to prevent the selection from being treated as
+ a command line option.)
+
+USAGE:
+Probe was designed for UNIX and the commands described below follow the
+UNIX conventions. For a brief description of probe features, run "probe"
+without any options. The command "probe -h" will give a more complete
+description of program options.
+
+In its most basic form, the syntax is
+
+ probe input.pdb >> outputDots.kin
+
+which will generate SELF dots for all atoms in the input file except
+alternate (e.g., B or C) conformations and append them to the end of the
+kinemage file. Note the ">>" redirection symbol which stands for APPEND;
+in the normal case, prekin would be used to make a kinemage of the
+molecular structure and probe would be used to append the dot information.
+
+A more extensive set of command line options is available in the format
+
+ probe [-flags] "pattern1" ["pattern2"] input.pdb [more.pdbs...] [>>outfile]
+
+(the parts in square brackets may be optional; by default the results go to
+standard output).
+
+There are four modes set by command line flags (-SELF is assumed if not given):
+
+ probe -SELF "pattern1" inputfiles >>kinfile # Intersect 1->1
+ probe -BOTH "pattern1" "pattern2" inputfiles >>kinfile # Intersect 1->2 and 2->1
+ probe -ONCE "pattern1" "pattern2" inputfiles >>kinfile # Intersect 1->2
+ probe -OUT "pattern1" inputfiles >>kinfile # External surface
+
+(How the selected atoms interact is listed above as a comment after the
+hash mark.)
+
+By default, HET groups and waters are included in the dot calculations
+but *NOT* mainchain to mainchain interactions. These settings may be
+changed with the -NOHET, -NOWATER and -MC flags.
+
+The flag -U is used to dump 'unformatted' dot information which can
+be sent to other programs or scripts for analysis. The flag -STDBONDS
+will make probe consult an internal table when deciding the bonding
+pattern. This is used in modeling where impossible conformations may
+be analyzed without the problem of improper bonding patterns being
+inferred from atomic distances.
+
+PATTERNS:
+The use of patterns to specify the interaction being examined is
+illustrated with the following examples:
+
+ probe "altA blt40" 1filH.pdb >>lowBdot.kin
+
+calculates self packing in all atoms from the file 1filH.pdb with a
+temperature factor less-than 40 and an alternate conformation code of
+blank or "A" (-self is the default and the pattern is in quotes because it
+contains a space). This is a useful pattern for validating a structure
+because it ignores atoms which may have poorly determined coordinates. In
+other situations, the pattern could be replaced with "all" to select all
+the atoms.
+
+To identify the interface between chain E and chain I in the file enzH.pdb
+
+ probe -both "chainE" "chainI" enzH.pdb >> interface.kin
+
+To create a table of contact statistics use -count.
+
+ probe -count -self "all" mypdbH > dotinfo.table
+
+The example also shows the use of a single '>' mark; the UNIX signal to
+overwrite (!) rather than append to the output file.
+
+Even more dot information for each dot can be tabulated with -unformated
+
+ probe -unformated -self "all" mypdbH > rawinfo.table
+
+You can create surface dots
+
+ probe -out all 1filH.pdb >> surfacedots.kin
+
+These dots are equivalent to the non-reentrant part of a Connolly surface.
+When using surface dots, it is sometimes useful to expand or contract
+the probe radius using the -rad#.# flag (e.g. -rad1.4 for a water size probe,
+or -rad0.0 to see a sphere-like representation of residues).
+
+Finally, here is a sequence of prekin and probe commands which can create
+a kinemage where each category of contact is broken down separately. The
+patterns used give some sense of the level of control probe permits.
+
+ prekin -lots input.pdb outputdot.kin
+ probe -3 -lens -q -name scsc -self "sc alta blt40 ogt33" input.pdb >> outputdot.kin
+ probe -3 -lens -q -name scmc -both "sc alta blt40 ogt33" "mc alta blt40 ogt33" input.pdb >> outputdot.kin
+ probe -3 -lens -q -name mcmc -mc -self "mc alta blt40 ogt33" input.pdb >> outputdot.kin
+ probe -3 -lens -q -name wathet -both "het,water alta blt40 ogt65,(not water ogt33)" \
+ "not(het,water) alta blt40 ogt33" input.pdb >> outputdot.kin
+
+AUTOBONDROT
+
+Starting with version 2.0, probe has been extended to read specially marked
+up fragments of a PDB file which describe dihedral rotations as well as
+other transformations. The command line flag -autobondrot preceeds the
+filename and causes the file to be interpreted as a script for scanning
+a range of conformations. A description of the format of these rotation
+scripts or .rotscr files is in the file README.autobondrot.txt.
+
+TROUBLESHOOTING
+
+If you don't have probe or if you have an old copy, you can get the latest
+release from ftp://kinemage.biochem.duke.edu; binary executable files are
+available for several operating systems along with source code. Make sure
+you download .exe or .tar or .gz files as BINARY. If you download an .exe
+file, you will probably wish to rename it to just "probe" and put it into
+a directory which is listed in your PATH environmental variable. For UNIX
+or LINUX you will also have to make it executable with the command:
+ chmod +x probe
+
+The source code should compile easily on almost all UNIX like systems.
+Copy the "Makefile" for your system (cp Makefile.xxx Makefile), check
+for any system specific issues (altering as required) and then type
+ make probe
+
+The most common problem using probe is specifying selection patterns.
+Remember self dots (-self, the default) takes one pattern and then
+the filename, while interface dots (-both) take two patterns before
+the filename.
+
+Output from probe is generally designed to be appended to the end of a
+kinemage file. If you just want to see the dots without creating a
+model first, add "@kinemage 1" as the first line to the dotfile (either
+by hand or using probe flag: -kin) and mage can now display it.
+
+
+REFERENCES
+
+1) Word, et. al. (1999) Visualizing and Quantifying Molecular
+ Goodness-of-Fit: Small-probe Contact Dots with Explicit Hydrogens,
+ J. Mol. Biol. 285, 1711-1733.
+
+2) Word, et. al. (1999) Asparagine and Glutamine: Using Hydrogen Atom
+ Contacts in the Choice of Side-chain Amide Orientation, J. Mol. Biol.
+ 285, 1735-1747.
+
+CONTACTS
+
+We hope this helps you get started looking at molecular contact surfaces.
+To find the latest version of probe, see http://kinemage.biochem.duke.edu.
+A comprehensive description of the small-probe method is found in [1] and
+[2].
+
+Mike Word and David Richardson
+(mike.word at duke.edu, dcr at kinemage.biochem.duke.edu)
+
+Richardson Lab
+Biochemistry Department
+Duke University
+Durham, NC USA 27710
diff --git a/SConscript b/SConscript
new file mode 100644
index 0000000..b052e9f
--- /dev/null
+++ b/SConscript
@@ -0,0 +1,27 @@
+import libtbx.load_env
+
+Import("env_base", "env_etc")
+
+env = env_base.Clone(
+ LIBS=env_etc.libm)
+if (libtbx.manual_date_stamp < 20090819):
+ # XXX backward compatibility 2009-08-19
+ env.Replace(CCFLAGS=env_etc.ccflags_base)
+if (env_etc.compiler != "win32_cl"):
+ env.Replace(LINK=env_base["CC"])
+
+exe = env.Program(
+ target=["#probe/exe/probe"],
+ source=[
+ "hybrid_36_c.c",
+ "probe.c",
+ "dots.c",
+ "abin.c",
+ "readPDBrecs.c",
+ "geom3d.c",
+ "utility.c",
+ "select.c",
+ "parse.c",
+ "atomprops.c",
+ "stdconntable.c",
+ "autobondrot.c"])
diff --git a/abin.c b/abin.c
new file mode 100644
index 0000000..79105f2
--- /dev/null
+++ b/abin.c
@@ -0,0 +1,131 @@
+/* name: abin.c */
+/* author: J. Michael Word (port from dcr and mez fortran code) */
+/* date written: 2/20/96 */
+/* purpose: organize atoms into bins to aid finding neighbors */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "utility.h"
+#include "abin.h"
+
+atomBins* initBins(char serialNum, region *boundingBox, float delta) {
+ atomBins *bp;
+ int i, j, k, nx, ny, nz;
+ int n1, n2, n3;
+ atomPtr ***b1, **b2, *b3;
+
+ if (delta < 0.1) delta = 5.0;
+
+ nx = OFFSET(boundingBox->max.x, boundingBox->min.x, delta) + 2;
+ ny = OFFSET(boundingBox->max.y, boundingBox->min.y, delta) + 2;
+ nz = OFFSET(boundingBox->max.z, boundingBox->min.z, delta) + 2;
+
+ bp = (atomBins *)malloc(sizeof(atomBins));
+
+ bp->delta = delta;
+
+ bp->min = boundingBox->min;
+ bp->max = boundingBox->max;
+ v3sub(&(bp->max), &(bp->min), &(bp->sz));
+ bp->nx = nx;
+ bp->ny = ny;
+ bp->nz = nz;
+ bp->binSerialNum = serialNum;
+
+ n1 = nx;
+ n2 = nx*ny;
+ n3 = nx*ny*nz;
+
+ b1 = (atomPtr ***)malloc(sizeof(atomPtr **)*n1);
+ b2 = (atomPtr **)malloc(sizeof(atomPtr *)*n2);
+ b3 = (atomPtr *)malloc(sizeof(atomPtr )*n3);
+ if (!bp || !b1 || !b2 || !b3) {
+ warn("could not create atom bins");
+ if (bp) free(bp);
+ if (b1) free(b1);
+ if (b2) free(b2);
+ if (b3) free(b3);
+ return NULL;
+ }
+
+ bp->list = b1;
+
+ for(i = 0; i < nx; i++) {
+ bp->list[i] = b2; b2 += ny;
+
+ for(j = 0; j < ny; j++) {
+ bp->list[i][j] = b3; b3 += nz;
+
+ for(k = 0; k < nz; k++) {
+ bp->list[i][j][k] = 0;
+ }
+ }
+ }
+
+ return bp;
+}
+
+void disposeBins(atomBins* bins) {
+ if (bins) {
+ free(bins->list[0][0]);
+ free(bins->list[0]);
+ free(bins->list);
+ free(bins);
+ }
+}
+
+void updateBoundingBox(point3d *loc, region *bb) {
+ if (loc->x < bb->min.x) {bb->min.x = loc->x;}
+ if (loc->y < bb->min.y) {bb->min.y = loc->y;}
+ if (loc->z < bb->min.z) {bb->min.z = loc->z;}
+
+ if (loc->x > bb->max.x) {bb->max.x = loc->x;}
+ if (loc->y > bb->max.y) {bb->max.y = loc->y;}
+ if (loc->z > bb->max.z) {bb->max.z = loc->z;}
+}
+
+void growBoundingBox(float margin, region *bb) {
+ bb->min.x -= margin; bb->min.y -= margin; bb->min.z -= margin;
+ bb->max.x += margin; bb->max.y += margin; bb->max.z += margin;
+}
+
+void addBBox2BBox(region *abb, region *bb) {
+ if (abb->min.x < bb->min.x) {bb->min.x = abb->min.x;}
+ if (abb->min.y < bb->min.y) {bb->min.y = abb->min.y;}
+ if (abb->min.z < bb->min.z) {bb->min.z = abb->min.z;}
+
+ if (abb->max.x > bb->max.x) {bb->max.x = abb->max.x;}
+ if (abb->max.y > bb->max.y) {bb->max.y = abb->max.y;}
+ if (abb->max.z > bb->max.z) {bb->max.z = abb->max.z;}
+}
+
+void addNeighbor(atom *a, atomBins *bins) {
+
+ binLoc(&(a->loc), &(a->ix), &(a->iy), &(a->iz), bins);
+
+ /* record bin identifier */
+ a->binSerialNum = bins->binSerialNum;
+
+ /* add atom in as first link in neighbor list */
+ a->nextInBin = bins->list[a->ix][a->iy][a->iz];
+
+ bins->list[a->ix][a->iy][a->iz] = a;
+}
+
+void binLoc(point3d *loc, int *ix, int *iy, int *iz, atomBins *bins) {
+
+ *ix = OFFSET(loc->x, bins->min.x, bins->delta);
+ *iy = OFFSET(loc->y, bins->min.y, bins->delta);
+ *iz = OFFSET(loc->z, bins->min.z, bins->delta);
+}
+
diff --git a/abin.h b/abin.h
new file mode 100644
index 0000000..1cde41e
--- /dev/null
+++ b/abin.h
@@ -0,0 +1,117 @@
+/* name: abin.h */
+/* author: J. Michael Word (port from dcr and mez fortran code) */
+/* date written: 2/20/96 */
+/* purpose: organize atoms into bins to aid finding neighbors */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef ABIN_H
+#define ABIN_H 1
+
+#include <math.h>
+#include "geom3d.h"
+
+typedef struct { /* 3D bounding region */
+ point3d min, max;
+} region;
+
+#define FPRINT_ATOMNAME(outf, aptr) \
+ fprintf((outf), "%4.4s%c%3.3s%2s%4d%c", \
+ (aptr)->atomname, (aptr)->altConf, \
+ (aptr)->r->resname, (aptr)->r->chain, \
+ (aptr)->r->resid, (aptr)->r->resInsCode)
+
+struct residue_t;
+
+typedef struct atom_t {
+ struct atom_t *next; /* primary list of atoms */
+ struct atom_t *nextInBin; /* list of atoms in same bin */
+ struct atom_t *scratch; /* used for arbitrary atom lists */
+
+ char* bondedto; /* for H atoms where the parent atom is specified */
+ /* for heavy atoms, the list of bonded heavy atoms */
+ /* are listed (for standard residues) */
+
+ int mark; /* general purpose (e.g. used for marking bonded atoms) */
+
+ int flags; /* selection mechanism */
+ int props; /* property flags */
+
+ int elem; /* elememt number */
+ int atomclass; /* either elem or (for H) the parent elem or -1 (for unknown) */
+
+ point3d loc; /* xyz position */
+ int ix, iy, iz; /* address in bins */
+
+ float radius; /* VDW radius */
+ float covRad; /* covalent radius */
+
+ float occ; /* fractional occupancy */
+ float bval; /* temperature factor */
+
+ struct residue_t *r;
+ char atomname[5];
+
+ char altConf; /* atom alternate conformation code */
+ char binSerialNum; /* identifies bin where (ix,iy,iz) applies */
+} atom, *atomPtr;
+
+typedef struct ringInfo_t {
+ struct ringInfo_t *nextRing; /* ring info list */
+
+ point3d ringNormal; /* direction for aromatic ring */
+ point3d ringCenter; /* center of aromatic ring */
+} ringInfo, *ringInfoPtr;
+
+typedef struct residue_t {
+ struct residue_t *nextRes; /* list of residues */
+ atom *a; /* pointer to first atom */
+
+ ringInfo *ring; /* pointer to ring info list */
+
+ int file; /* which file did atom come from? */
+ int model; /* which model is the atom for? */
+
+ int resid; /* residue number */
+ char Hy36resno[5]; /* Hybrid 36 residue number */
+ int rescnt; /* residue order 1, 2, 3, ... */
+
+ char segid[5]; /* segment identifier */
+ char resname[5]; /* residue name */
+ char resInsCode; /* insertion code */
+
+ char chain[3]; /* peptide chain code */
+} residue, *residuePtr;
+
+typedef struct {
+ point3d min, max, sz; /* bounding box and span */
+ int nx, ny, nz; /* bin size in each dimension */
+ float delta; /* size bin edges in angstroms */
+ char binSerialNum; /* identifier */
+ atomPtr ***list; /* 3d matrix of atom lists */
+} atomBins;
+
+#define OFFSET(val, min, delta) floor(1.0 + ((val)-(min))/(delta))
+
+#define isDummyAtom(a) ((a).loc.x >= 9998.0 \
+ && (a).loc.y >= 9998.0 \
+ && (a).loc.z >= 9998.0)
+
+atomBins* initBins(char serialNum, region *boundingBox, float delta);
+void disposeBins(atomBins* bins);
+void updateBoundingBox(point3d *loc, region *boundingBox);
+void growBoundingBox(float margin, region *bb);
+void addBBox2BBox(region *abb, region *bb);
+void addNeighbor(atom *a, atomBins *bins);
+void binLoc(point3d *loc, int *ix, int *iy, int *iz, atomBins *bins);
+
+#endif
+
diff --git a/atomprops.c b/atomprops.c
new file mode 100644
index 0000000..28a993d
--- /dev/null
+++ b/atomprops.c
@@ -0,0 +1,393 @@
+/* name: atomprops.c */
+/* author: J. Michael Word date written: 6/12/97 */
+/* purpose: define atom properties */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <stdio.h>
+#include <string.h> /*060902 needs this for strlen() */
+#include <ctype.h>
+#define INIT_ATOM_TABLE 1
+#include "atomprops.h"
+
+static atomProp* AtomTblIndex[NUMATOMTYPES];
+static float ExplMaxRad = 0.0;
+static float ImplMaxRad = 0.0;
+
+void initalizeAtomTbl() {
+ int i;
+ atomProp *ap;
+
+ ExplMaxRad = 0.0;
+ ImplMaxRad = 0.0;
+ for(i=0; i < NUMATOMTYPES; i++) { /* default to noAtom */
+ AtomTblIndex[i] = &(AtomTbl[0]);
+ }
+
+ for(i=0; i < NUMATOMTYPES; i++) {
+ ap = &(AtomTbl[i]);
+ AtomTblIndex[ap->type] = ap;
+
+ if (ap->iRad > ImplMaxRad){ ImplMaxRad = ap->iRad; }
+ if (ap->eRad > ExplMaxRad){ ExplMaxRad = ap->eRad; }
+ }
+}
+
+int getAtno(int a) { return AtomTblIndex[a]->atno; }
+char* getAtomName(int a) { return AtomTblIndex[a]->name; }
+float getExplRad(int a) { return AtomTblIndex[a]->eRad; }
+float getImplRad(int a) { return AtomTblIndex[a]->iRad; }
+float getCovRad(int a) { return AtomTblIndex[a]->covRad; }
+char* getColor(int a) { return AtomTblIndex[a]->color; }
+float getMaxRadius(int isImpl){
+ return (isImpl? ImplMaxRad : ExplMaxRad);
+}
+int atomHasProp(int a, int f) {
+ return AtomTblIndex[a]->flags & f;
+}
+
+int fixAtomName(const char* atomname, char resname[], int position) { /* no bool in C */
+ char resn[6];
+ char name[5] = " ";
+ int i;
+ sprintf(resn, ":%-3.3s:", resname);
+ for (i = 0; i < 4; i++) { /* uppercase the input */
+ if (atomname[i] == '\0') { break; }
+ name[i] = toupper(atomname[i]);
+ }
+ name[i] = '\0';
+ switch(name[position]) {
+ case 'E': if (strstr(HE_RESNAMES, resn) != NULL) { return 1; }
+ case 'F': if (strstr(HF_RESNAMES, resn) != NULL) { return 1; }
+ case 'G': if (strstr(HG_RESNAMES, resn) != NULL) { return 1; }
+ case 'O': if (strstr(HO_RESNAMES, resn) != NULL) { return 1; }
+ case 'S': if (strstr(HS_RESNAMES, resn) != NULL) { return 1; }
+ default: break;
+ }
+ return 0;
+}
+
+int identifyAtom(char* name, char resname[], int Verbose) { /*dcr041007 allow warning choice*/
+ int n = -1, emitWarning = 0;
+
+ switch(name[0]) {
+ case '*': case '\'': case '"': case '`': case '_':
+ case '+': case '-': case ' ':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ switch(name[1]) {
+ case 'A':
+ switch(name[3]) {
+ case '1': n = atomO; emitWarning = 1; break;
+ case '2': n = atomN; emitWarning = 1; break;
+ } break;
+ case 'B': n = atomB; break;
+ case 'C': n = atomC; break;
+ case 'D': n = atomH; break;
+ case 'F': n = atomF; break;
+ case 'H':
+ switch(name[2]) {
+ case 'E': n = fixAtomName(name,resname,2) ? atomHe : atomH; break;
+ case 'F': n = fixAtomName(name,resname,2) ? atomHf : atomH; break;
+ case 'G': n = fixAtomName(name,resname,2) ? atomHg : atomH; break;
+ case 'O': n = fixAtomName(name,resname,2) ? atomHo : atomH; break;
+/* case 'S': n = fixAtomName(name,resname,2) ? atomHs : atomH; break; */
+ default : n = atomH; break;
+ } break;
+ case 'I': n = atomI; break;
+ case 'K': n = atomK; break;
+ case 'N': n = atomN; break;
+ case 'O': n = atomO; break;
+ case 'P': n = atomP; break;
+ /*case 'S': n = atomS; break;*/
+ case 'S':
+ if(name[0] == ' ' && name[2] == 'E')
+ {/*_SE likely refmac,cns missplaced Selenium atom name dcr041007*/
+ n = atomSe; emitWarning = 1; break;
+ }
+ else {n = atomS; break;} /*050121 NO warning for other S*/
+ case 'U': n = atomU; break;
+ case 'V': n = atomV; break;
+ case 'W': n = atomW; break;
+ case 'Y': n = atomY; break;
+ } break;
+ case 'A':
+ switch(name[1]) {
+ case 'C': n = atomC; emitWarning = 1;break;/*nonstd!*/
+ case 'G': n = atomAg; break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'L': n = atomAl; break;
+ case 'M': n = atomAm; break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomO; emitWarning = 1;break;
+ case 'P': n = atomP; emitWarning = 1;break;
+ case 'R': n = atomAr; break;
+ case 'S': n = atomAs; break;
+ case 'T': n = atomAt; break;
+ case 'U': n = atomAu; break;
+ } break;
+ case 'B':
+ switch(name[1]) {
+ case 'A': n = atomBa; break;
+ case 'E': n = atomBe; break;
+ case 'I': n = atomBi; break;
+ case 'K': n = atomBk; break;
+ case 'R': n = atomBr; break;
+ } break;
+ case 'C':
+ switch(name[1]) {
+ case 'A': n = atomCa; break;
+ case 'C': n = atomC; emitWarning = 1;break;
+ case 'D': n = atomCd; break;
+ case 'E': n = atomCe; break;
+ case 'F': n = atomCf; break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'L': n = atomCl; break;
+ case 'M': n = atomCm; break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomCo; emitWarning = 1;break;
+ case 'P': n = atomP; emitWarning = 1;break;
+ case 'R': n = atomCr; break;
+ case 'S': n = atomCs; break;
+ case 'U': n = atomCu; break;
+ default: n = atomC; emitWarning = 1;break;
+ } break;
+ case 'D':
+ switch(name[1]) {
+ case 'Y': n = atomDy; break;
+ case 'C': n = atomC; emitWarning = 1;break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomO; emitWarning = 1;break;
+ case 'P': n = atomP; emitWarning = 1;break;
+ default: n = atomH; emitWarning = 1;break;
+ } break;
+ case 'E':
+ switch(name[1]) {
+ case 'R': n = atomEr; break;
+ case 'S': n = atomEs; break;
+ case 'U': n = atomEu; break;
+ case 'C': n = atomC; emitWarning = 1;break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomO; emitWarning = 1;break;
+ case 'P': n = atomP; emitWarning = 1;break;
+ } break;
+ case 'F':
+ switch(name[1]) {
+ case 'E': n = atomFe; break;
+ case 'M': n = atomFm; break;
+ case 'R': n = atomFr; break;
+ case 'C': n = atomC; emitWarning = 1;break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomO; emitWarning = 1;break;
+ case 'P': n = atomP; emitWarning = 1;break;
+ } break;
+ case 'G':
+ switch(name[1]) {
+ case 'A': n = atomGa; break;
+ case 'D': n = atomGd; break;
+ case 'E': n = atomGe; break;
+ case 'C': n = atomC; emitWarning = 1;break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomO; emitWarning = 1;break;
+ case 'P': n = atomP; emitWarning = 1;break;
+ } break;
+ case 'H':
+ switch(name[1]) {
+ case 'E': n = fixAtomName(name,resname,1) ? atomHe : atomH; break;
+ case 'F': n = fixAtomName(name,resname,1) ? atomHf : atomH; break;
+ case 'G': n = fixAtomName(name,resname,1) ? atomHg : atomH; break;
+ case 'O': n = fixAtomName(name,resname,1) ? atomHo : atomH; break;
+/* case 'S': n = fixAtomName(name,resname,1) ? atomHs : atomH; break; */
+ default : n = atomH; break;
+ } break;
+
+/* case 'E': */
+/* if (isdigit(name[2])) { n = atomH; emitWarning = 1;} */ /* Hepsilon?? */
+/* else {n = atomHe; emitWarning = 1;} */
+/* break; */
+/* case 'F': n = atomHf; emitWarning = 1;break; */
+/* case 'G': */
+/* if (isdigit(name[2])) { n = atomH; emitWarning = 1;} */ /* Hgamma?? */
+/* else {n = atomHg; emitWarning = 1;} */
+/* break; */
+/* case 'O': n = atomHo; emitWarning = 1;break; */
+/* default: n = atomH; emitWarning = 1;break; */
+/* } break; */
+
+ case 'I':
+ switch(name[1]) {
+ case 'N': n = atomIn; break;
+ case 'R': n = atomIr; break;
+ } break;
+ case 'K':
+ if (name[1] == 'R') n = atomKr; break;
+ case 'L':
+ switch(name[1]) {
+ case 'A': n = atomLa; break;
+ case 'I': n = atomLi; break;
+ case 'U': n = atomLu; break;
+ } break;
+ case 'M':
+ switch(name[1]) {
+ case 'D': n = atomMd; break;
+ case 'G': n = atomMg; break;
+ case 'N': n = atomMn; break;
+ case 'O': n = atomMo; break;
+ } break;
+ case 'N':
+ switch(name[1]) {
+ case 'A': n = atomNa; emitWarning = 1;break;
+ case 'B': n = atomNb; emitWarning = 1;break;
+ case 'C': n = atomC; emitWarning = 1;break;
+ case 'D': n = atomNd; emitWarning = 1;break;
+ case 'E': n = atomNe; emitWarning = 1;break;
+ case 'H': n = atomH; emitWarning = 1;break;
+ case 'I': n = atomNi; break;
+ case 'N': n = atomN; emitWarning = 1;break;
+ case 'O': n = atomO; emitWarning = 1;break;/*nonstd!*/
+ case 'P': n = atomP; emitWarning = 1;break;/*nonstd!*/
+ case 'S': n = atomS; emitWarning = 1;break;
+ default: n = atomN; emitWarning = 1;break;
+ } break;
+ case 'O':
+ switch(name[1]) {
+ case 'S': n = atomOs; break;
+ default: n = atomO; emitWarning = 1;break;
+ } break;
+ case 'P':
+ switch(name[1]) {
+ case 'A': n = atomPa; emitWarning = 1;break;
+ case 'B': n = atomPb; emitWarning = 1;break;
+ case 'D': n = atomPd; emitWarning = 1;break;
+ case 'M': n = atomPm; break;
+ case 'O': n = atomPo; break;
+ case 'R': n = atomPr; break;
+ case 'T': n = atomPt; break;
+ case 'U': n = atomPu; break;
+ default: n = atomP; emitWarning = 1;break;
+ } break;
+ case 'R':
+ switch(name[1]) {
+ case 'A': n = atomRa; break;
+ case 'B': n = atomRb; break;
+ case 'E': n = atomRe; break;
+ case 'H': n = atomRh; break;
+ case 'N': n = atomRn; break;
+ case 'U': n = atomRu; break;
+ } break;
+ case 'S':
+ switch(name[1]) {
+ case 'B': n = atomSb; emitWarning = 1;break;
+ case 'C': n = atomSc; break;
+ case 'E': n = atomSe; emitWarning = 1;break;
+ case 'I': n = atomSi; break;
+ case 'M': n = atomSm; break;
+ case 'N': n = atomSn; break;
+ case 'R': n = atomSr; break;
+ default: n = atomS; emitWarning = 1;break;
+ } break;
+ case 'T':
+ switch(name[1]) {
+ case 'A': n = atomTa; break;
+ case 'B': n = atomTb; break;
+ case 'C': n = atomTc; break;
+ case 'E': n = atomTe; break;
+ case 'H': n = atomTh; break;
+ case 'I': n = atomTi; break;
+ case 'L': n = atomTl; break;
+ case 'M': n = atomTm; break;
+ } break;
+ case 'X':
+ if (name[1] == 'E') n = atomXe; break;
+ case 'Y':
+ if (name[1] == 'B') n = atomYb; break;
+ case 'Z':
+ switch(name[1]) {
+ case 'N': n = atomZn; break;
+ case 'R': n = atomZr; break;
+ } break;
+ default: break;
+ }
+
+ if (n < 0) { emitWarning = 1;
+ n = atomC;
+
+ switch(name[1]) {
+ case 'H': case 'D': n = atomH; break;
+ case 'C': n = atomC; break;
+ case 'N': n = atomN; break;
+ case 'O': n = atomO; break;
+ case 'P': n = atomP; break;
+ case 'S': n = atomS; break;
+
+ case 'I': n = atomI; break;
+ case 'K': n = atomK; break;
+ case 'V': n = atomV; break;
+ case 'W': n = atomW; break;
+ case 'U': n = atomU; break;
+
+ case 'A':
+ switch(name[2]) {
+ case 'G': n = atomAg; break;
+ case 'L': n = atomAl; break;
+ case 'S': n = atomAs; break;
+ case 'U': n = atomAu; break;
+ } break;
+ case 'F':
+ if (name[2] == 'E') n = atomFe; break;
+ case 'G':
+ if (name[2] == 'D') n = atomGd; break;
+ case 'L':
+ if (name[2] == 'I') n = atomLi; break;
+ case 'M':
+ switch(name[2]) {
+ case 'G': n = atomMg; break;
+ case 'N': n = atomMn; break;
+ case 'O': n = atomMo; break;
+ } break;
+ case 'Z':
+ if (name[2] == 'N') n = atomZn; break;
+/* --------- default if we fall through... ---------------------*/
+ default: n = atomC; break;
+ }
+ }
+ if (emitWarning && Verbose) {/*Verbose controlled dcr041007*/
+ char warnstr[5]={'_','_','_','_','\0'}; /*dcr041007*/
+ char warnresn[5]={'_','_','_','_','\0'}; /*rmi070719*/
+ char* atstr;
+ int j=0;
+ while(name[j]!='\0'&&warnstr[j]!='\0')
+ {/*explicitly show blanks so can understand atom name problem*/
+ if(name[j]==' ') {warnstr[j]='_';}
+ else {warnstr[j]=name[j];}
+ j++;
+ }
+ j=0;
+ while(resname[j]!='\0'&&warnresn[j]!='\0')
+ {/*explicitly show blanks so can understand residue/atom name problem*/
+ if(name[j]==' ') {warnresn[j]='_';}
+ else {warnresn[j]=resname[j];}
+ j++;
+ }
+ atstr = getAtomName(n);
+ if(strlen(atstr)==1)
+ {fprintf(stderr,"WARNING: atom %s from resn %s will be treated as %s\n",warnstr,warnresn,atstr);}
+ else {fprintf(stderr,"WARNING: atom %s from resn %s will be treated as %s\n",warnstr,warnresn,atstr);}
+ /*name, getAtomName(n));*/
+ }
+
+ return n;
+}
+
diff --git a/atomprops.h b/atomprops.h
new file mode 100644
index 0000000..68084dc
--- /dev/null
+++ b/atomprops.h
@@ -0,0 +1,251 @@
+/* name: atomprops.h */
+/* author: J. Michael Word date written: 6/12/97 */
+/* purpose: define atom properties */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef ATOMPROPS_H
+#define ATOMPROPS_H 1
+
+#define HE_RESNAMES \
+ "currently there are none RMI 070711"
+
+#define HF_RESNAMES \
+ ":PHF:HF3:HF5:"
+
+#define HG_RESNAMES \
+ ": HG:HG2:HGB:HGC:HGI:MAC:MBO:MMC:PHG:PMB:AAS:AMS:BE7:CMH:EMC:EMT:"
+
+#define HO_RESNAMES \
+ ": HO:HO3:"
+
+#define HS_RESNAMES \
+ "currently there are none RMI 070711"
+
+typedef struct atomProp_t {
+ int type; /* atom identifier */
+ int atno; /* atomic number */
+ char* name; /* atom name */
+ float eRad; /* (explicit H) VDW radius */
+ float iRad; /* (implicit H) VDW radius */
+ float covRad;/* covalent radius */
+ char* color; /* dot color */
+ int flags; /* element features */
+} atomProp;
+
+void initalizeAtomTbl(void);
+int fixAtomName(const char* atomname, char resname[], int position); /*rmi070719 add resname info to identifyAtom*/
+int identifyAtom(char* name, char resname[], int Verbose); /*dcr041007 allow warning choice*/
+
+int getAtno(int a);
+char* getAtomName(int a);
+float getExplRad(int a);
+float getImplRad(int a);
+float getCovRad(int a);
+char* getColor(int a);
+float getMaxRadius(int isImplicit);
+int atomHasProp(int a, int f);
+
+/* Each atom identifier (except endAtomTypes) must be in the AtomTbl */
+/* A new atom must also be added to the function identifyAtomName() and */
+/* may need to be entered in setProperties() */
+enum atomIdentifiers {
+ noAtom=0, ignoreAtom,
+ atomH, atomHarom, atomHpolar, atomHOd,
+ atomC, atomN, atomO, atomF, atomS, atomP,
+
+ atomAc, atomAg, atomAl, atomAm, atomAr, atomAs, atomAt, atomAu,
+ atomB, atomBa, atomBe, atomBi, atomBk, atomBr, atomCa, atomCd,
+ atomCe, atomCf, atomCl, atomCm, atomCo, atomCr, atomCs, atomCu,
+ atomDy, atomEr, atomEs, atomEu, atomFe, atomFm, atomFr, atomGa,
+ atomGd, atomGe, atomHe, atomHf, atomHg, atomHo, atomI, atomIn,
+ atomIr, atomK, atomKr, atomLa, atomLi, atomLu, atomMd, atomMg,
+ atomMn, atomMo, atomNa, atomNb, atomNd, atomNe, atomNi, atomNo,
+ atomNp, atomOs, atomPa, atomPb, atomPd, atomPm, atomPo, atomPr,
+ atomPt, atomPu, atomRa, atomRb, atomRe, atomRh, atomRn, atomRu,
+ atomSb, atomSc, atomSe, atomSi, atomSm, atomSn, atomSr, atomTa,
+ atomTb, atomTc, atomTe, atomTh, atomTi, atomTl, atomTm, atomU,
+ atomV, atomW, atomXe, atomY, atomYb, atomZn, atomZr,
+
+ /* base identifiers are used in a real hack to paint nucleic acid */
+ /* contacts with colors for bases as an alternative to atom colors */
+ /* (dots are catagorized in a table NUMATOMTYPES wide) */
+ baseA, baseTU, baseC, baseG, baseOther, nonBase,
+
+ endAtomTypes
+};
+
+#define isHatom(atype) (getAtno(atype) == 1)
+#define NUMATOMTYPES endAtomTypes
+
+#define COVRADFUDGE 0.2
+
+#define METALIC_ATOM_FLAG (1 << 0) /*atomProp AtomTbl flags: element features*/
+#define IONIC_ATOM_FLAG (1 << 1) /*dcr041007 partial, now on halides*/
+
+#ifdef INIT_ATOM_TABLE
+/* For non-metals, explicit VDW radii from */
+/* Gavezzotti, J. Am. Chem. Soc. (1983) 105, 5220-5225. */
+/* or, if unavailable, */
+/* Bondi, J. Phys. Chem. (1964), V68, N3, 441-451. */
+/* Covalent and ionic radii from */
+/* Advanced Inorganic Chemistry, Cotton & Wilkinson, 1962, p93. */
+
+/* from above: struct atomProp, NUMATOMTYPES from enum of atomIdentifiers*/
+ /*type; atom identifier */
+ /*atno; atomic number */
+ /*name; atom name */
+ /*eRad; (explicit H) VDW radius */
+ /*iRad; (implicit H) VDW radius */
+ /*covRad; covalent radius */
+ /*color; dot color */
+ /*flags; element features */
+
+atomProp AtomTbl[NUMATOMTYPES] = { /* noAtom must be first */
+ {noAtom, 0, "?", 1.00, 0.00, 0.00, "magenta", 0},
+ {ignoreAtom, 0, ".", 0.00, 0.00, 0.00, "grey", 0},
+
+ {atomH, 1, "H", 1.17, 0.00, 0.30, "grey", 0},
+ {atomHarom, 1, "Har", 1.00, 0.00, 0.30, "grey", 0},
+ {atomHpolar, 1, "Hpol", 1.00, 0.00, 0.30, "grey", 0},
+ {atomHOd, 1, "HOd", 1.00, 0.00, 0.30, "grey", 0},/*hb-only-dummy*/
+ {atomC, 6, "C", 1.75, 1.90, 0.77, "white", 0},
+ {atomN, 7, "N", 1.55, 1.70, 0.70, "sky", 0},
+ {atomO, 8, "O", 1.40, 1.50, 0.66, "red", 0},
+ {atomP, 15, "P", 1.80, 1.80, 1.10, "pink", 0},
+ {atomS, 16, "S", 1.80, 1.90, 1.04, "yellow", 0},
+ {atomAs, 33, "As", 2.00, 2.10, 1.21, "grey", 0},
+ {atomSe, 34, "Se", 1.90, 2.00, 1.17, "green", 0},
+/*dcr041007 halides given IONIC_ATOM_FLAG*/
+ {atomF, 9, "F", 1.30, 1.30, 0.58, "green", IONIC_ATOM_FLAG},
+ {atomCl, 17, "Cl", 1.77, 1.77, 0.99, "green", IONIC_ATOM_FLAG},
+ {atomBr, 35, "Br", 1.95, 1.95, 1.14, "brown", IONIC_ATOM_FLAG},
+ {atomI, 53, "I", 2.10, 2.10, 1.33, "brown", IONIC_ATOM_FLAG},
+
+ /* for most common metals we use Pauling's ionic radii */
+ /* "covalent radii" = ionic + 0.74 (i.e., oxygenVDW(1.4) - oxygenCov(0.66)) */
+ /* because the ionic radii are usually calculated from Oxygen-Metal distance */
+
+ {atomLi, 3, "Li", 0.60, 0.60, 1.34, "grey", METALIC_ATOM_FLAG},
+ {atomNa, 11, "Na", 0.95, 0.95, 1.69, "grey", METALIC_ATOM_FLAG},
+ {atomAl, 13, "Al", 0.50, 0.50, 1.24, "grey", METALIC_ATOM_FLAG},
+ {atomK, 19, "K", 1.33, 1.33, 2.07, "grey", METALIC_ATOM_FLAG},
+ {atomMg, 12, "Mg", 0.65, 0.65, 1.39, "grey", METALIC_ATOM_FLAG},
+ {atomCa, 20, "Ca", 0.99, 0.99, 1.73, "grey", METALIC_ATOM_FLAG},
+ {atomMn, 25, "Mn", 0.80, 0.80, 1.54, "grey", METALIC_ATOM_FLAG},
+ {atomFe, 26, "Fe", 0.74, 0.74, 1.48, "grey", METALIC_ATOM_FLAG},
+ {atomCo, 27, "Co", 0.70, 0.70, 1.44, "blue", METALIC_ATOM_FLAG},
+ {atomNi, 28, "Ni", 0.66, 0.66, 1.40, "grey", METALIC_ATOM_FLAG},
+ {atomCu, 29, "Cu", 0.72, 0.72, 1.46,"orange",METALIC_ATOM_FLAG},
+ {atomZn, 30, "Zn", 0.71, 0.71, 1.45, "grey", METALIC_ATOM_FLAG},
+ {atomRb, 37, "Rb", 1.48, 1.48, 2.22, "grey", METALIC_ATOM_FLAG},
+ {atomSr, 38, "Sr", 1.10, 1.10, 1.84, "grey", METALIC_ATOM_FLAG},
+ {atomMo, 42, "Mo", 0.93, 0.93, 1.67, "grey", METALIC_ATOM_FLAG},
+ {atomAg, 47, "Ag", 1.26, 1.26, 2.00, "white",METALIC_ATOM_FLAG},
+ {atomCd, 48, "Cd", 0.91, 0.91, 1.65, "grey", METALIC_ATOM_FLAG},
+ {atomIn, 49, "In", 0.81, 0.81, 1.55, "grey", METALIC_ATOM_FLAG},
+ {atomCs, 55, "Cs", 1.69, 1.69, 2.43, "grey", METALIC_ATOM_FLAG},
+ {atomBa, 56, "Ba", 1.29, 1.29, 2.03, "grey", METALIC_ATOM_FLAG},
+ {atomAu, 79, "Au", 1.10, 1.10, 1.84, "gold", METALIC_ATOM_FLAG},
+ {atomHg, 80, "Hg", 1.00, 1.00, 1.74, "grey", METALIC_ATOM_FLAG},
+ {atomTl, 81, "Tl", 1.44, 1.44, 2.18, "grey", METALIC_ATOM_FLAG},
+ {atomPb, 82, "Pb", 0.84, 0.84, 1.58, "grey", METALIC_ATOM_FLAG},
+
+/* for other metals we use Shannon's ionic radii */
+/* Acta Crystallogr. (1975) A32, pg751. */
+ {atomV, 23, "V", 0.79, 0.79, 1.53, "grey", METALIC_ATOM_FLAG},
+ {atomCr, 24, "Cr", 0.73, 0.73, 1.47, "grey", METALIC_ATOM_FLAG},
+ {atomTe, 52, "Te", 0.97, 0.97, 1.71, "grey", METALIC_ATOM_FLAG},
+ {atomSm, 62, "Sm", 1.08, 1.08, 1.82, "grey", METALIC_ATOM_FLAG},
+ {atomGd, 64, "Gd", 1.05, 1.05, 1.79, "grey", METALIC_ATOM_FLAG},
+ {atomYb, 70, "Yb", 1.14, 1.14, 1.88, "grey", METALIC_ATOM_FLAG},
+ {atomW, 74, "W", 0.66, 0.66, 1.40, "grey", METALIC_ATOM_FLAG},
+ {atomPt, 78, "Pt", 0.63, 0.63, 1.37, "grey", METALIC_ATOM_FLAG},
+ {atomU, 92, "U", 1.03, 1.03, 1.77, "grey", METALIC_ATOM_FLAG},
+
+/* Cotton & Wilkinson and also- */
+/* L.E. Sutton (ed.) in Table of interatomic distances and configuration in molecules */
+/* and ions, Supplement 1956-1959, Special publication No. 18, Chemical Society, */
+/* London, UK, 1965 (as listed in web-elements by Mark Winter) */
+/* http://www.shef.ac.uk/chemistry/web-elements */
+
+ {atomHe, 2, "He", 1.60, 1.60, 0.00, "sky", 0},
+ {atomBe, 4, "Be", 0.31, 0.31, 0.90, "grey", METALIC_ATOM_FLAG},
+ {atomB, 5, "B", 0.20, 0.20, 0.86, "grey", 0},
+ {atomNe, 10, "Ne", 1.60, 1.60, 0.00, "pink", 0},
+ {atomSi, 14, "Si", 2.10, 2.10, 1.17, "grey", METALIC_ATOM_FLAG},
+ {atomAr, 18, "Ar", 1.89, 1.89, 0.00, "orange", 0},
+ {atomSc, 21, "Sc", 0.68, 0.68, 0.44, "grey", METALIC_ATOM_FLAG},
+ {atomTi, 22, "Ti", 0.75, 0.75, 1.49, "grey", METALIC_ATOM_FLAG},
+ {atomGa, 31, "Ga", 0.53, 0.53, 1.27, "grey", METALIC_ATOM_FLAG},
+ {atomGe, 32, "Ge", 0.60, 0.60, 1.34, "grey", METALIC_ATOM_FLAG},
+ {atomKr, 36, "Kr", 2.01, 2.01, 1.15, "greentint", 0},
+ {atomY, 39, "Y", 0.90, 0.90, 1.64, "grey", METALIC_ATOM_FLAG},
+ {atomZr, 40, "Zr", 0.77, 0.77, 1.51, "grey", METALIC_ATOM_FLAG},
+ {atomSn, 50, "Sn", 0.71, 0.71, 1.45, "grey", METALIC_ATOM_FLAG},
+ {atomSb, 51, "Sb", 2.20, 2.20, 1.41, "grey", METALIC_ATOM_FLAG},
+ {atomXe, 54, "Xe", 2.18, 2.18, 1.28, "magenta", 0},
+ {atomLa, 57, "La", 1.03, 1.03, 1.77, "grey", METALIC_ATOM_FLAG},
+ {atomCe, 58, "Ce", 0.87, 0.87, 1.61, "grey", METALIC_ATOM_FLAG},
+ {atomFr, 87, "Fr", 1.94, 1.94, 2.68, "grey", METALIC_ATOM_FLAG},
+ {atomRa, 88, "Ra", 1.62, 1.62, 2.36, "grey", METALIC_ATOM_FLAG},
+ {atomTh, 90, "Th", 1.08, 1.08, 1.82, "grey", METALIC_ATOM_FLAG},
+
+/* finally, we have a set of elements where the radii are unknown */
+/* so we use estimates and extrapolations based on web-elements data */
+ {atomNb, 41, "Nb", 0.86, 0.86, 1.40, "grey", METALIC_ATOM_FLAG},
+ {atomTc, 43, "Tc", 0.71, 0.71, 1.25, "grey", METALIC_ATOM_FLAG},
+ {atomRu, 44, "Ru", 0.82, 0.82, 1.36, "grey", METALIC_ATOM_FLAG},
+ {atomRh, 45, "Rh", 0.76, 1.76, 1.30, "grey", METALIC_ATOM_FLAG},
+ {atomPd, 46, "Pd", 1.05, 1.05, 1.59, "grey", METALIC_ATOM_FLAG},
+ {atomPr, 59, "Pr", 1.11, 1.11, 1.65, "grey", METALIC_ATOM_FLAG},
+ {atomNd, 60, "Nd", 1.10, 1.10, 1.64, "grey", METALIC_ATOM_FLAG},
+ {atomPm, 61, "Pm", 1.15, 1.15, 1.89, "grey", METALIC_ATOM_FLAG},
+ {atomEu, 63, "Eu", 1.31, 1.31, 1.85, "grey", METALIC_ATOM_FLAG},
+ {atomTb, 65, "Tb", 1.05, 1.05, 1.59, "grey", METALIC_ATOM_FLAG},
+ {atomDy, 66, "Dy", 1.05, 1.05, 1.59, "grey", METALIC_ATOM_FLAG},
+ {atomHo, 67, "Ho", 1.04, 1.04, 1.58, "grey", METALIC_ATOM_FLAG},
+ {atomEr, 68, "Er", 1.03, 1.03, 1.57, "grey", METALIC_ATOM_FLAG},
+ {atomTm, 69, "Tm", 1.02, 1.02, 1.56, "grey", METALIC_ATOM_FLAG},
+ {atomLu, 71, "Lu", 1.02, 1.02, 1.56, "grey", METALIC_ATOM_FLAG},
+ {atomHf, 72, "Hf", 0.85, 0.85, 1.46, "grey", METALIC_ATOM_FLAG},
+ {atomTa, 73, "Ta", 0.86, 0.86, 1.40, "grey", METALIC_ATOM_FLAG},
+ {atomRe, 75, "Re", 0.77, 0.77, 1.31, "grey", METALIC_ATOM_FLAG},
+ {atomOs, 76, "Os", 0.78, 0.78, 1.32, "grey", METALIC_ATOM_FLAG},
+ {atomIr, 77, "Ir", 0.80, 0.80, 1.34, "grey", METALIC_ATOM_FLAG},
+ {atomBi, 83, "Bi", 1.17, 1.17, 1.71, "grey", METALIC_ATOM_FLAG},
+ {atomPo, 84, "Po", 0.99, 0.99, 1.53, "grey", METALIC_ATOM_FLAG},
+ {atomAt, 85, "At", 0.91, 0.91, 1.45, "grey", METALIC_ATOM_FLAG},
+ {atomRn, 86, "Rn", 2.50, 2.50, 1.25, "pinktint", 0},
+ {atomAc, 89, "Ac", 1.30, 1.30, 2.00, "grey", METALIC_ATOM_FLAG},
+ {atomPa, 91, "Pa", 1.10, 1.10, 1.85, "grey", METALIC_ATOM_FLAG},
+ {atomNp, 93, "Np", 1.00, 1.00, 1.72, "grey", METALIC_ATOM_FLAG},
+ {atomPu, 94, "Pu", 1.00, 1.00, 1.67, "grey", METALIC_ATOM_FLAG},
+ {atomAm, 95, "Am", 1.00, 1.00, 1.63, "grey", METALIC_ATOM_FLAG},
+ {atomCm, 96, "Cm", 1.00, 1.00, 1.60, "grey", METALIC_ATOM_FLAG},
+ {atomBk, 97, "Bk", 1.00, 1.00, 1.58, "grey", METALIC_ATOM_FLAG},
+ {atomCf, 98, "Cf", 1.00, 1.00, 1.57, "grey", METALIC_ATOM_FLAG},
+ {atomEs, 99, "Es", 1.00, 1.00, 1.56, "grey", METALIC_ATOM_FLAG},
+ {atomFm, 100,"Fm", 1.00, 1.00, 1.55, "grey", METALIC_ATOM_FLAG},
+ {atomMd, 101,"Md", 1.00, 1.00, 1.55, "grey", METALIC_ATOM_FLAG},
+ {atomNo, 102,"No", 1.00, 1.00, 1.55, "grey", METALIC_ATOM_FLAG},
+
+ /* base identifiers are used in color hack (see note in enum above) */
+ {baseA, 0, "a", 0.00, 0.00, 0.00, "pink", 0},
+ {baseC, 0, "c", 0.00, 0.00, 0.00, "yellow", 0},
+ {baseTU, 0, "t/u", 0.00, 0.00, 0.00, "sky", 0},
+ {baseG, 0, "g", 0.00, 0.00, 0.00, "sea", 0},
+ {baseOther, 0,"other na",0.00, 0.00, 0.00, "white", 0},
+ {nonBase, 0, "nonbase",0.00, 0.00, 0.00, "grey", 0}
+};
+#endif
+
+#endif
diff --git a/autobondrot.c b/autobondrot.c
new file mode 100644
index 0000000..1bc2ede
--- /dev/null
+++ b/autobondrot.c
@@ -0,0 +1,1143 @@
+/* name: autobondrot.c */
+/* author: J. Michael Word */
+/* date written: 7/ 9/99 */
+/* purpose: manipulations of moving atoms */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "utility.h"
+#include "autobondrot.h"
+#include "readPDBrecs.h"
+
+/*describeXformDB() writes header-comments to the .map file! */
+void describeXformDB(FILE *outf, xformDatabase* xdb, char *cch);
+void fillinTransformationRec(transformData* xform, char* rec);
+xformDatabase* initXformDB();
+transformData* newTransformation(char* rec);
+transformData* deleteTransformation(transformData* xform,
+ abrAtomListProc delAtomProc, void *otherstuff);
+void appendTransformation(xformDatabase* xdb, transformData* xform);
+void appendAtomRec(transformData* xform, char* rec, abrMkAtomProc mkAtom, void *atomstuff);
+xformAtomRecords * newXformAtomRecord(char *rec, abrMkAtomProc mkAtom, void *otherstuff);
+xformAtomRecords* deleteXformAtomRecord(xformAtomRecords *xr,
+ abrAtomListProc delAtomProc, void *deletestuff);
+void indexLevels(xformDatabase* xdb);
+void buildXDBsortedAtomRecs(xformDatabase* xdb);
+void rebuildTmat(transformData* xform);
+atom* orientedAtoms(xformDatabase* xdb);
+void setOrientation(xformDatabase* xdb, goToRec* g);
+void cleanupListExtras(atom *alst, xformDatabase* xdb,
+ abrAtomListProc delAtomProc, void *deletestuff);
+void initializeXFStack(xformDatabase* xdb);
+int pushXFStack(xformDatabase* xdb, matrix4* ctm);
+void popXFStack(xformDatabase* xdb);
+matrix4* topXFStack(xformDatabase* xdb);
+double runnameAndTorsion(xformDatabase* xdb, char* buf, int max);
+void addGoToRecord(xformDatabase* xdb, char *rec);
+void XFdescribeAtomList(FILE *outf, atom* a);
+void appendBiasFunction(transformData* xform, char *rec);
+int compareXDBAtomRecs(const void *a, const void *b);
+void scanXDBinputText(xformDatabase* xdb, FILE *inf, FILE *outf,
+ abrMkAtomProc mkAtom, void *atomstuff, char *cch);
+void doListCleanupProcessing(xformDatabase* xdb, abrAtomListProc inputListProc, void *liststuff);
+
+#define MAX_XF_REC_LEN 300
+static char XFworkBuf[MAX_XF_REC_LEN + 1];
+/*e.g. angle values held in XFworkBuf for output to .map file*/
+
+/* read in records and interpret them to fillout a database */
+xformDatabase* readTransformationDatabase(FILE *inf, FILE *outf,
+ abrMkAtomProc mkAtom, void *atomstuff,
+ abrAtomListProc inputListProc, void *liststuff,
+ char *cch)
+{
+/*
+ mabis.inf == FILE *inf
+ outf == FILE *outf
+ newMovingAtom == abrMkAtomProc mkAtom
+ &mabis == void *atomstuff
+ movingAtomListProcessing == abrAtomListProc inputListProc
+ NULL == void *liststuff
+ RAW_HEADER_COMMENT == char *cch
+*/
+
+ xformDatabase* xdb = NULL;
+
+ xdb = initXformDB();
+ if (xdb)
+ {
+ scanXDBinputText(xdb, inf, outf, mkAtom, atomstuff, cch);
+
+ indexLevels(xdb);
+
+ buildXDBsortedAtomRecs(xdb);
+
+ doListCleanupProcessing(xdb, inputListProc, liststuff);
+
+ /*describeXformDB() writes header-comments to the .map file! */
+ describeXformDB(outf, xdb, cch);
+ }
+ return xdb;
+}
+
+void scanXDBinputText(xformDatabase* xdb, FILE *inf, FILE *outf,
+ abrMkAtomProc mkAtom, void *atomstuff, char *cch) {
+ transformData* xform = NULL;
+ char *s = NULL;
+ char saynull[] = "NULL:identity transformation:";
+
+ while(readRecord(inf, XFworkBuf, MAX_XF_REC_LEN) >= 0) {
+ if (isAtom(XFworkBuf) || isHet(XFworkBuf)) {
+ if (! xform) { /* make someplace to hang these atoms */
+ xform = newTransformation(saynull);
+ appendTransformation(xdb, xform);
+ }
+ if (! xform) {
+ errmsg("could not create Identity transformation - Atom skipped");
+ }
+ else if (isPseudoAtom(XFworkBuf)) { /* ignore pseudo atoms */ }
+ else {
+ appendAtomRec(xform, XFworkBuf, mkAtom, atomstuff);
+ }
+ }
+ else {
+ s = XFworkBuf + strspn(XFworkBuf, " \t\n\r");
+ if (!strncasecmp(s, "BONDROT",7)
+ || !strncasecmp(s, "ROT", 3)
+ || !strncasecmp(s, "TRANS",5)
+ || !strncasecmp(s, "SAVE", 4) || (s[0] == '(')
+ || !strncasecmp(s, "RESTORE",7) || (s[0] == ')') ) {
+ xform = newTransformation(s);
+ appendTransformation(xdb, xform);
+ }
+ else if (!strncasecmp(s, "GO", 2)) {
+ addGoToRecord(xdb, s);
+ }
+ else if (!strncasecmp(s, "COS", 3)
+ || !strncasecmp(s, "POLY", 4)
+ || !strncasecmp(s, "CONST", 5) ) {
+ if (xform) {
+ appendBiasFunction(xform, s);
+ }
+ else {
+ warn("no transformation to attach bias function:");
+ warn(s);
+ }
+ }
+ else if (s[0] == '#' || s[0] == '\0') {
+ /* comments are ok - we do nothing */
+ }
+ else if (s[0] == '@') { /* include file */
+ FILE *if2 = NULL;
+ if2 = fopen(s+1, "r");
+ if (if2) { /* recursive call */
+ fprintf(outf, "%s%s\n", cch, s);
+
+ scanXDBinputText(xdb, if2, outf, mkAtom, atomstuff, cch);
+ fclose(if2);
+ }
+ else {
+ warn("could not open include file:");
+ warn(s+1);
+ }
+ }
+ else {
+ warn("unknown record type:");
+ warn(s);
+ }
+ }
+ }
+}
+
+void discardXformDB(xformDatabase* xdb,
+ abrAtomListProc delAtomProc, void *deletestuff) {
+ int i = 0;
+ transformData *p = NULL, *next = NULL;
+ goToRec *g = NULL, *nextg = NULL;
+
+ if (xdb) {
+ for(p = xdb->xforms; p; p = next) {
+ next = p->next;
+ deleteTransformation(p, delAtomProc, deletestuff);
+ }
+ xdb->xforms = NULL;
+ xdb->last = NULL;
+
+ for(i = 0; i < MAX_XFORM_LEVELS; i++) {
+ xdb->level[i] = NULL;
+ }
+ xdb->nlevs = 0;
+ xdb->nstack = 0;
+ free(xdb->ctmstack[0]); /* all stack elements allocated in a block */
+ for(g = xdb->golist; g; g = nextg) {
+ nextg = g->next;
+ free(g);
+ }
+ if (xdb->sortedByRes) { free(xdb->sortedByRes); }
+ xdb->sortedByRes = NULL;
+
+ free(xdb);
+ }
+}
+
+void autobondrot(FILE *outf, xformDatabase* xdb,
+ abrProbeProc probeProc, void *probestuff,
+ abrAtomListProc delAtomProc, void *deletestuff,
+ int dumpGoToAtoms)
+{/*autobondrot()*/
+/*where: (see probe/autobondrot(...); )
+ outf == stderr
+ xdb == xdb
+ probeProc == movingDoCommand
+ probestuff == mcis
+ delAtomProc == deleteMovingAtom
+ deletestuff == mabis
+ dumpGoToAtoms == Verbose
+*/
+
+ int overflow = FALSE, cursor = 0;
+ transformData* xform = NULL;
+ goToRec* g = NULL;
+ atom* alst = NULL;
+ double torsionScore = 0.0;
+
+ if (xdb)
+ {
+ if (xdb->golist) /*working from a list of GO statements */
+ {/*if using GO statements: specific orientations requested */
+ for(g = xdb->golist; g; g = g->next)
+ {
+ setOrientation(xdb, g);
+
+ alst = orientedAtoms(xdb); /* atom* alst == atom *allMovingAtoms */
+ torsionScore = runnameAndTorsion(xdb, XFworkBuf, MAX_XF_REC_LEN);
+
+ /*torsionScore is NOT a score, holds angle-bias to modify score*/
+
+ if (dumpGoToAtoms)
+ {
+ fprintf(outf, "REMARK Atoms Rotated To %s\n", XFworkBuf);
+ XFdescribeAtomList(outf, alst);
+ }
+
+ probeProc(XFworkBuf, torsionScore, alst, probestuff);
+ /* process the oriented atoms */
+ /*probeProc == movingDoCommand() which calls doCommand()*/
+ /*where: (see probe.c/movingDoCommand() )
+ XFworkBuf == char* orientationName holds angle values
+ torsionScore == double scoreBias
+ alst == atom *allMovingAtoms existance implies autobondrot
+ probestuff == void *userdata == mcis
+ */
+
+ cleanupListExtras(alst, xdb, delAtomProc, deletestuff);
+ }
+ return; /* can quit when we are done with the 'go to's */
+ }/*if using GO statements: specific orientations requested */
+
+ /*else: working from intermixed atoms and transformations */
+
+ /* initialize transformation values */
+ for(cursor=0; cursor < xdb->nlevs; cursor++) {
+ xform = xdb->level[cursor];
+ xform->currVal = xform->startVal;
+ rebuildTmat(xform);
+ }
+
+#define ABR_COMP_EPSILON 0.00001
+
+ overflow = FALSE;
+ cursor = xdb->nlevs - 1;
+ while(cursor >= 0)
+ {
+ while(! overflow)
+ {
+
+ alst = orientedAtoms(xdb); /* atom* alst == atom *allMovingAtoms */
+ torsionScore = runnameAndTorsion(xdb, XFworkBuf, MAX_XF_REC_LEN);
+
+ /*torsionScore is NOT a score, holds angle-bias to modify score*/
+
+ probeProc(XFworkBuf, torsionScore, alst, probestuff);
+ /* process the oriented atoms */
+ /*probeProc == movingDoCommand() which calls doCommand()*/
+ /*where: (see probe.c/movingDoCommand() )
+ XFworkBuf == char* orientationName holds angle values
+ torsionScore == double scoreBias
+ alst == atom *allMovingAtoms existance implies autobondrot
+ probestuff == void *userdata == mcis
+ */
+
+ cleanupListExtras(alst, xdb, delAtomProc, deletestuff);
+
+ cursor = xdb->nlevs - 1;
+ xform = xdb->level[cursor];
+ xform->currVal += xform->stepVal;
+ rebuildTmat(xform);
+ overflow = (xform->stepVal > 0)
+ ? (xform->currVal > (xform->endVal + ABR_COMP_EPSILON))
+ : (xform->currVal < (xform->endVal - ABR_COMP_EPSILON));
+ }
+
+ xform = xdb->level[cursor];
+ xform->currVal = xform->startVal;
+ rebuildTmat(xform);
+
+ overflow = FALSE;
+
+ if (--cursor >= 0)
+ {
+ xform = xdb->level[cursor];
+ xform->currVal += xform->stepVal;
+ rebuildTmat(xform);
+ overflow = (xform->stepVal > 0)
+ ? (xform->currVal > (xform->endVal + ABR_COMP_EPSILON))
+ : (xform->currVal < (xform->endVal - ABR_COMP_EPSILON));
+ }
+ }
+ }
+}/*autobondrot()*/
+
+ /*describeXformDB() writes header-comments to the .map file! */
+void describeXformDB(FILE *outf, xformDatabase* xdb, char *cch)
+{
+ int n = 0, slev = 0;
+ transformData *p = NULL;
+ xformAtomRecords *xa = NULL;
+ biasFunction *f = NULL;
+ goToRec *g = NULL;
+
+ if (cch == NULL) { cch = "#"; }
+
+ if (xdb)
+ {/*xdb exists, write comments to .map file*/
+ slev = 0;
+
+ fprintf(outf, "%sAUTOBONDROT with %d variables\n", cch, xdb->nlevs);
+
+ for(p = xdb->xforms; p; p = p->next) {
+ if (p->type == NULLxform) {
+#ifdef DUMP_EXTRA_XDB_DESCR
+ fprintf(outf, "%sNULL transformation\n", cch);
+#else
+ fprintf(outf, "%s\n", cch);
+#endif
+ }
+ else if (p->type == ROTxform || p->type == TRANSxform) {
+ if (p->type == ROTxform) {
+ fprintf(outf, "%sROT ", cch);
+ }
+ else if (p->type == TRANSxform) {
+ fprintf(outf, "%sTRANS ", cch);
+ }
+ fprintf(outf, "%s ", ((p->name)?(p->name):""));
+#ifdef DUMP_EXTRA_XDB_DESCR
+ fprintf(outf, "orig %g scan from %g to %g by %g (curr %g)\n",
+ p->phase, p->startVal, p->endVal,
+ p->stepVal, p->currVal);
+#else
+ fprintf(outf, "orig %g scan from %g to %g by %g\n",
+ p->phase, p->startVal, p->endVal,
+ p->stepVal);
+#endif
+ fprintf(outf, "%s AXIS(%g, %g, %g -> %g, %g, %g)\n", cch,
+ p->a1.x, p->a1.y, p->a1.z,
+ p->a2.x, p->a2.y, p->a2.z);
+#ifdef DUMP_EXTRA_XDB_DESCR
+ fprintf(outf, "%s %12g %12g %12g %12g\n", cch,
+ p->tmat.element[0][0],
+ p->tmat.element[0][1],
+ p->tmat.element[0][2],
+ p->tmat.element[0][3]);
+ fprintf(outf, "%s %12g %12g %12g %12g\n", cch,
+ p->tmat.element[1][0],
+ p->tmat.element[1][1],
+ p->tmat.element[1][2],
+ p->tmat.element[1][3]);
+ fprintf(outf, "%s %12g %12g %12g %12g\n", cch,
+ p->tmat.element[2][0],
+ p->tmat.element[2][1],
+ p->tmat.element[2][2],
+ p->tmat.element[2][3]);
+ fprintf(outf, "%s %12g %12g %12g %12g\n", cch,
+ p->tmat.element[3][0],
+ p->tmat.element[3][1],
+ p->tmat.element[3][2],
+ p->tmat.element[3][3]);
+#endif
+ }
+ else if (p->type == SAVExform) {
+ fprintf(outf, "%sSAVE transformation (level %d)\n", cch, ++slev);
+ }
+ else if (p->type == RESTORExform) {
+ fprintf(outf, "%sRESTORE transformation (level %d)\n", cch, slev);
+ if (slev > 0) { slev--; }
+ }
+ else {
+ fprintf(outf, "%sUNKNOWN transformation (type %d)\n", cch, p->type);
+ }
+ for(f = p->funcs; f; f = f->next) {
+ if (f->type == CONSTbiasfunc) {
+ fprintf(outf, "%s CONST bias function %g\n", cch, f->v);
+ }
+ else if (f->type == POLYbiasfunc) {
+ fprintf(outf, "%s POLYNOMIAL bias function %g*(x - %g)^%g\n", cch,
+ f->v, f->ph, f->freq);
+ }
+ else if (f->type == COSbiasfunc) {
+ fprintf(outf, "%s COSINE bias function %g*(%g - cos(%g*(x - %g)))/2\n", cch,
+ f->v, f->shift, f->freq, f->ph);
+ }
+ else {
+ fprintf(outf, "%s UNKNOWN bias function type: %d\n", cch, f->type);
+ }
+ }
+
+ for(xa = p->recs; xa; xa = xa->next) {
+ fprintf(outf, "%s %4.4s%c%3.3s%2s%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f %s\n", cch,
+ xa->a->atomname, xa->a->altConf,
+ xa->a->r->resname, xa->a->r->chain,
+ xa->a->r->resid, xa->a->r->resInsCode,
+ xa->loc.x, xa->loc.y, xa->loc.z,
+ xa->a->occ, xa->a->bval, xa->a->r->segid);
+ }
+ }
+#ifdef DUMP_EXTRA_XDB_DESCR
+ for(i = 0; i < MAX_XFORM_LEVELS; i++) {
+ if (xdb->level[i]) {
+ fprintf(outf, "%sLevel%d (%s %d)\n", cch, i,
+ ((xdb->level[i]->name)?(xdb->level[i]->name):""),
+ xdb->level[i]->num);
+ }
+ }
+#endif
+ n = 0;
+ for(g = xdb->golist; g; g = g->next) {
+ ++n;
+#ifdef DUMP_EXTRA_XDB_DESCR
+ fprintf(outf, "%sGO %d", cch, n);
+ for(i = 0; i < xdb->nlevs; i++) {
+ fprintf(outf, ": %g ", g->level[i]);
+ }
+ fprintf(outf, "\n");
+#endif
+ }
+ fprintf(outf, "%sread %d GO statements\n", cch, n);
+ }/*xdb exists, write comments to .map file*/
+ else
+ {
+ fprintf(outf, "NULL xformDatabase\n");
+ }
+}
+
+void XFdescribeAtomList(FILE *outf, atom* a) {
+ int i = 0;
+ for(; a; a = a->next) {
+ fprintf(outf, "ATOM %4d %4.4s%c%3.3s%2s%4d%c %8.3f%8.3f%8.3f%6.2f%6.2f auto\n",
+ ++i, a->atomname, a->altConf,
+ a->r->resname, a->r->chain,
+ a->r->resid, a->r->resInsCode,
+ a->loc.x, a->loc.y, a->loc.z,
+ a->occ, a->bval);
+ }
+}
+
+xformDatabase* initXformDB() {
+ xformDatabase *xdb = NULL;
+ matrix4 *mp = NULL;
+ int i = 0;
+
+ xdb = (xformDatabase *)malloc(sizeof(xformDatabase));
+ if (!xdb) {
+ warn("could not create transformation database");
+ return NULL;
+ }
+
+ mp = (matrix4*)malloc(sizeof(matrix4)*MAX_XFORM_STACK_DEPTH);
+ if (!mp) {
+ warn("could not create transformation stack");
+ if (xdb) { free(xdb); }
+ return NULL;
+ }
+
+ xdb->xforms = xdb->last = NULL;
+
+ xdb->nlevs = 0;
+ for(i = 0; i < MAX_XFORM_LEVELS; i++) {
+ xdb->level[i] = NULL;
+ }
+
+ xdb->nstack = 0;
+ for(i = 0; i < MAX_XFORM_STACK_DEPTH; i++) {
+ xdb->ctmstack[i] = &(mp[i]);
+ }
+ initializeXFStack(xdb);
+
+ xdb->golist = xdb->glast = NULL;
+
+ xdb->sortedByRes = NULL;
+
+ return xdb;
+}
+
+transformData* newTransformation(char* rec) {
+ transformData* xform = NULL;
+ if (rec) {
+ xform = (transformData *)malloc(sizeof(transformData));
+ if (!xform) {
+ warn("could not create transformation");
+ return NULL;
+ }
+ xform->next = NULL;
+ xform->recs = NULL;
+ xform->lastrec = NULL;
+
+ xform->funcs = NULL;
+
+ fillinTransformationRec(xform, rec);
+ }
+ return xform;
+}
+
+void fillinTransformationRec(transformData* xform, char* rec) {
+ char *p = NULL, *s = NULL;
+
+ xform->name = NULL;
+ xform->num = -1; /* filled in during indexing */
+ xform->type = 0;
+
+ xform->phase = 0.0;
+ xform->startVal= 0.0;
+ xform->endVal = 0.0;
+ xform->stepVal = 0.0;
+ xform->currVal = 0.0; /* varied during processing */
+ xform->a1.x = 0.0;
+ xform->a1.y = 0.0;
+ xform->a1.z = 0.0;
+ xform->a2.x = 0.0;
+ xform->a2.y = 0.0;
+ xform->a2.z = 0.0;
+ v3identityMat(&(xform->tmat)); /* varied during processing */
+
+ p = strtok(rec, XFORMREC_DELIM);
+ if (p) {
+ s = p + strspn(rec, " \t");
+
+ if (!strncasecmp(s, "NULL", 4)) {
+ xform->type = NULLxform;
+ }
+ else if (!strncasecmp(s, "BONDROT", 7) || !strncasecmp(s, "ROT", 3)) {
+ xform->type = ROTxform;
+ }
+ else if (!strncasecmp(s, "TRANS", 5)) {
+ xform->type = TRANSxform;
+ }
+ else if (!strncasecmp(s, "SAVE", 4) || (s[0] == '(')) {
+ xform->type = SAVExform;
+ }
+ else if (!strncasecmp(s, "RESTORE", 7) || (s[0] == ')')) {
+ xform->type = RESTORExform;
+ }
+
+ if (xform->type == ROTxform || xform->type == TRANSxform) {
+ p = strtok(NULL, XFORMREC_DELIM);
+ xform->name = strdup(p?p:"/NULL/");
+ if (p) {
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->phase = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->startVal = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->endVal = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->stepVal = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->a1.x = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->a1.y = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->a1.z = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->a2.x = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->a2.y = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ xform->a2.z = atof(p);
+ } /* a2z */
+ } /* a2y */
+ } /* a2x */
+ } /* a1z */
+ } /* a1y */
+ } /* a1x */
+ } /* stepVal */
+ } /* endVal */
+ } /* startVal */
+ } /* phase */
+ } /* name */
+
+ /* insure agreement between range and step direction */
+ if (xform->startVal < xform->endVal) {
+ xform->stepVal = fabs(xform->stepVal);
+ }
+ else if (xform->startVal > xform->endVal) {
+ xform->stepVal = -fabs(xform->stepVal);
+ }
+ else { /* must be equal */
+ warn("TRANSFORMATION where start == end (step reset)");
+ xform->stepVal = 9999; /* error */
+ }
+ } /* ROT || TRANS */
+ } /* type */
+
+ if (xform->name == NULL) { xform->name = strdup(""); }
+}
+
+transformData* deleteTransformation(transformData* xform,
+ abrAtomListProc delAtomProc, void *deletestuff) {
+ transformData* following = NULL;
+ xformAtomRecords *p = NULL, *next = NULL;
+ biasFunction *f = NULL, *nextf = NULL;
+
+ if (xform) {
+ for (p = xform->recs; p; p = next) {
+ next = p->next;
+ deleteXformAtomRecord(p, delAtomProc, deletestuff);
+ }
+ xform->recs = xform->lastrec = NULL;
+
+ if (xform->name != NULL) {
+ free(xform->name);
+ xform->name = NULL;
+ }
+
+ for (f = xform->funcs; f; f = nextf) {
+ nextf = f->next;
+ f->next = NULL;
+ free(f);
+ }
+ xform->funcs = NULL;
+
+ following = xform->next;
+ xform->next = NULL;
+ free(xform);
+ }
+ return following;
+}
+
+void appendTransformation(xformDatabase* xdb, transformData* xform) {
+ if (xdb && xform) {
+ if (xdb->xforms == NULL) {
+ xdb->xforms = xform;
+ xdb->last = NULL;
+ }
+ if (xdb->last != NULL) {
+ xdb->last->next = xform;
+ }
+ xdb->last = xform;
+ }
+}
+
+void appendAtomRec(transformData* xform, char* rec, abrMkAtomProc mkAtom, void *atomstuff) {
+ xformAtomRecords * xr = NULL;
+
+ if (xform && rec) {
+ xr = newXformAtomRecord(rec, mkAtom, atomstuff);
+
+ if (xr) {
+ if (xform->recs == NULL) {
+ xform->recs = xr;
+ xform->lastrec = NULL;
+ }
+ if (xform->lastrec != NULL) {
+ xform->lastrec->next = xr;
+ }
+ xform->lastrec = xr;
+ }
+ }
+}
+
+xformAtomRecords * newXformAtomRecord(char *rec, abrMkAtomProc mkAtom, void *atomstuff) {
+ xformAtomRecords *xr = NULL;
+ int getAtno(int);
+
+ if (rec) {
+ xr = (xformAtomRecords *)malloc(sizeof(xformAtomRecords));
+ if (!xr) {
+ warn("could not create Xform atom record");
+ return NULL;
+ }
+ xr->next = NULL;
+ xr->a = mkAtom(rec, atomstuff);
+
+ if (xr->a) {
+ /* record the original position on the atom */
+ xr->loc = xr->a->loc; /* so that we can continually return to it */
+ }
+ else {
+ free(xr); /* may be an H when implicitH processing is being used */
+ xr = NULL;
+ }
+ }
+ return xr;
+}
+
+void doListCleanupProcessing(xformDatabase* xdb, abrAtomListProc inputListProc, void *liststuff) {
+ atom* alst = NULL, *a = NULL;
+ int i = 0;
+
+ if (xdb) {
+ alst = NULL;
+ if (xdb->sortedByRes) { /* (re-)compose the atom list from the sort index */
+ for(i=0; xdb->sortedByRes[i]; i++) {
+ a = xdb->sortedByRes[i]->a;
+ a->next = alst;
+ alst = a;
+ }
+ }
+ if (alst && inputListProc) {
+ inputListProc(alst, liststuff);
+ }
+ }
+}
+
+xformAtomRecords* deleteXformAtomRecord(xformAtomRecords *xr,
+ abrAtomListProc delAtomProc, void *deletestuff) {
+ xformAtomRecords* following = NULL;
+ if (xr) {
+ if (xr->a != NULL) {
+ delAtomProc(xr->a, deletestuff);
+ xr->a = NULL;
+ }
+
+ following = xr->next;
+ xr->next = NULL;
+ free(xr);
+ }
+ return following;
+}
+
+void indexLevels(xformDatabase* xdb) {
+ transformData* xform = NULL;
+ int n = 0;
+
+ if (xdb) {
+ n = 0;
+ for(xform = xdb->xforms; xform; xform = xform->next) {
+ if (xform->type == ROTxform || xform->type == TRANSxform) {
+ /* the NULL transformation does not get indexed (it is not a scan dimension) */
+ xform->num = n;
+ xdb->level[n++] = xform;
+ }
+ }
+ xdb->nlevs = n;
+ }
+}
+
+void buildXDBsortedAtomRecs(xformDatabase* xdb) {
+ transformData *xform = NULL;
+ xformAtomRecords *xa = NULL;
+ xformAtomRecords **srtvec = NULL;
+ int n = 0;
+
+ if (xdb) {
+ n = 0; /* first count the number of atoms */
+ for (xform = xdb->xforms; xform; xform = xform->next) {
+ for(xa = xform->recs; xa; xa = xa->next) {
+ n++;
+ }
+ }
+
+ /* build an array with extra room for a terminating null pointer */
+ srtvec = (xformAtomRecords**)malloc((n + 1)*sizeof(xformAtomRecords*));
+ if (!srtvec) {
+ errmsg("could not create atom sorted-order array");
+ xdb->sortedByRes = NULL;
+ return;
+ }
+
+ n = 0; /* now we store pointers to the AtomRecs in the array */
+ for (xform = xdb->xforms; xform; xform = xform->next) {
+ for(xa = xform->recs; xa; xa = xa->next) {
+ srtvec[n] = xa;
+ n++;
+ }
+ }
+ srtvec[n] = NULL; /* array ends with a NULL */
+
+ qsort(&(srtvec[0]), n, sizeof(xformAtomRecords*), compareXDBAtomRecs);
+
+ xdb->sortedByRes = srtvec; /* stash away the sorted array */
+ }
+}
+
+/* compare function used in sorting the transformation atom records */
+
+int compareXDBAtomRecs(const void *avptr, const void* bvptr) {
+ xformAtomRecords **ar = (xformAtomRecords **)avptr;
+ xformAtomRecords **br = (xformAtomRecords **)bvptr;
+ atom *a = NULL, *b = NULL;
+ int cmpval = 0, t = 0;
+
+ a = ar[0]->a;
+ b = br[0]->a;
+
+ /* Divide into separate residues. Atom sorting within a residue is less important. */
+
+ if (strcmp(a->r->chain, b->r->chain) > 0) { cmpval = 1; }
+ else if (strcmp(a->r->chain, b->r->chain) < 0) { cmpval = -1; }
+ else {
+ if (a->r->resid > b->r->resid) { cmpval = 1; }
+ else if (a->r->resid < b->r->resid) { cmpval = -1; }
+ else {
+ if (a->r->resInsCode > b->r->resInsCode) { cmpval = 1; }
+ else if (a->r->resInsCode < b->r->resInsCode) { cmpval = -1; }
+ else {
+ if (a->atomname[2] > b->atomname[2]) { cmpval = 1; }
+ else if (a->atomname[2] < b->atomname[2]) { cmpval = -1; }
+ else {
+ t = strcmp(a->atomname, b->atomname);
+ if (t != 0) { cmpval = t; }
+ else {
+ if (a->altConf > b->altConf) { cmpval = 1; }
+ else if (a->altConf < b->altConf) { cmpval = -1; }
+ else {
+ if (a->loc.x - 0.001 > b->loc.x) { cmpval = 1; }
+ else if (a->loc.x + 0.001 < b->loc.x) { cmpval = -1; }
+ else {
+ if (a->loc.y - 0.001 > b->loc.y) { cmpval = 1; }
+ else if (a->loc.y + 0.001 < b->loc.y) { cmpval = -1; }
+ else {
+ if (a->loc.z - 0.001 > b->loc.z) { cmpval = 1; }
+ else if (a->loc.z + 0.001 < b->loc.z) { cmpval = -1; }
+ else {
+ /* records seem to have the same name and position */
+
+ note("atom duplicated in autobondrot input");
+
+ cmpval = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return -cmpval; /* invert sort order because the list will be built "CONSed" (appended) */
+}
+
+void rebuildTmat(transformData* xform) {
+ vector3d v;
+
+ if (xform) {
+ if (xform->type == ROTxform) {
+ vector3d axis;
+ matrix4 m1, m2, m3, m4;
+ double twistangle = 0.0;
+
+ v = xform->a2;
+ v3translationMat(&v, &m1);
+
+ twistangle = xform->currVal - xform->phase;
+ v3makeVec(&(xform->a2), &(xform->a1), &axis);
+ v3rotationMat(&axis, twistangle, &m2);
+
+ v3negate(&v);
+ v3translationMat(&v, &m4);
+
+ v3matMul(&m2, &m1, &m3);
+ v3matMul(&m4, &m3, &(xform->tmat));
+ }
+ else if (xform->type == TRANSxform) {
+
+ v3sub(&(xform->a2), &(xform->a1), &v);
+ if (v3squaredLength(&v) > 0.000001) {
+ v3scale(&v, xform->currVal - xform->phase);
+ v3translationMat(&v, &(xform->tmat));
+ }
+ else { v3identityMat(&(xform->tmat)); }
+ }
+ }
+}
+
+atom* orientedAtoms(xformDatabase* xdb) {
+ transformData* xform = NULL;
+ xformAtomRecords* xa = NULL;
+ matrix4 ctm, rsltMat;
+ atom* alst = NULL, *a = NULL;
+
+ if (xdb) {
+ initializeXFStack(xdb);
+
+ v3identityMat(&ctm);
+
+ for (xform = xdb->xforms; xform; xform = xform->next) {
+ if (xform->type == SAVExform) {
+ pushXFStack(xdb, &ctm);
+ }
+ else if (xform->type == RESTORExform) {
+ ctm = * topXFStack(xdb);
+ popXFStack(xdb);
+ }
+ else if (xform != NULLxform) {
+ v3matMul(&(xform->tmat), &ctm, &rsltMat);
+ ctm = rsltMat;
+ }
+
+ for(xa = xform->recs; xa; xa = xa->next) {
+ a = xa->a;
+
+ a->loc = xa->loc; /* apply ctm to the original loc of each atom */
+ v3mulPointMat(&(a->loc), &ctm); /* and use to set the new position of the atom */
+ }
+ }
+
+ alst = NULL;
+ if (xdb->sortedByRes) { /* (re-)compose the atom list from the sort index */
+ int i = 0;
+ for(i=0; xdb->sortedByRes[i]; i++) {
+ a = xdb->sortedByRes[i]->a;
+ a->next = alst;
+ alst = a;
+ }
+ }
+ }
+
+ return alst; /* returns the list of (pre-)sorted atoms */
+}
+
+double runnameAndTorsion(xformDatabase* xdb, char* buf, int max) {
+ char *p = NULL;
+ int i = 0, n = 0;
+ double bias = 0.0, phi = 0.0;
+ biasFunction *f = NULL;
+
+ if (xdb && buf) {
+ bias = 0.0;
+ p = buf; /*dcr?: (dcr guesses) that p now points to beginning of buf */
+ for(i = 0; i < xdb->nlevs; i++) {
+ if (max > 15) { /* add value to the output buffer */
+ n = sprintf(p, "%g ", xdb->level[i]->currVal);
+ /*dcr?: that sprintf wrote n char into buf starting at p*/
+ p += n;
+ /*dcr?: p now points n nchar further along in buf*/
+ /*note the space after the %g conversion of double currVal*/
+ /*so when next char written they will have a space between*/
+ max -= n;
+
+ /*dcr?: max tracks available space in buf, now decremented by n */
+ /*buf holds the angle values in order of their use*/
+ /*it would be nice to reorder those values for output to .map file*/
+ /*e.g. so plotting of phi,tau,psi could be as phi,psi,tau ! */
+ /*probably this should be done at the output stage anyway*/
+ /*autobondrot output is from probe.c/rawEnumerate() where */
+ /*angle values are called char *rawname which seems to == buf */
+ }
+
+ /* sum up any bias functions */
+
+ for(f = xdb->level[i]->funcs; f; f = f->next) {
+ if (f->type == CONSTbiasfunc) {
+ bias += f->v;
+ }
+ else if (f->type == POLYbiasfunc) {
+ bias += f->v * pow(xdb->level[i]->currVal - f->ph, f->freq);
+ }
+ else if (f->type == COSbiasfunc) {
+ phi = f->freq * DEG2RAD * (xdb->level[i]->currVal - f->ph);
+ bias += f->v * 0.5 * (f->shift - cos(phi));
+ }
+ }
+ }
+ }
+ return bias;
+}
+
+void addGoToRecord(xformDatabase* xdb, char *rec) {
+ char *p = NULL;
+ int i = 0;
+ goToRec* g = NULL;
+
+ if (xdb && rec) {
+ g = (goToRec *)malloc(sizeof(goToRec));
+ if (!g) {
+ warn("could not create 'go to' record");
+ return;
+ }
+
+ /* initialize */
+ g->next = NULL;
+ for(i = 0; i < MAX_XFORM_LEVELS; i++) {
+ g->level[i] = 0.0;
+ }
+
+ if (! xdb->golist) { xdb->golist = g; }
+ if (xdb->glast) { xdb->glast->next = g; }
+ xdb->glast = g;
+
+ p = strtok(rec, XFORMREC_DELIM); /* type id */
+ if (p) {
+ p = strtok(NULL, XFORMREC_DELIM);
+ for(i=0; p && (i < MAX_XFORM_LEVELS); i++) {
+ g->level[i] = atof(p);
+ p = strtok(NULL, XFORMREC_DELIM);
+ }
+ }
+ }
+}
+
+/* transformation described in the database based on the 'go to' entry */
+void setOrientation(xformDatabase* xdb, goToRec* g) {
+ int i = 0;
+
+ if (xdb && g) {
+ for(i = 0; i < xdb->nlevs; i++) {
+ xdb->level[i]->currVal = g->level[i];
+ rebuildTmat(xdb->level[i]);
+ }
+ }
+}
+
+void appendBiasFunction(transformData* xform, char *rec) {
+ biasFunction *f = NULL;
+ char *p = NULL, *s = NULL;
+
+ if (xform && rec) {
+ f = (biasFunction *)malloc(sizeof(biasFunction));
+ if (!f) {
+ warn("could not create 'basis function' record");
+ return;
+ }
+
+ /* append to the transformation */
+ f->next = xform->funcs;
+ xform->funcs = f;
+
+ /* initialize */
+ f->type = CONSTbiasfunc;
+ f->v = 0.0;
+ f->ph = 0.0;
+ f->freq = 0;
+ f->shift = 0.0;
+
+ p = strtok(rec, XFORMREC_DELIM);
+ if (p) {
+ s = p + strspn(rec, " \t");
+
+ if (!strncasecmp(s, "CONST", 5)) {
+ f->type = CONSTbiasfunc;
+ }
+ else if (!strncasecmp(s, "POLY", 4)) {
+ f->type = POLYbiasfunc;
+ f->ph = 0.0;
+ f->freq = 2; /* default is a quadratic */
+ }
+ else if (!strncasecmp(s, "COS", 3)) {
+ f->type = COSbiasfunc;
+ f->ph = 60.0; /* default cos parameters (still need a scale value) */
+ f->freq = 3;
+ f->shift = 1.0;
+ }
+
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ if (nonblankstr(p)) { f->v = atof(p); }
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ if (nonblankstr(p)) { f->ph = atof(p); }
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ if (nonblankstr(p)) { f->freq = atof(p); }
+ p = strtok(NULL, XFORMREC_DELIM);
+ if (p) {
+ if (nonblankstr(p)) { f->shift = atof(p); }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/* cull out any new atoms added in processing */
+
+void cleanupListExtras(atom *alst, xformDatabase* xdb,
+ abrAtomListProc delAtomProc, void *deletestuff) {
+
+ atom *a = NULL, *prev= NULL, *next = NULL;
+ transformData *xform = NULL;
+ xformAtomRecords *xa = NULL;
+
+ if (alst && xdb) {
+ /* mark everything in the atom list */
+ for(a = alst; a; a = a->next) {
+ a->mark = 1;
+ }
+
+ /* unmark atoms reachable from the transformation database */
+ for(xform = xdb->xforms; xform; xform = xform->next) {
+ for(xa = xform->recs; xa; xa = xa->next) {
+ xa->a->mark = 0;
+ }
+ }
+
+ /* if still marked - must be extra - delete it */
+ prev = NULL;
+ for(a = alst; a; a = next) {
+ next = a->next;
+ if (a->mark) {
+ delAtomProc(a, deletestuff);
+ if (prev) { prev->next = next; }
+ }
+ else { prev = a; }
+ }
+ }
+}
+
+/* some stack manipulation functions */
+void initializeXFStack(xformDatabase* xdb) {
+ xdb->nstack = 1;
+ v3identityMat(xdb->ctmstack[0]);
+}
+
+int pushXFStack(xformDatabase* xdb, matrix4* ctm) {
+ if (xdb->nstack > 0 && xdb->nstack < MAX_XFORM_STACK_DEPTH) {
+ xdb->nstack++;
+ *(xdb->ctmstack[xdb->nstack - 1]) = *ctm;
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+void popXFStack(xformDatabase* xdb) {
+ if (xdb->nstack > 1) { xdb->nstack--; }
+}
+
+matrix4* topXFStack(xformDatabase* xdb) {
+ return (xdb->nstack > 0) ? xdb->ctmstack[xdb->nstack - 1] : NULL;
+}
diff --git a/autobondrot.h b/autobondrot.h
new file mode 100644
index 0000000..f43aee7
--- /dev/null
+++ b/autobondrot.h
@@ -0,0 +1,114 @@
+/* name: autobondrot.h */
+/* author: J. Michael Word */
+/* date written: 7/ 9/99 */
+/* purpose: manipulations of moving atoms */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef AUTOBONDROT_H
+#define AUTOBONDROT_H 1
+
+#include <stdio.h>
+#include <math.h>
+#include "abin.h"
+#include "geom3d.h"
+
+#define XFORMREC_DELIM ":"
+
+#define MAX_XFORM_LEVELS 8
+#define MAX_XFORM_STACK_DEPTH 8
+
+#define NULLxform 0
+#define ROTxform 1
+#define TRANSxform 2
+#define SAVExform 3
+#define RESTORExform 4
+
+#define CONSTbiasfunc 0
+#define COSbiasfunc 1
+#define POLYbiasfunc 2
+
+typedef atomPtr (abrMkAtomProc)(char*, void*); /* make an atom from a record */
+typedef void (abrAtomListProc)(atom*, void*); /* process a list of atoms */
+typedef void (abrProbeProc)(char*, double, atom*, void*); /* process a list of atoms */
+
+typedef struct xformAtomRecords_t {
+ struct xformAtomRecords_t *next; /* next record in list */
+ atom *a; /* atom being worked on */
+ point3d loc; /* original location (at "phase") */
+} xformAtomRecords;
+
+typedef struct goToRec_t {
+ struct goToRec_t *next; /* next record in list */
+ double level[MAX_XFORM_LEVELS]; /* value of each */
+} goToRec;
+
+typedef struct biasFunction_t {
+ struct biasFunction_t *next; /* next record in list */
+ int type; /* bias function type */
+ double v; /* scale */
+ double ph; /* phase angle or zeropoint */
+ double freq; /* cyclical frequency */
+ double shift; /* [shift - cos()] usually 1 */
+} biasFunction;
+
+typedef struct transformdata_t {
+ struct transformdata_t *next; /* list of transforms */
+
+ xformAtomRecords* recs; /* for which the current transformations apply */
+ xformAtomRecords* lastrec; /* last atom record in the list */
+
+ char *name; /* used to show the name */
+ int num; /* level number (helps when debugging) */
+
+ int type; /* ROTxform, etc. */
+
+ double phase; /* e.g. original angle in the starting structure */
+ double startVal; /* starting value */
+ double endVal; /* ending value */
+ double stepVal; /* change in value */
+
+ double currVal; /* working value (changes during processing) */
+
+ point3d a1, a2; /* axis vector end points */
+
+ matrix4 tmat; /* working transformation matrix (changes) */
+
+ biasFunction* funcs; /* list of bias functions */
+} transformData;
+
+typedef struct {
+ transformData *xforms; /* list of transformations */
+ transformData *last; /* last transformation in list */
+
+ int nlevs; /* number of adjustable levels */
+ transformData* level[MAX_XFORM_LEVELS]; /* index of each */
+
+ int nstack; /* how many CTMs on the stack */
+ matrix4* ctmstack[MAX_XFORM_STACK_DEPTH];
+
+ goToRec* golist; /* if non null, we do these instead of loop*/
+ goToRec* glast; /* last goTo record in list */
+
+ xformAtomRecords** sortedByRes; /* array of atom recs sorted by residue */
+} xformDatabase;
+
+xformDatabase* readTransformationDatabase(FILE *inf, FILE *outf,
+ abrMkAtomProc mkAtom, void *atomstuff,
+ abrAtomListProc inputListProc, void *liststuff,
+ char* cch);
+void discardXformDB(xformDatabase* db,
+ abrAtomListProc delAtomProc, void *deletestuff);
+void autobondrot(FILE *outf, xformDatabase* xdb,
+ abrProbeProc probeProc, void *probestuff,
+ abrAtomListProc delAtomProc, void *deletestuff,
+ int dumpGoToAtoms);
+#endif
diff --git a/buildep b/buildep
new file mode 100755
index 0000000..8455fe9
--- /dev/null
+++ b/buildep
@@ -0,0 +1 @@
+mkdepend -e "s,.*/usr/.*$,," -c "cc -M" makefile *.c
diff --git a/command_line/probe.launch b/command_line/probe.launch
new file mode 100755
index 0000000..f2a9bb7
--- /dev/null
+++ b/command_line/probe.launch
@@ -0,0 +1,2 @@
+# LIBTBX_SET_DISPATCHER_NAME phenix.probe
+# LIBTBX_LAUNCH_EXE
diff --git a/dots.c b/dots.c
new file mode 100644
index 0000000..73de5cd
--- /dev/null
+++ b/dots.c
@@ -0,0 +1,88 @@
+/* name: dots.c */
+/* author: J. Michael Word (port from dcr and mez fortran code) */
+/* date written: 2/20/96 */
+/* purpose: generate points on a sphere */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include "dots.h"
+
+#define PI 3.14159265359
+
+void dotSphere(pointSet *set, float radius, float density) {
+ int m;
+
+ if (set) {
+ m = estNumDots(radius, density);
+ set->n = 0;
+ set->p = (point3d *)malloc(m*sizeof(point3d));
+ if (set->p) {
+ set->n = makeDots(radius, set->p, m);
+ }
+ }
+}
+
+void freeDotSphere(pointSet *set){
+ if (set) {
+ set->n = 0;
+ if (set->p) {
+ free(set->p);
+ set->p = NULL;
+ }
+ }
+}
+
+int estNumDots(float radius, float density) {
+ float sizefact = 1.0;
+
+ /* overestimate of the number of dots */
+ return (int)floor(4.0 * PI * density * sizefact * (radius * radius));
+}
+
+int makeDots(float radius, point3d points[], int maxpnts) {
+ float offset = 0.2;
+ double ang, cosang, sinang, phi, theta, xy0, x0, y0, z0;
+ int i, j, k, odd, nequator, nvert, nhoriz;
+
+ nequator = (int)floor(sqrt(maxpnts * PI));
+
+ odd = 1;
+ ang = 5.0 * PI / 360.0;
+ cosang = cos(ang);
+ sinang = sin(ang);
+
+ i = 0;
+ nvert = nequator / 2;
+ for (j = 0; j <= nvert; j++) {
+ phi = (PI * j) / nvert;
+ z0 = cos(phi) * radius;
+ xy0= sin(phi) * radius;
+
+ nhoriz = (int)floor(nequator * sin(phi));
+ if (nhoriz < 1) nhoriz = 1;
+ for (k = 0; k < nhoriz; k++) {
+ if(odd) {theta = (2.0 * PI * k + offset)/nhoriz; }
+ else {theta = (2.0 * PI * k )/nhoriz; }
+ x0 = cos(theta) * xy0;
+ y0 = sin(theta) * xy0;
+
+ if (i >= maxpnts) return i;
+ points[i].x = x0;
+ points[i].y = y0*cosang - z0*sinang;
+ points[i].z = y0*sinang + z0*cosang;
+ i++;
+ }
+ odd = !odd;
+ }
+ return i;
+}
diff --git a/dots.h b/dots.h
new file mode 100644
index 0000000..f2ff101
--- /dev/null
+++ b/dots.h
@@ -0,0 +1,29 @@
+/* name: dots.h */
+/* purpose: routines to generate points on a sphere */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef DOTS_H
+#define DOTS_H 1
+
+#include "geom3d.h"
+
+typedef struct {
+ int n; /* number of three-dimensional points */
+ point3d *p; /* array of points */
+} pointSet;
+
+void dotSphere(pointSet *set, float radius, float density);
+void freeDotSphere(pointSet *set);
+int estNumDots(float radius, float density);
+int makeDots(float radius, point3d points[], int maxpnts);
+
+#endif
diff --git a/geom3d.c b/geom3d.c
new file mode 100644
index 0000000..7ca326b
--- /dev/null
+++ b/geom3d.c
@@ -0,0 +1,256 @@
+/* name: geom3d.c */
+/* author: J. Michael Word date written: 2/9/96 */
+/* purpose: collection of geometric primatives */
+/* from Graphics Gems book. */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <math.h>
+#include "geom3d.h"
+
+double v3squaredLength(vector3d* a) {
+ return ((a->x * a->x)+(a->y * a->y)+(a->z * a->z));
+}
+
+double v3length(vector3d* a) {
+ return(sqrt(v3squaredLength(a)));
+}
+
+vector3d* v3negate(vector3d* v) {
+ v->x = -v->x; v->y = -v->y; v->z = -v->z;
+ return(v);
+}
+
+vector3d* v3normalize(vector3d* v) {
+ double len = v3length(v);
+ if (len != 0.0) { v->x /= len; v->y /= len; v->z /= len; }
+ return(v);
+}
+
+vector3d* v3scale(vector3d* v, double newlen) {
+ double len = v3length(v), scale;
+ if (len != 0.0) {
+ scale = newlen/len;
+ v->x *= scale; v->y *= scale; v->z *= scale;
+ }
+ return(v);
+}
+
+vector3d* v3add(vector3d* a, vector3d* b, vector3d* c) {
+ c->x = a->x+b->x; c->y = a->y+b->y; c->z = a->z+b->z;
+ return(c);
+}
+
+vector3d* v3sub(vector3d* a, vector3d* b, vector3d* c) {
+ c->x = a->x-b->x; c->y = a->y-b->y; c->z = a->z-b->z;
+ return(c);
+}
+
+double v3dot(vector3d* a, vector3d* b) {
+ return((a->x*b->x) + (a->y*b->y) + (a->z*b->z));
+}
+
+vector3d* v3lerp(vector3d* lo, vector3d* hi, double alpha, vector3d* rslt) {
+
+ rslt->x = LERP(alpha, lo->x, hi->x);
+ rslt->y = LERP(alpha, lo->y, hi->y);
+ rslt->z = LERP(alpha, lo->z, hi->z);
+ return(rslt);
+}
+
+vector3d* v3cross(vector3d* a, vector3d* b, vector3d* c) {
+ c->x = (a->y*b->z) - (a->z*b->y);
+ c->y = (a->z*b->x) - (a->x*b->z);
+ c->z = (a->x*b->y) - (a->y*b->x);
+ return(c);
+}
+
+double v3distanceSq(point3d* a, point3d* b) {
+ double dx = a->x-b->x;
+ double dy = a->y-b->y;
+ double dz = a->z-b->z;
+ return((dx*dx)+(dy*dy)+(dz*dz));
+}
+
+double v3distance(point3d* a, point3d* b) {
+ return(sqrt(v3distanceSq(a, b)));
+}
+
+vector3d* v3makeVec(point3d* a, point3d* b, vector3d* v) {
+ v->x = a->x - b->x;
+ v->y = a->y - b->y;
+ v->z = a->z - b->z;
+ return(v3normalize(v));
+}
+
+matrix4* v3identityMat(matrix4* m) {
+ m->element[0][0] = 1.0;
+ m->element[0][1] = 0.0;
+ m->element[0][2] = 0.0;
+ m->element[0][3] = 0.0;
+
+ m->element[1][0] = 0.0;
+ m->element[1][1] = 1.0;
+ m->element[1][2] = 0.0;
+ m->element[1][3] = 0.0;
+
+ m->element[2][0] = 0.0;
+ m->element[2][1] = 0.0;
+ m->element[2][2] = 1.0;
+ m->element[2][3] = 0.0;
+
+ m->element[3][0] = 0.0;
+ m->element[3][1] = 0.0;
+ m->element[3][2] = 0.0;
+ m->element[3][3] = 1.0;
+
+ return(m);
+}
+
+point3d* v3mulPointMat(point3d* p, matrix4* m) {
+ double x, y, z, w;
+ x = (p->x * m->element[0][0]) +
+ (p->y * m->element[1][0]) +
+ (p->z * m->element[2][0]) +
+ m->element[3][0];
+ y = (p->x * m->element[0][1]) +
+ (p->y * m->element[1][1]) +
+ (p->z * m->element[2][1]) +
+ m->element[3][1];
+ z = (p->x * m->element[0][2]) +
+ (p->y * m->element[1][2]) +
+ (p->z * m->element[2][2]) +
+ m->element[3][2];
+ w = (p->x * m->element[0][3]) +
+ (p->y * m->element[1][3]) +
+ (p->z * m->element[2][3]) +
+ m->element[3][3];
+ p->x = x;
+ p->y = y;
+ p->z = z;
+
+ if (w != 0.0) { p->x /= w; p->y /= w; p->z /= w; }
+ return(p);
+}
+
+matrix4* v3matMul(matrix4* a, matrix4* b, matrix4* c) {
+ int i, j, k;
+ for (i=0; i < 4; i++) {
+ for (j=0; j < 4; j++) {
+ c->element[i][j] = 0.0;
+ for (k=0; k < 4; k++) {
+ c->element[i][j] +=
+ a->element[i][k] * b->element[k][j];
+ }
+ }
+ }
+ return(c);
+}
+
+/* v3rotationMat() - build a rotation matrix */
+
+matrix4* v3rotationMat(vector3d* axis, double theta, matrix4* m) {
+ double c, s, t, x, y, z;
+
+ x = axis->x;
+ y = axis->y;
+ z = axis->z;
+
+ c = cos(theta*DEG2RAD);
+ s = sin(theta*DEG2RAD);
+ t = 1.0 - c;
+
+ v3identityMat(m);
+
+ m->element[0][0] = t * x * x + c;
+ m->element[0][1] = t * x * y + z * s;
+ m->element[0][2] = t * x * z - y * s;
+
+ m->element[1][0] = t * y * x - z * s;
+ m->element[1][1] = t * y * y + c;
+ m->element[1][2] = t * y * z + x * s;
+
+ m->element[2][0] = t * z * x + y * s;
+ m->element[2][1] = t * z * y - x * s;
+ m->element[2][2] = t * z * z + c;
+
+ return(m);
+}
+
+/* v3translationMat() - build a translation matrix */
+
+matrix4* v3translationMat(vector3d* axis, matrix4* m) {
+
+ v3identityMat(m);
+
+ m->element[3][0] = axis->x;
+ m->element[3][1] = axis->y;
+ m->element[3][2] = axis->z;
+
+ return(m);
+}
+
+/* v3rotate() - rotate p around the a->b axis */
+
+point3d* v3rotate(point3d* p, double theta, point3d* a, point3d* b) {
+ vector3d axis;
+ point3d q;
+ matrix4 rotmat;
+
+ v3makeVec(b, a, &axis);
+ v3rotationMat(&axis, theta, &rotmat);
+
+ v3sub(p, b, &q);
+ v3mulPointMat(&q, &rotmat);
+ v3add(&q, b, p);
+
+ return(p);
+}
+
+/* v3angle() - calculate the angle (radians) between 3 points */
+
+double v3angle(point3d* p1, point3d* p2, point3d* p3) {
+ vector3d a, b;
+ double amag, bmag, dotval, theta;
+
+ dotval = v3dot(v3sub(p1, p2, &a), v3sub(p3, p2, &b));
+ amag = v3length(&a);
+ bmag = v3length(&b);
+
+ if (amag*bmag < 0.0001) { theta = 0.0; }
+ else { theta = acos(dotval/(amag*bmag)); }
+
+ return(theta);
+}
+
+/* v3dihedral() - calculate the dihedral angle (radians) given 4 points */
+
+double v3dihedral(point3d* p1, point3d* p2, point3d* p3, point3d* p4) {
+ vector3d a, b, c, d, e, f;
+ double dmag, emag, fmag, theta, phi;
+
+ v3cross(v3sub(p1, p2, &a), v3sub(p3, p2, &b), &d);
+ v3cross(v3sub(p2, p3, &b), v3sub(p4, p3, &c), &e);
+ dmag = v3length(&d);
+ emag = v3length(&e);
+
+ if (dmag*emag < 0.0001) { theta = 0.0; }
+ else { theta = acos(v3dot(&d, &e)/(dmag*emag)); }
+
+ v3cross(&d, &b, &f); /* this part sets the correct handedness */
+ fmag = v3length(&f);
+ if (fmag*emag < 0.0001) { phi = 0.0; }
+ else { phi = acos(v3dot(&f, &e)/(fmag*emag)); }
+
+ if (phi*RAD2DEG > 90.0) { theta = - theta; };
+
+ return(theta);
+}
diff --git a/geom3d.h b/geom3d.h
new file mode 100644
index 0000000..fe21c0c
--- /dev/null
+++ b/geom3d.h
@@ -0,0 +1,56 @@
+/* name: geom3d.h */
+/* author: J. Michael Word date written: 2/9/96 */
+/* purpose: collection of geometric primatives */
+/* from Graphics Gems book. */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef GEOM3D_H
+#define GEOM3D_H 1
+
+typedef struct {
+ double x, y, z;
+} point3d, vector3d;
+
+typedef struct {
+ double element[4][4];
+} matrix4;
+
+/* linear interpolation from l (when a=0) to h (when a=1) */
+#define LERP(a,l,h) ((l)+(((h)-(l))*(a)))
+
+#define DEG2RAD 0.017453293 /* convert degrees to radians */
+#define RAD2DEG 57.29578 /* convert radians to degrees */
+
+double v3squaredLength(vector3d* a);
+double v3length(vector3d* a);
+vector3d* v3negate(vector3d* a);
+vector3d* v3normalize(vector3d* a);
+vector3d* v3scale(vector3d* a, double newlen);
+vector3d* v3add(vector3d* a, vector3d* b, vector3d* c);
+vector3d* v3sub(vector3d* a, vector3d* b, vector3d* c);
+double v3dot(vector3d* a, vector3d* b);
+vector3d* v3lerp(vector3d* lo, vector3d* hi, double alpha, vector3d* rslt);
+vector3d* v3cross(vector3d* a, vector3d* b, vector3d* c);
+double v3distanceSq(point3d* a, point3d* b);
+double v3distance(point3d* a, point3d* b);
+vector3d* v3makeVec(point3d* a, point3d* b, vector3d* v);
+matrix4* v3identityMat(matrix4* m);
+point3d* v3mulPointMat(point3d* p, matrix4* m);
+matrix4* v3matMul(matrix4* a, matrix4* b, matrix4* c);
+matrix4* v3rotationMat(vector3d* a, double theta, matrix4* m);
+matrix4* v3translationMat(vector3d* a, matrix4* m);
+point3d* v3rotate(point3d* a,double theta,point3d* b,point3d* c);
+double v3angle(point3d* p1, point3d* p2, point3d* p3);
+double v3dihedral(point3d* p1, point3d* p2, point3d* p3, point3d* p4);
+
+#endif
+
diff --git a/hybrid_36_c.c b/hybrid_36_c.c
new file mode 100644
index 0000000..4bbdc81
--- /dev/null
+++ b/hybrid_36_c.c
@@ -0,0 +1,301 @@
+/*! C port of the hy36encode() and hy36decode() functions in the
+ hybrid_36.py Python prototype/reference implementation.
+ See the Python script for more information.
+
+ This file has no external dependencies, NOT even standard C headers.
+ Optionally, use hybrid_36_c.h, or simply copy the declarations
+ into your code.
+
+ This file is unrestricted Open Source (cctbx.sf.net).
+ Please send corrections and enhancements to cctbx at cci.lbl.gov .
+
+ See also: http://cci.lbl.gov/hybrid_36/
+
+ Ralf W. Grosse-Kunstleve, Feb 2007.
+ */
+
+/* The following #include may be commented out.
+ It is here only to enforce consistency of the declarations
+ and the definitions.
+ */
+#include "hybrid_36_c.h"
+
+/* All static functions below are implementation details
+ (and not accessible from other translation units).
+ */
+
+static
+const char*
+digits_upper() { return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+
+static
+const char*
+digits_lower() { return "0123456789abcdefghijklmnopqrstuvwxyz"; }
+
+static
+const char*
+value_out_of_range() { return "value out of range."; }
+
+static
+const char* invalid_number_literal() { return "invalid number literal."; }
+
+static
+const char* unsupported_width() { return "unsupported width."; }
+
+static
+void
+fill_with_stars(unsigned width, char* result)
+{
+ while (width) {
+ *result++ = '*';
+ width--;
+ }
+ *result = '\0';
+}
+
+static
+void
+encode_pure(
+ const char* digits,
+ unsigned digits_size,
+ unsigned width,
+ int value,
+ char* result)
+{
+ char buf[16];
+ int rest;
+ unsigned i, j;
+ i = 0;
+ j = 0;
+ if (value < 0) {
+ j = 1;
+ value = -value;
+ }
+ while (1) {
+ rest = value / digits_size;
+ buf[i++] = digits[value - rest * digits_size];
+ if (rest == 0) break;
+ value = rest;
+ }
+ if (j) buf[i++] = '-';
+ for(j=i;j<width;j++) *result++ = ' ';
+ while (i != 0) *result++ = buf[--i];
+ *result = '\0';
+}
+
+static
+const char*
+decode_pure(
+ const int* digits_values,
+ unsigned digits_size,
+ const char* s,
+ unsigned s_size,
+ int* result)
+{
+ int si, dv;
+ int have_minus = 0;
+ int have_non_blank = 0;
+ int value = 0;
+ unsigned i = 0;
+ for(;i<s_size;i++) {
+ si = s[i];
+ if (si < 0 || si > 127) {
+ *result = 0;
+ return invalid_number_literal();
+ }
+ if (si == ' ') {
+ if (!have_non_blank) continue;
+ value *= digits_size;
+ }
+ else if (si == '-') {
+ if (have_non_blank) {
+ *result = 0;
+ return invalid_number_literal();
+ }
+ have_non_blank = 1;
+ have_minus = 1;
+ continue;
+ }
+ else {
+ have_non_blank = 1;
+ dv = digits_values[si];
+ if (dv < 0 || dv >= digits_size) {
+ *result = 0;
+ return invalid_number_literal();
+ }
+ value *= digits_size;
+ value += dv;
+ }
+ }
+ if (have_minus) value = -value;
+ *result = value;
+ return 0;
+}
+
+/*! hybrid-36 encoder: converts integer value to string result
+
+ width: must be 4 (e.g. for residue sequence numbers)
+ or 5 (e.g. for atom serial numbers)
+
+ value: integer value to be converted
+
+ result: pointer to char array of size width+1 or greater
+ on return result is null-terminated
+
+ return value: pointer to error message, if any,
+ or 0 on success
+
+ Example usage (from C++):
+ char result[4+1];
+ const char* errmsg = hy36encode(4, 12345, result);
+ if (errmsg) throw std::runtime_error(errmsg);
+ */
+const char*
+hy36encode(unsigned width, int value, char* result)
+{
+ int i = value;
+ if (width == 4U) {
+ if (i >= -999) {
+ if (i < 10000) {
+ encode_pure(digits_upper(), 10U, 4U, i, result);
+ return 0;
+ }
+ i -= 10000;
+ if (i < 1213056 /* 26*36**3 */) {
+ i += 466560 /* 10*36**3 */;
+ encode_pure(digits_upper(), 36U, 0U, i, result);
+ return 0;
+ }
+ i -= 1213056;
+ if (i < 1213056) {
+ i += 466560;
+ encode_pure(digits_lower(), 36U, 0U, i, result);
+ return 0;
+ }
+ }
+ }
+ else if (width == 5U) {
+ if (i >= -9999) {
+ if (i < 100000) {
+ encode_pure(digits_upper(), 10U, 5U, i, result);
+ return 0;
+ }
+ i -= 100000;
+ if (i < 43670016 /* 26*36**4 */) {
+ i += 16796160 /* 10*36**4 */;
+ encode_pure(digits_upper(), 36U, 0U, i, result);
+ return 0;
+ }
+ i -= 43670016;
+ if (i < 43670016) {
+ i += 16796160;
+ encode_pure(digits_lower(), 36U, 0U, i, result);
+ return 0;
+ }
+ }
+ }
+ else {
+ fill_with_stars(width, result);
+ return unsupported_width();
+ }
+ fill_with_stars(width, result);
+ return value_out_of_range();
+}
+
+/*! hybrid-36 decoder: converts string s to integer result
+
+ width: must be 4 (e.g. for residue sequence numbers)
+ or 5 (e.g. for atom serial numbers)
+
+ s: string to be converted
+ does not have to be null-terminated
+
+ s_size: size of s
+ must be equal to width, or an error message is
+ returned otherwise
+
+ result: integer holding the conversion result
+
+ return value: pointer to error message, if any,
+ or 0 on success
+
+ Example usage (from C++):
+ int result;
+ const char* errmsg = hy36decode(width, "A1T5", 4, &result);
+ if (errmsg) throw std::runtime_error(errmsg);
+ */
+const char*
+hy36decode(unsigned width, const char* s, unsigned s_size, int* result)
+{
+ static int first_call = 1;
+ static int digits_values_upper[128U];
+ static int digits_values_lower[128U];
+ static const char*
+ ie_range = "internal error hy36decode: integer value out of range.";
+ unsigned i;
+ int di;
+ const char* errmsg;
+ if (first_call) {
+ first_call = 0;
+ for(i=0;i<128U;i++) digits_values_upper[i] = -1;
+ for(i=0;i<128U;i++) digits_values_lower[i] = -1;
+ for(i=0;i<36U;i++) {
+ di = digits_upper()[i];
+ if (di < 0 || di > 127) {
+ *result = 0;
+ return ie_range;
+ }
+ digits_values_upper[di] = i;
+ }
+ for(i=0;i<36U;i++) {
+ di = digits_lower()[i];
+ if (di < 0 || di > 127) {
+ *result = 0;
+ return ie_range;
+ }
+ digits_values_lower[di] = i;
+ }
+ }
+ if (s_size == width) {
+ di = s[0];
+ if (di >= 0 && di <= 127) {
+ if (digits_values_upper[di] >= 10) {
+ errmsg = decode_pure(digits_values_upper, 36U, s, s_size, result);
+ if (errmsg == 0) {
+ /* result - 10*36**(width-1) + 10**width */
+ if (width == 4U) (*result) -= 456560;
+ else if (width == 5U) (*result) -= 16696160;
+ else {
+ *result = 0;
+ return unsupported_width();
+ }
+ return 0;
+ }
+ }
+ else if (digits_values_lower[di] >= 10) {
+ errmsg = decode_pure(digits_values_lower, 36U, s, s_size, result);
+ if (errmsg == 0) {
+ /* result + 16*36**(width-1) + 10**width */
+ if (width == 4U) (*result) += 756496;
+ else if (width == 5U) (*result) += 26973856;
+ else {
+ *result = 0;
+ return unsupported_width();
+ }
+ return 0;
+ }
+ }
+ else {
+ errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
+ if (errmsg) return errmsg;
+ if (!(width == 4U || width == 5U)) {
+ *result = 0;
+ return unsupported_width();
+ }
+ return 0;
+ }
+ }
+ }
+ *result = 0;
+ return invalid_number_literal();
+}
diff --git a/hybrid_36_c.h b/hybrid_36_c.h
new file mode 100644
index 0000000..4811b00
--- /dev/null
+++ b/hybrid_36_c.h
@@ -0,0 +1,21 @@
+/* If you change the include guards, please be sure to also rename the
+ functions below. Otherwise your project will clash with the original
+ iotbx declarations and definitions.
+ */
+#ifndef IOTBX_PDB_HYBRID_36_C_H
+#define IOTBX_PDB_HYBRID_36_C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char*
+hy36encode(unsigned width, int value, char* result);
+
+const char*
+hy36decode(unsigned width, const char* s, unsigned s_size, int* result);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* IOTBX_PDB_HYBRID_36_C_H */
diff --git a/libtbx_refresh.py b/libtbx_refresh.py
new file mode 100755
index 0000000..08b5512
--- /dev/null
+++ b/libtbx_refresh.py
@@ -0,0 +1,19 @@
+import libtbx
+from libtbx.utils import warn_if_unexpected_md5_hexdigest
+import os
+
+if (self.env.is_ready_for_build()
+ and self.env.dist_path("iotbx", default=None) is not None):
+ if (not hasattr(libtbx, "manual_date_stamp")):
+ path = "include/iotbx/pdb/hybrid_36_c.c"
+ else:
+ path = "pdb/hybrid_36_c.c"
+ warn_if_unexpected_md5_hexdigest(
+ path=self.env.under_dist(module_name="iotbx", path=path),
+ expected_md5_hexdigests=[
+ "e96f85e8ab863dd241893941c427a5aa", # SVN revision 6312
+ ],
+ hints=[
+ " Files to review:",
+ " iotbx/pdb/hybrid_36_c.c",
+ " hybrid_36_c.c"])
diff --git a/parse.c b/parse.c
new file mode 100644
index 0000000..654cb56
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,944 @@
+/* name: parse.c */
+/* author: J. Michael Word date written: 2/29/96 */
+/* purpose: build a parse tree from an input string. */
+/* based on "Compilers", Aho, Sethi, and Ullman */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <stdlib.h> /*060902 needs this for malloc() */
+#include <string.h>
+#include <ctype.h>
+#include "utility.h"
+#include "parse.h"
+
+static symbolEntry SymTable[LEXSYMMAX] = {0};
+static char *inputStr = 0;
+static int tokenval = 0;
+static float realtokval = 0.0;
+static int lookahead = 0;
+static char lexbuf[LXBUFSZ+1] = {0};
+static char Lexemes[LEXSTRINGMAX] = {0};
+static int LastLexChar = -1;
+static int LastSymEntry = 0;
+static int ParseError = FALSE;
+
+pattern* parseArg(char *s) { /*called by select.c/getPat() */
+ pattern *pat;
+ inputStr = s;
+ lookahead = lexan();
+
+ ParseError = FALSE;
+
+ pat = exprItem();
+ matchTok(DONE_TOK);
+
+ if (ParseError == TRUE) {
+ pat = freePattern(pat);
+ }
+
+ return pat;
+}
+
+pattern* freePattern(pattern *pat) {
+ if (pat) {
+ pat->lhs = freePattern(pat->lhs);
+ pat->rhs = freePattern(pat->rhs);
+ free(pat);
+ }
+ return NULL;
+}
+
+pattern* exprItem() {
+ pattern *lhs, *rhs;
+
+ lhs = setItem();
+ for (;;) {
+ if (lookahead == '|') {
+ matchTok('|');
+ rhs = setItem();
+ lhs = makeNode(lhs, rhs, OR_NODE);
+ }
+ else {
+ break;
+ }
+ }
+ return lhs;
+}
+
+pattern* setItem() {
+ pattern *lhs, *rhs;
+
+ lhs = limitItem();
+ for (;;) {
+ if((lookahead == '(') /* a limitItem must begin with a feature! */
+ || (lookahead == NOT_TOK)
+ || (lookahead == NUM_TOK)
+ || (lookahead == ID_TOK)
+ || (lookahead == WITHIN_TOK)
+ || (lookahead == '-')) {
+ rhs = limitItem();
+ lhs = makeNode(lhs, rhs, AND_NODE);
+ }
+ else {
+ break;
+ }
+ }
+ return lhs;
+}
+
+pattern* limitItem() {
+ pattern *lhs, *rhs;
+
+ lhs = featureItem();
+ for (;;) {
+ if (lookahead == ',') {
+ matchTok(',');
+ rhs = featureItem();
+ lhs = makeNode(lhs, rhs, OR_NODE);
+ }
+ else {
+ break;
+ }
+ }
+ return lhs;
+}
+
+pattern* featureItem() {
+ pattern *f = NULL;
+
+ if (lookahead == '(') {
+ matchTok('(');
+ f = exprItem();
+ matchTok(')');
+ }
+ else if (lookahead == NOT_TOK) {
+ matchTok(NOT_TOK);
+ f = featureItem();
+ f = makeNode(f, NULL, NOT_NODE);
+ }
+ else if (lookahead == NUM_TOK) {
+ f = numericItem(+1);
+ }
+ else if (lookahead == ID_TOK) {
+ f = idItem();
+ }
+ else if (lookahead == WITHIN_TOK) {
+ f = distItem();
+ }
+ /* if an item starts with a minus */
+ /* it is a negative residue number */
+ else if (lookahead == '-') {
+ matchTok('-');
+ if (lookahead == NUM_TOK) {
+ f = numericItem(-1);
+ }
+ else {
+ char msg[100];
+ describeLookahead(msg,"syntax: minus sign requires a number ");
+ errmsg(msg);
+ ParseError = TRUE;
+ }
+ }
+ else {
+ char msg[100];
+ describeLookahead(msg,"syntax: improper feature ");
+ errmsg(msg);
+ ParseError = TRUE;
+ }
+ return f;
+}
+
+pattern* numericItem(int signFactor) {
+ pattern *lhs, *rhs, *rrs;
+ int inscode = 0;
+
+ lhs = makeTerminal(RES_NODE, signFactor*tokenval);
+ inscode = lexbuf[0];
+ matchTok(NUM_TOK);
+
+ if (isalpha(inscode) || inscode == ' ') { /* combine res# with insert code */
+ rhs = makeTerminal(INS_NODE, inscode);
+ lhs = makeNode(lhs, rhs, AND_NODE);
+ }
+
+ if (lookahead == '-') { /* first dash is the range separator */
+ matchTok('-');
+
+ signFactor = +1;
+ if (lookahead == '-') { /* this dash specifies a negative num */
+ matchTok('-');
+ signFactor = -1;
+ }
+ rhs = makeTerminal(RES_NODE, signFactor*tokenval);
+ inscode = lexbuf[0];
+ matchTok(NUM_TOK);
+
+ if (isalpha(inscode) || inscode == ' ') { /* combine res# with insert code */
+ rrs = makeTerminal(INS_NODE, inscode);
+ rhs = makeNode(rhs, rrs, AND_NODE);
+ }
+
+ if ((lhs->type == AND_NODE)|| (rhs->type == AND_NODE)) {
+ /* more than just a span of numbers */
+ /* includes insert codes */
+ lhs = makeNode(lhs, rhs, INS_RANGE_NODE);
+ }
+ else {
+ lhs = makeNode(lhs, rhs, RANGE_NODE);
+ }
+ }
+ return lhs;
+}
+
+pattern* idItem() {
+ pattern *lhs = NULL;
+ int type = 0, val = 0;
+ char *s, *tmpstr;
+
+ s = SymTable[tokenval].lexptr;
+
+ if ((strncmp(s, "FILE", 4) == 0) && isdigit(s[4])) {
+ type = FILE_NODE; val = parseInteger(s,4,10);
+ }
+ else if ((strncmp(s, "CHAIN", 5) == 0) && (isalnum(s[5])||(s[5]=='_'))) {
+ type = CHAIN_NODE;
+ for(tmpstr = s+5; *tmpstr; tmpstr++) { /* substitute blank for _ */
+ if (*tmpstr == '_') {*tmpstr = ' ';}
+ }
+ if (s[6] == '\0') {
+ s[4] = ' ';
+ val = lookup(s+4); if(val == 0) val = insert(s+4, ID_TOK);
+ }
+ else {
+ val = lookup(s+5); if(val == 0) val = insert(s+5, ID_TOK);
+ }
+ /* type = CHAIN_NODE; val = (unsigned char)s[5]; */
+ }
+ else if ((strncmp(s, "ALT", 3) == 0) && (isalnum(s[3])||(s[3]=='_'))) {
+ if (s[3] == '_') {s[3] = ' ';}
+ type = ALT_NODE; val = (unsigned char)s[3];
+ }
+ else if ((strncmp(s, "MODEL", 5) == 0) && isdigit(s[5])) {
+ type = MODEL_NODE; val = parseInteger(s,5,10);
+ }
+ else if ((strncmp(s, "ATOM", 4) == 0) && (isalnum(s[4])||(s[4]=='_'))) {
+ type = ANAME_NODE;
+ for(tmpstr = s+4; *tmpstr; tmpstr++) { /* substitute blank for _ */
+ if (*tmpstr == '_') {*tmpstr = ' ';}
+ }
+ val = lookup(s+4); if(val == 0) val = insert(s+4, ID_TOK);
+ }
+ else if ((strncmp(s, "SEG", 3) == 0) && (isalnum(s[3])||(s[3]=='_'))) {
+ type = SEGID_NODE;
+ for(tmpstr = s+3; *tmpstr; tmpstr++) { /* substitute blank for _ */
+ if (*tmpstr == '_') {*tmpstr = ' ';}
+ }
+ val = lookup(s+3); if(val == 0) val = insert(s+3, ID_TOK);
+ }
+ else if (strcmp(s, "ALL") == 0) {
+ type = TRUE_NODE; val = 0;
+ }
+ else if (strcmp(s, "NONE") == 0) {
+ type = FALSE_NODE; val = 0;
+ }
+ else if (strcmp(s, "ALPHA") == 0) {
+ type = PROP_NODE; val = ALPHA_PROP;
+ }
+ else if (strcmp(s, "BETA") == 0) {
+ type = PROP_NODE; val = BETA_PROP;
+ }
+ else if ((strcmp(s, "MAINCHAIN") == 0) || (strcmp(s, "MC") == 0)
+ || (strcmp(s, "BACKBONE") == 0)) {
+ type = PROP_NODE; val = MC_PROP;
+ }
+ else if ((strcmp(s, "SIDECHAIN") == 0) || (strcmp(s, "SC") == 0)
+ || (strcmp(s, "BASE") == 0)) {
+ type = PROP_NODE; val = SC_PROP;
+ }
+ else if (strcmp(s, "NITROGEN") == 0) {
+ type = PROP_NODE; val = N_PROP;
+ }
+ else if (strcmp(s, "CARBON") == 0) {
+ type = PROP_NODE; val = C_PROP;
+ }
+ else if (strcmp(s, "OXYGEN") == 0) {
+ type = PROP_NODE; val = O_PROP;
+ }
+ else if (strcmp(s, "SULFUR") == 0) {
+ type = PROP_NODE; val = S_PROP;
+ }
+ else if (strcmp(s, "PHOSPHORUS") == 0) {
+ type = PROP_NODE; val = P_PROP;
+ }
+ else if (strcmp(s, "HYDROGEN") == 0) {
+ type = PROP_NODE; val = H_PROP;
+ }
+ else if ((strcmp(s, "H2O") == 0) || (strcmp(s, "WATER") == 0)) {
+ type = PROP_NODE; val = WATER_PROP;
+ }
+ else if ((strcmp(s, "HET") == 0) || (strcmp(s, "HETATM") == 0)) {
+ type = PROP_NODE; val = HET_PROP;
+ }
+ else if ((strcmp(s, "PROTEIN") == 0) || (strcmp(s, "PEPTIDE") == 0)) {
+ type = PROP_NODE; val = PROT_PROP;
+ }
+ else if ((strcmp(s, "DNA") == 0) || (strcmp(s, "RNA") == 0)) {
+ type = PROP_NODE; val = DNA_PROP;
+ }
+ else if (strcmp(s, "METAL") == 0) {
+ type = PROP_NODE; val = METAL_PROP;
+ }
+ else if (strcmp(s, "METHYL") == 0) {
+ type = PROP_NODE; val = METHYL_PROP;
+ }
+ else if (strcmp(s, "DONOR") == 0) {
+ type = PROP_NODE; val = DONOR_PROP;
+ }
+ else if (strcmp(s, "ACCEPTOR") == 0) {
+ type = PROP_NODE; val = ACCEPTOR_PROP;
+ }
+ else if ((strcmp(s, "NONPOLAR") == 0) || (strcmp(s, "HYDROPHOBIC") == 0)
+ || (strcmp(s, "HPHOBIC")== 0)|| (strcmp(s, "PHOBIC") == 0)) {
+ type = PROP_NODE; val = RHPHOBIC_PROP;
+ }
+ else if ((strcmp(s, "POLAR") == 0) || (strcmp(s, "HYDROPHILIC") == 0)
+ || (strcmp(s, "HPHILIC")== 0)|| (strcmp(s, "PHILIC") == 0)) {
+ type = PROP_NODE; val = RHPHILIC_PROP;
+ }
+ else if ((strcmp(s, "CHARGED") == 0) || (strcmp(s, "CHARGE") == 0)) {
+ type = PROP_NODE; val = RCHARGED_PROP;
+ }
+ else if (strcmp(s, "AROMATIC") == 0) {
+ type = PROP_NODE; val = AROMATIC_PROP;
+ }
+ else if ((strcmp(s, "GLY") == 0) || (strcmp(s, "G") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("GLY"); if(val == 0) val = insert("GLY", ID_TOK);
+ }
+ else if ((strcmp(s, "ALA") == 0) || (strcmp(s, "A") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("ALA"); if(val == 0) val = insert("ALA", ID_TOK);
+ }
+ else if ((strcmp(s, "VAL") == 0) || (strcmp(s, "V") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("VAL"); if(val == 0) val = insert("VAL", ID_TOK);
+ }
+ else if ((strcmp(s, "PHE") == 0) || (strcmp(s, "F") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("PHE"); if(val == 0) val = insert("PHE", ID_TOK);
+ }
+ else if ((strcmp(s, "PRO") == 0) || (strcmp(s, "P") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("PRO"); if(val == 0) val = insert("PRO", ID_TOK);
+ }
+ else if ((strcmp(s, "MET") == 0) || (strcmp(s, "M") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("MET"); if(val == 0) val = insert("MET", ID_TOK);
+ }
+ else if ((strcmp(s, "ILE") == 0) || (strcmp(s, "I") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("ILE"); if(val == 0) val = insert("ILE", ID_TOK);
+ }
+ else if ((strcmp(s, "LEU") == 0) || (strcmp(s, "L") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("LEU"); if(val == 0) val = insert("LEU", ID_TOK);
+ }
+ else if ((strcmp(s, "ASP") == 0) || (strcmp(s, "D") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("ASP"); if(val == 0) val = insert("ASP", ID_TOK);
+ }
+ else if ((strcmp(s, "GLU") == 0) || (strcmp(s, "E") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("GLU"); if(val == 0) val = insert("GLU", ID_TOK);
+ }
+ else if ((strcmp(s, "LYS") == 0) || (strcmp(s, "K") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("LYS"); if(val == 0) val = insert("LYS", ID_TOK);
+ }
+ else if ((strcmp(s, "ARG") == 0) || (strcmp(s, "R") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("ARG"); if(val == 0) val = insert("ARG", ID_TOK);
+ }
+ else if ((strcmp(s, "SER") == 0) || (strcmp(s, "S") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("SER"); if(val == 0) val = insert("SER", ID_TOK);
+ }
+ else if ((strcmp(s, "THR") == 0) || (strcmp(s, "T") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("THR"); if(val == 0) val = insert("THR", ID_TOK);
+ }
+ else if ((strcmp(s, "TYR") == 0) || (strcmp(s, "Y") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("TYR"); if(val == 0) val = insert("TYR", ID_TOK);
+ }
+ else if ((strcmp(s, "HIS") == 0) || (strcmp(s, "H") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("HIS"); if(val == 0) val = insert("HIS", ID_TOK);
+ }
+ else if ((strcmp(s, "CYS") == 0) || (strcmp(s, "C") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("CYS"); if(val == 0) val = insert("CYS", ID_TOK);
+ }
+ else if ((strcmp(s, "ASN") == 0) || (strcmp(s, "N") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("ASN"); if(val == 0) val = insert("ASN", ID_TOK);
+ }
+ else if ((strcmp(s, "GLN") == 0) || (strcmp(s, "Q") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("GLN"); if(val == 0) val = insert("GLN", ID_TOK);
+ }
+ else if ((strcmp(s, "TRP") == 0) || (strcmp(s, "W") == 0)) {
+ type = RTYPE_NODE;
+ val = lookup("TRP"); if(val == 0) val = insert("TRP", ID_TOK);
+ }
+ else if (strcmp(s, "ACE") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("ACE"); if(val == 0) val = insert("ACE", ID_TOK);
+ }
+ else if (strcmp(s, "ASX") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("ASX"); if(val == 0) val = insert("ASX", ID_TOK);
+ }
+ else if (strcmp(s, "GLX") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("GLX"); if(val == 0) val = insert("GLX", ID_TOK);
+ }
+ else if (strcmp(s, "MSE") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("MSE"); if(val == 0) val = insert("MSE", ID_TOK);
+ }
+ else if (strcmp(s, "PCA") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("PCA"); if(val == 0) val = insert("PCA", ID_TOK);
+ }
+ else if (strcmp(s, "NH2") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("NH2"); if(val == 0) val = insert("NH2", ID_TOK);
+ }
+ else if (strcmp(s, "NME") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("NME"); if(val == 0) val = insert("NME", ID_TOK);
+ }
+ else if (strcmp(s, "FOR") == 0) {
+ type = RTYPE_NODE;
+ val = lookup("FOR"); if(val == 0) val = insert("FOR", ID_TOK);
+ }
+ else if ((strncmp(s, "RES", 3) == 0) && (isalnum(s[3])||(s[3]=='_'))) {
+ type = RTYPE_NODE;
+ for(tmpstr = s+3; *tmpstr; tmpstr++) { /* substitute blank for _ */
+ if (*tmpstr == '_') {*tmpstr = ' ';}
+ }
+ val = lookup(s+3); if(val == 0) val = insert(s+3, ID_TOK);
+ }
+ else if ((strncmp(s, "OLT", 3) == 0) && isdigit(s[3])) {
+ type = OCC_LT_NODE; val = parseInteger(s,3,10);
+ }
+ else if ((strncmp(s, "OGT", 3) == 0) && isdigit(s[3])) {
+ type = OCC_GT_NODE; val = parseInteger(s,3,10);
+ }
+ else if ((strncmp(s, "BLT", 3) == 0) && isdigit(s[3])) {
+ type = B_LT_NODE; val = parseInteger(s,3,10);
+ }
+ else if ((strncmp(s, "BGT", 3) == 0) && isdigit(s[3])) {
+ type = B_GT_NODE; val = parseInteger(s,3,10);
+ }
+ else if ((strncmp(s, "INS", 3) == 0) && (isalnum(s[3])||(s[3]=='_'))) {
+ if (s[3] == '_') {s[3] = ' ';}
+ type = INS_NODE; val = (unsigned char)s[3];
+ }
+ else {
+ char msg[200];
+ sprintf(msg,"syntax: unknown identifier: %s", s);
+ errmsg(msg);
+ ParseError = TRUE;
+ type = FALSE_NODE;
+ val = 0;
+ }
+
+ lhs = makeTerminal(type, val);
+ matchTok(ID_TOK);
+ return lhs;
+}
+
+pattern* distItem() {
+ pattern *f;
+ float dst = 0.0, px = 0.0, py = 0.0, pz = 0.0, signFactor = 0.0;
+ int ok = 1;
+
+/* within */
+ f = makeTerminal(DIST_NODE, 0);
+ matchTok(WITHIN_TOK);
+/* distance */
+ if (ok && lookahead == REALNUM_TOK) {
+ dst = realtokval;
+ matchTok(REALNUM_TOK);
+ }
+ else if (ok && lookahead == NUM_TOK) {
+ dst = tokenval;
+ matchTok(NUM_TOK);
+ }
+ else { ok = 0; }
+/* of */
+ if (ok && lookahead == ID_TOK
+ && strcmp(SymTable[tokenval].lexptr, "OF") == 0) {
+ matchTok(ID_TOK);
+ }
+ else { ok = 0; }
+/* x */
+ signFactor = 1.0;
+ if (ok && lookahead == '-') {
+ matchTok('-');
+ signFactor = -1.0;
+ }
+
+ if (ok && lookahead == REALNUM_TOK) {
+ px = signFactor * realtokval;
+ matchTok(REALNUM_TOK);
+ }
+ else if (ok && lookahead == NUM_TOK) {
+ px = signFactor * tokenval;
+ matchTok(NUM_TOK);
+ }
+ else { ok = 0; }
+/* , */
+ if (ok && lookahead == ',') {
+ matchTok(',');
+ }
+ else { ok = 0; }
+/* y */
+ signFactor = 1.0;
+ if (ok && lookahead == '-') {
+ matchTok('-');
+ signFactor = -1.0;
+ }
+
+ if (ok && lookahead == REALNUM_TOK) {
+ py = signFactor * realtokval;
+ matchTok(REALNUM_TOK);
+ }
+ else if (ok && lookahead == NUM_TOK) {
+ py = signFactor * tokenval;
+ matchTok(NUM_TOK);
+ }
+ else { ok = 0; }
+/* , */
+ if (ok && lookahead == ',') {
+ matchTok(',');
+ }
+ else { ok = 0; }
+/* z */
+ signFactor = 1.0;
+ if (ok && lookahead == '-') {
+ matchTok('-');
+ signFactor = -1.0;
+ }
+
+ if (ok && lookahead == REALNUM_TOK) {
+ pz = signFactor * realtokval;
+ matchTok(REALNUM_TOK);
+ }
+ else if (ok && lookahead == NUM_TOK) {
+ pz = signFactor * tokenval;
+ matchTok(NUM_TOK);
+ }
+ else { ok = 0; }
+
+/* info is packed into the floating-point vector */
+ if (ok) {
+ f->fvec[0] = dst;
+ f->fvec[1] = px;
+ f->fvec[2] = py;
+ f->fvec[3] = pz;
+ }
+ else {
+ char msg[100];
+ describeLookahead(msg,"syntax: parsing WITHIN: ");
+ errmsg(msg);
+ ParseError = TRUE;
+ }
+ return f;
+}
+
+pattern* makeNode(pattern *lhs, pattern *rhs, int type) {
+ pattern *node;
+ node = (pattern *)malloc(sizeof(pattern));
+ if (node) {
+ node->lhs = lhs;
+ node->rhs = rhs;
+ node->type = type;
+ node->val = 0;
+ node->fvec[0] = 0.0;
+ node->fvec[1] = 0.0;
+ node->fvec[2] = 0.0;
+ node->fvec[3] = 0.0;
+ }
+ else {
+ halt("out of memory in makeNode()");
+ }
+ return node;
+}
+
+pattern* makeTerminal(int type, int val) {
+ pattern *term;
+ term = (pattern *)malloc(sizeof(pattern));
+ if (term) {
+ term->lhs = NULL;
+ term->rhs = NULL;
+ term->type = type;
+ term->val = val;
+ term->fvec[0] = 0.0;
+ term->fvec[1] = 0.0;
+ term->fvec[2] = 0.0;
+ term->fvec[3] = 0.0;
+ }
+ else {
+ halt("out of memory in makeTerminal()");
+ }
+ return term;
+}
+
+void matchTok(int t) {
+ if (lookahead == t) {
+ lookahead = lexan();
+ }
+ else {
+ char msg[100];
+ describeLookahead(msg,"improper syntax ");
+ errmsg(msg);
+ sprintf(msg,"expect match code: %d", t);
+ errmsg(msg);
+ ParseError = TRUE;
+ }
+}
+
+char* lexString(int p) {
+
+ return SymTable[p].lexptr;
+}
+
+int lexan() {
+ int p, t, rc, cnt;
+
+ for (;;) {
+ t = toupper(*inputStr++);
+ if (t == ' ' || t == '\t' || t == '\n' || t == '\r') {
+ /* skip over whitespace */
+ }
+ else if (isdigit(t) || t == '.') {
+ int insCode = 0;
+ int fractional = (t == '.');
+ lexbuf[cnt = 0] = t;
+ while ( isdigit(*inputStr)
+ || ( (*inputStr == '.' ||
+ isalpha(*inputStr) || *inputStr == '_')
+ && ! (insCode || fractional)) ) {
+
+ if (*inputStr == '.') { fractional = 1; }
+ else if (isalpha(*inputStr)) { insCode = toupper(*inputStr); }
+ else if (*inputStr == '_') { insCode = ' '; }
+ if (cnt >= LXBUFSZ-1) { halt("number too long"); }
+ lexbuf[++cnt] = toupper(*inputStr++);
+ }
+ lexbuf[++cnt] = '\0';
+
+ if (fractional) {
+ realtokval = parseReal(lexbuf, 0, cnt);
+ tokenval = 0;
+ rc = REALNUM_TOK;
+ }
+ else { /* need to save insCode */
+ tokenval = parseInteger(lexbuf, 0, cnt);
+ cnt = 0;
+ if (insCode) { lexbuf[cnt++] = insCode; }
+ lexbuf[cnt] = '\0';
+ rc = NUM_TOK;
+ }
+ break;
+ }
+ else if (t == 'N' && toupper(inputStr[0]) == 'O'
+ && toupper(inputStr[1]) == 'T' && !isalnum(inputStr[2]) ) {
+ inputStr++;
+ inputStr++;
+ tokenval = 0;
+ rc = NOT_TOK;
+ break;
+ }
+ else if (t == 'W' && toupper(inputStr[0]) == 'I'
+ && toupper(inputStr[1]) == 'T' && toupper(inputStr[2]) == 'H'
+ && toupper(inputStr[3]) == 'I' && toupper(inputStr[4]) == 'N'
+ && !isalnum(inputStr[5]) ) {
+ inputStr += 5;
+ tokenval = 0;
+ rc = WITHIN_TOK;
+ break;
+ }
+ else if (isalpha(t)) {
+ lexbuf[cnt = 0] = t;
+ while (isalnum(*inputStr) || (*inputStr == '_')
+ || (*inputStr == '*') || (*inputStr == '\'')
+ || (*inputStr == '"')) {
+ if (cnt >= LXBUFSZ-1) { halt("symbol too long"); }
+ lexbuf[++cnt] = toupper(*inputStr++);
+ }
+ lexbuf[++cnt] = '\0';
+
+ p = lookup(lexbuf);
+ if (p == 0) {
+ p = insert(lexbuf, ID_TOK);
+ }
+ tokenval = p;
+ rc = ID_TOK;
+ break;
+ }
+ else if (t == '\0') {
+ tokenval = 0;
+ rc = DONE_TOK;
+ break;
+ }
+ else {
+ tokenval = 0;
+ rc = t;
+ break;
+ }
+ }
+ return rc;
+}
+
+int lookup(char *s) {
+ int p;
+ for (p = LastSymEntry; p > 0; p--) {
+ if (strcmp(SymTable[p].lexptr, s) == 0) {
+ return p;
+ }
+ }
+ return 0;
+}
+
+int insert(char *s, int tok) {
+ int len;
+ len = strlen(s);
+
+ if (LastSymEntry + 1 >= LEXSYMMAX) {
+ halt("symbol table full");
+ }
+ if (LastLexChar + len + 1 >= LEXSTRINGMAX) {
+ halt("symbol name array full");
+ }
+ LastSymEntry++;
+
+ SymTable[LastSymEntry].token = tok;
+ SymTable[LastSymEntry].lexptr = &Lexemes[LastLexChar + 1];
+ LastLexChar += len + 1;
+ strcpy(SymTable[LastSymEntry].lexptr, s);
+
+ return LastSymEntry;
+}
+
+int modelInPattern(pattern *pat)
+{
+ static int model=0;
+ static int ireturn=0;
+
+ if(pat == NULL) {model=0;}
+ else
+ {
+ switch(pat->type)
+ {
+ case OR_NODE:
+ case AND_NODE:
+ ireturn = modelInPattern(pat->rhs);
+ case NOT_NODE:
+ ireturn = modelInPattern(pat->lhs);
+ break;
+ case MODEL_NODE:
+ model = pat->val;
+ break;
+ }/*switch*/
+ }
+ if(model>0){ireturn = model;}
+ return(ireturn);
+}/*modelInPattern()*/
+
+void printPattern(FILE *outf, pattern *pat) {
+ if (pat) {
+ recPrint(outf, pat);
+ fprintf(outf, "\n");
+ }
+}
+
+void recPrint(FILE *outf, pattern *pat) {
+
+ if (pat == NULL) return;
+
+ switch(pat->type) {
+ case OR_NODE:
+ fprintf(outf, "(");
+ recPrint(outf, pat->lhs);
+ fprintf(outf, " or ");
+ recPrint(outf, pat->rhs);
+ fprintf(outf, ")");
+ break;
+ case AND_NODE:
+ fprintf(outf, "(");
+ recPrint(outf, pat->lhs);
+ fprintf(outf, " and ");
+ recPrint(outf, pat->rhs);
+ fprintf(outf, ")");
+ break;
+ case NOT_NODE:
+ fprintf(outf,"not(");
+ recPrint(outf, pat->lhs);
+ fprintf(outf,")");
+ break;
+ case RANGE_NODE:
+ fprintf(outf,"%d <= resno <= %d", pat->lhs->val, pat->rhs->val);
+ break;
+ case FILE_NODE:
+ fprintf(outf,"file=%d", pat->val);
+ break;
+ case MODEL_NODE:
+ fprintf(outf,"model=%d", pat->val);
+ break;
+ case CHAIN_NODE:
+ fprintf(outf,"chain=\"%s%s\"", lexString(pat->val),
+ ((strlen(lexString(pat->val))<3)?"*":""));
+ break;
+ case ALT_NODE:
+ fprintf(outf,"alt='%c'", pat->val);
+ break;
+ case ANAME_NODE:
+ fprintf(outf,"atom=\"%s%s\"", lexString(pat->val),
+ ((strlen(lexString(pat->val))<4)?"*":""));
+ break;
+ case SEGID_NODE:
+ fprintf(outf,"segID=\"%s%s\"", lexString(pat->val),
+ ((strlen(lexString(pat->val))<4)?"*":""));
+ break;
+ case RES_NODE:
+ fprintf(outf,"resno=%d", pat->val);
+ break;
+ case RTYPE_NODE:
+ fprintf(outf,"res=\"%s%s\"", lexString(pat->val),
+ ((strlen(lexString(pat->val))<3)?"*":""));
+ break;
+ case DIST_NODE:
+ fprintf(outf,"atoms within %.1f of %.3f, %.3f, %.3f", pat->fvec[0],
+ pat->fvec[1], pat->fvec[2], pat->fvec[3]);
+ break;
+ case PROP_NODE:
+ switch(pat->val) {
+ case ALPHA_PROP: fprintf(outf,"alpha"); break;
+ case BETA_PROP: fprintf(outf,"beta"); break;
+ case MC_PROP: fprintf(outf,"mainchain"); break;
+ case SC_PROP: fprintf(outf,"sidechain"); break;
+ case N_PROP: fprintf(outf,"Nitrogen"); break;
+ case C_PROP: fprintf(outf,"Carbon"); break;
+ case O_PROP: fprintf(outf,"Oxygen"); break;
+ case S_PROP: fprintf(outf,"Sulfur"); break;
+ case P_PROP: fprintf(outf,"Phosphorus"); break;
+ case H_PROP: fprintf(outf,"Hydrogen"); break;
+ case WATER_PROP: fprintf(outf,"H2O"); break;
+ case HET_PROP: fprintf(outf,"het-group"); break;
+ case PROT_PROP: fprintf(outf,"protein"); break;
+ case DNA_PROP: fprintf(outf,"dna/rna"); break;
+ case METAL_PROP: fprintf(outf,"metal"); break;
+ case METHYL_PROP: fprintf(outf,"methyl"); break;
+ case DONOR_PROP: fprintf(outf,"donor"); break;
+ case ACCEPTOR_PROP: fprintf(outf,"acceptor"); break;
+ case RHPHOBIC_PROP:
+ fprintf(outf,"A,V,L,I,M,C,F,W,Y (but not G,P!)"); break;
+ case RHPHILIC_PROP: fprintf(outf,"S,T,N,Q"); break;
+ case RCHARGED_PROP: fprintf(outf,"D,E,K,R(+H)"); break;
+ case AROMATIC_PROP:fprintf(outf,"aromatic-atoms");break;
+ default: fprintf(outf,"property=%d",pat->val); break;
+ }
+ break;
+ case TRUE_NODE:
+ fprintf(outf,"all");
+ break;
+ case FALSE_NODE:
+ fprintf(outf,"none");
+ break;
+ case OCC_LT_NODE:
+ fprintf(outf,"occupancy < %.2f", pat->val/100.0);
+ break;
+ case OCC_GT_NODE:
+ fprintf(outf,"occupancy > %.2f", pat->val/100.0);
+ break;
+ case B_LT_NODE:
+ fprintf(outf,"Bval < %d", pat->val);
+ break;
+ case B_GT_NODE:
+ fprintf(outf,"Bval > %d", pat->val);
+ break;
+ case INS_NODE:
+ fprintf(outf,"insert='%c'", pat->val);
+ break;
+ case INS_RANGE_NODE:
+ if (pat->lhs->type == RES_NODE) {
+ fprintf(outf,"%d", pat->rhs->val);
+ }
+ else if (pat->lhs->type == AND_NODE) {
+ fprintf(outf,"%d%c", pat->lhs->lhs->val,
+ pat->lhs->rhs->val);
+ }
+ else {
+ errmsg("***INTERNAL DEFECT - EXPECT AND***");
+ fprintf(outf, "(");
+ recPrint(outf, pat->lhs);
+ fprintf(outf, ")");
+ }
+ fprintf(outf," <= resno <= ");
+ if (pat->rhs->type == RES_NODE) {
+ fprintf(outf,"%d", pat->rhs->val);
+ }
+ else if (pat->rhs->type == AND_NODE) {
+ fprintf(outf,"%d%c", pat->rhs->lhs->val,
+ pat->rhs->rhs->val);
+ }
+ else {
+ errmsg("***INTERNAL DEFECT - EXPECT AND***");
+ fprintf(outf, "(");
+ recPrint(outf, pat->rhs);
+ fprintf(outf, ")");
+ }
+ fprintf(outf," /* warning: insert codes ignored in ranges */");
+ break;
+ default:
+ fprintf(outf,"<<bad type: %d>>", pat->type);
+ }
+}/*recPrint()*/
+
+char* describeLookahead(char formatstring[], char *s) {
+
+ if (lookahead == ID_TOK) {
+ sprintf(formatstring,"%s\"%s\"", s, lexString(tokenval));
+ }
+ else if (lookahead == NUM_TOK) {
+ sprintf(formatstring,"%s%d", s, tokenval);
+ }
+ else if (lookahead == REALNUM_TOK) {
+ sprintf(formatstring,"%s%g", s, realtokval);
+ }
+ else if (lookahead == NOT_TOK) {
+ sprintf(formatstring,"%sNOT", s);
+ }
+ else if (lookahead == WITHIN_TOK) {
+ sprintf(formatstring,"%sWITHIN", s);
+ }
+ else if (lookahead == DONE_TOK) {
+ sprintf(formatstring,"%s(end of pattern)", s);
+ }
+ else {
+ sprintf(formatstring,"%s\'%c\'", s, lookahead);
+ }
+ return formatstring;
+}
diff --git a/parse.h b/parse.h
new file mode 100644
index 0000000..079abfd
--- /dev/null
+++ b/parse.h
@@ -0,0 +1,131 @@
+/* name: parse.h */
+/* author: J. Michael Word date written: 2/29/96 */
+/* purpose: build a parse tree from an input string. */
+/* based on "Compilers", Aho, Sethi, and Ullman */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef PARSE_H
+#define PARSE_H 1
+
+#include <stdio.h>
+
+/* types of pattern entries */
+#define OR_NODE 300
+#define AND_NODE 301
+#define NOT_NODE 302
+#define RANGE_NODE 303
+#define FILE_NODE 304
+#define MODEL_NODE 305
+#define CHAIN_NODE 306
+#define ALT_NODE 307
+#define RES_NODE 308
+#define RTYPE_NODE 309
+#define TRUE_NODE 310
+#define FALSE_NODE 311
+#define PROP_NODE 312
+#define ANAME_NODE 313
+#define OCC_LT_NODE 314
+#define OCC_GT_NODE 315
+#define B_LT_NODE 316
+#define B_GT_NODE 317
+#define DIST_NODE 318
+#define SEGID_NODE 319
+#define INS_NODE 320
+#define INS_RANGE_NODE 321
+
+/* lexical analyzer tokens */
+#define NOT_TOK 400
+#define NUM_TOK 401
+#define REALNUM_TOK 402
+#define ID_TOK 403
+#define WITHIN_TOK 404
+#define DONE_TOK 405
+
+/* flags for atom properties */
+#define MC_PROP (1 << 0)
+#define SC_PROP (1 << 1)
+#define ALPHA_PROP (1 << 2)
+#define BETA_PROP (1 << 3)
+#define N_PROP (1 << 4)
+#define C_PROP (1 << 5)
+#define O_PROP (1 << 6)
+#define S_PROP (1 << 7)
+#define P_PROP (1 << 8)
+#define H_PROP (1 << 9)
+#define WATER_PROP (1 << 10)
+#define HET_PROP (1 << 11)
+#define PROT_PROP (1 << 12)
+#define DNA_PROP (1 << 13)
+#define METAL_PROP (1 << 14) /*re atomprops.h METALIC_ATOM_FLAG */
+#define METHYL_PROP (1 << 15)
+#define DONOR_PROP (1 << 16)
+#define ACCEPTOR_PROP (1 << 17)
+#define AROMATIC_PROP (1 << 18)
+#define CH_DONOR_PROP (1 << 19)
+#define TEST_ACCEPT_ANGLE_PROP (1 << 20)
+
+#define NEGATIVE_PROP (1 << 21)
+#define POSITIVE_PROP (1 << 22)
+
+#define RHPHOBIC_PROP (1 << 23)
+#define RHPHILIC_PROP (1 << 24)
+#define RCHARGED_PROP (1 << 25)
+
+#define MAYBECHG_PROP (1 << 26)
+#define CHECK_ENDS_PROP (1 << 27)
+#define AMBIGWATER_PROP (1 << 28)
+#define ION_PROP (1 << 29) /*re atomprops.h IONIC_ATOM_FLAG dcr041007*/
+
+typedef struct patternType {
+ struct patternType *lhs; /* link to sub-pattern */
+ struct patternType *rhs; /* ditto */
+ int type; /* pattern node type */
+ int val; /* value for leaf nodes */
+ float fvec[4]; /* real vector leaf data */
+} pattern;
+
+/* lexical analyzer symbol table entry */
+typedef struct {
+ char *lexptr; /* string */
+ int token; /* type */
+} symbolEntry;
+
+#define LXBUFSZ 100
+#define LEXSTRINGMAX 1000
+#define LEXSYMMAX 500
+
+pattern* parseArg(char *s);
+pattern* freePattern(pattern *p);
+pattern* exprItem();
+pattern* setItem();
+pattern* limitItem();
+pattern* featureItem();
+pattern* numericItem(int signFactor);
+pattern* idItem();
+pattern* distItem();
+pattern* makeNode(pattern *lhs, pattern *rhs, int type);
+pattern* makeTerminal(int type, int val);
+void matchTok(int t);
+
+char* lexString(int p);
+int lexan();
+int lookup(char *s);
+int insert(char *s, int tok);
+
+void printPattern(FILE *outf, pattern *pat);
+void recPrint(FILE *outf, pattern *pat);
+char* describeLookahead(char formatstring[], char *s);
+
+int modelInPattern(pattern *pat); /*041114*/
+
+#endif
+
diff --git a/probe.c b/probe.c
new file mode 100644
index 0000000..b215653
--- /dev/null
+++ b/probe.c
@@ -0,0 +1,5055 @@
+
+/*{{{--probe.c general comments */
+
+/* name: probe.c */
+/* author: J. Michael Word */
+/* date written: 2/26/96 */
+/* purpose: compute intersecton surfaces */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1996-2004 J. Michael Word */
+/*****************************************************************/
+
+/*Updated to work with the remediated PDB names rmi 070727 */
+/* Essentially ennumerated additional possible atom names and added */
+/* the residue name info to the routine that assigns element type */
+
+/*Jan 2006 DCR compromise comments to enable jEdit type folding {{{ }}} */
+/* without messing up vi type beginning-end bracket identification shift % */
+/* So jEdit folds have to stay within code regions, esp subroutines 060129*/
+
+/*Oct 2004 DCR modifications to version 2.10.031014 starting with dcr041007 */
+/*dcr: sorry Mike, but changing to Berkeley-Altman brackets really helps me!*/
+/*i.e. some routines changed: opening and closing brackets vertically in line*/
+/*also substituted spaces for tabs which are not robust across text editors*/
+/*also tend to shorten lines to <=80 col, standard card-image window size*/
+/*which many text editors use as a default width*/
+
+/*050111: in trying to track behavior of autobondrot mode, the lack of */
+/*global mode state is a severe limitation. */
+/*probe trys to be so object oriented as to not have global modal states */
+/*but given the existance of a whole slew of probe.c global parameters, */
+/*a few more would only help clear up dependencies and program flow! */
+/*hence logical Lautobondrot as a probe.c global*/
+
+
+/* modifications: see dump_changes() */
+/*}}}--probe.c general comments */
+
+/*{{{--includes and declarations (globals for probe.c) */
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include "probe.h"
+
+#define INLINE_FOR_SPEED 1
+
+static char *versionString = "probe: version 2.13.110909, Copyright 1996-2011, J. Michael Word";
+/*"probe: version 2.13.110830, Copyright 1996-2011, J. Michael Word";*/
+/*"probe: version 2.12.110413, Copyright 1996-2007, J. Michael Word";*/
+/*"probe: version 2.12.070821, Copyright 1996-2007, J. Michael Word";*/
+/*"probe: version 2.11.061018, Copyright 1996-2006, J. Michael Word";*/
+/*"probe: version 2.11.060831, Copyright 1996-2006, J. Michael Word";*/
+/*minor work: 2.11.060212*/
+/*"probe: version 2.11.060129, Copyright 1996-2006, J. Michael Word";*/
+/*"probe: version 2.11.050121, Copyright 1996-2005, J. Michael Word";*/
+/*"probe: version 2.11.041112, Copyright 1996-2004, J. Michael Word";*/
+/*"probe: version 2.10.031014dcr041101, Copyright 1996-2004, J. Michael Word";*/
+/*"probe: version 2.10 10/14/2003, Copyright 1996-2003, J. Michael Word";*/
+ /*jmw & dcr agreement on version name and maintenance by dcr 041110*/
+static char *shortVersionStr = "probe.2.13.110909";
+/*static char *shortVersionStr = "probe.2.13.110830";*/
+/*static char *shortVersionStr = "probe.2.12.110413";*/
+/*static char *shortVersionStr = "probe.2.11.061018";*/
+/*static char *shortVersionStr = "probe.2.11.060831";*/
+/*static char *shortVersionStr = "Probe V2.11.060129";*/
+/*static char *shortVersionStr = "Probe V2.11.050121";*/
+/*static char *shortVersionStr = "Probe V2.11.041112";*/ /*041112 version change*/
+/*static char *shortVersionStr = "Probe V2.10.031014dcr041101";*/
+/*static char *shortVersionStr = "Probe V2.9 ( 10/14/2003)";*/
+static char *referenceString = "Word, et. al. (1999) J. Mol. Biol. 285, 1711-1733.";
+static char *electronicReference = "http://kinemage.biochem.duke.edu/";
+
+static int LMasterName = FALSE; /*global extra master={name} on lists 060129*/
+static int LMergeContacts = TRUE; /*global combine wide & close contacts 060129*/
+/*static int Lautobondrot = FALSE;*/ /* global flag for AUTOBONDROT mode 050111*/
+static int ImplicitH = FALSE; /* global controling dot radii */
+static int UsePolarH = TRUE; /* global controling VDW radii of polar Hs */
+static int Verbose = TRUE; /* global flag for output messages */
+static int DoMcMc = FALSE; /* global controling mainchain->mainchain dots */
+static int DoHet = TRUE; /* global controling non-Water HET dots */
+static int DoH2O = TRUE; /* global controling Water dots */
+static int DoWatWat = FALSE; /* global controling water->water dots */
+static int LimitDots = TRUE; /* global controling chopping around bumps*/
+static int LensDots = FALSE; /* global controling lens keyword in kin file*/
+static int ColorGap = TRUE; /* global controling coloration of Gaps */
+static int ByNABaseColor= FALSE; /* global controling coloration of dots */
+static int DumpNewHO = FALSE; /*global controling dump of water newH atom data*/
+static int Maxbonded = 4; /* global controling exclusion bond count */
+static int UseStdBond= FALSE; /* global flag: if TRUE std AA and NA bonding assumed */
+static int UseHParent= TRUE; /* global flag: bonding based on parent names on std H atoms */
+static int ShowTicks = TRUE; /* global controling display of residue name ticker */
+static int OldStyleU = FALSE; /* global controling -u output (true gives kiss edge stuff) */
+static int SplitBySegID=FALSE;/* global controling the splitting of residues (-SEGID) */
+static int HB2aromFace=TRUE; /* global controling aromatic face Hbonding */
+static int AtomMasters=FALSE; /* global controling use of masters */
+static int PermitCHXHB=FALSE; /* global controling use CHX (CHO) hbonds */
+static int DebugLevel= 0; /* global controling debugging information */
+#ifdef JACKnANDREA
+static int writeHbonds = FALSE; /* global flag: if true, write out Hbonds every time they are detected */
+#endif
+
+static int OutputFmtType = 0; /* global selecting output format */
+ /* 0 ==> kinemage format */
+ /* 1 ==> O format */
+ /* 2 ==> XtalView format */
+ /* 3 ==> oneline multi:count:dcr041101*/
+static int OutputHBs = TRUE; /* global controling display of contact categories */
+static int OutputClashes = TRUE; /* global controling display of contact categories */
+static int OutputVDWs = TRUE; /* global controling display of contact categories */
+static int OnlyBadOut = FALSE; /* global controling display of contact categories dcr041010*/
+static int ContactSUMMARY = FALSE; /* global controling output of contact summaries dcr041101*/
+
+static float Min_regular_hb_cutoff=0.6; /* globals controling hbond cutoff */
+static float Min_charged_hb_cutoff=0.8; /* defaults set in processCommandline() */
+static float RadScaleFactor =1.0; /* global VDW radius scale Factor r*f */
+static float RadScaleOffset =0.0; /* global VDW radius scale Offset r+o */
+static float CORadScale =(1.65/1.75); /* global VDW radius scale Factor for C=O */
+static float GAPweight =0.25;/* global raw GAP score weight */
+static float BUMPweight =10.0;/* global raw BUMP score scale Factor */
+static float HBweight = 4.0;/* global raw HBond score scale Factor */
+static float CHOHBfactor = 0.5;/* global CH..O HBond score scale Factor */
+
+static float LowGoodCut =-0.4;/* global cutoff for good bin */
+static float HighGoodCut = 0.25;/* global cutoff for good bin */
+
+static float OccupancyCutoff =0.02; /* global occupancy below which atom has presence but no clashes */
+ /*unfortunately, one needs intervening atoms to avoid clashes between atoms*/
+ /*that are separated by <= Maxbonded, which thus needs to pass through any*/
+ /*atom no matter what it's own occupancy happens to be */
+ /*050118 atom->occ < OccupancyCutoff neither clash nor transfer bonded info*/
+ /* so flanking atoms show horrible spurious clashes (e.g. 1BKR lys 5 lys 78*/
+ /*mechanism seems to be atom->flags | IGNORE_FLAG */
+ /*050119 atoms irrespective of occ now put into neighbor bins for bonding*/
+ /* but atom->occ < OccupancyCutoff are not allowed to show clashes*/
+
+static int OccupancyCriteria = TRUE; /*global: use occupancy criteria 060831*/
+ /*explicit default: unset by -noocc flag, 060831*/
+
+static char *OutPointColor = "gray";
+
+static pointSet COdots; /* adjustible radius dots for C=O carbon */
+
+/*dcr041020 NODEWIDTH defined 5 probe.h, hard code 6 to match initialization*/
+/*0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
+/*5 running sum which can be tested for existance of any of these spikes*/
+static long mcmccont[2][6] = {0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020*/
+static long scsccont[2][6] = {0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020*/
+static long mcsccont[2][6] = {0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020*/
+static long othrcont[2][6] = {0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020*/
+static long summcont[2][6] = {0,0,0,0,0,0,0,0,0,0,0,0}; /*dcr041017,dcr041020*/
+static char inputfilename[256]; /*dcr041023 global, subroutines can report it*/
+static int modelNumber[100]; /*global record of incoming model # 041114*/
+static int modelCount = 0; /*global count of such records, all files 041114*/
+static int modelLimit = 0; /*global loop's flag for multiple models 041114*/
+ /*model counting simple-minded only good for one input file cases like SELF*/
+static int modelSrc = 0; /*global model specified for source 041114*/
+static int modelTarg = 0; /*global model specified for target 041114*/
+static int modelToProcess = 0; /*global model specified for processing 041114*/
+
+#define ATOMS_IN_THE_SAME_RES(aa, bb) IS_THE_SAME_RES((aa)->r, (bb)->r)
+/*041112 IS_THE_SAME_RES() cannot avoid modeltest, i.e. implied Lmodeltest==1*/
+#define IS_THE_SAME_RES(ra, rb) \
+ ( ((ra) == (rb)) \
+ ||( (ra)->resid == (rb)->resid \
+ && (ra)->resInsCode == (rb)->resInsCode \
+ && strcmp((ra)->chain, (rb)->chain) == 0 \
+ && (ra)->model == (rb)->model ) \
+ && ((SplitBySegID == FALSE) || ( strcmp((ra)->segid, (rb)->segid) == 0) ) )
+
+#define TRACEATOM(where, txt, atptr, endtxt) \
+(fprintf((where), "%s{%s%c %s%d%c}[%d]%s", (txt),\
+ (atptr)->atomname, (atptr)->altConf,\
+ (atptr)->r->resname, (atptr)->r->resid,\
+ (atptr)->r->resInsCode, (atptr)->r->rescnt, (endtxt)))
+/*}}}--includes and declarations */
+
+/*{{{main()***************************** MAIN ********************************/
+int main(int argc, char **argv) {
+ int rc = 0;
+ FILE *outf = stdout;
+
+ initalizeAtomTbl(); /*atomprops.c*/
+ initStdConnTable(); /*stdconntable.c*/
+
+ inputfilename[0] = '\0'; /*global dcr041023*/
+ rc = mainProbeProc(argc, argv, outf);
+ return rc;
+}
+/*}}}main()__________________________________________________________________*/
+
+/*{{{mainProbeProc()******** called from main() ******************************/
+int mainProbeProc(int argc, char **argv, FILE *outf)
+{/*mainProbeProc()*/
+ int method;
+ int keepUnselected;
+ region boundingBoxA;
+ atom *allMainAtoms = NULL;
+ atomBins *abins = NULL;
+ pointSet dots[NUMATOMTYPES];
+ char *srcArg=NULL, *targArg=NULL, *ignoreArg=NULL;
+ char *groupLabel=NULL;
+ pattern *srcPat = NULL, *targPat = NULL, *ignorePat = NULL;
+ float density, probeRad, spikelen;
+ int drawSpike, countDots, rawOutput, sayGroup, addKinToFile;
+ char message[200];
+ movingAtomBuildInfo mabis;
+ residue *resLst = NULL;
+
+ /*mabis moving atom build info structure */
+ /*buffer to pass data to newMovingAtom for autobondrot*/
+
+ allMainAtoms = processCommandline(argc, argv, &method,
+ &boundingBoxA, &density, &probeRad,
+ &drawSpike, &spikelen, &countDots, &keepUnselected,
+ &srcArg, &targArg, &ignoreArg, &groupLabel, &rawOutput,
+ &sayGroup, &addKinToFile, &mabis, &resLst);
+
+ /*called with address of mabis, i.e. mabip moving atom build info ptr */
+ /*autobondrot mode: not read in any mobile atoms yet*/
+ /*though may have static set of atoms already in. */
+
+/* dumpRes(resLst); */
+
+ if ((allMainAtoms == NULL) && (mabis.inf == NULL))
+ {
+ /*static atoms read into allMainAtoms linked list, */
+ /* and/or autobondrot file name for mobile atoms held in mabis.inf */
+
+ sprintf(message, "No atom data in input.");
+ note(message);
+ }
+ else
+ {/*there are atoms for probe to work on...*/
+ if (Verbose)
+ {/*Verbose: lots of stuff to screen...*/
+
+ note(versionString);
+ sprintf(message, "density: %g, probe radius: %g, maxBonded: %d",
+ density, probeRad, Maxbonded);
+ note(message);
+ sprintf(message, "regular HB cutoff: %g, charged HB cutoff: %g",
+ Min_regular_hb_cutoff, Min_charged_hb_cutoff);
+ note(message);
+ sprintf(message,
+ "Dot gap bins: low to %g, %g to 0, 0 to %g, %g to high, & Hbonds",
+ LowGoodCut, LowGoodCut, HighGoodCut, HighGoodCut);
+ note(message);
+ if (RadScaleOffset < -0.0001 || RadScaleOffset > 0.0001) {
+ sprintf(message, "Add %g to VDW Rradius",
+ RadScaleOffset);
+ note(message);
+ }
+ if (RadScaleFactor < 0.9999 || RadScaleFactor > 1.0001) {
+ sprintf(message, "Scale VDW Rradius by %g",
+ RadScaleFactor);
+ note(message);
+ }
+ sprintf(message, "C=O carbon VDW scaled by %.3f to a radius of %g A",
+ CORadScale, CORadScale*1.75);
+ note(message);
+ if (rawOutput || countDots) {
+ sprintf(message, "Score Weights: gapWt=%g, bumpWt=%g, HBWt=%g",
+ GAPweight, BUMPweight, HBweight);
+ note(message);
+ }
+ if (drawSpike) {
+ sprintf(message, "draw spike, len: %g", spikelen);
+ note(message);
+ }
+ if (ImplicitH) {
+ note("implicit hydrogens");
+ }
+ if (PermitCHXHB) {
+ sprintf(message, "CH..O type hbonds recognized (scale factor %g)", CHOHBfactor);
+ note(message);
+ }
+ if (!DoMcMc) {
+ note("Excluding mainchain-mainchain interactions");
+ }
+
+ if (!DoHet && !DoH2O) {
+ note("Excluding both HET groups and waters");
+ }
+ else {
+ if (!DoHet) {
+ note("Excluding non-water HET groups");
+ }
+ if (!DoH2O) {
+ note("Excluding waters");
+ }
+ else if (!DoWatWat) {
+ note("Excluding water-water interactions");
+ }
+ }
+ if (LimitDots) {
+ note("Limiting dots from bumps to max non-bump cap");
+ }
+
+ if (rawOutput) { /* nothing required for raw format */
+ }
+ else if (OutputFmtType == 1) {
+ note("Formatting for display in O");
+ }
+ else if (OutputFmtType == 2) {
+ note("Formatting for display in XtalView");
+ }
+ else if (OutputFmtType == 3) { /*dcr041101*/
+ note("outputing one line colon:deliminated:counts:by:severity:type:");
+ }
+
+ if (ByNABaseColor) {
+ if (ColorGap) {
+ note("Coloring dots by gap (& list color by nucleic acid base)");
+ }
+ else {
+ note("Coloring dots by nucleic acid base");
+ }
+ }
+ else if (ColorGap) {
+ note("Coloring dots by gap (& list color by atom)");
+ }
+ if (!UsePolarH) {
+ note("Using old (long) radii for polar H atoms");
+ }
+ if (!OutputHBs) {
+ note("Attention: ***Output not generated for H-Bond contacts***");
+ }
+ if (!OutputClashes) {
+ note("Attention: ***Output not generated for clashes***");
+ }
+ if (!OutputVDWs) {
+ note("Attention: ***Output not generated for van der Waals contacts***");
+ }
+ if (OnlyBadOut) {
+ note("Attention: ***Output only generated for Bad Clashes***");/*dcr041010*/
+ }
+ if (!keepUnselected) {
+ note("Attention: ***Unselected atoms dropped (ignored)***");
+ }
+ }/*Verbose: lots of stuff to screen...*/
+
+ /*now do some work...*/
+ if (addKinToFile && (OutputFmtType == 0)
+ && (! countDots) && (! rawOutput)) {
+ fprintf(outf, "@kinemage 1\n");
+ }
+
+ srcPat = getPat(srcArg, "pattern 1", Verbose);
+ modelSrc = modelInPattern(srcPat); /*parse.c 041114*/
+if(Verbose && modelSrc > 0)
+{
+ sprintf(message, "specified src model==%d", modelSrc);
+ note(message);
+}
+ targPat = getPat(targArg, "pattern 2", Verbose);
+ modelTarg = modelInPattern(targPat); /*parse.c 041114*/
+if(Verbose && modelSrc > 0)
+{
+ sprintf(message, "specified targ model==%d", modelTarg);
+ note(message);
+}
+
+ ignorePat = getPat(ignoreArg,"ignore", Verbose);
+
+ loadDotSpheres(dots, density);
+
+ if (allMainAtoms) /*atoms usually read in from processCommandline()*/
+ { /*build the bins for all static atoms*/
+ selectSource(allMainAtoms, srcPat, SET1,
+ targPat, SET2, ignorePat);
+ abins = binAtoms(allMainAtoms, &boundingBoxA,
+ 'a', probeRad, keepUnselected, SET1|SET2);
+ }
+ else /*but autobondrot mode may not yet have read in any atoms*/
+ {/*minimal boundingBoxes setup*/
+ boundingBoxA.min.x = boundingBoxA.min.y = boundingBoxA.min.z = 0.0;
+ boundingBoxA.max.x = boundingBoxA.max.y = boundingBoxA.max.z = 0.1;
+ abins = initBins('a', &boundingBoxA, 1); /* dummy bbox */
+ }
+
+ if (mabis.inf == NULL) /*pseudo modal flag for autobondrot*/
+ {/*there is NOT an autobondrot atom info input file */
+ if (! ImplicitH)
+ { /*preliminary step acts on all atoms*/
+ updateHydrogenInfo(outf, allMainAtoms, abins,
+ NULL, NULL, SET1|SET2, FALSE);
+ }
+ /*now do the real work: */
+ doCommand(outf, method,
+ allMainAtoms, abins, NULL, NULL,
+ dots, probeRad, density, spikelen,
+ countDots, rawOutput, "", 0.0, drawSpike,
+ sayGroup, groupLabel, argc, argv, message);
+ }
+ else
+ {/*setup to call autobondrot*/
+ xformDatabase* xdb = NULL;
+ movingCommandInfo mcis;
+
+ mcis.firstPass = TRUE;
+ mcis.keepUnselected = keepUnselected;
+ mcis.outf = outf;
+ mcis.method = method;
+ mcis.allMainAtoms = allMainAtoms;
+ mcis.waterClones= NULL;
+ mcis.abins = abins;
+ mcis.dots = dots;
+ mcis.probeRad = probeRad;
+ mcis.density = density;
+ mcis.spikelen = spikelen;
+ mcis.countDots = countDots;
+ mcis.rawOutput = rawOutput;
+ mcis.drawSpike = drawSpike;
+ mcis.sayGroup = sayGroup;
+ mcis.groupLabel = groupLabel;
+ mcis.argc = argc;
+ mcis.argv = argv;
+ mcis.message = message;
+
+ mabis.srcPat = srcPat;
+ mabis.targPat = targPat;
+
+#define RAW_HEADER_COMMENT "#"
+
+ descrCommand(outf, RAW_HEADER_COMMENT,
+ RAW_HEADER_COMMENT, argc, argv);
+
+ /*now actually read in both the mobile atoms and transformation info*/
+
+ xdb = readTransformationDatabase(mabis.inf, outf, newMovingAtom, &mabis,
+ movingAtomListProcessing, NULL,
+ RAW_HEADER_COMMENT);
+
+/* mabis.inf == FILE *inf */
+/* outf == FILE *outf */
+/* newMovingAtom == abrMkAtomProc mkAtom */
+/* &mabis == void *atomstuff */
+/* movingAtomListProcessing == abrAtomListProc inputListProc */
+/* NULL == void *liststuff */
+/* RAW_HEADER_COMMENT == char *cch */
+
+ /*autobondrot/readTransformationDatabase() */
+ /* also calls autobondrot/describeXformDB() */
+ /* which writes the header-comments to the .map file! */
+
+ if (mabis.close) { fclose(mabis.inf); }
+
+ autobondrot(stderr, xdb, movingDoCommand, &mcis,
+ deleteMovingAtom, &mabis, Verbose);
+
+ /*autobondrot.c/autobondrot() is the call to do the autobondrot stuff*/
+ /*movingDoCommand is the name of the probeProc() called from there */
+ /*probe.c/movingDoCommand() in turn calls probe.c/doCommand()*/
+
+ discardXformDB(xdb, deleteMovingAtom, &mabis);
+ }/*setup to call autobondrot*/
+
+ /*after finish, then drop through to here to release memory, etc.*/
+
+ disposeBins(abins); abins = NULL;
+ freeDotSphere(&COdots);
+ unloadDotSpheres(dots);
+ freePattern(ignorePat); ignorePat = NULL;
+ freePattern(targPat); targPat = NULL;
+ freePattern(srcPat); srcPat = NULL;
+
+ if (Verbose)
+ {
+ note("If you publish work which uses probe, please cite:");
+ note(referenceString);
+ sprintf(message, "For more information see %s", electronicReference);
+ note(message);
+ }
+ }/*there are atoms for probe to work on...*/
+
+ disposeListOfResidues(resLst); resLst = NULL;
+ disposeListOfAtoms(allMainAtoms); allMainAtoms = NULL;
+
+ return 0; /*to probe.c/main() */
+}/*mainProbeProc()*/
+/*}}}mainProbeProc()_________________________________________________________*/
+
+/*{{{newMovingAtom()**********************************************************/
+atom * newMovingAtom(char *rec, void *userdata)
+{
+ atom* a = NULL;
+ movingAtomBuildInfo *m = (movingAtomBuildInfo *)userdata;
+
+ if (rec == NULL) { return NULL; }
+
+ if (m->scratchRes == NULL) {
+ m->scratchRes = newResidueData();
+ }
+
+ /*atom * newAtom(char *rec, int file, int model, residue * resDataBuf)*/
+ a = newAtom(rec, m->filenum, 0, m->scratchRes);
+ if (a) {
+ a->next = NULL;
+ if (ImplicitH && isHatom(a->elem)) {
+ deleteAtom(a); /* filter out implicit hydrogens */
+ return NULL;
+ }
+
+ selectSource(a, m->srcPat, SET1, m->targPat, SET2, NULL);
+ /* note: new moving atom can not be ignored using -IGNORE flag */
+
+ if (*(m->reslstptr) == NULL) {/* first residue goes on residue list */
+ *(m->reslstptr) = m->scratchRes;
+ m->scratchRes = NULL;
+ }
+ else { /* otherwise we have to compare residue data blocks */
+ if (resDiffersFromPrev(*(m->reslstptr), m->scratchRes)) {
+ m->scratchRes->nextRes = *(m->reslstptr);
+ *(m->reslstptr) = m->scratchRes;
+ m->scratchRes = NULL;
+
+ }
+ else {
+ a->r = *(m->reslstptr); /* same, so point to prior block */
+ a->r->a = a; /* makes this atom the head of atom list for this res */
+ }
+ }
+ }
+ return a;
+}
+/*}}}newMovingAtom()_________________________________________________________*/
+
+/*{{{deleteMovingAtom()*******************************************************/
+void deleteMovingAtom(atom *a, void *userdata)
+{
+ movingAtomBuildInfo *m = (movingAtomBuildInfo *)userdata;
+ if (m && m->scratchRes) {
+ deleteResidueData(m->scratchRes); /* clean up extra memory */
+ m->scratchRes = NULL;
+ }
+ deleteAtom(a);
+}
+/*}}}deleteMovingAtom()______________________________________________________*/
+
+/*{{{movingDoCommand()********************************************************/
+void movingDoCommand(char* orientationName, double scoreBias,
+ atom *allMovingAtoms, void *userdata)
+{/*movingDoCommand() for autobondrot*/
+ /*orientationName holds the angle values as a character string*/
+
+/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
+/* sets of atoms (none in common) or allMovingAtoms/bbins can */
+/* be NULL. */
+/* allMovingAtoms refers to autobondrot set of atoms */
+
+ movingCommandInfo *m = (movingCommandInfo *)userdata;
+ region boundingBoxB, nonMovingBB;
+ atom *a = NULL;
+ atomBins *bbins = NULL;
+
+ /*autobondrot.c: alst == atom *allMovingAtoms existance implies autobondrot*/
+ if (allMovingAtoms) {
+ boundingBoxB.min = allMovingAtoms->loc;
+ boundingBoxB.max = allMovingAtoms->loc;
+ for(a = allMovingAtoms; a; a = a->next) {
+ updateBoundingBox(&(a->loc), &boundingBoxB);
+ }
+
+ /* Expand bounding box because of extra water hydrogens */
+ /* added in updateHydrogenInfo() */
+ nonMovingBB.min = m->abins->min;
+ nonMovingBB.max = m->abins->max;
+ addBBox2BBox(&nonMovingBB, &boundingBoxB);
+
+ bbins = binAtoms(allMovingAtoms, &boundingBoxB, 'b', m->probeRad,
+ m->keepUnselected, SET1|SET2);
+
+ if (m->abins == NULL || bbins == NULL) {
+ halt("no atoms for autobondrot processing");
+ }
+
+ if (! ImplicitH) {
+ if (m->firstPass) {
+ m->waterClones = updateHydrogenInfo(m->outf, m->allMainAtoms,
+ m->abins, allMovingAtoms, bbins, SET1|SET2, TRUE);
+ m->firstPass = FALSE;
+ }
+ else {
+ /*the DONOR prop tells updateHydrogenInfo() to build H? atoms*/
+ for(a = m->waterClones; a; a = a->next) {
+ if ((a->props & AMBIGWATER_PROP) && (a->elem == atomO)) {
+ a->props |= DONOR_PROP; /* turn water donor property back on*/
+ }
+ } /* since each pass through updateHydrogenInfo turns it off */
+
+ for(a = allMovingAtoms; a; a = a->next) {
+ if ((a->props & AMBIGWATER_PROP) && (a->elem == atomO)) {
+ a->props |= DONOR_PROP; /* turn water donor property back on*/
+ }
+ } /* since each pass through updateHydrogenInfo turns it off */
+
+ updateHydrogenInfo(m->outf, m->waterClones, m->abins,
+ allMovingAtoms, bbins, SET1|SET2, FALSE);
+ }
+ }
+
+ /*autobondrot at this stage has m->method == INTERSECTONCE == 1 */
+ /* or m->method == SELFINTERSECT == 3 (seems as given in probe command)*/
+ /* and m->countDots==1, m->rawOutput==1, m->drawSpike==1 */
+ /* orientationName==rawname== char* holding angle values */
+
+ doCommand(m->outf, m->method,
+ m->allMainAtoms, m->abins,
+ allMovingAtoms, bbins,
+ m->dots, m->probeRad, m->density, m->spikelen,
+ m->countDots, m->rawOutput, orientationName, scoreBias,
+ m->drawSpike, m->sayGroup, m->groupLabel,
+ m->argc, m->argv, m->message);
+
+ /*allMovingAtoms is closest thing to a flag for autobondrot mode*/
+
+ disposeBins(bbins);
+ }
+}/*movingDoCommand() for autobondrot*/
+/*}}}movingDoCommand()_______________________________________________________*/
+
+/*{{{doCommand()************ called from mainProbeProc() *********************/
+void doCommand(FILE *outf, int method,
+ atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[], float probeRad, float density, float spikelen,
+ int countDots, int rawOutput, char* rawname, double scoreBias,
+ int drawSpike, int sayGroup, char* groupLabel,
+ int argc, char **argv, char message[])
+{
+
+/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
+/* sets of atoms (none in common) or allMovingAtoms/bbins can */
+/* be NULL. */
+/* allMovingAtoms refers to autobondrot set of atoms */
+
+ /*doCommand is called from mainProbeProc() with rawname=="" */
+ /* and called from movingDoCommand() with rawname==orientationName */
+ /* which holds the string of the current autobondrot cycle's angle values*/
+ /*for autobondrot: method is set by probe command, e.g. */
+ /* INTERSECTONCE==1 as used in example of mobile sidechain in a protein */
+ /* SELFINTERSECT==3 as used by alaphitaupsi ramachandran calculation*/
+ /* autobondrot option defines: countDots==1, rawOutput==1*/
+ /* autobondrot seems to get here with: drawSpike==1*/
+
+ dotNode *rslts[NUMATOMTYPES][NODEWIDTH];
+ int nsel = 0, numSkinDots = 0;
+ int usesMovingAtoms = FALSE;
+
+ int j=0;
+
+ char extrastr[32]; /*060129 for extra master to control orig vs fitted dots*/
+
+ /*allMovingAtoms is closest thing to a flag for autobondrot mode*/
+ /*so if it exists and bbins exist (dcr?: mobile atoms near enough?) */
+ /*then usesMovingAtoms becomes the flag for autobondrot mode */
+ /*in effect probe is modal but too object oriented to admit such globalness*/
+
+ usesMovingAtoms = ((allMovingAtoms != NULL) && (bbins != NULL));
+ if (! usesMovingAtoms) { allMovingAtoms = NULL; bbins = NULL; }
+
+ initResults(rslts);
+ if (!countDots && rawOutput && Verbose) { /*write rawOutput col headers*/
+ if (OldStyleU) {
+ note(">>name:pat:type:srcAtom:targAtom:min-gap:gap:"
+ "kissEdge2BullsEye:dot2BE:dot2SC:spike:score:"
+ "stype:ttype:x:y:z:sBval:tBval");
+ }
+ else {
+ note(">>name:pat:type:srcAtom:targAtom:min-gap:gap:"
+ "spX:spY:spZ:spikeLen:score:"
+ "stype:ttype:x:y:z:sBval:tBval");
+ }
+ }
+ if (method == SELFINTERSECT)
+ {/*{{{(method == SELFINTERSECT)___expected default method___****/
+ if (Verbose && !(countDots && rawOutput)) { note("SelfIntersect"); }
+
+ /*SELFINTERSECT case, using one input file (and where srcPat == targPat)*/
+ /*is where unwashed NMR files with multiple models can be processed */
+ /*when there is not a single model specified in the pattern.*/
+ /*This uses a loop through all the model numbers actually in the file.*/
+
+ if(modelSrc == 0 && modelTarg == 0 && modelCount > 1) /*041114*/
+ {/*multiple models in file but no model specified in pattern*/
+ modelLimit = modelCount;
+ }
+ else {modelLimit = 1;}
+
+ for(j = 1; j <= modelLimit; j++) /*041114*/
+ {/*loop over models*/
+ if(modelLimit > 1)
+ {/*defines the multiple model case*/
+ modelToProcess = modelNumber[j]; /*models can be in any order 041114*/
+if(Verbose)
+{
+ fprintf(stderr,"processing modelNumber== %d\n",modelNumber[j]);
+}
+ }
+ if(j > 1)
+ {
+ freeResults(rslts);
+ initResults(rslts);
+ }
+ genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,
+ dots, probeRad, spikelen,SET1, SET1, rslts);
+ /*does this for all atoms... calls examineDots()*/
+
+ if (countDots) {/*autobondrot sets this, commandline can set this*/
+ if (!rawOutput) {
+ descrCommand(outf, "program:", "command:", argc, argv);
+ }
+ numSkinDots = enumDotSkin(allMainAtoms, abins,
+ allMovingAtoms, bbins, dots, SET1);
+ /*numSkinDots used to normalize output score*/
+ if (!rawOutput) {
+ fprintf(outf, "selection: self\nname: %s\n", groupLabel?groupLabel:"dots");
+ fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
+ density, probeRad, RadScaleFactor, RadScaleOffset);
+ fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
+ GAPweight, BUMPweight, HBweight);
+ }
+ if (usesMovingAtoms) {
+ nsel = countSelected(allMainAtoms, SET1) +
+ countSelected(allMovingAtoms, SET1);
+ }
+ else {
+ nsel = countSelected(allMainAtoms, SET1);
+ }
+ if (rawOutput) {/*autobondrot sets this*/
+ rawEnumerate(outf, "", rslts, method,
+ nsel, drawSpike, FALSE, numSkinDots, density,
+ groupLabel?groupLabel:"", rawname, scoreBias);
+ }
+ else {
+ enumerate(outf, "self dots", rslts, probeRad, method, nsel,
+ drawSpike, FALSE, numSkinDots, density);
+ }
+ }/*countDots*/
+ else {
+ if (rawOutput) {
+ writeRaw(outf, "1->1", rslts, probeRad,
+ groupLabel?groupLabel:"", density);
+ }
+ else if (OutputFmtType == 1) {
+ writeAltFmtO(outf, TRUE, TRUE, "self_dots", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 2) {
+ descrCommand(outf, "# software:", "# command:", argc, argv);
+ writeAltFmtXV(outf, TRUE, TRUE, "self_dots", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 3) { /*dcr041101 ONELINE :count:summaries:*/
+ countsummary(outf,"SelfIntersect", 1, 1); /*dcr041101 Lines,Pass*/
+ }
+ else
+ {/*kinemage output*/
+ if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
+ {countsummary(outf,"SelfIntersect", 9, 1);}
+
+ descrCommand(outf, "@caption", " command:", argc, argv);
+
+ if (sayGroup)
+ {
+ if(modelLimit > 1)
+ {/*doing jth of multiple models of an ensemble*/
+ fprintf(outf, "@group dominant {%s M%d} animate\n",
+ groupLabel?groupLabel:"dots",j);
+ }
+ else
+ {
+ fprintf(outf, "@group dominant {%s}\n",
+ groupLabel?groupLabel:"dots");
+ }
+ }
+ sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
+ writeOutput(outf, "self dots", rslts, drawSpike, method, extrastr);
+
+ }/*kinemage output*/
+ }
+ }/*loop over models*/
+ }/*}}}(method == SELFINTERSECT)________________________________*/
+ else if (method == INTERSECTONCE)
+ {/*{{{(method == INTERSECTONCE)*********************************/
+ if (Verbose && !(countDots && rawOutput)) { note("IntersectOnce"); }
+
+ genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,
+ dots, probeRad, spikelen, SET1, SET2, rslts);
+
+ if (countDots) {/*autobondrot sets this*/
+ if (!rawOutput) {
+ descrCommand(outf, "program:", "command:", argc, argv);
+ }
+ numSkinDots = enumDotSkin(allMainAtoms, abins,
+ allMovingAtoms, bbins, dots, SET1);
+ /*numSkinDots used to normalize output score*/
+ if (!rawOutput) {
+ fprintf(outf, "selection: once\nname: %s\n", groupLabel?groupLabel:"dots");
+ fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
+ density, probeRad, RadScaleFactor, RadScaleOffset);
+ fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
+ GAPweight, BUMPweight, HBweight);
+ }
+ if (usesMovingAtoms) {
+ nsel = countSelected(allMainAtoms, SET1) +
+ countSelected(allMovingAtoms, SET1);
+ }
+ else {
+ nsel = countSelected(allMainAtoms, SET1);
+ }
+ if (rawOutput) {/*autobondrot sets this*/
+ rawEnumerate(outf,"", rslts, method, nsel,
+ drawSpike, FALSE, numSkinDots, density,
+ groupLabel?groupLabel:"", rawname, scoreBias);
+ }
+ else {
+ enumerate(outf,"once dots", rslts, probeRad, method, nsel,
+ drawSpike, FALSE, numSkinDots, density);
+ }
+ }
+ else {
+ if (rawOutput) {
+ writeRaw(outf, "1->2", rslts, probeRad,
+ groupLabel?groupLabel:"", density);
+ }
+ else if (OutputFmtType == 1) {
+ writeAltFmtO(outf, TRUE, TRUE, "once_dots", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 2) {
+ descrCommand(outf, "# software:", "# command:", argc, argv);
+ writeAltFmtXV(outf, TRUE, TRUE, "once_dots", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 3) { /*dcr041101 ONELINE :count:summaries:*/
+ countsummary(outf,"IntersectOnce", 1, 1); /*dcr041101 Lines,Pass*/
+ }
+ else
+ {/*write kinemage*/
+
+ if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
+ {countsummary(outf,"IntersectOnce", 9, 1);}
+
+ descrCommand(outf, "@caption", " command:", argc, argv);
+ if (sayGroup) {
+ fprintf(outf, "@group dominant {%s}\n",
+ groupLabel?groupLabel:"dots");
+ }
+ sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
+ writeOutput(outf, "once dots", rslts, drawSpike, method, extrastr);
+ }
+ }
+ }/*}}}(method == INTERSECTONCE)________________________________*/
+ else if (method == INTERSECTBOTHWAYS)
+ {/*{{{(method == INTERSECTBOTHWAYS)*****************************/
+ if (Verbose && !(countDots && rawOutput)) { note("IntersectBothWays"); }
+ if (countDots) {
+ if (!rawOutput) {
+ descrCommand(outf, "program:", "command:", argc, argv);
+ fprintf(outf, "selection: both\nname: %s\n", groupLabel?groupLabel:"dots");
+ fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
+ density, probeRad, RadScaleFactor, RadScaleOffset);
+ fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
+ GAPweight, BUMPweight, HBweight);
+ }
+ }
+ else {
+ if (rawOutput) {
+ /* do nothing on purpose */
+ }
+ else if (OutputFmtType == 1) {
+ }
+ else if (OutputFmtType == 2) {
+ descrCommand(outf, "# software:", "# command:", argc, argv);
+ }
+ else {/*kinemage: keywords before double pass*/
+ descrCommand(outf, "@caption", " command:", argc, argv);
+ if (sayGroup) {
+ fprintf(outf, "@group {%s}\n",
+ groupLabel?groupLabel:"dots");
+ }
+ }
+ }
+
+ genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,
+ dots, probeRad, spikelen, SET1, SET2, rslts);
+
+ if (countDots) {
+ numSkinDots = enumDotSkin(allMainAtoms, abins,
+ allMovingAtoms, bbins, dots, SET1);
+ /*numSkinDots used to normalize output score*/
+ if (usesMovingAtoms) {
+ nsel = countSelected(allMainAtoms, SET1) +
+ countSelected(allMovingAtoms, SET1);
+ }
+ else {
+ nsel = countSelected(allMainAtoms, SET1);
+ }
+ if (rawOutput) {
+ rawEnumerate(outf, "1->2", rslts, method, nsel,
+ drawSpike, FALSE, numSkinDots, density,
+ groupLabel?groupLabel:"", rawname, scoreBias);
+ }
+ else {
+ enumerate(outf, "1->2", rslts, probeRad, method, nsel,
+ drawSpike, FALSE, numSkinDots, density);
+ }
+ }
+ else {
+ if (rawOutput) {
+ writeRaw(outf, "1->2", rslts, probeRad,
+ groupLabel?groupLabel:"", density);
+ }
+ else if (OutputFmtType == 1) {
+ writeAltFmtO(outf, TRUE, !sayGroup, "1->2", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 2) {
+ writeAltFmtXV(outf, TRUE, !sayGroup, "1->2", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 3) { /*dcr041101 ONELINE :count:summaries:*/
+ countsummary(outf,"IntersectBothWays 1->2", 1, 0);
+ /*dcr041101 Lines,Pass==0 no output for this pass*/
+ }
+ else {
+ sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
+ writeOutput(outf, "1->2", rslts, drawSpike, method, extrastr);
+
+ if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
+ {countsummary(outf,"IntersectBothWays 1->2", 9, 0);}
+ /*dcr041101 Lines,Pass==0 no output for this pass*/
+ }
+ }
+ freeResults(rslts);
+ initResults(rslts);
+
+ genDotIntersect(allMainAtoms, abins, allMovingAtoms, bbins,
+ dots, probeRad, spikelen, SET2, SET1, rslts);
+
+ if (countDots) {
+ numSkinDots = enumDotSkin(allMainAtoms, abins,
+ allMovingAtoms, bbins, dots, SET2);
+ /*numSkinDots used to normalize output score*/
+ if (usesMovingAtoms) {
+ nsel = countSelected(allMainAtoms, SET2) +
+ countSelected(allMovingAtoms, SET2);
+ }
+ else {
+ nsel = countSelected(allMainAtoms, SET2);
+ }
+ if (rawOutput) {
+ rawEnumerate(outf, "2->1", rslts, method, nsel,
+ drawSpike, FALSE, numSkinDots, density,
+ groupLabel?groupLabel:"", rawname, scoreBias);
+ }
+ else {
+ enumerate(outf, "2->1", rslts, probeRad, method, nsel,
+ drawSpike, FALSE, numSkinDots, density);
+ }
+ }
+ else {
+ if (rawOutput) {
+ writeRaw(outf, "2->1", rslts, probeRad,
+ groupLabel?groupLabel:"", density);
+ }
+ else if (OutputFmtType == 1) {
+ writeAltFmtO(outf, !sayGroup, TRUE, "2->1", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 2) {
+ writeAltFmtXV(outf, !sayGroup, TRUE, "2->1", rslts, drawSpike);
+ }
+ else if (OutputFmtType == 3) { /*dcr041101 ONELINE :count:summaries:*/
+ countsummary(outf,"IntersectBothWays 2->1", 1, 2);
+ /*dcr041101 Lines,Pass==2 output sum of 2 passes*/
+ }
+ else {
+ sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
+ writeOutput(outf, "2->1", rslts, drawSpike, method, extrastr);
+
+ if(ContactSUMMARY) /*dcr041101 Lines,Pass*/
+ {countsummary(outf,"IntersectBothWays 2->1", 9, 2);}
+ /*dcr041101 Lines,Pass==2 output sum of 2 passes*/
+ }
+ }
+ }/*}}}(method == INTERSECTBOTHWAYS)____________________________*/
+ else if (method == EXTERNALSURFACE)
+ {/*{{{(method == EXTERNALSURFACE)*******************************/
+ if (Verbose && !(countDots && rawOutput)) { note("ExternalSurface"); }
+
+ genDotSurface(allMainAtoms, abins, allMovingAtoms, bbins,
+ dots, probeRad, spikelen, SET1, rslts);
+
+ if (countDots) {
+ if (!rawOutput) {
+ descrCommand(outf, "program:", "command:", argc, argv);
+ }
+ numSkinDots = enumDotSkin(allMainAtoms, abins,
+ allMovingAtoms, bbins, dots, SET1);
+ /*numSkinDots used to normalize output score*/
+ if (!rawOutput) {
+ fprintf(outf, "selection: external\nname: %s\n",groupLabel?groupLabel:"dots");
+ fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
+ density, probeRad, RadScaleFactor, RadScaleOffset);
+ }
+ if (usesMovingAtoms) {
+ nsel = countSelected(allMainAtoms, SET1) +
+ countSelected(allMovingAtoms, SET1);
+ }
+ else {
+ nsel = countSelected(allMainAtoms, SET1);
+ }
+ if (rawOutput) {
+ rawEnumerate(outf, "", rslts, method, nsel,
+ FALSE, TRUE, numSkinDots, density,
+ groupLabel?groupLabel:"", rawname, scoreBias);
+ }
+ else {
+ enumerate(outf, "extern dots", rslts, probeRad, method, nsel,
+ FALSE, TRUE, numSkinDots, density);
+ }
+ }
+ else {
+ if (rawOutput) {
+ writeRaw(outf, "1->none", rslts, probeRad,
+ groupLabel?groupLabel:"", density);
+ }
+ else if (OutputFmtType == 1) {
+ writeAltFmtO(outf, TRUE, TRUE, "extern_dots", rslts, FALSE);
+ }
+ else if (OutputFmtType == 2) {
+ descrCommand(outf, "# software:", "# command:", argc, argv);
+ writeAltFmtXV(outf, TRUE, TRUE, "extern_dots", rslts, FALSE);
+ }
+ else {
+ descrCommand(outf, "@caption", " command:", argc, argv);
+ if (sayGroup) {
+ fprintf(outf, "@group dominant {%s}\n",
+ groupLabel?groupLabel:"dots");
+ }
+ sprintf(extrastr,"%s",groupLabel?groupLabel:"dots"); /*060129*/
+ writeOutput(outf, "extern dots", rslts, FALSE, method, extrastr);
+ }
+ }
+ }/*}}}(method == EXTERNALSURFACE)______________________________*/
+ else if (method == DUMPATOMCOUNT)
+ {/*{{{(method == DUMPATOMCOUNT)*********************************/
+ if (Verbose && !rawOutput) {
+ note("dumpAtomInfo");
+ descrCommand(outf, "program:", "command:", argc, argv);
+ fprintf(outf, "selection: self\nname: %s\n", groupLabel?groupLabel:"dots");
+ fprintf(outf, "density: %.1f dots per A^2\nprobeRad: %.3f A\nVDWrad: (r * %.3f) + %.3f A\n",
+ density, probeRad, RadScaleFactor, RadScaleOffset);
+ fprintf(outf, "score weights: gapWt=%g, bumpWt=%g, HBWt=%g\n",
+ GAPweight, BUMPweight, HBweight);
+ }
+ if (usesMovingAtoms) {
+ nsel = countSelected(allMainAtoms, SET1) +
+ countSelected(allMovingAtoms, SET1);
+ }
+ else {
+ nsel = countSelected(allMainAtoms, SET1);
+ }
+ if (rawOutput) {
+ if (groupLabel) {
+ fprintf(outf, "%d %s %s%s\n", nsel, rawname,
+ RAW_HEADER_COMMENT, groupLabel);
+ }
+ else {
+ fprintf(outf, "%d %s\n", nsel, rawname);
+ }
+ }
+ else {
+ fprintf(outf, "atoms selected: %d\n", nsel);
+ }
+ }/*}}}(method == DUMPATOMCOUNT)_______________________________*/
+
+ freeResults(rslts);
+}/*doCommand()*/
+/*}}}doCommand()_____________________________________________________________*/
+
+/*{{{descrCommand()***********************************************************/
+void descrCommand(FILE *outf, char *hdr1, char *hdr2, int argc, char **argv)
+{
+ int i = 0;
+ time_t t;
+ char *ts = NULL;
+
+ t = time(NULL);
+ ts = asctime(localtime(&t)); /* system dependent time string */
+
+ fprintf(outf, "%s %s, run %s", hdr1, shortVersionStr, ts);
+ fprintf(outf, "%s %s", hdr2, argv[0]);
+ for (i = 1; i < argc; i++) {
+ int dontQuote = (strpbrk(argv[i], " \t\n\b\r\v\f\a*\'") == NULL);
+ fprintf(outf,(dontQuote?" %s":" \"%s\""), argv[i]);
+ }
+ fprintf(outf, "\n");
+}
+/*}}}descrCommand()__________________________________________________________*/
+
+/*{{{loadDotSpheres()*********************************************************/
+void loadDotSpheres(pointSet dots[], float density)
+{
+ int i = 0;
+
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ dotSphere(&(dots[i]), getRadius(i, 0), density);
+ }
+ dotSphere(&COdots, getRadius(atomC, 1), density);
+}
+/*}}}loadDotSpheres()________________________________________________________*/
+
+/*{{{unloadDotSpheres()*******************************************************/
+void unloadDotSpheres(pointSet dots[])
+{
+ int i = 0;
+
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ freeDotSphere(&(dots[i]));
+ }
+}
+/*}}}unloadDotSpheres()______________________________________________________*/
+
+/*{{{probehelp()**************************************************************/
+void probehelp(int longlist)
+{
+ fprintf(stderr, "\nSyntax: probe input.pdb >> out.kin\n");
+ fprintf(stderr, " or: probe [flags] \"src pattern\" [\"target pattern\"] pdbfiles... >> out.kin\n\n");
+ fprintf(stderr, "Flags:\n");
+ fprintf(stderr, " -SElf self intersection: src -> src (default)\n");
+ fprintf(stderr, " -Both intersect both ways: src <=> targ\n");
+ fprintf(stderr, " -ONce single intersection: src -> targ\n");
+ fprintf(stderr, " -OUt external van der Waals surface of src (solvent contact surface)\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -AUTObondrot filename read and process an autobondrot file\n");
+if (! longlist) {
+ fprintf(stderr, "\n shortcuts: <<NO FLAGS>>, -SCSurface, -EXPOsed, -ASurface, -ACCESS, -SCAN0, -SCAN1\n");
+ fprintf(stderr, "\n most simple dotkin: probe -self all -kinemage input.pdb > out.kin\n");
+}
+else { /*longlist option*/
+ fprintf(stderr, "\n shortcuts:\n");
+ fprintf(stderr, " <<NO FLAGS>>same as: -4H -mc -het -self \"altA ogt33\"\n");
+ /*changed from 3 : dcr041017*/
+ fprintf(stderr, " -DEFAULTs same as: <<NO FLAGS>>, but allows some other flags\n"); /*dcr041101*/
+ fprintf(stderr, " -SCSurface same as: -drop -rad1.4 -out \"not water\"\n");
+ fprintf(stderr, " -EXPOsed same as: -drop -rad1.4 -out (note: user supplies pattern)\n");
+ fprintf(stderr, " -ASurface same as: -drop -rad0.0 -add1.4 -out \"not water\"\n");
+ fprintf(stderr, " -ACCESS same as: -drop -rad0.0 -add1.4 -out (note: user supplies pattern)\n");
+ fprintf(stderr, " -SCAN0 same as: -4H -mc -self \"alta blt40 ogt33\"\n");
+ /*changed from 3 : dcr041017*/
+ fprintf(stderr, " -SCAN1 same as: -4H -once \"sc alta blt40 ogt33\" \"alta blt40 ogt65,(not water ogt33)\"\n");
+ /*changed from 3 : dcr041017*/
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -DUMPAtominfo count the atoms in the selection: src\n\n");
+ fprintf(stderr, " (note that BOTH and ONCE require two patterns while\n");
+ fprintf(stderr, " OUT, SELF and DUMPATOMINFO require just one pattern)\n\n");
+ fprintf(stderr, " -Implicit implicit hydrogens\n");
+ fprintf(stderr, " -Explicit explicit hydrogens (default)\n");
+ fprintf(stderr, " -DEnsity# set dot density (default 16 dots/sq A)\n");
+ fprintf(stderr, " -Radius#.# set probe radius (default 0.25 A)\n");
+ fprintf(stderr, " -ADDvdw#.# offset added to Van der Waals radii (default 0.0)\n");
+ fprintf(stderr, " -SCALEvdw#.# scale factor for Van der Waals radii (default 1.0)\n");
+ fprintf(stderr, " -COSCale#.# scale C=O carbon Van der Waals radii (default 0.94)\n");
+ fprintf(stderr, " -SPike draw spike instead of dots (default)\n");
+ fprintf(stderr, " -SPike#.# set spike scale (default=0.5)\n");
+ fprintf(stderr, " -NOSpike draw only dots\n");
+ fprintf(stderr, " -HBRegular#.# max overlap for regular Hbonds(default=%.1f)\n", Min_regular_hb_cutoff);
+ fprintf(stderr, " -HBCharged#.# max overlap for charged Hbonds(default=%.1f)\n", Min_charged_hb_cutoff);
+ fprintf(stderr, " -Keep keep nonselected atoms (default)\n");
+ fprintf(stderr, " -DRop drop nonselected atoms\n");
+ fprintf(stderr, " -LIMit limit bump dots to max dist when kissing (default)\n");
+ fprintf(stderr, " -NOLIMit do not limit bump dots\n");
+ fprintf(stderr, " -LENs add lens keyword to kin file\n");
+ fprintf(stderr, " -NOLENs do not add lens keyword to kin file (default)\n");
+ fprintf(stderr, " -MC include mainchain->mainchain interactions\n");
+ fprintf(stderr, " -HETs include dots to non-water HET groups (default)\n");
+ fprintf(stderr, " -NOHETs exclude dots to non-water HET groups\n");
+ fprintf(stderr, " -WATers include dots to water (default)\n");
+ fprintf(stderr, " -NOWATers exclude dots to water\n");
+ fprintf(stderr, " -WAT2wat show dots between waters\n");
+ fprintf(stderr, " -DUMPH2O include water H? vectorlist in output\n");
+ fprintf(stderr, " -4H extend bond chain dot removal to 4 for H (default)\n");
+ fprintf(stderr, " -3 limit bond chain dot removal to 3\n");
+ fprintf(stderr, " -2 limit bond chain dot removal to 2\n");
+ fprintf(stderr, " -1 limit bond chain dot removal to 1\n");
+ fprintf(stderr, " -IGNORE \"pattern\" explicit drop: ignore atoms selected by pattern\n");
+ fprintf(stderr, " -DOCHO recognize CH..O Hbonds\n");
+ fprintf(stderr, " -CHO#.# scale factor for CH..O Hbond score (default=%.1f)\n", CHOHBfactor);
+ fprintf(stderr, " -PolarH use short radii of polar hydrogens (default)\n");
+ fprintf(stderr, " -NOPolarH do not shorten radii of polar hydrogens\n");
+ fprintf(stderr, " -NOFACEhbond do not identify HBonds to aromatic faces\n\n");
+
+ fprintf(stderr, " -Name \"name\" specify the group name (default \"dots\")\n");
+ fprintf(stderr, " -DOTMASTER group name used as extra master={name} on lists\n"); /*060129*/
+ fprintf(stderr, " -NOGroup do not generate @group statement in .kin format output\n");
+ fprintf(stderr, " -KINemage add @kinemage 1 statement to top of .kin format output\n\n");
+
+ fprintf(stderr, " -Countdots produce a count of dots-not a dotlist\n");
+ fprintf(stderr, " -Unformated output raw dot info\n");
+ fprintf(stderr, " name:pat:type:srcAtom:targAtom:mingap:gap:spX:spY:spZ:spikeLen:score:stype:ttype:x:y:z:sBval:tBval:\n");
+ fprintf(stderr, " -OFORMAT output dot info formatted for display in O\n");
+ fprintf(stderr, " -XVFORMAT output dot info formatted for display in XtalView\n");
+ fprintf(stderr, " -ONELINE output one line :contacts:by:severity:type:\n"); /*dcr041101*/
+ fprintf(stderr, " -GAPcolor color dots by gap amount (default)\n");
+ fprintf(stderr, " -ATOMcolor color dots by atom type\n");
+ fprintf(stderr, " -BASEcolor color dots by nucleic acid base type\n");
+ fprintf(stderr, " -COLORBase color dots by gap and nucleic acid base type\n");
+ fprintf(stderr, " -OUTCOLor \"name\" specify the point color for -OUT (default \"gray\")\n");
+ fprintf(stderr, " -GAPWeight# set weight for scoring gaps (default 0.25)\n");
+ fprintf(stderr, " -BUMPWeight# set relative scale for scoring bumps (default 10.0)\n");
+ fprintf(stderr, " -HBWeight# set relative scale for scoring Hbonds (default 4.0)\n");
+ fprintf(stderr, " -DIVLow#.# Division for Bump categories (default -0.4)\n");
+ fprintf(stderr, " -DIVHigh#.# Division for Contact categories (default 0.25)\n");
+ fprintf(stderr, " -MINOCCupancy#.# Occupancy below this is same as zero (default 0.02)\n");
+ fprintf(stderr, " -ELEMent add master buttons for different elements in kin output\n");
+ fprintf(stderr, " -NOHBOUT do not output contacts for HBonds\n");
+ fprintf(stderr, " -NOCLASHOUT do not output contacts for clashes\n");
+ fprintf(stderr, " -NOVDWOUT do not output contacts for van der Waals interactions\n");
+ fprintf(stderr, " -ONLYBADOUT onlybadout output bad clashes (severe overlap contacts)\n"); /*dcr041010*/
+ fprintf(stderr, " -SUMMARY output summary list of contacts and clashes\n"); /*dcr041101*/
+ fprintf(stderr, " -ONELINE output summary list on oneline\n"); /*dcr041101*/
+ fprintf(stderr, " -NOTICKs do not display the residue name ticker during processing\n");
+ fprintf(stderr, " -STDBONDs assume only standard bonding patterns in standard residues\n");
+ fprintf(stderr, " -NOPARENT do not bond hydrogens based on table of parent heavy atoms\n\n");
+ fprintf(stderr, " -SEGID use the PDB SegID field to descriminate between residues\n");
+ fprintf(stderr, " -OLDU generate old style -u output: kissEdge2BullsEye, etc\n");
+ fprintf(stderr, " -VErbose verbose mode (default)\n");
+ fprintf(stderr, " -REFerence display reference string\n");
+ fprintf(stderr, " -CHANGEs display a list of program changes\n");
+ fprintf(stderr, " -Quiet quiet mode\n");
+}/*longlist option*/
+ fprintf(stderr, "\n -Help show expanded help notice (includes other flags)\n");
+ fprintf(stderr, "\n -VERSION one line version to stdout\n\n");/*dcr041009*/
+ fprintf(stderr, "Pattern elements: (should be put in quotes on the command line)\n");
+if (longlist) { /*longlist option continues*/
+ fprintf(stderr, " FILE# within file #\n");
+ fprintf(stderr, " MODEL# within model #\n");
+ fprintf(stderr, " CHAINaa within chain a\n");
+ fprintf(stderr, " SEGaaaa segment identifier aaaa (where _ represents blank)\n");
+ fprintf(stderr, " ALTa alternate conformation a\n");
+ fprintf(stderr, " ATOMaaaa atom name aaaa (where _ represents blank)\n");
+ fprintf(stderr, " (all 4 characters are used so H would be ATOM_H__)\n");
+ fprintf(stderr, " RESaaa residue aaa\n");
+ fprintf(stderr, " # residue #\n");
+ fprintf(stderr, " #a residue #, insert a\n");
+ fprintf(stderr, " #-# residue range # (insert codes ignored)\n");
+ fprintf(stderr, " a residue type by one letter codes (eg. y)\n");
+ fprintf(stderr, " aaa residue type by three letter codes (eg. tyr)\n");
+ fprintf(stderr, " ALL,PROTEIN,MC,SC,BASE,ALPHA,BETA,NITROGEN,CARBON,OXYGEN,\n");
+ fprintf(stderr, " SULFUR,PHOSPHORUS,HYDROGEN,METAL,POLAR,NONPOLAR,CHARGED,\n");
+ fprintf(stderr, " DONOR,ACCEPTOR,AROMATIC,METHYL,HET,WATER,DNA,RNA\n");
+ fprintf(stderr, " all or a subset of the atoms\n");
+ fprintf(stderr, " OLT# Occupancy less than # (integer percent)\n");
+ fprintf(stderr, " OGT# Occupancy greater than # (integer percent)\n");
+ fprintf(stderr, " BLT# B-value less than # (integer)\n");
+ fprintf(stderr, " BGT# B-value greater than # (integer)\n");
+ fprintf(stderr, " INSa Insert code a (where _ represents blank)\n");
+ fprintf(stderr, " \n");
+ fprintf(stderr, " WITHIN #.# OF #.#, #.#, #.# atoms within distance from point\n");
+}/*longlist option continues*/
+else { /*NOT longlist*/
+ fprintf(stderr, " # residue number\n");
+ fprintf(stderr, " #a residue #, insert a\n");
+ fprintf(stderr, " #-# residue number range\n");
+ fprintf(stderr, " a OR aaa residue type by one or three letter codes\n");
+ fprintf(stderr, " FILE#,MODEL#,CHAINa,SEGaaaa,ALTa,ATOMaaaa,RESaaa,\n");
+ fprintf(stderr, " ALL,PROTEIN,MC,SC,BASE,ALPHA,BETA,NITROGEN,CARBON,OXYGEN,\n");
+ fprintf(stderr, " SULFUR,PHOSPHORUS,HYDROGEN,METAL,POLAR,NONPOLAR,CHARGED,\n");
+ fprintf(stderr, " DONOR,ACCEPTOR,AROMATIC,METHYL,HET,WATER,DNA,RNA,\n");
+ fprintf(stderr, " OLT#, OGT#, BLT#, BGT#, INSa, WITHIN #.# OF #.#, #.#, #.#\n");
+}
+ fprintf(stderr, " \n");
+ fprintf(stderr, " Patterns can be combined into comma separated lists\n");
+ fprintf(stderr, " such as \"trp,phe,tyr\" meaning TRP or PHE or TYR.\n");
+ fprintf(stderr, " \n");
+ fprintf(stderr, " Patterns that are sepatated by blanks must all be true\n");
+ fprintf(stderr, " such as \"chainb 1-5\" meaning residues 1 to 5 in chain B.\n");
+ fprintf(stderr, " \n");
+ fprintf(stderr, " You can also group patterns with parenthesis, separate\n");
+ fprintf(stderr, " multiple patterns with | meaning 'or' and choose the\n");
+ fprintf(stderr, " complement with NOT as in \"not file1\" meaning not in file 1.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " An autobondrot file is similar to other PDB input files\n");
+ fprintf(stderr, " but it includes information identifying atoms subject to rotations\n");
+ fprintf(stderr, " and other transformations.\n");
+if (longlist) { /*more longlist*/
+ fprintf(stderr, "\n Example autobondrot file fragment showing Calpha-Cbeta bond rotation\n");
+ fprintf(stderr, " and a periodic torsion penalty function for this rotation\n");
+ fprintf(stderr, " ATOM 1 CB TYR 61 34.219 17.937 4.659 1.00 0.00\n");
+ fprintf(stderr, " bondrot:chi1:78.7: 0:359:5:33.138:18.517: 5.531:34.219:17.937: 4.659\n");
+ fprintf(stderr, " cos:-3:60:3:\n");
+ fprintf(stderr, " ATOM 1 1HB TYR 61 34.766 18.777 4.206 1.00 0.00\n");
+ fprintf(stderr, " ATOM 1 2HB TYR 61 34.927 17.409 5.315 1.00 0.00\n");
+ fprintf(stderr, " ATOM 1 CG TYR 61 33.836 16.989 3.546 1.00 0.00\n");
+ fprintf(stderr, " ...\n");
+
+ fprintf(stderr, " Autobondrot commands use colons to separate values\n");
+ fprintf(stderr, " Transformations: BONDROT:id:currAng:start:end:stepSz:x1:y1:z1:x2:y2:z2\n");
+ fprintf(stderr, " TRANS: id:currpos:start:end:stepSz:x1:y1:z1:x2:y2:z2\n");
+ fprintf(stderr, " NULL # dummy\n");
+ fprintf(stderr, " Bias functions: COS:scale:phaseOffset:frequency\n");
+ fprintf(stderr, " POLY:scale:offset:polynomialDegree\n");
+ fprintf(stderr, " CONST:value\n");
+ fprintf(stderr, " Branching: SAVE and RESTORE or \"(\" and \")\"\n");
+ fprintf(stderr, " (e.g. to rotate each Chi and the methyls for isoleucine the\n");
+ fprintf(stderr, " sequence is: rotChi1/SAVE/rotChi2/rotCD1/RESTORE/rotCG2)\n");
+ fprintf(stderr, " Set orientation: GO:angle1:angle2:...\n");
+ fprintf(stderr, " Include files: @filename\n");
+ fprintf(stderr, " Comments: # comment text\n");
+}/*more longlist*/
+ fprintf(stderr, "\n%s\n", versionString);
+ exit(0);
+}/*probehelp()*/
+/*}}}probehelp()_____________________________________________________________*/
+
+/*{{{probeversion()***********************************************************/
+void probeversion(void) /*VERSION dcr041009*/
+{/*stdout one liner version for, e.g., MolProbity dcr041009*/
+ /*beware: orig defaults get superseded by shortcuts, like raw "probe"*/
+ printf("%s\n", shortVersionStr);
+ exit(0);
+}
+/*}}}probeversion()__________________________________________________________*/
+
+/*{{{processCommandline()**** called from mainProbeProc() ********************/
+atom* processCommandline(int argc, char **argv, int *method, region *bboxA,
+ float *density, float *probeRad,
+ int *drawSpike, float *spikelen, int *countDots,
+ int *keepUnselected,
+ char **srcArg, char **targArg, char **ignoreArg,
+ char **groupLabel, int *rawOutput, int *sayGroup,
+ int *addKinToFile, movingAtomBuildInfo *mabip,
+ residue **reslstptr)
+{/*processCommandline()*/
+ /*gets running conditions from the commandline as well as */
+ /*loads atomlist from in file, returns atomlist which becomes allMainAtoms*/
+ /* atomlist = probe.c/loadAtoms() */
+
+ /*called with address of mabis, i.e. mabip moving atom build info ptr */
+
+ int file = 0, nargs = 0, argcnt = 0, i = 0, n = 0;
+ char *p, message[200];
+ FILE *inf = stdin;
+ atom *atomlist = NULL;
+
+ *method = SELFINTERSECT;
+ nargs = 1;
+
+ *density = 16.0;
+ *probeRad = 0.25;
+ *drawSpike = TRUE;
+ *spikelen = 0.50;
+ *countDots = FALSE;
+ *keepUnselected = TRUE;
+ *rawOutput = FALSE;
+ *sayGroup = TRUE;
+ *addKinToFile = FALSE;
+
+ *srcArg = NULL;
+ *targArg = NULL;
+ *ignoreArg=NULL;
+ *groupLabel = NULL;
+
+ /*&mabis of mainProbeProc()== *mabip here */
+ if (mabip) {
+ mabip->filenum = 0;
+ mabip->inf = NULL;
+ mabip->close = FALSE;
+ mabip->srcPat = NULL;
+ mabip->targPat = NULL;
+ mabip->reslstptr= reslstptr;
+ mabip->scratchRes= NULL;
+ }
+
+ file = 0;
+ argcnt = 0;
+ for (i = 1; i < argc; i++) {
+ p = argv[i];
+ if (p[0] == '-') { /* -flag item */
+ if ((argcnt >= nargs) && (p[1] == '\0')) {
+ file++;
+ atomlist = loadAtoms(stdin,atomlist,bboxA,file, reslstptr);
+ }
+ else if(compArgStr(p+1, "HELP", 1)){
+ probehelp(1);
+ }
+ else if(compArgStr(p+1, "VERSION", 7)){/*before VERBOSE, dcr041009*/
+ probeversion();
+ }
+ else if(compArgStr(p+1, "VERBOSE", 2)){
+ Verbose = TRUE;
+ }
+ else if(compArgStr(p+1, "QUIET", 1)){
+ Verbose = FALSE;
+ }
+ else if(compArgStr(p+1, "EXPLICIT", 1)){
+ ImplicitH = FALSE;
+ }
+ else if(compArgStr(p+1, "IMPLICIT", 1)){
+ ImplicitH = TRUE;
+ }
+ else if(compArgStr(p+1, "DROP", 2)){
+ *keepUnselected = FALSE;
+ }
+ else if(compArgStr(p+1, "KEEP", 2)){
+ *keepUnselected = TRUE;
+ }
+ else if(n = compArgStr(p+1, "DENSITY", 2)){
+ *density = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "RADIUS", 1)){
+ *probeRad = parseReal(p, n+1, 10);
+
+ /* parameters correlated with radius */
+ if ((*probeRad) > GAPweight) {
+ GAPweight = *probeRad;
+ }
+ if ((*probeRad) > HighGoodCut) {
+ HighGoodCut = *probeRad;
+ }
+ }
+ else if((n = compArgStr(p+1, "SCALEVDW", 5)) /* new name,*/
+ || (n = compArgStr(p+1, "VDWSCALE", 3))){ /* old name */
+ RadScaleFactor = parseReal(p, n+1, 10);
+ if (RadScaleFactor < 0.0001
+ || RadScaleFactor > 1000.0) {
+ sprintf(message, "invalid scale factor: -scalevdw%g",
+ RadScaleFactor);
+ halt(message);
+ }
+ }
+ else if(n = compArgStr(p+1, "ADDVDW", 3)){
+ RadScaleOffset = parseReal(p, n+1, 10);
+ if (RadScaleOffset < -10.0
+ || RadScaleOffset > 1000.0) {
+ sprintf(message, "invalid vdw offset: -addvdw%g",
+ RadScaleOffset);
+ halt(message);
+ }
+ }
+ else if(n = compArgStr(p+1, "SPIKE", 2)){
+ *drawSpike = TRUE;
+ if (p[n+1]) {
+ *spikelen = parseReal(p, n+1, 10);
+ }
+ }
+ else if(compArgStr(p+1, "NOSPIKE", 3)){
+ *drawSpike = FALSE;
+ }
+ else if(compArgStr(p+1, "KINEMAGE", 3)){
+ *addKinToFile = TRUE;
+ *countDots = FALSE; /* also forces kin format */
+ *rawOutput = FALSE;
+ OutputFmtType = 0;
+ }
+ else if(compArgStr(p+1, "NOGROUP", 3)){
+ *sayGroup = FALSE;
+ }
+ else if(compArgStr(p+1, "ELEMENT", 4)){
+ AtomMasters = TRUE;
+ }
+ else if(compArgStr(p+1, "COUNTDOTS", 1)){
+ *countDots = TRUE;
+ }
+ else if(compArgStr(p+1, "UNFORMATED", 1)){
+ *rawOutput = TRUE;
+ }
+ else if(compArgStr(p+1, "OUTSIDE", 2)){
+ *method = EXTERNALSURFACE;
+ nargs = 1;
+ }
+ else if(compArgStr(p+1, "ONCE", 2)){
+ *method = INTERSECTONCE;
+ nargs = 2;
+ }
+ else if(compArgStr(p+1, "BOTH", 1)){
+ *method = INTERSECTBOTHWAYS;
+ nargs = 2;
+ }
+ else if(compArgStr(p+1, "SELF", 2)){
+ *method = SELFINTERSECT;
+ nargs = 1;
+ }
+ else if(compArgStr(p+1, "DUMPATOMINFO", 5)){
+ *method = DUMPATOMCOUNT;
+ nargs = 1;
+ }
+ else if(compArgStr(p+1, "SCSURFACE", 3)){
+ *method = EXTERNALSURFACE;
+ nargs = 1;
+ argcnt = 1;
+ * srcArg = "not water";
+ *keepUnselected = FALSE;
+ *probeRad = 1.4;
+ *groupLabel = "SCS";
+ }
+ else if(compArgStr(p+1, "EXPOSED", 4)){
+ *method = EXTERNALSURFACE;
+ nargs = 1;
+ *keepUnselected = FALSE;
+ *probeRad = 1.4;
+ *groupLabel = "SCS";
+ }
+ else if(compArgStr(p+1, "ASURFACE", 2)){
+ *method = EXTERNALSURFACE;
+ nargs = 1;
+ argcnt = 1;
+ * srcArg = "not water";
+ *keepUnselected = FALSE;
+ RadScaleOffset = 1.4;
+ *probeRad = 0.0;
+ *groupLabel = "AS";
+ }
+ else if(compArgStr(p+1, "ACCESS", 6)){
+ *method = EXTERNALSURFACE;
+ nargs = 1;
+ *keepUnselected = FALSE;
+ RadScaleOffset = 1.4;
+ *probeRad = 0.0;
+ *groupLabel = "AS";
+ }
+ else if(n = compArgStr(p+1, "SCAN", 4)){
+ int scanType = parseInteger(p, n+1, 10);
+ switch(scanType) {
+ case 0:
+ *method = SELFINTERSECT;
+ nargs = 1;
+ argcnt = 1;
+ * srcArg = "alta blt40 ogt33";
+ Maxbonded = 4; /*changed from 3 : dcr041017*/
+ DoMcMc = TRUE;
+ break;
+ case 1:
+ *method = INTERSECTONCE;
+ nargs = 2;
+ argcnt = 2;
+ * srcArg = "sc alta blt40 ogt33";
+ *targArg = "alta blt40 ogt65,(not water ogt33)";
+ Maxbonded = 4; /*changed from 3 : dcr041017*/
+ break;
+ default:
+ sprintf(message,
+ "invalid scan type %d, for more info use -help",
+ scanType);
+ halt(message);
+ break;
+ }
+ }
+ else if(compArgStr(p+1, "SEGID", 5)){
+ SplitBySegID = TRUE;
+ }
+ else if(compArgStr(p+1, "LIMIT", 3)){
+ LimitDots = TRUE;
+ }
+ else if(compArgStr(p+1, "NOLIMIT", 5)){
+ LimitDots = FALSE;
+ }
+ else if(compArgStr(p+1, "LENS", 3)){
+ LensDots = TRUE;
+ }
+ else if(compArgStr(p+1, "NOLENS", 5)){
+ LensDots = FALSE;
+ }
+ else if(compArgStr(p+1, "MC", 2)){
+ DoMcMc = TRUE;
+ }
+ else if(compArgStr(p+1, "DUMPH2O", 5)){
+ DumpNewHO = TRUE;
+ }
+ else if(compArgStr(p+1, "HETS", 3)){
+ DoHet = TRUE;
+ }
+ else if(compArgStr(p+1, "NOHETS", 5)){
+ DoHet = FALSE;
+ }
+ else if(compArgStr(p+1, "WAT2WAT", 4)){
+ DoWatWat = TRUE; /* should be before WATERS */
+ DoH2O = TRUE;
+ }
+ else if(compArgStr(p+1, "WATERS", 3)){
+ DoH2O = TRUE;
+ }
+ else if(compArgStr(p+1, "NOWATERS", 5)){
+ DoH2O = FALSE;
+ }
+ else if(compArgStr(p+1, "4H", 1)){
+ Maxbonded = 4;
+ }
+ else if(compArgStr(p+1, "3", 1)){
+ Maxbonded = 3;
+ }
+ else if(compArgStr(p+1, "2", 1)){
+ Maxbonded = 2;
+ }
+ else if(compArgStr(p+1, "1", 1)){
+ Maxbonded = 1;
+ }
+ else if(compArgStr(p+1, "POLARH", 1)){
+ UsePolarH = TRUE;
+ }
+ else if(compArgStr(p+1, "NOPOLARH", 3)){
+ UsePolarH = FALSE;
+ }
+ else if(compArgStr(p+1, "NOFACEHBOND", 6)){
+ HB2aromFace = FALSE;
+ }
+ else if(compArgStr(p+1, "NAME", 1)){
+ if (++i < argc) {
+ *groupLabel = argv[i];
+ }
+ else {
+ halt("no group name after -Name flag");
+ }
+ }
+ else if(compArgStr(p+1, "DOTMASTER", 9)){
+ LMasterName = TRUE; /*extra master={name} on lists 060129*/
+ }
+ else if(compArgStr(p+1, "IGNORE", 6)){
+ if (++i < argc) {
+ *ignoreArg = argv[i];
+ }
+ else {
+ halt("no pattern after -IGNORE flag");
+ }
+ }
+ else if(n = compArgStr(p+1, "COSCALE", 4)){
+ CORadScale = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "HBREGULAR", 3)){
+ Min_regular_hb_cutoff = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "HBCHARGED", 3)){
+ Min_charged_hb_cutoff = parseReal(p, n+1, 10);
+ }
+ else if(compArgStr(p+1, "DOCHO", 5)){
+ PermitCHXHB = TRUE;
+ }
+ else if(n = compArgStr(p+1, "CHO", 3)){
+ CHOHBfactor = parseReal(p, n+1, 10);
+ }
+ else if(compArgStr(p+1, "ATOMCOLOR", 4)){
+ ColorGap = FALSE;
+ }
+ else if(compArgStr(p+1, "GAPCOLOR", 3)){
+ ColorGap = TRUE;
+ }
+ else if(compArgStr(p+1, "BASECOLOR", 4)){
+ ByNABaseColor = TRUE;
+ ColorGap = FALSE; /* forces base color to be only type of display */
+ }
+ else if(compArgStr(p+1, "COLORBASE", 6)){
+ ByNABaseColor = TRUE;
+ }
+ else if(n = compArgStr(p+1, "GAPWEIGHT", 4)){
+ GAPweight = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "BUMPWEIGHT", 5)){
+ BUMPweight = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "HBWEIGHT", 3)){
+ HBweight = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "DIVLow", 4)){
+ LowGoodCut = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "DIVHigh", 4)){
+ HighGoodCut = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "MINOCCupancy", 6)){
+ OccupancyCutoff = parseReal(p, n+1, 10);
+ }
+ else if(n = compArgStr(p+1, "NOOCCupancy", 5)){
+ OccupancyCriteria = FALSE; /*060831*/
+ }
+ else if(compArgStr(p+1, "OFORMAT", 7)){
+ OutputFmtType = 1;
+ }
+ else if(compArgStr(p+1, "XVFORMAT", 8)){
+ OutputFmtType = 2;
+ }
+ else if(compArgStr(p+1, "ONELINE", 7)){ /*oneline dcr041101*/
+ ContactSUMMARY = TRUE;
+ OutputFmtType = 3;
+ argcnt = 1; /*recognize next naked item as an input file name*/
+ }
+ else if(compArgStr(p+1, "SUMMARY", 7)){ /*summary dcr041101*/
+ ContactSUMMARY = TRUE;
+ argcnt = 1; /*recognize next naked item as an input file name*/
+ }
+ else if(compArgStr(p+1, "DEFAULTS", 7)){ /*defaults dcr041101*/
+ *srcArg = "altA ogt33";
+ *method = SELFINTERSECT;
+ Maxbonded = 4; /*changed from 3 : dcr041017*/
+ DoMcMc = TRUE;
+ DoHet = TRUE;
+ argcnt = 1; /*recognize next naked item as an input file name*/
+ /*like naked defaults but allow flags like -summary or -oneline*/
+ }
+ else if(compArgStr(p+1, "NOHBOUT", 7)){
+ OutputHBs = FALSE;
+ }
+ else if(compArgStr(p+1, "NOCLASHOUT", 10)){
+ OutputClashes = FALSE;
+ }
+ else if(compArgStr(p+1, "NOVDWOUT", 8)){
+ OutputVDWs = FALSE;
+ }
+ else if(compArgStr(p+1, "ONLYBADOUT", 10)){ /*dcr041010*/
+ OnlyBadOut = TRUE;
+ }
+ else if(compArgStr(p+1, "NOTICKS", 6)){
+ ShowTicks = FALSE;
+ }
+ else if(compArgStr(p+1, "STDBONDS", 7)){
+ UseStdBond = TRUE;
+ }
+ else if(compArgStr(p+1, "OLDU", 4)){
+ OldStyleU = TRUE;
+ *rawOutput = TRUE;
+ }
+#ifdef JACKnANDREA
+ else if(compArgStr(p+1, "WRITEHBONDS", 6)){
+ writeHbonds = TRUE;
+ }
+#endif
+ else if(compArgStr(p+1, "NOPARENT", 8)){
+ UseHParent = FALSE;
+ }
+ else if(compArgStr(p+1, "OUTCOLOR", 6)){
+ if (++i < argc) {
+ OutPointColor = argv[i];
+ }
+ else {
+ halt("no color name after -OUTCOLolor flag");
+ }
+ }
+ else if(compArgStr(p+1, "AUTObondrot", 4)){
+ if (++i < argc) {
+ p = argv[i];
+ if (p[0] == '-') {
+ if (p[1] == '\0') {
+ file++;
+ if (mabip) {
+ mabip->filenum = file;
+ mabip->inf = stdin; /*input of autobondrot atoms*/
+ mabip->close = FALSE;
+ }
+ }
+ else {
+ sprintf(message, "%s flag instead of filename after -AUTObondrot", p);
+ halt(message);
+ }
+ }
+ else {
+ file++;
+ inf = fopen(p, "r"); /*p holds autobondrot input file name*/
+ if (inf) {
+ if (mabip) {
+ mabip->filenum = file;
+ mabip->inf = inf;
+ mabip->close = TRUE;
+ }
+ }
+ else {
+ sprintf(message, "could not open -AUTOBONDROT file: %s", p);
+ halt(message);
+ }
+ }
+ /*Lautobondrot = TRUE;*/ /*050111 probe.c global logical */
+ *countDots = TRUE;
+ *rawOutput = TRUE;
+ /*autobondrot mode does NOT read from input file at this time*/
+ }
+ else {
+ halt("no filename after -AUTObondrot flag");
+ }
+ }
+ else if(compArgStr(p+1, "REFerence", 3)){
+ sprintf(message, "Please cite: %s", referenceString);
+ note(message);
+ sprintf(message, "For more information see %s", electronicReference);
+ note(message);
+ exit(0);
+ }
+ else if(n = compArgStr(p+1, "CHANGEs", 6)){
+ dump_changes(stderr);
+ }
+ else if(n = compArgStr(p+1, "DEBUG", 5)){
+ DebugLevel = parseInteger(p, n+1, 10);
+ }
+ else { /*either naked - or unrecognized character string*/
+ sprintf(message, "unrecognized flag, %s", p);
+ halt(message);
+ }
+ }/* -flag item */
+ else if (argcnt <= 0) { /*lonely naked item: store as a source argument*/
+ *srcArg = p; /*if nothing else comes in, use as input file name*/
+ argcnt = 1;
+ }
+ else if (argcnt == 1 && nargs == 2) {
+ if((p[0] == '=') && (p[1] == '\0')){
+ *targArg = *srcArg;
+ }
+ else {
+ *targArg = p;
+ }
+ argcnt = 2;
+ }
+ else {
+ file++;
+ inf = fopen(p, "r");
+ if (inf) {
+ strcpy(inputfilename,p); /*dcr041023*/
+ /*read atoms from input file now*/
+ atomlist = loadAtoms(inf, atomlist, bboxA, file, reslstptr);
+ fclose(inf);
+ }
+ else {
+ sprintf(message, "could not open file %d: %s",
+ file, p);
+ halt(message);
+ }
+ }
+ }
+ if (file < 1) {
+ if (argc == 2 && argcnt == 1 && *srcArg) { /*naked item stored as srcArg*/
+ p = *srcArg; /*interpret as an input file name, then presume defaults*/
+ note("*SIMPLE SELF DOTS (for more info use -help flag and look for <<NO FLAGS>>)");
+ *srcArg = "altA ogt33";
+ *method = SELFINTERSECT;
+ Maxbonded = 4; /*changed from 3 : dcr041017*/
+ DoMcMc = TRUE;
+ DoHet = TRUE;
+ file++;
+ inf = fopen(p, "r");
+ if (inf) {
+ strcpy(inputfilename,p); /*dcr041023*/
+ /*read atoms from input file now*/
+ atomlist = loadAtoms(inf, atomlist, bboxA, file, reslstptr);
+ fclose(inf);
+ }
+ else {
+ sprintf(message, "could not open file %d: %s",
+ file, p);
+ halt(message);
+ }
+ }
+ else {
+ errmsg("no input files");
+ probehelp(0);
+ }
+ }
+
+ return atomlist; /*loaded under some conditions, but not if autobondrot!*/
+}/*processCommandline()*/
+/*}}}processCommandline()____________________________________________________*/
+
+/*{{{initEndData()************************************************************/
+void initEndData(chainEndData_t *ed)
+{
+ int i = 0;
+ for (i = 0; i < 8; i++) { ed->ambigN[i] = NULL; ed->ambigO[i] = NULL; }
+ ed->res_mc_oxy_cnt = 0;
+ ed->first = 0;
+ ed->last = 0;
+ ed->Ntmarkers = 0;
+ ed->Ctmarkers = 0;
+ for (i = 0; i < 4; i++) { ed->hisNHcount[i] = 0; }
+}
+/*}}}initEndData()___________________________________________________________*/
+
+/*{{{hisNHcheck()*************************************************************/
+/* His ring atoms start out with a positive charge. */
+/* Here we remove the charge for His residues without two ring NH protons.*/
+void hisNHcheck(chainEndData_t *ed, atom *atomlist, int rescnt)
+{
+ int i = 0;
+ atom *rat = NULL;
+
+ if (ed->hisNHcount[0]) { /* the zeroth counter flags: Is this a HIS? */
+ /*is a histidine*/
+ for(rat = atomlist; rat; rat = rat->next) {
+ if ((rat->r->rescnt == rescnt) && (rat->props & POSITIVE_PROP)) {
+ char altc = toupper(rat->altConf);
+ int ialt = 0;
+
+ if ((altc==' ')||(altc=='A')||(altc=='1')) { ialt = 1; }
+ else if ((altc=='B')||(altc=='2')) { ialt = 2; }
+ else if ((altc=='C')||(altc=='3')) { ialt = 3; }
+
+ if (ialt > 0) {
+ if (ed->hisNHcount[ialt] < 2) { /* his not positive */
+ rat->props &= ~POSITIVE_PROP;
+ }
+ else { /* his positive but not an acceptor */
+ rat->props &= ~ACCEPTOR_PROP;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < 4; i++) { ed->hisNHcount[i] = 0; }
+ }/*is a histidine*/
+}
+/*}}}hisNHcheck()____________________________________________________________*/
+
+/*{{{resCheck()***************************************************************/
+/* called after each residue is read */
+void resCheck(chainEndData_t *ed, atom *atomlist, int rescnt)
+{
+ hisNHcheck(ed, atomlist, rescnt);
+}
+/*}}}resCheck()______________________________________________________________*/
+
+/*{{{CtermCheck()*************************************************************/
+/* called when a new residue begins and at the end of all processing */
+/* to process the previous residue */
+void CtermCheck(chainEndData_t *ed, int rescnt, int isChainEnd)
+{
+ int i = 0;
+ /* avoid processing the first time 'cause there ain't no chain pending */
+
+ if (isChainEnd && rescnt) {
+ ed->last = rescnt; /* last residue */
+
+ /* see if we can put the pieces together to determine end charge */
+
+ for (i = 0; i < 4; i++) { /* only array[0-3] contains first Ns */
+ if (ed->ambigN[i]) {
+ if (ed->ambigN[i]->r->rescnt == ed->first
+ && ed->Ntmarkers == ed->first) {
+ ed->ambigN[i]->props |= POSITIVE_PROP;
+ }
+ }
+ else { break; }
+ }
+ for (i = 0; i < 8; i++) { /* array[0-7] contains last Os */
+ if (ed->ambigO[i]) {
+ if (ed->ambigO[i]->r->rescnt == ed->last
+ && ed->Ctmarkers == ed->last) {
+ ed->ambigO[i]->props |= NEGATIVE_PROP;
+ }
+ }
+ else { break; }
+ }
+
+ initEndData(ed); /* reset the end data record */
+ }
+}
+/*}}}CtermCheck()____________________________________________________________*/
+
+/*{{{noticedNt()**************************************************************/
+/* called when we have an indicator that residue is at N terminus */
+/* to look for ambigN and mark charged */
+void noticedNt(chainEndData_t *ed, int rescnt)
+{
+ int i = 0;
+
+ for (i = 4; i < 8; i++) { /* only array[4-7] contains last Ns */
+
+ if (ed->ambigN[i]) {
+ if (ed->ambigN[i]->r->rescnt == rescnt) {
+ ed->ambigN[i]->props |= POSITIVE_PROP;
+ }
+ }
+ else { break; }
+ }
+}
+/*}}}noticedNt()_____________________________________________________________*/
+
+/*{{{noticedCt()**************************************************************/
+/* called when we have an indicator that residue is at C terminus */
+/* to look for ambigO and mark charged */
+void noticedCt(chainEndData_t *ed, int rescnt)
+{
+ int i = 0;
+
+ for (i = 0; i < 8; i++) { /* array[0-7] contains last Os */
+ if (ed->ambigO[i]) {
+ if (ed->ambigO[i]->r->rescnt == rescnt) {
+ ed->ambigO[i]->props |= NEGATIVE_PROP;
+ }
+ }
+ else { break; }
+ }
+}
+/*}}}noticedCt()_____________________________________________________________*/
+
+/*{{{NtermCheck()*************************************************************/
+/* called whenever a new residue begins */
+void NtermCheck(chainEndData_t *ed, int rescnt, int isChainEnd)
+{
+ int i = 0;
+
+ ed->res_mc_oxy_cnt = 0; /* reset Oxygen data for each residue */
+ for (i = 0; i < 8; i++) { ed->ambigO[i] = NULL; }
+
+ /* we have reserved the top 4 nitrogen slots for most recent res */
+ /* so we have to clear this here */
+ for (i = 4; i < 8; i++) { ed->ambigN[i] = NULL; }
+
+ if (isChainEnd) {
+ ed->first = rescnt; /* first residue */
+ }
+}
+/*}}}NtermCheck()____________________________________________________________*/
+
+/*{{{ProcessResInfo()*** called from loadAtoms() & movingAtomListProcessing()*/
+/* called for each atom read in */
+void ProcessResInfo(chainEndData_t *ed, atom *a)
+{
+ int i = 0;
+
+ if (strstr("HIS:his", a->r->resname)) {/*is a histidine*/
+ ed->hisNHcount[0] = 1; /* indicates this is a HIS */
+ if ( strstr(" HD1: hd1: HE2: he2", a->atomname)) {
+ char altc = toupper(a->altConf);
+ if ((altc==' ')||(altc=='A')||(altc=='1')) {
+ ed->hisNHcount[1]++;
+ }
+ else if ((altc=='B')||(altc=='2')) {
+ ed->hisNHcount[2]++;
+ }
+ else if ((altc=='C')||(altc=='3')) {
+ ed->hisNHcount[3]++;
+ }
+ }
+ }/*is a histidine*/
+
+ /* look for indicators that we are at the end of a chain */
+
+ if (a->props & CHECK_ENDS_PROP) {
+ if (isHatom(a->elem)) {
+ if (! ed->Ntmarkers) { ed->Ntmarkers = a->r->rescnt; }
+ noticedNt(ed, a->r->rescnt);
+ }
+ else if ( (a->elem == atomO) &&
+ ((a->altConf==' ')||(a->altConf=='A')||(a->altConf=='1')) ){
+ ed->res_mc_oxy_cnt++;
+ if (ed->res_mc_oxy_cnt == 2) {
+ ed->Ctmarkers = a->r->rescnt;
+ noticedCt(ed, a->r->rescnt);
+ }
+ }
+ else if (strstr(a->atomname, "OXT")) { /* check SUBSET of name */
+ ed->Ctmarkers = a->r->rescnt;
+ noticedCt(ed, a->r->rescnt);
+ }
+ }
+
+ /* save pointers to the first ambigNs and the last ambigOs and Ns */
+ /* we save multiple atoms to both find both possible mc oxygens */
+ /* and to handle multiple conformations (we can do 4 max) */
+ /* All atoms must have the same residue counter */
+
+ if (a->props & MAYBECHG_PROP) {
+ if (!strcmp(a->atomname, " N ")) {
+
+ if (ed->first == a->r->rescnt) { /* mark the Nterm -- jmw 20011001 */
+ a->props |= CHECK_ENDS_PROP;
+ }
+
+ for (i = 0; i < 4; i++) {/* first Ns[0-3] (cleared at chain ends)*/
+ if (ed->ambigN[i] == NULL) {
+ if ((i == 0) || (ed->ambigN[i-1]->r == a->r)) {
+ ed->ambigN[i] = a;
+ }
+ break;
+ }
+ }
+ for (i = 4; i < 8; i++) { /* last Ns[4-7] (cleared each res)*/
+ if (ed->ambigN[i] == NULL) {
+ if ((i == 4) || (ed->ambigN[i-1]->r == a->r)) {
+ ed->ambigN[i] = a;
+ }
+ break;
+ }
+ }
+ }
+ if (!strcmp(a->atomname, " O ")) { /* last Os[0-7] (cleared each res)*/
+ for (i = 0; i < 8; i++) {
+ if (ed->ambigO[i] == NULL) {
+ if ((i == 0)|| (ed->ambigN[i-1]->r == a->r)) {
+ ed->ambigO[i] = a;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+}
+/*}}}ProcessResInfo()________________________________________________________*/
+
+/*{{{movingAtomListProcessing()***********************************************/
+void movingAtomListProcessing(atom *initAtomLst, void *userdata)
+{
+ int previd = 0, rescnt = 0;
+ char prevInsCode = ' ';
+ char prevChain[3];
+ atom *a = NULL, *prevAtomLst = NULL, *nexta = NULL;
+ chainEndData_t endData;
+
+ initEndData(&endData);
+
+ prevChain[0] = prevChain[1] = '?';
+ prevChain[2] = '\0';
+
+ for(a=initAtomLst; a; a = nexta) {
+ nexta = a->next;
+
+ a->next = prevAtomLst; /* remove a from initial atom list */
+ prevAtomLst = a; /* and build up a reversed list of */
+ /* only atoms previously seen */
+
+ if (a->r->resid != previd || a->r->resInsCode != prevInsCode
+ || strcmp(a->r->chain, prevChain) != 0) {
+
+ if (rescnt){
+ resCheck(&endData, prevAtomLst, rescnt);
+ }
+ CtermCheck(&endData, rescnt, (strcmp(a->r->chain, prevChain) != 0));
+
+ ++rescnt;
+
+ NtermCheck(&endData, rescnt, (strcmp(a->r->chain, prevChain) != 0));
+ previd = a->r->resid;
+ prevInsCode = a->r->resInsCode;
+ strcpy(prevChain, a->r->chain);
+ prevChain[2] = '\0';
+ }
+ a->r->rescnt = rescnt;
+
+ ProcessResInfo(&endData, a);
+ }
+
+ if (rescnt) { resCheck(&endData, prevAtomLst, rescnt); }
+ CtermCheck(&endData, rescnt, TRUE);
+}
+/*}}}movingAtomListProcessing()______________________________________________*/
+
+/*{{{loadAtoms()************* called from processCommandline() ***************/
+atom* loadAtoms(FILE *fp, atom *atomlist, region *boundingBox, int file,
+ residue **reslstptr)
+{
+ int previd = 0, rescnt = 0, model = 0;
+ char *rec, prevInsCode = ' ';
+ char prevChain[3];
+ atom *a = NULL;
+ residue *scratchRes;
+ chainEndData_t endData;
+
+ prevChain[0] = prevChain[1] = '?';
+ prevChain[2] = '\0';
+
+ scratchRes = newResidueData();
+
+ initEndData(&endData);
+
+ while(rec = getPDBrecord(fp)) { /*loop over all records in pdb file*/
+ if (isTer(rec)) {
+ prevChain[0] = prevChain[1] = '?';
+ prevChain[2] = '\0';
+ }
+ if ((isAtom(rec) || isHet(rec)) && ! isPseudoAtom(rec)) {/*atom or htatm*/
+ a = newAtom(rec, file, model, scratchRes);
+ if (!a) { break;}
+
+ if (a->r->resid != previd || a->r->resInsCode != prevInsCode
+ || strcmp(a->r->chain, prevChain) != 0) {
+
+ if (rescnt){
+ resCheck(&endData, atomlist, rescnt);
+ }
+ CtermCheck(&endData, rescnt, (strcmp(a->r->chain, prevChain) != 0));
+
+ ++rescnt;
+
+ NtermCheck(&endData, rescnt, (strcmp(a->r->chain, prevChain) != 0));
+ previd = a->r->resid;
+ prevInsCode = a->r->resInsCode;
+ strcpy(prevChain, a->r->chain);
+ prevChain[2] = '\0';
+ }
+ a->r->rescnt = rescnt;
+
+ ProcessResInfo(&endData, a);
+
+ if (ImplicitH && isHatom(a->elem)) {
+ deleteAtom(a); /* filter out implicit hydrogens */
+ continue;
+ }
+ if (isDummyAtom(*a)) {
+ deleteAtom(a); /* filter out dummy Xplor atoms */
+ continue;
+ }
+
+ if (!atomlist) {
+ boundingBox->min = a->loc;
+ boundingBox->max = a->loc;
+ }
+ a->next = atomlist;
+ atomlist = a;
+
+ updateBoundingBox(&(a->loc), boundingBox);
+
+ if (*reslstptr == NULL) {/* first residue goes on residue list */
+ *reslstptr = scratchRes;
+ scratchRes = newResidueData();
+ }
+ else { /* otherwise we have to compare residue data blocks */
+ if (resDiffersFromPrev(*reslstptr, scratchRes)) {
+ scratchRes->nextRes = *reslstptr;
+ *reslstptr = scratchRes;
+ scratchRes = newResidueData();
+
+ }
+ else {
+ a->r = *reslstptr; /* same, so point to prior block */
+ a->r->a = a; /* makes this atom the head of atom list for this res */
+ }
+ }
+
+ }/*atom or htatm*/
+ if (isModel(rec)) {
+ model = parseModel(rec);
+ modelNumber[++modelCount] = model; /*041114*/
+if(Verbose)
+{
+ fprintf(stderr,"modelNumber[%d]==%d\n",modelCount,modelNumber[modelCount]);
+}
+ }
+ }/*loop over all records in pdb file*/
+ if (rescnt) { resCheck(&endData, atomlist, rescnt); }
+ CtermCheck(&endData, rescnt, TRUE);
+
+ deleteResidueData(scratchRes); /* clean up any extra residue */
+
+ return atomlist;
+}
+/*}}}loadAtoms()_____________________________________________________________*/
+
+/*{{{binAtoms()***************************************************************/
+atomBins* binAtoms(atom *theAtoms, region *boundingBox, char serialNum,
+ float probeRad, int keepUnselected, int selflags)
+{
+ atom *a = NULL;
+ atomBins *bins = NULL;
+
+ bins = initBins(serialNum, boundingBox,
+ 2.0*(getMaxRadius(ImplicitH)+probeRad)+0.2);
+ if (bins) {
+ for(a = theAtoms; a; a = a->next) {
+ if (keepUnselected || (a->flags & selflags)) {
+ if (! (a->flags & IGNORE_FLAG)) {
+ addNeighbor(a, bins);
+ }
+ /*050118 this seems the only place that uses IGNORE_FLAG*/
+ }
+ }
+ }
+ /* note: addNeighbor() also called in updateHydrogenInfo() */
+ return bins;
+}
+/*}}}binAtoms()______________________________________________________________*/
+
+/*{{{getRadius()**************************************************************/
+float getRadius(int at, int useCOScale)
+{
+ float rad = 0.0, sf = RadScaleFactor;
+
+ if (useCOScale){ sf *= CORadScale; }
+
+ if (ImplicitH) { rad = getImplRad(at); }
+ else { rad = getExplRad(at); }
+
+ return (rad*sf) + RadScaleOffset;
+}
+/*}}}getRadius()_____________________________________________________________*/
+
+/*{{{newRingInfo()************************************************************/
+ringInfo * newRingInfo(ringInfo **head, point3d* ctr, point3d* norm)
+{
+ ringInfo *ri = NULL;
+ ri = (ringInfo *)malloc(sizeof(ringInfo));
+ if (ri) {
+ ri->nextRing = NULL;
+ ri->ringCenter = *ctr;
+ ri->ringNormal = *norm;
+
+ if (head) { /* if list passed, link new ring as new head */
+ ri->nextRing = *head;
+ *head = ri;
+ }
+ }
+ return ri;
+}
+/*}}}newRingInfo()___________________________________________________________*/
+
+/*{{{deleteRingInfoList()*****************************************************/
+void deleteRingInfoList(ringInfo *ri)
+{ /* kill entire list */
+ ringInfo *p = NULL, *nxt = NULL;
+ p = ri;
+ while(p) {
+ nxt = p->nextRing;
+ free(p);
+ p = nxt;
+ }
+}
+/*}}}deleteRingInfoList()____________________________________________________*/
+
+/*{{{newResidueData()*********************************************************/
+residue * newResidueData()
+{ /* new blank residue */
+ residue *r = NULL;
+ r = (residue *)malloc(sizeof(residue));
+ if (r) {
+ r->nextRes = NULL;
+ r->a = NULL;
+ r->file = 0;
+ r->model = 0;
+ r->chain[0] = ' '; /*RMI I don't know what to do here*/
+ r->resid = ' ';
+ r->resInsCode = ' ';
+ r->rescnt = 0;
+ r->segid[0] = '\0';
+
+ r->ring = NULL;
+ }
+ return r;
+}
+/*}}}newResidueData()________________________________________________________*/
+
+/*{{{resDiffersFromPrev()*****************************************************/
+int resDiffersFromPrev(residue *r1, residue *r2)
+{
+ if (r1 == NULL || r2 == NULL) { return 1; }
+ return (! IS_THE_SAME_RES(r1, r2));
+}
+/*}}}resDiffersFromPrev()____________________________________________________*/
+
+/*{{{deleteResidueData()******************************************************/
+void deleteResidueData(residue *r)
+{
+ if (r) {
+ deleteRingInfoList(r->ring);
+ free(r);
+ }
+}
+/*}}}deleteResidueData()_____________________________________________________*/
+
+/*{{{disposeListOfResidues()**************************************************/
+void disposeListOfResidues(residue *theRes)
+{
+ residue *r = NULL, *nextr = NULL;
+
+ for(r=theRes; r; r = nextr) {
+ nextr = r->nextRes;
+ deleteResidueData(r);
+ }
+}
+/*}}}disposeListOfResidues()_________________________________________________*/
+
+/*{{{dumpRes()****************************************************************/
+/* dumpRes() used for debugging */
+void dumpRes(residue *theRes)
+{
+ residue *r = NULL;
+ atom *a = NULL;
+ for(r = theRes; r; r = r->nextRes) {
+ fprintf(stderr, "RES{%s%d%c}[%d] ring(%p)\n",
+ r->resname, r->resid, r->resInsCode, r->rescnt,
+ r->ring);
+ fprintf(stderr, " ");
+ for(a = r->a; a && (a->r == r); a = a->next) {
+ fprintf(stderr, "%s ", a->atomname);
+ }
+ fprintf(stderr, "\n");
+ }
+}
+/*}}}dumpRes()_______________________________________________________________*/
+
+/*{{{deleteAtom()*************************************************************/
+void deleteAtom(atom *a)
+{
+ if (a) {
+ free(a);
+ }
+}
+/*}}}deleteAtom()____________________________________________________________*/
+
+/*{{{disposeListOfAtoms()*****************************************************/
+void disposeListOfAtoms(atom *theAtoms)
+{
+ atom *a = NULL, *nexta = NULL;
+
+ for(a=theAtoms; a; a = nexta) {
+ nexta = a->next;
+ deleteAtom(a);
+ }
+}
+/*}}}disposeListOfAtoms()____________________________________________________*/
+
+/*{{{newAtom() <--loadAtoms(),newMovingAtom(); -->various property tests *****/
+atom * newAtom(char *rec, int file, int model, residue * resDataBuf)
+{/*newAtom()*/
+ atom *a = NULL;
+ char msg[100];
+
+ a = (atom *)malloc(sizeof(atom));
+ if (a) {
+ a->r = resDataBuf;
+
+ a->next = NULL;
+ a->nextInBin= NULL;
+ a->scratch = NULL;
+ a->mark = 0; /* used to mark bonds */
+ a->flags = 0;
+ a->props = 0;
+ parseResidueName(rec, a->r->resname);
+ parseAtomName(rec, a->atomname);
+ a->r->a = a; /* residue points back to this atom (can change for res) */
+ a->r->file = file;
+ a->r->model = model;
+ parseChain(rec, a->r->chain);
+ /* a->r->chain = parseChain(rec);*/
+ a->r->resid = parseResidueNumber(rec);
+ parseResidueHy36Num(rec, a->r->Hy36resno);
+ a->r->resInsCode = parseResidueInsertionCode(rec);
+ a->r->rescnt = 0;
+ a->altConf = parseAltLocCode(rec);
+ a->binSerialNum = '?'; /* set when we bin */
+ if (strstr(":ASX:GLX:ASN:GLN:", a->r->resname) /* special case treats undecided */
+ && (a->atomname[1] == 'A')) { /* as an oxygen */
+ a->elem = identifyAtom(" O ", a->r->resname, Verbose); /*dcr041007 allow warning add resname to call */
+ sprintf(msg, "atom %s will be treated as oxygen", a->atomname);
+ warn(msg);
+ }
+ else { /* normal case */
+ a->elem = identifyAtom(a->atomname, a->r->resname, Verbose);/*dcr041007 allow warning add resname to call */
+ }
+
+ /*next section seems to be the only place where atom->bondedto is set.*/
+ /*select.c/setHydrogenParentName() and select.c/setMainchainBonding()*/
+ /* both merely call stdconntable.c/searchForStdBondingPartner() */
+ /* which constructs a search string from (a->r->resname, a->atomname) */
+ /* and calls stdconntable.c/SearchStdResConnTable() */
+ /* which returns the string found in the StdResTblBucket[] hash table.*/
+ /*This hash table is a marvelous tour de force listing of names of*/
+ /*residue/atoms and what atoms they can be bonded to */
+
+ a->bondedto = NULL;
+ if (isHatom(a->elem)) {
+ a->atomclass = -1; /* to be specified later */
+ if (UseHParent) {
+ a->bondedto = setHydrogenParentName(a->r->resname, a->atomname);
+ }
+ }
+ else {
+ a->atomclass = a->elem;
+ if (UseStdBond) {
+ a->bondedto = setMainchainBonding(a->r->resname, a->atomname);
+
+ /*setMainchainBonding() does not seem to have a distance limit*/
+ }
+ }
+
+ setProperties(a, isHet(rec), HB2aromFace, PermitCHXHB); /*select.c*/
+ /*This is where (e.g.) both HET_PROP and DNA_PROP are set for the atom*/
+ if (ByNABaseColor) { /* forces coloring by base rather than atom type */
+ a->atomclass = naBaseCategory(a);
+ }
+
+ parseXYZ(rec, &(a->loc));
+ a->ix = a->iy = a->iz = 0;
+
+ /* note: H DONOR_PROP assignment done later in updateHydrogenInfo() */
+
+ a->occ = parseOccupancy(rec);
+ a->bval = parseTempFactor(rec);
+ parseSegID(rec, a->r->segid);
+
+ a->radius = getRadius(a->elem, isCarbonylAtom(a));
+ a->covRad = getCovRad(a->elem);
+ }
+ else {
+ warn("could not allocate space for new atom");
+ }
+ return a;
+}/*newAtom()*/
+/*}}}newAtom()_______________________________________________________________*/
+
+/*{{{selectSource() <--mainProbeProc(),newMovingAtom(); -->select/matchPat() */
+void selectSource(atom *theAtoms, pattern *srcPat, int srcFlag,
+ pattern *targPat, int targFlg, pattern *ignorePat)
+{
+ atom *src = NULL;
+
+ for(src = theAtoms; src; src = src->next)
+ {
+ if( (DoHet || ! (src->props & HET_PROP) )
+ && (DoH2O || ! (src->props & WATER_PROP) ) )
+ {
+ /*060212 hets marked as prot,dna,rna could be excluded by these tests*/
+ /* if src||target was specified as not-prot,dna,rna,... */
+ /* seemingly because atoms of hets are also assigned those types */
+ if (srcPat && matchPat(src, srcPat)) { src->flags |= srcFlag; }
+ if(targPat && matchPat(src, targPat)) { src->flags |= targFlg; }
+
+ /*if ((FABS(src->occ) <= OccupancyCutoff) */
+ /* || (ignorePat && matchPat(src, ignorePat))) */
+ /*050119 not use occ cutoff here, so 0-occ atom will be put into bins*/
+ if (ignorePat && matchPat(src, ignorePat))
+ {
+ src->flags = IGNORE_FLAG; /* overwrite any other settings */
+ /*050118 this seems the only place that sets IGNORE_FLAG*/
+ }
+ }
+ }
+}
+/*}}}selectSource()__________________________________________________________*/
+
+/*{{{atomsClose()*************************************************************/
+/*atomsClose() only called from findTouchingAtoms() */
+int atomsClose(atom *a, atom *b, float probeRad)
+{
+ int nearpt = FALSE;
+ float lim = 0.0, dsq = 0.0;
+
+ lim = a->radius + b->radius + probeRad + probeRad;
+
+ dsq = v3distanceSq(&(a->loc), &(b->loc));
+
+ /* if too close they must be the same atom... */
+
+/*removing the (dsq > 0.001) test actually removes one side of a clash!!*/
+ if ((dsq > 0.001) && (dsq <= (lim*lim)))
+ {
+ nearpt = TRUE;
+ }
+ return nearpt;
+}
+/*}}}atomsClose()____________________________________________________________*/
+
+/*{{{inRange()****************************************************************/
+int inRange(point3d *p, point3d *q, float lim)
+{
+ return v3distanceSq(p, q) <= (lim*lim);
+}
+/*}}}inRange()_______________________________________________________________*/
+
+/*{{{gapSize()****************************************************************/
+float gapSize(point3d *p, point3d *q, float qrad)
+{
+ return v3distance(p, q) - qrad;
+}
+/*}}}gapSize()_______________________________________________________________*/
+
+/*{{{findTouchingAtoms()******************************************************/
+/* findTouchingAtoms() - Note: resets bond marks! Returns list of close atoms */
+/*that are in the set of bins here called abins */
+/*in the form of the first atom that is close to the src-atom where */
+/*a linked list of all close atoms is made by the scratch member of each atom*/
+/*which indicates another neighbor of the src-atom */
+
+atom* findTouchingAtoms(atom *src, atom *head, atomBins *abins,
+ float probeRad, int targFlg, int *ok)
+{/*findTouchingAtoms()*/
+ atom *a = NULL;
+ int i = 0, j = 0, k = 0, nearpt = 0, targcount = 0;
+ int jx = (src->ix), jy = (src->iy), jz = (src->iz);
+ int imin = 0, jmin = 0, kmin = 0;
+ int imax = 0, jmax = 0, kmax = 0;
+
+ if (src->binSerialNum != abins->binSerialNum)
+ {/*in foreign bins */
+ /*dcr?: why do they have to be in foreign==different bins??*/
+ /*this requirement seems not to affect loss of close clashes*/
+
+ /* must look up the positions */
+
+ if( (src->loc.x < (abins->min.x - abins->delta))
+ || (src->loc.y < (abins->min.y - abins->delta))
+ || (src->loc.z < (abins->min.z - abins->delta))
+ || (src->loc.x > (abins->max.x + abins->delta))
+ || (src->loc.y > (abins->max.y + abins->delta))
+ || (src->loc.z > (abins->max.z + abins->delta)) )
+ {
+ return NULL; /* nothing anywhere nearby */
+ }
+ binLoc(&(src->loc), &jx, &jy, &jz, abins);
+
+#ifdef DEBUG_A2B
+fprintf(stderr, "f(%c != %c) %s%d %s [%d, %d, %d] <1..%d, 1..%d, 1..%d>\n",
+ src->binSerialNum, abins->binSerialNum,
+ src->r->resname, src->r->resid, src->atomname, jx, jy, jz, abins->nx-2, abins->ny-2, abins->nz-2);
+#endif
+
+ }/*in foreign bins */
+
+ imin = jx-1; imax = jx+1; /* bin ranges */
+ jmin = jy-1; jmax = jy+1;
+ kmin = jz-1; kmax = jz+1;
+
+ /* trim any excess edges */
+ if (imin < 1) { imin = 1; }
+ if (jmin < 1) { jmin = 1; }
+ if (kmin < 1) { kmin = 1; }
+ if (imax > (abins->nx - 2)) { imax = (abins->nx - 2); }
+ if (jmax > (abins->ny - 2)) { jmax = (abins->ny - 2); }
+ if (kmax > (abins->nz - 2)) { kmax = (abins->nz - 2); }
+
+ for(i = imin; i <= imax; i++) {
+ for(j = jmin; j <= jmax; j++) {
+ for(k = kmin; k <= kmax; k++) {
+
+ for(a = abins->list[i][j][k]; a; a = a->nextInBin) {
+
+ /*Lmodeltest for interaction of diff. models 041112*/
+ /*050121 Lmodeltest superseded, mage sends model# */
+ /*...within subroutine findTouchingAtoms()... */
+ if( (src->r->model != a->r->model) ) { continue; }
+ if( modelLimit > 1 ) /*041114*/
+ {/*looping through multiple models*/
+ if(src->r->model != modelToProcess) { continue; }
+ }
+
+ /*if (( src->r == a->r) && -- alternate */
+ /* alternate */
+ if (( src->altConf != a->altConf) && /* conformations */
+ ( src->altConf != ' ') && /* don't interact */
+ ( a->altConf != ' ') ) { continue; }
+
+/*nearpt seems to be essential to get any dots or spikes */
+/*...seems not to be where too-close atoms fail to get any dots or spikes*/
+ nearpt = atomsClose(src, a, probeRad);/*only call to atomsClose*/
+ if (nearpt)
+ {/*add this atom to the linked-list of those touching src atom*/
+ a->mark = 0; /* clear the bonding marker. */
+ a->scratch = head; /* link using scratch pointers */
+ head = a; /* with <a> at head of list */
+
+ if (a->flags & targFlg) { targcount++; }
+ }
+ }
+ }
+ }
+ }
+ src->mark = 0; /* clear the src atom bonding marker. */
+
+ *ok = !(targFlg && (targcount < 1));
+
+ return head;
+}/*findTouchingAtoms*/
+/*}}}findTouchingAtoms()_____________________________________________________*/
+
+/*{{{dotClassIndex()**********************************************************/
+/* dotClassIndex() - maps dot type to class index */
+/* t == 0 --> 0,1 : contact dot */
+/* t < 0 --> 2,3 : bump */
+/* t > 0 --> 4 : hbond */
+int dotClassIndex(int t, float mingap)
+{
+ int idx = 0;
+ if (t == 0) { idx = (mingap > HighGoodCut) ? 0 : 1; } /* contact */
+ else if (t < 0) { idx = (mingap > LowGoodCut) ? 2 : 3; } /* clash */
+ else { idx = 4; } /* hbonds */
+ return idx;
+}
+/*}}}dotClassIndex()_________________________________________________________*/
+
+/*{{{saveDot() called from examineDots() and from SurfDots() *****************/
+void saveDot(atom *src, atom *targ, int type, point3d *loc, point3d *spike,
+ dotNode *results[][NODEWIDTH], int ovrlaptype, float mingap, char ptmaster)
+{/*saveDot()*/
+ /*ptmaster dcr041009*/
+ dotNode* dot = NULL;
+ int which = 0, idx = 0;
+
+ /*overlaptype: -1 bump, 0 touch, +1 H bond */
+ /*entering from SurfDots needs no further Logical filtering*/
+ /*move this decision making back up into examineDots()*/
+ /*where we now will accummulate count numbers also*/
+#ifdef OLDCODE /*041020 saveDot() decisions moved up into examineDots*/
+ if ((OutputHBs && ovrlaptype > 0)
+ || (OutputClashes && ovrlaptype < 0)
+ || (OutputVDWs && ovrlaptype == 0)) {
+#endif
+
+ idx = dotClassIndex(ovrlaptype, mingap);
+ /*0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
+ /*idx=1 for EXTERNALSURFACE ovrlaptype==0, mingap==0.0 */
+
+ dot = newDot(src, targ, loc, spike, ovrlaptype, mingap, ptmaster);
+ /*ptmaster dcr041009*/
+ if (dot)
+ {/*add new dot to head of lists arrayed by type and severity */
+ which = type;
+ dot->next = results[which][idx];
+ results[which][idx] = dot;
+ }
+#ifdef OLDCODE
+ } /* otherwise we forget about the dot */
+#endif
+}/*saveDot()*/
+/*}}}saveDot_________________________________________________________________*/
+
+/*{{{newDot()*****************************************************************/
+dotNode* newDot(atom *src, atom* targ, point3d *loc, point3d *spike,
+ int ovrlaptype, float gap, char masterchr)
+{ /*ptmaster dcr041009*/
+ dotNode* d = NULL;
+
+ d = (dotNode *)malloc(sizeof(dotNode));
+ if (d) {
+ d->next = NULL;
+ d->a = src;
+ d->t = targ;
+ d->loc = *loc;
+ d->spike = *spike;
+ d->type = ovrlaptype; /* -1 bump, 0 touch, +1 H bond */
+ d->gap = gap;
+ d->ptmaster = masterchr; /*dcr041009*/
+ }
+ else warn("could not allocate space for new dot");
+
+ return d;
+}
+/*}}}newDot()________________________________________________________________*/
+
+/*{{{INRANGEINLINE()**********************************************************/
+#define INRANGEINLINE(a, b, lim) \
+(((((a).x-(b).x)*((a).x-(b).x))+\
+ (((a).y-(b).y)*((a).y-(b).y))+\
+ (((a).z-(b).z)*((a).z-(b).z))) <= ((lim)*(lim)))
+
+ /*returns true when distance-sq between a and b <= limit-sq */
+/*}}}INRANGEINLINE()_________________________________________________________*/
+
+/*{{{examineDots()*********** called from genDotIntersect() ******************/
+void examineDots(atom *src, int type, atom *scratch,
+ pointSet dots[], float probeRad,
+ float spikelen, int targFlg, dotNode *results[][NODEWIDTH])
+{
+ /*called from genDotIntersect() with same names except scratch==atomList2 */
+
+ atom *targ = NULL, *cause = NULL;
+ int i = 0, nearpt = 0, within = 0, ok = 0, maskHB = 0;
+ int skipthisMCMC = 0, isaHB = 0, tooCloseHB = 0, ovrlaptype = 0;
+ float gap = 0.0, mingap = 0.0, sl = 0.0, hbondbumpgap = 0.0;
+ float hbcutoff = 0.0, targVDW = 0.0;
+ point3d targetloc, dotloc, dotvect, exploc, spikeloc;
+ pointSet *srcDots = NULL;
+ char ptmaster = ' '; /*pointmaster character dcr041009*/
+ int idx = 0; /*dcr041020*/
+
+ if (src->elem == ignoreAtom) { return; }
+ /*050119 but there seems no way to ever set an atom->elem = ignoreAtom !?*/
+
+ if (OccupancyCriteria && src->occ < OccupancyCutoff) /*Occ.Crit. 060831*/
+ {/*050119*/ return; }
+
+ cause = NULL; /* who is responsible for the dot */
+
+ srcDots = &(dots[src->elem]);
+
+ if (src->elem == atomC && isCarbonylAtom(src)) {
+ srcDots = &COdots;
+ }
+
+ maskHB = 0;
+ if(src->props & DONOR_PROP) {
+ maskHB = ACCEPTOR_PROP;
+ if(src->props & ACCEPTOR_PROP) { /* ambig */
+ maskHB |= DONOR_PROP;
+ }
+ }
+ else if (src->props & ACCEPTOR_PROP) {
+ maskHB = DONOR_PROP;
+ }
+
+ for(i=0; i < srcDots->n; i++)
+ {/*loop over dots on src dot-ball */
+ dotvect = srcDots->p[i];
+
+ v3add(&(src->loc), &dotvect, &dotloc);
+
+ v3scale(&dotvect, src->radius + probeRad);
+ v3add(&(src->loc), &dotvect, &exploc);
+
+ ok = FALSE;
+ mingap = 999.9;
+ isaHB = tooCloseHB = FALSE;
+ hbondbumpgap = 0.0;
+
+ /*targ is an atom*, scratch is an atom*, atom* defined in abin.h */
+ /* atom* scratch is a member of atom*: which has member scratch...*/
+ /* so for-loop moves through all these atoms while an atom has a scratch*/
+
+ for(targ = scratch; targ; targ = targ->scratch)
+ {/*for: loop over target atoms: set ok=1 for some subset*/
+ hbcutoff = Min_regular_hb_cutoff; /* redefined later on */
+
+ targetloc = targ->loc;
+ targVDW = targ->radius;
+
+#ifdef INLINE_FOR_SPEED
+ nearpt = INRANGEINLINE(exploc, targetloc, probeRad+targVDW);
+#else
+ nearpt = inRange(&exploc, &targetloc, probeRad+targVDW);
+#endif
+ /*returns true when distance-sq between a and b <= limit-sq */
+ /*...in subroutine examineDots()...*/
+
+ skipthisMCMC = 0;
+
+ /*just checking if this target atom acceptable for current src dot*/
+ /*(premature to assign pointmasters when target not yet determined*/
+ if( DoMcMc == FALSE
+ && ( src->props & MC_PROP)
+ && (targ->props & MC_PROP) )
+ {
+ /*potential MC-MC for us to skip this target atom*/
+ if (! ( ( src->props & HET_PROP)
+ || (targ->props & HET_PROP) ) )
+ {/* neither can be a HET */
+ if (strcmp(src->r->chain, targ->r->chain) == 0)
+ {/* must be the same chain*/ /*problem for NMR models ????*/
+ skipthisMCMC = 1;
+ }
+ }
+ }
+
+ /*now enter if...if else... chain of decisions...*/
+
+ if (targ->elem == ignoreAtom) {/* will not contribute */}
+
+ else if (OccupancyCriteria && targ->occ < OccupancyCutoff)
+ {/*050119 will not contribute */} /*Occ.Crit. 060831*/
+
+ else if (skipthisMCMC) {/* will not contribute */}
+
+ else if( DoWatWat == FALSE
+ && ( src->props & WATER_PROP)
+ && (targ->props & WATER_PROP))
+ {
+ ; /* water will not contribute when not being considered*/
+ }
+
+/*Lautobondrot 050111 investigation point */
+
+ else if (nearpt && (targ->mark == 0))
+ {/*else if: close but nonbonded*/
+ gap = gapSize(&dotloc, &targetloc, targVDW);
+
+ /*identify target with minimum gap*/
+
+ if (gap < mingap)
+ {/*if: gap < mingap*/
+
+ int bothCharged = FALSE;
+ int chargeComplement = FALSE;
+
+ if( ( src->props & (NEGATIVE_PROP|POSITIVE_PROP))
+ &&(targ->props & (NEGATIVE_PROP|POSITIVE_PROP)) )
+ {
+ bothCharged = TRUE;
+ chargeComplement =
+ ( ( ( src->props & POSITIVE_PROP)
+ && (targ->props & NEGATIVE_PROP))
+ || ( ( src->props & NEGATIVE_PROP)
+ && (targ->props & POSITIVE_PROP)) );
+ }
+
+ if( (targ->props & maskHB)
+ && ( (! bothCharged) || chargeComplement) )
+ {
+ hbcutoff = bothCharged ?
+ Min_charged_hb_cutoff :
+ Min_regular_hb_cutoff;
+
+ if (gap < -hbcutoff)
+ {
+ tooCloseHB = TRUE; /* treat like a bump */
+ hbondbumpgap = gap;
+ isaHB = TRUE;
+ }
+ else
+ { /* hbond or contact */
+ isaHB = TRUE;
+ tooCloseHB = FALSE;
+ }
+ }
+ else
+ { /* clash or contact */
+ /*NOTE: atomHOd : hb-only-dummy, phantom H atom*/
+ if (src->elem == atomHOd) { continue; } /*with for: loop*/
+ if (targ->elem == atomHOd) { continue; } /*with for: loop*/
+ isaHB = FALSE;
+ }
+ mingap = gap; /* update minimum gap */
+ ok = TRUE;
+ cause = targ;
+ }/*if: gap < mingap*/
+ }/*else if: close but nonbonded*/
+ }/*for: loop over target atoms: set ok=1 for some subset*/
+ if (ok && !(cause->flags & targFlg)) { /* drop non-target atom dot */
+ ok = FALSE;
+ }
+ if (ok)
+ {/*ok: apply bonded atom dot filters */
+
+ /*targ is an atom*, scratch is an atom*, atom* defined in abin.h */
+ /* atom* scratch is a member of atom*: which has member scratch...*/
+ /* so for-loop moves through all these atoms while an atom has a scratch*/
+
+ for(targ = scratch; targ; targ = targ->scratch)
+ {/*for: scan over target atoms*/
+ /* eliminate dot if within bonded atom! */
+ if (targ->mark && (targ->elem != atomHOd))
+ { /*NOTE: atomHOd : hb-only-dummy, phantom H atom*/
+#ifdef INLINE_FOR_SPEED
+ within = INRANGEINLINE(dotloc, (targ->loc), targ->radius);
+#else
+ within = inRange(&dotloc, &(targ->loc), targ->radius);
+#endif
+ /*returns true when distance-sq between a and b <= limit-sq */
+ /*...in subroutine examineDots()...*/
+
+ if (within) { ok = FALSE; break; }
+ }
+ else if ((src->elem == atomHOd) && !(targ->props & ACCEPTOR_PROP))
+ { /*NOTE: atomHOd : hb-only-dummy, phantom H atom*/
+ /* eliminate if H? within non-Acceptor atom! */
+#ifdef INLINE_FOR_SPEED
+ within = INRANGEINLINE(dotloc, (targ->loc), targ->radius);
+#else
+ within = inRange(&dotloc, &(targ->loc), targ->radius);
+#endif
+ /*returns true when distance-sq between a and b <= limit-sq */
+ /*...in subroutine examineDots()...*/
+
+ if (within) { ok = FALSE; break; }
+ }
+ }/*for: scan over target atoms*/
+ }/*ok: apply bonded atom dot filters */
+ if (ok)
+ {/*dot is ok, atom that this dot hits is called cause */ /* Contact */
+ /* ovrlaptype : -1 bump, 0 touch, +1 H bond */
+ /*dcr?: mingap seems to do what ???? 050111*/
+ if (mingap > 0.0)
+ {
+ sl = 0.0;
+ ovrlaptype = 0;
+ }
+ else if (isaHB && tooCloseHB)
+ {
+ mingap = hbondbumpgap + hbcutoff;
+ sl = spikelen*mingap;
+ ovrlaptype =-1; /* Hbond which is too close is a clash */
+ }
+ else if (isaHB) /* Hbond */
+ {
+ sl = spikelen*mingap;
+ ovrlaptype =+1;
+
+ /* must test angle for Hbond in some cases */
+ if ( src->props & TEST_ACCEPT_ANGLE_PROP)
+ {
+ /* cause->loc vs src->aromaticRing; ovrlaptype =-1;?? */
+ }
+ else if ( cause->props & TEST_ACCEPT_ANGLE_PROP)
+ {
+ /* src->loc vs cause->aromaticRing; ovrlaptype =-1;?? */
+ }
+
+ if( src->props & CH_DONOR_PROP
+ || cause->props & CH_DONOR_PROP)
+ {/* CH..O type Hbond */
+ sl *= CHOHBfactor; /*down scale score for these types of Hbonds*/
+ }
+
+#ifdef JACKnANDREA
+ if (writeHbonds)
+ printf("{%s %s %2s %d}P %f %f %f {%s %s %2s %d} %f %f %f\n",
+ src->atomname, src->r->resname, src->r->chain, src->r->resid, src->loc.x, src->loc.y, src->loc.z,
+ cause->atomname, cause->r->resname, cause->r->chain, cause->r->resid, cause->loc.x, cause->loc.y, cause->loc.z);
+/*this makes a monster list of all possible H-bond dots as heavy-atom--H vecs*/
+/*which must then be pared down to the unique atom-pair vectors*/
+/*also includes all the atomOHd dummy phantoms which junks up the display*/
+#endif
+
+ }
+ else /* Clash */
+ {
+ sl = spikelen*mingap;
+ ovrlaptype =-1;
+ }
+
+ /*NOTE: atomHOd : hb-only-dummy, phantom H atom*/
+ /* ovrlaptype : -1 bump, 0 touch, +1 H bond */
+ if( (ovrlaptype == 1)
+ ||(src->elem != atomHOd && cause->elem != atomHOd) )
+ {
+ v3scale(&dotvect, src->radius + sl);
+ v3add(&(src->loc), &dotvect, &spikeloc);
+
+ /* possibly limit contact dots... */
+ /* ovrlaptype : -1 bump, 0 touch, +1 H bond */
+
+ /*kissEdge2bullsEye seems not responsible for loss of very close clashes*/
+ if ( ovrlaptype != 0
+ || LimitDots == FALSE
+ || dot2srcCenter(&dotloc, src, cause) <=
+ kissEdge2bullsEye(src->radius, cause->radius, probeRad))
+ {/*could use this dot/spike, */
+ /*saveDot decisions moved here to examineDots 041020 */
+ /*overlaptype: -1 bump, 0 touch, +1 H bond */
+ idx = dotClassIndex(ovrlaptype, mingap);
+/*idx: 0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
+ /*OnlyBadOut option dcr041010*/
+
+ /* ovrlaptype : -1 bump, 0 touch, +1 H bond */
+ if( (!OnlyBadOut && OutputHBs && ovrlaptype > 0)
+ ||(!OnlyBadOut && OutputClashes && ovrlaptype < 0)
+ ||( OnlyBadOut && OutputClashes && idx==3)/*Bad Clash dcr041020*/
+ ||(!OnlyBadOut && OutputVDWs && ovrlaptype == 0))
+ { /*logicals allow the overlaptype of this dot*/
+
+ /*now derive ptmaster*/
+ if( (src->props & MC_PROP) && (cause->props & MC_PROP) )
+ {/*potential MC-MC to flag*/
+ if( !(( src->props & HET_PROP) || (cause->props & HET_PROP)) )
+ {/*neither can be a HET, what wierd condition is avoided?*/
+ ptmaster = 'M'; /*McMc interaction*/
+ mcmccont[0][idx]++;
+ mcmccont[0][5]++;
+ }
+ }
+ else if( (src->props & SC_PROP) && (cause->props & SC_PROP) )
+ {/*potential SC-SC to flag*/
+ if( !(( src->props & HET_PROP) || (cause->props & HET_PROP)) )
+ {/*neither can be a HET, what wierd condition is avoided?*/
+ ptmaster = 'S'; /*ScSc interaction*/
+ scsccont[0][idx]++;
+ scsccont[0][5]++;
+ }
+ }
+ else if( ((src->props & SC_PROP) && (cause->props & MC_PROP))
+ ||((src->props & MC_PROP) && (cause->props & SC_PROP)))
+ {/*potential MC-SC or SC-MC to flag*/
+ if( !(( src->props & HET_PROP) || (cause->props & HET_PROP)) )
+ {/*neither can be a HET, what wierd condition is avoided?*/
+ ptmaster = 'P'; /*McSc or ScMc interaction*/
+ mcsccont[0][idx]++;
+ mcsccont[0][5]++;
+ }
+ }
+ else
+ {
+ ptmaster = 'O'; /*Oh for Other, general default*/
+ othrcont[0][idx]++;
+ othrcont[0][5]++;
+ }
+
+ saveDot(src, cause, type, &dotloc, &spikeloc,
+ results, ovrlaptype, mingap, ptmaster); /* dcr041009 */
+ }/*logicals allow the overlaptype of this dot*/
+ }/*could use this dot/spike, */
+ }
+ }/*dot is ok, atom that this dot hits is called cause */
+ }/*loop over dots on src dot-ball */
+}/*examineDots()*/
+/*}}}examineDots()___________________________________________________________*/
+
+/*{{{markBonds()**************************************************************/
+/*markBonds() decides which atoms are bonded to each other and thus */
+/*decides under what conditions close atoms will NOT be considered to clash*/
+/*this seems to be the only subroutine that uses atom->bondedto information*/
+/*for a given src atom: mark all atoms that are close enough to bond and are */
+/*allowed to bond and extend this to thier neighbors through Maxbonded bonds*/
+/*including marking the src atom itself if such a Maxbonded-loop returns to it*/
+
+void markBonds(atom *src, atom *neighbors, int distcount, int max)
+{/*markBonds reformated 041112*/
+ atom *targ = NULL, *theHatom = NULL, *theOtherAtom = NULL;
+ int nearpt, tooclose, isAanH, isBanH, letItBond = FALSE;
+
+ /*when making surface dots, max==1 */
+ /*when looking for contacts and clashes, max==Maxbonded */
+
+ for(targ = neighbors; targ; targ = targ->scratch)
+ {/*for(loop over neighbors)*/
+
+ /*first pass look at neighbors of external calling atom: targ->mark == 0*/
+ /*later look at neighbors of neighbors: targ->mark > max */
+ /* until Maxbonded neighbor when targ->mark == max */
+
+ if (targ->mark == 0 || targ->mark > distcount)
+ {/*if(targ->mark == 0 || targ->mark > distcount) */
+
+ /* note: when we are relying on the StdBond table */
+ /* to figure out which bonds are allowed */
+ /* we can be more generous with the distance */
+ /* cuttofs to permit more oddball distortions */
+ /*dcr: so it seems that with UseStdBond 2*COVRADFUDGE is added */
+ /*atomprops.h/defines COVRADFUDGE 0.2 050111 */
+
+#ifdef INLINE_FOR_SPEED
+ nearpt = INRANGEINLINE((src->loc), (targ->loc),
+ src->covRad + targ->covRad + COVRADFUDGE
+ + (UseStdBond ? COVRADFUDGE : 0.0) );
+
+ tooclose = INRANGEINLINE((src->loc), (targ->loc),
+ src->covRad + targ->covRad - 0.6
+ - (UseStdBond ? COVRADFUDGE : 0.0) );
+#else
+ nearpt = inRange(&(src->loc), &(targ->loc),
+ src->covRad + targ->covRad + COVRADFUDGE
+ + (UseStdBond ? COVRADFUDGE : 0.0) );
+
+ tooclose = inRange(&(src->loc), &(targ->loc),
+ src->covRad + targ->covRad - 0.6
+ - (UseStdBond ? COVRADFUDGE : 0.0) );
+#endif
+ /*returns true when distance-sq between a and b <= limit-sq */
+
+/*050111 tooclose= does NOT seem to be the call where */
+/*atoms that move too close together suddenly stop showing bad clashes ! */
+/*i.e. force tooclose = 0 here does not affect very close clash cut-off*/
+/* and indeed atoms not bonded because of tooclose should show clashes !? */
+/*but actual close distance of cut-off seems to be dependent on UseStdBond */
+/*so since this is the only place where COVRADFUDGE is used, one suspects */
+/*that this markBonds() is responsible for showing as bonded those atoms */
+/*that fail to show clashes as they get near to each other*/
+/*However, although this markBonds seems to check each atom pair many times, */
+/*it does look as if it declares the letItBond flag correctly even when close!*/
+/*050111 BUT this seems where all bonding info is calc, so maybe letItBond is */
+/*not interpreted correctly by this analysis...*/
+/*050117 specific case of ala_dipeptide at phi==0,psi==0, tau<= 102.25 seems */
+/*the N of res 2 is just within bonding criteria of C of res 0 and with*/
+/*UseStdBond N -- C bonds are allowed between atoms of different residues*/
+/*thus the covalent neighbors of that N and that C, e.g. NH of 2 and O of 0 */
+/*are also considered to NOT clash! */
+/*For autobondrot and mage/probe strict succession would cure this...*/
+/*BUT one does need to allow for deletions in residue order!*/
+/*SO this is a FEATURE, NOT a BUG */
+/*and the work-around is to restrict the tau deviation to what is more */
+/*reasonable for tau anyway of -8, thus -5 to +10 around ideal 111.1 */
+/*might be the best range for getting a feel for allowable phi,psi regions*/
+
+ /* conditions for allowing a bond to be formed... */
+
+ if (nearpt && (! tooclose) )
+ {/*close enough for a bond*/
+ isAanH = isHatom(src->elem);
+ isBanH = isHatom(targ->elem);
+
+#ifdef OLD_BONDING_CALC
+ if( ( ! isAanH && ! isBanH ) /* neither atom is a hydrogen */
+ ||( (! isAanH || ! isBanH) /*or one is an H */
+ && ATOMS_IN_THE_SAME_RES(src, targ) /* and both are in same*/
+ /* res with parent name*/
+ &&( (theHatom->bondedto == NULL) /*and either unknown */
+ or as expected*/
+ || strstr(theHatom->bondedto, theOtherAtom->atomname)
+ ) ) )
+ {
+ targ->mark = distcount;
+ if (distcount < max) {
+ markBonds(targ, neighbors, distcount+1, max);
+ }
+ }
+#else /*NOT OLD_BONDING_CALC*/
+ letItBond = FALSE; /* we start out skeptical */
+ if ((! isAanH) && (! isBanH))
+ {/* neither atom is a hydrogen - both are heavy atoms */
+
+ if (UseStdBond)
+ {/* if we are allowing only "standard" bonding */
+
+ if (! ATOMS_IN_THE_SAME_RES(src, targ))
+ { /* and are in diff res */
+
+ if ((src->props & MC_PROP) && (targ->props & MC_PROP))
+ {/* both are mc in diff res - */
+ /*only specific bonding patterns allowed */
+
+ /*strcmp(a,b) returns 0 when strings == (a==b) */
+ /*strstr returns 1 when any str in colon delineated*/
+ /* list matches reference str */
+
+ letItBond =
+ ( !strcmp(" N ", src->atomname)
+ && !strcmp(" C ",targ->atomname) )
+ || ( !strcmp(" N ",targ->atomname)
+ && !strcmp(" C ", src->atomname) )
+ || ( !strcmp(" P ", src->atomname)
+ && strstr(" O3*: O3'", targ->atomname) )
+ || ( !strcmp(" P ",targ->atomname)
+ && strstr(" O3*: O3'", src->atomname) );
+ }
+ else if( !(src->props & MC_PROP)
+ && !(targ->props & MC_PROP) )
+ {
+ /* both are sc in diff res they must be CYS-CYS SS */
+ letItBond = ( !strcmp(src->r->resname, "CYS")
+ && !strcmp(src->atomname, " SG ")
+ && !strcmp(targ->r->resname, "CYS")
+ && !strcmp(targ->atomname, " SG ") );
+ }
+
+ /*050121 remove dcr041112 code insertion */
+ /*inserted test to allow mage/probe fitting of a*/
+ /*particular sidechain in context of an NMR ensemble*/
+ /*Lmodeltest not needed, mage sends model # when needed*/
+
+ }/* and are in diff res */
+ else
+ {/* both heavy atoms in same res */
+ /*strstr returns 1 when any str in colon delineated*/
+ /* list matches reference str */
+#ifdef STRICT_CONN_TABLE /*050111 seems to be not defined*/
+ /* strict - heavy atom must be as exactly expected */
+ letItBond = ( (src->bondedto != NULL)
+ && strstr(src->bondedto, targ->atomname) );
+#else /*NOT STRICT_CONN_TABLE*/
+ /* heavy atom either unknown or as expected */
+ letItBond = ( (src->bondedto == NULL)
+ || strstr(src->bondedto, targ->atomname) );
+#endif /*def? STRICT_CONN_TABLE*/
+ }
+ }/* if we are allowing only "standard" bonding */
+ else
+ {/* not using std bond table - */
+ /*so we let heavy atoms bond when they are close enough */
+ letItBond = TRUE;
+ }
+ }/* neither atom is a hydrogen - both are heavy atoms */
+ else if( (! isAanH || ! isBanH) /* only one atom is a hydrogen */
+ && ATOMS_IN_THE_SAME_RES(src, targ) ) /* and both atoms*/
+ /* are in the same res*/
+ {
+ if (isAanH) { theHatom = src; theOtherAtom = targ; }
+ else { theHatom = targ; theOtherAtom = src; }
+
+ if( (theHatom->bondedto == NULL) /* heavy atom either unknown*/
+ /* or as expected */
+ || strstr(theHatom->bondedto, theOtherAtom->atomname)
+ || (UseHParent == FALSE) )
+ {
+ letItBond = TRUE;
+ }
+ }
+ else
+ {/*either both are hydrogens in the same residue- no bond possible*/
+ /* or one is a H and they are in diff res - no bond possible */
+ letItBond = FALSE;
+ }
+
+ if (letItBond) /*check connectivity through Maxbonded neighbors*/
+ {
+ targ->mark = distcount; /*initially == 1 as called externally*/
+ if (distcount < max) /*max == Maxbonded as input or defaulted*/
+ {/*reentrant: no clashes between atoms within Maxbonded bonds*/
+ markBonds(targ, neighbors, distcount+1, max);
+ }
+ /*else targ->mark == max > discount and loop will end*/
+#ifdef DUMP_DEBUG_EXTRA
+ if (DebugLevel > 7)
+ {
+ fprintf(stdout, "{%4.4s%c%3.3s%2s%4.4s%c}P %8.3f%8.3f%8.3f\n",
+ src->atomname, src->altConf,
+ src->r->resname, src->r->chain,
+ src->r->Hy36resno, src->r->resInsCode,
+ src->loc.x, src->loc.y, src->loc.z);
+ fprintf(stdout, "{%4.4s%c%3.3s%2s%4.4s%c}L %8.3f%8.3f%8.3f\n",
+ targ->atomname, targ->altConf,
+ targ->r->resname, targ->r->chain,
+ targ->r->Hy36resno, targ->r->resInsCode,
+ targ->loc.x, targ->loc.y, targ->loc.z);
+ }
+#endif /*DUMP_DEBUG_EXTRA*/
+ }
+#endif /*def? OLD_BONDING_CALC not defined as of 050111*/
+ }/*close enough for a bond*/
+ }/*if(targ->mark == 0 || targ->mark > distcount) */
+
+ }/*for(loop over neighbors)*/
+}/*markBonds*/
+/*}}}markBonds()_____________________________________________________________*/
+
+/*{{{fixupLongBondChains()****************************************************/
+/* fixupLongBondChains() - unmark and remove from the bonded set */
+/* atoms which are more than cutoff bonds */
+/* from the source when neither src or targ */
+/* is a hydrogen */
+void fixupLongBondChains(atom *src, atom *neighbors, int cutoff)
+{
+ atom *targ = NULL;
+
+ if (! isHatom(src->elem)) {
+ for(targ = neighbors; targ; targ = targ->scratch) {
+ if (targ->mark > cutoff && ! isHatom(targ->elem)) {
+ targ->mark = 0;
+ }
+ }
+ }
+}
+/*}}}fixupLongBondChains()___________________________________________________*/
+
+/*{{{dotType()****************************************************************/
+int dotType(atom *src, atom *atomList, int recalcOnly)
+{
+ atom *a = NULL;
+ int rslt = src->atomclass;
+
+ /* When ByNABaseColor is TRUE, the atomclass is not the real element type */
+ /* but instead is the nucleic acid base type. In this case, the times we */
+ /* need the actual element (or parent element for hydrogens) recalcOnly is*/
+ /* TRUE, we determine the element & do not molest the atomclass assignment*/
+
+ if (src->atomclass < 0 || recalcOnly) {
+ rslt = src->elem;
+
+ if (isHatom(src->elem)) {
+ for(a = atomList; a; a = a->scratch) {
+ if (a->mark == 1 && ! isHatom(a->elem)
+ && src->r == a->r) {
+ rslt = a->elem; break;
+ }
+ }
+ }
+ if (!recalcOnly) { /* usually reassign atomclass, but not for recalc */
+ src->atomclass = rslt;
+ }
+ }
+
+ return rslt;
+}
+/*}}}dotType()_______________________________________________________________*/
+
+/*{{{debugBondingLists()******************************************************/
+void debugBondingLists(atom *src, atom *neighbors)
+{
+ atom *targ = NULL;
+ int i = 0;
+
+ fprintf(stdout, "%4.4s%c%3.3s%2s%4.4s%c(%c%d)",
+ src->atomname, src->altConf,
+ src->r->resname, src->r->chain,
+ src->r->Hy36resno, src->r->resInsCode,
+ src->binSerialNum, src->mark);
+ for(targ = neighbors; targ; targ = targ->scratch) {
+ fprintf(stdout, ", %d: %4.4s%c%3.3s%2s%4.4s%c(%c%d)", ++i,
+ targ->atomname, targ->altConf,
+ targ->r->resname, targ->r->chain,
+ targ->r->Hy36resno, targ->r->resInsCode,
+ targ->binSerialNum, targ->mark);
+ }
+ fprintf(stdout, "\n");
+}
+/*}}}debugBondingLists()_____________________________________________________*/
+
+/*{{{genDotIntersect()*** called from doCommand() *** calls examineDots() ****/
+/*genDotIntersect() called from doCommand during processing of modes: */
+/*once with srcFlag==1, targFlag==2 in modes SELFINTERSECT,INTERSECTONCE, */
+/*and twice from INTERSECTBOTHWAYS first with srcFlag,targFlag == 1,2 then 2,1*/
+/*autobondrot static atoms are allMainAtoms with abin bins*/
+/* mobile atoms are allMovingAtoms with bbins bins*/
+
+/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
+/* sets of atoms (none in common) or allMovingAtoms/bbins can */
+/* be NULL. */
+/* allMovingAtoms refers to autobondrot set of atoms */
+
+void genDotIntersect(atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[],
+ float probeRad, float spikelen,
+ int srcFlag, int targFlg, dotNode *results[][NODEWIDTH])
+{/*genDotIntersect()*/
+ atom *src = NULL, *atomList = NULL, *atomList2 = NULL;
+ int type = 0, usesMovingAtoms = FALSE;
+ int oktargsA = TRUE, oktargsB = TRUE;
+
+ usesMovingAtoms = ((allMovingAtoms != NULL) && (bbins != NULL));
+
+ for(src = allMainAtoms; src; src = src->next) /*main==autobondrotstatic*/
+ {/*for: loop over all main atoms taking each in turn as the src-atom*/
+
+ if (src->flags & srcFlag) /*dcr?: seems srcFlag always either 1 or 2 ??*/
+ {/*for each src atom*/
+
+ oktargsA = TRUE; oktargsB = TRUE;
+ atomList = findTouchingAtoms(src, NULL, abins, probeRad, targFlg, &oktargsA);
+ if (usesMovingAtoms) /*autobondrot*/
+ {
+ atomList2 = findTouchingAtoms(src, atomList, bbins, probeRad, targFlg, &oktargsB);
+ }
+ else { atomList2 = atomList; }
+ if (atomList2 && (oktargsA || (usesMovingAtoms && oktargsB) ))
+ {
+ markBonds(src, atomList2, 1, Maxbonded); /*in genDotIntersect()*/
+ /*markBonds identifies bonds between atoms - */
+ /*seems not to have lower distance limit*/
+ /*but this is where autobondrot fails to spike very close atoms*/
+
+ if (Maxbonded > 3) fixupLongBondChains(src, atomList2, 3);
+
+ type = dotType(src, atomList2, FALSE);
+
+ examineDots(src, type, atomList2, dots,
+ probeRad, spikelen, targFlg, results);
+
+ if(Verbose && ShowTicks)
+ {
+ fprintf(stderr, "%s%d \r",
+ src->r->resname, src->r->resid);
+ }
+ }
+ }/*for each src atom*/
+ }/*for: loop over all static atoms taking each in turn as the src-atom*/
+
+ if(usesMovingAtoms)
+ {/*if: usesMovingAtoms==autobondrot*/
+
+ for(src = allMovingAtoms; src; src = src->next)
+ {/*for: loop over allMovingAtoms taking each in turn as the src-atom*/
+
+ if (src->flags & srcFlag) /*dcr?: what is being flagged here??*/
+ {
+
+ oktargsA = TRUE;
+ oktargsB = TRUE;
+ atomList = findTouchingAtoms(src, NULL, abins, probeRad, targFlg, &oktargsA);
+ atomList2 = findTouchingAtoms(src, atomList, bbins, probeRad, targFlg, &oktargsB);
+ if (atomList2 && (oktargsA || oktargsB))
+ {
+ markBonds(src, atomList2, 1, Maxbonded);
+ /*markBonds identifies bonds between atoms - */
+ /*seems not to have lower distance limit*/
+ /*but is where autobondrot fails to spike very close atoms*/
+
+ if (Maxbonded > 3) fixupLongBondChains(src, atomList2, 3);
+
+ type = dotType(src, atomList2, FALSE);
+
+ examineDots(src, type, atomList2, dots,
+ probeRad, spikelen, targFlg, results);
+
+ if(Verbose && ShowTicks)
+ {
+ fprintf(stderr, "%s%d \r",
+ src->r->resname, src->r->resid);
+ }
+ }
+ }
+ }/*for: loop over allMovingAtoms taking each in turn as the src-atom*/
+ }/*if: usesMovingAtoms==autobondrot*/
+}/*genDotIntersect()*/
+/*}}}genDotIntersect()_______________________________________________________*/
+
+/*{{{genDotSurface() only called when method == EXTERNALSURFACE **************/
+
+/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
+/* sets of atoms (none in common) or allMovingAtoms/bbins can */
+/* be NULL. */
+/* allMovingAtoms refers to autobondrot set of atoms */
+
+void genDotSurface(atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[],
+ float probeRad, float spikelen, int srcFlag,
+ dotNode *results[][NODEWIDTH])
+{
+ atom *src = NULL, *atomList = NULL, *atomList2 = NULL;
+ int type = 0, usesMovingAtoms = FALSE;
+ int dummy = TRUE;
+
+ usesMovingAtoms = ((allMovingAtoms != NULL) && (bbins != NULL));
+
+ for(src = allMainAtoms; src; src = src->next) {
+ if (src->flags & srcFlag) {
+
+ atomList = findTouchingAtoms(src, NULL, abins, probeRad, 0, &dummy);
+ if (usesMovingAtoms) {
+ atomList2 = findTouchingAtoms(src, atomList, bbins, probeRad, 0, &dummy);
+ }
+ else { atomList2 = atomList; }
+
+ if (atomList2) {
+ markBonds(src, atomList2, 1, 1); /*in genDotSurface()*/
+ }
+
+ type = dotType(src, atomList2, FALSE);
+
+ surfDots(src, type, atomList2, dots,
+ probeRad, spikelen, results);
+
+ if(Verbose && ShowTicks) {
+ fprintf(stderr, "%s%d \r",
+ src->r->resname, src->r->resid);
+ }
+ }
+ }
+
+ if (usesMovingAtoms) {
+ for(src = allMovingAtoms; src; src = src->next) {
+ if (src->flags & srcFlag) {
+
+ atomList = findTouchingAtoms(src, NULL, abins, probeRad, 0, &dummy);
+ atomList2 = findTouchingAtoms(src, atomList, bbins, probeRad, 0, &dummy);
+ if (atomList2) {
+ markBonds(src, atomList2, 1, 1); /*in genDotSurface()*/
+ }
+
+ type = dotType(src, atomList2, FALSE);
+
+ surfDots(src, type, atomList2, dots,
+ probeRad, spikelen, results);
+
+ if(Verbose && ShowTicks) {
+ fprintf(stderr, "%s%d \r",
+ src->r->resname, src->r->resid);
+ }
+ }
+ }
+ }
+}
+/*}}}genDotIntersect()_______________________________________________________*/
+
+/*{{{surfDots() only called from genDotSurface(), method == EXTERNALSURFACE **/
+void surfDots(atom *src, int type, atom *scratch, pointSet dots[],
+ float probeRad, float spikelen, dotNode *results[][NODEWIDTH])
+{
+ atom *targ;
+ int i, nearpt, ok;
+ point3d dotloc, dotvect, exploc, spikeloc;
+ pointSet *srcDots;
+ char ptmaster = ' '; /*pointmaster character dcr041009*/
+
+ if (src->elem == ignoreAtom) { return; }
+
+ srcDots = &(dots[src->elem]);
+ if (src->elem == atomC && isCarbonylAtom(src)) {
+ srcDots = &COdots;
+#ifdef DUMP_DEBUG_EXTRA
+ if (DebugLevel>8) {
+ fprintf(stdout, "DEBUG surfDots(%s%d %s radius = %.3f)\n",
+ src->r->resname,src->r->resid,src->atomname,src->radius);
+ }
+#endif
+ }
+
+ for(i=0; i < srcDots->n; i++) {
+ dotvect = srcDots->p[i];
+
+ v3add(&(src->loc), &dotvect, &dotloc);
+
+ v3scale(&dotvect, src->radius + probeRad);
+ v3add(&(src->loc), &dotvect, &exploc);
+
+ v3scale(&dotvect, src->radius + 0.0);
+ v3add(&(src->loc), &dotvect, &spikeloc);
+
+ ok = TRUE;
+
+ /*targ is an atom*, scratch is an atom*, atom* defined in abin.h */
+ /* atom* scratch is a member of atom*: which has member scratch...*/
+ /* so for-loop moves through all these atoms while an atom has a scratch*/
+
+ for(targ = scratch; targ; targ = targ->scratch) {
+ if ( (targ->elem == ignoreAtom)
+ || ((!DoWatWat) && (src->props & WATER_PROP)
+ && (targ->props & WATER_PROP)
+ && (src->r != targ->r)) /* we do see HOH hydrogens */
+ || ((!DoHet) && (targ->props & HET_PROP))
+ || ((!DoH2O) && (targ->props & WATER_PROP)) ) {
+ /* ignore */
+ }
+ else {
+#ifdef INLINE_FOR_SPEED
+ nearpt = INRANGEINLINE(exploc, (targ->loc),
+ probeRad+targ->radius);
+#else
+ nearpt = inRange(&exploc, &(targ->loc),
+ probeRad+targ->radius);
+#endif
+
+ if (nearpt) { ok = FALSE; break; }
+ }
+ }
+ if (ok) {
+ saveDot(src, NULL, type, &dotloc, &spikeloc, results, 0, 0.0,ptmaster);
+ /*ptmaster not used to distinguish anykind of surface dots dcr041009*/
+ /*Note: here only when method == EXTERNALSURFACE */
+ /*and ovrlaptype==0, mingap==0.0, ptmaster==' ' */
+ }
+ }
+}/*surfDots()*/
+/*}}}genDotIntersect()_______________________________________________________*/
+
+/*{{{initResults()************************************************************/
+void initResults(dotNode *results[][NODEWIDTH])
+{
+ int i, j;
+
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ for (j = 0; j < NODEWIDTH; j++) {
+ results[i][j] = NULL;
+ }
+ }
+}
+/*}}}initResults()___________________________________________________________*/
+
+/*{{{freeResults()************************************************************/
+void freeResults(dotNode *results[][NODEWIDTH])
+{
+ int i, j;
+ dotNode *node, *next;
+
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ for (j = 0; j < NODEWIDTH; j++) {
+ for (node = results[i][j]; node; node = next) {
+ next = node->next;
+ free(node);
+ }
+ results[i][j] = NULL;
+ }
+ }
+}
+/*}}}freeResults()___________________________________________________________*/
+
+/*{{{assignGapColorForKin()***************************************************/
+char* assignGapColorForKin(float gap, int class)
+{
+ char *colorValue = "";
+ if (class == 4) { colorValue = "greentint "; } /* hbond */
+ else if (gap > 0.35){ colorValue = "blue "; }
+ else if (gap > 0.25){ colorValue = "sky "; }
+ else if (gap > 0.15){ colorValue = "sea "; }
+ else if (gap > 0.0) { colorValue = "green "; }
+ else if (gap >-0.1) { colorValue = "yellowtint ";}
+ else if (gap >-0.2) { colorValue = "yellow "; }
+ else if (gap >-0.3) { colorValue = "orange "; }
+ else if (gap >-0.4) { colorValue = "red "; }
+ else { colorValue = "hotpink "; }
+ return colorValue;
+}
+/*}}}assignGapColorForKin()__________________________________________________*/
+
+/*{{{assignGapColorForO()*****************************************************/
+char* assignGapColorForO(float gap, int class)
+{
+ char *colorValue = "";
+ if (class == 4) { colorValue = "pale_green "; } /* hbond */
+ else if (gap > 0.35){ colorValue = "cornflower_blue "; }
+ else if (gap > 0.25){ colorValue = "sky_blue "; }
+ else if (gap > 0.15){ colorValue = "aquamarine "; }
+ else if (gap > 0.0) { colorValue = "green "; }
+ else if (gap >-0.1) { colorValue = "yellow_green "; }
+ else if (gap >-0.2) { colorValue = "yellow "; }
+ else if (gap >-0.3) { colorValue = "orange "; }
+ else if (gap >-0.4) { colorValue = "red "; }
+ else { colorValue = "orange_red "; }
+ return colorValue;
+}
+/*}}}assignGapColorForO()____________________________________________________*/
+
+/*{{{assignGapColorForXV()****************************************************/
+char* assignGapColorForXV(float gap, int class)
+{
+ return assignGapColorForKin(gap, class);
+}
+/*}}}assignGapColorForXV()___________________________________________________*/
+
+/*{{{convertKinColorToO()*****************************************************/
+char* convertKinColorToO(char* incolor)
+{
+ char *outcolor = "light_gray";
+ if (strcmp(incolor, "red" ) == 0) { outcolor = "red"; }
+ else if (strcmp(incolor, "green" ) == 0) { outcolor = "green"; }
+ else if (strcmp(incolor, "blue" ) == 0) { outcolor = "cornflower_blue"; }
+ else if (strcmp(incolor, "cyan" ) == 0) { outcolor = "cyan"; }
+ else if (strcmp(incolor, "yellow" ) == 0) { outcolor = "yellow"; }
+ else if (strcmp(incolor, "magenta" ) == 0) { outcolor = "magenta"; }
+ else if (strcmp(incolor, "white" ) == 0) { outcolor = "white"; }
+ else if (strcmp(incolor, "pink" ) == 0) { outcolor = "salmon"; }
+ else if (strcmp(incolor, "orange" ) == 0) { outcolor = "orange"; }
+ else if (strcmp(incolor, "purple" ) == 0) { outcolor = "purple"; }
+ else if (strcmp(incolor, "sky" ) == 0) { outcolor = "sky_blue"; }
+ else if (strcmp(incolor, "brown" ) == 0) { outcolor = "brown"; }
+ else if (strcmp(incolor, "gray" ) == 0) { outcolor = "light_gray"; }
+ else if (strcmp(incolor, "black" ) == 0) { outcolor = "black"; }
+ else if (strcmp(incolor, "gold" ) == 0) { outcolor = "gold"; }
+ else if (strcmp(incolor, "yellowtint") == 0) { outcolor = "yellow_green"; }
+ else if (strcmp(incolor, "sea" ) == 0) { outcolor = "aquamarine"; }
+ else if (strcmp(incolor, "pinktint" ) == 0) { outcolor = "pink"; }
+ else if (strcmp(incolor, "bluetint" ) == 0) { outcolor = "light_blue"; }
+ else if (strcmp(incolor, "greentint" ) == 0) { outcolor = "pale_green"; }
+ else if (strcmp(incolor, "hotpink" ) == 0) { outcolor = "orange_red"; }
+ else if (strcmp(incolor, "invisible" ) == 0) { outcolor = "black"; }
+ else { outcolor = "light_gray"; }
+ return outcolor;
+}
+/*}}}convertKinColorToO()____________________________________________________*/
+
+/*{{{convertKinColorToXV()****************************************************/
+char* convertKinColorToXV(char* incolor)
+{
+ return incolor;
+}
+/*}}}convertKinColorToXV()___________________________________________________*/
+
+/*{{{writeOutput()************************************************************/
+void writeOutput(FILE *outf, char* groupname, dotNode *results[][NODEWIDTH], int spike, int method, char* extrastr)
+{ /*writeOutput for kinemage*/
+ /*dcr041020 need method for better kinemage keywords*/
+ /* 060129 extrastr for extra master to control orig vs fitted dots */
+ int i, j;
+ dotNode *node;
+ atom *a;
+ char *color = "";
+ char *mast[NODEWIDTH] = {"wide contact", "close contact", "small overlap", "bad overlap", "H-bonds"};
+ char *surfacestr = "surface"; /*041020*/
+ char *contactstr = "vdw contact"; /*060129*/
+ char extraMstr[32]; /*fill below with extra master name 060129*/
+ char pointid[100], lastpointid[100];
+ char ptmast[6]={'\0','\0','\0','\0','\0','\0'};
+ /*dcr041009 string to hold 'M' (McMc), 'S' (ScSc), 'P' (McSc), 'O' (other)*/
+ /*dcr041009 ptmaster part of each dotNode member of results[][]*/
+ char masterchr=' '; /*dcr041017*/
+
+ if(LMergeContacts) /*060129*/
+ {
+ mast[0] = contactstr;
+ mast[1] = contactstr;
+ }
+ if(LMasterName) /*060129*/
+ {
+ sprintf(extraMstr," master={%s}",extrastr);
+ }
+ else{extraMstr[0] = '\0';} /*occupies no space in output*/
+
+ fprintf(outf, "@subgroup dominant {%s}\n", groupname);
+ /*list masters for contact types dcr041020*/
+ if(method == EXTERNALSURFACE) /*dcr041020*/
+ {/*a bit crude, but better than calling all surfaces a close contact*/
+ mast[1] = surfacestr; /*the only master button invoked dcr041020*/
+ fprintf(outf, "@master {%s}\n", mast[1]); /*was close contact*/
+ }
+ else
+ {/*fine control over masters names dcr041020*/
+ if (OutputVDWs && !OnlyBadOut) { /*dcr041010*/
+ fprintf(outf, "@master {%s}\n", mast[0]);
+ if(!LMergeContacts)
+ fprintf(outf, "@master {%s}\n", mast[1]);
+ }
+ if (OutputClashes || OnlyBadOut) { /*dcr041010*/
+ if(!OnlyBadOut) {fprintf(outf, "@master {%s}\n", mast[2]);}
+ fprintf(outf, "@master {%s}\n", mast[3]); /*the Bad clashes*/
+ }
+ if (OutputHBs && !OnlyBadOut) { /*dcr041010*/
+ fprintf(outf, "@master {%s}\n", mast[4]);
+ }
+ }/*fine control over masters names*/
+ if(mcmccont[0][5] > 0)
+ {
+ masterchr = MCMCCHR; /*single char*/
+ fprintf(outf, "@pointmaster '%c' {McMc contacts}\n",masterchr);
+ }
+ if(scsccont[0][5] > 0)
+ {
+ masterchr = SCSCCHR; /*single char*/
+ fprintf(outf, "@pointmaster '%c' {ScSc contacts}\n",masterchr);
+ }
+ if(mcsccont[0][5] > 0)
+ {
+ masterchr = MCSCCHR; /*single char*/
+ fprintf(outf, "@pointmaster '%c' {McSc contacts}\n",masterchr);
+ }
+ if(othrcont[0][5] > 0)
+ {
+ masterchr = OTHERCHR; /*single char*/
+ fprintf(outf, "@pointmaster '%c' {Hets contacts}\n",masterchr);
+ }
+ for (i = 0; i < NUMATOMTYPES; i++)
+ {/*i: Hatom varients + rest of periodic table + base types, see atomprops.h*/
+ for (j = 0; j < NODEWIDTH; j++)
+ {/*j: wide contact, close contact, small overlap, bad overlap, H-bonds*/
+ node = results[i][j]; /*head of list of dot nodes, i.e. first node*/
+ if (node) { /*write list header*/
+ if (j == 0 || j == 1) {/* contact */
+ if (AtomMasters) {
+ fprintf(outf,
+ "@dotlist {x} color=%s master={%s dots} master={%s}%s%s\n",
+ getColor(i), getAtomName(i), mast[j],extraMstr,
+ LensDots ? " lens" : "");
+ }
+ else {
+ fprintf(outf,
+ "@dotlist {x} color=%s master={%s}%s%s\n",
+ getColor(i), mast[j],extraMstr,
+ LensDots ? " lens" : "");
+ }
+ }
+ else if ((j == 2 || j == 3) && spike) {/* bump w/ spike */
+ if (AtomMasters) {
+ fprintf(outf,
+ "@vectorlist {x} color=%s master={%s dots} master={%s}%s\n",
+ getColor(i), getAtomName(i), mast[j],extraMstr);
+ }
+ else {
+ fprintf(outf,
+ "@vectorlist {x} color=%s master={%s}%s\n",
+ getColor(i), mast[j],extraMstr);
+ }
+ }
+ else {/* bump w/o spike or H-bond */
+ if (AtomMasters) {
+ fprintf(outf,
+ "@dotlist {x} color=%s master={%s dots} master={%s}%s\n",
+ getColor(i), getAtomName(i), mast[j],extraMstr);
+ }
+ else {
+ fprintf(outf,
+ "@dotlist {x} color=%s master={%s}%s\n",
+ getColor(i), mast[j],extraMstr);
+ }
+ }
+ lastpointid[0] = '\0'; /* reset */
+ }/*write list header*/
+ while(node)
+ {/*kinemage point or point-line for each node in (ij)th dot-node list*/
+ a = node->a;
+ if(node->ptmaster == ' ') /*dcr041009*/
+ {/*blank means NO pointmaster*/
+ ptmast[0] = '\0'; /*which will print as a zero-length str*/
+ }
+ else
+ {
+ ptmast[0] = ' '; /*insure leading space*/
+ ptmast[1] = '\''; /*surround single char pointmaster with*/
+ ptmast[2] = node->ptmaster;
+ ptmast[3] = '\''; /*single quote marks*/
+ ptmast[4] = ' '; /*need trailing space*/
+ ptmast[5] = '\0'; /*end string*/
+ }
+/* sprintf(pointid, "%s%c %s%d%c", */
+/* a->atomname, a->altConf, */
+/* a->r->resname, a->r->resid, */
+/* a->r->resInsCode); */
+
+ sprintf(pointid, "%s%c%s%s%c%2s",
+ a->atomname, a->altConf,
+ a->r->resname, a->r->Hy36resno,
+ a->r->resInsCode, a->r->chain);
+
+
+ if (strcmp(pointid, lastpointid)) {
+ strcpy(lastpointid, pointid);
+ fprintf(outf, "{%s}", pointid);
+ }
+ else {
+ fprintf(outf, "{\"}");
+ }
+ if (ColorGap) {
+ if (node->t) {
+ color = assignGapColorForKin(node->gap, j);
+ fprintf(outf, "%s", color);
+ }
+ else {fprintf(outf, "%s", OutPointColor);}
+ } /* added "%s" string format to color and */
+ /* edited "%s " to "%s" in OutPointColor, wba 110909 */
+ if ((j == 2 || j == 3) && spike) {/* bump */
+ fprintf(outf,
+ "P %s%.3f,%.3f,%.3f {\"}%s %s%.3f,%.3f,%.3f\n", /*dcr041009*/
+ ptmast,node->loc.x, node->loc.y, node->loc.z, /*dcr041009*/
+ color, /*** note: second color reference */
+ ptmast,node->spike.x, node->spike.y, node->spike.z); /*dcr041009*/
+ }
+ else {/* contact or H-bond */
+ fprintf(outf, "%s%.3f,%.3f,%.3f\n", /*dcr041009*/
+ ptmast,node->loc.x, node->loc.y, node->loc.z); /*dcr041009*/
+ }
+ node = node->next; /*in this (ij)th dot-node list*/
+ }/*kinemage point or point-line for each node in (ij)th dot-node list*/
+ }/*j: wide contact, close contact, small overlap, bad overlap, H-bonds*/
+ }/*i: Hatom varients + rest of periodic table + base types, see atomprops.h*/
+}/*writeOutput for kinemage*/
+/*}}}writeOutput()___________________________________________________________*/
+
+/*{{{writeAltFmtO()***********************************************************/
+void writeAltFmtO(FILE *outf, int showBegin, int showEnd,
+ char* groupname, dotNode *results[][NODEWIDTH], int spike)
+{
+ int i, j, numGroups, gn;
+ dotNode *node;
+ char *color = "", *prevColor = "";
+ char *mast[NODEWIDTH] = {"WC", "CC", "SO", "BO", "HB"};
+
+ numGroups = (showBegin && showEnd) ? 1 : 2;
+ gn = (!showBegin && showEnd) ? 2 : 1;
+
+ for (j = 0; j < NODEWIDTH; j++) {
+ fprintf(outf, "begin_object %s%d\n", mast[j], gn);
+ fprintf(outf, "mode solid\n");
+
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ prevColor = "--none--";
+ node = results[i][j];
+ if (node) {
+ color = convertKinColorToXV(getColor(i));
+ }
+ while(node) {
+ if (ColorGap) {
+ if (node->t) {
+ color = assignGapColorForO(node->gap, j);
+ }
+ else { color = "124";}
+ }
+ if (color != prevColor) {
+ fprintf(outf, "colour %s\n", color);
+ prevColor = color;
+ }
+ if ((j == 2 || j == 3) && spike) {/* bump */
+ fprintf(outf,
+ "move %.3f %.3f %.3f\nline %.3f %.3f %.3f\n",
+ node->loc.x, node->loc.y, node->loc.z,
+ node->spike.x, node->spike.y, node->spike.z);
+ }
+ else {/* contact or H-bond */
+ fprintf(outf, "sphere_xyz %.3f %.3f %.3f 0.03\n",
+ node->loc.x, node->loc.y, node->loc.z);
+ }
+ node = node->next;
+ }
+ }
+ fprintf(outf, "end_object\n");
+ }
+
+ if (showEnd) {
+ if (showBegin) { fprintf(outf, "begin_object %s\n", groupname); }
+ else { fprintf(outf, "begin_object contsurf\n"); }
+ for (j = 0; j < NODEWIDTH; j++) {
+ for (i = 0; i < numGroups; i++) {
+ fprintf(outf, "instance %s%d\n", mast[j], i+1);
+ }
+ }
+ fprintf(outf, "end_object\n");
+ }
+}
+/*}}}writeAltFmtO()__________________________________________________________*/
+
+/*{{{writeAltFmtXV()**********************************************************/
+void writeAltFmtXV(FILE *outf, int showBegin, int showEnd,
+ char* groupname, dotNode *results[][NODEWIDTH], int spike)
+{
+ int i, j;
+ dotNode *node;
+ char *color = "";
+ char *mast[NODEWIDTH] = {"wide contact", "close contact", "small overlap", "bad overlap", "H-bonds"};
+
+ if (showBegin) {
+ if (showEnd) { fprintf(outf, "# begin %s\n", groupname); }
+ else { fprintf(outf, "# begin object\n# group: %s\n", groupname); }
+ }
+ else { fprintf(outf, "# group: %s\n", groupname); }
+
+ for (j = 0; j < NODEWIDTH; j++) {
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ node = results[i][j];
+ if (node) {
+ fprintf(outf, "# (%s %s)\n", getAtomName(i), mast[j]);
+ color = convertKinColorToXV(getColor(i));
+ }
+ while(node) {
+ if (ColorGap) {
+ if (node->t) {
+ color = assignGapColorForXV(node->gap, j);
+ }
+ else { color = "124";}
+ }
+ if ((j == 2 || j == 3) && spike) {/* bump */
+ fprintf(outf,
+ "%.3f %.3f %.3f %.3f %.3f %.3f %s\n",
+ node->loc.x, node->loc.y, node->loc.z,
+ node->spike.x, node->spike.y, node->spike.z, color);
+ }
+ else {/* contact or H-bond */
+ fprintf(outf, "%.3f %.3f %.3f %.3f %.3f %.3f %s\n",
+ node->loc.x, node->loc.y, node->loc.z,
+ node->loc.x, node->loc.y, node->loc.z, color);
+ }
+ node = node->next;
+ }
+ }
+ }
+ if (showEnd) {
+ if (showBegin) { fprintf(outf, "# end %s\n", groupname); }
+ else { fprintf(outf, "# endgroup: %s\n# end object\n", groupname); }
+ }
+ else { fprintf(outf, "# endgroup: %s\n", groupname); }
+}
+/*}}}writeAltFmtXV()_________________________________________________________*/
+
+/*{{{dot2bullsEye()***********************************************************/
+float dot2bullsEye(point3d *dot, atom *src, atom *targ)
+{
+ point3d targ2srcVec, targSurfacePoint;
+
+ v3sub(&(src->loc), &(targ->loc), &targ2srcVec);
+ v3scale(&targ2srcVec, targ->radius);
+ v3add(&targ2srcVec, &(targ->loc), &targSurfacePoint);
+ return v3distance(dot, &targSurfacePoint);
+}
+/*}}}dot2bullsEye()__________________________________________________________*/
+
+/*{{{dot2srcCenter()**********************************************************/
+float dot2srcCenter(point3d *dot, atom *src, atom *targ)
+{
+ point3d src2targVec, srcSurfacePoint;
+
+ v3sub(&(targ->loc), &(src->loc), &src2targVec);
+ v3scale(&src2targVec, src->radius);
+ v3add(&src2targVec, &(src->loc), &srcSurfacePoint);
+ return v3distance(dot, &srcSurfacePoint);
+}
+/*}}}dot2srcCenter()_________________________________________________________*/
+
+/*{{{kissEdge2bullsEye()******************************************************/
+float kissEdge2bullsEye(float ra, float rb, float rp)
+{
+ return 2.0*ra*sqrt(rb*rp/((ra+rb)*(ra+rp)));
+}
+/*}}}kissEdge2bullsEye()_____________________________________________________*/
+
+/*{{{writeRaw()***************************************************************/
+void writeRaw(FILE *outf, char* groupname, dotNode *results[][NODEWIDTH],
+ float probeRad, char* label, float density)
+{
+ int i, j;
+ dotNode *node;
+ atom *a, *t;
+ char *mast[NODEWIDTH] = {"wc", "cc", "so", "bo", "hb"};
+ float gap, sl, dtgp, ke2be, d2be, d2sc, score;
+ double scaledGap;
+
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ for (j = 0; j < NODEWIDTH; j++) {
+ node = results[i][j];
+ while(node) {
+ fprintf(outf, "%s:%s:%s:", label, groupname, mast[j]);
+
+ a = node->a;
+ fprintf(outf, "%2s%4.4s%c%s %s%c:",
+ a->r->chain, a->r->Hy36resno, a->r->resInsCode, a->r->resname,
+ a->atomname, a->altConf);
+ t = node->t;
+ if (t) {
+ fprintf(outf, "%2s%4.4s%c%s %s%c:",
+ t->r->chain, t->r->Hy36resno, t->r->resInsCode, t->r->resname,
+ t->atomname, t->altConf);
+ gap = gapSize(&(a->loc), &(t->loc),
+ (a->radius + t->radius));
+ dtgp = node->gap;
+ if (OldStyleU) {
+ ke2be = kissEdge2bullsEye(a->radius, t->radius, probeRad);
+ d2be = dot2bullsEye(&(node->loc), a, t);
+ d2sc = dot2srcCenter(&(node->loc), a, t);
+ }
+ sl = gapSize(&(node->loc), &(node->spike), 0.0);
+ score = 0.0;
+ switch(j) {
+ case 0:
+ case 1:
+ scaledGap = dtgp/GAPweight;
+ score = exp(-scaledGap*scaledGap);
+ break;
+ case 2:
+ case 3: score = -BUMPweight * sl; break;
+ case 4: score = HBweight * sl; break;
+ }
+ if (OldStyleU) {
+ fprintf(outf, "%.3f:%.3f:%.3f:%.3f:%.3f:%.3f:%.4f",
+ gap, dtgp, ke2be, d2be, d2sc, sl, score/density);
+ }
+ else { /* spike end now part of -u output */
+ fprintf(outf, "%.3f:%.3f:%.3f:%.3f:%.3f:%.3f:%.4f",
+ gap, dtgp,
+ node->spike.x, node->spike.y, node->spike.z, sl,
+ score/density);
+ }
+ }
+ else { fprintf(outf, ":::::::"); }
+
+ fprintf(outf, ":%s:%s:%.3f:%.3f:%.3f",
+ getAtomName(i),
+ (t?getAtomName(t->atomclass):""),
+ node->loc.x,node->loc.y,node->loc.z);
+
+ if (t) { fprintf(outf, ":%.2f:%.2f\n", a->bval, t->bval);}
+ else { fprintf(outf, ":%.2f:\n", a->bval);}
+
+ node = node->next;
+ }
+ }
+ }
+}
+/*}}}writeRaw()______________________________________________________________*/
+
+/*{{{enumerate()**************************************************************/
+void enumerate(FILE *outf, char* groupname, dotNode *results[][NODEWIDTH],
+ float probeRad, int method,
+ int nsel, int spike, int outdots, int numSkinDots,
+ float density)
+{
+ int i, j, doit;
+ float gs, hs, bs, hslen, bslen, tgs, ths, tbs, thslen, tbslen, psas, tsas;
+ float dtgp, score, tGscore, tHscore, tBscore, tscore, scoreValue, a_radius;
+ double scaledGap, slen;
+ dotNode *node;
+ char *mast[NODEWIDTH] = {"wide_contact ", "close_contact ",
+ "small_overlap ", "bad_overlap ", "H-bond "};
+
+ /* psas and tsas are the partial and total solvent accessible surface */
+
+ fprintf(outf, " \nsubgroup: %s\n", groupname);
+ fprintf(outf, "atoms selected: %d\npotential dots: %d\npotential area: %.1f A^2\n",
+ nsel, numSkinDots, numSkinDots/density);
+
+ if (nsel <= 0 || numSkinDots <= 0) {
+ fprintf(outf, "empty selection\n");
+ return;
+ }
+ if (spike) {
+ fprintf(outf, " type # %% score score/A^2 x 1000\n");
+ }
+ else {
+ fprintf(outf, " type # %%\n");
+ }
+
+ tgs = ths = thslen = tbs = tbslen = tsas = 0.0;
+ tGscore = tHscore = tBscore = tscore = 0.0;
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ for (j = 0; j < NODEWIDTH; j++) {
+ gs = hs = hslen = bs = bslen = score = psas = 0.0;
+ node = results[i][j];
+ doit = (node != NULL);
+ if (doit) {
+ fprintf(outf, "%3s %s ", getAtomName(i),
+ outdots?"external_dots ":mast[j]);
+ }
+ while(node) {
+ if (spike) {
+ if (j == 0 || j == 1) { /* contact dot */
+ gs += 1.0;
+ dtgp = node->gap;
+ scaledGap = dtgp/GAPweight;
+ scoreValue = exp(-scaledGap*scaledGap);
+ score += scoreValue;
+ tGscore += scoreValue;
+ }
+ else if (j == 2 || j == 3) { /* bump */
+ bs += 1.0;
+ slen = 0.5*FABS(node->gap);
+ bslen += slen;
+ scoreValue = - BUMPweight * slen;
+ score += scoreValue;
+ tBscore += scoreValue;
+ }
+ else { /* H-bond */
+ hs += 1.0;
+ slen = 0.5*FABS(node->gap);
+ hslen += slen;
+ scoreValue = HBweight * slen;
+ score += scoreValue;
+ tHscore += scoreValue;
+ }
+ }
+ else { gs += 1.0; }
+
+ if (method == EXTERNALSURFACE) {
+ a_radius = node->a->radius;
+ psas += (a_radius + probeRad)*(a_radius + probeRad)/(a_radius * a_radius);
+ }
+ node = node->next;
+ }
+ if (doit) {
+ if (spike) {
+ if (j == 0 || j == 1) { /* contact dot */
+ fprintf(outf, "%7.0f %5.1f%% %9.1f %9.2f\n",
+ gs, 100.0*gs/numSkinDots, score/density,
+ 1000.0*score/numSkinDots);
+ }
+ else if (j == 2 || j == 3) { /* bump */
+ fprintf(outf, "%7.0f %5.1f%% %9.1f %9.2f\n",
+ bs, 100.0*bs/numSkinDots, score/density,
+ 1000.0*score/numSkinDots);
+ }
+ else { /* H-bond */
+ fprintf(outf, "%7.0f %5.1f%% %9.1f %9.2f\n",
+ hs, 100.0*hs/numSkinDots, score/density,
+ 1000.0*score/numSkinDots);
+ }
+ }
+ else {
+ fprintf(outf, "%7.0f %5.1f%%\n",
+ gs, 100.0*gs/numSkinDots);
+ }
+ tgs += gs;
+ ths += hs;
+ thslen += hslen;
+ tbs += bs;
+ tbslen += bslen;
+ tscore += score;
+ if (method == EXTERNALSURFACE) {
+ tsas += psas; /* tally the solvent accessible surface */
+ }
+ }
+ }
+ }
+ if (spike) {
+/* fprintf(outf, " score/A^2 x 1000\n");*/
+ fprintf(outf, "\n tot contact: %7.0f %5.1f%% %9.1f %9.2f\n",
+ tgs, 100.0*tgs/numSkinDots, tGscore/density,
+ 1000.0*tGscore/numSkinDots);
+ fprintf(outf, " tot overlap: %7.0f %5.1f%% %9.1f %9.2f\n",
+ tbs, 100.0*tbs/numSkinDots, tBscore/density,
+ 1000.0*tBscore/numSkinDots);
+ fprintf(outf, " tot H-bond: %7.0f %5.1f%% %9.1f %9.2f\n",
+ ths, 100.0*ths/numSkinDots, tHscore/density,
+ 1000.0*tHscore/numSkinDots);
+
+ fprintf(outf, "\n grand tot: %7.0f %5.1f%% %9.1f %9.2f\n",
+ (tgs+tbs+ths),
+ 100.0*(tgs+tbs+ths)/numSkinDots,
+ tscore/density, 1000.0*tscore/numSkinDots);
+ fprintf(outf, "\ncontact surface area: %.1f A^2\n",
+ (tgs+tbs+ths)/density);
+ }
+ else {
+ fprintf(outf, " tot: %7.0f %5.1f%%\n\n",
+ tgs, 100.0*tgs/numSkinDots);
+ fprintf(outf, " contact surface area: %.1f A^2\n",
+ tgs/density);
+ if (method == EXTERNALSURFACE) {
+ fprintf(outf, "accessible surface area: %.1f A^2\n\n",
+ tsas/density);
+ }
+ }
+}
+/*}}}enumerate()_____________________________________________________________*/
+
+/*{{{rawEnumerate()***********************************************************/
+void rawEnumerate(FILE *outf, char* groupname, dotNode *results[][NODEWIDTH],
+ int method, int nsel, int spike, int outdots, int numSkinDots,
+ float density, char *namestring, char *rawname, double scoreBias)
+{/*rawEnumerate*/
+ int i, j, doit;
+ float gs, hs, bs, hslen, bslen, tgs, ths, tbs, thslen, tbslen;
+ float dtgp, score, tGscore, tHscore, tBscore, tscore, scoreValue;
+ double scaledGap, slen;
+ dotNode *node;
+
+ /*autobondrot: countDots==1, rawOutput==1 */
+ /* *rawname holds autobondrot angle values as space_char deliniated string*/
+
+ if (nsel <= 0 || numSkinDots <= 0) { /* empty selection */
+ if (method == EXTERNALSURFACE) {
+ fprintf(outf, "%9.3f", 0.0);
+ }
+ else if (spike) {
+ fprintf(outf, "%9.3f", scoreBias);
+ }
+
+ if (*rawname) { fprintf(outf, " %s", rawname); }
+ if (*namestring || *groupname) {
+ fprintf(outf, "%s", RAW_HEADER_COMMENT);
+ if (*namestring) { fprintf(outf, " %s", namestring); }
+ if (*groupname) { fprintf(outf, " %s", groupname); }
+ }
+ fprintf(outf, "\n");
+ return;
+ }
+
+ tgs = ths = thslen = tbs = tbslen = 0.0;
+ tGscore = tHscore = tBscore = tscore = 0.0;
+ for (i = 0; i < NUMATOMTYPES; i++) {
+ for (j = 0; j < NODEWIDTH; j++) {
+ gs = hs = hslen = bs = bslen = score = 0.0;
+ node = results[i][j];
+ doit = (node != NULL);
+ while(node) {
+ if (spike) {
+ if (j == 0 || j == 1) { /* contact dot */
+ gs += 1.0;
+ dtgp = node->gap;
+ scaledGap = dtgp/GAPweight;
+ scoreValue = exp(-scaledGap*scaledGap);
+ score += scoreValue;
+ tGscore += scoreValue;
+ }
+ else if (j == 2 || j == 3) { /* bump */
+ bs += 1.0;
+ slen = 0.5*FABS(node->gap);
+ bslen += slen;
+ scoreValue = - BUMPweight * slen;
+ score += scoreValue;
+ tBscore += scoreValue;
+ }
+ else { /* H-bond */
+ hs += 1.0;
+ slen = 0.5*FABS(node->gap);
+ hslen += slen;
+ scoreValue = HBweight * slen;
+ score += scoreValue;
+ tHscore += scoreValue;
+ }
+ }
+ else { gs += 1.0; }
+ node = node->next;
+ }
+ if (doit) {
+ tgs += gs;
+ ths += hs;
+ thslen += hslen;
+ tbs += bs;
+ tbslen += bslen;
+ tscore += score;
+ }
+ }
+ }
+
+ /*output one line of information */
+ if (method == EXTERNALSURFACE) {
+ fprintf(outf, "%9.3f", (tgs+tbs+ths)/density);
+ }
+ else if (spike) /*autobondrot: spike==1 at least in all examples dcr tested*/
+ {
+ fprintf(outf, "%9.3f", scoreBias + (tscore/density)); /*value # ...*/
+ }
+ else {
+ fprintf(outf, "%9.3f", scoreBias + tgs);
+ }
+ if (*rawname) { fprintf(outf, " %s", rawname); } /*autobondrot angle values*/
+ if (*namestring || *groupname) {
+ fprintf(outf, "%s", RAW_HEADER_COMMENT);
+ if (*namestring) { fprintf(outf, " %s", namestring); }
+ if (*groupname) { fprintf(outf, " %s", groupname); }
+ }
+ fprintf(outf, "\n"); /* NOTE this is the LF for above print statements*/
+
+ /* char* rawname == buf that is filled in autobondrot.c/runnameAndTorsion()*/
+ /* contains the autobondrot angle values in the order in which processed*/
+
+}/*rawEnumerate*/
+/*}}}rawEnumerate()__________________________________________________________*/
+
+/*{{{countSelected()**********************************************************/
+int countSelected(atom *theAtoms, int srcFlag)
+{
+ atom *a = NULL;
+ int ns = 0;
+ for(a = theAtoms; a; a = a->next) {
+ if (a->flags & srcFlag) { ns++; }
+ }
+ return ns;
+}
+/*}}}countSelected()_________________________________________________________*/
+
+/*{{{enumDotSkin()************************************************************/
+
+/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
+/* sets of atoms (none in common) or allMovingAtoms/bbins can */
+/* be NULL. */
+/* allMovingAtoms refers to autobondrot set of atoms */
+
+int enumDotSkin(atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[], int srcFlag)
+{
+ atom *src = NULL, *atomList = NULL, *atomList2 = NULL;
+ int dotTotal = 0, usesMovingAtoms = FALSE;
+ int dummy = TRUE;
+
+ /*numSkinDots used to normalize output score*/
+
+ usesMovingAtoms = ((allMovingAtoms != NULL) && (bbins != NULL));
+
+ for(src = allMainAtoms; src; src = src->next) {
+ if (src->flags & srcFlag) {
+
+ atomList = findTouchingAtoms(src, NULL, abins, 0.0, 0, &dummy);
+ if (usesMovingAtoms) {
+ atomList2 = findTouchingAtoms(src, atomList, bbins, 0.0, 0, &dummy);
+ }
+ else { atomList2 = atomList; }
+
+ if (atomList2) {
+ markBonds(src, atomList2, 1, Maxbonded); /*in enumDotSkin()*/
+ if (Maxbonded > 3) { fixupLongBondChains(src, atomList2, 3); }
+ }
+ dotTotal += countSkin(src, atomList2, dots);
+
+ if(Verbose && ShowTicks) {
+ fprintf(stderr, "%s%s \r",
+ src->r->resname, src->r->Hy36resno);
+ }
+ }
+ }
+
+ if (usesMovingAtoms) {
+ for(src = allMovingAtoms; src; src = src->next) {
+ if (src->flags & srcFlag) {
+
+ atomList = findTouchingAtoms(src, NULL, abins, 0.0, 0, &dummy);
+ atomList2 = findTouchingAtoms(src, atomList, bbins, 0.0, 0, &dummy);
+ if (atomList2) {
+ markBonds(src, atomList2, 1, Maxbonded); /*in enumDotSkin()*/
+ if (Maxbonded > 3) { fixupLongBondChains(src, atomList2, 3); }
+ }
+ dotTotal += countSkin(src, atomList2, dots);
+
+ if(Verbose && ShowTicks) {
+ fprintf(stderr, "%s%s \r",
+ src->r->resname, src->r->Hy36resno);
+ }
+ }
+ }
+ }
+ return dotTotal;
+}
+/*}}}enumDotSkin()___________________________________________________________*/
+
+/*{{{countSkin()**************************************************************/
+int countSkin(atom *src, atom *scratch, pointSet dots[])
+{
+ atom *targ = NULL;
+ int i = 0, within = 0, ok = 0;
+ point3d dotloc, dotvect;
+ pointSet *srcDots;
+ int dotCnt = 0;
+
+ if (src->elem == ignoreAtom
+ || src->elem == atomHOd) { return 0; } /*hb-only-dummy, phantom H atom*/
+
+ srcDots = &(dots[src->elem]);
+ if (src->elem == atomC && isCarbonylAtom(src)) {
+ srcDots = &COdots;
+ }
+
+ for(i=0; i < srcDots->n; i++) {
+ dotvect = srcDots->p[i];
+
+ v3add(&(src->loc), &dotvect, &dotloc);
+
+ ok = TRUE;
+
+ /*targ is an atom*, scratch is an atom*, atom* defined in abin.h */
+ /* atom* scratch is a member of atom*: which has member scratch...*/
+ /* so for-loop moves through all these atoms while an atom has a scratch*/
+
+ for(targ = scratch; targ; targ = targ->scratch) {
+ if (targ->elem == ignoreAtom) {continue;}
+
+ /* eliminate if within bonded atom! */
+ if (targ->mark && (targ->elem != atomHOd)) {
+#ifdef INLINE_FOR_SPEED
+ within = INRANGEINLINE(dotloc, (targ->loc), targ->radius);
+#else
+ within = inRange(&dotloc, &(targ->loc), targ->radius);
+#endif
+
+ if (within) { ok = FALSE; break; }
+ }
+ }
+ if (ok) { dotCnt++; }
+ }
+ return dotCnt;
+}
+/*}}}countSkin()_____________________________________________________________*/
+
+/*{{{updateHydrogenInfo()*****************************************************/
+/* Make polor hydrogens HB donors. */
+/* Waters without hydrogens are protonated with "phantoms". */
+/* If we are using moving atoms, all the new water H atoms go there */
+
+/* can return a list of new atom "clones" which are just the MainAtoms waters */
+
+/* NOTE: allMainAtoms/abins & allMovingAtoms/bbins must be disjoint */
+/* sets of atoms (none in common) or allMovingAtoms/bbins can */
+/* be NULL. */
+/* allMovingAtoms refers to autobondrot set of atoms */
+
+/*usual call: (i.e. NOT autobondrot)
+ updateHydrogenInfo(outf, allMainAtoms, abins,
+ NULL, NULL,
+ SET1|SET2, FALSE);
+*/
+atom* updateHydrogenInfo(FILE *outf, atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ int selectedFlag, int mustSaveMainWater)
+{
+ atom *src = NULL, *orig = NULL, *atomList = NULL, *a = NULL;
+ atom *newH = NULL, *tempStaticList = NULL, *mainWaterStorage = NULL;
+ int type = 0, newHcount = 0, i = 0, whichList = 0;
+ int nProx = 0, usesMovingAtoms = FALSE;
+ int dummy = FALSE;
+
+/* Information specific to making sure only one H2O Hydrogen is */
+/* generated which points into ring atoms on a given aromatic ring. */
+ struct {atom *a; float gap;} proximity[20];
+
+ usesMovingAtoms = ((allMovingAtoms != NULL) && (bbins != NULL));
+ if (! usesMovingAtoms) { allMovingAtoms = NULL; bbins = NULL; }
+
+ if (DumpNewHO) { fprintf(outf,"@vectorlist {water H?} color= gray\n"); }
+
+ tempStaticList = NULL; /* new hydrogens for MainAtoms when usesMovingAtoms */
+ mainWaterStorage = NULL; /* MainAtoms waters when usesMovingAtoms */
+
+ for(whichList = 0; whichList <= 1; whichList++) { /* loop over both lists of atoms */
+ for(src = ((whichList==0)?allMainAtoms:allMovingAtoms); src; src = src->next) {
+
+/* Note: we have to examine ALL the atoms at this point. */
+/* Not testing (src->flags & selectedFlag) for H will slow down */
+/* the code but it is neccessary to get the atom types correct. */
+
+ if (isHatom(src->elem)) { /* fixup Hs in the input */
+
+ atomList = NULL;
+ if (src->flags & selectedFlag) {
+ atomList = findTouchingAtoms(src, NULL, abins, 0.0, 0, &dummy);
+ if (usesMovingAtoms) {
+ atomList = findTouchingAtoms(src, atomList, bbins, 0.0, 0, &dummy);
+ }
+ }
+ if (atomList) {
+ markBonds(src, atomList, 1, 1); /*in updateHydrogenInfo()*/
+ type = dotType(src, atomList, ByNABaseColor);
+
+ if ( type == atomN || type == atomO || type == atomS ) {
+ if(Verbose && ShowTicks) {
+ fprintf(stderr, "%s%d \r",
+ src->r->resname, src->r->resid);
+ }
+
+ src->props |= DONOR_PROP; /* polar hydrogens are donors */
+
+ if (UsePolarH) {
+ src->elem = atomHpolar; /* very important */
+ src->radius = getRadius(src->elem, 0);
+ }
+/* there are a more restrictive set of cutoffs in reduce: 0.7 & 40 */
+#define H2OoccCUTTOFF 0.25
+#define H2ObvalCUTTOFF 80.0
+ if ((FABS(src->occ) < H2OoccCUTTOFF
+ || src->bval >= H2ObvalCUTTOFF)
+ && (src->props & WATER_PROP)) {
+ src->elem = ignoreAtom;
+ src->radius = 0.0;
+ } /* ignore low occupancy water hydrogens */
+
+ for(a = atomList; a; a = a->scratch) {
+ /* since we found a hydrogen, then we know */
+ /* that the heavy atom is not the donor */
+ /* so we can disable that property */
+ if ((a->mark == 1) && ! isHatom(a->elem)
+ && (FABS(src->occ) >= H2OoccCUTTOFF)
+ && (src->bval < H2ObvalCUTTOFF)) {
+
+ a->props &= ~DONOR_PROP;
+ }
+ }
+ } /* end if (atom types) */
+ }
+ }/* fixup Hs in the input */
+ else if ((src->flags & selectedFlag) /* fixup water oxygen */
+ && (src->props & WATER_PROP) && (src->elem == atomO)) {
+
+ /*if connected H already found, the DONOR prop will not be set*/
+ /*if it is, we look further ahead in this residue for Hs */
+ if (src->props & DONOR_PROP) {
+ for(a = src->next; a && (src->r == a->r); a = a->next) {
+ if ( isHatom(a->elem)
+ && (src->altConf == a->altConf)
+ && (a->occ > 0.1)) {
+ src->props &= ~DONOR_PROP; /* turn off donor property */
+ }
+ }
+ }
+ /* if donor flag still set... */
+ if (src->props & DONOR_PROP) { /* water O without occupied Hs */
+
+/* begin clone procedure */
+ /* special case for when we want to remember just these waters */
+ /* in this state */
+ if (mustSaveMainWater && usesMovingAtoms && (whichList==0)) {
+ atom* waterClone = NULL;
+ waterClone = (atom *)malloc(sizeof(atom));
+ if (waterClone) {
+ *waterClone = *src;
+ waterClone->next = mainWaterStorage; /* add clone to list */
+ mainWaterStorage = waterClone;
+ }
+ }
+/* end clone procedure */
+
+ src->props |= AMBIGWATER_PROP; /* this is a water which needs H? added */
+ src->props |= ACCEPTOR_PROP;
+ src->props &= ~DONOR_PROP; /* acceptor, not donor */
+ orig = src; /* keep track of the original Oxygen atom */
+ atomList = findTouchingAtoms(src, NULL, abins, 0.25, 0, &dummy);
+ if (usesMovingAtoms) {
+ atomList = findTouchingAtoms(src, atomList, bbins, 0.25, 0, &dummy);
+ }
+ /* the 0.25 comes from:
+ OxygenVDW(1.4) + 2*probeRad(0.3) == HpolVDW(1.0) + OHBondLen(1.0)
+ and we want a minimum overlap of 0.1 before we consider possible Hs
+ */
+
+ /* for each nearby HB acceptor, keep only 1 per aromatic ring */
+ nProx = 0;
+ for(a = atomList; a; a = a->scratch) {
+ if (a->props & ACCEPTOR_PROP) {
+ float hbgap = gapSize(&(a->loc), &(orig->loc),
+ a->radius + 2.0);
+
+ int foundAromRingAtom = FALSE;
+
+ if (a->props & AROMATIC_PROP) {
+ for (i=0; i < nProx; i++) {
+ if (a->r == proximity[i].a->r
+ && proximity[i].a->props & AROMATIC_PROP) {
+
+ if (hbgap < proximity[i].gap) {
+ proximity[i].a = a;
+ proximity[i].gap = hbgap;
+ }
+ foundAromRingAtom = TRUE;
+ break;
+ }
+ }
+ }
+ if ( (!foundAromRingAtom)
+ && nProx < sizeof(proximity)/sizeof(proximity[0])) {
+ proximity[nProx].a = a;
+ proximity[nProx].gap = hbgap;
+ ++nProx;
+ }
+ } /* end if acceptor_prop */
+ }
+
+ /* build new HOH hydrogens in the direction of each acceptor */
+ newHcount = 0;
+ for (i=0; i < nProx; i++) {
+
+ a = proximity[i].a;
+
+ if (a->props & ACCEPTOR_PROP) {
+
+ /* Make a phantom H in the direction of each Acceptor */
+ newH = (atom *)malloc(sizeof(atom));
+ if (newH) {
+ point3d o2aVec;
+ double waterOHbondLen;
+
+ *newH = *orig;
+ if (usesMovingAtoms) {
+ newH->next = tempStaticList; /* hook into temp list */
+ tempStaticList = newH;
+ }
+ else {
+ newH->next = src->next; /* hook into list of atoms */
+ src->next = newH;
+ }
+
+ v3sub(&(a->loc), &(orig->loc), &o2aVec);
+#define BEST_HBOND_OVERLAP 0.6
+ waterOHbondLen = 1.0 +
+ MAX(-1.0, MIN(0.0, proximity[i].gap + BEST_HBOND_OVERLAP));
+ v3scale(&o2aVec, waterOHbondLen);
+ v3add(&(orig->loc), &o2aVec, &(newH->loc));
+
+ newH->nextInBin= NULL; /* added to bins below */
+ newH->scratch = NULL;
+ newH->elem = atomHOd; /*hb-only-dummy, phantom H atom*/
+ newH->radius = getRadius(newH->elem, 0);
+ newH->covRad = getCovRad(newH->elem);
+ /*atomprops.h/atomProp AtomTbl covRad*/
+ strcpy(newH->atomname, " H? ");
+
+ newH->props |= DONOR_PROP;
+ newH->props &= ~ACCEPTOR_PROP; /* donor, not acceptor */
+
+ /* *** adding an atom not in input! *** */
+ addNeighbor(newH, (usesMovingAtoms ? bbins : abins));
+
+ if (DumpNewHO) {
+if (DebugLevel>3) {
+fprintf(stderr,
+"HETATM%5d H%-2d%c%3.3s%2s%4.4s%c %8.3f%8.3f%8.3f%6.2f%6.2f new H\n",
+ 0, ++newHcount, newH->altConf,
+ newH->r->resname, newH->r->chain,
+ newH->r->Hy36resno, newH->r->resInsCode,
+ newH->loc.x, newH->loc.y, newH->loc.z,
+ newH->occ, newH->bval);
+}
+ fprintf(outf, "{%4.4s%c%3.3s%2s%4.4s%c}P %8.3f%8.3f%8.3f\n",
+ orig->atomname, orig->altConf,
+ orig->r->resname, orig->r->chain,
+ orig->r->Hy36resno, orig->r->resInsCode,
+ orig->loc.x, orig->loc.y, orig->loc.z);
+ fprintf(outf, "{%4.4s%c%3.3s%2s%4s%c}L %8.3f%8.3f%8.3f\n",
+ newH->atomname, newH->altConf,
+ newH->r->resname, newH->r->chain,
+ newH->r->Hy36resno, newH->r->resInsCode,
+ newH->loc.x, newH->loc.y, newH->loc.z);
+ }
+
+ if (! usesMovingAtoms) {
+ src = src->next; /* bypass new atom when we iterate */
+ /* when inserted after src atom */
+ }
+ }
+ } /* end if acceptor_prop */
+ } /* end for */
+
+ }
+ } /* else if water */ /* fixup water oxygen */
+
+ /* non-water polar (N/O/S) atoms in selection list */
+ else if ((src->flags & selectedFlag) && !(src->props & WATER_PROP)
+ && (src->elem == atomN
+ || src->elem == atomO
+ || src->elem == atomS)) {
+ /* Remove any DONOR property for non-water non-H */
+ /* polar atoms since the Hydrogen atoms will be the DONORs. */
+ /* This was assigned in select.c to facilitate selections. */
+
+ src->props &= ~DONOR_PROP;
+ }
+
+ } /* end loop over list of atoms */
+ } /* end loop over each atom lists */
+
+ /* new hydrogens for MainAtoms when usesMovingAtoms */
+
+ if (tempStaticList) {
+ for(src = allMovingAtoms; src; src = src->next) {
+ if (src->next == NULL) {
+ src->next = tempStaticList;
+ break; /* make sure we don't continually loop */
+ }
+ }
+ }
+ return mainWaterStorage;
+}/*updateHydrogenInfo*/
+/*}}}updateHydrogenInfo()____________________________________________________*/
+
+/*{{{dump_changes()***********************************************************/
+void dump_changes(FILE *outf)
+{
+fprintf(outf, "Probe change log:\n");
+fprintf(outf, "\n");
+fprintf(outf, "Note: Not captured prior to Aug 1998.\n");
+fprintf(outf, " JMW = J Michael Word\n");
+fprintf(outf, "\n");
+fprintf(outf, " 8/ 7/98 - JMW - added segID parsing for XPLOR compatibility\n");
+fprintf(outf, " 8/10/98 - JMW - added formatting for O and XtalView output\n");
+fprintf(outf, "11/12/98 - JMW - use table to parent H atoms in std. residues,\n");
+fprintf(outf, " made GAPweight expand with expanded radius,\n");
+fprintf(outf, " and reorganized O format output in chunks\n");
+fprintf(outf, " and changed xview format colors and modified\n");
+fprintf(outf, " hydrogen name parsing for HG## and HE##\n");
+fprintf(outf, "11/15/98 - JMW - added -stdbonds and -noparent flags and built\n");
+fprintf(outf, " a complete std AA and NA connectivity table\n");
+fprintf(outf, "11/23/98 - JMW - extended std bond table for truncated H names\n");
+fprintf(outf, " 3/ 8/99 - JMW - atom names can include * and ' characters\n");
+fprintf(outf, " 3/11/99 - JMW - fixed HBond problem with implicit hydrogens\n");
+fprintf(outf, " and altered the skipping of MCMC to skip them\n");
+fprintf(outf, " only if within a single chain and not a HET\n");
+fprintf(outf, " 3/16/99 - JMW - Made water donor/acceptor insensitive to names\n");
+fprintf(outf, " and extended atom name parsing for wierd HETS\n");
+fprintf(outf, " 4/05/99 - JMW - Fixed typo in error checking in parse.c for\n");
+fprintf(outf, " processing within _ of _,_,_\n");
+fprintf(outf, " 4/06/99 - JMW - Updated stdbond table for NT and OXT\n");
+fprintf(outf, " 4/07/99 - JMW - Cleaned up compiler warnings on initialization\n");
+fprintf(outf, " and unused variables\n");
+fprintf(outf, " 5/10/99 - JMW - Added AIB,ABU and MSE to mc hbond NH & O list\n");
+fprintf(outf, " and added HN to the list of aliases for H\n");
+fprintf(outf, " 7/12/99 - JMW - Begin changes for version 2\n");
+fprintf(outf, " 7/17/99 - JMW - Added support for autobondrot, display ref.\n");
+fprintf(outf, " 8/ 3/99 - JMW - Fixed typo in UpdateHydrogenInfo about bins\n");
+fprintf(outf, " 8/ 5/99 - JMW - Sort autobondrot atoms in residue order,\n");
+fprintf(outf, " add include file processing to autobondrot,\n");
+fprintf(outf, " add -notick and -kinemage probe options\n");
+fprintf(outf, " list process Nt/Ct/res for moving atoms\n");
+fprintf(outf, " 8/16/99 - JMW - Flag -kinemage forces kin format (for -auto)\n");
+fprintf(outf, " added CA-CB for gly in stdbonds for mutants\n");
+fprintf(outf, " 9/ 2/99 - JMW - Added stdbond info to support alternate name\n");
+fprintf(outf, " C5A for the methyl on a THY nucleic acid base\n");
+fprintf(outf, "10/ 5/99 - JMW - Dropped unused variables flagged by compiler\n");
+fprintf(outf, "12/ 6/99 - JMW - -OUT shows the contact surface area and the\n");
+fprintf(outf, " solvent accessible surface area\n");
+fprintf(outf, " -ADDVDW for radius offset(-SCALEVDW for scale)\n");
+fprintf(outf, " -OUTColor sets the point color for -OUT\n");
+fprintf(outf, "12/13/99 - JMW - added shortcuts: -SCSurface, -CONTACT,\n");
+fprintf(outf, " -SASurface, -ACCESS\n");
+fprintf(outf, "12/13/99 - JMW - renamed: -SASurface to -ASurface\n");
+fprintf(outf, " 1/ 3/00 - JMW - added names to surface shortcuts\n");
+fprintf(outf, " 1/13/00 - JMW - renamed: -CONTACT to -EXPOsed\n");
+fprintf(outf, " 1/14/00 - JMW - fixed TRANS keyword in autobondrot\n");
+fprintf(outf, " 5/ 4/00 - JMW - changed -u output to print spike coords and\n");
+fprintf(outf, " added -oldu flag to give the old output\n");
+fprintf(outf, " added -ignore flag to drop data from input\n");
+fprintf(outf, " 5/31/00 - JMW - Added modified bases used in tRNAs\n");
+fprintf(outf, " Included new properties TEST_ACCEPT_ANGLE and\n");
+fprintf(outf, " CH_DONOR\n");
+fprintf(outf, " 6/ 9/00 - JMW - constructed chain of residues view of atomlist\n");
+fprintf(outf, " in order to support ring normals\n");
+fprintf(outf, " 7/ 5/00 - JMW - inlined inRange for speed, remembered inosine,\n");
+fprintf(outf, " dropped dummy atoms, added -segid flag,\n");
+fprintf(outf, " fixed bug when water was used with -auto\n");
+fprintf(outf, " 7/27/00 - JMW - added code to free extra memory at end of run\n");
+fprintf(outf, "10/31/00 - JMW - added O2* & O2' to NABackbone list (oversite)\n");
+fprintf(outf, "11/ 6/00 - JMW - changed malloc.h and memory.h to stdlib.h\n");
+fprintf(outf, "11/14/00 - JMW - added -basecolor & -colorbase to color DNA/RNA\n");
+fprintf(outf, "11/19/00 - JMW - fixed naBase typo for 7MG and added -nofaceHB\n");
+fprintf(outf, "11/27/00 - JMW - updated properties of odd bases in select.c\n");
+fprintf(outf, "11/28/00 - JMW - added H2U to base class table and moved PSU\n");
+fprintf(outf, "12/01/00 - JMW - fixed H atomclass bug with -colorbase\n");
+fprintf(outf, " 2/14/01 - JMW - changed LowGoodCut from -0.2 to -0.4\n");
+fprintf(outf, " 7/11/01 - JMW - dots no longer broken out by element in .kin,\n");
+fprintf(outf, " added -element to generate old style output\n");
+fprintf(outf, " 7/25/01 - JMW - negative residue numbers in patterns\n");
+fprintf(outf, "10/ 1/01 - JMW - allow Nterminal fragnents to Hbond\n");
+fprintf(outf, "10/ 9/01 - JMW - take out Nterm code and make CHX HBs an option\n");
+fprintf(outf, " 1/23/03 - 2.09 - JMW - Run default now:-3 -mc -het -self \"altA ogt33\"\n");
+fprintf(outf, " was: -het -self \"altA\"\n");
+fprintf(outf, " Default for -ignore is now \"olt1\"\n");
+fprintf(outf, " Recognise insert codes like 123a, 2B-3, & insC\n");
+fprintf(outf, " Fixed bounding box water-H bug in autobondrot!\n");
+fprintf(outf, "10/14/03 - 2.10 - JMW - Fixed bug (found by Patrick Reardon) caused by\n");
+fprintf(outf, " filtering out non-target contacts too early \n");
+fprintf(outf, " Also made sure atoms in different models\n");
+fprintf(outf, " can not interact in any way.\n");
+fprintf(outf, " Also changed how alternate conformations in\n");
+fprintf(outf, " in different residues interact. Now altA and\n");
+fprintf(outf, " altB never see one another. Previously, they\n");
+fprintf(outf, " could if alts A and B weren't the same res.\n");
+fprintf(outf, " Added -minocc flag with a default of 0.02\n");
+fprintf(outf, " as the minimum non-zero occupancy.\n");
+fprintf(outf, " Added -changes flag to dump change log.\n");
+fprintf(outf, "Oct 2004: DCR code annotations, fixups, default modifiations\n");
+fprintf(outf, "10/07/04 - 2.10 dcr041007 now presumes atom named _SE_ is Selenium\n");
+fprintf(outf, " i.e. refmac or cns missadjusted name.\n");
+fprintf(outf, "halides flagged as negative ions and H-bond acceptors\n");
+fprintf(outf, "default: probe infile > outfile \n");
+fprintf(outf, "same as: probe -3 -mc -het -self \"altA ogt33\" infile > outfile \n");
+fprintf(outf, "try : probe -4H -mc -het -self \"altA ogt33\" infile > outfile \n");
+fprintf(outf,"dcr041009 pointmasters M==McMc, S==ScSc, O==Other(McSc,Het--)\n");
+fprintf(outf,"dcr041010 -onlybadout option for Bad clashes only\n");
+fprintf(outf,"dcr041017 default -4H, pointtmaster P==McSc, report counts\n");
+fprintf(outf,"dcr041020 master= {surface}, more work on count reports\n");
+fprintf(outf,"dcr041020 annotated (NOT implemented) writeHbonds JACKnANDREA\n");
+fprintf(outf,"dcr041023 2D array of count information\n");
+fprintf(outf,"dcr041026 NOT report count IntersectBothWays re probe update\n");
+fprintf(outf,"dcr041101 -summary colon deliminated multi-count report\n");
+fprintf(outf,"dcr041101 -oneline summary all on oneline\n");
+fprintf(outf,"dcr041101 -DEFAULTs same as: <<NO FLAGS>>, \n");
+fprintf(outf," but allows flags like -summary or -oneline\n");
+
+ /*jmw & dcr agreement of 041110 on version name and maintenance by dcr*/
+
+fprintf(outf,"2.11.041112 by agreement of 041110: maintained now by dcr\n");
+fprintf(outf,"041112 -nomodeltest for mage/probe (Lmodeltest) see 050121\n");
+fprintf(outf,"041114 more fussing with NMR models\n");
+fprintf(outf,"050111,17,18,19 flow, esp. autobondrot, annotations...\n");
+fprintf(outf,"050119 very low occ atoms have presence but not show contacts\n");
+fprintf(outf,"050121 remove -nomodeltest stuff, mage now sends model # \n");
+fprintf(outf,"060129 jEdit type fold-comments on each subroutine \n");
+fprintf(outf," single vdw contact button replaces both wide and small \n");
+fprintf(outf," -mastername flags extra master={name} (default: dots)\n");
+fprintf(outf,"060212 something about hets also marked prot,rna,dna... \n");
+fprintf(outf,"060831 -NOOCC atoms NOT filtered by occ value \n");
+fprintf(outf,"061018 not treat HIS as aromatic ACCEPTOR \n");
+fprintf(outf,"070801 rmi Updated for wwPDB remediation and PDB v3.0 \n");
+fprintf(outf,"070801 Recognizes both new and old heavy atom names \n");
+fprintf(outf," Recognizes both new and old residue names for DNA \n");
+fprintf(outf," Builds atom connectivity and is able to generate contact dots on \n");
+fprintf(outf," Xplor, PDBv2.3, PDBv3.0, or files with mixed format even within a \n");
+fprintf(outf," single residue \n");
+fprintf(outf,"070821 add strcasecmp to utility.c rwgk \n");
+fprintf(outf,"070905 add alternate names of thymine methyl \n");
+fprintf(outf,"070913 add detail on probe unformatted to help \n");
+fprintf(outf,"070913 fixed handling of mixed RNA files \n");
+fprintf(outf,"071010 added support for Hybrid36 atom and residue numbers \n");
+fprintf(outf,"071025 added support of Coot style RNA names \n");
+fprintf(outf,"071101 added support for two character chain names \n");
+fprintf(outf,"071107 added support for OT1 and OT2 as C-term carboxylate oxygens \n");
+fprintf(outf,"071128 bug fix in parsing of command line chainIds \n");
+fprintf(outf,"110413 bug fix onlybadout outputs only bo, not cc gjk\n");
+fprintf(outf,"110830 MacOSX10.6 GCC finicky re. no format string in \n");
+fprintf(outf," writeOutput function for color \n");
+fprintf(outf,"110909 changed the elseif portion of coloroutput to have no extra space \n");
+
+exit(0);
+
+}/*dump_changes()*/
+/*}}}dump_changes()__________________________________________________________*/
+
+/*{{{countsummary()***********************************************************/
+/*
+filename: mcmc wide: mcmc close : mcmc small : mcmc bad: mcmc h- bond:
+mcmc sum: scsc wide: scsc close: scsc small: scsc bad: scsc h-bond:
+scsc sum: mcsc wide: mcsc close: mcsc small: mcsc bad: mcsc h-bond:
+mcsc sum: other wide: other close: other small: other bad: other
+h-bond: other sum: wide sum: close sum: small sum: bad sum: h-bond
+sum:
+*/
+
+void countsummary(FILE *outf, char* modestr, int Lines, int Pass) /*dcr041101*/
+{
+ char message[200];
+ int N=0; /*index Number*/
+ int k=0;
+
+ if(Pass == 1 || Pass == 0) {N = 0;}
+ else {N = 1;}
+
+ summcont[N][0] = mcmccont[N][0]+scsccont[N][0]+mcsccont[N][0]+othrcont[N][0];
+ summcont[N][1] = mcmccont[N][1]+scsccont[N][1]+mcsccont[N][1]+othrcont[N][1];
+ summcont[N][2] = mcmccont[N][2]+scsccont[N][2]+mcsccont[N][2]+othrcont[N][2];
+ summcont[N][3] = mcmccont[N][3]+scsccont[N][3]+mcsccont[N][3]+othrcont[N][3];
+ summcont[N][4] = mcmccont[N][4]+scsccont[N][4]+mcsccont[N][4]+othrcont[N][4];
+ summcont[N][5] = mcmccont[N][5]+scsccont[N][5]+mcsccont[N][5]+othrcont[N][5];
+ /*where index 5 holds the running sum of items indexed 0-4 */
+ if(Pass == 0)
+ {/*expect another pass, so save these values, and clear arrays for next pass*/
+ for(k=0 ; k<=5 ; k++)
+ {/*copy values*/
+ mcmccont[1][k] = mcmccont[0][k];
+ scsccont[1][k] = scsccont[0][k];
+ mcsccont[1][k] = mcsccont[0][k];
+ othrcont[1][k] = othrcont[0][k];
+ summcont[1][k] = summcont[0][k];
+ }
+ for(k=0 ; k<=5 ; k++)
+ {/*clear arrays*/
+ mcmccont[0][k] = 0;
+ scsccont[0][k] = 0;
+ mcsccont[0][k] = 0;
+ othrcont[0][k] = 0;
+ summcont[0][k] = 0;
+ }
+ }
+ if(Pass == 2)
+ {/*should have been a previous pass with values saved*/
+ for(k=0 ; k<=5 ; k++)
+ {
+ mcmccont[0][k] = mcmccont[0][k] + mcmccont[1][k];
+ scsccont[0][k] = scsccont[0][k] + scsccont[1][k];
+ mcsccont[0][k] = mcsccont[0][k] + mcsccont[1][k];
+ othrcont[0][k] = othrcont[0][k] + othrcont[1][k];
+ summcont[0][k] = summcont[0][k] + summcont[1][k];
+ }
+ }
+
+ if(Pass == 1 || Pass == 2)
+ {/*output*/
+ if(Lines == 1) /*for accummulating oneliners for comparisons dcr041101*/
+ {
+ /*0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
+ fprintf(outf,": %s "
+ ":%9ld :%9ld :%9ld :%9ld :%9ld :%9ld "
+ ":%9ld :%9ld :%9ld :%9ld :%9ld :%9ld "
+ ":%9ld :%9ld :%9ld :%9ld :%9ld :%9ld "
+ ":%9ld :%9ld :%9ld :%9ld :%9ld :%9ld "
+ ":%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :\n"
+ ,inputfilename
+ ,mcmccont[0][0],mcmccont[0][1],mcmccont[0][2],mcmccont[0][3],mcmccont[0][4]
+ ,mcmccont[0][5]
+ ,scsccont[0][0],scsccont[0][1],scsccont[0][2],scsccont[0][3],scsccont[0][4]
+ ,scsccont[0][5]
+ ,mcsccont[0][0],mcsccont[0][1],mcsccont[0][2],mcsccont[0][3],mcsccont[0][4]
+ ,mcsccont[0][5]
+ ,othrcont[0][0],othrcont[0][1],othrcont[0][2],othrcont[0][3],othrcont[0][4]
+ ,othrcont[0][5]
+ ,summcont[0][0],summcont[0][1],summcont[0][2],summcont[0][3],summcont[0][4]
+ ,summcont[0][5]
+ );
+
+ }
+ else /*for kinemage*/
+ {
+ fprintf(outf,"@text\n");
+ fprintf(outf,"probe: %s\n",modestr);
+ fprintf(outf,"%s\n",inputfilename);
+ /*0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
+ fprintf(outf,":CONTACT: WIDE : CLOSE : SMALL : BAD : H-BOND : SUM :\n");
+ fprintf(outf,":MCMC :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :\n"
+ ,mcmccont[0][0],mcmccont[0][1],mcmccont[0][2],mcmccont[0][3],mcmccont[0][4]
+ ,mcmccont[0][5]);
+ fprintf(outf,":SCSC :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :\n"
+ ,scsccont[0][0],scsccont[0][1],scsccont[0][2],scsccont[0][3],scsccont[0][4]
+ ,scsccont[0][5]);
+ fprintf(outf,":MCSC :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :\n"
+ ,mcsccont[0][0],mcsccont[0][1],mcsccont[0][2],mcsccont[0][3],mcsccont[0][4]
+ ,mcsccont[0][5]);
+ fprintf(outf,":OTHER :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :\n"
+ ,othrcont[0][0],othrcont[0][1],othrcont[0][2],othrcont[0][3],othrcont[0][4]
+ ,othrcont[0][5]);
+ fprintf(outf,":SUM :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :\n"
+ ,summcont[0][0],summcont[0][1],summcont[0][2],summcont[0][3],summcont[0][4]
+ ,summcont[0][5]);
+ }
+
+ if (Verbose)
+ {
+ sprintf(message,"%s",inputfilename);
+ note(message);
+ /*0 wide contact,1 close contact,2 small overlap,3 bad overlap,4 H-bonds*/
+ sprintf(message,":CONTACT: WIDE : CLOSE : SMALL : BAD : H-BOND : SUM :");
+ note(message);
+ sprintf(message,":MCMC :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :"
+ ,mcmccont[0][0],mcmccont[0][1],mcmccont[0][2],mcmccont[0][3],mcmccont[0][4]
+ ,mcmccont[0][5]);
+ note(message);
+ sprintf(message,":SCSC :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :"
+ ,scsccont[0][0],scsccont[0][1],scsccont[0][2],scsccont[0][3],scsccont[0][4]
+ ,scsccont[0][5]);
+ note(message);
+ sprintf(message,":MCSC :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :"
+ ,mcsccont[0][0],mcsccont[0][1],mcsccont[0][2],mcsccont[0][3],mcsccont[0][4]
+ ,mcsccont[0][5]);
+ note(message);
+ sprintf(message,":OTHER :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :"
+ ,othrcont[0][0],othrcont[0][1],othrcont[0][2],othrcont[0][3],othrcont[0][4]
+ ,othrcont[0][5]);
+ note(message);
+ sprintf(message,":SUM :%9ld :%9ld :%9ld :%9ld :%9ld :%9ld :"
+ ,summcont[0][0],summcont[0][1],summcont[0][2],summcont[0][3],summcont[0][4]
+ ,summcont[0][5]);
+ note(message);
+ }
+ }/*output*/
+}
+/*}}}countsummary()__________________________________________________________*/
diff --git a/probe.h b/probe.h
new file mode 100644
index 0000000..3f06dc5
--- /dev/null
+++ b/probe.h
@@ -0,0 +1,224 @@
+/* name: probe.h */
+/* author: J. Michael Word */
+/* date written: 2/26/96 */
+/* modified: 10/18/96, 11/6/96 */
+/* purpose: compute intersecton surfaces */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef PROBE_H
+#define PROBE_H 1
+
+#include <stdio.h>
+#include "utility.h"
+#include "dots.h"
+#include "abin.h"
+#include "readPDBrecs.h"
+#include "select.h"
+#include "atomprops.h"
+#include "stdconntable.h"
+#include "autobondrot.h"
+
+/* number of dot categories */
+#define NODEWIDTH 5
+
+/* selection identifiers */
+#define SET1 1
+#define SET2 2
+#define IGNORE_FLAG 4
+
+/* mode types */
+#define EXTERNALSURFACE 0
+#define INTERSECTONCE 1
+#define INTERSECTBOTHWAYS 2
+#define SELFINTERSECT 3
+#define DUMPATOMCOUNT 4
+
+#define MCMCCHR 'M' /*dcr041017*/
+#define SCSCCHR 'S' /*dcr041017*/
+#define MCSCCHR 'P' /*dcr041017*/
+#define OTHERCHR 'O' /*dcr041017*/
+
+/* before output, dots are stored in dotNodes */
+typedef struct dotNode_t {
+ struct dotNode_t *next; /* link to next dot */
+ atom *a; /* dot's owner */
+ atom *t; /* dot's cause */
+ point3d loc; /* dot position */
+ point3d spike; /* end of spike */
+ int type; /* -1 bump, 0 touch, +1 H bond */
+ float gap; /* vdw-vdw distance */
+ char ptmaster; /* point master, kinemage output, (M for mc) dcr041009*/
+} dotNode;
+
+/* data structure used to determine if N and O are at chain ends */
+typedef struct {
+ atom *ambigN[8]; /* first residue's ambiguous N in this chain [0-3]*/
+ /* along with the last residue's Ns [4-7] */
+ atom *ambigO[8]; /* last residue's ambiguous Os in this chain [0-7] */
+ int res_mc_oxy_cnt; /* how many mainchain Oxygens on last res? */
+ int first, last; /* where do the chain ids break? */
+ int Ntmarkers, Ctmarkers; /* where were N and C term markers observed? */
+ int hisNHcount[4];
+} chainEndData_t;
+
+typedef struct { /* buffer to pass data to newMovingAtom */
+ int filenum;
+ FILE *inf;
+ int close; /* do we need to close the file */
+ pattern *srcPat;
+ pattern *targPat;
+ residue **reslstptr;
+ residue *scratchRes;
+} movingAtomBuildInfo;
+
+typedef struct { /* buffer to pass data to movingDoCommand */
+ int firstPass;
+ int keepUnselected;
+ FILE *outf;
+ int method;
+ atom *allMainAtoms;
+ atom *waterClones;
+ atomBins *abins;
+ pointSet *dots;
+ float probeRad;
+ float density;
+ float spikelen;
+ int countDots;
+ int rawOutput;
+ int drawSpike;
+ int sayGroup;
+ char* groupLabel;
+ int argc;
+ char **argv;
+ char *message;
+} movingCommandInfo;
+
+int mainProbeProc(int argc, char **argv, FILE *outf);
+void doCommand(FILE *outf, int method,
+ atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[], float probeRad, float density, float spikelen,
+ int countDots, int rawOutput, char* rawname, double scoreBias,
+ int drawSpike, int sayGroup, char* groupLabel,
+ int argc, char **argv, char message[]);
+void descrCommand(FILE *fp, char* hdr1, char* hdr2, int argc, char **argv);
+void loadDotSpheres(pointSet dots[], float density);
+void unloadDotSpheres(pointSet dots[]);
+atom* processCommandline(int argc, char **argv, int *method, region *bboxA,
+ float *density, float *probeRad,
+ int *drawSpike, float *spikelen, int *countDots,
+ int *keepUnselected,
+ char **srcArg, char **targArg, char **ignoreArg,
+ char **groupLabel, int *rawOutput, int *sayGroup,
+ int *addKinToFile, movingAtomBuildInfo *mabip,
+ residue **reslstptr);
+atom* loadAtoms(FILE *fp, atom *atomlist, region *boundingBox, int file,
+ residue **resDataLst);
+atomBins* binAtoms(atom* allAtoms, region *boundingBox, char serialNum,
+ float probeRad, int keepUnselected, int selflags);
+float getRadius(int at, int useCOScale);
+atom * newAtom(char *rec, int file, int model, residue* resDataBlk);
+int atomsClose(atom *a, atom *b, float probeRad);
+int inRange(point3d *p, point3d *q, float lim);
+float gapSize(point3d *p, point3d *q, float qrad);
+void selectSource(atom *allAtoms, pattern *sp, int srcFlag,
+ pattern *tp, int objFlag, pattern *ignorePat);
+atom* findTouchingAtoms(atom *src, atom *head, atomBins *bins, float probeRad, int flag,int *ok);
+
+void saveDot(atom *src, atom *targ, int type, point3d *loc, point3d *spike,
+ dotNode *results[][NODEWIDTH], int ovrlaptype, float mingap, char ptmaster);/*dcr041009*/
+dotNode * newDot(atom *src,atom *targ, point3d *loc, point3d *spike, int ovrlaptype, float gap, char ptmaster);/*dcr041009*/
+
+void examineDots(atom *src, int type, atom *scratch,
+ pointSet dots[], float probeRad, float spikelen,
+ int objFlag, dotNode *results[][NODEWIDTH]);
+void markBonds(atom *src, atom *neighbors, int distcount, int max);
+int dotType(atom *src, atom *atomList, int recalcOnly);
+void genDotIntersect(atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[],
+ float probeRad, float spikelen,
+ int srcFlag, int targFlg, dotNode *results[][NODEWIDTH]);
+void genDotSurface(atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[],
+ float probeRad, float spikelen, int srcFlag,
+ dotNode *results[][NODEWIDTH]);
+void surfDots(atom *src, int type, atom *scratch,
+ pointSet dots[], float probeRad,
+ float spikelen, dotNode *results[][NODEWIDTH]);
+void initResults(dotNode *results[][NODEWIDTH]);
+void freeResults(dotNode *results[][NODEWIDTH]);
+void writeOutput(FILE *outf, char *groupname, dotNode *results[][NODEWIDTH],
+ int drawSpike, int method, char *extramastername);
+ /*041020 method for better kinemage keywords*/
+ /*060129 extra master name controls original vs fitted dots*/
+void writeAltFmtO(FILE *outf, int showBegin, int showEnd,
+ char* groupname, dotNode *results[][NODEWIDTH], int drawSpike);
+void writeAltFmtXV(FILE *outf, int showBegin, int showEnd,
+ char* groupname, dotNode *results[][NODEWIDTH], int drawSpike);
+
+void writeRaw(FILE *outf, char *groupname, dotNode *results[][NODEWIDTH],
+ float rp, char*s, float);
+void enumerate(FILE *outf, char* groupname, dotNode *results[][NODEWIDTH],
+ float probeRad, int method,
+ int nsel, int spike, int outdots, int numSkinDots,
+ float density);
+void rawEnumerate(FILE *outf, char* groupname, dotNode *results[][NODEWIDTH],
+ int method, int nsel, int spike, int outdots, int numSkinDots,
+ float density, char *namestring, char *rawname, double scoreBias);
+int countSelected(atom *allAtoms, int srcFlag);
+int enumDotSkin(atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ pointSet dots[], int srcFlag);
+int countSkin(atom *src, atom *scratch, pointSet dots[]);
+atom* updateHydrogenInfo(FILE *outf, atom *allMainAtoms, atomBins *abins,
+ atom *allMovingAtoms, atomBins *bbins,
+ int selectedFlag, int mustSaveMainWater);
+int dotClassIndex(int t, float mingap);
+void fixupLongBondChains(atom *src, atom *neighbors, int cutoff);
+float dot2bullsEye(point3d *dot, atom *src, atom *targ);
+float dot2srcCenter(point3d *dot, atom *src, atom *targ);
+float kissEdge2bullsEye(float ra, float rb, float rp);
+char* assignGapColorForKin(float gap, int class);
+char* assignGapColorForO(float gap, int class);
+char* assignGapColorForXV(float gap, int class);
+char* convertKinColorToO(char* incolor);
+char* convertKinColorToXV(char* incolor);
+
+atom * newMovingAtom(char *rec, void* userdata);
+void deleteMovingAtom(atom *a, void*);
+void movingAtomListProcessing(atom *atomlst, void *userdata);
+void movingDoCommand(char* name, double scoreBias, atom *allMovingAtoms, void* userdata);
+
+void initEndData(chainEndData_t *ed);
+void hisNHcheck(chainEndData_t *ed, atom *atomlist, int rescnt);
+void resCheck(chainEndData_t *ed, atom *atomlist, int rescnt);
+void CtermCheck(chainEndData_t *ed, int rescnt, int isChainEnd);
+void noticedNt(chainEndData_t *ed, int rescnt);
+void noticedCt(chainEndData_t *ed, int rescnt);
+void NtermCheck(chainEndData_t *ed, int rescnt, int isChainEnd);
+void ProcessResInfo(chainEndData_t *ed, atom *a);
+
+
+ringInfo * newRingInfo(ringInfo **head, point3d* ctr, point3d* norm);
+void deleteRingInfoList(ringInfo *ri);
+residue * newResidueData();
+void deleteResidueData(residue *r);
+void disposeListOfResidues(residue *theRes);
+void deleteAtom(atom *a);
+void disposeListOfAtoms(atom *theAtom);
+int resDiffersFromPrev(residue *r1, residue *r2);
+void dumpRes(residue *theRes);
+void dump_changes(FILE *outf);
+void countsummary(FILE *outf, char* modestr, int Lines, int Pass); /*dcr041101*/
+#endif
diff --git a/readPDBrecs.c b/readPDBrecs.c
new file mode 100644
index 0000000..cd85152
--- /dev/null
+++ b/readPDBrecs.c
@@ -0,0 +1,228 @@
+/* name: readPDBrecs.c */
+/* author: J. Michael Word date written: 2/16/96 */
+/* purpose: read records in a pdb file */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <string.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include "hybrid_36_c.h"
+#include "readPDBrecs.h"
+
+char globPDBrec[PDBRECSIZE + 1];
+char globPDBrecLen = 0;
+
+char * getPDBrecord(FILE *inf) {
+ int rlen;
+
+ rlen = readRecord(inf, globPDBrec, PDBRECSIZE );
+ if (rlen < 0) {
+ globPDBrecLen = 0;
+ return NULL;
+ }
+ else {
+ globPDBrecLen = rlen;
+ return globPDBrec;
+ }
+}
+
+/* readRecord() - read characters until the end of the line */
+/* putting the first maxChars characters into */
+/* buffer and adding a trailing end-of-string.*/
+/* Returns the length of the buffer string. */
+int readRecord(FILE *inf, char buffer[], int maxChars) {
+ register int ch;
+ register int count = 0;
+ register int done = 0;
+ int makeUpperCase = 1;
+
+ if (!inf || feof(inf)) {
+ count = -1; /* signal end-of-file */
+ buffer[0] = '\0';
+ }
+ else {
+ while(!done) {
+ ch = getc(inf);
+ if ((ch == '@') || (ch == '#')) {
+ /* special codes turn off forced uppercase */
+ /* "at sign" used for commands */
+ /* "hash" used for comments */
+ makeUpperCase = 0;
+ }
+ if (makeUpperCase) {
+ ch = toupper(ch);
+ }
+ if ((ch == EOF) || (ch == '\n')) {
+ done = 1;
+ }
+ else if (ch == '\r') {
+ ch = getc(inf);
+ if (ch != '\n') { ungetc(ch, inf); }
+ done = 1;
+ }
+ else if (count < maxChars) {
+ buffer[count++] = ch;
+ }
+ /* otherwise we drop ch in the bit bucket */
+ }
+ buffer[count] = '\0';
+ }
+
+ return count;
+}
+
+/* isAtom() - basic validation for an atom record */
+/* must be long enough for 1 digit temp factor */
+int isAtom(char *line) {
+ if (line) {
+ return (strncmp(line, "ATOM", 4) == 0) && (strlen(line) >= 47);
+ }
+ else return 0;
+}
+
+/* isHet() - basic validation for an het record */
+int isHet(char *line) {
+ if (line) {
+ return (strncmp(line, "HETA", 4) == 0) && (strlen(line) >= 47);
+ }
+ else return 0;
+}
+
+int isPseudoAtom(char *line) {
+ if (line) {
+ return (line[13] == 'Q');
+ }
+ else return 0;
+}
+
+/* isTer() - is this a ter record? */
+int isTer(char *line) {
+ if (line) {
+ return (strncmp(line, "TER", 3) == 0) && (strlen(line) >= 27);
+ }
+ else return 0;
+}
+
+/* isModel() - is this a Model record? */
+int isModel(char *line) {
+ if (line) {
+ return (strncmp(line, "MODEL", 5) == 0) && (strlen(line) >= 14);
+ }
+ else return 0;
+}
+
+int parseModel(char *line) {
+
+ return parseInteger(line, 6, 8);
+}
+
+/*
+int parseAtomNumber(char *line) {
+
+ return parseInteger(line, 6, 5);
+}
+
+int parseResidueNumber(char *line) {
+
+ return parseInteger(line, 22, 4);
+}
+*/
+
+int parseAtomNumber(char *line) {
+ int atomno;
+ const char* errmsg = hy36decode(5, &line[6], 5, &atomno);
+/* if (errmsg) throw std::runtime_error(errmsg);
+ fprintf(stderr, "ATOM NUMBER %d\n", atomno); */
+
+ return atomno;
+}
+
+int parseResidueNumber(char *line) {
+ int resid;
+ const char* errmsg = hy36decode(4, &line[22], 4, &resid);
+/* if (errmsg) throw std::runtime_error(errmsg);
+ fprintf(stderr, "RESIDUE NUMBER %d\n", resid); */
+
+ return resid;
+}
+
+void parseResidueHy36Num(char *line, char Hy36resno[]) {
+ Hy36resno[0] = line[22];
+ Hy36resno[1] = line[23];
+ Hy36resno[2] = line[24];
+ Hy36resno[3] = line[25];
+ Hy36resno[4] = '\0';
+}
+
+void parseChain(char *line, char chain[]) {
+ chain[0] = line[20];
+ chain[1] = line[21];
+ chain[2] = '\0';
+}
+
+/* Now using two character chain ids
+char parseChain(char *line) {
+
+ return line[21];
+}
+*/
+
+float parseOccupancy(char *line) {
+
+ return nonblankrange(line, 54, 6) ? parseReal(line, 54, 6) : 1.0;
+}
+
+float parseTempFactor(char *line) {
+
+ return nonblankrange(line, 60, 6) ? parseReal(line, 60, 6) : 0.0;
+}
+
+char parseResidueInsertionCode(char *line) {
+
+ return line[26];
+}
+
+char parseAltLocCode(char *line) {
+
+ return line[16];
+}
+
+void parseResidueName(char *line, char name[]) {
+ name[0] = line[17];
+ name[1] = line[18];
+ name[2] = line[19];
+ name[3] = '\0';
+}
+
+void parseAtomName(char *line, char name[]) {
+ name[0] = line[12];
+ name[1] = line[13];
+ name[2] = line[14];
+ name[3] = line[15];
+ name[4] = '\0';
+}
+
+void parseXYZ(char *line, point3d *loc) {
+ loc->x = parseReal(line, 30, 8);
+ loc->y = parseReal(line, 38, 8);
+ loc->z = parseReal(line, 46, 8);
+}
+
+
+void parseSegID(char *line, char id[]) {
+ int reclen = strlen(line);
+ id[0] = (reclen >= 73) ? line[72] : ' ';
+ id[1] = (reclen >= 74) ? line[73] : ' ';
+ id[2] = (reclen >= 75) ? line[74] : ' ';
+ id[3] = (reclen >= 76) ? line[75] : ' ';
+ id[4] = '\0';
+}
diff --git a/readPDBrecs.h b/readPDBrecs.h
new file mode 100644
index 0000000..7eb5734
--- /dev/null
+++ b/readPDBrecs.h
@@ -0,0 +1,51 @@
+/* name: readPDBrecs.h */
+/* author: J. Michael Word date written: 2/16/96 */
+/* purpose: read records in a pdb file */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef READPDBRECS_H
+#define READPDBRECS_H 1
+
+#include <stdio.h>
+#include "utility.h"
+#include "geom3d.h"
+#include "hybrid_36_c.h"
+
+/* while parsing, the last rec is kept in globPDBrec */
+#define PDBRECSIZE 80
+extern char globPDBrec[];
+
+char * getPDBrecord(FILE *inf);
+int readRecord(FILE *inf, char buffer[], int maxChars);
+int isAtom(char *line);
+int isHet(char *line);
+int isPseudoAtom(char *line);
+int isTer(char *line);
+int isModel(char *line);
+int parseModel(char *line);
+/*int parseAtomNumber(char *line);
+int parseResidueNumber(char *line);*/
+int parseAtomNumber(char *line);
+int parseResidueNumber(char *line);
+void parseResidueHy36Num(char *line, char Hy36resno[]);
+void parseChain(char *line, char chain[]);
+/*char parseChain(char *line);*/
+float parseOccupancy(char *line);
+float parseTempFactor(char *line);
+char parseResidueInsertionCode(char *line);
+char parseAltLocCode(char *line);
+void parseResidueName(char *line, char name[]);
+void parseAtomName(char *line, char name[]);
+void parseXYZ(char *line, point3d *loc);
+void parseSegID(char *line, char id[]);
+#endif
+
diff --git a/select.c b/select.c
new file mode 100644
index 0000000..ec95f80
--- /dev/null
+++ b/select.c
@@ -0,0 +1,671 @@
+/*{{{select.c general comments */
+/* name: select.c */
+/* author: J. Michael Word */
+/* date written: 2/20/96 */
+/* purpose: parse atom selections */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+/*}}}select.c general comments */
+
+/*{{{--includes */
+#include <string.h> /*060902 needs this for strstr() */
+#include "select.h"
+#include "atomprops.h"
+#include "stdconntable.h"
+#include "utility.h"
+
+/*}}}--includes */
+
+/*{{{getPat() ****************************************************************/
+/*select.h includes parse.h, so why is getPat here instead of in parse.c ? */
+pattern* getPat(char *line, char *which, int verbose)
+{
+ pattern *pat;
+
+ if (!line) return NULL;
+
+ pat = parseArg(line); /* parse.c/parseArg() */
+
+ if (verbose && pat) {
+ fprintf(stderr, "%s: ", which);
+ printPattern(stderr, pat); /* parse.c/printPattern() */
+ }
+
+ return pat;
+}
+/*}}}getPat() _______________________________________________________________*/
+
+/*{{{declarations ... globals */
+
+/*{{{AromaticAtomsTbl[] ***/
+static ResidueAndAtomPair AromaticAtomsTbl[] = {
+":PHE:", ": HD1: HD2: HE1: HE2: HZ : DD1: DD2: DE1: DE2: DZ :", 0,
+":HIS:", ": HD1: HD2: HE1: HE2: DD1: DD2: DE1: DE2:", 0,
+":TYR:", ": HD1: HD2: HE1: HE2: DD1: DD2: DE1: DE2:", 0,
+":TRP:", ": HD1: HE1: HE3: HZ2: HZ3: HH2: DD1: DE1: DE3: DZ2: DZ3: DH2:", 0,
+": U:URA:UTP:UDP:UMP: UR:", ": H3 : HN3: H5 : H6 : D3 : DN3: D5 : D6 :", 0,
+": T:THY:TTP:TDP:TMP:5MU: DT: TR:", ": H3 : HN3: H6 : D3 : DN3: D6 :", 0,
+": A:ADE:ATP:ADP:AMP:1MA:RIA:T6A: DA: AR:", ": H8 : H2 : D8 : D2 :", 0,
+": C:CYT:CTP:CDP:CMP:5MC:OMC: DC: CR:", ": H5 : H6 : D5 : D6 :", 0,
+": G:GUA:GTP:GDP:GMP:GSP:2MG:M2G:7MG:OMG: DG: GR:",
+ ": H8 : H1 : HN1: D8 : D1 : DN1:", 0,
+": YG:1MG:", ": H8 : D8 :", 0,
+":PSU:", ": H6 : D6 : H1 : HN1: D1 : DN1: H3 : HN3: D3 : DN3:", 0,
+": I: DI:", ": H8 : H2 : H1 : HN1: D8 : D2 : D1 : DN1:", 0,
+":PHE:", ": CG : CD1: CD2: CE1: CE2: CZ :", TEST_ACCEPT_ANGLE_PROP,
+":HIS:", ": ND1: CD2: CE1: NE2: CG :", 0,
+":TYR:", ": CG : CD1: CD2: CE1: CE2: CZ :", TEST_ACCEPT_ANGLE_PROP,
+":TRP:", ": CG : CD1: CD2: NE1: CE2: CE3: CZ2: CZ3: CH2:", TEST_ACCEPT_ANGLE_PROP,
+": U:URA:UTP:UDP:UMP:PSU: UR:",
+ ": N1 : C2 : N3 : C4 : C5 : C6 :", TEST_ACCEPT_ANGLE_PROP,
+": T:THY:TTP:TDP:TMP:5MU: DT: TR:",
+ ": N1 : C2 : N3 : C4 : C5 : C6 :", TEST_ACCEPT_ANGLE_PROP,
+": A:ADE:ATP:ADP:AMP:1MA:RIA:T6A: I: DA: DI: AR:",
+ ": N1 : C2 : N3 : C4 : C5 : C6 : N7 : C8 : N9 :",TEST_ACCEPT_ANGLE_PROP,
+": C:CYT:CTP:CDP:CMP:5MC:OMC: DC: CR:",
+ ": N1 : C2 : N3 : C4 : C5 : C6 :", TEST_ACCEPT_ANGLE_PROP,
+": G:GUA:GTP:GDP:GMP:GSP:1MG:2MG:M2G:7MG:OMG: DG: GR:",
+ ": N1 : C2 : N3 : C4 : C5 : C6 : N7 : C8 : N9 :",TEST_ACCEPT_ANGLE_PROP,
+": YG:", ": N1 : C2 : N3 : C4 : C5 : C6 : N7 : C8 : N9 :\
+ : N2 : C11: C12:",TEST_ACCEPT_ANGLE_PROP,
+":HEM:", ": N A: C1A: C2A: C3A: C4A: N B: C1B: C2B: C3B: C4B:", TEST_ACCEPT_ANGLE_PROP,
+":HEM:", ": N C: C1C: C2C: C3C: C4C: N D: C1D: C2D: C3D: C4D:", TEST_ACCEPT_ANGLE_PROP,
+0, 0, 0};
+
+/*061018 not allow HIS to accept H-bonds as as aromatic ring system
+":HIS:", ": ND1: CD2: CE1: NE2: CG :", TEST_ACCEPT_ANGLE_PROP, */
+
+/*}}}AromaticAtomsTbl[] ___________________________________________*/
+/*{{{AAList ***/
+static char *AAList = ":GLY:ALA:VAL:PHE:PRO:MET:ILE:LEU:ASP:GLU:LYS:ARG:\
+SER:THR:TYR:HIS:CYS:ASN:GLN:TRP:ASX:GLX:ACE:FOR:NH2:NME:MSE:AIB:ABU:PCA:";
+/*}}}AAList */
+/*{{{HphobicAAList ***/
+static char *HphobicAAList = ":ALA:VAL:PHE:MET:ILE:LEU:TYR:CYS:TRP:MSE:AIB:ABU:";
+/*}}}HphobicAAList */
+/*{{{HphilicAAList ***/
+static char *HphilicAAList = ":SER:THR:ASN:GLN:";
+/*}}}HphilicAAList */
+/*{{{AromaticAAList ***/
+static char *AromaticAAList = ":PHE:HIS:TYR:TRP:HEM:";
+/*}}}AromaticAAList */
+/*{{{NAList ***/
+static char *NAList = ": C: G: A: T: U:CYT:GUA:ADE:THY:URA:\
+CTP:CDP:CMP:GTP:GDP:GMP:ATP:ADP:AMP:TTP:TDP:TMP:UTP:UDP:UMP:\
+GSP:H2U:PSU:1MG:2MG:M2G:7MG:5MC:5MU:T6A:1MA:RIA:\
+OMC:OMG: YG: I: DA: DT: DC: DG: DI: AR: UR: TR: GR: CR:";
+/*}}}NAList */
+/*{{{NAbackboneList ***/
+static char *NAbackboneList = ": P : O1P: O2P: OP1: OP2: PA : PB : PG :\
+: O1A: O2A: O3A: O1B: O2B: O3B: O1G: O2G: O3G: S1G:\
+: O5*: C5*: C4*: O4*: C3*: O3*: C2*: O2*: C1*:\
+: O5': C5': C4': O4': C3': O3': C2': O2': C1':\
+: H1*: H1': H3*: H3': H4*: H4':1H5*:\
+:2H5*:*H51:*H52:H5'': H5':1H2*:2H2*:\
+: H2*:H2'':2HO*:*HO2: H2': H3T: H5T:\
+:3HO*:HO3':*HO3:5HO*:*HO5:HO5':";
+/*}}}NAbackboneList */
+/*{{{NAbaseGrouping[] **/
+/* used to treat similar nucleic acid bases similarly */
+static ResidueAndAtomPair NAbaseGrouping[] = {
+": U:URA:UTP:UDP:UMP: UR: T:THY:TTP:TDP:TMP:5MU: DT: TR:", "", baseTU,
+": A:ADE:ATP:ADP:AMP:1MA:RIA:T6A: DA: AR:", "", baseA,
+": C:CYT:CTP:CDP:CMP:5MC:OMC: DC: CR:", "", baseC,
+": G:GUA:GTP:GDP:GMP:GSP:1MG:2MG:M2G:7MG:OMG: DG: GR:", "", baseG,
+": I: YG:H2U:PSU: DI:", "", baseOther,
+0, 0, 0};
+/*}}}NAbaseGrouping[] */
+/*{{{MethylResList ***/
+/* for identifying methyl groups */
+static char *MethylResList =
+":THR:ALA:MET:LEU:VAL:ILE: T:THY: DT:AIB:ABU:ACE:MSE:NME:HEM:\
+ :OMG:OMC:1MA:1MG:2MG:M2G:5MU:5MC:7MG: YG:T6A:";
+ /*}}}MethylResList */
+ /*{{{MethylAtomsTbl[] ***/
+static ResidueAndAtomPair MethylAtomsTbl[] = { /* including xplor names */
+":THR:", ": CG2:1HG2:2HG2:3HG2:HG21:HG22:HG23:", 0,
+":ALA:", ": CB :1HB :2HB :3HB : HB1: HB2: HB3:", 0,
+":MET:", ": CE :1HE :2HE :3HE : HE1: HE2: HE3:", 0,
+":LEU:", ": CD1:1HD1:2HD1:3HD1:HD11:HD12:HD13:\
+ : CD2:1HD2:2HD2:3HD2:HD21:HD22:HD23:", 0,
+":VAL:", ": CG1:1HG1:2HG1:3HG1:HG11:HG12:HG13:\
+ : CG2:1HG2:2HG2:3HG2:HG21:HG22:HG23:", 0,
+":ILE:", ": CG2:1HG2:2HG2:3HG2:HG21:HG22:HG23:\
+ : CD1:1HD1:2HD1:3HD1:HD11:HD12:HD13:", 0,
+": T:", ": C5M:1H5M:2H5M:3H5M:H5M1:H5M2:H5M3:", 0,
+":THY:", ": C5A:1H5 :2H5 :3H5 : H51: H52: H53:", 0,
+": DT:", ": C7 : H71: H72: H73:", 0,
+":AIB:", ": CB1:1HB1:2HB1:3HB1:HB11:HB12:HB13:\
+ : CB2:1HB2:2HB2:3HB2:HB21:HB22:HB23:", 0,
+":ABU:", ": CG :1HG :2HG :3HG : HG1: HG2: HG3:", 0,
+":ACE:", ": CH3:1HH3:2HH3:3HH3:HH31:HH32:HH33:", 0,
+":MSE:", ": CE :1HE :2HE :3HE : HE1: HE2: HE3:", 0,
+":NME:", ": CH3:1HH3:2HH3:3HH3:HH31:HH32:HH33:", 0,
+":HEM:", ": CMA:1HMA:2HMA:3HMA:HMA1:HMA2:HMA3:\
+ : CMB:1HMB:2HMB:3HMB:HMB1:HMB2:HMB3:\
+ : CMC:1HMC:2HMC:3HMC:HMC1:HMC2:HMC3:\
+ : CMD:1HMD:2HMD:3HMD:HMD1:HMD2:HMD3:", 0,
+
+":OMG:OMC:",
+ ": CM2:1HM2:2HM2:3HM2:HM22:HM22:HM23:", 0,
+":1MA:1MG:",
+ ": CM1:1HM1:2HM1:3HM1:HM12:HM12:HM13: C1A:1H1A:2H1A:3H1A:", 0,
+":2MG:M2G:", ": CM1:1HM1:2HM1:3HM1:HM12:HM12:HM13: C1A:1H1A:2H1A:3H1A:\
+ : CM2:1HM2:2HM2:3HM2:HM22:HM22:HM23: C2A:1H2A:2H2A:3H2A:", 0,
+":5MU:5MC:",
+ ": CM5:1HM5:2HM5:3HM5:HM52:HM52:HM53: C5A:1H5A:2H5A:3H5A:", 0,
+":7MG:", ": CM7:1HM7:2HM7:3HM7:HM72:HM72:HM73: C7A:1H7A:2H7A:3H7A:", 0,
+": YG:", ": C3 :1H3 :2H3 :3H3 : H32: H32: H33:\
+ : C10:1H10:2H10:3H10:H102:H102:H103:\
+ : C19:1H19:2H19:3H19:H192:H192:H193:\
+ : C24:1H24:2H24:3H24:H242:H242:H243:", 0,
+":T6A:", ": C15:1H15:2H15:3H15:H152:H152:H153:", 0,
+0, 0, 0};
+/*}}}MethylAtomsTbl[] */
+/*{{{ChargedAAList ***/
+/* for computing charge state (currently treating HIS as charged) */
+static char *ChargedAAList = ":ASP:GLU:LYS:ARG:HIS:HEM:";
+/*}}}ChargedAAList */
+/*{{{ChargedAAAtomsTbl[] ***/
+static ResidueAndAtomPair ChargedAAAtomsTbl[] = {
+":ASP:", ": OD1: OD2:", NEGATIVE_PROP,
+":GLU:", ": OE1: OE2:", NEGATIVE_PROP,
+":LYS:", ":1HZ :2HZ :3HZ :1DZ :2DZ :3DZ : NZ :\
+ : HZ1: HZ2: HZ3: DZ1: DZ2: DZ3:", POSITIVE_PROP,
+":ARG:", ": HE :1HH1:2HH1:1HH2:2HH2:\
+ : DE :1DH1:2DH1:1DH2:2DH2: NE : NH1: NH2:\
+ :HH11:HH12:HH21:HH22:\
+ :DH11:DH12:DH21:DH22:", POSITIVE_PROP,
+":HIS:", ": HD1: HE2: DD1: DE2: ND1: NE2:\
+ : CG : CD2: CE1:", POSITIVE_PROP,
+":HEM:", ": O1A: O2A: O1D: O2D:", NEGATIVE_PROP,
+0, 0, 0};
+/*}}}ChargedAAAtomsTbl[] */
+/*{{{AlwaysChargedAtomsList ***/
+static char *AlwaysChargedAtomsList =
+":1H :2H :3H :1D :2D :3D : HT1: HT2: HT3: DT1: DT2: DT3:\
+ : NT : OXT:1OXT:2OXT:";
+ /*}}}AlwaysChargedAtomsList */
+ /*{{{AmbigChargedAtomsList ***/
+static char *AmbigChargedAtomsList = ": O : N :";
+/*}}}AmbigChargedAtomsList */
+/*{{{ChargedNucAcidAtomsList ***/
+static char *ChargedNucAcidAtomsList = ": P : O1P: O2P:\
+ PA : PB : PG : O1A: O2A: O3A: O1B: O2B: O3B: O1G: O2G: O3G:\
+ S1G:";
+ /*}}}ChargedNucAcidAtomsList */
+ /*{{{WaterList ***/
+static char *WaterList = ":HOH:DOD:H2O:D2O:WAT:TIP:SOL:MTO:";
+/*}}}WaterList */
+/*{{{DonorAcceptorAtomTbl[] ***/
+static ResidueAndAtomPair DonorAcceptorAtomTbl[] = {
+":GLY:ALA:VAL:PHE:PRO:MET:ILE:LEU:ASP:GLU:LYS:ARG:\
+ :SER:THR:TYR:HIS:CYS:ASN:GLN:TRP:ASX:GLX:NH2:NME:MSE:AIB:ABU:PCA:",
+ ": N : NT : H : HT1: HT2: HT3:1H :2H :3H :\
+ : HN : D : DT1: DT2: DT3:1D :2D :3D :",
+ DONOR_PROP,
+
+":GLY:ALA:VAL:PHE:PRO:MET:ILE:LEU:ASP:GLU:LYS:ARG:\
+ :SER:THR:TYR:HIS:CYS:ASN:GLN:TRP:ASX:GLX:ACE:FOR:MSE:AIB:ABU:PCA:",
+ ": O : OXT:1OXT:2OXT:", ACCEPTOR_PROP,
+
+":ASN:ASX:", ": AD1: AD2:", DONOR_PROP|ACCEPTOR_PROP,
+":ASN:ASX:", ":1HD1:2HD1:HD11:HD12:\
+ :1DD1:2DD1:DD11:DD12:", DONOR_PROP, /* if ass backwards */
+":GLN:GLX:", ": AE1: AE2:", DONOR_PROP|ACCEPTOR_PROP,
+":GLN:GLX:", ":1HE1:2HE1:HE11:HE12:\
+ :1DE1:2DE1:DE11:DE12:", DONOR_PROP, /* if ass backwards */
+
+":ASN:", ": OD1:", ACCEPTOR_PROP,
+":ASN:", ": ND2:1HD2:2HD2:HD21:HD22:\
+ :1DD2:2DD2:DD21:DD22:", DONOR_PROP,
+":GLN:", ": OE1:", ACCEPTOR_PROP,
+":GLN:", ": NE2:1HE2:2HE2:HE21:HE22:\
+ :1DE2:2DE2:DE21:DE22:", DONOR_PROP,
+
+":ASP:", ": OD1: OD2:", ACCEPTOR_PROP,
+":GLU:", ": OE1: OE2:", ACCEPTOR_PROP,
+":LYS:", ": NZ :1HZ :2HZ :3HZ : HZ1: HZ2: HZ3:\
+ :1DZ :2DZ :3DZ : DZ1: DZ2: DZ3:",
+ DONOR_PROP,
+":ARG:", ": NE : NH1: NH2:\
+ : HE :1HH1:2HH1:1HH2:2HH2:HH11:HH12:HH21:HH22:\
+ : DE :1DH1:2DH1:1DH2:2DH2:DH11:DH12:DH21:DH22:",
+ DONOR_PROP,
+
+":HIS:", ": ND1: NE2:", DONOR_PROP|ACCEPTOR_PROP,
+":HIS:", ": HD1: HE2: DD1: DE2:", DONOR_PROP,
+":HIS:", ": HD2: HE1: DD2: DE1:", DONOR_PROP|CH_DONOR_PROP,
+":SER:", ": OG :", DONOR_PROP|ACCEPTOR_PROP,
+":SER:", ": HG : DG :", DONOR_PROP,
+":THR:", ": OG1:", DONOR_PROP|ACCEPTOR_PROP,
+":THR:", ": HG1: DG1:", DONOR_PROP,
+":TYR:", ": OH :", DONOR_PROP|ACCEPTOR_PROP,
+":TYR:", ": HH : DH :", DONOR_PROP,
+":CYS:", ": SG :", ACCEPTOR_PROP, /* usually */
+":CYS:", ": HG : DG :", DONOR_PROP,
+":TRP:", ": NE1: HE1: DE1:", DONOR_PROP,
+":MET:", ": SD :", ACCEPTOR_PROP,
+":MSE:", ":SED :", ACCEPTOR_PROP,
+":NH2:", ": HN1: HN2:1HN :2HN : DN1: DN2:1DN :2DN :", DONOR_PROP,
+
+": C: G: A: T: U:CYT:GUA:ADE:THY:URA:\
+ :CTP:CDP:CMP:GTP:GDP:GMP:ATP:ADP:AMP:TTP:TDP:TMP:UTP:UDP:UMP:GSP:\
+ :H2U:PSU:1MG:2MG:M2G:5MC:5MU:T6A:1MA: YG: I: DA: DT: DC: DG: DI: AR: UR: TR: CR: GR:",
+ ": O2*: O2':", DONOR_PROP|ACCEPTOR_PROP,
+": C: G: A: T: U:CYT:GUA:ADE:THY:URA:\
+ :CTP:CDP:CMP:GTP:GDP:GMP:ATP:ADP:AMP:TTP:TDP:TMP:UTP:UDP:UMP:GSP:\
+ :H2U:PSU:1MG:2MG:M2G:5MC:5MU:T6A:1MA:RIA:OMC:OMG: YG: I: DA: DT: DC: DG: DI: AR: UR: TR: CR: GR:",
+ ":2HO*:3HO*:5HO*: H3T: H5T:HO3':HO5':\
+ :2DO*:3DO*:5DO*: D3T: D5T:DO3':DO5':",
+/* ":2HO*:3HO*:5HO*: H2': H3': H5': H3T: H5T:HO3':HO5':\ RMI removed H2', H3' and H5' 070723 */
+/* :2DO*:3DO*:5DO*: D2': D3': D5': D3T: D5T:DO3':DO5':", */
+ DONOR_PROP,
+": C: G: A: T: U:CYT:GUA:ADE:THY:URA:\
+ :CTP:CDP:CMP:GTP:GDP:GMP:ATP:ADP:AMP:TTP:TDP:TMP:UTP:UDP:UMP:GSP:\
+ :H2U:PSU:1MG:2MG:M2G:5MC:5MU:T6A:1MA:RIA:OMC:OMG: YG: I: DA: DT: DC: DG: DI: AR: UR: TR: CR: GR:",
+ ": O1P: O2P: OP1: OP2: O1A: O2A: O3A: O1B: O2B: O3B: O1G: O2G: O3G: S1G:\
+ : O3*: O5*: O3': O5':", ACCEPTOR_PROP,
+
+": U:URA:UTP:UDP:UMP:H2U: DU: UR:",": N3 : H3 : HN3: D3 : DN3:",DONOR_PROP,
+":PSU:", ": N1 : H1 : D1 : HN1: DN1:\
+ : N3 : H3 : D3 : HN3: DN3:", DONOR_PROP,
+": U:URA:UTP:UDP:UMP:H2U:PSU: DU: UR:", ": O2 : O4 :", ACCEPTOR_PROP,
+": T:THY:TTP:TDP:TMP:5MU: DT: TR:",": N3 : H3 : HN3: D3 : DN3:",DONOR_PROP,
+": T:THY:TTP:TDP:TMP:5MU: DT: TR:", ": O2 : O4 :", ACCEPTOR_PROP,
+": A:ADE:ATP:ADP:AMP:1MA:RIA: DA: AR:",
+ ": N6 :1H6 :2H6 : H61: H62:1HN6:2HN6:\
+ :1D6 :2D6 : D61: D62:1DN6:2DN6:", DONOR_PROP,
+": A:ADE:ATP:ADP:AMP:RIA: DA: AR:", ": N1 : N3 : N7 :", ACCEPTOR_PROP,
+ ":1MA: I: DI:", ": N3 : N7 :", ACCEPTOR_PROP,
+
+":T6A:", ": N6 : HN6: DN6: N11: HN1: DN1: H14: D14:\
+ : H11: D11: HO4: DO4:", DONOR_PROP,
+":T6A:", ": N1 : N3 : N7 : O10:AO13:BO13: O14:", ACCEPTOR_PROP,
+
+": C:CYT:CTP:CDP:CMP:OMC:5MC: DC: CR:",
+ ": N4 :1H4 :2H4 : H41: H42:1HN4:2HN4:\
+ :1D4 :2D4 : D41: D42:1DN4:2DN4:", DONOR_PROP,
+": C:CYT:CTP:CDP:CMP:OMC:5MC: DC: CR:", ": O2 : N3 :", ACCEPTOR_PROP,
+": G:GUA:GTP:GDP:GMP:GSP:OMG:7MG: DG: GR:",
+ ": N1 : N2 : H1 :1H2 :2H2 : H21: H22: HN1:1HN2:2HN2:\
+ : D1 :1D2 :2D2 : D21: D22: DN1:1DN2:2DN2:",DONOR_PROP,
+":2MG:", ": N1 : N2 : H1 : H2 : HN1: HN2:\
+ : D1 : D2 : DN1: DN2:", DONOR_PROP,
+": G:GUA:GTP:GDP:GMP:GSP:OMG:1MG:2MG:M2G: DG: GR:",
+ ": O6 : N3 : N7 :", ACCEPTOR_PROP,
+": YG:", ": O6 : N2 : N7 : O17: O17: O22: O23:", ACCEPTOR_PROP,
+
+":1MG:", ": N2 :1H2 :2H2 : H21: H22:1HN2:2HN2:\
+ :1D2 :2D2 : D21: D22:1DN2:2DN2:", DONOR_PROP,
+":M2G:", ": N1 : H1 : HN1: D1 : DN1:", DONOR_PROP,
+":7MG:", ": O6 : N3 :", ACCEPTOR_PROP,
+
+": A:ADE:ATP:ADP:AMP:1MA:RIA:T6A: I: DA: DI: AR:", ": H2 : H8 :", DONOR_PROP|CH_DONOR_PROP,
+": G:GUA:GTP:GDP:GMP:GSP:OMG:1MG:2MG:M2G:7MG: YG: DG: GR:", ": H8 :", DONOR_PROP|CH_DONOR_PROP,
+
+#ifdef EXPLICIT_WATER_ATOM_NAMES
+":HOH:DOD:H2O:D2O:WAT:TIP:SOL:MTO:", ": O : OH2: OD2: OW :", DONOR_PROP|ACCEPTOR_PROP,
+":HOH:DOD:H2O:D2O:WAT:TIP:SOL:MTO:",
+ ": H : H1 : H2 :1H :2H : D : D1 : D2 :1D :2D : H? :", DONOR_PROP,
+#endif
+
+/* also, the aromatic heavy atoms are considered H bond acceptors (see setAromaticProp) */
+
+0, 0, 0};
+/*}}}DonorAcceptorAtomTbl[] */
+/*}}}declarations */
+
+/*{{{naBaseCategory() ********************************************************/
+/* used to assign a category to atoms to allow coloring */
+/* dots by base rather than atom type */
+/* naBaseCategory() must be called after setProperties() */
+
+int naBaseCategory(atom *a) {
+ ResidueAndAtomPair *pair;
+
+ if ((a->props & DNA_PROP) && (a->props & SC_PROP)) {
+ if(strstr(NAList, a->r->resname)) {
+ for (pair = NAbaseGrouping; pair->rlist; pair++){
+ if(strstr(pair->rlist, a->r->resname)) {
+ return pair->bits; /* bits contain the atom type */
+ }
+ }
+ return baseOther; /* not in table */
+ }
+ else return baseOther; /* not in list */
+ }
+ else return nonBase; /* backbone or not recognized as a nucleic acid */
+}
+/*}}}naBaseCategory() _______________________________________________________*/
+
+/*{{{setAromaticProp() *******************************************************/
+/* hunt for aromatic atoms and set AROMATIC property & atomHarom */
+
+void setAromaticProp(atom *a) {
+ ResidueAndAtomPair *pair;
+
+ if((strstr(AromaticAAList, a->r->resname))
+ || (strstr(NAList, a->r->resname))) {
+ for (pair = AromaticAtomsTbl; pair->rlist && pair->alist; pair++){
+ if((strstr(pair->rlist, a->r->resname))
+ && (strstr(pair->alist, a->atomname))) {
+ a->props |= AROMATIC_PROP;
+ a->props |= pair->bits; /* selectively set TEST_ACCEPT_ANGLE prop */
+ if(isHatom(a->elem)) { a->elem = atomHarom; }
+ break;
+ }
+ }
+ }
+}
+/*}}}setAromaticProp() ______________________________________________________*/
+
+/*{{{setMethylProp() *********************************************************/
+/* hunt for Methyl atoms and set METHYL property */
+
+void setMethylProp(atom *a) {
+ ResidueAndAtomPair *pair;
+
+ if(strstr(MethylResList, a->r->resname)) {
+ for (pair = MethylAtomsTbl; pair->rlist && pair->alist; pair++){
+ if((strstr(pair->rlist, a->r->resname))
+ && (strstr(pair->alist, a->atomname))) {
+ a->props |= METHYL_PROP;
+ break;
+ }
+ }
+ }
+}
+/*}}}setMethylProp()_________________________________________________________*/
+
+/*{{{isCarbonylAtom() ********************************************************/
+int isCarbonylAtom(atom *a) { /* limitation: this will not handle het groups properly */
+ return (strstr(AAList, a->r->resname) && (!strcmp(a->atomname, " C ")))
+ ||((strstr(":ASP:ASN:ASX:",a->r->resname))&&(strstr(": CG :",a->atomname)))
+ ||((strstr(":GLU:GLN:GLX:",a->r->resname))&&(strstr(": CD :",a->atomname)));
+}
+/*}}}isCarbonylAtom() _______________________________________________________*/
+
+/*{{{setProperties() *********************************************************/
+/* set property flags for this atom and return T/F as an indicator */
+/* that this atom is important in figuring out if N and O atoms */
+/* are in the N or C terminus */
+/* later functions can look through a list of these atoms to see if */
+/* atoms marked MAYBECHG_PROP are in a terminal residue */
+
+/*060212 Properties as specified in current pdb-format files, */
+/*are not logically complete. HETATM records and residue names that are*/
+/*known valid protein or nucleic acid names can occur both in regions that */
+/*are protein/nucleic chain and regions that are het-chains */
+/* The only way to beat this is to accummulate evidence of the type of */
+/*region as atoms are read in, then set a new and different flag for region*/
+
+void setProperties(atom *a, int hetflag, int hb2aromaticFace, int chohb) {
+ char *s;
+ ResidueAndAtomPair *pair;
+ int addCharge = FALSE, checkTerminal = FALSE;
+
+ a->props = 0;
+
+ setAromaticProp(a);
+ setMethylProp(a);
+
+ if (strstr(WaterList, a->r->resname)) {
+ a->props |= WATER_PROP;
+ }
+ else if(hetflag) { /* non water hets */
+ if (! strstr(":MSE:", a->r->resname)) {
+ /* SelenoMet is not a HET for our purposes here */
+
+ a->props |= HET_PROP;
+ }
+ }
+
+ if(strstr(AAList, a->r->resname)) { /* proteins and peptides */
+ a->props |= PROT_PROP;
+ if(strstr(HphobicAAList, a->r->resname)){a->props |= RHPHOBIC_PROP;}
+ else if(strstr(HphilicAAList, a->r->resname)){a->props |= RHPHILIC_PROP;}
+ else if(strstr(ChargedAAList, a->r->resname)){a->props |= RCHARGED_PROP;}
+ s = a->atomname;
+ if (a->elem == atomC || isHatom(a->elem)) {
+ if (s[2] == 'A') {
+ if (!strcmp(s, "2HA ")){ a->props |= ALPHA_PROP; }
+ else { a->props |= ALPHA_PROP|MC_PROP; }
+ }
+ else if (s[2] == 'B') { a->props |= BETA_PROP; }
+ else if (!strcmp(s, " C ")) { a->props |= MC_PROP; }
+ else if (!strcmp(s+1, "H ")) { a->props |= MC_PROP; }
+ else if (!strcmp(s+1, "D ")) { a->props |= MC_PROP; }
+ else if (strstr(": HXT: DXT: HN :", s)){ a->props|= MC_PROP; }
+ }
+ else if (!strcmp(s, " N ")) { a->props |= MC_PROP; }
+ else if (!strcmp(s, " O ")) { a->props |= MC_PROP; }
+
+ else if (strstr(AlwaysChargedAtomsList, s)) { a->props |= MC_PROP; }
+
+ if (!(a->props & MC_PROP)) { a->props |= SC_PROP;}
+ }
+ else if(strstr(NAList, a->r->resname)) { /* DNA and RNA */
+ a->props |= DNA_PROP;
+ if (strstr(NAbackboneList, a->atomname)) { a->props |= MC_PROP; }
+ else { a->props |= SC_PROP;}
+ }
+ switch(a->elem) {
+ case atomN: a->props |= N_PROP; break;
+ case atomC: a->props |= C_PROP; break;
+ case atomO: a->props |= O_PROP; break;
+ case atomS: a->props |= S_PROP; break;
+ case atomP: a->props |= P_PROP; break;
+ }
+
+ if (isHatom(a->elem)) { a->props |= H_PROP; }
+
+ if (atomHasProp(a->elem, METALIC_ATOM_FLAG)) { a->props |= METAL_PROP; }
+ if (atomHasProp(a->elem, IONIC_ATOM_FLAG)) { a->props |= ION_PROP; }/*dcr041007*/
+
+/* HBond Donor/Acceptor status */
+ if (hb2aromaticFace
+ && (a->props & TEST_ACCEPT_ANGLE_PROP)) { a->props |= ACCEPTOR_PROP; }
+
+ if (a->props & WATER_PROP) { /* water O or H */
+ if (a->elem == atomO) { a->props |= DONOR_PROP|ACCEPTOR_PROP; }
+ else if (isHatom(a->elem)) { a->props |= DONOR_PROP; }
+ }
+ else if ((a->elem == atomN)||(a->elem == atomO)||(a->elem == atomS)||isHatom(a->elem)){
+ if((strstr(AAList, a->r->resname))
+ || (strstr(NAList, a->r->resname))
+ || (strstr(WaterList, a->r->resname))) {
+ for (pair = DonorAcceptorAtomTbl; pair->rlist && pair->alist; pair++){
+ if((strstr(pair->rlist, a->r->resname))
+ && (strstr(pair->alist, a->atomname))) {
+
+ if ((! chohb) && (pair->bits & CH_DONOR_PROP)) {
+ /* do nothing --- not doing CH..O type hbonds */
+ }
+ else { /* we generally fall in this category */
+ a->props |= pair->bits; /* set donor/acceptor properties */
+ }
+ break;
+ }
+ }
+ if ( !( isHatom(a->elem) ||
+ (a->props & (ACCEPTOR_PROP|DONOR_PROP)) ) ) {
+ a->props |= ACCEPTOR_PROP; /* default for N,O,S */
+ }
+ }
+ else if (!isHatom(a->elem)){/* mostly handles het groups we are unsure about */
+ a->props |= DONOR_PROP|ACCEPTOR_PROP;
+ }
+ }
+/* note: final H atom DONOR assignment done later in updateHydrogenInfo() */
+/* but the above code will set (for selections) most HB donor hydrogens */
+
+ /* determining charge state of atoms */
+ addCharge = FALSE;
+ checkTerminal = FALSE;
+ if (a->props & PROT_PROP) {
+ if(strstr(AmbigChargedAtomsList, a->atomname)) {
+ if (!strcmp(a->atomname, " N ")) { /* *** N+ must be first residue *** */
+ a->props |= MAYBECHG_PROP;
+ }
+ else if (!strcmp(a->atomname, " O ")) { /* *** O- must be last residue *** */
+ a->props |= MAYBECHG_PROP;
+ checkTerminal = TRUE; /* O used to indicate end of chain */
+ }
+ }
+ else if(strstr(AlwaysChargedAtomsList, a->atomname)) {
+ addCharge = TRUE;
+ checkTerminal = TRUE; /* 1H,2H,3H or OXT indicate end of chain */
+ }
+ else if (strstr(ChargedAAList, a->r->resname)) {
+ for (pair = ChargedAAAtomsTbl; pair->rlist && pair->alist; pair++){
+ if((strstr(pair->rlist, a->r->resname))
+ && (strstr(pair->alist, a->atomname))) {
+ /* addCharge = TRUE; */
+
+ a->props |= pair->bits;
+ break;
+ }
+ }
+ }
+ }
+ else if ((a->props & DNA_PROP)
+ && (strstr(ChargedNucAcidAtomsList, a->atomname))) {
+ addCharge = TRUE;
+ }
+ else if (a->props & METAL_PROP) { addCharge = TRUE; }
+ else if (a->props & ION_PROP) { addCharge = TRUE; } /*dcr041007*/
+
+ if(addCharge) {
+ if (a->props & METAL_PROP) { a->props |= POSITIVE_PROP; }
+ else if (a->props & H_PROP) { a->props |= POSITIVE_PROP; }
+ else {
+ switch(a->elem) {
+ case atomN: a->props |= POSITIVE_PROP; break;
+ case atomO: a->props |= NEGATIVE_PROP; break;
+ case atomS: a->props |= NEGATIVE_PROP; break;
+ case atomP: a->props |= NEGATIVE_PROP; break;
+ /*dcr041007 should O,S,Se be allowed to be acceptors ???? */
+ /*dcr041007 halides get (NEGATIVE_PROP|ACCEPTOR_PROP) */
+ case atomF: a->props |= (NEGATIVE_PROP|ACCEPTOR_PROP); break;
+ case atomCl: a->props |= (NEGATIVE_PROP|ACCEPTOR_PROP); break;
+ case atomBr: a->props |= (NEGATIVE_PROP|ACCEPTOR_PROP); break;
+ case atomI: a->props |= (NEGATIVE_PROP|ACCEPTOR_PROP); break;
+ /*dcr041007 halides only need ACCEPTOR_PROP to not clash with polar H*/
+ }
+ }
+ }
+
+ if (checkTerminal) {
+ /* now we have to fixup some of the MAYBECHG_PROP atoms elsewhere */
+ a->props |= CHECK_ENDS_PROP; /* these atoms will help us do that */
+ }
+
+}/*setProperties*/
+/*}}}setProperties() ________________________________________________________*/
+
+/*{{{matchPat() ************* only called from probe.c/selectSource() ********/
+/* recursive at OR,AND,NOT nodes; TRUE,FALSE nodes allow those logic choices*/
+int matchPat(atom *a, pattern *pat)
+{
+ int lp, rc = FALSE;
+
+ if (pat)
+ {
+ switch(pat->type)
+ {
+ case OR_NODE: rc = matchPat(a, pat->lhs) ?
+ TRUE : matchPat(a, pat->rhs); break;
+ case AND_NODE: rc = matchPat(a, pat->lhs) ?
+ matchPat(a, pat->rhs) : FALSE; break;
+ case NOT_NODE: rc = !matchPat(a, pat->lhs); break;
+ case FILE_NODE: rc = (a->r->file == pat->val); break;
+ case MODEL_NODE: rc = (a->r->model == pat->val); break;
+ case CHAIN_NODE: lp = strlen(lexString(pat->val));
+ rc = (strncmp(lexString(pat->val), a->r->chain, lp)
+ == 0); break;
+ case ALT_NODE: rc = (a->altConf == ' ' || a->altConf == pat->val); break;
+ case RES_NODE: rc = (a->r->resid == pat->val); break;
+ case RANGE_NODE: rc = (pat->lhs->val <= a->r->resid
+ && a->r->resid <= pat->rhs->val); break;
+ case RTYPE_NODE: lp = strlen(lexString(pat->val));
+ rc = (strncmp(lexString(pat->val), a->r->resname, lp)
+ == 0); break;
+ case DIST_NODE: rc = atomWithinDistance(a, pat->fvec); break;
+ case PROP_NODE: rc = (a->props & pat->val); break;
+ case ANAME_NODE: lp = strlen(lexString(pat->val));
+ rc = (strncmp(lexString(pat->val), a->atomname, lp)
+ == 0); break;
+ case SEGID_NODE: lp = strlen(lexString(pat->val));
+ rc = (strncmp(lexString(pat->val), a->r->segid, lp)
+ == 0); break;
+ case TRUE_NODE: rc = TRUE; break;
+ case FALSE_NODE: rc = FALSE; break;
+ case OCC_LT_NODE: rc = (a->occ < pat->val/100.0); break;
+ case OCC_GT_NODE: rc = (a->occ > pat->val/100.0); break;
+ case B_LT_NODE: rc = (a->bval < pat->val); break;
+ case B_GT_NODE: rc = (a->bval > pat->val); break;
+ case INS_NODE: rc = (a->r->resInsCode == pat->val); break;
+
+ /* ignores the insertion code */
+ case INS_RANGE_NODE: rc = (((pat->lhs->val == AND_NODE)
+ ? pat->lhs->lhs->val
+ : pat->lhs->val)
+ <= a->r->resid
+ && a->r->resid <=
+ ((pat->rhs->val == AND_NODE)
+ ? pat->rhs->lhs->val
+ : pat->rhs->val));
+ break;
+ default: { char msg[100];
+ sprintf(msg, "unknown pattern type: %d", pat->type);
+ halt(msg);
+ }
+ }/*switch*/
+ }
+ return rc;
+}
+/*}}}matchPat() _____________________________________________________________*/
+
+/*{{{atomWithinDistance() ****************************************************/
+/* is the atom within the specified distance from the given point? */
+int atomWithinDistance(atom *a, float *fvec) {
+ double dx = a->loc.x - fvec[1];
+ double dy = a->loc.y - fvec[2];
+ double dz = a->loc.z - fvec[3];
+ return ((dx*dx)+(dy*dy)+(dz*dz)) < (fvec[0]*fvec[0]);
+}
+/*}}}atomWithinDistance() ___________________________________________________*/
+
+/*{{{setHydrogenParentName() *************************************************/
+/* Set the parent atom name for a hydrogen */
+/* if can be determined from the hydrogen name.*/
+/* These parent names are used when a hydrogen */
+/* has more than one parent close enough to */
+/* bond. No such bonding table is currently */
+/* setup for non-hydrogens. */
+char * setHydrogenParentName(char *rname, char *aname) {
+
+ return searchForStdBondingPartner(rname, aname, TRUE);
+}
+/*}}}setHydrogenParentName() ________________________________________________*/
+
+/*{{{setMainchainBonding() ***************************************************/
+/* For heavy atoms, set the name of atoms which would bond with */
+/* in standard residues. */
+/* This is used only when the -STDBOND flag */
+/* is on the command line (UseStdBond == TRUE). */
+
+char * setMainchainBonding(char *rname, char *aname) {
+
+ return searchForStdBondingPartner(rname, aname, FALSE);
+}
+/*}}}setMainchainBonding() __________________________________________________*/
diff --git a/select.h b/select.h
new file mode 100644
index 0000000..ff15c47
--- /dev/null
+++ b/select.h
@@ -0,0 +1,35 @@
+/* name: select.h */
+/* author: J. Michael Word */
+/* date written: 2/20/96 */
+/* purpose: parse atom selections */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef SELECT_H
+#define SELECT_H 1
+
+#include "abin.h"
+#include "parse.h"
+
+typedef struct {char * rlist; char * alist; int bits;} ResidueAndAtomPair;
+
+pattern* getPat(char *line, char *which, int verbose);
+void setProperties(atom *a, int hetflag, int hb2aromaticFace, int chohb);
+int matchPat(atom *a, pattern *pat);
+void setAromaticProp(atom *a);
+void setMethylProp(atom *a);
+int isCarbonylAtom(atom *a);
+int atomWithinDistance(atom *a, float *fvec);
+char * setHydrogenParentName(char *rname, char *aname);
+char * setMainchainBonding(char *rname, char *aname);
+
+int naBaseCategory(atom *a);
+#endif
diff --git a/stdconntable.c b/stdconntable.c
new file mode 100644
index 0000000..0a29f35
--- /dev/null
+++ b/stdconntable.c
@@ -0,0 +1,2811 @@
+/* name: stdconntable.c */
+/* author: J. Michael Word Date Written: 11/15/98 */
+/* purpose: describes the bonding connectivies for */
+/* each std amino acid residue or */
+/* nucleic acid base */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "stdconntable.h"
+
+/* the hash modulus M must be prime */
+#define M 2617
+
+typedef struct _StdResConnTableEntry {
+ char *key;
+ char *value;
+ struct _StdResConnTableEntry *next;
+} StdResConnTableEntry_t;
+
+int HashInStdResTbl(char *s);
+int InsertInStdResConnTable(StdResConnTableEntry_t *e);
+char *SearchStdResConnTable(char *key);
+
+static StdResConnTableEntry_t *StdResTblBucket[M] = {NULL};
+
+/* For each of the standard amino acids and bases, we */
+/* list the parent atom for each hydrogen in the table */
+/* below. We want this table to be as general as */
+/* possible so where alternative names are commonly */
+/* employed for an H atom, we list each of them. Where */
+/* the parent atom name has several forms, we list */
+/* each of them separated by a colon */
+/* Farther down the table is the connectivity for the */
+/* non hydrogens in each standard residue or base. */
+
+static StdResConnTableEntry_t StandardResAtomConnRec[] = {
+
+/* fix for problem with output of truncated H names from O */
+#define ALLOW_TRUNCATED_H_NAMES 1
+
+/*---------------------------------------*/
+{"ALA: H ", " N : NT ", NULL},
+{"ALA: HN ", " N : NT ", NULL},
+{"ALA:1H ", " N : NT ", NULL},
+{"ALA:2H ", " N : NT ", NULL},
+{"ALA:3H ", " N : NT ", NULL},
+{"ALA: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"ALA: H2 ", " N : NT ", NULL}, /* */
+{"ALA: H3 ", " N : NT ", NULL}, /* */
+{"ALA: HT1", " N : NT ", NULL},
+{"ALA: HT2", " N : NT ", NULL},
+{"ALA: HT3", " N : NT ", NULL},
+{"ALA: HA ", " CA ", NULL},
+{"ALA:1HB ", " CB ", NULL},
+{"ALA:2HB ", " CB ", NULL},
+{"ALA:3HB ", " CB ", NULL},
+{"ALA: HB1", " CB ", NULL},
+{"ALA: HB2", " CB ", NULL},
+{"ALA: HB3", " CB ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"ALA: HT ", " N : NT ", NULL},
+{"ALA: HB ", " CB ", NULL},
+#endif
+
+{"CYS: H ", " N : NT ", NULL},
+{"CYS: HN ", " N : NT ", NULL},
+{"CYS:1H ", " N : NT ", NULL},
+{"CYS:2H ", " N : NT ", NULL},
+{"CYS:3H ", " N : NT ", NULL},
+{"CYS: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"CYS: H2 ", " N : NT ", NULL}, /* */
+{"CYS: H3 ", " N : NT ", NULL}, /* */
+{"CYS: HT1", " N : NT ", NULL},
+{"CYS: HT2", " N : NT ", NULL},
+{"CYS: HT3", " N : NT ", NULL},
+{"CYS: HA ", " CA ", NULL},
+{"CYS:1HB ", " CB ", NULL},
+{"CYS:2HB ", " CB ", NULL},
+{"CYS: HB1", " CB ", NULL},
+{"CYS: HB2", " CB ", NULL},
+/* {"CYS: HB2", " CB ", NULL},*/ /* remediated names RMI 070718 */
+{"CYS: HB3", " CB ", NULL}, /* */
+{"CYS: HG ", " SG ", NULL}, /* check for SH2 ? reduce has HG2 and HG3... */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"CYS: HT ", " N : NT ", NULL},
+{"CYS: HB ", " CB ", NULL},
+#endif
+
+{"ASP: H ", " N : NT ", NULL},
+{"ASP: HN ", " N : NT ", NULL},
+{"ASP:1H ", " N : NT ", NULL},
+{"ASP:2H ", " N : NT ", NULL},
+{"ASP:3H ", " N : NT ", NULL},
+{"ASP: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"ASP: H2 ", " N : NT ", NULL}, /* */
+{"ASP: H3 ", " N : NT ", NULL}, /* */
+{"ASP: HT1", " N : NT ", NULL},
+{"ASP: HT2", " N : NT ", NULL},
+{"ASP: HT3", " N : NT ", NULL},
+{"ASP: HA ", " CA ", NULL},
+{"ASP:1HB ", " CB ", NULL},
+{"ASP:2HB ", " CB ", NULL},
+{"ASP: HB1", " CB ", NULL},
+{"ASP: HB2", " CB ", NULL},
+/* {"ASP: HB2", " CB ", NULL},*/ /* remediated names RMI 070718 */
+{"ASP: HB3", " CB ", NULL}, /* */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"ASP: HT ", " N : NT ", NULL},
+{"ASP: HB ", " CB ", NULL},
+#endif
+
+{"GLU: H ", " N : NT ", NULL},
+{"GLU: HN ", " N : NT ", NULL},
+{"GLU:1H ", " N : NT ", NULL},
+{"GLU:2H ", " N : NT ", NULL},
+{"GLU:3H ", " N : NT ", NULL},
+{"GLU: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"GLU: H2 ", " N : NT ", NULL}, /* */
+{"GLU: H3 ", " N : NT ", NULL}, /* */
+{"GLU: HT1", " N : NT ", NULL},
+{"GLU: HT2", " N : NT ", NULL},
+{"GLU: HT3", " N : NT ", NULL},
+{"GLU: HA ", " CA ", NULL},
+{"GLU:1HB ", " CB ", NULL},
+{"GLU:2HB ", " CB ", NULL},
+{"GLU: HB1", " CB ", NULL},
+{"GLU: HB2", " CB ", NULL},
+/* {"GLU: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"GLU: HB3", " CB ", NULL}, /* */
+{"GLU:1HG ", " CG ", NULL},
+{"GLU:2HG ", " CG ", NULL},
+{"GLU: HG1", " CG ", NULL},
+{"GLU: HG2", " CG ", NULL},
+/* {"GLU: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"GLU: HG3", " CG ", NULL}, /* */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"GLU: HT ", " N : NT ", NULL},
+{"GLU: HB ", " CB ", NULL},
+{"GLU: HG ", " CG ", NULL},
+#endif
+
+{"PHE: H ", " N : NT ", NULL},
+{"PHE: HN ", " N : NT ", NULL},
+{"PHE:1H ", " N : NT ", NULL},
+{"PHE:2H ", " N : NT ", NULL},
+{"PHE:3H ", " N : NT ", NULL},
+{"PHE: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"PHE: H2 ", " N : NT ", NULL}, /* */
+{"PHE: H3 ", " N : NT ", NULL}, /* */
+{"PHE: HT1", " N : NT ", NULL},
+{"PHE: HT2", " N : NT ", NULL},
+{"PHE: HT3", " N : NT ", NULL},
+{"PHE: HA ", " CA ", NULL},
+{"PHE:1HB ", " CB ", NULL},
+{"PHE:2HB ", " CB ", NULL},
+{"PHE: HB1", " CB ", NULL},
+{"PHE: HB2", " CB ", NULL},
+/* {"PHE: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"PHE: HB3", " CB ", NULL}, /* */
+{"PHE: HD1", " CD1", NULL},
+{"PHE: HD2", " CD2", NULL},
+{"PHE: HE1", " CE1", NULL},
+{"PHE: HE2", " CE2", NULL},
+{"PHE: HZ ", " CZ ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"PHE: HT ", " N : NT ", NULL},
+{"PHE: HB ", " CB ", NULL},
+{"PHE: HD ", " CD1: CD2", NULL},
+{"PHE: HE ", " CE1: CE2", NULL},
+#endif
+
+{"GLY: H ", " N : NT ", NULL},
+{"GLY: HN ", " N : NT ", NULL},
+{"GLY:1H ", " N : NT ", NULL},
+{"GLY:2H ", " N : NT ", NULL},
+{"GLY:3H ", " N : NT ", NULL},
+{"GLY: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"GLY: H2 ", " N : NT ", NULL}, /* */
+{"GLY: H3 ", " N : NT ", NULL}, /* */
+{"GLY: HT1", " N : NT ", NULL},
+{"GLY: HT2", " N : NT ", NULL},
+{"GLY: HT3", " N : NT ", NULL},
+{"GLY:1HA ", " CA ", NULL},
+{"GLY:2HA ", " CA ", NULL},
+{"GLY: HA1", " CA ", NULL},
+{"GLY: HA2", " CA ", NULL},
+/* {"GLY: HA2", " CA ", NULL}, */ /* remediated names RMI 070718 */
+{"GLY: HA3", " CA ", NULL}, /* */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"GLY: HT ", " N : NT ", NULL},
+{"GLY: HA ", " CA ", NULL},
+#endif
+
+{"HIS: H ", " N : NT ", NULL},
+{"HIS: HN ", " N : NT ", NULL},
+{"HIS:1H ", " N : NT ", NULL},
+{"HIS:2H ", " N : NT ", NULL},
+{"HIS:3H ", " N : NT ", NULL},
+{"HIS: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"HIS: H2 ", " N : NT ", NULL}, /* */
+{"HIS: H3 ", " N : NT ", NULL}, /* */
+{"HIS: HT1", " N : NT ", NULL},
+{"HIS: HT2", " N : NT ", NULL},
+{"HIS: HT3", " N : NT ", NULL},
+{"HIS: HA ", " CA ", NULL},
+{"HIS:1HB ", " CB ", NULL},
+{"HIS:2HB ", " CB ", NULL},
+{"HIS: HB1", " CB ", NULL},
+{"HIS: HB2", " CB ", NULL},
+/* {"HIS: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"HIS: HB3", " CB ", NULL}, /* */
+{"HIS: HD1", " ND1", NULL},
+{"HIS: HD2", " CD2", NULL},
+{"HIS: HE1", " CE1", NULL},
+{"HIS: HE2", " NE2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"HIS: HT ", " N : NT ", NULL},
+{"HIS: HB ", " CB ", NULL},
+{"HIS: HD ", " ND1: CD2", NULL},
+{"HIS: HE ", " CE1: NE2", NULL},
+#endif
+
+{"ILE: H ", " N : NT ", NULL},
+{"ILE: HN ", " N : NT ", NULL},
+{"ILE:1H ", " N : NT ", NULL},
+{"ILE:2H ", " N : NT ", NULL},
+{"ILE:3H ", " N : NT ", NULL},
+{"ILE: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"ILE: H2 ", " N : NT ", NULL}, /* */
+{"ILE: H3 ", " N : NT ", NULL}, /* */
+{"ILE: HT1", " N : NT ", NULL},
+{"ILE: HT2", " N : NT ", NULL},
+{"ILE: HT3", " N : NT ", NULL},
+{"ILE: HA ", " CA ", NULL},
+{"ILE: HB ", " CB ", NULL},
+{"ILE:1HG1", " CG1", NULL},
+{"ILE:2HG1", " CG1", NULL},
+{"ILE:HG11", " CG1", NULL},
+{"ILE:HG12", " CG1", NULL},
+{"ILE:1HG2", " CG2", NULL},
+{"ILE:2HG2", " CG2", NULL},
+{"ILE:3HG2", " CG2", NULL},
+{"ILE:HG21", " CG2", NULL},
+{"ILE:HG22", " CG2", NULL},
+{"ILE:HG23", " CG2", NULL},
+{"ILE:1HD1", " CD1", NULL},
+{"ILE:2HD1", " CD1", NULL},
+{"ILE:3HD1", " CD1", NULL},
+{"ILE:HD11", " CD1", NULL},
+{"ILE:HD12", " CD1", NULL},
+{"ILE:HD13", " CD1", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"ILE: HT ", " N : NT ", NULL},
+{"ILE:1HG ", " CG1: CG2", NULL},
+{"ILE:2HG ", " CG1: CG2", NULL},
+{"ILE:3HG ", " CG2", NULL},
+{"ILE:HG1 ", " CG1", NULL},
+{"ILE:HG2 ", " CG2", NULL},
+{"ILE:1HD ", " CD1", NULL},
+{"ILE:2HD ", " CD1", NULL},
+{"ILE:3HD ", " CD1", NULL},
+{"ILE:HD1 ", " CD1", NULL},
+#endif
+
+{"LYS: H ", " N : NT ", NULL},
+{"LYS: HN ", " N : NT ", NULL},
+{"LYS:1H ", " N : NT ", NULL},
+{"LYS:2H ", " N : NT ", NULL},
+{"LYS:3H ", " N : NT ", NULL},
+{"LYS: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"LYS: H2 ", " N : NT ", NULL}, /* */
+{"LYS: H3 ", " N : NT ", NULL}, /* */
+{"LYS: HT1", " N : NT ", NULL},
+{"LYS: HT2", " N : NT ", NULL},
+{"LYS: HT3", " N : NT ", NULL},
+{"LYS: HA ", " CA ", NULL},
+{"LYS:1HB ", " CB ", NULL},
+{"LYS:2HB ", " CB ", NULL},
+{"LYS: HB1", " CB ", NULL},
+{"LYS: HB2", " CB ", NULL},
+/* {"LYS: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"LYS: HB3", " CB ", NULL}, /* */
+{"LYS:1HG ", " CG ", NULL},
+{"LYS:2HG ", " CG ", NULL},
+{"LYS: HG1", " CG ", NULL},
+{"LYS: HG2", " CG ", NULL},
+/* {"LYS: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"LYS: HG3", " CG ", NULL}, /* */
+{"LYS:1HD ", " CD ", NULL},
+{"LYS:2HD ", " CD ", NULL},
+{"LYS: HD1", " CD ", NULL},
+{"LYS: HD2", " CD ", NULL},
+/* {"LYS: HD2", " CD ", NULL}, */ /* remediated names RMI 070718 */
+{"LYS: HD3", " CD ", NULL}, /* */
+{"LYS:1HE ", " CE ", NULL},
+{"LYS:2HE ", " CE ", NULL},
+{"LYS: HE1", " CE ", NULL},
+{"LYS: HE2", " CE ", NULL},
+/* {"LYS: HE2", " CE ", NULL}, */ /* remediated names RMI 070718 */
+{"LYS: HE3", " CE ", NULL}, /* */
+{"LYS:1HZ ", " NZ ", NULL},
+{"LYS:2HZ ", " NZ ", NULL},
+{"LYS:3HZ ", " NZ ", NULL},
+{"LYS: HZ1", " NZ ", NULL},
+{"LYS: HZ2", " NZ ", NULL},
+{"LYS: HZ3", " NZ ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"LYS: HT ", " N : NT ", NULL},
+{"LYS: HB ", " CB ", NULL},
+{"LYS: HG ", " CG ", NULL},
+{"LYS: HD ", " CD ", NULL},
+{"LYS: HE ", " CE ", NULL},
+{"LYS: HZ ", " NZ ", NULL},
+#endif
+
+{"LEU: H ", " N : NT ", NULL},
+{"LEU: HN ", " N : NT ", NULL},
+{"LEU:1H ", " N : NT ", NULL},
+{"LEU:2H ", " N : NT ", NULL},
+{"LEU:3H ", " N : NT ", NULL},
+{"LEU: HT1", " N : NT ", NULL},
+{"LEU: HT2", " N : NT ", NULL},
+{"LEU: HT3", " N : NT ", NULL},
+{"LEU: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"LEU: H2 ", " N : NT ", NULL}, /* */
+{"LEU: H3 ", " N : NT ", NULL}, /* */
+{"LEU: HA ", " CA ", NULL},
+{"LEU:1HB ", " CB ", NULL},
+{"LEU:2HB ", " CB ", NULL},
+{"LEU: HB1", " CB ", NULL},
+{"LEU: HB2", " CB ", NULL},
+/* {"LEU: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"LEU: HB3", " CB ", NULL}, /* */
+{"LEU: HG ", " CG ", NULL},
+{"LEU:1HD1", " CD1", NULL},
+{"LEU:2HD1", " CD1", NULL},
+{"LEU:3HD1", " CD1", NULL},
+{"LEU:HD11", " CD1", NULL},
+{"LEU:HD12", " CD1", NULL},
+{"LEU:HD13", " CD1", NULL},
+{"LEU:1HD2", " CD2", NULL},
+{"LEU:2HD2", " CD2", NULL},
+{"LEU:3HD2", " CD2", NULL},
+{"LEU:HD21", " CD2", NULL},
+{"LEU:HD22", " CD2", NULL},
+{"LEU:HD23", " CD2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"LEU: HT ", " N : NT ", NULL},
+{"LEU: HB ", " CB ", NULL},
+{"LEU:1HD ", " CD1: CD2", NULL},
+{"LEU:2HD ", " CD1: CD2", NULL},
+{"LEU:3HD ", " CD1: CD2", NULL},
+{"LEU:HD1 ", " CD1", NULL},
+{"LEU:HD2 ", " CD2", NULL},
+#endif
+
+{"MET: H ", " N : NT ", NULL},
+{"MET: HN ", " N : NT ", NULL},
+{"MET:1H ", " N : NT ", NULL},
+{"MET:2H ", " N : NT ", NULL},
+{"MET:3H ", " N : NT ", NULL},
+{"MET: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"MET: H2 ", " N : NT ", NULL}, /* */
+{"MET: H3 ", " N : NT ", NULL}, /* */
+{"MET: HT1", " N : NT ", NULL},
+{"MET: HT2", " N : NT ", NULL},
+{"MET: HT3", " N : NT ", NULL},
+{"MET: HA ", " CA ", NULL},
+{"MET:1HB ", " CB ", NULL},
+{"MET:2HB ", " CB ", NULL},
+{"MET: HB1", " CB ", NULL},
+{"MET: HB2", " CB ", NULL},
+/* {"MET: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"MET: HB3", " CB ", NULL}, /* */
+{"MET:1HG ", " CG ", NULL},
+{"MET:2HG ", " CG ", NULL},
+{"MET: HG1", " CG ", NULL},
+{"MET: HG2", " CG ", NULL},
+/* {"MET: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"MET: HG3", " CG ", NULL}, /* */
+{"MET:1HE ", " CE ", NULL},
+{"MET:2HE ", " CE ", NULL},
+{"MET:3HE ", " CE ", NULL},
+{"MET: HE1", " CE ", NULL},
+{"MET: HE2", " CE ", NULL},
+{"MET: HE3", " CE ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"MET: HT ", " N : NT ", NULL},
+{"MET: HB ", " CB ", NULL},
+{"MET: HG ", " CG ", NULL},
+{"MET: HE ", " CE ", NULL},
+#endif
+
+{"ASN: H ", " N : NT ", NULL},
+{"ASN: HN ", " N : NT ", NULL},
+{"ASN:1H ", " N : NT ", NULL},
+{"ASN:2H ", " N : NT ", NULL},
+{"ASN:3H ", " N : NT ", NULL},
+{"ASN: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"ASN: H2 ", " N : NT ", NULL}, /* */
+{"ASN: H3 ", " N : NT ", NULL}, /* */
+{"ASN: HT1", " N : NT ", NULL},
+{"ASN: HT2", " N : NT ", NULL},
+{"ASN: HT3", " N : NT ", NULL},
+{"ASN: HA ", " CA ", NULL},
+{"ASN:1HB ", " CB ", NULL},
+{"ASN:2HB ", " CB ", NULL},
+{"ASN: HB1", " CB ", NULL},
+{"ASN: HB2", " CB ", NULL},
+/* {"ASN: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"ASN: HB3", " CB ", NULL}, /* */
+{"ASN:1HD2", " ND2", NULL},
+{"ASN:2HD2", " ND2", NULL},
+{"ASN:HD21", " ND2", NULL},
+{"ASN:HD22", " ND2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"ASN: HT ", " N : NT ", NULL},
+{"ASN: HB ", " CB ", NULL},
+{"ASN:1HD ", " ND2", NULL},
+{"ASN:2HD ", " ND2", NULL},
+{"ASN:HD2 ", " ND2", NULL},
+#endif
+
+{"PRO:1H ", " N : NT ", NULL},
+{"PRO:2H ", " N : NT ", NULL},
+{"PRO: HT1", " N : NT ", NULL},
+{"PRO: HT2", " N : NT ", NULL},
+{"PRO: HA ", " CA ", NULL},
+{"PRO:1HB ", " CB ", NULL},
+{"PRO:2HB ", " CB ", NULL},
+{"PRO: HB1", " CB ", NULL},
+{"PRO: HB2", " CB ", NULL},
+/* {"PRO: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"PRO: HB3", " CB ", NULL}, /* */
+{"PRO:1HG ", " CG ", NULL},
+{"PRO:2HG ", " CG ", NULL},
+{"PRO: HG1", " CG ", NULL},
+{"PRO: HG2", " CG ", NULL},
+/* {"PRO: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"PRO: HG3", " CG ", NULL}, /* */
+{"PRO:1HD ", " CD ", NULL},
+{"PRO:2HD ", " CD ", NULL},
+{"PRO: HD1", " CD ", NULL},
+{"PRO: HD2", " CD ", NULL},
+/* {"PRO: HD2", " CD ", NULL}, */ /* remediated names RMI 070718 */
+{"PRO: HD3", " CD ", NULL}, /* */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"PRO: HT ", " N : NT ", NULL},
+{"PRO: HB ", " CB ", NULL},
+{"PRO: HG ", " CG ", NULL},
+{"PRO: HD ", " CD ", NULL},
+#endif
+
+{"GLN: H ", " N : NT ", NULL},
+{"GLN: HN ", " N : NT ", NULL},
+{"GLN:1H ", " N : NT ", NULL},
+{"GLN:2H ", " N : NT ", NULL},
+{"GLN:3H ", " N : NT ", NULL},
+{"GLN: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"GLN: H2 ", " N : NT ", NULL}, /* */
+{"GLN: H3 ", " N : NT ", NULL}, /* */
+{"GLN: HT1", " N : NT ", NULL},
+{"GLN: HT2", " N : NT ", NULL},
+{"GLN: HT3", " N : NT ", NULL},
+{"GLN: HA ", " CA ", NULL},
+{"GLN:1HB ", " CB ", NULL},
+{"GLN:2HB ", " CB ", NULL},
+{"GLN: HB1", " CB ", NULL},
+{"GLN: HB2", " CB ", NULL},
+/* {"GLN: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"GLN: HB3", " CB ", NULL}, /* */
+{"GLN:1HG ", " CG ", NULL},
+{"GLN:2HG ", " CG ", NULL},
+{"GLN: HG1", " CG ", NULL},
+{"GLN: HG2", " CG ", NULL},
+/* {"GLN: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"GLN: HG3", " CG ", NULL}, /* */
+{"GLN:1HE2", " NE2", NULL},
+{"GLN:2HE2", " NE2", NULL},
+{"GLN:HE21", " NE2", NULL},
+{"GLN:HE22", " NE2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"GLN: HT ", " N : NT ", NULL},
+{"GLN: HB ", " CB ", NULL},
+{"GLN: HG ", " CG ", NULL},
+{"GLN:1HE ", " NE2", NULL},
+{"GLN:2HE ", " NE2", NULL},
+{"GLN:HE2 ", " NE2", NULL},
+#endif
+
+{"ARG: H ", " N : NT ", NULL},
+{"ARG: HN ", " N : NT ", NULL},
+{"ARG:1H ", " N : NT ", NULL},
+{"ARG:2H ", " N : NT ", NULL},
+{"ARG:3H ", " N : NT ", NULL},
+{"ARG: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"ARG: H2 ", " N : NT ", NULL}, /* */
+{"ARG: H3 ", " N : NT ", NULL}, /* */
+{"ARG: HT1", " N : NT ", NULL},
+{"ARG: HT2", " N : NT ", NULL},
+{"ARG: HT3", " N : NT ", NULL},
+{"ARG: HA ", " CA ", NULL},
+{"ARG:1HB ", " CB ", NULL},
+{"ARG:2HB ", " CB ", NULL},
+{"ARG: HB1", " CB ", NULL},
+{"ARG: HB2", " CB ", NULL},
+/* {"ARG: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"ARG: HB3", " CB ", NULL}, /* */
+{"ARG:1HG ", " CG ", NULL},
+{"ARG:2HG ", " CG ", NULL},
+{"ARG: HG1", " CG ", NULL},
+{"ARG: HG2", " CG ", NULL},
+/* {"ARG: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"ARG: HG3", " CG ", NULL}, /* */
+{"ARG:1HD ", " CD ", NULL},
+{"ARG:2HD ", " CD ", NULL},
+{"ARG: HD1", " CD ", NULL},
+{"ARG: HD2", " CD ", NULL},
+/* {"ARG: HD2", " CD ", NULL}, */ /* remediated names RMI 070718 */
+{"ARG: HD3", " CD ", NULL}, /* */
+{"ARG: HE ", " NE ", NULL},
+{"ARG:1HH1", " NH1", NULL},
+{"ARG:2HH1", " NH1", NULL},
+{"ARG:1HH2", " NH2", NULL},
+{"ARG:2HH2", " NH2", NULL},
+{"ARG:HH11", " NH1", NULL},
+{"ARG:HH12", " NH1", NULL},
+{"ARG:HH21", " NH2", NULL},
+{"ARG:HH22", " NH2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"ARG: HT ", " N : NT ", NULL},
+{"ARG: HB ", " CB ", NULL},
+{"ARG: HG ", " CG ", NULL},
+{"ARG: HD ", " CD ", NULL},
+{"ARG:1HH ", " NH1: NH2", NULL},
+{"ARG:2HH ", " NH1: NH2", NULL},
+{"ARG:HH1 ", " NH1", NULL},
+{"ARG:HH2 ", " NH2", NULL},
+#endif
+
+{"SER: H ", " N : NT ", NULL},
+{"SER: HN ", " N : NT ", NULL},
+{"SER:1H ", " N : NT ", NULL},
+{"SER:2H ", " N : NT ", NULL},
+{"SER:3H ", " N : NT ", NULL},
+{"SER: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"SER: H2 ", " N : NT ", NULL}, /* */
+{"SER: H3 ", " N : NT ", NULL}, /* */
+{"SER: HT1", " N : NT ", NULL},
+{"SER: HT2", " N : NT ", NULL},
+{"SER: HT3", " N : NT ", NULL},
+{"SER: HA ", " CA ", NULL},
+{"SER:1HB ", " CB ", NULL},
+{"SER:2HB ", " CB ", NULL},
+{"SER: HB1", " CB ", NULL},
+{"SER: HB2", " CB ", NULL},
+/* {"SER: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"SER: HB3", " CB ", NULL}, /* */
+{"SER: HG ", " OG ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"SER: HT ", " N : NT ", NULL},
+{"SER: HB ", " CB ", NULL},
+#endif
+
+{"THR: H ", " N : NT ", NULL},
+{"THR: HN ", " N : NT ", NULL},
+{"THR:1H ", " N : NT ", NULL},
+{"THR:2H ", " N : NT ", NULL},
+{"THR:3H ", " N : NT ", NULL},
+{"THR: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"THR: H2 ", " N : NT ", NULL}, /* */
+{"THR: H3 ", " N : NT ", NULL}, /* */
+{"THR: HT1", " N : NT ", NULL},
+{"THR: HT2", " N : NT ", NULL},
+{"THR: HT3", " N : NT ", NULL},
+{"THR: HA ", " CA ", NULL},
+{"THR: HB ", " CB ", NULL},
+{"THR: HG1", " OG1", NULL},
+{"THR: HG ", " OG1", NULL},
+{"THR:1HG2", " CG2", NULL},
+{"THR:2HG2", " CG2", NULL},
+{"THR:3HG2", " CG2", NULL},
+{"THR:HG21", " CG2", NULL},
+{"THR:HG22", " CG2", NULL},
+{"THR:HG23", " CG2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"THR: HT ", " N : NT ", NULL},
+{"THR:1HG ", " CG2", NULL},
+{"THR:2HG ", " CG2", NULL},
+{"THR:3HG ", " CG2", NULL},
+{"THR:HG2 ", " CG2", NULL},
+#endif
+
+{"VAL: H ", " N : NT ", NULL},
+{"VAL: HN ", " N : NT ", NULL},
+{"VAL:1H ", " N : NT ", NULL},
+{"VAL:2H ", " N : NT ", NULL},
+{"VAL:3H ", " N : NT ", NULL},
+{"VAL: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"VAL: H2 ", " N : NT ", NULL}, /* */
+{"VAL: H3 ", " N : NT ", NULL}, /* */
+{"VAL: HT1", " N : NT ", NULL},
+{"VAL: HT2", " N : NT ", NULL},
+{"VAL: HT3", " N : NT ", NULL},
+{"VAL: HA ", " CA ", NULL},
+{"VAL: HB ", " CB ", NULL},
+{"VAL:1HG1", " CG1", NULL},
+{"VAL:2HG1", " CG1", NULL},
+{"VAL:3HG1", " CG1", NULL},
+{"VAL:HG11", " CG1", NULL},
+{"VAL:HG12", " CG1", NULL},
+{"VAL:HG13", " CG1", NULL},
+{"VAL:1HG2", " CG2", NULL},
+{"VAL:2HG2", " CG2", NULL},
+{"VAL:3HG2", " CG2", NULL},
+{"VAL:HG21", " CG2", NULL},
+{"VAL:HG22", " CG2", NULL},
+{"VAL:HG23", " CG2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"VAL: HT ", " N : NT ", NULL},
+{"VAL:1HG ", " CG1: CG2", NULL},
+{"VAL:2HG ", " CG1: CG2", NULL},
+{"VAL:3HG ", " CG1: CG2", NULL},
+{"VAL:HG1 ", " CG1", NULL},
+{"VAL:HG2 ", " CG2", NULL},
+#endif
+
+{"TRP: H ", " N : NT ", NULL},
+{"TRP: HN ", " N : NT ", NULL},
+{"TRP:1H ", " N : NT ", NULL},
+{"TRP:2H ", " N : NT ", NULL},
+{"TRP:3H ", " N : NT ", NULL},
+{"TRP: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"TRP: H2 ", " N : NT ", NULL}, /* */
+{"TRP: H3 ", " N : NT ", NULL}, /* */
+{"TRP: HT1", " N : NT ", NULL},
+{"TRP: HT2", " N : NT ", NULL},
+{"TRP: HT3", " N : NT ", NULL},
+{"TRP: HA ", " CA ", NULL},
+{"TRP:1HB ", " CB ", NULL},
+{"TRP:2HB ", " CB ", NULL},
+{"TRP: HB1", " CB ", NULL},
+{"TRP: HB2", " CB ", NULL},
+/* {"TRP: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"TRP: HB3", " CB ", NULL}, /* */
+{"TRP: HD1", " CD1", NULL},
+{"TRP: HE1", " NE1", NULL},
+{"TRP: HE3", " CE3", NULL},
+{"TRP: HZ2", " CZ2", NULL},
+{"TRP: HZ3", " CZ3", NULL},
+{"TRP: HH2", " CH2", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"TRP: HT ", " N : NT ", NULL},
+{"TRP: HB ", " CB ", NULL},
+{"TRP: HD ", " CD1", NULL},
+{"TRP: HE ", " NE1: CE3", NULL},
+{"TRP: HZ ", " CZ2: CZ3", NULL},
+{"TRP: HH ", " CH2", NULL},
+#endif
+
+{"TYR: H ", " N : NT ", NULL},
+{"TYR: HN ", " N : NT ", NULL},
+{"TYR:1H ", " N : NT ", NULL},
+{"TYR:2H ", " N : NT ", NULL},
+{"TYR:3H ", " N : NT ", NULL},
+{"TYR: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"TYR: H2 ", " N : NT ", NULL}, /* */
+{"TYR: H3 ", " N : NT ", NULL}, /* */
+{"TYR: HT1", " N : NT ", NULL},
+{"TYR: HT2", " N : NT ", NULL},
+{"TYR: HT3", " N : NT ", NULL},
+{"TYR: HA ", " CA ", NULL},
+{"TYR:1HB ", " CB ", NULL},
+{"TYR:2HB ", " CB ", NULL},
+{"TYR: HB1", " CB ", NULL},
+{"TYR: HB2", " CB ", NULL},
+/* {"TYR: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"TYR: HB3", " CB ", NULL}, /* */
+{"TYR: HD1", " CD1", NULL},
+{"TYR: HD2", " CD2", NULL},
+{"TYR: HE1", " CE1", NULL},
+{"TYR: HE2", " CE2", NULL},
+{"TYR: HH ", " OH ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"TYR: HT ", " N : NT ", NULL},
+{"TYR: HB ", " CB ", NULL},
+{"TYR: HD ", " CD1: CD2", NULL},
+{"TYR: HE ", " CE1: CE2", NULL},
+#endif
+
+/*---------------------------------------*/
+
+{"ASX: H ", " N : NT ", NULL},
+{"ASX: HN ", " N : NT ", NULL},
+{"ASX:1H ", " N : NT ", NULL},
+{"ASX:2H ", " N : NT ", NULL},
+{"ASX:3H ", " N : NT ", NULL},
+{"ASX: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"ASX: H2 ", " N : NT ", NULL}, /* */
+{"ASX: H3 ", " N : NT ", NULL}, /* */
+{"ASX: HT1", " N : NT ", NULL},
+{"ASX: HT2", " N : NT ", NULL},
+{"ASX: HT3", " N : NT ", NULL},
+{"ASX: HA ", " CA ", NULL},
+{"ASX:1HB ", " CB ", NULL},
+{"ASX:2HB ", " CB ", NULL},
+{"ASX: HB1", " CB ", NULL},
+{"ASX: HB2", " CB ", NULL},
+/* {"ASX: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"ASX: HB3", " CB ", NULL}, /* */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"ASX: HT ", " N : NT ", NULL},
+{"ASX: HB ", " CB ", NULL},
+#endif
+
+{"GLX: H ", " N : NT ", NULL},
+{"GLX: HN ", " N : NT ", NULL},
+{"GLX:1H ", " N : NT ", NULL},
+{"GLX:2H ", " N : NT ", NULL},
+{"GLX:3H ", " N : NT ", NULL},
+{"GLX: H1 ", " N : NT ", NULL}, /* remediated names RMI 070718 */
+{"GLX: H2 ", " N : NT ", NULL}, /* */
+{"GLX: H3 ", " N : NT ", NULL}, /* */
+{"GLX: HT1", " N : NT ", NULL},
+{"GLX: HT2", " N : NT ", NULL},
+{"GLX: HT3", " N : NT ", NULL},
+{"GLX: HA ", " CA ", NULL},
+{"GLX:1HB ", " CB ", NULL},
+{"GLX:2HB ", " CB ", NULL},
+{"GLX: HB1", " CB ", NULL},
+{"GLX: HB2", " CB ", NULL},
+/* {"GLX: HB2", " CB ", NULL}, */ /* remediated names RMI 070718 */
+{"GLX: HB3", " CB ", NULL}, /* */
+{"GLX:1HG ", " CG ", NULL},
+{"GLX:2HG ", " CG ", NULL},
+{"GLX: HG1", " CG ", NULL},
+{"GLX: HG2", " CG ", NULL},
+/* {"GLX: HG2", " CG ", NULL}, */ /* remediated names RMI 070718 */
+{"GLX: HG3", " CG ", NULL}, /* */
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{"GLX: HT ", " N : NT ", NULL},
+{"GLX: HB ", " CB ", NULL},
+{"GLX: HG ", " CG ", NULL},
+#endif
+
+/*---------------------------------------*/
+
+{" U: H1*", " C1*: C1'", NULL},
+{" U: H1'", " C1*: C1'", NULL},
+{" U: H3*", " C3*: C3'", NULL},
+{" U: H3'", " C3*: C3'", NULL},
+{" U: H4*", " C4*: C4'", NULL},
+{" U: H4'", " C4*: C4'", NULL},
+{" U:1H5*", " C5*: C5'", NULL},
+{" U:2H5*", " C5*: C5'", NULL},
+{" U:*H51", " C5*: C5'", NULL},
+{" U:*H52", " C5*: C5'", NULL},
+{" U:H5''", " C5*: C5'", NULL},
+{" U: H5'", " C5*: C5'", NULL},
+{" U:1H2*", " C2*: C2'", NULL},
+{" U:2H2*", " C2*: C2'", NULL},
+{" U: H2*", " C2*: C2'", NULL},
+{" U:H2''", " C2*: C2'", NULL},
+{" U: H2'", " C2*: C2'", NULL},
+{" U:2HO*", " O2*: O2'", NULL},
+{" U:*HO2", " O2*: O2'", NULL},
+{" U:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" U: H3T", " O3*: O3'", NULL},
+{" U: H5T", " O5*: O5'", NULL},
+{" U:3HO*", " O3*: O3'", NULL},
+{" U:*HO3", " O3*: O3'", NULL},
+{" U:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" U:5HO*", " O5*: O5'", NULL},
+{" U:*HO5", " O5*: O5'", NULL},
+{" U:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" U: HN3", " N3 ", NULL},
+/* {" U: H3 ", " N3 ", NULL}, */ /* remediated names RMI 070718 */
+{" U: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" U: H1 ", " C1*: C1'", NULL},
+{" U: H4 ", " C4*: C4'", NULL},
+{" U:1H5 ", " C5*: C5'", NULL},
+{" U:2H5 ", " C5*: C5'", NULL},
+{" U:*H5 ", " C5*", NULL},
+{" U:H5' ", " C5'", NULL},
+{" U:1H2 ", " C2*: C2'", NULL},
+{" U:2H2 ", " C2*: C2'", NULL},
+{" U: H2 ", " C2*: C2': O2*: O2'", NULL},
+{" U:H2' ", " C2'", NULL},
+{" U:2HO ", " O2*: O2'", NULL},
+{" U:*HO ", " O2*: O3*: O5*", NULL},
+{" U:3HO ", " O3*: O3'", NULL},
+{" U:5HO ", " O5*: O5'", NULL},
+
+{" U: HN ", " N3 ", NULL},
+
+{" U: H3 ", " N3 : C3*: C3': O3*: O3'", NULL},
+{" U: H5 ", " C5 : C5': C5*: O5*: O5'", NULL},
+#else
+{" U: H3 ", " N3 ", NULL},
+{" U: H5 ", " C5 ", NULL},
+#endif
+
+{" T: H1*", " C1*: C1'", NULL},
+{" T: H1'", " C1*: C1'", NULL},
+{" T: H3*", " C3*: C3'", NULL},
+{" T: H3'", " C3*: C3'", NULL},
+{" T: H4*", " C4*: C4'", NULL},
+{" T: H4'", " C4*: C4'", NULL},
+{" T:1H5*", " C5*: C5'", NULL},
+{" T:2H5*", " C5*: C5'", NULL},
+{" T:*H51", " C5*: C5'", NULL},
+{" T:*H52", " C5*: C5'", NULL},
+{" T:H5''", " C5*: C5'", NULL},
+{" T: H5'", " C5*: C5'", NULL},
+{" T:1H2*", " C2*: C2'", NULL},
+{" T:2H2*", " C2*: C2'", NULL},
+{" T: H2*", " C2*: C2'", NULL},
+{" T:H2''", " C2*: C2'", NULL},
+{" T: H2'", " C2*: C2'", NULL},
+{" T:2HO*", " O2*: O2'", NULL},
+{" T:*HO2", " O2*: O2'", NULL},
+{" T:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" T: H3T", " O3*: O3'", NULL},
+{" T: H5T", " O5*: O5'", NULL},
+{" T:3HO*", " O3*: O3'", NULL},
+{" T:*HO3", " O3*: O3'", NULL},
+{" T:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" T:5HO*", " O5*: O5'", NULL},
+{" T:*HO5", " O5*: O5'", NULL},
+{" T:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" T: HN3", " N3 ", NULL},
+{" T:1H5M", " C7 : C5A: CA5: C5M", NULL},
+{" T:2H5M", " C7 : C5A: CA5: C5M", NULL},
+{" T:3H5M", " C7 : C5A: CA5: C5M", NULL},
+{" T:1HM5", " C7 : C5A: CA5: C5M", NULL},
+{" T:2HM5", " C7 : C5A: CA5: C5M", NULL},
+{" T:3HM5", " C7 : C5A: CA5: C5M", NULL},
+{" T:H5M1", " C7 : C5A: CA5: C5M", NULL},
+{" T:H5M2", " C7 : C5A: CA5: C5M", NULL},
+{" T:H5M3", " C7 : C5A: CA5: C5M", NULL},
+{" T:1H5A", " C7 : C5A: CA5: C5M", NULL},
+{" T:2H5A", " C7 : C5A: CA5: C5M", NULL},
+{" T:3H5A", " C7 : C5A: CA5: C5M", NULL},
+{" T:1HA5", " C7 : C5A: CA5: C5M", NULL},
+{" T:2HA5", " C7 : C5A: CA5: C5M", NULL},
+{" T:3HA5", " C7 : C5A: CA5: C5M", NULL},
+{" T:H5A1", " C7 : C5A: CA5: C5M", NULL},
+{" T:H5A2", " C7 : C5A: CA5: C5M", NULL},
+{" T:H5A3", " C7 : C5A: CA5: C5M", NULL},
+{" T: H71", " C7 : C5A: CA5: C5M", NULL}, /* remediated names RMI 070718 */
+{" T: H72", " C7 : C5A: CA5: C5M", NULL}, /* */
+{" T: H73", " C7 : C5A: CA5: C5M", NULL}, /* */
+{" T: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" T: H1 ", " C1*: C1'", NULL},
+{" T: H4 ", " C4*: C4'", NULL},
+{" T:*H5 ", " C5*", NULL},
+{" T:H5' ", " C5'", NULL},
+{" T: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" T:1H2 ", " C2*: C2'", NULL},
+{" T:2H2 ", " C2*: C2'", NULL},
+{" T: H2 ", " C2*: C2': O2*: O2'", NULL},
+{" T:H2' ", " C2'", NULL},
+{" T:2HO ", " O2*: O2'", NULL},
+{" T:*HO ", " O2*: O3*: O5*", NULL},
+{" T:3HO ", " O3*: O3'", NULL},
+{" T:5HO ", " O5*: O5'", NULL},
+
+{" T: HN ", " N3 ", NULL},
+{" T:1H5 ", " C5M: C5A: C5*: C5'", NULL},
+{" T:2H5 ", " C5M: C5A: C5*: C5'", NULL},
+{" T:3H5 ", " C5M: C5A", NULL},
+{" T:1HM ", " C5M: CM5", NULL},
+{" T:2HM ", " C5M: CM5", NULL},
+{" T:3HM ", " C5M: CM5", NULL},
+{" T:1HA ", " C5A: CA5", NULL},
+{" T:2HA ", " C5A: CA5", NULL},
+{" T:3HA ", " C5A: CA5", NULL},
+{" T:H5M ", " C5M", NULL},
+{" T:H5A ", " C5A", NULL},
+
+{" T: H3 ", " N3 : C3*: C3': O3*: O3'", NULL},
+#else
+{" T: H3 ", " N3 ", NULL},
+#endif
+
+{" A: H1*", " C1*: C1'", NULL},
+{" A: H1'", " C1*: C1'", NULL},
+{" A: H3*", " C3*: C3'", NULL},
+{" A: H3'", " C3*: C3'", NULL},
+{" A: H4*", " C4*: C4'", NULL},
+{" A: H4'", " C4*: C4'", NULL},
+{" A:1H5*", " C5*: C5'", NULL},
+{" A:2H5*", " C5*: C5'", NULL},
+{" A:*H51", " C5*: C5'", NULL},
+{" A:*H52", " C5*: C5'", NULL},
+{" A:H5''", " C5*: C5'", NULL},
+{" A: H5'", " C5*: C5'", NULL},
+{" A:1H2*", " C2*: C2'", NULL},
+{" A:2H2*", " C2*: C2'", NULL},
+{" A: H2*", " C2*: C2'", NULL},
+{" A:H2''", " C2*: C2'", NULL},
+{" A: H2'", " C2*: C2'", NULL},
+{" A:2HO*", " O2*: O2'", NULL},
+{" A:*HO2", " O2*: O2'", NULL},
+{" A:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" A: H3T", " O3*: O3'", NULL},
+{" A: H5T", " O5*: O5'", NULL},
+{" A:3HO*", " O3*: O3'", NULL},
+{" A:*HO3", " O3*: O3'", NULL},
+{" A:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" A:5HO*", " O5*: O5'", NULL},
+{" A:*HO5", " O5*: O5'", NULL},
+{" A:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" A:1H6 ", " N6 ", NULL},
+{" A:2H6 ", " N6 ", NULL},
+{" A:1HN6", " N6 ", NULL},
+{" A:2HN6", " N6 ", NULL},
+{" A: H61", " N6 ", NULL},
+{" A: H62", " N6 ", NULL},
+{" A: H8 ", " C8 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" A: H1 ", " C1*: C1'", NULL},
+{" A: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" A: H4 ", " C4*: C4'", NULL},
+{" A:1H5 ", " C5*: C5'", NULL},
+{" A:2H5 ", " C5*: C5'", NULL},
+{" A:*H5 ", " C5*: C5'", NULL},
+{" A:H5' ", " C5*: C5*", NULL},
+{" A: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" A:1H2 ", " C2*: C2'", NULL},
+{" A:2H2 ", " C2*: C2'", NULL},
+{" A:H2' ", " C2*: C2'", NULL},
+{" A:2HO ", " O2*: O2'", NULL},
+{" A:*HO ", " O2*: O3*: O5*", NULL},
+{" A:3HO ", " O3*: O3'", NULL},
+{" A:5HO ", " O5*: O5'", NULL},
+
+{" A:1HN ", " N6 ", NULL},
+{" A:2HN ", " N6 ", NULL},
+{" A: H6 ", " N6 ", NULL},
+
+{" A: H2 ", " C2 : C2*: C2': O2*: O2'", NULL},
+#else
+{" A: H2 ", " C2 ", NULL},
+#endif
+
+{" C: H1*", " C1*: C1'", NULL},
+{" C: H1'", " C1*: C1'", NULL},
+{" C: H3*", " C3*: C3'", NULL},
+{" C: H3'", " C3*: C3'", NULL},
+{" C: H4*", " C4*: C4'", NULL},
+{" C: H4'", " C4*: C4'", NULL},
+{" C:1H5*", " C5*: C5'", NULL},
+{" C:2H5*", " C5*: C5'", NULL},
+{" C:*H51", " C5*: C5'", NULL},
+{" C:*H52", " C5*: C5'", NULL},
+{" C:H5''", " C5*: C5'", NULL},
+{" C: H5'", " C5*: C5'", NULL},
+{" C:1H2*", " C2*: C2'", NULL},
+{" C:2H2*", " C2*: C2'", NULL},
+{" C: H2*", " C2*: C2'", NULL},
+{" C:H2''", " C2*: C2'", NULL},
+{" C: H2'", " C2*: C2'", NULL},
+{" C:2HO*", " O2*: O2'", NULL},
+{" C:*HO2", " O2*: O2'", NULL},
+{" C:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" C: H3T", " O3*: O3'", NULL},
+{" C: H5T", " O5*: O5'", NULL},
+{" C:3HO*", " O3*: O3'", NULL},
+{" C:*HO3", " O3*: O3'", NULL},
+{" C:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" C:5HO*", " O5*: O5'", NULL},
+{" C:*HO5", " O5*: O5'", NULL},
+{" C:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" C:1H4 ", " N4 ", NULL},
+{" C:2H4 ", " N4 ", NULL},
+{" C:1HN4", " N4 ", NULL},
+{" C:2HN4", " N4 ", NULL},
+{" C: H41", " N4 ", NULL},
+{" C: H42", " N4 ", NULL},
+{" C: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" C: H1 ", " C1*: C1'", NULL},
+{" C: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" C:1H5 ", " C5*: C5'", NULL},
+{" C:2H5 ", " C5*: C5'", NULL},
+{" C:*H5 ", " C5*", NULL},
+{" C:H5' ", " C5'", NULL},
+{" C:1H2 ", " C2*: C2'", NULL},
+{" C:2H2 ", " C2*: C2'", NULL},
+{" C: H2 ", " C2*: C2': O2*: O2'", NULL},
+{" C:H2' ", " C2'", NULL},
+{" C:2HO ", " O2*: O2'", NULL},
+{" C:*HO ", " O2*: O3*: O5*", NULL},
+{" C:3HO ", " O3*: O3'", NULL},
+{" C:5HO ", " O5*: O5'", NULL},
+
+{" C:1HN ", " N4 ", NULL},
+{" C:2HN ", " N4 ", NULL},
+{" C: H4 ", " N4 : C4*: C4'", NULL},
+
+{" C: H5 ", " C5 : C5': C5*: O5*: O5'", NULL},
+#else
+{" C: H5 ", " C5 ", NULL},
+#endif
+
+{" G: H1*", " C1*: C1'", NULL},
+{" G: H1'", " C1*: C1'", NULL},
+{" G: H3*", " C3*: C3'", NULL},
+{" G: H3'", " C3*: C3'", NULL},
+{" G: H4*", " C4*: C4'", NULL},
+{" G: H4'", " C4*: C4'", NULL},
+{" G:1H5*", " C5*: C5'", NULL},
+{" G:2H5*", " C5*: C5'", NULL},
+{" G:*H51", " C5*: C5'", NULL},
+{" G:*H52", " C5*: C5'", NULL},
+{" G:H5''", " C5*: C5'", NULL},
+{" G: H5'", " C5*: C5'", NULL},
+{" G:1H2*", " C2*: C2'", NULL},
+{" G:2H2*", " C2*: C2'", NULL},
+{" G: H2*", " C2*: C2'", NULL},
+{" G:H2''", " C2*: C2'", NULL},
+{" G: H2'", " C2*: C2'", NULL},
+{" G:2HO*", " O2*: O2'", NULL},
+{" G:*HO2", " O2*: O2'", NULL},
+{" G:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" G: H3T", " O3*: O3'", NULL},
+{" G: H5T", " O5*: O5'", NULL},
+{" G:3HO*", " O3*: O3'", NULL},
+{" G:*HO3", " O3*: O3'", NULL},
+{" G:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" G:5HO*", " O5*: O5'", NULL},
+{" G:*HO5", " O5*: O5'", NULL},
+{" G:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" G: HN1", " N1 ", NULL},
+{" G:1HN2", " N2 ", NULL},
+{" G:2HN2", " N2 ", NULL},
+{" G: H21", " N2 ", NULL},
+{" G: H22", " N2 ", NULL},
+{" G: H8 ", " C8 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" G: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" G: H4 ", " C4*: C4'", NULL},
+{" G:1H5 ", " C5*: C5'", NULL},
+{" G:2H5 ", " C5*: C5'", NULL},
+{" G:*H5 ", " C5*", NULL},
+{" G:H5' ", " C5'", NULL},
+{" G: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" G:H2' ", " C2'", NULL},
+{" G:2HO ", " O2*: O2'", NULL},
+{" G:*HO ", " O2*: O3*: O5*", NULL},
+{" G:3HO ", " O3*: O3'", NULL},
+{" G:5HO ", " O5*: O5'", NULL},
+
+{" G: HN ", " N1 ", NULL},
+{" G:1HN ", " N2 ", NULL},
+{" G:2HN ", " N2 ", NULL},
+{" G: H2 ", " N2 : C2*: C2': O2*: O2'", NULL},
+
+{" G: H1 ", " N1 : C1*: C1'", NULL},
+{" G:1H2 ", " N2 : C2*: C2'", NULL},
+{" G:2H2 ", " N2 : C2*: C2'", NULL},
+#else
+{" G: H1 ", " N1 ", NULL},
+{" G:1H2 ", " N2 ", NULL},
+{" G:2H2 ", " N2 ", NULL},
+#endif
+
+/* RNA for Coot and CCP4 Ar, Ur, Tr, Cr, Gr */
+
+{" UR: H1*", " C1*: C1'", NULL},
+{" UR: H1'", " C1*: C1'", NULL},
+{" UR: H3*", " C3*: C3'", NULL},
+{" UR: H3'", " C3*: C3'", NULL},
+{" UR: H4*", " C4*: C4'", NULL},
+{" UR: H4'", " C4*: C4'", NULL},
+{" UR:1H5*", " C5*: C5'", NULL},
+{" UR:2H5*", " C5*: C5'", NULL},
+{" UR:*H51", " C5*: C5'", NULL},
+{" UR:*H52", " C5*: C5'", NULL},
+{" UR:H5''", " C5*: C5'", NULL},
+{" UR: H5'", " C5*: C5'", NULL},
+{" UR:1H2*", " C2*: C2'", NULL},
+{" UR:2H2*", " C2*: C2'", NULL},
+{" UR: H2*", " C2*: C2'", NULL},
+{" UR:H2''", " C2*: C2'", NULL},
+{" UR: H2'", " C2*: C2'", NULL},
+{" UR:2HO*", " O2*: O2'", NULL},
+{" UR:*HO2", " O2*: O2'", NULL},
+{" UR:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" UR: H3T", " O3*: O3'", NULL},
+{" UR: H5T", " O5*: O5'", NULL},
+{" UR:3HO*", " O3*: O3'", NULL},
+{" UR:*HO3", " O3*: O3'", NULL},
+{" UR:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" UR:5HO*", " O5*: O5'", NULL},
+{" UR:*HO5", " O5*: O5'", NULL},
+{" UR:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" UR: HN3", " N3 ", NULL},
+/* {" U: H3 ", " N3 ", NULL}, */ /* remediated names RMI 070718 */
+{" UR: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" UR: H1 ", " C1*: C1'", NULL},
+{" UR: H4 ", " C4*: C4'", NULL},
+{" UR:1H5 ", " C5*: C5'", NULL},
+{" UR:2H5 ", " C5*: C5'", NULL},
+{" UR:*H5 ", " C5*", NULL},
+{" UR:H5' ", " C5'", NULL},
+{" UR:1H2 ", " C2*: C2'", NULL},
+{" UR:2H2 ", " C2*: C2'", NULL},
+{" UR: H2 ", " C2*: C2': O2*: O2'", NULL},
+{" UR:H2' ", " C2'", NULL},
+{" UR:2HO ", " O2*: O2'", NULL},
+{" UR:*HO ", " O2*: O3*: O5*", NULL},
+{" UR:3HO ", " O3*: O3'", NULL},
+{" UR:5HO ", " O5*: O5'", NULL},
+
+{" UR: HN ", " N3 ", NULL},
+
+{" UR: H3 ", " N3 : C3*: C3': O3*: O3'", NULL},
+{" UR: H5 ", " C5 : C5': C5*: O5*: O5'", NULL},
+#else
+{" UR: H3 ", " N3 ", NULL},
+{" UR: H5 ", " C5 ", NULL},
+#endif
+
+{" TR: H1*", " C1*: C1'", NULL},
+{" TR: H1'", " C1*: C1'", NULL},
+{" TR: H3*", " C3*: C3'", NULL},
+{" TR: H3'", " C3*: C3'", NULL},
+{" TR: H4*", " C4*: C4'", NULL},
+{" TR: H4'", " C4*: C4'", NULL},
+{" TR:1H5*", " C5*: C5'", NULL},
+{" TR:2H5*", " C5*: C5'", NULL},
+{" TR:*H51", " C5*: C5'", NULL},
+{" TR:*H52", " C5*: C5'", NULL},
+{" TR:H5''", " C5*: C5'", NULL},
+{" TR: H5'", " C5*: C5'", NULL},
+{" TR:1H2*", " C2*: C2'", NULL},
+{" TR:2H2*", " C2*: C2'", NULL},
+{" TR: H2*", " C2*: C2'", NULL},
+{" TR:H2''", " C2*: C2'", NULL},
+{" TR: H2'", " C2*: C2'", NULL},
+{" TR:2HO*", " O2*: O2'", NULL},
+{" TR:*HO2", " O2*: O2'", NULL},
+{" TR:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" TR: H3T", " O3*: O3'", NULL},
+{" TR: H5T", " O5*: O5'", NULL},
+{" TR:3HO*", " O3*: O3'", NULL},
+{" TR:*HO3", " O3*: O3'", NULL},
+{" TR:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" TR:5HO*", " O5*: O5'", NULL},
+{" TR:*HO5", " O5*: O5'", NULL},
+{" TR:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" TR: HN3", " N3 ", NULL},
+{" TR:1H5M", " C7 : C5A: CA5: C5M", NULL},
+{" TR:2H5M", " C7 : C5A: CA5: C5M", NULL},
+{" TR:3H5M", " C7 : C5A: CA5: C5M", NULL},
+{" TR:1HM5", " C7 : C5A: CA5: C5M", NULL},
+{" TR:2HM5", " C7 : C5A: CA5: C5M", NULL},
+{" TR:3HM5", " C7 : C5A: CA5: C5M", NULL},
+{" TR:H5M1", " C7 : C5A: CA5: C5M", NULL},
+{" TR:H5M2", " C7 : C5A: CA5: C5M", NULL},
+{" TR:H5M3", " C7 : C5A: CA5: C5M", NULL},
+{" TR:1H5A", " C7 : C5A: CA5: C5M", NULL},
+{" TR:2H5A", " C7 : C5A: CA5: C5M", NULL},
+{" TR:3H5A", " C7 : C5A: CA5: C5M", NULL},
+{" TR:1HA5", " C7 : C5A: CA5: C5M", NULL},
+{" TR:2HA5", " C7 : C5A: CA5: C5M", NULL},
+{" TR:3HA5", " C7 : C5A: CA5: C5M", NULL},
+{" TR:H5A1", " C7 : C5A: CA5: C5M", NULL},
+{" TR:H5A2", " C7 : C5A: CA5: C5M", NULL},
+{" TR:H5A3", " C7 : C5A: CA5: C5M", NULL},
+{" TR: H71", " C7 : C5A: CA5: C5M", NULL}, /* remediated names RMI 070718 */
+{" TR: H72", " C7 : C5A: CA5: C5M", NULL}, /* */
+{" TR: H73", " C7 : C5A: CA5: C5M", NULL}, /* */
+{" TR: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" TR: H1 ", " C1*: C1'", NULL},
+{" TR: H4 ", " C4*: C4'", NULL},
+{" TR:*H5 ", " C5*", NULL},
+{" TR:H5' ", " C5'", NULL},
+{" TR: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" TR:1H2 ", " C2*: C2'", NULL},
+{" TR:2H2 ", " C2*: C2'", NULL},
+{" TR: H2 ", " C2*: C2': O2*: O2'", NULL},
+{" TR:H2' ", " C2'", NULL},
+{" TR:2HO ", " O2*: O2'", NULL},
+{" TR:*HO ", " O2*: O3*: O5*", NULL},
+{" TR:3HO ", " O3*: O3'", NULL},
+{" TR:5HO ", " O5*: O5'", NULL},
+
+{" TR: HN ", " N3 ", NULL},
+{" TR:1H5 ", " C5M: C5A: C5*: C5'", NULL},
+{" TR:2H5 ", " C5M: C5A: C5*: C5'", NULL},
+{" TR:3H5 ", " C5M: C5A", NULL},
+{" TR:1HM ", " C5M: CM5", NULL},
+{" TR:2HM ", " C5M: CM5", NULL},
+{" TR:3HM ", " C5M: CM5", NULL},
+{" TR:1HA ", " C5A: CA5", NULL},
+{" TR:2HA ", " C5A: CA5", NULL},
+{" TR:3HA ", " C5A: CA5", NULL},
+{" TR:H5M ", " C5M", NULL},
+{" TR:H5A ", " C5A", NULL},
+
+{" TR: H3 ", " N3 : C3*: C3': O3*: O3'", NULL},
+#else
+{" TR: H3 ", " N3 ", NULL},
+#endif
+
+{" AR: H1*", " C1*: C1'", NULL},
+{" AR: H1'", " C1*: C1'", NULL},
+{" AR: H3*", " C3*: C3'", NULL},
+{" AR: H3'", " C3*: C3'", NULL},
+{" AR: H4*", " C4*: C4'", NULL},
+{" AR: H4'", " C4*: C4'", NULL},
+{" AR:1H5*", " C5*: C5'", NULL},
+{" AR:2H5*", " C5*: C5'", NULL},
+{" AR:*H51", " C5*: C5'", NULL},
+{" AR:*H52", " C5*: C5'", NULL},
+{" AR:H5''", " C5*: C5'", NULL},
+{" AR: H5'", " C5*: C5'", NULL},
+{" AR:1H2*", " C2*: C2'", NULL},
+{" AR:2H2*", " C2*: C2'", NULL},
+{" AR: H2*", " C2*: C2'", NULL},
+{" AR:H2''", " C2*: C2'", NULL},
+{" AR: H2'", " C2*: C2'", NULL},
+{" AR:2HO*", " O2*: O2'", NULL},
+{" AR:*HO2", " O2*: O2'", NULL},
+{" AR:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" AR: H3T", " O3*: O3'", NULL},
+{" AR: H5T", " O5*: O5'", NULL},
+{" AR:3HO*", " O3*: O3'", NULL},
+{" AR:*HO3", " O3*: O3'", NULL},
+{" AR:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" AR:5HO*", " O5*: O5'", NULL},
+{" AR:*HO5", " O5*: O5'", NULL},
+{" AR:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" AR:1H6 ", " N6 ", NULL},
+{" AR:2H6 ", " N6 ", NULL},
+{" AR:1HN6", " N6 ", NULL},
+{" AR:2HN6", " N6 ", NULL},
+{" AR: H61", " N6 ", NULL},
+{" AR: H62", " N6 ", NULL},
+{" AR: H8 ", " C8 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" AR: H1 ", " C1*: C1'", NULL},
+{" AR: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" AR: H4 ", " C4*: C4'", NULL},
+{" AR:1H5 ", " C5*: C5'", NULL},
+{" AR:2H5 ", " C5*: C5'", NULL},
+{" AR:*H5 ", " C5*: C5'", NULL},
+{" AR:H5' ", " C5*: C5*", NULL},
+{" AR: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" AR:1H2 ", " C2*: C2'", NULL},
+{" AR:2H2 ", " C2*: C2'", NULL},
+{" AR:H2' ", " C2*: C2'", NULL},
+{" AR:2HO ", " O2*: O2'", NULL},
+{" AR:*HO ", " O2*: O3*: O5*", NULL},
+{" AR:3HO ", " O3*: O3'", NULL},
+{" AR:5HO ", " O5*: O5'", NULL},
+
+{" AR:1HN ", " N6 ", NULL},
+{" AR:2HN ", " N6 ", NULL},
+{" AR: H6 ", " N6 ", NULL},
+
+{" AR: H2 ", " C2 : C2*: C2': O2*: O2'", NULL},
+#else
+{" AR: H2 ", " C2 ", NULL},
+#endif
+
+{" CR: H1*", " C1*: C1'", NULL},
+{" CR: H1'", " C1*: C1'", NULL},
+{" CR: H3*", " C3*: C3'", NULL},
+{" CR: H3'", " C3*: C3'", NULL},
+{" CR: H4*", " C4*: C4'", NULL},
+{" CR: H4'", " C4*: C4'", NULL},
+{" CR:1H5*", " C5*: C5'", NULL},
+{" CR:2H5*", " C5*: C5'", NULL},
+{" CR:*H51", " C5*: C5'", NULL},
+{" CR:*H52", " C5*: C5'", NULL},
+{" CR:H5''", " C5*: C5'", NULL},
+{" CR: H5'", " C5*: C5'", NULL},
+{" CR:1H2*", " C2*: C2'", NULL},
+{" CR:2H2*", " C2*: C2'", NULL},
+{" CR: H2*", " C2*: C2'", NULL},
+{" CR:H2''", " C2*: C2'", NULL},
+{" CR: H2'", " C2*: C2'", NULL},
+{" CR:2HO*", " O2*: O2'", NULL},
+{" CR:*HO2", " O2*: O2'", NULL},
+{" CR:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" CR: H3T", " O3*: O3'", NULL},
+{" CR: H5T", " O5*: O5'", NULL},
+{" CR:3HO*", " O3*: O3'", NULL},
+{" CR:*HO3", " O3*: O3'", NULL},
+{" CR:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" CR:5HO*", " O5*: O5'", NULL},
+{" CR:*HO5", " O5*: O5'", NULL},
+{" CR:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" CR:1H4 ", " N4 ", NULL},
+{" CR:2H4 ", " N4 ", NULL},
+{" CR:1HN4", " N4 ", NULL},
+{" CR:2HN4", " N4 ", NULL},
+{" CR: H41", " N4 ", NULL},
+{" CR: H42", " N4 ", NULL},
+{" CR: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" CR: H1 ", " C1*: C1'", NULL},
+{" CR: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" CR:1H5 ", " C5*: C5'", NULL},
+{" CR:2H5 ", " C5*: C5'", NULL},
+{" CR:*H5 ", " C5*", NULL},
+{" CR:H5' ", " C5'", NULL},
+{" CR:1H2 ", " C2*: C2'", NULL},
+{" CR:2H2 ", " C2*: C2'", NULL},
+{" CR: H2 ", " C2*: C2': O2*: O2'", NULL},
+{" CR:H2' ", " C2'", NULL},
+{" CR:2HO ", " O2*: O2'", NULL},
+{" CR:*HO ", " O2*: O3*: O5*", NULL},
+{" CR:3HO ", " O3*: O3'", NULL},
+{" CR:5HO ", " O5*: O5'", NULL},
+
+{" CR:1HN ", " N4 ", NULL},
+{" CR:2HN ", " N4 ", NULL},
+{" CR: H4 ", " N4 : C4*: C4'", NULL},
+
+{" CR: H5 ", " C5 : C5': C5*: O5*: O5'", NULL},
+#else
+{" CR: H5 ", " C5 ", NULL},
+#endif
+
+{" GR: H1*", " C1*: C1'", NULL},
+{" GR: H1'", " C1*: C1'", NULL},
+{" GR: H3*", " C3*: C3'", NULL},
+{" GR: H3'", " C3*: C3'", NULL},
+{" GR: H4*", " C4*: C4'", NULL},
+{" GR: H4'", " C4*: C4'", NULL},
+{" GR:1H5*", " C5*: C5'", NULL},
+{" GR:2H5*", " C5*: C5'", NULL},
+{" GR:*H51", " C5*: C5'", NULL},
+{" GR:*H52", " C5*: C5'", NULL},
+{" GR:H5''", " C5*: C5'", NULL},
+{" GR: H5'", " C5*: C5'", NULL},
+{" GR:1H2*", " C2*: C2'", NULL},
+{" GR:2H2*", " C2*: C2'", NULL},
+{" GR: H2*", " C2*: C2'", NULL},
+{" GR:H2''", " C2*: C2'", NULL},
+{" GR: H2'", " C2*: C2'", NULL},
+{" GR:2HO*", " O2*: O2'", NULL},
+{" GR:*HO2", " O2*: O2'", NULL},
+{" GR:HO2'", " O2*: O2'", NULL}, /* remediated names RMI 070718 */
+{" GR: H3T", " O3*: O3'", NULL},
+{" GR: H5T", " O5*: O5'", NULL},
+{" GR:3HO*", " O3*: O3'", NULL},
+{" GR:*HO3", " O3*: O3'", NULL},
+{" GR:HO3'", " O3*: O3'", NULL}, /* remediated names RMI 070718 */
+{" GR:5HO*", " O5*: O5'", NULL},
+{" GR:*HO5", " O5*: O5'", NULL},
+{" GR:HO5'", " O5*: O5'", NULL}, /* remediated names RMI 070718 */
+{" GR: HN1", " N1 ", NULL},
+{" GR:1HN2", " N2 ", NULL},
+{" GR:2HN2", " N2 ", NULL},
+{" GR: H21", " N2 ", NULL},
+{" GR: H22", " N2 ", NULL},
+{" GR: H8 ", " C8 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" GR: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" GR: H4 ", " C4*: C4'", NULL},
+{" GR:1H5 ", " C5*: C5'", NULL},
+{" GR:2H5 ", " C5*: C5'", NULL},
+{" GR:*H5 ", " C5*", NULL},
+{" GR:H5' ", " C5'", NULL},
+{" GR: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" GR:H2' ", " C2'", NULL},
+{" GR:2HO ", " O2*: O2'", NULL},
+{" GR:*HO ", " O2*: O3*: O5*", NULL},
+{" GR:3HO ", " O3*: O3'", NULL},
+{" GR:5HO ", " O5*: O5'", NULL},
+
+{" GR: HN ", " N1 ", NULL},
+{" GR:1HN ", " N2 ", NULL},
+{" GR:2HN ", " N2 ", NULL},
+{" GR: H2 ", " N2 : C2*: C2': O2*: O2'", NULL},
+
+{" GR: H1 ", " N1 : C1*: C1'", NULL},
+{" GR:1H2 ", " N2 : C2*: C2'", NULL},
+{" GR:2H2 ", " N2 : C2*: C2'", NULL},
+#else
+{" GR: H1 ", " N1 ", NULL},
+{" GR:1H2 ", " N2 ", NULL},
+{" GR:2H2 ", " N2 ", NULL},
+#endif
+
+/* DNA in the remediated system is DA, DT, DG, DC */
+
+{" DT: H1*", " C1*", NULL},
+{" DT: H1'", " C1'", NULL},
+{" DT: H3*", " C3*", NULL},
+{" DT: H3'", " C3'", NULL},
+{" DT: H4*", " C4*", NULL},
+{" DT: H4'", " C4'", NULL},
+{" DT:1H5*", " C5*", NULL},
+{" DT:2H5*", " C5*", NULL},
+{" DT:*H51", " C5*", NULL},
+{" DT:*H52", " C5*", NULL},
+{" DT:H5''", " C5'", NULL},
+{" DT: H5'", " C5'", NULL},
+{" DT:1H2*", " C2*", NULL},
+{" DT:2H2*", " C2*", NULL},
+{" DT: H2*", " C2*", NULL},
+{" DT: H2'", " C2'", NULL}, /* remediated names RMI 070722 */
+{" DT:H2''", " C2'", NULL},
+{" DT: H3T", " O3*: O3'", NULL},
+{" DT: H5T", " O5*: O5'", NULL},
+{" DT:3HO*", " O3*", NULL},
+{" DT:*HO3", " O3*", NULL},
+{" DT:HO3'", " O3'", NULL}, /* remediated names RMI 070718 */
+{" DT:5HO*", " O5*", NULL},
+{" DT:*HO5", " O5*", NULL},
+{" DT:HO5'", " O5'", NULL}, /* remediated names RMI 070718 */
+{" DT: HN3", " N3 ", NULL},
+{" DT:1H5M", " C7 : C5A: CA5: C5M", NULL},
+{" DT:2H5M", " C7 : C5A: CA5: C5M", NULL},
+{" DT:3H5M", " C7 : C5A: CA5: C5M", NULL},
+{" DT:1HM5", " C7 : C5A: CA5: C5M", NULL},
+{" DT:2HM5", " C7 : C5A: CA5: C5M", NULL},
+{" DT:3HM5", " C7 : C5A: CA5: C5M", NULL},
+{" DT:H5M1", " C7 : C5A: CA5: C5M", NULL},
+{" DT:H5M2", " C7 : C5A: CA5: C5M", NULL},
+{" DT:H5M3", " C7 : C5A: CA5: C5M", NULL},
+{" DT:1H5A", " C7 : C5A: CA5: C5M", NULL},
+{" DT:2H5A", " C7 : C5A: CA5: C5M", NULL},
+{" DT:3H5A", " C7 : C5A: CA5: C5M", NULL},
+{" DT:1HA5", " C7 : C5A: CA5: C5M", NULL},
+{" DT:2HA5", " C7 : C5A: CA5: C5M", NULL},
+{" DT:3HA5", " C7 : C5A: CA5: C5M", NULL},
+{" DT:H5A1", " C7 : C5A: CA5: C5M", NULL},
+{" DT:H5A2", " C7 : C5A: CA5: C5M", NULL},
+{" DT:H5A3", " C7 : C5A: CA5: C5M", NULL},
+{" DT: H71", " C7 : C5A: CA5: C5M", NULL}, /* remediated names RMI 070718 */
+{" DT: H72", " C7 : C5A: CA5: C5M", NULL}, /* */
+{" DT: H73", " C7 : C5A: CA5: C5M", NULL}, /* */
+{" DT: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" DT: H1 ", " C1*: C1'", NULL},
+{" DT: H4 ", " C4*: C4'", NULL},
+{" DT:*H5 ", " C5*", NULL},
+{" DT:H5' ", " C5'", NULL},
+{" DT: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" DT:1H2 ", " C2*: C2'", NULL},
+{" DT:2H2 ", " C2*: C2'", NULL},
+{" DT: H2 ", " C2*: C2'", NULL},
+{" DT:H2' ", " C2'", NULL},
+{" DT:*HO ", " O3*: O5*", NULL},
+{" DT:3HO ", " O3*: O3'", NULL},
+{" DT:5HO ", " O5*: O5'", NULL},
+
+{" DT: HN ", " N3 ", NULL},
+{" DT:1H5 ", " C5M: C5A: C5*: C5'", NULL},
+{" DT:2H5 ", " C5M: C5A: C5*: C5'", NULL},
+{" DT:3H5 ", " C5M: C5A", NULL},
+{" DT:1HM ", " C5M: CM5", NULL},
+{" DT:2HM ", " C5M: CM5", NULL},
+{" DT:3HM ", " C5M: CM5", NULL},
+{" DT:1HA ", " C5A: CA5", NULL},
+{" DT:2HA ", " C5A: CA5", NULL},
+{" DT:3HA ", " C5A: CA5", NULL},
+{" DT:H5M ", " C5M", NULL},
+{" DT:H5A ", " C5A", NULL},
+
+{" DT: H3 ", " N3 : C3*: C3': O3*: O3'", NULL},
+#else
+{" DT: H3 ", " N3 ", NULL},
+#endif
+
+{" DA: H1*", " C1*", NULL},
+{" DA: H1'", " C1'", NULL},
+{" DA: H3*", " C3*", NULL},
+{" DA: H3'", " C3'", NULL},
+{" DA: H4*", " C4*", NULL},
+{" DA: H4'", " C4'", NULL},
+{" DA:1H5*", " C5*", NULL},
+{" DA:2H5*", " C5*", NULL},
+{" DA:*H51", " C5*", NULL},
+{" DA:*H52", " C5*", NULL},
+{" DA:H5''", " C5'", NULL},
+{" DA: H5'", " C5'", NULL},
+{" DA:1H2*", " C2*", NULL},
+{" DA:2H2*", " C2*", NULL},
+{" DA: H2*", " C2*", NULL},
+{" DA: H2'", " C2'", NULL}, /* remediated names RMI 070722 */
+{" DA:H2''", " C2'", NULL},
+{" DA: H3T", " O3*: O3'", NULL},
+{" DA: H5T", " O5*: O5'", NULL},
+{" DA:3HO*", " O3*", NULL},
+{" DA:*HO3", " O3*", NULL},
+{" DA:HO3'", " O3'", NULL}, /* remediated names RMI 070718 */
+{" DA:5HO*", " O5*", NULL},
+{" DA:*HO5", " O5*", NULL},
+{" DA:HO5'", " O5'", NULL}, /* remediated names RMI 070718 */
+{" DA:1H6 ", " N6 ", NULL},
+{" DA:2H6 ", " N6 ", NULL},
+{" DA:1HN6", " N6 ", NULL},
+{" DA:2HN6", " N6 ", NULL},
+{" DA: H61", " N6 ", NULL},
+{" DA: H62", " N6 ", NULL},
+{" DA: H8 ", " C8 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" DA: H1 ", " C1*: C1'", NULL},
+{" DA: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" DA: H4 ", " C4*: C4'", NULL},
+{" DA:1H5 ", " C5*: C5'", NULL},
+{" DA:2H5 ", " C5*: C5'", NULL},
+{" DA:*H5 ", " C5*", NULL},
+{" DA:H5' ", " C5'", NULL},
+{" DA: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" DA:1H2 ", " C2*: C2'", NULL},
+{" DA:2H2 ", " C2*: C2'", NULL},
+{" DA:H2' ", " C2'", NULL},
+{" DA:*HO ", " O3*: O5*", NULL},
+{" DA:3HO ", " O3*: O3'", NULL},
+{" DA:5HO ", " O5*: O5'", NULL},
+
+{" DA:1HN ", " N6 ", NULL},
+{" DA:2HN ", " N6 ", NULL},
+{" DA: H6 ", " N6 ", NULL},
+
+{" DA: H2 ", " C2 : C2*: C2'", NULL},
+#else
+{" DA: H2 ", " C2 ", NULL},
+#endif
+
+{" DC: H1*", " C1*", NULL},
+{" DC: H1'", " C1'", NULL},
+{" DC: H3*", " C3*", NULL},
+{" DC: H3'", " C3'", NULL},
+{" DC: H4*", " C4*", NULL},
+{" DC: H4'", " C4'", NULL},
+{" DC:1H5*", " C5*", NULL},
+{" DC:2H5*", " C5*", NULL},
+{" DC:*H51", " C5*", NULL},
+{" DC:*H52", " C5*", NULL},
+{" DC:H5''", " C5'", NULL},
+{" DC: H5'", " C5'", NULL},
+{" DC:1H2*", " C2*", NULL},
+{" DC:2H2*", " C2*", NULL},
+{" DC: H2*", " C2*", NULL},
+{" DC: H2'", " C2'", NULL}, /* remediated names RMI 070722 */
+{" DC:H2''", " C2'", NULL},
+{" DC: H3T", " O3*: O3'", NULL},
+{" DC: H5T", " O5*: O5'", NULL},
+{" DC:3HO*", " O3*", NULL},
+{" DC:*HO3", " O3*", NULL},
+{" DC:HO3'", " O3'", NULL}, /* remediated names RMI 070718 */
+{" DC:5HO*", " O5*", NULL},
+{" DC:*HO5", " O5*", NULL},
+{" DC:HO5'", " O5'", NULL}, /* remediated names RMI 070718 */
+{" DC:1H4 ", " N4 ", NULL},
+{" DC:2H4 ", " N4 ", NULL},
+{" DC:1HN4", " N4 ", NULL},
+{" DC:2HN4", " N4 ", NULL},
+{" DC: H41", " N4 ", NULL},
+{" DC: H42", " N4 ", NULL},
+{" DC: H6 ", " C6 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" DC: H1 ", " C1*: C1'", NULL},
+{" DC: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" DC:1H5 ", " C5*: C5'", NULL},
+{" DC:2H5 ", " C5*: C5'", NULL},
+{" DC:*H5 ", " C5*", NULL},
+{" DC:H5' ", " C5'", NULL},
+{" DC:1H2 ", " C2*: C2'", NULL},
+{" DC:2H2 ", " C2*: C2'", NULL},
+{" DC: H2 ", " C2*: C2'", NULL},
+{" DC:H2' ", " C2'", NULL},
+{" DC:*HO ", " O3*: O5*", NULL},
+{" DC:3HO ", " O3*: O3'", NULL},
+{" DC:5HO ", " O5*: O5'", NULL},
+
+{" DC:1HN ", " N4 ", NULL},
+{" DC:2HN ", " N4 ", NULL},
+{" DC: H4 ", " N4 : C4*: C4'", NULL},
+
+{" DC: H5 ", " C5 : C5': C5*: O5*: O5'", NULL},
+#else
+{" DC: H5 ", " C5 ", NULL},
+#endif
+
+{" DG: H1*", " C1*", NULL},
+{" DG: H1'", " C1'", NULL},
+{" DG: H3*", " C3*", NULL},
+{" DG: H3'", " C3'", NULL},
+{" DG: H4*", " C4*", NULL},
+{" DG: H4'", " C4'", NULL},
+{" DG:1H5*", " C5*", NULL},
+{" DG:2H5*", " C5*", NULL},
+{" DG:*H51", " C5*", NULL},
+{" DG:*H52", " C5*", NULL},
+{" DG:H5''", " C5'", NULL},
+{" DG: H5'", " C5'", NULL},
+{" DG:1H2*", " C2*", NULL},
+{" DG:2H2*", " C2*", NULL},
+{" DG: H2*", " C2*", NULL},
+{" DG: H2'", " C2'", NULL}, /* remediated names RMI 070722 */
+{" DG:H2''", " C2'", NULL},
+{" DG: H3T", " O3*: O3'", NULL},
+{" DG: H5T", " O5*: O5'", NULL},
+{" DG:3HO*", " O3*", NULL},
+{" DG:*HO3", " O3*", NULL},
+{" DG:HO3'", " O3'", NULL}, /* remediated names RMI 070718 */
+{" DG:5HO*", " O5*", NULL},
+{" DG:*HO5", " O5*", NULL},
+{" DG:HO5'", " O5'", NULL}, /* remediated names RMI 070718 */
+{" DG: HN1", " N1 ", NULL},
+{" DG:1HN2", " N2 ", NULL},
+{" DG:2HN2", " N2 ", NULL},
+{" DG: H21", " N2 ", NULL},
+{" DG: H22", " N2 ", NULL},
+{" DG: H8 ", " C8 ", NULL},
+#ifdef ALLOW_TRUNCATED_H_NAMES
+{" DG: H3 ", " C3*: C3': O3*: O3'", NULL},
+{" DG: H4 ", " C4*: C4'", NULL},
+{" DG:1H5 ", " C5*: C5'", NULL},
+{" DG:2H5 ", " C5*: C5'", NULL},
+{" DG:*H5 ", " C5*", NULL},
+{" DG:H5' ", " C5'", NULL},
+{" DG: H5 ", " C5': C5*: O5*: O5'", NULL},
+{" DG:H2' ", " C2'", NULL},
+{" DG:*HO ", " O3*: O5*", NULL},
+{" DG:3HO ", " O3*: O3'", NULL},
+{" DG:5HO ", " O5*: O5'", NULL},
+
+{" DG: HN ", " N1 ", NULL},
+{" DG:1HN ", " N2 ", NULL},
+{" DG:2HN ", " N2 ", NULL},
+{" DG: H2 ", " N2 : C2*: C2'", NULL},
+
+{" DG: H1 ", " N1 : C1*: C1'", NULL},
+{" DG:1H2 ", " N2 : C2*: C2'", NULL},
+{" DG:2H2 ", " N2 : C2*: C2'", NULL},
+#else
+{" DG: H1 ", " N1 ", NULL},
+{" DG:1H2 ", " N2 ", NULL},
+{" DG:2H2 ", " N2 ", NULL},
+#endif
+
+/*---------------------------------------*/
+/* the following definitions are used to specify how */
+/* heavy atoms interact with other heavy atoms WITHIN a */
+/* standard amino acid residue or base. */
+/* This is accessed only when the -STDBOND flag is on the */
+/* command line (UseStdBond == TRUE). */
+
+{"ALA: N ", " CA ", NULL},
+{"ALA: NT ", " CA ", NULL},
+{"ALA: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"ALA: O ", " C ", NULL},
+{"ALA: OXT", " C ", NULL},
+{"ALA: OT1", " C ", NULL},
+{"ALA: OT2", " C ", NULL},
+{"ALA: CA ", " N : NT : C : CB ", NULL},
+{"ALA: CB ", " CA ", NULL},
+
+{"CYS: N ", " CA ", NULL},
+{"CYS: NT ", " CA ", NULL},
+{"CYS: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"CYS: O ", " C ", NULL},
+{"CYS: OXT", " C ", NULL},
+{"CYS: OT1", " C ", NULL},
+{"CYS: OT2", " C ", NULL},
+{"CYS: CA ", " N : NT : C : CB ", NULL},
+{"CYS: CB ", " CA : SG ", NULL},
+{"CYS: SG ", " CB ", NULL},
+
+{"ASP: N ", " CA ", NULL},
+{"ASP: NT ", " CA ", NULL},
+{"ASP: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"ASP: O ", " C ", NULL},
+{"ASP: OXT", " C ", NULL},
+{"ASP: OT1", " C ", NULL},
+{"ASP: OT2", " C ", NULL},
+{"ASP: CA ", " N : NT : C : CB ", NULL},
+{"ASP: CB ", " CA : CG ", NULL},
+{"ASP: CG ", " CB : OD1: OD2", NULL},
+{"ASP: OD1", " CG ", NULL},
+{"ASP: OD2", " CG ", NULL},
+
+{"GLU: N ", " CA ", NULL},
+{"GLU: NT ", " CA ", NULL},
+{"GLU: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"GLU: O ", " C ", NULL},
+{"GLU: OXT", " C ", NULL},
+{"GLU: OT1", " C ", NULL},
+{"GLU: OT2", " C ", NULL},
+{"GLU: CA ", " N : NT : C : CB ", NULL},
+{"GLU: CB ", " CA : CG ", NULL},
+{"GLU: CG ", " CB : CD ", NULL},
+{"GLU: CD ", " CG : OE1: OE2", NULL},
+{"GLU: OE1", " CD ", NULL},
+{"GLU: OE2", " CD ", NULL},
+
+{"PHE: N ", " CA ", NULL},
+{"PHE: NT ", " CA ", NULL},
+{"PHE: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"PHE: O ", " C ", NULL},
+{"PHE: OXT", " C ", NULL},
+{"PHE: OT1", " C ", NULL},
+{"PHE: OT2", " C ", NULL},
+{"PHE: CA ", " N : NT : C : CB ", NULL},
+{"PHE: CB ", " CA : CG ", NULL},
+{"PHE: CG ", " CB : CD1: CD2", NULL},
+{"PHE: CD1", " CG : CE1", NULL},
+{"PHE: CD2", " CG : CE2", NULL},
+{"PHE: CE1", " CD1: CZ ", NULL},
+{"PHE: CE2", " CD2: CZ ", NULL},
+{"PHE: CZ ", " CE1: CE2", NULL},
+
+{"GLY: N ", " CA ", NULL},
+{"GLY: NT ", " CA ", NULL},
+{"GLY: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"GLY: O ", " C ", NULL},
+{"GLY: OXT", " C ", NULL},
+{"GLY: OT1", " C ", NULL},
+{"GLY: OT2", " C ", NULL},
+{"GLY: CA ", " N : NT : C : CB ", NULL},
+/* note CA-CB for gly is to support mutations gracefully */
+/* where a gly MC is attached to some other SC */
+
+{"HIS: N ", " CA ", NULL},
+{"HIS: NT ", " CA ", NULL},
+{"HIS: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"HIS: O ", " C ", NULL},
+{"HIS: OXT", " C ", NULL},
+{"HIS: OT1", " C ", NULL},
+{"HIS: OT2", " C ", NULL},
+{"HIS: CA ", " N : NT : C : CB ", NULL},
+{"HIS: CB ", " CA : CG ", NULL},
+{"HIS: CG ", " CB : ND1: CD2", NULL},
+{"HIS: ND1", " CG : CE1", NULL},
+{"HIS: CD2", " CG : NE2", NULL},
+{"HIS: CE1", " ND1: NE2", NULL},
+{"HIS: NE2", " CD2: CE1", NULL},
+
+{"ILE: N ", " CA ", NULL},
+{"ILE: NT ", " CA ", NULL},
+{"ILE: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"ILE: O ", " C ", NULL},
+{"ILE: OXT", " C ", NULL},
+{"ILE: OT1", " C ", NULL},
+{"ILE: OT2", " C ", NULL},
+{"ILE: CA ", " N : NT : C : CB ", NULL},
+{"ILE: CB ", " CA : CG1: CG2", NULL},
+{"ILE: CG1", " CB : CD1", NULL},
+{"ILE: CG2", " CB ", NULL},
+{"ILE: CD1", " CG1", NULL},
+
+{"LYS: N ", " CA ", NULL},
+{"LYS: NT ", " CA ", NULL},
+{"LYS: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"LYS: O ", " C ", NULL},
+{"LYS: OXT", " C ", NULL},
+{"LYS: OT1", " C ", NULL},
+{"LYS: OT2", " C ", NULL},
+{"LYS: CA ", " N : NT : C : CB ", NULL},
+{"LYS: CB ", " CA : CG ", NULL},
+{"LYS: CG ", " CB : CD ", NULL},
+{"LYS: CD ", " CG : CE ", NULL},
+{"LYS: CE ", " CD : NZ ", NULL},
+{"LYS: NZ ", " CE ", NULL},
+
+{"LEU: N ", " CA ", NULL},
+{"LEU: NT ", " CA ", NULL},
+{"LEU: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"LEU: O ", " C ", NULL},
+{"LEU: OXT", " C ", NULL},
+{"LEU: OT1", " C ", NULL},
+{"LEU: OT2", " C ", NULL},
+{"LEU: CA ", " N : NT : C : CB ", NULL},
+{"LEU: CB ", " CA : CG ", NULL},
+{"LEU: CG ", " CB : CD1: CD2", NULL},
+{"LEU: CD1", " CG ", NULL},
+{"LEU: CD2", " CG ", NULL},
+
+{"MET: N ", " CA ", NULL},
+{"MET: NT ", " CA ", NULL},
+{"MET: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"MET: O ", " C ", NULL},
+{"MET: OXT", " C ", NULL},
+{"MET: OT1", " C ", NULL},
+{"MET: OT2", " C ", NULL},
+{"MET: CA ", " N : NT : C : CB ", NULL},
+{"MET: CB ", " CA : CG ", NULL},
+{"MET: CG ", " CB : SD ", NULL},
+{"MET: SD ", " CG : CE ", NULL},
+{"MET: CE ", " SD ", NULL},
+
+{"ASN: N ", " CA ", NULL},
+{"ASN: NT ", " CA ", NULL},
+{"ASN: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"ASN: O ", " C ", NULL},
+{"ASN: OXT", " C ", NULL},
+{"ASN: OT1", " C ", NULL},
+{"ASN: OT2", " C ", NULL},
+{"ASN: CA ", " N : NT : C : CB ", NULL},
+{"ASN: CB ", " CA : CG ", NULL},
+{"ASN: CG ", " CB : OD1: ND2", NULL},
+{"ASN: OD1", " CG ", NULL},
+{"ASN: ND2", " CG ", NULL},
+
+{"PRO: N ", " CA : CD ", NULL},
+{"PRO: NT ", " CA : CD ", NULL},
+{"PRO: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"PRO: O ", " C ", NULL},
+{"PRO: OXT", " C ", NULL},
+{"PRO: OT1", " C ", NULL},
+{"PRO: OT2", " C ", NULL},
+{"PRO: CA ", " N : NT : C : CB ", NULL},
+{"PRO: CB ", " CA : CG ", NULL},
+{"PRO: CG ", " CB : CD ", NULL},
+{"PRO: CD ", " CG : N : NT ", NULL},
+
+{"GLN: N ", " CA ", NULL},
+{"GLN: NT ", " CA ", NULL},
+{"GLN: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"GLN: O ", " C ", NULL},
+{"GLN: OXT", " C ", NULL},
+{"GLN: OT1", " C ", NULL},
+{"GLN: OT2", " C ", NULL},
+{"GLN: CA ", " N : NT : C : CB ", NULL},
+{"GLN: CB ", " CA : CG ", NULL},
+{"GLN: CG ", " CB : CD ", NULL},
+{"GLN: CD ", " CG : OE1: NE2", NULL},
+{"GLN: OE1", " CD ", NULL},
+{"GLN: NE2", " CD ", NULL},
+
+{"ARG: N ", " CA ", NULL},
+{"ARG: NT ", " CA ", NULL},
+{"ARG: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"ARG: O ", " C ", NULL},
+{"ARG: OXT", " C ", NULL},
+{"ARG: OT1", " C ", NULL},
+{"ARG: OT2", " C ", NULL},
+{"ARG: CA ", " N : NT : C : CB ", NULL},
+{"ARG: CB ", " CA : CG ", NULL},
+{"ARG: CG ", " CB : CD ", NULL},
+{"ARG: CD ", " CG : NE ", NULL},
+{"ARG: NE ", " CD : CZ ", NULL},
+{"ARG: CZ ", " NE : NH1: NH2", NULL},
+{"ARG: NH1", " CZ ", NULL},
+{"ARG: NH2", " CZ ", NULL},
+
+{"SER: N ", " CA ", NULL},
+{"SER: NT ", " CA ", NULL},
+{"SER: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"SER: O ", " C ", NULL},
+{"SER: OXT", " C ", NULL},
+{"SER: OT1", " C ", NULL},
+{"SER: OT2", " C ", NULL},
+{"SER: CA ", " N : NT : C : CB ", NULL},
+{"SER: CB ", " CA : OG ", NULL},
+{"SER: OG ", " CB ", NULL},
+
+{"THR: N ", " CA ", NULL},
+{"THR: NT ", " CA ", NULL},
+{"THR: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"THR: O ", " C ", NULL},
+{"THR: OXT", " C ", NULL},
+{"THR: OT1", " C ", NULL},
+{"THR: OT2", " C ", NULL},
+{"THR: CA ", " N : NT : C : CB ", NULL},
+{"THR: CB ", " CA : OG1: CG2", NULL},
+{"THR: OG1", " CB ", NULL},
+{"THR: CG2", " CB ", NULL},
+
+{"VAL: N ", " CA ", NULL},
+{"VAL: NT ", " CA ", NULL},
+{"VAL: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"VAL: O ", " C ", NULL},
+{"VAL: OXT", " C ", NULL},
+{"VAL: OT1", " C ", NULL},
+{"VAL: OT2", " C ", NULL},
+{"VAL: CA ", " N : NT : C : CB ", NULL},
+{"VAL: CB ", " CA : CG1: CG2", NULL},
+{"VAL: CG1", " CB ", NULL},
+{"VAL: CG2", " CB ", NULL},
+
+{"TRP: N ", " CA ", NULL},
+{"TRP: NT ", " CA ", NULL},
+{"TRP: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"TRP: O ", " C ", NULL},
+{"TRP: OXT", " C ", NULL},
+{"TRP: OT1", " C ", NULL},
+{"TRP: OT2", " C ", NULL},
+{"TRP: CA ", " N : NT : C : CB ", NULL},
+{"TRP: CB ", " CA : CG ", NULL},
+{"TRP: CG ", " CB : CD1: CD2", NULL},
+{"TRP: CD1", " CG : NE1", NULL},
+{"TRP: CD2", " CG : CE2: CE3", NULL},
+{"TRP: NE1", " CD1: CE2", NULL},
+{"TRP: CE2", " NE1: CD2: CZ2", NULL},
+{"TRP: CZ2", " CE2: CH2", NULL},
+{"TRP: CE3", " CD2: CZ3", NULL},
+{"TRP: CZ3", " CE3: CH2", NULL},
+{"TRP: CH2", " CZ2: CZ3", NULL},
+
+{"TYR: N ", " CA ", NULL},
+{"TYR: NT ", " CA ", NULL},
+{"TYR: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"TYR: O ", " C ", NULL},
+{"TYR: OXT", " C ", NULL},
+{"TYR: OT1", " C ", NULL},
+{"TYR: OT2", " C ", NULL},
+{"TYR: CA ", " N : NT : C : CB ", NULL},
+{"TYR: CB ", " CA : CG ", NULL},
+{"TYR: CG ", " CB : CD1: CD2", NULL},
+{"TYR: CD1", " CG : CE1", NULL},
+{"TYR: CD2", " CG : CE2", NULL},
+{"TYR: CE1", " CD1: CZ ", NULL},
+{"TYR: CE2", " CD2: CZ ", NULL},
+{"TYR: CZ ", " CE1: CE2: OH ", NULL},
+{"TYR: OH ", " CZ ", NULL},
+
+{"ASX: N ", " CA ", NULL},
+{"ASX: NT ", " CA ", NULL},
+{"ASX: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"ASX: O ", " C ", NULL},
+{"ASX: OXT", " C ", NULL},
+{"ASX: OT1", " C ", NULL},
+{"ASX: OT2", " C ", NULL},
+{"ASX: CA ", " N : NT : C : CB ", NULL},
+{"ASX: CB ", " CA : CG ", NULL},
+{"ASX: CG ", " CB : OD1: ND2: AD1: AD2: XD1: XD2", NULL}, /* remediated RMI 070718 */
+{"ASX: OD1", " CG ", NULL},
+{"ASX: AD1", " CG ", NULL},
+{"ASX: XD1", " CG ", NULL}, /* */
+{"ASX: ND2", " CG ", NULL},
+{"ASX: AD2", " CG ", NULL},
+{"ASX: XD2", " CG ", NULL}, /* */
+
+{"GLX: N ", " CA ", NULL},
+{"GLX: NT ", " CA ", NULL},
+{"GLX: C ", " CA : O : OXT: OT1: OT2", NULL},
+{"GLX: O ", " C ", NULL},
+{"GLX: OXT", " C ", NULL},
+{"GLX: OT1", " C ", NULL},
+{"GLX: OT2", " C ", NULL},
+{"GLX: CA ", " N : NT : C : CB ", NULL},
+{"GLX: CB ", " CA : CG ", NULL},
+{"GLX: CG ", " CB : CD ", NULL},
+{"GLX: CD ", " CG : OE1: NE2: AE1: AE2: XE1: XE2", NULL}, /* remediated RMI 070718 */
+{"GLX: OE1", " CD ", NULL},
+{"GLX: AE1", " CD ", NULL},
+{"GLX: XE1", " CD ", NULL}, /* */
+{"GLX: NE2", " CD ", NULL},
+{"GLX: AE2", " CD ", NULL},
+{"GLX: XE2", " CD ", NULL}, /* */
+
+{" U: C1*", " N1 : C2*: O4*", NULL},
+{" U: C1'", " N1 : C2': O4'", NULL},
+{" U: C2*", " C3*: O2*: C1*", NULL},
+{" U: O2*", " C2*", NULL},
+{" U: C3*", " C4*: O3*: C2*", NULL},
+{" U: O3*", " C3*", NULL},
+{" U: C4*", " C5*: O4*: C3*", NULL},
+{" U: O4*", " C4*: C1*", NULL},
+{" U: C5*", " C4*: O5*", NULL},
+{" U: O5*", " C5*: P : PA ", NULL},
+{" U: C2'", " C3': O2': C1'", NULL},
+{" U: O2'", " C2'", NULL},
+{" U: C3'", " C4': O3': C2'", NULL},
+{" U: O3'", " C3'", NULL},
+{" U: C4'", " C5': O4': C3'", NULL},
+{" U: O4'", " C4': C1'", NULL},
+{" U: C5'", " C4': O5'", NULL},
+{" U: O5'", " C5': P : PA ", NULL},
+{" U: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" U: O1P", " P ", NULL}, /* */
+{" U: O2P", " P ", NULL}, /* */
+{" U: O3P", " P ", NULL}, /* */
+{" U: OP1", " P ", NULL},
+{" U: OP2", " P ", NULL},
+{" U: OP3", " P ", NULL},
+{" U: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" U: O1A", " PA ", NULL},
+{" U: O2A", " PA ", NULL},
+{" U: O3A", " PA : PB ", NULL},
+{" U: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" U: O1B", " PB ", NULL},
+{" U: O2B", " PB ", NULL},
+{" U: O3B", " PB : PG ", NULL},
+{" U: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" U: O1G", " PG ", NULL},
+{" U: O2G", " PG ", NULL},
+{" U: O3G", " PG ", NULL},
+{" U: S1G", " PG ", NULL},
+{" U: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" U: C2 ", " N1 : N3 : O2 ", NULL},
+{" U: N3 ", " C2 : C4 ", NULL},
+{" U: C4 ", " N3 : C5 : O4 ", NULL},
+{" U: C5 ", " C4 : C6 ", NULL},
+{" U: C6 ", " C5 : N1 ", NULL},
+{" U: O2 ", " C2 ", NULL},
+{" U: O4 ", " C4 ", NULL},
+
+{" T: C1*", " N1 : C2*: O4*", NULL},
+{" T: C1'", " N1 : C2': O4'", NULL},
+{" T: C2*", " C3*: O2*: C1*", NULL},
+{" T: O2*", " C2*", NULL},
+{" T: C3*", " C4*: O3*: C2*", NULL},
+{" T: O3*", " C3*", NULL},
+{" T: C4*", " C5*: O4*: C3*", NULL},
+{" T: O4*", " C4*: C1*", NULL},
+{" T: C5*", " C4*: O5*", NULL},
+{" T: O5*", " C5*: P : PA ", NULL},
+{" T: C2'", " C3': O2': C1'", NULL},
+{" T: O2'", " C2'", NULL},
+{" T: C3'", " C4': O3': C2'", NULL},
+{" T: O3'", " C3'", NULL},
+{" T: C4'", " C5': O4': C3'", NULL},
+{" T: O4'", " C4': C1'", NULL},
+{" T: C5'", " C4': O5'", NULL},
+{" T: O5'", " C5': P : PA ", NULL},
+{" T: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" T: O1P", " P ", NULL}, /* */
+{" T: O2P", " P ", NULL}, /* */
+{" T: O3P", " P ", NULL}, /* */
+{" T: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" T: O1A", " PA ", NULL},
+{" T: O2A", " PA ", NULL},
+{" T: O3A", " PA : PB ", NULL},
+{" T: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" T: O1B", " PB ", NULL},
+{" T: O2B", " PB ", NULL},
+{" T: O3B", " PB : PG ", NULL},
+{" T: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" T: O1G", " PG ", NULL},
+{" T: O2G", " PG ", NULL},
+{" T: O3G", " PG ", NULL},
+{" T: S1G", " PG ", NULL},
+{" T: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" T: C2 ", " N1 : N3 : O2 ", NULL},
+{" T: N3 ", " C2 : C4 ", NULL},
+{" T: C4 ", " N3 : C5 : O4 ", NULL},
+{" T: C5 ", " C4 : C6 : C5M: C5A: CM5: CA5: C7 ", NULL}, /* remediated RMI 070718 */
+{" T: C6 ", " C5 : N1 ", NULL},
+{" T: O2 ", " C2 ", NULL},
+{" T: O4 ", " C4 ", NULL},
+{" T: C5M", " C5 ", NULL},
+{" T: C5A", " C5 ", NULL},
+{" T: CM5", " C5 ", NULL},
+{" T: CA5", " C5 ", NULL},
+{" T: C7 ", " C5 ", NULL}, /* */
+
+
+{" C: C1*", " N1 : C2*: O4*", NULL},
+{" C: C1'", " N1 : C2': O4'", NULL},
+{" C: C2*", " C3*: O2*: C1*", NULL},
+{" C: O2*", " C2*", NULL},
+{" C: C3*", " C4*: O3*: C2*", NULL},
+{" C: O3*", " C3*", NULL},
+{" C: C4*", " C5*: O4*: C3*", NULL},
+{" C: O4*", " C4*: C1*", NULL},
+{" C: C5*", " C4*: O5*", NULL},
+{" C: O5*", " C5*: P : PA ", NULL},
+{" C: C2'", " C3': O2': C1'", NULL},
+{" C: O2'", " C2'", NULL},
+{" C: C3'", " C4': O3': C2'", NULL},
+{" C: O3'", " C3'", NULL},
+{" C: C4'", " C5': O4': C3'", NULL},
+{" C: O4'", " C4': C1'", NULL},
+{" C: C5'", " C4': O5'", NULL},
+{" C: O5'", " C5': P : PA ", NULL},
+{" C: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" C: O1P", " P ", NULL}, /* */
+{" C: O2P", " P ", NULL}, /* */
+{" C: O3P", " P ", NULL}, /* */
+{" C: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" C: O1A", " PA ", NULL},
+{" C: O2A", " PA ", NULL},
+{" C: O3A", " PA : PB ", NULL},
+{" C: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" C: O1B", " PB ", NULL},
+{" C: O2B", " PB ", NULL},
+{" C: O3B", " PB : PG ", NULL},
+{" C: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" C: O1G", " PG ", NULL},
+{" C: O2G", " PG ", NULL},
+{" C: O3G", " PG ", NULL},
+{" C: S1G", " PG ", NULL},
+{" C: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" C: C2 ", " N1 : N3 : O2 ", NULL},
+{" C: N3 ", " C2 : C4 ", NULL},
+{" C: C4 ", " N3 : C5 : N4 ", NULL},
+{" C: C5 ", " C4 : C6 ", NULL},
+{" C: C6 ", " C5 : N1 ", NULL},
+{" C: O2 ", " C2 ", NULL},
+{" C: N4 ", " C4 ", NULL},
+
+{" A: C1*", " N9 : C2*: O4*", NULL},
+{" A: C1'", " N9 : C2': O4'", NULL},
+{" A: C2*", " C3*: O2*: C1*", NULL},
+{" A: O2*", " C2*", NULL},
+{" A: C3*", " C4*: O3*: C2*", NULL},
+{" A: O3*", " C3*", NULL},
+{" A: C4*", " C5*: O4*: C3*", NULL},
+{" A: O4*", " C4*: C1*", NULL},
+{" A: C5*", " C4*: O5*", NULL},
+{" A: O5*", " C5*: P : PA ", NULL},
+{" A: C2'", " C3': O2': C1'", NULL},
+{" A: O2'", " C2'", NULL},
+{" A: C3'", " C4': O3': C2'", NULL},
+{" A: O3'", " C3'", NULL},
+{" A: C4'", " C5': O4': C3'", NULL},
+{" A: O4'", " C4': C1'", NULL},
+{" A: C5'", " C4': O5'", NULL},
+{" A: O5'", " C5': P : PA ", NULL},
+{" A: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" A: O1P", " P ", NULL}, /* */
+{" A: O2P", " P ", NULL}, /* */
+{" A: O3P", " P ", NULL}, /* */
+{" A: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" A: O1A", " PA ", NULL},
+{" A: O2A", " PA ", NULL},
+{" A: O3A", " PA : PB ", NULL},
+{" A: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" A: O1B", " PB ", NULL},
+{" A: O2B", " PB ", NULL},
+{" A: O3B", " PB : PG ", NULL},
+{" A: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" A: O1G", " PG ", NULL},
+{" A: O2G", " PG ", NULL},
+{" A: O3G", " PG ", NULL},
+{" A: S1G", " PG ", NULL},
+{" A: N9 ", " C8 : C4 : C1*: C1'", NULL},
+{" A: C8 ", " N9 : N7 ", NULL},
+{" A: N7 ", " C8 : C5 ", NULL},
+{" A: C5 ", " N7 : C6 : C4 ", NULL},
+{" A: C6 ", " C5 : N6 : N1 ", NULL},
+{" A: N6 ", " C6 ", NULL},
+{" A: N1 ", " C6 : C2 ", NULL},
+{" A: C2 ", " N1 : N3 ", NULL},
+{" A: N3 ", " C2 : C4 ", NULL},
+{" A: C4 ", " N9 : C5 : N3 ", NULL},
+
+{" G: C1*", " N9 : C2*: O4*", NULL},
+{" G: C1'", " N9 : C2': O4'", NULL},
+{" G: C2*", " C3*: O2*: C1*", NULL},
+{" G: O2*", " C2*", NULL},
+{" G: C3*", " C4*: O3*: C2*", NULL},
+{" G: O3*", " C3*", NULL},
+{" G: C4*", " C5*: O4*: C3*", NULL},
+{" G: O4*", " C4*: C1*", NULL},
+{" G: C5*", " C4*: O5*", NULL},
+{" G: O5*", " C5*: P : PA ", NULL},
+{" G: C2'", " C3': O2': C1'", NULL},
+{" G: O2'", " C2'", NULL},
+{" G: C3'", " C4': O3': C2'", NULL},
+{" G: O3'", " C3'", NULL},
+{" G: C4'", " C5': O4': C3'", NULL},
+{" G: O4'", " C4': C1'", NULL},
+{" G: C5'", " C4': O5'", NULL},
+{" G: O5'", " C5': P : PA ", NULL},
+{" G: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" G: O1P", " P ", NULL}, /* */
+{" G: O2P", " P ", NULL}, /* */
+{" G: O3P", " P ", NULL}, /* */
+{" G: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" G: O1A", " PA ", NULL},
+{" G: O2A", " PA ", NULL},
+{" G: O3A", " PA : PB ", NULL},
+{" G: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" G: O1B", " PB ", NULL},
+{" G: O2B", " PB ", NULL},
+{" G: O3B", " PB : PG ", NULL},
+{" G: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" G: O1G", " PG ", NULL},
+{" G: O2G", " PG ", NULL},
+{" G: O3G", " PG ", NULL},
+{" G: S1G", " PG ", NULL},
+{" G: N9 ", " C8 : C4 : C1*: C1'", NULL},
+{" G: C8 ", " N9 : N7 ", NULL},
+{" G: N7 ", " C8 : C5 ", NULL},
+{" G: C5 ", " N7 : C6 : C4 ", NULL},
+{" G: C6 ", " C5 : O6 : N1 ", NULL},
+{" G: O6 ", " C6 ", NULL},
+{" G: N1 ", " C6 : C2 ", NULL},
+{" G: C2 ", " N1 : N2 : N3 ", NULL},
+{" G: N2 ", " C2 ", NULL},
+{" G: N3 ", " C2 : C4 ", NULL},
+{" G: C4 ", " N9 : C5 : N3 ", NULL},
+
+/* DNA in the remediated system is DA, DT, DG, DC */
+
+{" DT: C1*", " N1 : C2*: O4*", NULL},
+{" DT: C1'", " N1 : C2': O4'", NULL},
+{" DT: C2*", " C3*: C1*", NULL},
+{" DT: C3*", " C4*: O3*: C2*", NULL},
+{" DT: O3*", " C3*", NULL},
+{" DT: C4*", " C5*: O4*: C3*", NULL},
+{" DT: O4*", " C4*: C1*", NULL},
+{" DT: C5*", " C4*: O5*", NULL},
+{" DT: O5*", " C5*: P : PA ", NULL},
+{" DT: C2'", " C3': C1'", NULL},
+{" DT: C3'", " C4': O3': C2'", NULL},
+{" DT: O3'", " C3'", NULL},
+{" DT: C4'", " C5': O4': C3'", NULL},
+{" DT: O4'", " C4': C1'", NULL},
+{" DT: C5'", " C4': O5'", NULL},
+{" DT: O5'", " C5': P : PA ", NULL},
+{" DT: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" DT: O1P", " P ", NULL}, /* */
+{" DT: O2P", " P ", NULL}, /* */
+{" DT: O3P", " P ", NULL}, /* */
+{" DT: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" DT: O1A", " PA ", NULL},
+{" DT: O2A", " PA ", NULL},
+{" DT: O3A", " PA : PB ", NULL},
+{" DT: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" DT: O1B", " PB ", NULL},
+{" DT: O2B", " PB ", NULL},
+{" DT: O3B", " PB : PG ", NULL},
+{" DT: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" DT: O1G", " PG ", NULL},
+{" DT: O2G", " PG ", NULL},
+{" DT: O3G", " PG ", NULL},
+{" DT: S1G", " PG ", NULL},
+{" DT: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" DT: C2 ", " N1 : N3 ", NULL},
+{" DT: N3 ", " C2 : C4 ", NULL},
+{" DT: C4 ", " N3 : C5 : O4 ", NULL},
+{" DT: C5 ", " C4 : C6 : C5M: C5A: CM5: CA5: C7 ", NULL}, /* remediated RMI 070718 */
+{" DT: C6 ", " C5 : N1 ", NULL},
+{" DT: O4 ", " C4 ", NULL},
+{" DT: C5M", " C5 ", NULL},
+{" DT: C5A", " C5 ", NULL},
+{" DT: CM5", " C5 ", NULL},
+{" DT: CA5", " C5 ", NULL},
+{" DT: C7 ", " C5 ", NULL}, /* */
+
+
+{" DC: C1*", " N1 : C2*: O4*", NULL},
+{" DC: C1'", " N1 : C2': O4'", NULL},
+{" DC: C2*", " C3*: C1*", NULL},
+{" DC: C3*", " C4*: O3*: C2*", NULL},
+{" DC: O3*", " C3*", NULL},
+{" DC: C4*", " C5*: O4*: C3*", NULL},
+{" DC: O4*", " C4*: C1*", NULL},
+{" DC: C5*", " C4*: O5*", NULL},
+{" DC: O5*", " C5*: P : PA ", NULL},
+{" DC: C2'", " C3': C1'", NULL},
+{" DC: C3'", " C4': O3': C2'", NULL},
+{" DC: O3'", " C3'", NULL},
+{" DC: C4'", " C5': O4': C3'", NULL},
+{" DC: O4'", " C4': C1'", NULL},
+{" DC: C5'", " C4': O5'", NULL},
+{" DC: O5'", " C5': P : PA ", NULL},
+{" DC: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" DC: O1P", " P ", NULL}, /* */
+{" DC: O2P", " P ", NULL}, /* */
+{" DC: O3P", " P ", NULL}, /* */
+{" DC: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" DC: O1A", " PA ", NULL},
+{" DC: O2A", " PA ", NULL},
+{" DC: O3A", " PA : PB ", NULL},
+{" DC: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" DC: O1B", " PB ", NULL},
+{" DC: O2B", " PB ", NULL},
+{" DC: O3B", " PB : PG ", NULL},
+{" DC: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" DC: O1G", " PG ", NULL},
+{" DC: O2G", " PG ", NULL},
+{" DC: O3G", " PG ", NULL},
+{" DC: S1G", " PG ", NULL},
+{" DC: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" DC: C2 ", " N1 : N3 ", NULL},
+{" DC: N3 ", " C2 : C4 ", NULL},
+{" DC: C4 ", " N3 : C5 : N4 ", NULL},
+{" DC: C5 ", " C4 : C6 ", NULL},
+{" DC: C6 ", " C5 : N1 ", NULL},
+{" DC: N4 ", " C4 ", NULL},
+
+{" DA: C1*", " N9 : C2*: O4*", NULL},
+{" DA: C1'", " N9 : C2': O4'", NULL},
+{" DA: C2*", " C3*: C1*", NULL},
+{" DA: C3*", " C4*: O3*: C2*", NULL},
+{" DA: O3*", " C3*", NULL},
+{" DA: C4*", " C5*: O4*: C3*", NULL},
+{" DA: O4*", " C4*: C1*", NULL},
+{" DA: C5*", " C4*: O5*", NULL},
+{" DA: O5*", " C5*: P : PA ", NULL},
+{" DA: C2'", " C3': C1'", NULL},
+{" DA: C3'", " C4': O3': C2'", NULL},
+{" DA: O3'", " C3'", NULL},
+{" DA: C4'", " C5': O4': C3'", NULL},
+{" DA: O4'", " C4': C1'", NULL},
+{" DA: C5'", " C4': O5'", NULL},
+{" DA: O5'", " C5': P : PA ", NULL},
+{" DA: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" DA: O1P", " P ", NULL}, /* */
+{" DA: O2P", " P ", NULL}, /* */
+{" DA: O3P", " P ", NULL}, /* */
+{" DA: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" DA: O1A", " PA ", NULL},
+{" DA: O2A", " PA ", NULL},
+{" DA: O3A", " PA : PB ", NULL},
+{" DA: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" DA: O1B", " PB ", NULL},
+{" DA: O2B", " PB ", NULL},
+{" DA: O3B", " PB : PG ", NULL},
+{" DA: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" DA: O1G", " PG ", NULL},
+{" DA: O2G", " PG ", NULL},
+{" DA: O3G", " PG ", NULL},
+{" DA: S1G", " PG ", NULL},
+{" DA: N9 ", " C8 : C4 : C1*: C1'", NULL},
+{" DA: C8 ", " N9 : N7 ", NULL},
+{" DA: N7 ", " C8 : C5 ", NULL},
+{" DA: C5 ", " N7 : C6 : C4 ", NULL},
+{" DA: C6 ", " C5 : N6 : N1 ", NULL},
+{" DA: N6 ", " C6 ", NULL},
+{" DA: N1 ", " C6 : C2 ", NULL},
+{" DA: C2 ", " N1 : N3 ", NULL},
+{" DA: N3 ", " C2 : C4 ", NULL},
+{" DA: C4 ", " N9 : C5 : N3 ", NULL},
+
+{" DG: C1*", " N9 : C2*: O4*", NULL},
+{" DG: C1'", " N9 : C2': O4'", NULL},
+{" DG: C2*", " C3*: C1*", NULL},
+{" DG: C3*", " C4*: O3*: C2*", NULL},
+{" DG: O3*", " C3*", NULL},
+{" DG: C4*", " C5*: O4*: C3*", NULL},
+{" DG: O4*", " C4*: C1*", NULL},
+{" DG: C5*", " C4*: O5*", NULL},
+{" DG: O5*", " C5*: P : PA ", NULL},
+{" DG: C2'", " C3': C1'", NULL},
+{" DG: C3'", " C4': O3': C2'", NULL},
+{" DG: O3'", " C3'", NULL},
+{" DG: C4'", " C5': O4': C3'", NULL},
+{" DG: O4'", " C4': C1'", NULL},
+{" DG: C5'", " C4': O5'", NULL},
+{" DG: O5'", " C5': P : PA ", NULL},
+{" DG: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" DG: O1P", " P ", NULL}, /* */
+{" DG: O2P", " P ", NULL}, /* */
+{" DG: O3P", " P ", NULL}, /* */
+{" DG: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" DG: O1A", " PA ", NULL},
+{" DG: O2A", " PA ", NULL},
+{" DG: O3A", " PA : PB ", NULL},
+{" DG: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" DG: O1B", " PB ", NULL},
+{" DG: O2B", " PB ", NULL},
+{" DG: O3B", " PB : PG ", NULL},
+{" DG: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" DG: O1G", " PG ", NULL},
+{" DG: O2G", " PG ", NULL},
+{" DG: O3G", " PG ", NULL},
+{" DG: S1G", " PG ", NULL},
+{" DG: N9 ", " C8 : C4 : C1*: C1'", NULL},
+{" DG: C8 ", " N9 : N7 ", NULL},
+{" DG: N7 ", " C8 : C5 ", NULL},
+{" DG: C5 ", " N7 : C6 : C4 ", NULL},
+{" DG: C6 ", " C5 : O6 : N1 ", NULL},
+{" DG: O6 ", " C6 ", NULL},
+{" DG: N1 ", " C6 : C2 ", NULL},
+{" DG: C2 ", " N1 : N2 : N3 ", NULL},
+{" DG: N2 ", " C2 ", NULL},
+{" DG: N3 ", " C2 : C4 ", NULL},
+{" DG: C4 ", " N9 : C5 : N3 ", NULL},
+
+/* RNA for Coot and CCP4 Ar, Ur, Tr, Cr, Gr */
+
+{" UR: C1*", " N1 : C2*: O4*", NULL},
+{" UR: C1'", " N1 : C2': O4'", NULL},
+{" UR: C2*", " C3*: O2*: C1*", NULL},
+{" UR: O2*", " C2*", NULL},
+{" UR: C3*", " C4*: O3*: C2*", NULL},
+{" UR: O3*", " C3*", NULL},
+{" UR: C4*", " C5*: O4*: C3*", NULL},
+{" UR: O4*", " C4*: C1*", NULL},
+{" UR: C5*", " C4*: O5*", NULL},
+{" UR: O5*", " C5*: P : PA ", NULL},
+{" UR: C2'", " C3': O2': C1'", NULL},
+{" UR: O2'", " C2'", NULL},
+{" UR: C3'", " C4': O3': C2'", NULL},
+{" UR: O3'", " C3'", NULL},
+{" UR: C4'", " C5': O4': C3'", NULL},
+{" UR: O4'", " C4': C1'", NULL},
+{" UR: C5'", " C4': O5'", NULL},
+{" UR: O5'", " C5': P : PA ", NULL},
+{" UR: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" UR: O1P", " P ", NULL}, /* */
+{" UR: O2P", " P ", NULL}, /* */
+{" UR: O3P", " P ", NULL}, /* */
+{" UR: OP1", " P ", NULL},
+{" UR: OP2", " P ", NULL},
+{" UR: OP3", " P ", NULL},
+{" UR: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" UR: O1A", " PA ", NULL},
+{" UR: O2A", " PA ", NULL},
+{" UR: O3A", " PA : PB ", NULL},
+{" UR: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" UR: O1B", " PB ", NULL},
+{" UR: O2B", " PB ", NULL},
+{" UR: O3B", " PB : PG ", NULL},
+{" UR: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" UR: O1G", " PG ", NULL},
+{" UR: O2G", " PG ", NULL},
+{" UR: O3G", " PG ", NULL},
+{" UR: S1G", " PG ", NULL},
+{" UR: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" UR: C2 ", " N1 : N3 : O2 ", NULL},
+{" UR: N3 ", " C2 : C4 ", NULL},
+{" UR: C4 ", " N3 : C5 : O4 ", NULL},
+{" UR: C5 ", " C4 : C6 ", NULL},
+{" UR: C6 ", " C5 : N1 ", NULL},
+{" UR: O2 ", " C2 ", NULL},
+{" UR: O4 ", " C4 ", NULL},
+
+{" TR: C1*", " N1 : C2*: O4*", NULL},
+{" TR: C1'", " N1 : C2': O4'", NULL},
+{" TR: C2*", " C3*: O2*: C1*", NULL},
+{" TR: O2*", " C2*", NULL},
+{" TR: C3*", " C4*: O3*: C2*", NULL},
+{" TR: O3*", " C3*", NULL},
+{" TR: C4*", " C5*: O4*: C3*", NULL},
+{" TR: O4*", " C4*: C1*", NULL},
+{" TR: C5*", " C4*: O5*", NULL},
+{" TR: O5*", " C5*: P : PA ", NULL},
+{" TR: C2'", " C3': O2': C1'", NULL},
+{" TR: O2'", " C2'", NULL},
+{" TR: C3'", " C4': O3': C2'", NULL},
+{" TR: O3'", " C3'", NULL},
+{" TR: C4'", " C5': O4': C3'", NULL},
+{" TR: O4'", " C4': C1'", NULL},
+{" TR: C5'", " C4': O5'", NULL},
+{" TR: O5'", " C5': P : PA ", NULL},
+{" TR: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" TR: O1P", " P ", NULL}, /* */
+{" TR: O2P", " P ", NULL}, /* */
+{" TR: O3P", " P ", NULL}, /* */
+{" TR: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" TR: O1A", " PA ", NULL},
+{" TR: O2A", " PA ", NULL},
+{" TR: O3A", " PA : PB ", NULL},
+{" TR: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" TR: O1B", " PB ", NULL},
+{" TR: O2B", " PB ", NULL},
+{" TR: O3B", " PB : PG ", NULL},
+{" TR: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" TR: O1G", " PG ", NULL},
+{" TR: O2G", " PG ", NULL},
+{" TR: O3G", " PG ", NULL},
+{" TR: S1G", " PG ", NULL},
+{" TR: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" TR: C2 ", " N1 : N3 : O2 ", NULL},
+{" TR: N3 ", " C2 : C4 ", NULL},
+{" TR: C4 ", " N3 : C5 : O4 ", NULL},
+{" TR: C5 ", " C4 : C6 : C5M: C5A: CM5: CA5: C7 ", NULL}, /* remediated RMI 070718 */
+{" TR: C6 ", " C5 : N1 ", NULL},
+{" TR: O2 ", " C2 ", NULL},
+{" TR: O4 ", " C4 ", NULL},
+{" TR: C5M", " C5 ", NULL},
+{" TR: C5A", " C5 ", NULL},
+{" TR: CM5", " C5 ", NULL},
+{" TR: CA5", " C5 ", NULL},
+{" TR: C7 ", " C5 ", NULL}, /* */
+
+
+{" CR: C1*", " N1 : C2*: O4*", NULL},
+{" CR: C1'", " N1 : C2': O4'", NULL},
+{" CR: C2*", " C3*: O2*: C1*", NULL},
+{" CR: O2*", " C2*", NULL},
+{" CR: C3*", " C4*: O3*: C2*", NULL},
+{" CR: O3*", " C3*", NULL},
+{" CR: C4*", " C5*: O4*: C3*", NULL},
+{" CR: O4*", " C4*: C1*", NULL},
+{" CR: C5*", " C4*: O5*", NULL},
+{" CR: O5*", " C5*: P : PA ", NULL},
+{" CR: C2'", " C3': O2': C1'", NULL},
+{" CR: O2'", " C2'", NULL},
+{" CR: C3'", " C4': O3': C2'", NULL},
+{" CR: O3'", " C3'", NULL},
+{" CR: C4'", " C5': O4': C3'", NULL},
+{" CR: O4'", " C4': C1'", NULL},
+{" CR: C5'", " C4': O5'", NULL},
+{" CR: O5'", " C5': P : PA ", NULL},
+{" CR: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" CR: O1P", " P ", NULL}, /* */
+{" CR: O2P", " P ", NULL}, /* */
+{" CR: O3P", " P ", NULL}, /* */
+{" CR: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" CR: O1A", " PA ", NULL},
+{" CR: O2A", " PA ", NULL},
+{" CR: O3A", " PA : PB ", NULL},
+{" CR: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" CR: O1B", " PB ", NULL},
+{" CR: O2B", " PB ", NULL},
+{" CR: O3B", " PB : PG ", NULL},
+{" CR: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" CR: O1G", " PG ", NULL},
+{" CR: O2G", " PG ", NULL},
+{" CR: O3G", " PG ", NULL},
+{" CR: S1G", " PG ", NULL},
+{" CR: N1 ", " C2 : C6 : C1*: C1'", NULL},
+{" CR: C2 ", " N1 : N3 : O2 ", NULL},
+{" CR: N3 ", " C2 : C4 ", NULL},
+{" CR: C4 ", " N3 : C5 : N4 ", NULL},
+{" CR: C5 ", " C4 : C6 ", NULL},
+{" CR: C6 ", " C5 : N1 ", NULL},
+{" CR: O2 ", " C2 ", NULL},
+{" CR: N4 ", " C4 ", NULL},
+
+{" AR: C1*", " N9 : C2*: O4*", NULL},
+{" AR: C1'", " N9 : C2': O4'", NULL},
+{" AR: C2*", " C3*: O2*: C1*", NULL},
+{" AR: O2*", " C2*", NULL},
+{" AR: C3*", " C4*: O3*: C2*", NULL},
+{" AR: O3*", " C3*", NULL},
+{" AR: C4*", " C5*: O4*: C3*", NULL},
+{" AR: O4*", " C4*: C1*", NULL},
+{" AR: C5*", " C4*: O5*", NULL},
+{" AR: O5*", " C5*: P : PA ", NULL},
+{" AR: C2'", " C3': O2': C1'", NULL},
+{" AR: O2'", " C2'", NULL},
+{" AR: C3'", " C4': O3': C2'", NULL},
+{" AR: O3'", " C3'", NULL},
+{" AR: C4'", " C5': O4': C3'", NULL},
+{" AR: O4'", " C4': C1'", NULL},
+{" AR: C5'", " C4': O5'", NULL},
+{" AR: O5'", " C5': P : PA ", NULL},
+{" AR: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" AR: O1P", " P ", NULL}, /* */
+{" AR: O2P", " P ", NULL}, /* */
+{" AR: O3P", " P ", NULL}, /* */
+{" AR: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" AR: O1A", " PA ", NULL},
+{" AR: O2A", " PA ", NULL},
+{" AR: O3A", " PA : PB ", NULL},
+{" AR: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" AR: O1B", " PB ", NULL},
+{" AR: O2B", " PB ", NULL},
+{" AR: O3B", " PB : PG ", NULL},
+{" AR: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" AR: O1G", " PG ", NULL},
+{" AR: O2G", " PG ", NULL},
+{" AR: O3G", " PG ", NULL},
+{" AR: S1G", " PG ", NULL},
+{" AR: N9 ", " C8 : C4 : C1*: C1'", NULL},
+{" AR: C8 ", " N9 : N7 ", NULL},
+{" AR: N7 ", " C8 : C5 ", NULL},
+{" AR: C5 ", " N7 : C6 : C4 ", NULL},
+{" AR: C6 ", " C5 : N6 : N1 ", NULL},
+{" AR: N6 ", " C6 ", NULL},
+{" AR: N1 ", " C6 : C2 ", NULL},
+{" AR: C2 ", " N1 : N3 ", NULL},
+{" AR: N3 ", " C2 : C4 ", NULL},
+{" AR: C4 ", " N9 : C5 : N3 ", NULL},
+
+{" GR: C1*", " N9 : C2*: O4*", NULL},
+{" GR: C1'", " N9 : C2': O4'", NULL},
+{" GR: C2*", " C3*: O2*: C1*", NULL},
+{" GR: O2*", " C2*", NULL},
+{" GR: C3*", " C4*: O3*: C2*", NULL},
+{" GR: O3*", " C3*", NULL},
+{" GR: C4*", " C5*: O4*: C3*", NULL},
+{" GR: O4*", " C4*: C1*", NULL},
+{" GR: C5*", " C4*: O5*", NULL},
+{" GR: O5*", " C5*: P : PA ", NULL},
+{" GR: C2'", " C3': O2': C1'", NULL},
+{" GR: O2'", " C2'", NULL},
+{" GR: C3'", " C4': O3': C2'", NULL},
+{" GR: O3'", " C3'", NULL},
+{" GR: C4'", " C5': O4': C3'", NULL},
+{" GR: O4'", " C4': C1'", NULL},
+{" GR: C5'", " C4': O5'", NULL},
+{" GR: O5'", " C5': P : PA ", NULL},
+{" GR: P ", " O5*: O5': O1P: O2P: O3P: OP1: OP2: OP3", NULL}, /* remediated RMI 070718 */
+{" GR: O1P", " P ", NULL}, /* */
+{" GR: O2P", " P ", NULL}, /* */
+{" GR: O3P", " P ", NULL}, /* */
+{" GR: PA ", " O5*: O5': O1A: O2A: O3A", NULL},
+{" GR: O1A", " PA ", NULL},
+{" GR: O2A", " PA ", NULL},
+{" GR: O3A", " PA : PB ", NULL},
+{" GR: PB ", " O5*: O5': O1B: O2B: O3B", NULL},
+{" GR: O1B", " PB ", NULL},
+{" GR: O2B", " PB ", NULL},
+{" GR: O3B", " PB : PG ", NULL},
+{" GR: PG ", " O5*: O5': O1G: O2G: O3G : S1G", NULL},
+{" GR: O1G", " PG ", NULL},
+{" GR: O2G", " PG ", NULL},
+{" GR: O3G", " PG ", NULL},
+{" GR: S1G", " PG ", NULL},
+{" GR: N9 ", " C8 : C4 : C1*: C1'", NULL},
+{" GR: C8 ", " N9 : N7 ", NULL},
+{" GR: N7 ", " C8 : C5 ", NULL},
+{" GR: C5 ", " N7 : C6 : C4 ", NULL},
+{" GR: C6 ", " C5 : O6 : N1 ", NULL},
+{" GR: O6 ", " C6 ", NULL},
+{" GR: N1 ", " C6 : C2 ", NULL},
+{" GR: C2 ", " N1 : N2 : N3 ", NULL},
+{" GR: N2 ", " C2 ", NULL},
+{" GR: N3 ", " C2 : C4 ", NULL},
+{" GR: C4 ", " N9 : C5 : N3 ", NULL},
+
+
+{NULL, NULL, NULL}
+};
+
+/* initStdConnTable() - we have to do this once to setup the hash table */
+
+void initStdConnTable() {
+ StdResConnTableEntry_t *r;
+ int i;
+
+ for (i = 0; i < M; i++) { /* empty all the buckets */
+ StdResTblBucket[i] = NULL;
+ }
+
+ for( r = StandardResAtomConnRec; r->key != NULL; r++) {
+ InsertInStdResConnTable(r);
+ }
+}
+
+/* searchForStdBondingPartner() - given a residue name and atom name find the bonded atom */
+char * searchForStdBondingPartner(char *resname, char *atomname, int isAhydrogen) {
+ char querystring[10], *p;
+
+ /* a large part of this routine is devoted to converting residue names */
+ /* and atom names into a search pattern. This pattern is 8 chars long */
+ /* and all uppercase. It has a colon as the forth character, separating*/
+ /* residue name from atom name. Deuterum is converted to hydrogen. */
+
+ if (resname && atomname) {
+ if (resname[0]) {
+ querystring[0] = toupper(resname[0]);
+ if (resname[1]) {
+ querystring[1] = toupper(resname[1]);
+ querystring[2] = resname[2] ? toupper(resname[2]) : ' ';
+ }
+ else { querystring[1] = querystring[2] = ' '; }
+ }
+ else { querystring[0] = querystring[1] = querystring[2] = ' '; }
+ querystring[3] = ':';
+ if (atomname[0]) {
+ querystring[4] = toupper(atomname[0]);
+ if (atomname[1]) {
+ querystring[5] = toupper(atomname[1]);
+ if (atomname[2]) {
+ querystring[6] = toupper(atomname[2]);
+ querystring[7] = atomname[3] ? toupper(atomname[3]) : ' ';
+ }
+ else { querystring[6] = querystring[7] = ' '; }
+ }
+ else { querystring[5] = querystring[6] = querystring[7] = ' '; }
+ }
+ else {
+ querystring[4] = querystring[5] = ' ';
+ querystring[6] = querystring[7] = ' ';
+ }
+ querystring[8] = '\0';
+
+ if (isAhydrogen) {
+ /* because we know atomname is for a hydrogen atom we can */
+ /* make the following fixup for deuterium atoms */
+ if ((querystring[4] == 'D') && (querystring[7] != ' ')) {
+ querystring[4] = 'H';
+ }
+ else if ((querystring[4] != 'H') && (querystring[5] == 'D')) {
+ querystring[5] = 'H';
+ }
+ }
+
+ p = SearchStdResConnTable(querystring);
+
+ if (p == NULL) {
+ /* if failed because of a non-std nucleic acid residue name */
+ /* convert to "..X" and retry */
+
+ char *naALTlist = ":GUA:GTP:GDP:GMP:GSP:ADE:ATP:ADP:AMP:CYT:CTP:CDP:CMP:URA:UTP:UDP:UMP:THY:TTP:TDP:TMP: DA: DT: DC: DG: AR: UR: TR: CR: GR:";
+
+ querystring[3] = '\0'; /* temporarily look at just the first three chars */
+ if (strstr(naALTlist, querystring)) {
+ /* fixup common alternate nucleic acid residue names */
+ if(strstr(":GUA:GTP:GDP:GMP:GSP: DG: GR:", querystring)) {
+ querystring[2] = 'G';
+ }
+ else if(strstr(":ADE:ATP:ADP:AMP: DA: AR:", querystring)) {
+ querystring[2] = 'A';
+ }
+ else if(strstr(":CYT:CTP:CDP:CMP: DC: CR:", querystring)) {
+ querystring[2] = 'C';
+ }
+ else if(strstr(":URA:UTP:UDP:UMP: UR:", querystring)) {
+ querystring[2] = 'U';
+ }
+ else if(strstr(":THY:TTP:TDP:TMP: DT: TR:", querystring)) {
+ querystring[2] = 'T';
+ }
+ else { querystring[2] = ' '; }
+
+ querystring[0] = querystring[1] = ' '; /* i.e., blank-blank-[GACUT] */
+ /* put the string back together */
+ querystring[3] = ':';
+
+ p = SearchStdResConnTable(querystring); /* second time is a charm */
+ }
+ }
+ }
+ else { p = NULL; }
+ return p;
+}
+
+/* Hash function from PJ Weinberger's compiler as described */
+/* in Aho, Sethi & Ullman, Compilers, Principles, Techniques & Tools */
+/* 1986, Addison Wesley, pg 436 */
+int HashInStdResTbl(char *s) {
+ unsigned h, g;
+
+ for (h = 0; *s != '\0'; s++) {
+ h = (h<<4) + *s;
+ if (g = h & 0xf0000000) {
+ h ^= g >> 24;
+ h ^= g;
+ }
+ }
+ return h % M;
+}
+
+/* InsertInStdResConnTable() - add an entry into the has table */
+int InsertInStdResConnTable(StdResConnTableEntry_t *elem) {
+ int r = 0, h = 0, rc = 1;
+ StdResConnTableEntry_t *t = NULL;
+
+ h = HashInStdResTbl(elem->key);
+ t = StdResTblBucket[h];
+
+ if (t == NULL) { /* nothing else stored at this h value yet */
+ elem->next = NULL; /* the cdr of the new list is Z */
+ StdResTblBucket[h] = elem; /* store the element at the head of the list */
+ }
+ else if ((r = strcmp(elem->key, t->key)) > 0) { /* key(e) > key(t), look further down list */
+
+ while (t->next && (r = strcmp(elem->key, t->next->key)) > 0) {
+ t = t->next;
+ }
+
+ if ((t->next == NULL) || (r != 0)) { /* hook elem in after t and before t->next */
+ elem->next = t->next;
+ t->next = elem;
+ }
+ else {
+ fprintf(stderr, "ERROR duplicate key: InsertInStdResConnTable(\"%s\", \"%s\") -- old(\"%s\" @%d)\n",
+ elem->key, elem->value, t->next->value, h);
+ rc = 0;
+ }
+ }
+ else if (r < 0) { /* the element comes ahead of the first list element */
+ elem->next = t; /* the cdr of the new list is the old list */
+ StdResTblBucket[h] = elem; /* store the element at the head of the list */
+ }
+ else { /* duplicate */
+ fprintf(stderr, "ERROR duplicate key: InsertInStdResConnTable(\"%s\", \"%s\") - old(\"%s\" @%d)\n",
+ elem->key, elem->value, t->value, h);
+ rc = 0;
+ }
+ return rc;
+}
+
+/* SearchStdResConnTable() - given a formatted search key, return the value in the hash table */
+char *SearchStdResConnTable(char *key) {
+ int r = 0;
+ StdResConnTableEntry_t *t;
+
+ t = StdResTblBucket[HashInStdResTbl(key)];
+
+ while (t && (r = strcmp(key, t->key)) > 0) {
+ t = t->next;
+ }
+
+ return (t ? (r ? NULL : t->value) : NULL);
+}
+
+/* dumpStdConnTable() - dump dictionary contents for debugging purposes */
+void dumpStdConnTable(FILE * outf) {
+ int h;
+ StdResConnTableEntry_t *t;
+
+ for (h = 0; h < M; h++) {
+ fprintf(outf, "%5d] ", h);
+ for (t = StdResTblBucket[h]; t; t = t->next) {
+ fprintf(outf, "(\"%s\" --> \"%s\") ", t->key, t->value);
+ }
+ fprintf(outf, "\n");
+ }
+}
diff --git a/stdconntable.h b/stdconntable.h
new file mode 100644
index 0000000..a7c0d9c
--- /dev/null
+++ b/stdconntable.h
@@ -0,0 +1,24 @@
+/* name: stdconntable.h */
+/* author: J. Michael Word Date Written: 11/15/98 */
+/* purpose: describes the bonding connectivies for */
+/* each std amino acid residue or */
+/* nucleic acid base */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef STDCONNTABLE_H
+#define STDCONNTABLE_H 1
+
+void initStdConnTable();
+char * searchForStdBondingPartner(char *resname, char *atomname, int isAhydrogen);
+void dumpStdConnTable(FILE * outf);
+
+#endif
diff --git a/utility.c b/utility.c
new file mode 100644
index 0000000..de68642
--- /dev/null
+++ b/utility.c
@@ -0,0 +1,167 @@
+/* name: utility.c */
+/* author: J. Michael Word */
+/* date written: 2/26/96 */
+/* purpose: utility functions */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#include "utility.h"
+#include <stdlib.h> /*060902 needs this for exit() */
+#include <stdio.h>
+#include <string.h> /*060902 needs this for strlen() */
+#include <ctype.h>
+
+#ifdef NEEDSTRCASECMP
+int strncasecmp(const char *buf, const char *pat, int sz) {
+ int rc = 0;
+ int i = 0;
+ for(; i < sz; i++) {
+ if (tolower(buf[i]) != tolower(pat[i])) { rc = 1; break; }
+ else if (buf[i] == '\0') { break; }
+ }
+ return rc;
+}
+int strcasecmp(const char *buf, const char *pat) {
+ int rc = 0;
+ int i = 0;
+ for(; buf[i] && pat[i]; i++) {
+ if (tolower(buf[i]) != tolower(pat[i])) { rc = 1; break; }
+ }
+ return rc;
+}
+#endif
+
+void note(char *message) {
+ fprintf(stderr, "%s\n", message);
+}
+
+void warn(char *message) {
+ fprintf(stderr, "WARNING: %s\n", message);
+}
+
+void errmsg(char *message) {
+ fprintf(stderr, "ERROR: %s\n", message);
+}
+
+void halt(char *message) {
+ fprintf(stderr, "ERROR: %s\n", message);
+ exit(1);
+}
+
+int parseInteger(char *str, int start, int len) {
+ register int value = 0;
+ register char ch;
+ int neg = 0, inside = 0;
+
+ if (!str || start < 0) { return 0; }
+ str += start;
+
+ while((len-- > 0) && *str) {
+ ch = *str++;
+ if ((ch >='0') && (ch <= '9')) {
+ value = (10*value) + (ch - '0');
+ inside = 1;
+ }
+ else if (ch == '+' && !inside) {
+ inside = 1;
+ }
+ else if (ch == '-' && !inside) {
+ neg = 1;
+ inside = 1;
+ }
+ else if (isspace(ch) && !inside) { /* nothing */ }
+ else break; /* end of integer */
+ }
+ return (neg?-value:value);
+}
+
+float parseReal(char *str, int start, int len) {
+ double value = 0.0, scale = 1.0;
+ register char ch;
+ int inside = 0, infract = 0;
+
+ if (!str || start < 0) { return 0; }
+ str += start;
+
+ while((len-- > 0) && *str) {
+ ch = *str++;
+ if ((ch >='0') && (ch <= '9')) {
+ value = (10.0*value) + (ch - '0');
+ if (infract) { scale *= 0.1; }
+ inside = 1;
+ }
+ else if (ch == '+' && !inside) {
+ inside = 1;
+ }
+ else if (ch == '-' && !inside) {
+ scale = -1.0;
+ inside = 1;
+ }
+ else if (ch == '.' && !infract) {
+ infract = 1;
+ }
+ else if (isspace(ch) && !inside) { /* nothing */ }
+ else break; /* end of real */
+ }
+ return value*scale;
+}
+
+void copyChars(char *to, char *from, int n) {
+ int i;
+
+ for(i=0; i<n; i++) { to[i] = from[i]; }
+}
+
+int compArgStr(char *str, char *arg, int min) {
+ int i, max;
+ char s, a;
+
+ if (!str || !arg) return 0;
+
+ max = strlen(arg);
+
+ for(i=0; i<max; i++) {
+ s = toupper(str[i]);
+ a = toupper(arg[i]);
+
+ if (i >= min && (s == '\0' || s == '.'
+ || s == '+' || s == '-' || isdigit(s))) {
+ break; /* good ending point */
+ }
+ else if (s != a) {
+ i = 0; /* failed to match */
+ break;
+ }
+ }
+
+ return i;
+}
+
+int nonblankstr(char *str) {
+ for(; *str; str++) {
+ if (! isspace(*str)) { return 1; }
+ }
+ return 0;
+}
+
+int nonblankrange(char *str, int start, int len) {
+ register int i;
+
+ for(i = 0; i < start; i++) {
+ if (*str++ == '\0') { return 0; }
+ }
+ for(i = 0; i < len; i++) {
+ if (*str == '\0') { break; }
+ if (! isspace(*str)) { return 1; }
+ str++;
+ }
+ return 0;
+}
diff --git a/utility.h b/utility.h
new file mode 100644
index 0000000..38bba36
--- /dev/null
+++ b/utility.h
@@ -0,0 +1,45 @@
+/* name: utility.h */
+/* author: J. Michael Word */
+/* date written: 2/26/96 */
+/* purpose: utility functions */
+
+/*****************************************************************/
+/* NOTICE: This is free software and the source code is freely */
+/* available. You are free to redistribute or modify under the */
+/* conditions that (1) this notice is not removed or modified */
+/* in any way and (2) any modified versions of the program are */
+/* also available for free. */
+/* ** Absolutely no Warranty ** */
+/* Copyright (C) 1999 J. Michael Word */
+/*****************************************************************/
+
+#ifndef UTILITY_H
+#define UTILITY_H 1
+
+#define TRUE 1
+#define FALSE 0
+
+#define FABS(x) (((x)<0.0)?-(x):(x))
+#define MIN(x,y) (((x)<(y))? (x):(y))
+#define MAX(x,y) (((x)>(y))? (x):(y))
+
+#if defined(__DECCXX_VER) || defined(_MSC_VER)
+#define NEEDSTRCASECMP
+#endif
+#ifdef NEEDSTRCASECMP
+int strncasecmp(const char *buf, const char *pat, int sz);
+int strcasecmp(const char *buf, const char *pat);
+#endif
+
+void note(char *message);
+void warn(char *message);
+void errmsg(char *message);
+void halt(char *message);
+
+int parseInteger(char *str, int start, int len);
+float parseReal(char *str, int start, int len);
+void copyChars(char *to, char *from, int n);
+int compArgStr(char *str, char *arg, int n);
+int nonblankstr(char *str);
+int nonblankrange(char *str, int start, int len);
+#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/probe.git
More information about the debian-med-commit
mailing list