[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