diff -NaurdbB -xCVS lsqrms-2.0.4b.old/AUTHORS lsqrms-2.0.4b/AUTHORS
--- lsqrms-2.0.4b.old/AUTHORS	Wed Mar 12 17:18:30 EST 2003
+++ lsqrms-2.0.4b/AUTHORS	Mon Feb 25 15:39:52 EST 2008
@@ -0,0 +1,4 @@
+Vadim Alexandrov (initial authorship; http://bioinfo.mbb.yale.edu/~vadim/)
+Julian Graham (April 2003)
+Allen Smith (modified 2003-2007; http://cesario.rutgers.edu/easmith/research/)
+
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/README lsqrms-2.0.4b/README
--- lsqrms-2.0.4b.old/README	Wed Mar 12 17:18:28 EST 2003
+++ lsqrms-2.0.4b/README	Sun Feb 24 22:49:52 EST 2008
@@ -0,0 +1,43 @@
+LSQRMS program. V. Alexandrov, Yale (2000).
+
+The LSQ fitting routine (when the program is called with "lsq" keyword) works 
+as follows. Assuming that the set of equivalence pairs for two structures (we 
+call them "moving" and "reference" structures, respectively) is determined, 
+e.g. found from the corresponding sequence alignment, the structural alignment
+is done in two steps. The first is to find the translation vector (TV) that 
+takes the center-of-mass (CM) of one structure to the other (easy: find CM 
+coordinates for each structure and subtract the CM vector of the "moving" 
+structure from the CM vector of the "fixed" one). The second step is to compute
+the matrix transformation (Rotation Matrix) that minimizes RMSD between the two
+structures after applying TV transformation to the moving structure from the 
+previous step. Note that CM for both structures is calculated based only on
+those C-alphas that are present in the set of equivalence pairs.
+
+After the CM (center-of-mass) of the "moving" structure is first moved to that
+of the "reference" structure (with help of the Translation Vector from the 
+previous step) the rotation matrix (RM) is computed using a wide-known method 
+suggested by Kabsch (1977). The method is based on finding the solution for the
+parameters of the 3D rotation matrix minimizing the RMSD of the CM-transformed
+structures (actually, their equivalence pairs only).
+
+After applying RM to the "moving" structure (preceded by TV translation), the
+RMSD is calculated between the coordinates for all the equivalence pairs.
+If the program is not called with "lsq" argument, it repeats the
+above-mentioned process (skipping the sequence alignment stage at each
+iteration) finding new equivalence pairs and minimizing RMSD in each iteration
+until it converges to some minimum value or until the program reaches the 
+maximum number of iterations (currently 100).
+
+If supplied with keyword "structal", the program outputs the resulting 
+structures (original "target" and rotated "query" structures + the
+corresponding equivalence pairs) in the original Structal format (Levitt, 
+1994). Otherwise, the program outputs only the new (rotated and translated) 
+coordinates of the query.
+
+Refs.
+
+1) Kabsch (Kabsch, W (1976) Acta Cryst. A32, 922-923) 
+2) Levitt, M., STRUCTAL. A structural alignment program, Stanford U, (1994).
+
+
+
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/README.txt lsqrms-2.0.4b/README.txt
--- lsqrms-2.0.4b.old/README.txt
+++ lsqrms-2.0.4b/README.txt	Sun Feb 24 22:49:52 EST 2008
@@ -0,0 +1,43 @@
+LSQRMS program. V. Alexandrov, Yale (2000).
+
+The LSQ fitting routine (when the program is called with "lsq" keyword) works 
+as follows. Assuming that the set of equivalence pairs for two structures (we 
+call them "moving" and "reference" structures, respectively) is determined, 
+e.g. found from the corresponding sequence alignment, the structural alignment
+is done in two steps. The first is to find the translation vector (TV) that 
+takes the center-of-mass (CM) of one structure to the other (easy: find CM 
+coordinates for each structure and subtract the CM vector of the "moving" 
+structure from the CM vector of the "fixed" one). The second step is to compute
+the matrix transformation (Rotation Matrix) that minimizes RMSD between the two
+structures after applying TV transformation to the moving structure from the 
+previous step. Note that CM for both structures is calculated based only on
+those C-alphas that are present in the set of equivalence pairs.
+
+After the CM (center-of-mass) of the "moving" structure is first moved to that
+of the "reference" structure (with help of the Translation Vector from the 
+previous step) the rotation matrix (RM) is computed using a wide-known method 
+suggested by Kabsch (1977). The method is based on finding the solution for the
+parameters of the 3D rotation matrix minimizing the RMSD of the CM-transformed
+structures (actually, their equivalence pairs only).
+
+After applying RM to the "moving" structure (preceded by TV translation), the
+RMSD is calculated between the coordinates for all the equivalence pairs.
+If the program is not called with "lsq" argument, it repeats the
+above-mentioned process (skipping the sequence alignment stage at each
+iteration) finding new equivalence pairs and minimizing RMSD in each iteration
+until it converges to some minimum value or until the program reaches the 
+maximum number of iterations (currently 100).
+
+If supplied with keyword "structal", the program outputs the resulting 
+structures (original "target" and rotated "query" structures + the
+corresponding equivalence pairs) in the original Structal format (Levitt, 
+1994). Otherwise, the program outputs only the new (rotated and translated) 
+coordinates of the query.
+
+Refs.
+
+1) Kabsch (Kabsch, W (1976) Acta Cryst. A32, 922-923) 
+2) Levitt, M., STRUCTAL. A structural alignment program, Stanford U, (1994).
+
+
+
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/dynapro.c lsqrms-2.0.4b/src/dynapro.c
--- lsqrms-2.0.4b.old/src/dynapro.c	Wed Apr 16 15:07:45 EDT 2003
+++ lsqrms-2.0.4b/src/dynapro.c	Sun Feb 24 22:49:49 EST 2008
@@ -1,49 +1,64 @@
+#include "umath.h"
+#include "matvecalloc.h"
 #include "dynapro.h"
 
-int    *iVector(long, long);
-int   **iMatrix(long, long, long, long);
-void free_iVector(int     *, long, long);
-void free_fMatrix(int    **, long, long, long, long);
+#define MAX_COLS MAXSEQ
+#define MAX_ROWS MAXSEQ
 
-double               /* OUT: maximum score in sum matrix                          */
-/*******/
-dyn_pr_n2
-/*******/
+#define INF_INT 2147480000
+
+#define STOP_TRACEBACK -1
+
 /* Sequence 1 runs down   matrix index by row index i.
    Sequence 2 runs across matrix index by row index j. */
-(double **s        /* IN:  similarity matrix               [0..rows-1][0..cols-1] */, 
- int *iOpnPen      /* IN:  gap-open pen. vector for seq. 1 [0..rows-1]            */, 
- int *iExtPen      /* IN:  gap-extend pen. vec. for seq. 1 [0..rows-1]            */, 
- int *jOpnPen      /* IN:  gap-open pen. vector for seq. 2 [0..cols-1]            */, 
- int *jExtPen      /* IN:  gap-extend pen. vec. for seq. 2 [0..cols-1]            */, 
- int rows          /* IN:  length of sequence 1 (Runs down matrix,  indexed by i) */,
- int cols          /* IN:  length of sequence 2 (Runs across matrix, indexed by j)*/,
- double **SS       /* OUT: sum matrix                      [0..rows-1][0..cols-1] */, 
- double **TrRow    /* OUT: traceback matrix with i index   [0..rows-1][0..cols-1] */, 
- double **TrCol    /* OUT: traceback matrix with j index   [0..rows-1][0..cols-1] */,
- int *iOverallMax  /* OUT: i index where overall max occurs 0..rows-1             */,
- int *jOverallMax  /* OUT: j index where overall max occurs 0..cols-1             */
-)
-{
-  double TrialScore, ColMax, BlkMax, RowMax;
-  int 
-    i,j,i2,j2, jRowMax,
-    iBlkMax, jBlkMax, 
-    iGapLength, jGapLength, iGapPenalty, jGapPenalty;
-  double OverallMax = - INF_INT;
+
+/* OUT: maximum score in sum matrix */
+double dyn_pr_n2
+(
+ /* IN:  similarity matrix [0..rows-1][0..cols-1] */
+ double **s,
+ /* IN:  gap-open pen. vector for seq. 1 [0..rows-1] */
+ int *iOpnPen,
+ /* IN:  gap-extend pen. vec. for seq. 1 [0..rows-1] */
+ double *iExtPen,
+ /* IN:  gap-open pen. vector for seq. 2 [0..cols-1] */
+ int *jOpnPen,
+ /* IN:  gap-extend pen. vec. for seq. 2 [0..cols-1] */
+ double *jExtPen,
+ /* IN:  residue number for seq. 1 [0..rows-1] */
+ int *iresnum,
+ /* IN:  residue number for seq. 2 [0..cols-1] */
+ int *jresnum,
+ /* IN:  length of sequence 1 (Runs down matrix, indexed by i) */
+ int rows,
+ /* IN:  length of sequence 2 (Runs across matrix, indexed by j)*/
+ int cols,
+ /* OUT: sum matrix [0..rows-1][0..cols-1] */
+ double **SS,
+ /* OUT: traceback matrix with i index [0..rows-1][0..cols-1] */
+ double **TrRow,
+ /* OUT: traceback matrix with j index [0..rows-1][0..cols-1] */
+ double **TrCol,
+ /* OUT: i index where overall max occurs 0..rows-1 */
+ int *iOverallMax,
+ /* OUT: j index where overall max occurs 0..cols-1 */
+ int *jOverallMax) {
+  double TrialScore, ColMax, RowMax;
+  int i,j,i2,j2, jRowMax;
+  int iGapLength, jGapLength;
+  double iGapPenalty, jGapPenalty;
+  double OverallMax = -INF_INT;
   int iColMax[MAX_COLS];
-  int Parm_FastBlkMax = 0;
-  int Parm_SlowBlkMax = 0;
   
   for(i=0; i< rows; i++) {
     SS[i][0] = s[i][0];
-    TrRow[i][0] = STOP_TRACEBACK ;
-    TrCol[i][0] = STOP_TRACEBACK ;
+    TrRow[i][0] = STOP_TRACEBACK;
+    TrCol[i][0] = STOP_TRACEBACK;
   }
   for(j=0; j< cols; j++) {
     SS[0][j] = s[0][j];
-    TrRow[0][j] = STOP_TRACEBACK ;
-    TrCol[0][j] = STOP_TRACEBACK ;
+    TrRow[0][j] = STOP_TRACEBACK;
+    TrCol[0][j] = STOP_TRACEBACK;
     iColMax[j] = 0;
   }
   
@@ -50,12 +65,10 @@
   for(i=1; i< rows; i++) {
 
     jRowMax = 0;
-    jBlkMax = 0;
-    iBlkMax = iColMax[0];
     
     for(j=1; j< cols; j++) {
       
-      /* You are at position i,j, consider four
+      /* You are at position i,j, consider three
          possible maximum values: */
       
       /* 1. The value at SS[i-1][j-1] with no gaps */
@@ -62,151 +75,137 @@
 
       /* 2. The maximum on column j-1 up to row i-2. */
 
-      for (ColMax = -INF_INT,i2=iColMax[j-1];
-	   i2<i-1; i2++) {
+      ColMax = -INF_INT;
+      if (iresnum[i-1] != iresnum[i]) { /* No gaps inside residues! - Allen */
+	for (i2=iColMax[j-1]; i2<i-1; i2++) {
+	  if ((iresnum[i2] != iresnum[i2+1]) &&
+	      ((SS[i-1][j-1] <= 0) || (s[i-1][j-1] < 0) || (i2 == 0) ||
+	       (j == (cols-1)) || (TrCol[i2][j-1] == j-2) ||
+	       (TrCol[i2][j-1] == STOP_TRACEBACK))) { /* XXX */
 	iGapLength = i - i2 - 1;
-	iGapPenalty = iOpnPen[i] + (iGapLength - 1) * iExtPen[i];
-	TrialScore = SS[i2][j-1] - iGapPenalty ;
+	    iGapPenalty = /* XXX */
+	      MIN(iOpnPen[i],iOpnPen[i2]) +
+	      ((iGapLength - 1) * MIN(iExtPen[i],iExtPen[i2]));
+	    TrialScore = SS[i2][j-1] - iGapPenalty;
 	if (TrialScore >= ColMax) {
-	  iColMax[j-1] = i2 ;
-	  ColMax = TrialScore ;
+	      iColMax[j-1] = i2;
+	      ColMax = TrialScore;
+	    }
 	}
       }
+      }
       
       /* 3. The maximum on row i-1 up to column j-2. */
 
-      RowMax = -INF_INT ;
+      RowMax = -INF_INT;
+      if (jresnum[j-1] != jresnum[j]) {
       for (j2=jRowMax; j2<j-1; j2++) {
+	  if ((jresnum[j2] != jresnum[j2+1]) &&
+	      ((SS[i-1][j-1] <= 0) || (s[i-1][j-1] < 0) || (j2 == 0) ||
+	       (i == (rows-1)) || (TrRow[i-1][j2] == i-2) ||
+	       (TrRow[i-1][j2] == STOP_TRACEBACK))) { /* XXX */
 	jGapLength = j - j2 - 1;
-	jGapPenalty = jOpnPen[j] + (jGapLength - 1) * jExtPen[j];
-	TrialScore = SS[i-1][j2] - jGapPenalty ;
+	    jGapPenalty = /* XXX */
+	      MIN(jOpnPen[j],jOpnPen[j2]) +
+	      ((jGapLength - 1) * MIN(jExtPen[j],jExtPen[j2]));
+	    TrialScore = SS[i-1][j2] - jGapPenalty;
 	if (TrialScore >= RowMax) {
-	  jRowMax = j2 ;
-	  RowMax = TrialScore ;
-	}
-      }
-      
-      /* 4. The maximum in block 
-	 with bottom right-hand corner at (i-2,j-1) 
-	 and top left-hand corner at (iBlkMax, jBlkMax). */
- 
-      if (Parm_SlowBlkMax) {
-
-	BlkMax = -INF_INT ;
-	for (i2=iBlkMax; i2 < i-1; i2++) {
-	  for (j2=jBlkMax; j2 < j-1; j2++) {
-	    jGapLength = j - j2 - 1;
-	    jGapPenalty = jOpnPen[j] + (jGapLength - 1) * jExtPen[j];
-	    iGapLength = i - i2 - 1;
-	    iGapPenalty = iOpnPen[i] + (iGapLength - 1) * iExtPen[i];
-	    TrialScore = SS[i2][j2] - iGapPenalty - jGapPenalty;
-	    if (TrialScore >= BlkMax) {
-	      jBlkMax = j2 ;
-	      iBlkMax = i2 ;
-	      BlkMax = TrialScore ;
-	    }
-	  }
-	}
-	
-      } else if (Parm_FastBlkMax) {
-	
-	BlkMax = -INF_INT ;
-	for (j2=jBlkMax; j2 < j-1; j2++) {
-	  i2 = iColMax[j2];
-	  if (i2 < i - 1) {
-	    jGapLength = j - j2 - 1;
-	    jGapPenalty = jOpnPen[j] + (jGapLength - 1) * jExtPen[j];
-	    iGapLength = i - i2 - 1;
-	    iGapPenalty = iOpnPen[i] + (iGapLength - 1) * iExtPen[i];
-	    TrialScore = SS[i2][j2] - iGapPenalty - jGapPenalty;
-	    if (TrialScore >= BlkMax) {
-	      jBlkMax = j2 ;
-	      iBlkMax = i2 ;
-	      BlkMax = TrialScore ;
+	      jRowMax = j2;
+	      RowMax = TrialScore;
 	    }
 	  }
 	}
-	
-      } else {
-	jBlkMax = j2 ;
-	iBlkMax = i2 ;
-	BlkMax = -INF_INT ;
       }
 	
-      
       if /* Case 1 */ 
 	(SS[i-1][j-1] >= ColMax &&
-	 SS[i-1][j-1] >= RowMax &&
-	 SS[i-1][j-1] >= BlkMax) {
-	  TrRow[i][j] =  i-1 ;
+	 SS[i-1][j-1] >= RowMax) {
+	  TrRow[i][j] =  i-1;
 	  TrCol[i][j] =  j-1;
-	  SS[i][j] = s[i][j] + SS[i-1][j-1] ;
+	  SS[i][j] = s[i][j] + SS[i-1][j-1];
       } else if /* Case 2 */
 	(/* ColMax >= SS[i-1][j-1] .. True anyway! */
-	 ColMax >= RowMax &&
-	 ColMax >= BlkMax) {
-	  TrRow[i][j] =  iColMax[j-1] ;
+	 ColMax > RowMax) {
+	  TrRow[i][j] =  iColMax[j-1];
 	  TrCol[i][j] =  j-1;
-	  SS[i][j] = s[i][j] + ColMax ;
-      } else if /* Case 3 */
-	(/* RowMax >= SS[i-1][j-1]  ..True anyway! */
-	 /* RowMax >= ColMax        ..True anyway! */
-	 RowMax >= BlkMax) {
+	  SS[i][j] = s[i][j] + ColMax;
+      } else if (RowMax > ColMax) { /* Case 3 */
+	/* RowMax >= SS[i-1][j-1]  ..True anyway! */
 	  TrRow[i][j] =  i-1;
-	  TrCol[i][j] =  jRowMax ;
-	  SS[i][j] = s[i][j] + RowMax ;
-      } else if /* Case 4 */
-	(BlkMax >= SS[i-1][j-1] && /*True anyway! */
-	 BlkMax >= ColMax &&       /*True anyway! */
-	 BlkMax >= RowMax) {       /*True anyway! */
-	  TrRow[i][j] =  iBlkMax;
-	  TrCol[i][j] =  jRowMax ;
-	  SS[i][j] = s[i][j] + BlkMax ;
+	TrCol[i][j] =  jRowMax;
+	SS[i][j] = s[i][j] + RowMax;
+      } else { /* Tied ColMax, RowMax */
+	if (rows > cols) {
+	  TrRow[i][j] =  iColMax[j-1];
+	  TrCol[i][j] =  j-1;
+	  SS[i][j] = s[i][j] + ColMax;
+	} else if (cols > rows) {
+	  TrRow[i][j] =  i-1;
+	  TrCol[i][j] =  jRowMax;
+	  SS[i][j] = s[i][j] + RowMax;
       } else {
-	printf("Error somehow not in case 1 to 4.\n");
+	  iGapLength = i - iColMax[j-1] - 1;
+	  jGapLength = j - jRowMax - 1;
+	  if (jGapLength >= iGapLength) {
+	    TrRow[i][j] =  iColMax[j-1];
+	    TrCol[i][j] =  j-1;
+	    SS[i][j] = s[i][j] + ColMax;
+	  } else {
+	    TrRow[i][j] =  i-1;
+	    TrCol[i][j] =  jRowMax;
+	    SS[i][j] = s[i][j] + RowMax;
       }
+	}
+      }
       
-      if (SS[i][j] > OverallMax) {
+      if (((i == (rows-1)) || (j == (cols-1))) && /* global alignment */
+	  (SS[i][j] >= OverallMax)) {
 	OverallMax = SS[i][j];
-	*iOverallMax = i ;
-	*jOverallMax = j ;
+	*iOverallMax = i;
+	*jOverallMax = j;
       }
     } /* j-loop */
   } /* i-loop */
-  return OverallMax ;
+  return OverallMax;
 }
 
-int                /* OUT: number of equivalenced residues = n                       */
-/*--------------*/
-TrMat2Equivalences 
-/*--------------*/
+/* OUT: number of equivalenced residues = n */
+int TrMat2Equivalences 
 (
- int rows          /* IN:  length of sequence 1                                      */,
- int cols          /* IN:  length of sequence 2                                      */,
- double **TrRow    /* IN:  traceback matrix with row index   [0..rows-1][0..cols-1]  */, 
- double **TrCol    /* IN:  traceback matrix with col index   [0..rows-1][0..cols-1]  */,
- int iOverallMax   /* IN:  row index where overall max occurs 0..rows-1              */,
- int jOverallMax   /* IN:  col index where overall max occurs 0..cols-1              */,
- int *equiv1       /* OUT: seq. 1 equivalenced residues, using fortran conv. [0..n-1]*/,
- int *equiv2       /* OUT: seq. 2 equivalenced residues, using fortran conv. [0..n-1]*/,
- int *nbrks        /* OUT: number of chain breaks                                    */
-)
-{
+ /* IN:  length of sequence 1 */
+ int rows,
+ /* IN:  length of sequence 2 */
+ int cols,
+ /* IN:  traceback matrix with row index [0..rows-1][0..cols-1] */
+ double **TrRow,
+ /* IN:  traceback matrix with col index [0..rows-1][0..cols-1] */
+ double **TrCol,
+ /* IN:  row index where overall max occurs 0..rows-1 */
+ int iOverallMax,
+ /* IN:  col index where overall max occurs 0..cols-1 */
+ int jOverallMax,
+ /* OUT: seq. 1 equivalenced residues, using fortran conv. [0..n-1] */
+ int *equiv1,
+ /* OUT: seq. 2 equivalenced residues, using fortran conv. [0..n-1] */
+ int *equiv2,
+ /* OUT: number of chain breaks */
+ int *nbrks){
   int ReversedEquiv1[MAX_ROWS];
   int ReversedEquiv2[MAX_COLS];
   int n = 0; 
-  int i = iOverallMax ;
-  int j = jOverallMax ;
-  int ii, jj,nn;
+  int i = iOverallMax;
+  int j = jOverallMax;
+  int ii,jj,nn;
   do {
-    ReversedEquiv1[n] = i ;
-    ReversedEquiv2[n] = j ;
-    n++ ;
-    ii = (int)TrRow[i][j] ;
-    jj = (int)TrCol[i][j] ;
+    ii = (int)TrRow[i][j];
+    jj = (int)TrCol[i][j];
+
+    ReversedEquiv1[n] = i;
+    ReversedEquiv2[n] = j;
+    n++;
     if (ii != STOP_TRACEBACK && 
 	!(ii == i - 1 && jj == j - 1)) {
-      *nbrks = *nbrks + 1 ;
+      *nbrks = *nbrks + 1;
     }
     i = ii; j = jj;
   } while (i != STOP_TRACEBACK);
@@ -217,5 +216,5 @@
     equiv2[i] = ReversedEquiv2[nn-1] + 1; 
   }
 
-  return n ;
+  return i;
 }
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/dynapro.h lsqrms-2.0.4b/src/dynapro.h
--- lsqrms-2.0.4b.old/src/dynapro.h	Wed Mar 12 17:12:03 EST 2003
+++ lsqrms-2.0.4b/src/dynapro.h	Sun Feb 24 22:49:49 EST 2008
@@ -1,11 +1,6 @@
-# include <stdio.h>
-
-#define MAX_COLS 1000
-#define MAX_ROWS 1000
-
-#define INF_INT 2147480000
-
-extern int Parm_SlowBlkMax ;
-extern int Parm_FastBlkMax ;
+#include <stdio.h>
 
-#define STOP_TRACEBACK -1
+double dyn_pr_n2(double **, int *, double *, int *, double *, int *, int *,
+		 int, int, double **, double **, double **, int *, int *);
+int TrMat2Equivalences(int, int, double **, double **, int, int,
+		       int *, int *, int *);
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/lsqrms.h lsqrms-2.0.4b/src/lsqrms.h
--- lsqrms-2.0.4b.old/src/lsqrms.h
+++ lsqrms-2.0.4b/src/lsqrms.h	Sun Feb 24 22:49:49 EST 2008
@@ -0,0 +1,53 @@
+#ifndef LSQRMS_H
+#define LSQRMS_H
+
+#define MAXSEQ 4000
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#ifdef __sgi
+# include <sgidefs.h>
+#endif
+
+#include <stdio.h>
+/* will probably want to make below conditional */
+#include <errno.h>
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+# include <string.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  if HAVE_STRINGS_H
+#   include <strings.h>
+#  endif
+# endif
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if (!HAVE_SYS_TYPES_H || (!defined(__sgi)))
+# if HAVE_INTTYPES_H
+#  include <inttypes.h>
+# else
+#  if HAVE_STDINT_H
+#   include <stdint.h>
+#  endif
+# endif
+#endif
+
+#endif /* LSQRMS_H */
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/main.c lsqrms-2.0.4b/src/main.c
--- lsqrms-2.0.4b.old/src/main.c	Wed Apr 16 18:33:17 EDT 2003
+++ lsqrms-2.0.4b/src/main.c	Sun Feb 24 22:49:49 EST 2008
@@ -1,218 +1,411 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "provepdb.h"
+#include "lsqrms.h"
 #include "umath.h"
-
-#define RELEASE char*
-
-typedef double rotate_t[3][3];
-typedef double xlate_t[3];
-typedef struct Coord { double x, y, z; } CoordType;
-
-double MAX2(double, double);
-double MIN2(double, double);
-double FormRotMatrX(double **, double);
-double FormRotMatrY(double **, double);
-double FormRotMatrZ(double **, double);
-double AlignZ(double, double, double, double *, double *);
-int FindMaxXYZDistIdxLast(double **, int);
-int FindMaxXYDistIdxLast(double **, int);
-double TRmoveXYZstruc(double *,double **,double **, int);
-double TRvec(double *, double **, double *);
-double findCM(double **, int, double *);
-double blossom62(char, char);
-char convert321(char *);
-double distrms(CoordType *a, CoordType *b, int npts);
-int check_eq(int *, int *, int *, int *, int);
-double rotrans(double **, int, rotate_t, xlate_t);
-double bestfit(rotate_t , xlate_t , CoordType *, CoordType *, const int );
+#include "provepdb.h"
+#include "matvecalloc.h"
+#include "dynapro.h"
+#include "matvecutils.h"
 
-int     *iVector(long, long);
-int    **iMatrix(long, long, long, long);
-double  *dVector(long, long);
-char    *cVector(long, long);
-double **dMatrix(long, long, long, long);
-char   **cMatrix(long, long, long, long);
-void free_iVector(int     *, long, long);
-void free_iMatrix(int    **, long, long, long, long);
-void free_dVector(double     *, long, long);
-void free_dMatrix(double    **, long, long, long, long);
-void free_cMatrix(char      **, long, long, long, long);
-void free_cVector(char     *, long, long);
+/* cRMS = 0.44*e^(2.22*[fraction mutated residues]) -
+   Koehl and Levitt, JMB 323(3):551-562, 2002 */
+#define L_MIN 0.44		/* fraction mutated = 0 */
+#define L_MIN_SQR (L_MIN*L_MIN)
+#define L_THRESH 0.96		/* fraction mutated = 0.35 */
+#define L_THRESH_SQR (L_THRESH*L_THRESH)
+#define L_THRESH2 2.08		/* fraction mutated = 0.7 */
+#define L_THRESH2_SQR (L_THRESH2*L_THRESH2)
+#define BAD_THRESH 3.626 /* fraction mutated = 0.95 */
 
-double dyn_pr_n2(double **, int *, int *, int *, int *, int, 
-                 int, double **, double **, double **, int *, int *);
-int TrMat2Equivalences(int, int, double **, double **, int, int, int *, int *, int *);
+#define epsilon2 MAX(epsilon,1e-10)
 
-int MAXSEQ = 1000;
+static void usage(int status) {
+  fprintf(stderr,
+	  "lsqrms [-sGhao1] [-b|-B|-i|-n|-g|-p] [-l|-L|-t] source.pdb target.pdb [structal.out]\n");
+  fprintf(stderr, "Options:\n");
+  fprintf(stderr, "  -s: generate STRUCTAL-like output\n");
+  fprintf(stderr, "  -l: use LSQ_ONLY fit instead of iterated RMSD\n");
+  fprintf(stderr, "  -L: scale <= %f to 0 (%f thresh)\n", L_MIN, L_THRESH);
+  fprintf(stderr, "  -t: scale <= %f to 0 (%f thresh)\n", L_MIN, L_THRESH2);
+  fprintf(stderr, "  -G: don't use gap penalties for sequence alignment\n");
+  fprintf(stderr, "  -h: print this usage message\n");
+  fprintf(stderr, "  -1: OK if single-residue 'alignment' (also does -o)\n");
+  fprintf(stderr, "  -b: use blosum62 for initial alignment\n");
+  fprintf(stderr, "  -B: use positive-only blosum62 for initial alignment\n");
+  fprintf(stderr, "  -n: use Nussinov matrix for initial alignment\n");
+  fprintf(stderr, "  -i: use identity matrix for initial alignment\n");
+  fprintf(stderr, "  -g: use gonnet_p matrix for initial alignment\n");
+  fprintf(stderr, "  -p: use pam120_p matrix for initial alignment\n");
+  fprintf(stderr,
+	  "  -a: use altered residues (__[_0-9]) - cannot be used with -i\n");
+  fprintf(stderr, "  -o: use O, C, N as well as CA (also done by -1)\n");
+  exit(status);
+}
 
 int main(int argc, char* argv[]) {
-  double ret_val, RMS, PID, tempval;
+  double RMS, RMSold, PEQUIV, tempval, RMSsav, quality, quality_old;
   double RMSmin = 1000000;
+  double quality_max = 0;
+  double quality_sav = 0;
   int i, j;
   int rows, cols;
-  double ** s;
+  double ** ss;
   double ** SS;
+  double ** dd;
   int * iOpnPen;
-  int * iExtPen;
+  int total_OpnPen = 0;
+  double * iExtPen;
   int * jOpnPen;
-  int * jExtPen;
+  double * jExtPen;
   double ** TrRow;
   double ** TrCol;
   int iOverallMax;
   int jOverallMax;
   
-  int *iina, *iina_sav;
-  int *jinb, *jinb_sav;
-  int nbrks, nEqPairs;
+  int opt_c;
+  int opt_errflag = 0;
+  extern int optind;
+  
+  int *iina, *iina_sav, *iina_old;
+  int *jinb, *jinb_sav, *jinb_old;
+  int nbrks, nbrks_old, nEqPairs, nbrks_sav;
   
   float fp1, fp2, fp3;
   char   ** aa_que, ** aa_tar;
   double ** x_que, **x_que_original;
   double ** x_tar;
-  double ** x_que_sav;
+  double ** x_que_sav, ** x_que_old;
   double * Tcm;
   FILE *stream;
   char *char_stream, *char_stream_backup, *char_stream_head;
+  char *structal_out;
+  extern int errno;
   
-  char *s1, *s2, *s3, *s4, *a_que, *a_tar;
-  int d1, d2;
+  char *s2, *s3, *a_que, *a_tar;
+  int d2;
+  int *r_num_que, *r_num_tar;
   int StringMax = 4;
   
   rotate_t U;
   xlate_t  T;
   
-  int stay, nEqPairs_sav;
+  int stay, nEqPairs_old, nEqPairs_sav;
   int iter = 0;
+  int again = 0;
+  int again2 = 0;
+  int sav_updated = 0;
+  int increased_gap_penalties = 0;
   char aa;
   
-  double *TMPvec, *Tzero, *Tcm_que, *Tcm_tar; 
+  double *TMPvec, *Tzero, /* *Tcm_que, */ *Tcm_tar; 
   double **Rtemp, **Runity;
-  double angle_b, angle_c, angle_b_que, angle_c_que, angle_b_tar, angle_c_tar;
-  double xdir_que, ydir_que, rdir_que, xdir_tar, ydir_tar, rdir_tar;
+  double angle_b, angle_c/*, angle_b_que, angle_c_que */;
+  double angle_b_tar, angle_c_tar;
+  double xdir_que, /* ydir_que, */ rdir_que;
+  double xdir_tar, /* ydir_tar, */ rdir_tar;
   int iMaxDist;
   
   CoordType *str1, *str2;
   
-  int structal     = 0;    /* Flag to use OLD output similar to the one from STRUCTAL*/
-  int lsq          = 0;    /* Flag to use LSQ_ONLY fit instead of iterational RMSD */
+  /* Flag to use OLD output similar to the one from STRUCTAL*/
+  int structal     = 0;
+
+  /* Flag to use LSQ_ONLY fit instead of iterational RMSD */
+  int lsq          = 0;
   
   /* Modified by Julian Graham, April 2003 */
-  if (argc < 3) {
-    fprintf (stderr, "LSQRMS: need to specify .PDB filenames!  Format:\n");
-    fprintf (stderr, "  lsqrms source.pdb target.pdb\n");
-    fprintf (stderr, "Other options:\n");
-    fprintf (stderr, "  structal: generate STRUCTAL-like output\n");
-    fprintf (stderr, "  lsq: use LSQ_ONLY fit instead of interated RMSD\n");
-    return 1;   
-  }
-  if (argc == 4 && strcmp( argv[3], "structal" ) == 0 ) {
-    printf("LSQRMS was called with argument %s \n\n",argv[1]);
+
+  /* Then by Allen Smith, 2003-2007 */
+
+  int use_blosum62 = 0;
+  int use_blosum62_pos = 0;
+  int use_nussinov = 0;
+  int use_identity = 0;
+  int use_gonnet_p = 0;
+  int use_pam120_p = 0;
+  int use_gap = 1;
+  int altered = 0;
+  int use_carbonyl = 0;
+  int use_min_thresh = 0;
+  int use_min_thresh2 = 0;
+  int single_ok = 0;
+
+  while ((opt_c = getopt(argc, argv, "slLbBiGhaongtp1")) != -1) {
+    switch (opt_c) {
+    case 'a':
+      if (use_identity)
+	opt_errflag = 1;
+      else
+	altered = 1;
+      break;
+
+    case 'o':
+      use_carbonyl = 1;
+      break;
+
+    case 's':
     structal = 1;
-  }
+      break;
   
-  if (argc == 4 && strcmp( argv[3], "lsq" ) == 0 ) {
-    printf("LSQRMS was called with argument %s \n\n",argv[1]);
+    case '1':
+      single_ok = 1;
+      use_carbonyl = 1;
+      break;
+
+    case 'l':
+      if (use_min_thresh || use_min_thresh2)
+	opt_errflag = 1;
+      else
     lsq = 1;
+      break;
+
+    case 'L':
+      if (lsq || use_min_thresh2)
+	opt_errflag = 1;
+      else
+	use_min_thresh = 1;
+      break;
+
+    case 't':
+      if (lsq || use_min_thresh)
+	opt_errflag = 1;
+      else
+	use_min_thresh2 = 1;
+      break;
+
+    case 'p':
+      if (use_identity || use_nussinov || use_gonnet_p || use_blosum62 ||
+	  use_blosum62_pos)
+	opt_errflag = 1;
+      else
+	use_pam120_p = 1;
+      break;
+
+    case 'b':
+      if (use_identity || use_nussinov || use_gonnet_p || use_pam120_p)
+	opt_errflag = 1;
+      else
+	use_blosum62 = 1;
+      break;
+
+    case 'B':
+      if (use_identity || use_nussinov || use_gonnet_p || use_pam120_p)
+	opt_errflag = 1;
+      else
+	use_blosum62_pos = 1;
+      break;
+
+    case 'i':
+      if (use_blosum62 || altered || use_nussinov || use_pam120_p ||
+	  use_blosum62_pos || use_gonnet_p)
+	opt_errflag = 1;
+      else
+	use_identity = 1;
+      break;
+
+    case 'n':
+      if (use_blosum62 || use_identity || use_blosum62_pos ||
+	  use_gonnet_p || use_pam120_p)
+	opt_errflag = 1;
+      else
+	use_nussinov = 1;
+      break;
+
+    case 'g':
+      if (use_blosum62 || use_identity || use_blosum62_pos ||
+	  use_nussinov || use_pam120_p)
+	opt_errflag = 1;
+      else
+	use_gonnet_p = 1;
+      break;
+
+    case 'G':
+      use_gap = 0;
+      break;
+
+    case 'h':
+      usage(0);
+      /* NOTREACHED */
+      break;
+
+    case '?':
+      opt_errflag = 1;
+      break;
   }
-  if (argc == 5 && (strcmp( argv[3], "structal" ) == 0) && 
-      strcmp( argv[4], "lsq" ) == 0 ) {
-    printf("LSQRMS was called with arguments %s %s \n\n",argv[3],argv[4]);
-    lsq = 1;
-    structal = 1;
   }
-  if (argc == 5 && (strcmp( argv[4], "structal" ) == 0) && 
-      strcmp( argv[3], "lsq" ) == 0 ) {
-    printf("LSQRMS was called with arguments %s %s \n\n",argv[1],argv[2]);
-    lsq = 1;
-    structal = 1;
+
+  if (opt_errflag)
+    usage(2);
+
+  if ((argc - optind) < 1) {
+    fprintf (stderr, "LSQRMS: need to specify (2) .PDB filenames!\n");
+    usage(2);
   }
   
-  printf("Program LSQRMS. Version 2.02\n");
-  stay = 1; nEqPairs_sav = -1; nEqPairs = -1;
+  printf("Program LSQRMS. Version 2.02-Allen-10/26/2005\n");
+  if (structal) {
+    if ((argc - optind) < 2)
+      structal_out = strdup("structal.out");
+    else
+      structal_out = strdup(argv[optind+2]);
+    printf("Using Structal output format (output to %s)\n", structal_out);
+  }
   
-  s1 = cVector(1,StringMax);
+  if (lsq)
+    printf("Doing LSQ_ONLY fit instead of iterated RMSD\n");
+  else if (use_min_thresh)
+    printf("Scaling <= %f to 0 (%f threshold)\n", L_MIN, L_THRESH);
+  else if (use_min_thresh2)
+    printf("Scaling <= %f to 0 (%f threshold)\n", L_MIN, L_THRESH2);
+
+  if (altered)
+    printf("Using altered residues for site/whatever alignment\n");
+  if (use_carbonyl)
+    printf("Using O, C, N as well as CA\n");
+
+  if (use_blosum62_pos)
+    printf("Using positive-only blosum62 for initial alignment\n");
+  else if (use_blosum62)
+    printf("Using blosum62 for initial alignment\n");
+  else if (use_nussinov)
+    printf("Using Nussinov (Naor et al 1996) matrix for initial alignment\n");
+  else if (use_identity)
+    printf("Using identity matrix for initial alignment\n");
+  else if (use_gonnet_p)
+    printf("Using gonnet_p matrix for initial alignment\n");
+  else if (use_pam120_p)
+    printf("Using pam120_p matrix for initial alignment\n");
+
+  if (use_gap)
+    printf("Using gap penalties for initial alignment\n");
+  else
+    printf("Not using gap penalties for initial alignment\n");
+  fflush(NULL);
+
+  stay = 1; nEqPairs_sav = -1; nEqPairs = -1; nEqPairs_old = -1;
+  
+  /* s1 = cVector(1,StringMax); */
   s2 = cVector(1,StringMax);
   s3 = cVector(1,3);
-  s4 = cVector(1,StringMax);
+  /* s4 = cVector(1,StringMax); */
   
   /* ATOM      2  CA  ASP H  19      30.313   5.590  12.619  */
-  char_stream = provepdb (argv[1]);
+  /* ATOM      3  O   ASP H  19      30.313   5.590  12.619  */
+  char_stream = provepdb(argv[optind],altered,use_carbonyl);
   if (char_stream == NULL) {
-    fprintf (stderr, "Couldn't open file \'%s\'\n", argv[1]);
+    fprintf (stderr, "Couldn't open file \'%s\'\n", argv[optind]);
+    return 1; 
+  } else {
+    char_stream_backup = strdup(char_stream);
+    if (char_stream_backup == NULL) {
+      fprintf(stderr, "Out of memory for strdup of char_stream for \'%s\'\n",
+	      argv[optind]);
     return 1; 
   }
-  else {
-    char_stream_backup = strdup (char_stream);
     char_stream_head = char_stream;
     i=0;
     while (1) {
-      (void) sscanf (char_stream, "%4c %d %2c %3c %c %d %f %f %f\n", 
-		      s1, &d1, s2, s3, s4, &d2,
-		      &fp1, &fp2, &fp3);
-      char *new_pointer = strstr (char_stream + 4, "ATOM");      
-      aa = convert321( s3 );
+      char *new_pointer;
+
+      (void) sscanf(char_stream,
+		    "ATOM %*d %2c %3[^ ] %d %f %f %f\n", 
+		    s2, s3, &d2, &fp1, &fp2, &fp3);
+      new_pointer = strstr(char_stream + 4, "ATOM");
       i++;
-      if (new_pointer == NULL) break;
+      if (new_pointer == NULL)
+	break;
       else {
 	char_stream = (char *) (new_pointer);
 	continue;
       }      
-    } 
+    } /* while (1) */
   }
   rows = i;
 
-  free (char_stream_head);
+  free(char_stream_head);
   char_stream = char_stream_backup;
   char_stream_head = char_stream;
 
   x_que     = dMatrix(1,3,0,rows-1);
   x_que_sav = dMatrix(1,3,0,rows-1);
+  x_que_old = dMatrix(1,3,0,rows-1);
   x_que_original = dMatrix(1,3,0,rows-1);
   a_que     = cVector(0,rows-1);
   aa_que    = cMatrix(0,rows-1,0,2);
+  r_num_que = iVector(0,rows-1);
 
-  for(i = 0; i < rows; i++) {
+  for (i = 0; i < rows; i++) {
     char *new_pointer = strstr (char_stream + 4, "ATOM");
-    (void) sscanf (char_stream, "%4c %d %2c %3c %c %d %f %f %f\n", 
-		   s1, &d1, s2, s3, s4, &d2, &fp1, &fp2, &fp3);
+
+    if (sscanf(char_stream,
+	       "ATOM %*d %2c %3[^ ] %d %f %f %f\n", 
+	       s2, s3, &d2, &fp1, &fp2, &fp3) == 6) {
     char_stream = (char *) (new_pointer);
-    aa = convert321( s3 );
+      aa = convert321(s3,1,altered);
+      if (use_carbonyl && isalpha(aa)) {
+	if (islower(aa))
+	  aa = _toupper(aa);
+	if (s2[0] == 'C') {
+	  if (s2[1] != 'A')
+	    aa = tohigh(_tolower(aa));
+	} else if (s2[0] == 'O')
+	  aa = _tolower(aa);
+	else
+	  aa = tohigh(aa);
+      }
     a_que[i] = aa;
+      r_num_que[i] = d2;
     aa_que[i][0] = s3[0];
     aa_que[i][1] = s3[1];
     aa_que[i][2] = s3[2];
-    x_que[1][i]=fp1; x_que_sav[1][i]=fp1; x_que_original[1][i]=fp1;
-    x_que[2][i]=fp2; x_que_sav[2][i]=fp2; x_que_original[2][i]=fp2;
-    x_que[3][i]=fp3; x_que_sav[3][i]=fp3; x_que_original[3][i]=fp3;
+      
+      x_que[1][i] = fp1;
+      x_que_sav[1][i] = fp1;
+      x_que_old[1][i] = fp1;
+      x_que_original[1][i] = fp1;
+      
+      x_que[2][i] = fp2;
+      x_que_sav[2][i] = fp2;
+      x_que_old[2][i] = fp2;
+      x_que_original[2][i] = fp2;
+      
+      x_que[3][i] = fp3;
+      x_que_sav[3][i] = fp3;
+      x_que_old[3][i] = fp3;
+      x_que_original[3][i] = fp3;
+    } else {
+      fprintf(stderr, "Unable to convert %s\n", char_stream);
+      return 1;
+    }
   } /* for(i) */
   
-  free (char_stream_head);
-  char_stream = provepdb (argv[2]);
+  free(char_stream_head);
+  char_stream = provepdb(argv[optind+1],altered,use_carbonyl);
   if (char_stream == NULL) {
-    fprintf (stderr, "Couldn't open file \'%s\'\n", argv[2]);
+    fprintf (stderr, "Couldn't open file \'%s\'\n", argv[optind+1]);
     return 1; 
-  }
-  else {
+  } else {
     char_stream_backup = strdup (char_stream);
+    if (char_stream_backup == NULL) {
+      fprintf(stderr, "Out of memory for strdup of char_stream for \'%s\'\n",
+	      argv[optind+1]);
+      return 1;
+    }
     char_stream_head = char_stream;
     i=0;
     while (1) {
-      (void) sscanf (char_stream, "%4c %d %2c %3c %c %d %f %f %f\n",
-		      s1, &d1, s2, s3, s4, &d2,
-		      &fp1, &fp2, &fp3);
-      char *new_pointer = strstr (char_stream + 4, "ATOM");
-      aa = convert321( s3 );
+      char *new_pointer;
+
+      (void) sscanf(char_stream,
+		    "ATOM %*d %2c %3[^ ] %d %f %f %f\n", 
+		    s2, s3, &d2, &fp1, &fp2, &fp3);
+      new_pointer = strstr (char_stream + 4, "ATOM");
       i++;
-      if (new_pointer == NULL) break;
+      if (new_pointer == NULL)
+	break;
       else {
 	char_stream = (char *) (new_pointer);
 	continue;
       }
-    }
-      /* while */
+    } /* while (1) */
   }
   cols = i;
   
@@ -224,142 +417,292 @@
   x_tar     = dMatrix(1,3,0,cols-1);
   a_tar     = cVector(0,cols-1);
   aa_tar    = cMatrix(0,cols-1,0,2);
+  r_num_tar = iVector(0,cols-1);
   
   for (i = 0; i < cols; i++) {
     char *new_pointer = strstr (char_stream + 4, "ATOM");
-    (void) sscanf (char_stream, "%4c %d %2c %3c %c %d %f %f %f\n", 
-		s1, &d1, s2, s3, s4, &d2,
-		   &fp1, &fp2, &fp3);
+
+    if (sscanf(char_stream,
+	       "ATOM %*d %2c %3[^ ] %d %f %f %f\n", 
+	       s2, s3, &d2, &fp1, &fp2, &fp3) == 6) {
     char_stream = (char *) (new_pointer);
-    aa = convert321( s3 );
+      aa = convert321(s3,1,altered);
+      if (use_carbonyl && isalpha(aa)) {
+	if (islower(aa))
+	  aa = _toupper(aa);
+	if (s2[0] == 'C') {
+	  if (s2[1] != 'A')
+	    aa = tohigh(_tolower(aa));
+	} else if (s2[0] == 'O')
+	  aa = _tolower(aa);
+	else
+	  aa = tohigh(aa);
+      }
     a_tar[i] = aa;
+      r_num_tar[i] = d2;
     aa_tar[i][0] = s3[0];
     aa_tar[i][1] = s3[1];
     aa_tar[i][2] = s3[2];
-    x_tar[1][i]=fp1; 
-    x_tar[2][i]=fp2; 
-    x_tar[3][i]=fp3; 
-  } /* for(i) */
-  free (char_stream_head);
+      x_tar[1][i] = fp1; 
+      x_tar[2][i] = fp2; 
+      x_tar[3][i] = fp3;
+    } else {
+      fprintf(stderr, "Unable (2) to interpret %s\n",char_stream);
+      return 1;
+    }
+  } /* for (i < cols) */
+
+  free(char_stream_head);
   /* ATOM     10  CA  GLU H  20      30.998   8.719  10.360  */
   
   iOverallMax = -1;
   jOverallMax = -1;
   
-  s       = dMatrix(0,rows-1,0,cols-1);
-  SS      = dMatrix(0,rows-1,0,cols-1);
-  TrRow   = dMatrix(0,rows-1,0,cols-1);
-  TrCol   = dMatrix(0,rows-1,0,cols-1);
+  ss      = dMatrix(0,rows+1,0,cols+1);
+  SS      = dMatrix(0,rows+1,0,cols+1);
+  dd      = dMatrix(0,rows+1,0,cols+1);
+  TrRow   = dMatrix(0,rows,0,cols);
+  TrCol   = dMatrix(0,rows,0,cols);
   iOpnPen = iVector(0,rows-1);
-  iExtPen = iVector(0,rows-1);
+  iExtPen = dVector(0,rows-1);
   jOpnPen = iVector(0,cols-1);
-  jExtPen = iVector(0,cols-1);
+  jExtPen = dVector(0,cols-1);
   
   iina_sav = iVector(0,MAXSEQ);
   jinb_sav = iVector(0,MAXSEQ);
   
+  
   /* FIRST OF ALL, MOVE que->CM(tar); NEXT, align PRINCIPAL AXES OF INERTIA: */
   
   Tcm     = dVector(1,3); 
-  Tcm_que = dVector(1,3); 
+  /* Tcm_que = dVector(1,3); */
   Tcm_tar = dVector(1,3); 
  Tzero   = dVector(1,3); 
  TMPvec  = dVector(1,3); 
  Rtemp   = dMatrix(1,3,1,3);
  Runity  = dMatrix(1,3,1,3);
- Rtemp[1][1]  = 1.0; Rtemp[1][2]  = 0.0; Rtemp[1][3]  = 0.0;
- Rtemp[2][1]  = 0.0; Rtemp[2][2]  = 1.0; Rtemp[2][3]  = 0.0;
- Rtemp[3][1]  = 0.0; Rtemp[3][2]  = 0.0; Rtemp[3][3]  = 1.0;
- Runity[1][1] = 1.0; Runity[1][2] = 0.0; Runity[1][3] = 0.0;
- Runity[2][1] = 0.0; Runity[2][2] = 1.0; Runity[2][3] = 0.0;
- Runity[3][1] = 0.0; Runity[3][2] = 0.0; Runity[3][3] = 1.0;
- TMPvec[1]  = 2; TMPvec[2]  = 3;   TMPvec[3]  = 4;
- Tzero[1]   = 00.e0; Tzero[2] = 0.0e0; Tzero[3]   = 0.0e0;
  
- ret_val = findCM(x_tar,cols,Tcm);
+  Rtemp[1][1]  = 1.0;
+  Rtemp[1][2]  = 0.0;
+  Rtemp[1][3]  = 0.0;
 
- Tcm_tar[1] = Tcm[1];  Tcm_tar[2] = Tcm[2];  Tcm_tar[3] = Tcm[3]; /* saved inv translation */
- Tcm[1] = -Tcm[1];  Tcm[2] = -Tcm[2];  Tcm[3] = -Tcm[3];
+  Rtemp[2][1]  = 0.0;
+  Rtemp[2][2]  = 1.0;
+  Rtemp[2][3]  = 0.0;
 
- ret_val = TRmoveXYZstruc(Tcm,Runity,x_tar,cols);
+  Rtemp[3][1]  = 0.0;
+  Rtemp[3][2]  = 0.0;
+  Rtemp[3][3]  = 1.0;
 
- ret_val = findCM(x_tar,cols,Tcm);
+  Runity[1][1] = 1.0;
+  Runity[1][2] = 0.0;
+  Runity[1][3] = 0.0;
+
+  Runity[2][1] = 0.0;
+  Runity[2][2] = 1.0;
+  Runity[2][3] = 0.0;
+
+  Runity[3][1] = 0.0;
+  Runity[3][2] = 0.0;
+  Runity[3][3] = 1.0;
+
+  TMPvec[1] = 2;
+  TMPvec[2] = 3;
+  TMPvec[3] = 4;
+
+  Tzero[1] = 00.e0;
+  Tzero[2] = 0.0e0;
+  Tzero[3] = 0.0e0;
+ 
+  (void)findCM(x_tar,cols,Tcm);
+
+  /* saved inv translation */
+  Tcm_tar[1] = Tcm[1];
+  Tcm_tar[2] = Tcm[2];
+  Tcm_tar[3] = Tcm[3];
+
+  Tcm[1] = -Tcm[1];
+  Tcm[2] = -Tcm[2];
+  Tcm[3] = -Tcm[3];
+
+  (void)TRmoveXYZstruc(Tcm,Runity,x_tar,cols);
+  
+  (void)findCM(x_tar,cols,Tcm);
 
  iMaxDist = FindMaxXYZDistIdxLast(x_tar,cols);
- ret_val  = AlignZ(x_tar[1][iMaxDist],x_tar[2][iMaxDist],x_tar[3][iMaxDist],&angle_b,&angle_c);
- angle_b_tar = -angle_b; angle_c_tar = -angle_c; /* saved inv rotation */
+  (void)AlignZ(x_tar[1][iMaxDist],x_tar[2][iMaxDist],x_tar[3][iMaxDist],
+	       &angle_b,&angle_c);
+  /* saved inv rotation */
+  angle_b_tar = -angle_b;
+  angle_c_tar = -angle_c;
 
- ret_val = FormRotMatrY(Rtemp,angle_b);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
- ret_val = FormRotMatrX(Rtemp,angle_c);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
+  (void)FormRotMatrY(Rtemp,angle_b);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
+  (void)FormRotMatrX(Rtemp,angle_c);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
 
  iMaxDist = FindMaxXYDistIdxLast(x_tar,cols);
 
  rdir_tar = sqrt( SQR(x_tar[1][iMaxDist]) + SQR(x_tar[2][iMaxDist]) );
- xdir_tar = x_tar[1][iMaxDist]/rdir_tar; /* <- need it to determine XY-plane rotation */
- ydir_tar = x_tar[2][iMaxDist]/rdir_tar; /* <- need it to determine XY-plane rotation */
+  /* xdir_tar: needed to determine XY-plane rotation */
+  xdir_tar = x_tar[1][iMaxDist]/rdir_tar;
+  /* ydir_tar = x_tar[2][iMaxDist]/rdir_tar; */
 
-/* Do the same for the QUERY: */
- ret_val = findCM(x_que,rows,Tcm);
- Tcm_que[1] = Tcm[1];  Tcm_que[2] = Tcm[2];  Tcm_que[3] = Tcm[3]; /* saved inv translation */
+  /* Do the same for the QUERY: */
+  (void)findCM(x_que,rows,Tcm);
+  /* saved inv translation */
+  /* Tcm_que[1] = Tcm[1];
+     Tcm_que[2] = Tcm[2];
+     Tcm_que[3] = Tcm[3]; */
 
- Tcm[1] = -Tcm[1];  Tcm[2] = -Tcm[2];  Tcm[3] = -Tcm[3];
+  Tcm[1] = -Tcm[1];
+  Tcm[2] = -Tcm[2];
+  Tcm[3] = -Tcm[3];
 
- ret_val = TRmoveXYZstruc(Tcm,Runity,x_que,rows);
+  (void)TRmoveXYZstruc(Tcm,Runity,x_que,rows);
+  printf("Moving query: %.10f %.10f %.10f\n", Tcm[1], Tcm[2], Tcm[3]);
 
- ret_val = findCM(x_que,rows,Tcm);
+  (void)findCM(x_que,rows,Tcm);
 
  iMaxDist = FindMaxXYZDistIdxLast(x_que,rows);
- ret_val  = AlignZ(x_que[1][iMaxDist],x_que[2][iMaxDist],x_que[3][iMaxDist],&angle_b,&angle_c);
- angle_b_que = -angle_b; angle_c_que = -angle_c; /* saved inv rotation */
+  (void)AlignZ(x_que[1][iMaxDist],x_que[2][iMaxDist],x_que[3][iMaxDist],
+	       &angle_b,&angle_c);
+  /* saved inv rotation - not needed (Allen) */
+  /* angle_b_que = -angle_b; angle_c_que = -angle_c; */
 
- ret_val = FormRotMatrY(Rtemp,angle_b);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
- ret_val = FormRotMatrX(Rtemp,angle_c);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  (void)FormRotMatrY(Rtemp,angle_b);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  printf("Rotating query: y-angle %.10f; %.10f %.1f %.10f; %.1f %.1f %.1f; %.10f %.1f %.10f\n",
+	 angle_b,
+	 Rtemp[1][1],Rtemp[1][2],Rtemp[1][3],
+	 Rtemp[2][1],Rtemp[2][2],Rtemp[2][3],
+	 Rtemp[3][1],Rtemp[3][2],Rtemp[3][3]);
+  (void)FormRotMatrX(Rtemp,angle_c);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  printf("Rotating query: x-angle %.10f; %.1f %.1f %.1f; %.1f %.10f %.10f; %.1f %.10f %.10f\n",
+	 angle_c,
+	 Rtemp[1][1],Rtemp[1][2],Rtemp[1][3],
+	 Rtemp[2][1],Rtemp[2][2],Rtemp[2][3],
+	 Rtemp[3][1],Rtemp[3][2],Rtemp[3][3]);
 
  iMaxDist = FindMaxXYDistIdxLast(x_que,rows);
 
  rdir_que = sqrt( SQR(x_que[1][iMaxDist]) + SQR(x_que[2][iMaxDist]) );
- xdir_que = x_que[1][iMaxDist]/rdir_que; /* <- need it to determine XY-plane rotation */
- ydir_que = x_que[2][iMaxDist]/rdir_que; /* <- need it to determine XY-plane rotation */
+  /* xdir_que: needed to determine XY-plane rotation */
+  xdir_que = x_que[1][iMaxDist]/rdir_que;
+  /* ydir_que = x_que[2][iMaxDist]/rdir_que; */
 
  angle_b = acos(xdir_tar);
  angle_c = acos(xdir_que);
 
- ret_val = FormRotMatrZ(Rtemp,angle_c-angle_b);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  (void)FormRotMatrZ(Rtemp,angle_c-angle_b);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  printf("Rotating query: z-angle %.10f; %.10f %.10f %.1f; %.10f %.10f %.1f; %.1f %.1f %.1f\n",
+	 (angle_c-angle_b),
+	 Rtemp[1][1],Rtemp[1][2],Rtemp[1][3],
+	 Rtemp[2][1],Rtemp[2][2],Rtemp[2][3],
+	 Rtemp[3][1],Rtemp[3][2],Rtemp[3][3]);
 
-/* CHECK COORDINATES: */
-/*
- stream = fopen( "coordchk.txt", "w" );
- if( stream == NULL )
-   printf( "Couldn't open file coordchk.txt\n" );
- else   {
-   fprintf( stream, "Query: \n");
-   for(i=0;i<rows;i++) {
-	  fprintf( stream, "%12.3f %8.3f %8.3f\n", x_que[1][i], x_que[2][i], x_que[3][i]);
+  /* CHECK COORDINATES: */
+/*   stream = fopen( "coordchk.txt", "w" ); */
+/*   if( stream == NULL ) */
+/*     printf( "Couldn't open file coordchk.txt\n" ); */
+/*   else { */
+/*     fprintf( stream, "Query: \n"); */
+/*     for (i=0;i<rows;i++) { */
+/*       fprintf( stream, "%12.3f %8.3f %8.3f\n", */
+/* 	       x_que[1][i], x_que[2][i], x_que[3][i]); */
+/*     } */
+/*     fprintf( stream, "Target: \n"); */
+/*     for (i=0;i<cols;i++) { */
+/*       fprintf( stream, "%12.3f %8.3f %8.3f\n", */
+/* 	       x_tar[1][i], x_tar[2][i], x_tar[3][i]); */
+/*     } */
+/*     fclose( stream ); */
+/*   } */
+ 
+  /* INITIAL STARTING POINT: SEQUENCE ALIGNMENT.
+     Decide if needed (based on PID) */
+  iina = iVector(0,MAXSEQ);
+  jinb = iVector(0,MAXSEQ);
+  iina_old = iVector(0,MAXSEQ);
+  jinb_old = iVector(0,MAXSEQ);
+  for (i=0; i<=MAXSEQ; i++) {
+    iina[i] = -1;
+    jinb[i] = -1;
 	}
-   fprintf( stream, "Target: \n");
-   for(i=0;i<cols;i++) {
-	  fprintf( stream, "%12.3f %8.3f %8.3f\n", x_tar[1][i], x_tar[2][i], x_tar[3][i]);
+  for (j=0; j<=(cols-1); j++) {
+    if (use_gap && (j < (cols-1))) {
+/* values from J. Mol. Biol. (1995) 249, 816-831:
+   An Assessment of Amino Acid Exchange Matrices in
+   Aligning Protein Sequences: The Twilight Zone
+   Revisited, by Gerhard Vogt, Thure Etzold and
+   Patrick Argos */
+      /* NOTE: values use Opn + ((len-1)*Ext) formula */
+      if (use_nussinov) { /* estimated from pam60_p values */
+	jOpnPen[j] = 14;
+	jExtPen[j] = 1.5;
+      } else if (use_gonnet_p) {
+	jOpnPen[j] = 6;
+	jExtPen[j] = 0.8;
+      } else if (use_blosum62_pos) {
+	jOpnPen[j] = 20;
+	jExtPen[j] = 1.2;
+      } else if (use_blosum62) {
+	jOpnPen[j] = 15;
+	jExtPen[j] = 1.8;
+      } else if (use_identity) {
+	jOpnPen[j] = 1;
+	jExtPen[j] = 0.07;
+      } else if (use_pam120_p) {
+	jOpnPen[j] = 12.5;
+	jExtPen[j] = 1;
+      } else {
+	jOpnPen[j] = 15;
+	jExtPen[j] = 0.92;
    }
-   fclose( stream );
+      if ((cols > rows) && (j >= (rows-1)))
+	jOpnPen[j] = 0;
+      if ((toascii(a_tar[j]) == 'X') || (toascii(a_tar[j]) == 'x'))
+	jExtPen[j] = 0.0;
+    } else {
+      jOpnPen[j] = 0;
+      jExtPen[j] = 0.0;
  }
-*/
-/* INITIAL STARTING POINT: SEQUENCE ALIGNMENT. Decide if needed (based on PID) */
- iina = iVector(0,MAXSEQ);
- jinb = iVector(0,MAXSEQ);
- for(i=0;i<=MAXSEQ;i++) {
-   iina[i] = -1; jinb[i] = -1;
  }
- for(j=0;j<=cols-1;j++) {
-     jOpnPen[j] = 0; jExtPen[j] = 0;
+  for (i=0; i<=(rows-1); i++) {
+    if (use_gap && (i < (rows-1))) {
+      if (use_nussinov) { /* estimated from pam60_p values */
+	iOpnPen[i] = 14;
+	iExtPen[i] = 1.5;
+      } else if (use_gonnet_p) {
+	iOpnPen[i] = 6;
+	iExtPen[i] = 0.8;
+      } else if (use_blosum62_pos) {
+	iOpnPen[i] = 20;
+	iExtPen[i] = 1.2;
+      } else if (use_blosum62) {
+	iOpnPen[i] = 15;
+	iExtPen[i] = 1.8;
+      } else if (use_identity) {
+	iOpnPen[i] = 1;
+	iExtPen[i] = 0.07;
+      } else if (use_pam120_p) {
+	iOpnPen[i] = 12.5;
+	iExtPen[i] = 1;
+      } else {
+	iOpnPen[i] = 15;
+	iExtPen[i] = 0.92;
  }
- for(i=0;i<=rows-1;i++) {
-	 iOpnPen[i] = 0;  iExtPen[i] = 0;
-	for(j=0;j<=cols-1;j++) {       
+      if ((rows > cols) && (i >= (cols-1)))
+	iOpnPen[i] = 0;
+      if ((toascii(a_que[i]) == 'X') || (toascii(a_que[i]) == 'x'))
+	iExtPen[i] = 0.0;
+    } else {
+      iOpnPen[i] = 0;
+      iExtPen[i] = 0.0;
+    }
+    for (j=0; j<=(cols-1); j++) {       
 		SS[i][j]    = 0.0;
         TrRow[i][j] = 0.0;
 		TrCol[i][j] = 0.0;
@@ -366,99 +709,244 @@
 	 }
  }
  /* Use substitution matrix over here: */
- for(i=0;i<rows;i++) {
-	for(j=0;j<cols;j++) {
-		if( a_que[i] == a_tar[j] ) s[i][j] = 1.0; /* primitive! */
-		else s[i][j] = 0.0;                       /* primitive! */
-/* blossom62 enhancement, not always good
-        tempval = blossom62(a_que[i],a_tar[j]);   
-		s[i][j] += tempval;
-*/
+  for (i=0; i<rows; i++) {
+    for(j=0; j<cols; j++) {
+      if (use_identity || use_blosum62 || use_blosum62_pos) {
+	if (a_que[i] == a_tar[j])
+	  ss[i][j] = 1.0; /* primitive! */
+	else
+	  ss[i][j] = 0.0; /* primitive! */
+	if (use_blosum62 || use_blosum62_pos) {
+	  /* blosum62 enhancement, not always good */
+	  tempval = blosum62(a_que[i],a_tar[j],altered,use_carbonyl);
+	  ss[i][j] += tempval;
+	  if (use_blosum62_pos)
+	    ss[i][j] += 8;
+	} else if (use_carbonyl) {
+	  if (isascii(a_que[i]) != isascii(a_tar[j]))
+	    ss[i][j] = -1000;
+	  else if (! isascii(a_que[i])) {
+	    if (isupper(toascii(a_que[i])) != isupper(toascii(a_tar[j])))
+	      ss[i][j] = -1000;
+	    else if (isalpha(toascii(a_que[i])) !=
+		     isalpha(toascii(a_tar[j])))
+	      ss[i][j] = -1000;
+	  } else if (isupper(a_que[i]) != isupper(a_tar[j]))
+	    ss[i][j] = -1000;
+	}
+      } else if (use_nussinov) {
+	ss[i][j] = 0.0;
+	tempval = nussinov(a_que[i],a_tar[j],altered,use_carbonyl);
+	ss[i][j] += tempval;
+      } else if (use_gonnet_p) {
+	ss[i][j] = 0.0;
+	tempval = gonnet_p(a_que[i],a_tar[j],altered,use_carbonyl);
+	ss[i][j] += tempval;
+      } else if (use_pam120_p) {
+	ss[i][j] = 0.0;
+	tempval = pam120_p(a_que[i],a_tar[j],altered,use_carbonyl);
+	ss[i][j] += tempval;
+      } else {
+	ss[i][j] = 0.0;
+	tempval = glyproaln(a_que[i],a_tar[j],altered,use_carbonyl);
+	ss[i][j] += tempval;
 	}
  }
- ret_val = dyn_pr_n2(s, iOpnPen, iExtPen, jOpnPen, jExtPen, rows, cols,
-                     SS,  TrRow,   TrCol, &iOverallMax, &jOverallMax); 
+  }
+
+  printf("Have %d rows, %d cols\n", rows, cols);
+  fflush(NULL);
+
+  (void)dyn_pr_n2(ss, iOpnPen, iExtPen, jOpnPen, jExtPen, r_num_que, r_num_tar,
+		  rows, cols, SS, TrRow, TrCol, &iOverallMax, &jOverallMax); 
  nbrks = -1;
  nEqPairs_sav = nEqPairs;
- nEqPairs = TrMat2Equivalences (rows,cols,TrRow,TrCol,
-	                            iOverallMax,jOverallMax,iina,jinb,&nbrks);
-
- for(i=0;i<=MAXSEQ;i++) {
+  nEqPairs_old = nEqPairs;
+  nEqPairs = TrMat2Equivalences(rows,cols,TrRow,TrCol,
+				iOverallMax,jOverallMax,
+				iina,jinb,&nbrks);
+  printf("nEqPairs: %d\n", nEqPairs); fflush(NULL);
+  nbrks_sav = nbrks;
+  nbrks_old = nbrks;
+  for (i=0; i<=MAXSEQ; i++) {
    iina_sav[i] = iina[i];
+    iina_old[i] = iina[i];
    jinb_sav[i] = jinb[i];
+    jinb_old[i] = jinb[i];
  }
 
- tempval = MIN2( (double)rows, (double)cols);
- PID = (double)nEqPairs/( tempval );
+  tempval = MIN((double)rows, (double)cols);
+  PEQUIV = (double)nEqPairs/(tempval);
 
- if(PID > 0.1) { /* It makes sense to start with eq.pairs from sequence alignment: */
+  if ((single_ok && (nEqPairs >= tempval) && (nEqPairs >= 4)) ||
+      ((nEqPairs > 2) && (lsq || (PEQUIV >= 0.3)) &&
+       ((nEqPairs > 8) || (! use_carbonyl)))) {
+    /* It makes sense to start with eq.pairs from sequence alignment: */
 
- str1 = (CoordType *) malloc(nEqPairs * sizeof(CoordType));
- str2 = (CoordType *) malloc(nEqPairs * sizeof(CoordType));
+    if (use_carbonyl)
+      nEqPairs = 4*(floor((double)nEqPairs/4.0));
 
- for(i=0;i<nEqPairs;i++) {
-   str1[i].x = x_que[1][iina[i]-1]; str2[i].x = x_tar[1][jinb[i]-1];
-   str1[i].y = x_que[2][iina[i]-1]; str2[i].y = x_tar[2][jinb[i]-1];
-   str1[i].z = x_que[3][iina[i]-1]; str2[i].z = x_tar[3][jinb[i]-1];		
+    str1 = (CoordType *)malloc(nEqPairs * sizeof(CoordType));
+    if (!str1) {
+      fprintf(stderr, "main: Allocation failed!\n");
+      exit(1);
+    }
+    str2 = (CoordType *)malloc(nEqPairs * sizeof(CoordType));
+    if (!str2) {
+      fprintf(stderr, "main: Allocation failed!\n");
+      exit(1);
  }
 
- RMS = bestfit(U, T, str1, str2, nEqPairs); 
- printf("PID, RMS, eq.pairs (from sequence alignment) = %f %f %d\n",PID*100,RMS,nEqPairs);
+    for (i=0;i<nEqPairs;i++) {
+      str1[i].x = x_que[1][iina[i]-1];
+      str2[i].x = x_tar[1][jinb[i]-1];
 
- ret_val = rotrans(x_que, rows, U, T);
+      str1[i].y = x_que[2][iina[i]-1];
+      str2[i].y = x_tar[2][jinb[i]-1];
 
- if( RMS < RMSmin ) {
-   RMSmin = RMS;
+      str1[i].z = x_que[3][iina[i]-1];
+      str2[i].z = x_tar[3][jinb[i]-1];
+    }
+
+    RMS = bestfit(U, T, str1, str2, nEqPairs);
+    if (RMS > 0.01)
+      quality = fsqrt(nEqPairs)/RMS;
+    else
+      quality = 100*fsqrt(nEqPairs);
+    printf("PEQUIV, RMS, eq.pairs, quality (from seq align) = %f %f %d %f\n",
+	   PEQUIV*100,RMS,nEqPairs,quality);
+    quality_max = quality;
+    quality_sav = quality;
+    quality_old = quality;
+    RMSsav = RMS;
+    RMSold = RMS;
    for(i=0; i<rows; i++) {
      x_que_sav[1][i] = x_que[1][i]; 
      x_que_sav[2][i] = x_que[2][i]; 
      x_que_sav[3][i] = x_que[3][i]; 
-   }
+      x_que_old[1][i] = x_que[1][i];
+      x_que_old[2][i] = x_que[2][i];
+      x_que_old[3][i] = x_que[3][i];
  }
- free( (RELEASE) (str1) );
- free( (RELEASE) (str2) );
+
+    (void)rotrans(x_que, rows, U, T);
+    
+    if (RMS < RMSmin)
+      RMSmin = RMS;
+    free((RELEASE)(str1));
+    free((RELEASE)(str2));
  } else { /* PID < threshold */
-   printf("PID is %f, rather low to start with SeqAli Eq. pairs\n",PID*100);
+    printf("PEQUIV is %f, rather low to start with %d SeqAli Eq. pairs\n",
+	   PEQUIV*100, nEqPairs);
  }
 
  free_iVector(iina,0, MAXSEQ);
  free_iVector(jinb,0, MAXSEQ);
 
-/* END OF THE INITIAL STARTING POINT */
+  fflush(NULL);
 
- if(!lsq) {
- do{ iter++;    /* START OF MAIN ITERATION CYCLE: */
-/* CHECK COORDINATES:
-    stream = fopen( "coordchk.dat", "a" );
-	if( stream == NULL )
-	   printf( "Couldn't open file coordchk.dat\n" );
-	else   {
-    fprintf( stream, "Iteration # %d: \n",iter);
-    fprintf( stream, "Query: \n");
-	for(i=0;i<rows;i++) {
-	  fprintf( stream, "%f %f %f\n", x_que[1][i], x_que[2][i], x_que[3][i]);
+  /* END OF THE INITIAL STARTING POINT */
+  
+  if (!lsq) {
+    for (j=0; j<=(cols-1); j++) {
+      if (altered && isascii(a_tar[j]) && (! isalpha(a_tar[j]))) {
+	jOpnPen[j] = 20;
+	jExtPen[j] = 20;
+      } else {
+	jOpnPen[j] = 0;
+	jExtPen[j] = 0;
 	}
-    fprintf( stream, "Target: \n");
-	for(i=0;i<cols;i++) {
-	  fprintf( stream, "%f %f %f\n", x_tar[1][i], x_tar[2][i], x_tar[3][i]);
 	}
-    fclose( stream );
+    for (i=0; i<=(rows-1); i++) {
+      if (altered && isascii(a_que[i]) && (! isalpha(a_que[i]))) {
+	iOpnPen[i] = 20;
+	iExtPen[i] = 20;
+      } else {
+	iOpnPen[i] = 0;
+	iExtPen[i] = 0;
 	}
-*/
+    }
+
+    do {
+      iter++;    /* START OF MAIN ITERATION CYCLE: */
+      /* CHECK COORDINATES: */
+      /*      stream = fopen( "coordchk.dat", "a" ); */
+      /*      if (stream == NULL) */
+      /*        printf("Couldn't open file coordchk.dat\n" ); */
+      /*      else { */
+      /*        fprintf(stream, "Iteration # %d: \n",iter); */
+      /*        fprintf(stream, "Query: \n"); */
+      /*        for (i=0; i<rows; i++) { */
+      /* 	 fprintf(stream, "%f %f %f\n", */
+      /* 		 x_que[1][i], x_que[2][i], x_que[3][i]); */
+      /*        } */
+      /*        fprintf(stream, "Target: \n"); */
+      /*        for (i=0; i<cols; i++) { */
+      /* 	 fprintf(stream, "%f %f %f\n", */
+      /* 		 x_tar[1][i], x_tar[2][i], x_tar[3][i]); */
+      /*        } */
+      /*        fclose(stream); */
+      /*      } */
+
+      again = 0;
+      again2 = 0;
+      sav_updated = 0;
+      increased_gap_penalties = 0;
+     
  iina     = iVector(0,MAXSEQ);
  jinb     = iVector(0,MAXSEQ);
 
- for(i=0;i<=MAXSEQ;i++) {
+      for (i=0; i<=MAXSEQ; i++) {
    iina[i] = -1;
    jinb[i] = -1;
  }
 
- for(i=0;i<=rows-1;i++) {
-	for(j=0;j<=cols-1;j++) {
-		s[i][j]     = sqrt( (x_que[1][i]-x_tar[1][j])*(x_que[1][i]-x_tar[1][j]) +
+      for (i=0; i<=rows-1; i++) {
+	for (j=0;j<=cols-1;j++) {
+	  dd[i][j] = (SQR(x_que[1][i]-x_tar[1][j]) +
+			SQR(x_que[2][i]-x_tar[2][j]) +
+			SQR(x_que[3][i]-x_tar[3][j]));
+	  ss[i][j] = 0;
+	  if (use_carbonyl) {
+	    tempval = check_carbonyl(a_que[i],a_tar[j]);
+	    ss[i][j] += tempval;
+	  }
+	  if (ss[i][j] == 0) {
+	    ss[i][j] = dd[i][j];
+	    if (use_min_thresh && (ss[i][j] < L_THRESH_SQR)) {
+	      if (ss[i][j] <= L_MIN_SQR)
+		ss[i][j] = 0;
+	      else {
+		ss[i][j] =
+		  (sqrt(ss[i][j]) - L_MIN)*(L_THRESH/(L_THRESH-L_MIN));
+		if (ss[i][j] > 0) /* in case of roundoff error */
+		  ss[i][j] *= ss[i][j];
+		else
+		  ss[i][j] = 0;
+	      }
+	    } else if (use_min_thresh2 && (ss[i][j] < L_THRESH2_SQR)) {
+	      if (ss[i][j] <= L_MIN_SQR)
+		ss[i][j] = 0;
+	      else {
+		ss[i][j] =
+		  (sqrt(ss[i][j]) - L_MIN)*(L_THRESH2/(L_THRESH2-L_MIN));
+		if (ss[i][j] > 0) /* in case of roundoff error */
+		  ss[i][j] *= ss[i][j];
+		else
+		  ss[i][j] = 0;
+	      }
+	    }
+	    ss[i][j] = 20.0/(1.0 + (ss[i][j]/25.0));
+	    dd[i][j] = sqrt(dd[i][j]);
+	    
+	    /* ss[i][j] =
+	       sqrt((x_que[1][i]-x_tar[1][j])*(x_que[1][i]-x_tar[1][j]) +
 			                (x_que[2][i]-x_tar[2][j])*(x_que[2][i]-x_tar[2][j]) +
-			                (x_que[3][i]-x_tar[3][j])*(x_que[3][i]-x_tar[3][j]) );
-		s[i][j] = 20.0 / ( 1.0 + SQR(s[i][j]/5.0) );
+	       (x_que[3][i]-x_tar[3][j])*(x_que[3][i]-x_tar[3][j]));
+	       
+		 ss[i][j] = 20.0 / ( 1.0 + SQR(ss[i][j]/5.0) ); */
+	  }
+
 		SS[i][j]    = 0.0;
         TrRow[i][j] = 0.0;
 		TrCol[i][j] = 0.0;
@@ -465,175 +953,568 @@
 	 }
  }
 
- ret_val = dyn_pr_n2(s, iOpnPen, iExtPen, jOpnPen, jExtPen, rows, cols,
+      (void)dyn_pr_n2(ss, iOpnPen, iExtPen, jOpnPen, jExtPen,
+		      r_num_que, r_num_tar, rows, cols,
                      SS,  TrRow,   TrCol, &iOverallMax, &jOverallMax); 
 
+      nbrks_old = nbrks;
  nbrks = -1;
 
- nEqPairs_sav = nEqPairs;
- nEqPairs = TrMat2Equivalences (rows,cols,TrRow,TrCol,
-	                            iOverallMax,jOverallMax,iina,jinb,&nbrks);
+      nEqPairs_old = nEqPairs;
+      quality_old = quality;
+      nEqPairs = TrMat2Equivalences(rows,cols,TrRow,TrCol,
+				    iOverallMax,jOverallMax,
+				    iina,jinb,&nbrks);
 
- str1 = (CoordType *) malloc(nEqPairs * sizeof(CoordType));
- str2 = (CoordType *) malloc(nEqPairs * sizeof(CoordType));
+      if (use_carbonyl)
+	nEqPairs = 4*(floor((double)nEqPairs/4.0));
 
- for(i=0;i<nEqPairs;i++) {
-   str1[i].x = x_que[1][iina[i]-1]; str2[i].x = x_tar[1][jinb[i]-1];
-   str1[i].y = x_que[2][iina[i]-1]; str2[i].y = x_tar[2][jinb[i]-1];
-   str1[i].z = x_que[3][iina[i]-1]; str2[i].z = x_tar[3][jinb[i]-1];		
+      str1 = (CoordType *)malloc(nEqPairs * sizeof(CoordType));
+      if (!str1) {
+	fprintf(stderr,"main: Allocation failed!\n");
+	exit(1);
  }
+      str2 = (CoordType *)malloc(nEqPairs * sizeof(CoordType));
+      if (!str2) {
+	fprintf(stderr,"main: Allocation failed!\n");
+	exit(1);
+      }
+
+      for (i=0; i<nEqPairs; i++) {
+	str1[i].x = x_que[1][iina[i]-1];
+	str2[i].x = x_tar[1][jinb[i]-1];
+
+	str1[i].y = x_que[2][iina[i]-1];
+	str2[i].y = x_tar[2][jinb[i]-1];
+
+	str1[i].z = x_que[3][iina[i]-1];
+	str2[i].z = x_tar[3][jinb[i]-1];
+      }
 
+      RMSold = RMS;
  RMS = bestfit(U, T, str1, str2, nEqPairs); 
- printf("RMS, eq.pairs = %f %d\n",RMS,nEqPairs);
+      if (RMS > 0.01)
+	quality = fsqrt(nEqPairs)/RMS;
+      else
+	quality = 100*fsqrt(nEqPairs);
+      printf("RMS, eq.pairs, quality = %f %d %f\n",RMS,nEqPairs,quality);
 
- ret_val = rotrans(x_que, rows, U, T);
+      (void)rotrans(x_que, rows, U, T);
 
- if( RMS < RMSmin ) {
+      /* expected increase in RMS is proportional to square root of chain
+	 length - Allen */
+
+      if ((RMS < RMSmin) || 
+	  ((quality > quality_sav) && ((RMS < BAD_THRESH) ||
+				       (RMS == RMSmin))) ||
+	  ((nEqPairs_sav < 0) &&
+	   ((nEqPairs > nEqPairs_old) || (quality >= quality_sav) ||
+	    (RMS <= RMSsav) ||
+	    ((nEqPairs < nEqPairs_old) && (quality < quality_sav) &&
+	     (total_OpnPen < 10)))) ||
+	  ((nbrks < nbrks_sav) && (quality_sav <= quality) &&
+	   ((RMS < BAD_THRESH) || (RMS <= RMSsav))) ||
+	  ((nEqPairs_sav < nEqPairs) &&
+	   ((RMS < BAD_THRESH) || (RMS <= RMSmin)) &&
+	   ((RMS - RMSsav) < 0.1))) {
+	if ((nEqPairs_sav < 0) && (nEqPairs < nEqPairs_old) &&
+	    (quality < quality_sav) && (total_OpnPen < 10) &&
+	    ((RMS > RMSsav) || (RMSsav < BAD_THRESH))) {
+	  /* increase gap penalties -
+	     ratio of 1/0.05 btwn Opn and Ext == Structal original
+	     of 10/0.5 */
+	  again = 1;
+	  again2 = 1;
+	  increased_gap_penalties = 1;
+	  printf("Increasing gap penalties\n");
+	  total_OpnPen++; /* Should thresh of 10 be adjusted for changes in
+			     structal formula constants? XXX */
+	  for (j=1; j < (cols-1); j++) {
+	    jOpnPen[j]++;
+	    jExtPen[j] += 0.05;
+	  }
+	  for (i=1; i < (rows-1); i++) {
+	    iOpnPen[i]++;
+	    iExtPen[i] += 0.05;
+	  }
+	} else if (((quality > quality_sav) && ((RMS < BAD_THRESH) ||
+						(RMS <= RMSsav))) ||
+		   ((nEqPairs_sav < 0) && ((nEqPairs > nEqPairs_old) ||
+					   (quality >= quality_sav) ||
+					   ((nEqPairs == nEqPairs_old) &&
+					    (RMS <= RMSsav)))) ||
+		   ((nbrks < nbrks_sav) && (quality_sav <= quality) &&
+		    ((RMS < BAD_THRESH) || (RMS <= RMSsav))) ||
+		   ((nEqPairs_sav < nEqPairs) &&
+		    ((RMS < BAD_THRESH) || (RMS <= RMSmin)) &&
+		    ((RMS - RMSsav) < 0.1))) {
+	  if (nEqPairs_sav < 0) {
+	    again = 1;
+	    if (((quality_sav - quality) >= 0.5) ||
+		((quality < quality_sav) &&
+		 (nEqPairs < nEqPairs_old))) {
+	      printf("Structal method may have failed\n");
+	      again2 = 1;
+	    }
+	  }
+	  if (quality > quality_max)
+	    quality_max = quality;
+	  quality_sav = quality;
+	  RMSsav = RMS;
+	  nEqPairs_sav = nEqPairs;
+	  nbrks_sav = nbrks;
+	  sav_updated = 1;
+	  if (RMS < RMSmin) {
    RMSmin = RMS;
-   for(i=0; i<rows; i++) {
+	    again = 1;
+	  } else if (RMS == RMSmin)
+	    again = 1;
+
+	  for (i=0; i<rows; i++) {
      x_que_sav[1][i] = x_que[1][i]; 
      x_que_sav[2][i] = x_que[2][i]; 
      x_que_sav[3][i] = x_que[3][i]; 
    }
-   for(i=0;i<=MAXSEQ;i++) {
+	  for (i=0; i<=MAXSEQ; i++) {
+	    iina_sav[i] = iina[i];
+	    jinb_sav[i] = jinb[i];
+	  }
+	} else if ((quality_sav == quality) ||
+		   ((RMSmin >= BAD_THRESH) && (RMS < RMSsav)) ||
+		   ((((quality_max - quality) < 0.001) ||
+		     (((quality_max - quality) < 0.5) &&
+		      (total_OpnPen >= 10))) &&
+		    ((RMSmin - RMS) >= 0.1))) {
+	  again = 1;
+	  RMSmin = RMS;
+	  RMSsav = RMS;
+	  quality_sav = quality;
+	  nEqPairs_sav = nEqPairs;
+	  nbrks_sav = nbrks;
+	  sav_updated = 1;
+	  for (i=0; i<rows; i++) {
+	    x_que_sav[1][i] = x_que[1][i]; 
+	    x_que_sav[2][i] = x_que[2][i]; 
+	    x_que_sav[3][i] = x_que[3][i]; 
+	  }
+	  for (i=0; i<=MAXSEQ; i++) {
      iina_sav[i] = iina[i];
      jinb_sav[i] = jinb[i];
    }
+	} else { /* increase gap penalties -
+		    ratio of 1/0.05 btwn Opn and Ext == Structal original
+		    of 10/0.5 */
+	  again = 1;
+	  again2 = 1;
+	  increased_gap_penalties = 1;
+	  printf("Increasing gap penalties\n");
+	  total_OpnPen++;
+	  for (j=1; j < (cols-1); j++) {
+	    jOpnPen[j]++;
+	    jExtPen[j] += 0.05;
+	  }
+	  for (i=1; i < (rows-1); i++) {
+	    iOpnPen[i]++;
+	    iExtPen[i] += 0.05;
+	  }
+	}
  }
 
+      if (nEqPairs_sav < 0) {
+	if (increased_gap_penalties)
+	  stay = 1;
+	else {
+	  printf("Structal method unsuccessful\n");
+	  RMSmin = RMSold;
+	  RMSsav = RMSold;
+	  quality_sav = quality_old;
+	  nEqPairs_sav = nEqPairs_old;
+	  nbrks_sav = nbrks_old;
+	  for (i=0; i<rows; i++) {
+	    x_que_sav[1][i] = x_que_old[1][i]; 
+	    x_que_sav[2][i] = x_que_old[2][i]; 
+	    x_que_sav[3][i] = x_que_old[3][i]; 
+	  }
+	  for (i=0; i<=MAXSEQ; i++) {
+	    iina_sav[i] = iina_old[i];
+	    jinb_sav[i] = jinb_old[i];
+	  }
+	}
+      } else if ((nEqPairs == nEqPairs_old) ||
+		 (nEqPairs == nEqPairs_sav)) {
+	stay = check_eq(iina,jinb,iina_old,jinb_old,
+			MIN(nEqPairs,nEqPairs_old));
+	if (stay && (! sav_updated) && (! again2) &&
+	    (nEqPairs == nEqPairs_sav) && (iter > 1)) {
+	  if (! check_eq(iina,jinb,iina_sav,jinb_sav,
+			 MIN(nEqPairs,nEqPairs_sav)))
+	    stay = 0;
+	}
 
- if( !(nEqPairs-nEqPairs_sav) ) {
-	 stay = check_eq(iina,jinb,iina_sav,jinb_sav,nEqPairs);
+	if (again2) {
+	  if ((! stay) && (iter > 1) && (! increased_gap_penalties))
+	    printf("Doing again despite equal pairs (again2 is 1)\n");
+	  stay = 1;
+	} else if (again) {
+	  if ((! stay) && (iter > 1)) {
+	    if ((fabs(U[0][0]-1) >= epsilon2) ||
+		(fabs(U[0][1]) >= epsilon2) ||
+		(fabs(U[0][2]) >= epsilon2) ||
+		(fabs(U[1][0]) >= epsilon2) ||
+		(fabs(U[1][1]-1) >= epsilon2) ||
+		(fabs(U[1][2]) >= epsilon2) ||
+		(fabs(U[2][0]) >= epsilon2) ||
+		(fabs(U[2][1]) >= epsilon2) ||
+		(fabs(U[2][2]-1) >= epsilon2) ||
+		(fabs(T[0]) >= epsilon2) ||
+		(fabs(T[1]) >= epsilon2) ||
+		(fabs(T[2]) >= epsilon2)) {
+	      printf("Doing again despite equal pairs\n");
+	      stay = 1;
+	    }
+	  } else
+	    stay = 1;
+	} else {
+	  if (stay && (iter > 1) &&
+	      (fabs(U[0][0]-1) < epsilon) &&
+	      (fabs(U[0][1]) < epsilon) &&
+	      (fabs(U[0][2]) < epsilon) &&
+	      (fabs(U[1][0]) < epsilon) &&
+	      (fabs(U[1][1]-1) < epsilon) &&
+	      (fabs(U[1][2]) < epsilon) &&
+	      (fabs(U[2][0]) < epsilon) &&
+	      (fabs(U[2][1]) < epsilon) &&
+	      (fabs(U[2][2]-1) < epsilon) &&
+	      (fabs(T[0]) < epsilon2) &&
+	      (fabs(T[1]) < epsilon2) &&
+	      (fabs(T[2]) < epsilon2)) {
+	    /* prevent getting stuck - Allen */
+	    for (i = (stay-1); (i <= nEqPairs) && (i <= nEqPairs_old); i++) {
+	      if (isascii(a_que[iina_old[i]-1]) &&
+		  isascii(a_que[iina[i]-1]) &&
+		  (! islower(a_que[iina_old[i]-1])) &&
+		  (! islower(a_que[iina[i]-1])) &&
+		  isascii(a_tar[jinb_old[i]-1]) &&
+		  isascii(a_tar[jinb[i]-1]) &&
+		  (! islower(a_tar[jinb_old[i]-1])) &&
+		  (! islower(a_tar[jinb[i]-1])) &&
+		  ((iina[i] != iina_old[i]) || (jinb[i] != jinb_old[i]))) {
+		printf("Looping; old:  %5d %c%c%c %4d :  %5d  :  %5d %c%c%c %4d\n",
+		       iina_old[i], aa_que[iina_old[i]-1][0],
+		       aa_que[iina_old[i]-1][1],
+		       aa_que[iina_old[i]-1][2], 
+		       r_num_que[iina_old[i]-1],
+		       i,
+		       jinb_old[i], aa_tar[jinb_old[i]-1][0],
+		       aa_tar[jinb_old[i]-1][1],
+		       aa_tar[jinb_old[i]-1][2],
+		       r_num_tar[jinb_old[i]-1]);
+		printf("Looping; new:  %5d %c%c%c %4d :  %5d  :  %5d %c%c%c %4d\n",
+		       iina[i], aa_que[iina[i]-1][0],
+		       aa_que[iina[i]-1][1],
+		       aa_que[iina[i]-1][2], r_num_que[iina[i]-1],
+		       i,
+		       jinb[i], aa_tar[jinb[i]-1][0],
+		       aa_tar[jinb[i]-1][1],
+		       aa_tar[jinb[i]-1][2],
+		       r_num_tar[jinb[i]-1]);
+		if (((quality_old - quality) >= 0.5) ||
+		    ((RMSold >= BAD_THRESH) && ((RMS - RMSold) >= 0.1)) ||
+		    ((RMSold < BAD_THRESH) && (quality_old > quality)) ||
+		    ((quality_sav - MAX(quality,quality_old)) >= 0.5) ||
+		    ((RMSsav >= BAD_THRESH) &&
+		     ((MIN(RMS,RMSold) - RMSsav) >= 0.1)) ||
+		    ((RMSsav < BAD_THRESH) &&
+		     (quality_sav > MAX(quality,quality_old))))
+		  break;
+	      }
+	    }
+	    stay = 0;
  }
+	}
+      }
 
- free( (RELEASE) (str1) );
- free( (RELEASE) (str2) );
+      free((RELEASE)(str1));
+      free((RELEASE)(str2));
 
+      for (i=0; i<=MAXSEQ; i++) {
+	iina_old[i] = iina[i];
+	jinb_old[i] = jinb[i];
+      }
+      
  free_iVector(iina,0, MAXSEQ);
  free_iVector(jinb,0, MAXSEQ);
 
-} while(stay > 0 && iter < 100); /* End of iteration cycle */
- } /* if(structal) */
+      fflush(NULL);
 
- printf("RMSmin = %f \n",RMSmin);
+    } while(stay > 0 && iter < 100); /* End of iteration cycle */
+  } /* if(!lsq) */
 
-/* Performing back-transformation of BOTH structures (QUERY will still be PMI-aligned!): */
- ret_val = FormRotMatrX(Rtemp,angle_c_tar);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
- ret_val = FormRotMatrY(Rtemp,angle_b_tar); 
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
- ret_val = TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
- ret_val = TRmoveXYZstruc(Tcm_tar,Runity,x_que,rows);
- ret_val = TRmoveXYZstruc(Tcm_tar,Runity,x_tar,cols);
+  printf("RMSmin = %f\n",RMSmin);
+  printf("quality_max = %f\n", quality_max);
 
-/* CHECK COORDINATES: */
-/*
- stream = fopen( "rot_query.dat", "w" );
- if( stream == NULL )
-   printf( "Couldn't open file rot_query.dat\n" );
+  /* Performing back-transformation of BOTH structures
+     (QUERY will still be PMI-aligned!): */
+  (void)FormRotMatrX(Rtemp,angle_c_tar);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  printf("Rotating query: x-angle %.10f; %.1f %.1f %.1f; %.1f %.10f %.10f; %.1f %.10f %.10f\n",
+	 angle_c_tar,
+	 Rtemp[1][1],Rtemp[1][2],Rtemp[1][3],
+	 Rtemp[2][1],Rtemp[2][2],Rtemp[2][3],
+	 Rtemp[3][1],Rtemp[3][2],Rtemp[3][3]);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
+  (void)FormRotMatrY(Rtemp,angle_b_tar); 
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_que,rows);
+  printf("Rotating query: y-angle %.10f; %.10f %.1f %.10f; %.1f %.1f %.1f; %.10f %.1f %.10f\n",
+	 angle_b_tar,
+	 Rtemp[1][1],Rtemp[1][2],Rtemp[1][3],
+	 Rtemp[2][1],Rtemp[2][2],Rtemp[2][3],
+	 Rtemp[3][1],Rtemp[3][2],Rtemp[3][3]);
+  (void)TRmoveXYZstruc(Tzero,Rtemp,x_tar,cols);
+  (void)TRmoveXYZstruc(Tcm_tar,Runity,x_que,rows);
+  printf("Moving query: %.10f %.10f %.10f\n",
+	 Tcm_tar[1], Tcm_tar[2], Tcm_tar[3]);
+  (void)TRmoveXYZstruc(Tcm_tar,Runity,x_tar,cols);
+
+  /* CHECK COORDINATES: */
+/*   stream = fopen("rot_query.dat", "w"); */
+/*   if (stream == NULL) */
+/*     perror("main: Couldn't open file rot_query.dat"); */
+/*   else { */
+/*     for (i=0; i<rows; i++) { */
+/*       fprintf(stream, "%4s%7d%4s  %c%c%c %1s%4d%12.3f %8.3f %8.3f\n", */
+/* 	      "ATOM",i+1,"CA",aa_que[i][0], aa_que[i][1], aa_que[i][2],"L", */
+/* 	      i+1,x_que[1][i],  x_que[2][i], x_que[3][i]); */
+/*     } */
+/*     fclose(stream); */
+/*   } */
+
+  if (lsq)
+    nEqPairs_sav = nEqPairs;
+
+  printf("Final: RMS, eq.pairs, quality = %f %d %f\n",
+	 RMSsav,nEqPairs_sav,quality_sav);
+
+  fflush(NULL);
+
+  if (structal) {  /* STRUCTAL-LIKE OUTPUT */
+    stream = fopen(structal_out, "w");
+    if (stream == NULL)
+      fprintf(stderr, "main: Couldn't open file %s: %s", structal_out,
+	      strerror(errno));
  else {
-   for(i=0;i<rows;i++) {
-	  fprintf( stream, "%4s%7d%4s  %c%c%c %1s%4d%12.3f %8.3f %8.3f\n", "ATOM",i+1,"CA",
-		  aa_que[i][0], aa_que[i][1], aa_que[i][2],"L",i+1,
-		  x_que[1][i],  x_que[2][i], x_que[3][i]);
+      fprintf(stream, "DUMP rmsnoe   %f (RMS deviation, before elim. bad)\n",
+	      RMSsav);
+      /*
+	EQUIV i seqai : k : j seqaj ja
+	EQUIV   105 GLN  105  :    86 :     98 VAL   98
+      */  
+      fprintf(stream, "#EQUIV WHAT i seqa i : j : m seqa m\n");
+      for (i=0; i<nEqPairs_sav; i++) {
+	if (a_que[iina_sav[i]-1] == a_tar[jinb_sav[i]-1])
+	  aa = '*';
+	else
+	  aa = ' ';
+	if (use_carbonyl && (! isascii(a_que[iina_sav[i]-1]))) {
+	  if (islower(toascii(a_que[iina_sav[i]-1]))) {
+	    fprintf(stream,
+	       "EQUIV C   %5d %c%c%c %c %4d :  %5d  : %c  %5d %c%c%c %4d %c\n",
+		    iina_sav[i],aa_que[iina_sav[i]-1][0],
+		    aa_que[iina_sav[i]-1][1],
+		    aa_que[iina_sav[i]-1][2],
+		    _toupper(toascii(a_que[iina_sav[i]-1])),
+		    r_num_que[iina_sav[i]-1],
+		    i+1,_toupper(toascii(a_tar[jinb_sav[i]-1])),
+		    jinb_sav[i],
+		    aa_tar[jinb_sav[i]-1][0], aa_tar[jinb_sav[i]-1][1],
+		    aa_tar[jinb_sav[i]-1][2], 
+		    r_num_tar[jinb_sav[i]-1], aa);
+	  } else {
+	    fprintf(stream,
+	       "EQUIV N   %5d %c%c%c %c %4d :  %5d  : %c  %5d %c%c%c %4d %c\n",
+		    iina_sav[i],aa_que[iina_sav[i]-1][0],
+		    aa_que[iina_sav[i]-1][1],
+		    aa_que[iina_sav[i]-1][2], toascii(a_que[iina_sav[i]-1]),
+		    r_num_que[iina_sav[i]-1],
+		    i+1, toascii(a_tar[jinb_sav[i]-1]), jinb_sav[i],
+		    aa_tar[jinb_sav[i]-1][0], aa_tar[jinb_sav[i]-1][1],
+		    aa_tar[jinb_sav[i]-1][2],
+		    r_num_tar[jinb_sav[i]-1], aa);
    }
-   fclose( stream );
+	} else if (use_carbonyl && islower(a_que[iina_sav[i]-1])) {
+	  fprintf(stream,
+	       "EQUIV O   %5d %c%c%c %c %4d :  %5d  : %c  %5d %c%c%c %4d %c\n",
+		  iina_sav[i],aa_que[iina_sav[i]-1][0],
+		  aa_que[iina_sav[i]-1][1],
+		  aa_que[iina_sav[i]-1][2], _toupper(a_que[iina_sav[i]-1]),
+		  r_num_que[iina_sav[i]-1],
+		  i+1, _toupper(a_tar[jinb_sav[i]-1]), jinb_sav[i],
+		  aa_tar[jinb_sav[i]-1][0], aa_tar[jinb_sav[i]-1][1],
+		  aa_tar[jinb_sav[i]-1][2],
+		  r_num_tar[jinb_sav[i]-1], aa);
+	} else {
+	  fprintf(stream,
+	       "EQUIV CA  %5d %c%c%c %c %4d :  %5d  : %c  %5d %c%c%c %4d %c\n",
+		  iina_sav[i],aa_que[iina_sav[i]-1][0],
+		  aa_que[iina_sav[i]-1][1],
+		  aa_que[iina_sav[i]-1][2], a_que[iina_sav[i]-1],
+		  r_num_que[iina_sav[i]-1],
+		  i+1, a_tar[jinb_sav[i]-1], jinb_sav[i],
+		  aa_tar[jinb_sav[i]-1][0], aa_tar[jinb_sav[i]-1][1],
+		  aa_tar[jinb_sav[i]-1][2],
+		  r_num_tar[jinb_sav[i]-1], aa);
  }
-*/
- stream = fopen( "que.dat", "w" );
- if( stream == NULL )
-   printf( "Couldn't open file que.dat\n" );
- else {
-   fprintf( stream, "%d\n", rows);
-   for(i=0;i<rows;i++) { 
-      fprintf( stream, "%8.3f %8.3f %8.3f\n", x_que[1][i], x_que[2][i], x_que[3][i]);
    }
-   fclose( stream );
+      fprintf(stream, "#EQUIV DONE\n\n");
+      fprintf(stream, "IXYZ x_oldk, str. 1 original (PDB standard format)\n");
+      for (i=0; i<rows; i++) {
+	if (use_carbonyl && (! isascii(a_que[i]))) {
+	  if (islower(toascii(a_que[i]))) {
+	    fprintf(stream,
+		    "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		    i+1," C  ",aa_que[i][0], aa_que[i][1],
+		    aa_que[i][2],
+		    r_num_que[i], x_que_original[1][i],
+		    x_que_original[2][i],
+		    x_que_original[3][i]);
+	  } else {
+	   fprintf(stream,
+		   "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		   i+1," N  ",aa_que[i][0], aa_que[i][1],
+		   aa_que[i][2],
+		   r_num_que[i], x_que_original[1][i],
+		   x_que_original[2][i], x_que_original[3][i]);
  }
-
- if(structal) {  /* STRUCTAL-LIKE OUTPUT */
-   stream = fopen( "structal.out", "w" );
-   if( stream == NULL )
-     printf( "Couldn't open file structal.out\n" );
-   else {
-     fprintf( stream, "DUMP rmsnoe   %f (RMS deviation, before elim. bad)\n", RMSmin);
-     fprintf( stream, "IXYZ x_oldk, str. 1 original (PDB standard format)\n");
-     for(i=0;i<rows;i++) {
-	    fprintf( stream, "%4s%7d%4s  %c%c%c %1s%4d%12.3f %8.3f %8.3f\n", "ATOM",i+1,"CA",
-	    	  aa_que[i][0], aa_que[i][1], aa_que[i][2],"L",i+1,
-		      x_que_original[1][i],  x_que_original[2][i], x_que_original[3][i]);
+       } else if (use_carbonyl && islower(a_que[i])) {
+	 fprintf(stream,
+		 "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		 i+1," O  ",aa_que[i][0], aa_que[i][1], aa_que[i][2],
+		 r_num_que[i],x_que_original[1][i],
+		 x_que_original[2][i],
+		 x_que_original[3][i]);
+       } else {
+	 fprintf(stream,
+		 "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		 i+1," CA ",aa_que[i][0], aa_que[i][1], aa_que[i][2],
+		 r_num_que[i],
+		 x_que_original[1][i],
+		 x_que_original[2][i],
+		 x_que_original[3][i]);
 	 }
-     fprintf( stream, "IXYZ DONE\n\n");
-	 fprintf( stream, "IXYZ x_old, str. 1 rotated (PDB standard format)\n");
-     for(i=0;i<rows;i++) {
-	    fprintf( stream, "%4s%7d%4s  %c%c%c %1s%4d%12.3f %8.3f %8.3f\n", "ATOM",i+1,"CA",
-	    	  aa_que[i][0], aa_que[i][1], aa_que[i][2],"L",i+1,
-		      x_que[1][i],  x_que[2][i], x_que[3][i]);
 	 }
-     fprintf( stream, "IXYZ DONE\n\n");
-	 fprintf( stream, "IXYZ x_new, str. 2 original (PDB standard format)\n");
-     for(i=0;i<cols;i++) {
-	    fprintf( stream, "%4s%7d%4s  %c%c%c %1s%4d%12.3f %8.3f %8.3f\n", "ATOM",i+1,"CA",
-	    	  aa_tar[i][0], aa_tar[i][1], aa_tar[i][2],"L",i+1,
-		      x_tar[1][i],  x_tar[2][i], x_tar[3][i]);
+     fprintf(stream, "IXYZ DONE\n\n");
+     fprintf(stream, "IXYZ x_old, str. 1 rotated (PDB standard format)\n");
+     for (i=0; i<rows; i++) {
+       if (use_carbonyl && (! isascii(a_que[i]))) {
+	 if (islower(toascii(a_que[i]))) {
+	   fprintf(stream,
+		   "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		   i+1," C  ",aa_que[i][0], aa_que[i][1],
+		   aa_que[i][2],
+		   r_num_que[i], x_que[1][i], x_que[2][i],x_que[3][i]);
+	 } else {
+	   fprintf(stream,
+		   "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		   i+1," N  ",aa_que[i][0], aa_que[i][1],
+		   aa_que[i][2],
+		   r_num_que[i], x_que[1][i], x_que[2][i], x_que[3][i]);
 	 }
-     fprintf( stream, "IXYZ DONE\n\n");
-     /*
-     EQUIV i seqai : k : j seqaj ja
-     EQUIV   105 GLN  105  :    86 :     98 VAL   98
-     */  
-     fprintf( stream, "EQUIV i seqa i : k : j seqa j \n");	
-     for(i=0;i<nEqPairs;i++) {	 
-	 fprintf( stream, "EQUIV %5d %c%c%c %4d  : %5d :  %5d  %c%c%c%4d\n",
-		iina_sav[i],
-		aa_que[iina_sav[i]-1][0], aa_que[iina_sav[i]-1][1], aa_que[iina_sav[i]-1][2],
-		iina_sav[i], i,
-		jinb_sav[i],
-	    aa_tar[jinb_sav[i]-1][0], aa_tar[jinb_sav[i]-1][1], aa_tar[jinb_sav[i]-1][2],
-		jinb_sav[i]);
+       } else if (use_carbonyl && islower(a_que[i])) {
+	 fprintf(stream,
+		 "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		 i+1," O  ",aa_que[i][0], aa_que[i][1], aa_que[i][2],
+		 r_num_que[i],x_que[1][i],  x_que[2][i], x_que[3][i]);
+       } else {
+	 fprintf(stream,
+		 "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		 i+1," CA ",aa_que[i][0], aa_que[i][1], aa_que[i][2],
+		 r_num_que[i],x_que[1][i],  x_que[2][i], x_que[3][i]);
 	 }
-     fclose( stream );
    } 
- } /* if(structal) */
+     fprintf(stream, "IXYZ DONE\n\n");
+     fprintf(stream, "IXYZ x_new, str. 2 original (PDB standard format)\n");
+     for (i=0; i<cols; i++) {
+       if (use_carbonyl && (! isascii(a_tar[i]))) {
+	 if (islower(toascii(a_tar[i]))) {
+	   fprintf(stream,
+		   "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		   i+1," C  ",aa_tar[i][0], aa_tar[i][1],
+		   aa_tar[i][2],
+		   r_num_tar[i], x_tar[1][i], x_tar[2][i],x_tar[3][i]);
+	 } else {
+	   fprintf(stream,
+		   "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		   i+1," N  ",aa_tar[i][0], aa_tar[i][1],
+		   aa_tar[i][2],
+		   r_num_tar[i], x_tar[1][i], x_tar[2][i], x_tar[3][i]);
+	 }
+       } else if (use_carbonyl && islower(a_tar[i])) {
+	 fprintf(stream,
+		 "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		 i+1," O  ",aa_tar[i][0], aa_tar[i][1], aa_tar[i][2],
+		 r_num_tar[i],x_tar[1][i],  x_tar[2][i], x_tar[3][i]);
+       } else {
+	 fprintf(stream,
+		 "ATOM  %5d %4s %c%c%c L%4d    %8.3f%8.3f%8.3f  1.00\n",
+		 i+1," CA ",aa_tar[i][0], aa_tar[i][1], aa_tar[i][2],
+		 r_num_tar[i],x_tar[1][i],  x_tar[2][i], x_tar[3][i]);
+       }
+     }
+     fprintf(stream, "IXYZ DONE\n\n");
+     fclose(stream);
+   }
+  } /* if(structal) */ else {
+    stream = fopen("que.dat", "w");
+    if (stream == NULL)
+      perror("main: Couldn't open file que.dat");
+    else {
+      fprintf(stream, "%d\n", rows);
+      for (i=0; i<rows; i++) { 
+	fprintf(stream, "%8.3f %8.3f %8.3f\n",
+		x_que[1][i], x_que[2][i], x_que[3][i]);
+      }
+      fclose(stream);
+    }
+  }
 
-/* FREE ALL ALLOCATED MEMORY: */
- free_iVector(iina_sav,0, MAXSEQ);
- free_iVector(jinb_sav,0, MAXSEQ);
+  /* FREE ALL ALLOCATED MEMORY: */
+  /* Not necessary if returning/exiting from main - Allen */
+/*   free_iVector(iina_sav,0, MAXSEQ); */
+/*   free_iVector(jinb_sav,0, MAXSEQ); */
 
- free_dMatrix(s,0,rows-1,0,cols-1);
- free_dMatrix(SS,0,rows-1,0,cols-1);
- free_dMatrix(TrRow,0,rows-1,0,cols-1);
- free_dMatrix(TrCol,0,rows-1,0,cols-1);
- free_iVector(jOpnPen,0, cols-1);
- free_iVector(jExtPen,0, cols-1);
- free_iVector(iOpnPen,0, rows-1);
- free_iVector(iExtPen,0, rows-1);
+/*   free_dMatrix(s,0,rows-1,0,cols-1); */
+/*  free_dMatrix(SS,0,rows-1,0,cols-1); */
+/*  free_dMatrix(TrRow,0,rows-1,0,cols-1); */
+/*  free_dMatrix(TrCol,0,rows-1,0,cols-1); */
+/*  free_iVector(jOpnPen,0, cols-1); */
+/*  free_iVector(jExtPen,0, cols-1); */
+/*  free_iVector(iOpnPen,0, rows-1); */
+/*  free_iVector(iExtPen,0, rows-1); */
 
- free_dMatrix(x_que,1,3,0,rows-1);
- free_dMatrix(x_que_sav,1,3,0,rows-1);
- free_dMatrix(x_que_original,1,3,0,rows-1);
- free_dMatrix(x_tar,1,3,0,cols-1);
+/*  free_dMatrix(x_que,1,3,0,rows-1); */
+/*  free_dMatrix(x_que_sav,1,3,0,rows-1); */
+/*  free_dMatrix(x_que_original,1,3,0,rows-1); */
+/*  free_dMatrix(x_tar,1,3,0,cols-1); */
 
- free_cVector(a_que,0,rows-1);
- free_cVector(a_tar,0,cols-1);
+/*  free_cVector(a_que,0,rows-1); */
+/*  free_cVector(a_tar,0,cols-1); */
 
- free_cVector(s1,1,StringMax);
- free_cVector(s2,1,StringMax);
- free_cVector(s3,1,StringMax);
- free_cVector(s4,1,StringMax);
+/*  free_cVector(s1,1,StringMax); */
+/*  free_cVector(s2,1,StringMax); */
+/*  free_cVector(s3,1,StringMax); */
+/*  free_cVector(s4,1,StringMax); */
 
- free_cMatrix(aa_que,0,rows-1,0,2);
- free_cMatrix(aa_tar,0,cols-1,0,2);
+/*  free_cMatrix(aa_que,0,rows-1,0,2); */
+/*  free_cMatrix(aa_tar,0,cols-1,0,2); */
 
  /* freeing memory from PMI alignment: */
- free_dVector(Tcm,1,3);
- free_dVector(Tzero,1,3);
- free_dVector(TMPvec,1,3);
- free_dVector(Tcm_que,1,3);
- free_dVector(Tcm_tar,1,3);
- free_dMatrix(Rtemp,1,3,1,3);
- free_dMatrix(Runity,1,3,1,3);
+/*  free_dVector(Tcm,1,3); */
+/*  free_dVector(Tzero,1,3); */
+/*  free_dVector(TMPvec,1,3); */
+/*  free_dVector(Tcm_que,1,3); */ /* not needed */
+/*  free_dVector(Tcm_tar,1,3); */
+/*  free_dMatrix(Rtemp,1,3,1,3); */
+/*  free_dMatrix(Runity,1,3,1,3); */
 
  return 0;
 }
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/Makefile.am lsqrms-2.0.4b/src/Makefile.am
--- lsqrms-2.0.4b.old/src/Makefile.am	Sun Apr 20 01:25:04 EDT 2003
+++ lsqrms-2.0.4b/src/Makefile.am	Sun Feb 24 22:49:49 EST 2008
@@ -1,6 +1,6 @@
 bin_PROGRAMS = lsqrms
 AM_LDFLAGS = -lm
-AM_CFLAGS = -Wall -g
+AM_CFLAGS = 
 
 lsqrms_SOURCES = dynapro.c main.c matvecalloc.c matvecutils.c \
  provepdb.c
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/Makefile.in lsqrms-2.0.4b/src/Makefile.in
--- lsqrms-2.0.4b.old/src/Makefile.in	Sun Apr 20 01:25:09 EDT 2003
+++ lsqrms-2.0.4b/src/Makefile.in	Sun Feb 24 22:50:02 EST 2008
@@ -104,7 +104,7 @@
 target_alias = @target_alias@
 bin_PROGRAMS = lsqrms
 AM_LDFLAGS = -lm
-AM_CFLAGS = -Wall -g
+AM_CFLAGS = 
 
 lsqrms_SOURCES = dynapro.c main.c matvecalloc.c matvecutils.c \
  provepdb.c
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/matvecalloc.c lsqrms-2.0.4b/src/matvecalloc.c
--- lsqrms-2.0.4b.old/src/matvecalloc.c	Wed Mar 12 17:12:13 EST 2003
+++ lsqrms-2.0.4b/src/matvecalloc.c	Sun Feb 24 22:49:49 EST 2008
@@ -1,14 +1,16 @@
-#include <stdio.h>
-#include <stdlib.h>
+#include "lsqrms.h"
+#include "matvecalloc.h"
 
 #define EDGE 1
-#define RELEASE char*
 
 char *cVector(long nfirst, long nlast)
 {
    char *vtr;
-   vtr = (char *)malloc( (size_t) ((nlast-nfirst+1+EDGE)*sizeof(char)) );
-   if(!vtr) printf( "Allocation failed!\n" );
+   vtr = (char *)malloc((size_t)((nlast-nfirst+1+EDGE) * sizeof(char)));
+   if (!vtr) {
+     fprintf(stderr,"cVector: Allocation failed!\n");
+     return NULL;
+   } else
    return vtr-nfirst+EDGE;
 }
 
@@ -15,8 +17,11 @@
 int *iVector(long nfirst, long nlast)
 {
    int *vtr;
-   vtr = (int *)malloc( (size_t) ((nlast-nfirst+1+EDGE)*sizeof(int)) );
-   if(!vtr) printf( "Allocation failed!\n" );
+   vtr = (int *)malloc((size_t)((nlast-nfirst+1+EDGE) * sizeof(int)));
+   if (!vtr) {
+     fprintf(stderr,"iVector: Allocation failed!\n");
+     return NULL;
+   } else
    return vtr-nfirst+EDGE;
 }
 
@@ -23,8 +28,11 @@
 double *dVector(long nfirst, long nlast)
 {
    double *vtr;
-   vtr = (double *)malloc( (size_t) ((nlast-nfirst+1+EDGE)*sizeof(double)) );
-   if(!vtr) printf( "Allocation failed!\n" );
+   vtr = (double *)malloc((size_t)((nlast-nfirst+1+EDGE) * sizeof(double)));
+   if (!vtr) {
+     fprintf(stderr,"dVector: Allocation failed!\n");
+     return NULL;
+   } else
    return vtr-nfirst+EDGE;
 }
 
@@ -31,87 +39,121 @@
 float *fVector(long nfirst, long nlast)
 {
    float *vtr;
-   vtr = (float *)malloc( (size_t) ((nlast-nfirst+1+EDGE)*sizeof(float)) );
-   if(!vtr) printf( "Allocation failed!\n" );
+   vtr = (float *)malloc((size_t)((nlast-nfirst+1+EDGE) * sizeof(float)));
+   if (!vtr) {
+     fprintf(stderr,"fVector: Allocation failed!\n");
+     return NULL;
+   } else
    return vtr-nfirst+EDGE;
 }
 
-double **dMatrix(long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
-   long   i, nrow=nrowlast-nrowfirst+1, ncol=ncolumnlast-ncolumnfirst+1;
+double **dMatrix(int nrowfirst, int nrowlast,
+		 int ncolumnfirst, int ncolumnlast) {
+   int   i;
+   int nrow=(nrowlast-nrowfirst)+1;
+   int ncol=(ncolumnlast-ncolumnfirst)+1;
    double **mtr;
 
-   mtr = (double **) malloc( (size_t)((nrow+EDGE)*sizeof(double*)) );
-   if(!mtr) printf( "Allocation failed!\n" );
+   mtr = (double **)malloc((size_t)((nrow+EDGE) * sizeof(double*)));
+   if (!mtr) {
+     fprintf(stderr,"dMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr += EDGE;
    mtr -= nrowfirst;
 
-   mtr[nrowfirst] = (double *) malloc( (size_t)( (nrow*ncol+EDGE)*sizeof(double)));
-   if(!mtr[nrowfirst]) printf( "Allocation failed!\n" );
+   mtr[nrowfirst] = (double *)malloc((size_t)((nrow*ncol+EDGE)*
+					      sizeof(double)));
+   if (!mtr[nrowfirst]) {
+     fprintf(stderr,"dMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr[nrowfirst] += EDGE;
    mtr[nrowfirst] -= ncolumnfirst;
 
-   for(i=nrowfirst+1;i<=nrowlast;i++) mtr[i]=mtr[i-1]+ncol;
+   for (i=nrowfirst+1; i<=nrowlast; i++)
+     mtr[i] = mtr[i-1] + ncol;
 
    return mtr;
 }
 
-float **fMatrix(long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
+float **fMatrix(long nrowfirst, long nrowlast,
+		long ncolumnfirst, long ncolumnlast) {
    long   i, nrow=nrowlast-nrowfirst+1, ncol=ncolumnlast-ncolumnfirst+1;
    float **mtr;
 
-   mtr = (float **) malloc( (size_t)((nrow+EDGE)*sizeof(float*)) );
-   if(!mtr) printf( "Allocation failed!\n" );
+   mtr = (float **)malloc((size_t)((nrow+EDGE) * sizeof(float*)) );
+   if (!mtr) {
+     fprintf(stderr,"fMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr += EDGE;
    mtr -= nrowfirst;
 
-   mtr[nrowfirst] = (float *) malloc( (size_t)( (nrow*ncol+EDGE)*sizeof(float)));
-   if(!mtr[nrowfirst]) printf( "Allocation failed!\n" );
+   mtr[nrowfirst] = (float *)malloc((size_t)((nrow*ncol+EDGE)*sizeof(float)));
+   if (!mtr[nrowfirst]) {
+     fprintf(stderr,"fMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr[nrowfirst] += EDGE;
    mtr[nrowfirst] -= ncolumnfirst;
 
-   for(i=nrowfirst+1;i<=nrowlast;i++) mtr[i]=mtr[i-1]+ncol;
+   for (i=nrowfirst+1; i<=nrowlast; i++)
+     mtr[i] = mtr[i-1] + ncol;
 
    return mtr;
 }
 
-int **iMatrix(long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
+int **iMatrix(long nrowfirst, long nrowlast,
+	      long ncolumnfirst, long ncolumnlast) {
    long   i, nrow=nrowlast-nrowfirst+1, ncol=ncolumnlast-ncolumnfirst+1;
    int **mtr;
 
-   mtr = (int **) malloc( (size_t)((nrow+EDGE)*sizeof(int*)) );
-   if(!mtr) printf( "Allocation failed!\n" );
+   mtr = (int **)malloc((size_t)((nrow+EDGE) * sizeof(int*)));
+   if (!mtr) {
+     fprintf(stderr,"iMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr += EDGE;
    mtr -= nrowfirst;
 
-   mtr[nrowfirst] = (int *) malloc( (size_t)( (nrow*ncol+EDGE)*sizeof(int)));
-   if(!mtr[nrowfirst]) printf( "Allocation failed!\n" );
+   mtr[nrowfirst] = (int *)malloc((size_t)((nrow*ncol+EDGE) * sizeof(int)));
+   if (!mtr[nrowfirst]) {
+     fprintf(stderr,"iMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr[nrowfirst] += EDGE;
    mtr[nrowfirst] -= ncolumnfirst;
 
-   for(i=nrowfirst+1;i<=nrowlast;i++) mtr[i]=mtr[i-1]+ncol;
+   for (i=nrowfirst+1; i<=nrowlast; i++)
+     mtr[i] = mtr[i-1] + ncol;
 
    return mtr;
 }
 
-char **cMatrix(long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
+char **cMatrix(long nrowfirst, long nrowlast,
+	       long ncolumnfirst, long ncolumnlast) {
    long   i, nrow=nrowlast-nrowfirst+1, ncol=ncolumnlast-ncolumnfirst+1;
    char **mtr;
 
-   mtr = (char **) malloc( (size_t)((nrow+EDGE)*sizeof(char*)) );
-   if(!mtr) printf( "Allocation failed!\n" );
+   mtr = (char **)malloc((size_t)((nrow+EDGE) * sizeof(char*)));
+   if (!mtr) {
+     fprintf(stderr,"cMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr += EDGE;
    mtr -= nrowfirst;
 
-   mtr[nrowfirst] = (char *) malloc( (size_t)( (nrow*ncol+EDGE)*sizeof(char)));
-   if(!mtr[nrowfirst]) printf( "Allocation failed!\n" );
+   mtr[nrowfirst] = (char *)malloc((size_t)((nrow*ncol+EDGE) * sizeof(char)));
+   if (!mtr[nrowfirst]) {
+     fprintf(stderr,"cMatrix: Allocation failed!\n");
+     return NULL;
+   }
    mtr[nrowfirst] += EDGE;
    mtr[nrowfirst] -= ncolumnfirst;
 
-   for(i=nrowfirst+1;i<=nrowlast;i++) mtr[i]=mtr[i-1]+ncol;
+   for (i=nrowfirst+1; i<=nrowlast; i++)
+     mtr[i] = mtr[i-1] + ncol;
 
    return mtr;
 }
@@ -118,44 +160,44 @@
 
 void free_iVector(int *vtr, long nfirst, long nlast)
 {
-	free( (RELEASE) (vtr+nfirst-EDGE) );
+  free((RELEASE)(vtr+nfirst-EDGE));
 }
 
 void free_cVector(char *vtr, long nfirst, long nlast)
 {
-	free( (RELEASE) (vtr+nfirst-EDGE) );
+  free((RELEASE)(vtr+nfirst-EDGE));
 }
 
 void free_dVector(double *vtr, long nfirst, long nlast)
 {
-	free( (RELEASE) (vtr+nfirst-EDGE) );
+  free((RELEASE)(vtr+nfirst-EDGE));
 }
 
 void free_fVector(float *vtr, long nfirst, long nlast)
 {
-	free( (RELEASE) (vtr+nfirst-EDGE) );
+  free((RELEASE)(vtr+nfirst-EDGE));
 }
 
-void free_dMatrix(double **mtr, long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
-    free( (RELEASE) (mtr[nrowfirst]+ncolumnfirst-EDGE) );
-    free( (RELEASE) (mtr+nrowfirst-EDGE) );
+void free_dMatrix(double **mtr, int nrowfirst, int nrowlast,
+		  int ncolumnfirst, int ncolumnlast) {
+  free((RELEASE)(mtr[nrowfirst]+ncolumnfirst-EDGE));
+  free((RELEASE)(mtr+nrowfirst-EDGE));
 }
 
-void free_fMatrix(float **mtr, long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
-    free( (RELEASE) (mtr[nrowfirst]+ncolumnfirst-EDGE) );
-    free( (RELEASE) (mtr+nrowfirst-EDGE) );
+void free_fMatrix(float **mtr, long nrowfirst, long nrowlast,
+		  long ncolumnfirst, long ncolumnlast) {
+  free((RELEASE)(mtr[nrowfirst]+ncolumnfirst-EDGE));
+  free((RELEASE)(mtr+nrowfirst-EDGE));
 }
 
-void free_iMatrix(int **mtr, long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
-    free( (RELEASE) (mtr[nrowfirst]+ncolumnfirst-EDGE) );
-    free( (RELEASE) (mtr+nrowfirst-EDGE) );
+void free_iMatrix(int **mtr, long nrowfirst, long nrowlast,
+		  long ncolumnfirst, long ncolumnlast) {
+  free((RELEASE)(mtr[nrowfirst]+ncolumnfirst-EDGE));
+  free((RELEASE)(mtr+nrowfirst-EDGE));
 }
 
-void free_cMatrix(char **mtr, long nrowfirst, long nrowlast, long ncolumnfirst, long ncolumnlast)
-{
-    free( (RELEASE) (mtr[nrowfirst]+ncolumnfirst-EDGE) );
-    free( (RELEASE) (mtr+nrowfirst-EDGE) );
+void free_cMatrix(char **mtr, long nrowfirst, long nrowlast,
+		  long ncolumnfirst, long ncolumnlast) {
+  free((RELEASE)(mtr[nrowfirst]+ncolumnfirst-EDGE));
+  free((RELEASE)(mtr+nrowfirst-EDGE));
 }
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/matvecalloc.h lsqrms-2.0.4b/src/matvecalloc.h
--- lsqrms-2.0.4b.old/src/matvecalloc.h
+++ lsqrms-2.0.4b/src/matvecalloc.h	Sun Feb 24 22:49:49 EST 2008
@@ -0,0 +1,30 @@
+#ifndef MATVECALLOC_H
+#define MATVECALLOC_H
+
+#define RELEASE char*
+
+#include "lsqrms.h"
+
+#if HAVE_MEMORY_H
+# include <memory.h>
+#endif
+
+char    *cVector(long, long);
+int     *iVector(long, long);
+double  *dVector(long, long);
+float   *fVector(long, long);
+char   **cMatrix(long, long, long, long);
+int    **iMatrix(long, long, long, long);
+double **dMatrix(int, int, int, int);
+float  **fMatrix(long, long, long, long);
+
+void free_cVector(char*, long, long);
+void free_dVector(double*, long, long);
+void free_iVector(int*, long, long);
+void free_fVector(float*, long, long);
+void free_cMatrix(char**, long, long, long, long);
+void free_iMatrix(int**, long, long, long, long);
+void free_dMatrix(double**, int, int, int, int);
+void free_fMatrix(float**, long, long, long, long);
+
+#endif
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/matvecutils.c lsqrms-2.0.4b/src/matvecutils.c
--- lsqrms-2.0.4b.old/src/matvecutils.c	Wed Mar 12 17:12:16 EST 2003
+++ lsqrms-2.0.4b/src/matvecutils.c	Sun Feb 24 22:49:50 EST 2008
@@ -1,408 +1,263 @@
-#include <math.h>
-#include <stdio.h>
-
-
-#include "umath.h"
-
-
-
-typedef double rotate_t[3][3];
-
-typedef double xlate_t[3];
-
-typedef struct Coord { double x, y, z; } CoordType;
-
-
-
-int     *iVector(long, long);
-
-int    **iMatrix(long, long, long, long);
-
-double  *dVector(long, long);
-
-char    *cVector(long, long);
-
-double **dMatrix(long, long, long, long);
-
-void free_iVector(int     *, long, long);
-
-void free_iMatrix(int    **, long, long, long, long);
-
-void free_dVector(double  *, long, long);
-
-void free_dMatrix(double **, long, long, long, long);
-
-void free_cVector(char    *, long, long);
-
-
-
-/*=====================================================================*/
-
-static int solve(double e[3],
-
-                   double e0, double det, double spur, double cof)
-
-{
-
-double d, h, g, cth, sth, sqrth;
-
-#define epsilon 1e-7
-
-#define sqrt3 1.7320508075688772
-
-  
-
-  det *= det;
-
-  d = SQR(spur);
-
-  h = d - cof;
-
-  g = spur * (cof*1.5 - d) - det*0.5;
-
-  if (h > d*epsilon) {
-
-    sqrth = SQRTABS(h);
-
-    d = -g/(h*sqrth);
-
-    if (d > 1-epsilon) {    /* Two identical roots */
-
-      e[0] = spur + 2*sqrth;
-
-      e[2] = e[1] = spur - sqrth;
-
-      return 2;
-
-      }
-
-    else if (d < -1+epsilon) {    /* Two identical roots */ 
-
-      e[1] = e[0] = spur+sqrth;
-
-      e[2] = MAX(0, spur - 2*sqrth);
-
-      return 3;
-
-      }
-
-    else {    /* Three distinct roots */
-
-      d = acos(d)/3.0;
-
-      cth = sqrth*cos(d); sth = sqrth*sqrt3*sin(d);
-
-      e[0] = spur + 2*cth;
-
-      e[1] = spur - cth + sth;
-
-      e[2] = MAX(0, spur - cth - sth);
-
-      return 1;
-
-      }
-
-    }
-
-  else {    /* Three identical roots */ 
-
-    e[0] = e[1] = e[2] = spur;
-
-    return 4;
-
-    }
-
-
-
- } /* solve */
-
-
-
-
-
-static int matrix(rotate_t u, xlate_t t,
-
-                   int sw, double e[3], double rr[6], double r[3][3],
-
-                   double sx[3], double sy[3], int npts)
-
-{
-
-  double ss[6], d, h, p, a[3][3], b[3][3];
-
-  int i, j, l, m, m1, m2, m3;
-
-
-
-  if (sw == 4) {
-
-    /* Case of three identical roots */
-
-    for (i = 0; i < 3; i++)
-
-      for (j = 0; j < 3; j++)
-
-        if (i == j) a[i][j] = 1.0; else a[i][j] = 0.0;
-
-    }
-
-  else {
-
-    if (sw == 1) {
-
-      /* Case of three distinct roots */
-
-      for (l=0; l < 2; l++) {
-
-        d = e[l];
-
-        ss[0] = (d-rr[2]) * (d-rr[5]) - SQR(rr[4]);
-
-        ss[1] = (d-rr[5]) * rr[1] + rr[3]*rr[4];
-
-        ss[2] = (d-rr[0]) * (d-rr[5]) - SQR(rr[3]);
-
-        ss[3] = (d-rr[2]) * rr[3] + rr[1]*rr[4];
-
-        ss[4] = (d-rr[0]) * rr[4] + rr[1]*rr[3];
-
-        ss[5] = (d-rr[0]) * (d-rr[2]) - SQR(rr[1]);
-
-        if (FABS(ss[0]) >= FABS(ss[2])) {
-
-          if (FABS(ss[0]) >= FABS(ss[5])) {
-
-            a[0][l] = ss[0]; a[1][l] = ss[1]; a[2][l] = ss[3];
-
-            }
-
-          else {
-
-            a[0][l] = ss[3]; a[1][l] = ss[4]; a[2][l] = ss[5];
-
-            }
-
-          }
-
-        else if (FABS(ss[2]) >= FABS(ss[5])) {
-
-          a[0][l] = ss[1]; a[1][l] = ss[2]; a[2][l] = ss[4];
-
-          }
-
-        else {
-
-          a[0][l] = ss[3]; a[1][l] = ss[4]; a[2][l] = ss[5];
-
-          }
-
-        d = sqrt(SQR(a[0][l]) + SQR(a[1][l]) + SQR(a[2][l]));
-
-        a[0][l] /= d; a[1][l] /= d; a[2][l] /= d;
-
-        }
-
-      m1 = 2; m2 = 0; m3 = 1;
-
-      }
-
-    else {
-
-      /* Cases of two distinct roots */
-
-      if (sw == 2) {
-
-        m = 0; m1 = 2; m2 = 0; m3 = 1;
-
-        }
-
-      else {
-
-        m = 2; m1 = 0; m2 = 1; m3 = 2;
-
-        }
-
-      h = e[2];
-
-      a[0][1] = 1.0; a[1][1] = 1.0; a[2][1] = 1.0;
-
-      if (FABS(rr[0]-h) > FABS(rr[2]-h)) {
-
-        if (FABS(rr[0]-h) > FABS(rr[5]-h)) {
-
-          a[0][m] = rr[0]-h; a[1][m] = rr[1]; a[2][m] = rr[3];
-
-          p = -(rr[0] + rr[1] + rr[3] - h);
-
-          a[0][1] = p/a[0][m];
-
-          }
-
-        else {
-
-          a[0][m] = rr[3]; a[1][m] = rr[4]; a[2][m] = rr[5]-h;
-
-          p = -(rr[3] + rr[4] + rr[5] - h);
-
-          a[2][1] = p/a[2][m];
+#include "lsqrms.h"
+#include "umath.h"
+#include "matvecalloc.h"
+#include "matvecutils.h"
 
-          }
+static int solve(LDBL [], LDBL, LDBL, LDBL, LDBL);
+static double TRvec(double *, double **, double *);
+static LDBL vsumby3(double [], int);
+static LDBL vsumsqr(double [], int);
+static LDBL vdotby3(double [], double [], int);
 
-        }
 
-      else {
+/*=====================================================================*/
 
-        if (FABS(rr[2]-h) > FABS(rr[5]-h)) {
+static int solve(LDBL e[3],LDBL e0, LDBL det, LDBL spur, LDBL cof) {
+  LDBL d, h, g, cth, sth, sqrth;
 
-          a[0][m] = rr[1]; a[1][m] = rr[2]-h; a[2][m] = rr[4];
+#define sqrt3 1.732050807568877293527446341506
 
-          p = -(rr[1] + rr[2] + rr[4] - h);
+  d = DSQR(spur);
 
-          a[1][1] = p/a[1][m];
+  h = d - cof;
 
-          }
+  if (h > d*epsilon) {
+    det *= det;
+    g = spur * (cof*1.5 - d) - det*0.5;
 
-        else {
+    sqrth = DSQRTABS(h);
 
-          a[0][m] = rr[3]; a[1][m] = rr[4]; a[2][m] = rr[5]-h;
+    d = -g/(h*sqrth);
 
-          p = -(rr[3] + rr[4] + rr[5] - h);
+    if (d > 1-epsilon) {    /* Two identical roots */
+      e[0] = spur + 2*sqrth;
+      e[2] = e[1] = spur - sqrth;
 
-          a[2][1] = p/a[2][m];
+      return 2;
+    } else if (d < -1+epsilon) {    /* Two identical roots */ 
+      e[1] = e[0] = spur+sqrth;
+      e[2] = MAX(0, spur - 2*sqrth);
 
-          }
+      return 3;
+    } else {    /* Three distinct roots */
+      d = DACOS(d)/3.0;
 
-        }
+      cth = sqrth*DCOS(d);
+      sth = sqrth*sqrt3*DSIN(d);
 
-      d = sqrt(SQR(a[0][m]) + SQR(a[1][m]) + SQR(a[2][m]));
+      e[0] = spur + 2*cth;
+      e[1] = spur - cth + sth;
+      e[2] = MAX(0, spur - cth - sth);
 
-      p = sqrt(SQR(a[0][1]) + SQR(a[1][1]) + SQR(a[2][1]));
+      return 1;
+    }
 
-      for (i = 0; i < 3; i++) {
+  } else {    /* Three identical roots */ 
+    e[0] = e[1] = e[2] = spur;
 
-        a[i][1] /= p;
+    return 4;
+  }
+} /* solve */
 
-        a[i][m] /= d;
+static void matrix(rotate_t u, xlate_t t, int sw, LDBL e[3],
+		   LDBL rr[6], LDBL r[3][3],
+		   LDBL sx[3], LDBL sy[3], int npts) {
+  LDBL ss[6], d, h, p, a[3][3], b[3][3];
+  int i, j, l, m, m1, m2, m3;
 
-        }
+  if (sw == 4) {
+    /* Case of three identical roots */
+    for (i = 0; i < 3; i++) {
+      for (j = 0; j < 3; j++) {
+        if (i == j)
+	  a[i][j] = 1.0;
+	else
+	  a[i][j] = 0.0;
+      }
+    }
+  } else {
+    if (sw == 1) {
+      /* Case of three distinct roots */
+      for (l=0; l < 2; l++) {
+        d = e[l];
 
-      }
+        ss[0] = (d-rr[2]) * (d-rr[5]) - DSQR(rr[4]);
+        ss[1] = (d-rr[5]) * rr[1] + rr[3]*rr[4];
+        ss[2] = (d-rr[0]) * (d-rr[5]) - DSQR(rr[3]);
+        ss[3] = (d-rr[2]) * rr[3] + rr[1]*rr[4];
+        ss[4] = (d-rr[0]) * rr[4] + rr[1]*rr[3];
+        ss[5] = (d-rr[0]) * (d-rr[2]) - DSQR(rr[1]);
 
-    /* Common for either two or three distinct roots */
+        if (FABS(ss[0]) >= FABS(ss[2])) {
+          if (FABS(ss[0]) >= FABS(ss[5])) {
+            a[0][l] = ss[0];
+	    a[1][l] = ss[1];
+	    a[2][l] = ss[3];
+	  } else {
+            a[0][l] = ss[3];
+	    a[1][l] = ss[4];
+	    a[2][l] = ss[5];
+	  }
+	} else if (FABS(ss[2]) >= FABS(ss[5])) {
+          a[0][l] = ss[1];
+	  a[1][l] = ss[2];
+	  a[2][l] = ss[4];
+	} else {
+          a[0][l] = ss[3];
+	  a[1][l] = ss[4];
+	  a[2][l] = ss[5];
+	}
 
-    a[0][m1] = a[1][m2]*a[2][m3] - a[1][m3]*a[2][m2];
+        d = DSQRT(DSQR(a[0][l]) + DSQR(a[1][l]) + DSQR(a[2][l]));
 
-    a[1][m1] = a[2][m2]*a[0][m3] - a[2][m3]*a[0][m2];
+        a[0][l] /= d;
+	a[1][l] /= d;
+	a[2][l] /= d;
+      }
 
-    a[2][m1] = a[0][m2]*a[1][m3] - a[0][m3]*a[1][m2];
+      m1 = 2; m2 = 0; m3 = 1;
+    } else {
+      /* Cases of two distinct roots */
+      if (sw == 2) {
+        m = 0;
+	m1 = 2;
+	m2 = 0;
+	m3 = 1;
+      } else {
+        m = 2;
+	m1 = 0;
+	m2 = 1;
+	m3 = 2;
+      }
 
-    }
+      h = e[2];
 
-  
+      a[0][1] = 1.0;
+      a[1][1] = 1.0;
+      a[2][1] = 1.0;
 
-  for (l = 0; l < 2; l++) {
+      if (FABS(rr[0]-h) > FABS(rr[2]-h)) {
+        if (FABS(rr[0]-h) > FABS(rr[5]-h)) {
+          a[0][m] = rr[0]-h;
+	  a[1][m] = rr[1];
+	  a[2][m] = rr[3];
 
-    d = 0;
+          p = -(rr[0] + rr[1] + rr[3] - h);
 
-    for (i = 0; i < 3; i++) {
+          a[0][1] = p/a[0][m];
+	} else {
+          a[0][m] = rr[3];
+	  a[1][m] = rr[4];
+	  a[2][m] = rr[5]-h;
 
-      b[i][l] = r[0][i]*a[0][l] + r[1][i]*a[1][l] + r[2][i]*a[2][l];
+          p = -(rr[3] + rr[4] + rr[5] - h);
 
-      d += SQR(b[i][l]);
+          a[2][1] = p/a[2][m];
+	}
+      } else {
+        if (FABS(rr[2]-h) > FABS(rr[5]-h)) {
+          a[0][m] = rr[1];
+	  a[1][m] = rr[2]-h;
+	  a[2][m] = rr[4];
 
-      }
+          p = -(rr[1] + rr[2] + rr[4] - h);
 
-    d = sqrt(d);
+          a[1][1] = p/a[1][m];
+	} else {
+          a[0][m] = rr[3];
+	  a[1][m] = rr[4];
+	  a[2][m] = rr[5]-h;
 
-    if (d == 0) printf("degenerate rotation matrix in matrix()\n"); 
+          p = -(rr[3] + rr[4] + rr[5] - h);
 
-    for (i = 0; i < 3; i++) b[i][l] /= d;
+          a[2][1] = p/a[2][m];
+	}
+      }
 
-    }
+      d = sqrt(DSQR(a[0][m]) + DSQR(a[1][m]) + DSQR(a[2][m]));
+      p = sqrt(DSQR(a[0][1]) + DSQR(a[1][1]) + DSQR(a[2][1]));
 
-  b[0][2] = b[1][0]*b[2][1] - b[1][1]*b[2][0];
+      for (i = 0; i < 3; i++) {
+        a[i][1] /= p;
+        a[i][m] /= d;
+      }
+    }
 
-  b[1][2] = b[2][0]*b[0][1] - b[2][1]*b[0][0];
+    /* Common for either two or three distinct roots */
 
-  b[2][2] = b[0][0]*b[1][1] - b[0][1]*b[1][0];
+    a[0][m1] = a[1][m2]*a[2][m3] - a[1][m3]*a[2][m2];
+    a[1][m1] = a[2][m2]*a[0][m3] - a[2][m3]*a[0][m2];
+    a[2][m1] = a[0][m2]*a[1][m3] - a[0][m3]*a[1][m2];
+  }
 
-  
+  for (l = 0; l < 2; l++) {
+    d = 0.0;
 
-  /* Calculate rotation matrix */
+    for (i = 0; i < 3; i++) {
+      b[i][l] = r[0][i]*a[0][l] + r[1][i]*a[1][l] + r[2][i]*a[2][l];
 
-  for (i = 0; i < 3; i++)
+      d += SQR(b[i][l]);
+    }
 
-    for (j = 0; j < 3; j++)
+    d = DSQRT(d);
 
-      u[i][j] = b[i][0]*a[j][0] + b[i][1]*a[j][1] + b[i][2]*a[j][2];
+    if (d == 0.0) {
+      fprintf(stderr,"matrix: degenerate rotation matrix!\n");
+      exit(1);
+    } else {
+      for (i = 0; i < 3; i++)
+	b[i][l] /= d;
+    }
+  }
 
-  /* Calculate translation vector */
+  b[0][2] = b[1][0]*b[2][1] - b[1][1]*b[2][0];
+  b[1][2] = b[2][0]*b[0][1] - b[2][1]*b[0][0];
+  b[2][2] = b[0][0]*b[1][1] - b[0][1]*b[1][0];
 
-  for (i = 0; i < 3; i++)
+  /* Calculate rotation matrix */
 
-    t[i] = (sy[i] - u[i][0]*sx[0] - u[i][1]*sx[1] - u[i][2]*sx[2])/npts;
+  for (i = 0; i < 3; i++) {
+    for (j = 0; j < 3; j++)
+      u[i][j] = (double)(b[i][0]*a[j][0] + b[i][1]*a[j][1] + b[i][2]*a[j][2]);
+  }
 
-
+  /* Calculate translation vector */
 
-  return 7;
+  for (i = 0; i < 3; i++)
+    t[i] =
+      (double)((sy[i] - u[i][0]*sx[0] - u[i][1]*sx[1] - u[i][2]*sx[2])/npts);
 
-}
+  /* return 7; */
+}
 
 
-double bestfit(rotate_t u, xlate_t t, CoordType *a, CoordType *b, const int npts)
-{
-  double sx[3], sy[3], sxy[3][3], sx2, sy2, temp; 
-  double r[3][3], rr[6];
-  double d, spur, det, cof, e0, e[3], inpts;
+double bestfit(rotate_t u, xlate_t t, CoordType *a, CoordType *b,
+	       const int npts) {
+  LDBL sx[3], sy[3], sxy[3][3], sx2, sy2;
+  LDBL r[3][3], rr[6];
+  LDBL d, spur, det, cof, e0, e[3], inpts;
   int i, j, m, sw;
-
-
-  double vsumby3(double [], int);
-
-  double vsumsqr(double [], int);
-
-  double vdotby3(double [], double [], int n);
-
-
-
-  temp = vsumby3(&a[0].x, npts);
-
-  temp = vsumby3(&a[0].y, npts);
-
-  temp = vsumby3(&a[0].z, npts);
-
-  temp = vsumby3(&b[0].x, npts);
-
-  temp = vsumby3(&b[0].y, npts);
-
-  temp = vsumby3(&b[0].z, npts);
-
-
-
-  temp = vsumsqr(&a[0].x, 3*npts);
-
-  temp = vsumsqr(&b[0].x, 3*npts);
-
-
-
-  temp = vdotby3(&a[0].x, &b[0].x, npts);
-
-  temp = vdotby3(&a[0].x, &b[0].y, npts);
-
-  temp = vdotby3(&a[0].x, &b[0].z, npts);
 
-  temp = vdotby3(&a[0].y, &b[0].x, npts);
-
-  temp = vdotby3(&a[0].y, &b[0].y, npts);
-
-  temp = vdotby3(&a[0].y, &b[0].z, npts);
-
-  temp = vdotby3(&a[0].z, &b[0].x, npts);
+  (void)vsumby3(&a[0].x, npts);
+  (void)vsumby3(&a[0].y, npts);
+  (void)vsumby3(&a[0].z, npts);
 
-  temp = vdotby3(&a[0].z, &b[0].y, npts);
+  (void)vsumby3(&b[0].x, npts);
+  (void)vsumby3(&b[0].y, npts);
+  (void)vsumby3(&b[0].z, npts);
 
-  temp = vdotby3(&a[0].z, &b[0].z, npts);
+  (void)vsumsqr(&a[0].x, 3*npts);
+  (void)vsumsqr(&b[0].x, 3*npts);
 
+  (void)vdotby3(&a[0].x, &b[0].x, npts);
+  (void)vdotby3(&a[0].x, &b[0].y, npts);
+  (void)vdotby3(&a[0].x, &b[0].z, npts);
+  (void)vdotby3(&a[0].y, &b[0].x, npts);
+  (void)vdotby3(&a[0].y, &b[0].y, npts);
+  (void)vdotby3(&a[0].y, &b[0].z, npts);
+  (void)vdotby3(&a[0].z, &b[0].x, npts);
+  (void)vdotby3(&a[0].z, &b[0].y, npts);
+  (void)vdotby3(&a[0].z, &b[0].z, npts);
 
   sx[0] = vsumby3(&a[0].x, npts);
   sx[1] = vsumby3(&a[0].y, npts);
@@ -423,8 +278,8 @@
   sxy[2][2] = vdotby3(&a[0].z, &b[0].z, npts);
 
   inpts = 1.0/npts;
-  e0 = (sx2 - (SQR(sx[0])+SQR(sx[1])+SQR(sx[2]))*inpts +
-        sy2 - (SQR(sy[0])+SQR(sy[1])+SQR(sy[2]))*inpts)*inpts;
+  e0 = (sx2 - (DSQR(sx[0])+DSQR(sx[1])+DSQR(sx[2]))*inpts +
+        sy2 - (DSQR(sy[0])+DSQR(sy[1])+DSQR(sy[2]))*inpts)*inpts;
 
   for (i = 0; i < 3; i++) {
     for (j = 0; j < 3; j++) {
@@ -443,1019 +298,2041 @@
       + r[2][0] * (r[0][1]*r[1][2] - r[1][1]*r[0][2]);
 
   spur = (rr[0]+rr[2]+rr[5])/3.0;
-  cof = (rr[2]*rr[5] - SQR(rr[4]) + rr[0]*rr[5] -
-         SQR(rr[3]) + rr[0]*rr[2] - SQR(rr[1]))/3.0;
+  cof = (rr[2]*rr[5] - DSQR(rr[4]) + rr[0]*rr[5] -
+         DSQR(rr[3]) + rr[0]*rr[2] - DSQR(rr[1]))/3.0;
 
   sw = solve(e, e0, det, spur, cof);
-  i = matrix(u, t, sw, e, rr, r, sx, sy, npts);
-  d = SQRTABS(e[2]);
+  matrix(u, t, sw, e, rr, r, sx, sy, npts);
+  d = DSQRTABS(e[2]);
   if (det < 0) d = -d;
-  d += SQRTABS(e[1]) + SQRTABS(e[0]);
+  d += DSQRTABS(e[1]) + DSQRTABS(e[0]);
   d = e0-2*d;
-  return SQRTABS(d);
-
-  } /* bestfit */
-
-double rotrans(double **x_str, int size_str, rotate_t u, xlate_t t) {
-
-  int i;
-
-  double xx, yy, zz;
-
-  for(i=0; i<size_str; i++) {
-
-    xx = x_str[1][i]; yy = x_str[2][i]; zz = x_str[3][i]; 
-
-    x_str[1][i] = u[0][0]*xx + u[0][1]*yy + u[0][2]*zz;
-
-    x_str[2][i] = u[1][0]*xx + u[1][1]*yy + u[1][2]*zz;
-
-    x_str[3][i] = u[2][0]*xx + u[2][1]*yy + u[2][2]*zz;
-
-    x_str[1][i] +=  t[0];
-
-    x_str[2][i] +=  t[1];
-
-    x_str[3][i] +=  t[2];
-
-  } /* i */
-
-  return 7;
-
-} /* rotrans */
-
-
-
-int check_eq(int *iina, int *jinb, int *iina_sav, int *jinb_sav, int nentry) {
-
-  int i, ret_sum;
-
-  ret_sum = 0;
-
-  for(i=0; i<=nentry; i++) {
-
-	if( (iina[i] != iina_sav[i]) || (jinb[i] != jinb_sav[i]) ) ret_sum++;
-
-    if(ret_sum) return ret_sum;
-
-  }
-
-  return ret_sum;
-
-} /* check_eq */
-
-
-
-double distrms(CoordType *a, CoordType *b, int npts)
-
-  {
-
-  int i, j;
-
-  double ad, bd, sum;
-
-
-
-  sum = 0.0;
-
-  for (i = 0; i < npts; i++) {
-
-    for (j = 0; j < i; j++) {
-
-      ad = sqrt(SQR(a[i].x-a[j].x) + SQR(a[i].y-a[j].y) +
-
-                 SQR(a[i].z-a[j].z));
-
-      bd = sqrt(SQR(b[i].x-b[j].x) + SQR(b[i].y-b[j].y) +
-
-                 SQR(b[i].z-b[j].z));
-
-      sum += SQR(ad-bd);
-
-      }
-
-    }
-
-  return sqrt(2*sum/(npts*(npts-1)));
-
-} /* distrms */
-
-
-
-char convert321(char *s) {
-
- if(s[0] == 'G' && s[1] == 'L' && s[2] == 'Y') return 'G';   
-
- if(s[0] == 'A' && s[1] == 'L' && s[2] == 'A') return 'A';    
-
- if(s[0] == 'V' && s[1] == 'A' && s[2] == 'L') return 'V';   
-
- if(s[0] == 'L' && s[1] == 'E' && s[2] == 'U') return 'L';    
-
- if(s[0] == 'I' && s[1] == 'L' && s[2] == 'E') return 'I';   
-
- if(s[0] == 'S' && s[1] == 'E' && s[2] == 'R') return 'S';    
-
- if(s[0] == 'T' && s[1] == 'H' && s[2] == 'R') return 'T';   
-
- if(s[0] == 'C' && s[1] == 'Y' && s[2] == 'S') return 'C';    
-
- if(s[0] == 'M' && s[1] == 'E' && s[2] == 'T') return 'M';   
-
- if(s[0] == 'P' && s[1] == 'R' && s[2] == 'O') return 'P';    
-
- if(s[0] == 'A' && s[1] == 'S' && s[2] == 'P') return 'D';   
-
- if(s[0] == 'A' && s[1] == 'S' && s[2] == 'N') return 'N';    
-
- if(s[0] == 'G' && s[1] == 'L' && s[2] == 'U') return 'E';   
-
- if(s[0] == 'G' && s[1] == 'L' && s[2] == 'N') return 'Q';    
-
- if(s[0] == 'L' && s[1] == 'Y' && s[2] == 'S') return 'K';   
-
- if(s[0] == 'A' && s[1] == 'R' && s[2] == 'G') return 'R';    
-
- if(s[0] == 'H' && s[1] == 'I' && s[2] == 'S') return 'H';   
-
- if(s[0] == 'P' && s[1] == 'H' && s[2] == 'E') return 'F';    
-
- if(s[0] == 'T' && s[1] == 'Y' && s[2] == 'R') return 'Y';   
-
- if(s[0] == 'T' && s[1] == 'R' && s[2] == 'P') return 'W';	 
-
- printf("321 convertion did not succeed! \n");
-
- return 'X';
-
-} /* convert321 */
-
-
-
-double blossom62(char a, char b) {
-
-if( a == 'A' && b == 'A' ) return    8 ;
-
-if( a == 'B' && b == 'A' ) return   -4 ;
-
-if( a == 'B' && b == 'B' ) return    8 ;
-
-if( a == 'C' && b == 'A' ) return    0 ;
-
-if( a == 'C' && b == 'B' ) return   -6 ;
-
-if( a == 'C' && b == 'C' ) return   18 ;
-
-if( a == 'D' && b == 'A' ) return   -4 ;
-
-if( a == 'D' && b == 'B' ) return    8 ;
-
-if( a == 'D' && b == 'C' ) return   -6 ;
-
-if( a == 'D' && b == 'D' ) return   12 ;
-
-if( a == 'E' && b == 'A' ) return   -2 ;
-
-if( a == 'E' && b == 'B' ) return    2 ;
-
-if( a == 'E' && b == 'C' ) return   -8 ;
-
-if( a == 'E' && b == 'D' ) return    4 ;
-
-if( a == 'E' && b == 'E' ) return   10 ;
-
-if( a == 'F' && b == 'A' ) return   -4 ;
-
-if( a == 'F' && b == 'B' ) return   -6 ;
-
-if( a == 'F' && b == 'C' ) return   -4 ;
-
-if( a == 'F' && b == 'D' ) return   -6 ;
-
-if( a == 'F' && b == 'E' ) return   -6 ;
-
-if( a == 'F' && b == 'F' ) return   12 ;
-
-if( a == 'G' && b == 'A' ) return    0 ;
-
-if( a == 'G' && b == 'B' ) return   -2 ;
-
-if( a == 'G' && b == 'C' ) return   -6 ;
-
-if( a == 'G' && b == 'D' ) return   -2 ;
-
-if( a == 'G' && b == 'E' ) return   -4 ;
-
-if( a == 'G' && b == 'F' ) return   -6 ;
-
-if( a == 'G' && b == 'G' ) return   12 ;
-
-if( a == 'H' && b == 'A' ) return   -4 ;
-
-if( a == 'H' && b == 'B' ) return    0 ;
-
-if( a == 'H' && b == 'C' ) return   -6 ;
-
-if( a == 'H' && b == 'D' ) return   -2 ;
-
-if( a == 'H' && b == 'E' ) return    0 ;
-
-if( a == 'H' && b == 'F' ) return   -2 ;
-
-if( a == 'H' && b == 'G' ) return   -4 ;
-
-if( a == 'H' && b == 'H' ) return   16 ;
-
-if( a == 'I' && b == 'A' ) return   -2 ;
-
-if( a == 'I' && b == 'B' ) return   -6 ;
-
-if( a == 'I' && b == 'C' ) return   -2 ;
-
-if( a == 'I' && b == 'D' ) return   -6 ;
-
-if( a == 'I' && b == 'E' ) return   -6 ;
-
-if( a == 'I' && b == 'F' ) return    0 ;
-
-if( a == 'I' && b == 'G' ) return   -8 ;
-
-if( a == 'I' && b == 'H' ) return   -6 ;
-
-if( a == 'I' && b == 'I' ) return    8 ;
-
-if( a == 'K' && b == 'A' ) return   -2 ;
-
-if( a == 'K' && b == 'B' ) return    0 ;
-
-if( a == 'K' && b == 'C' ) return   -6 ;
-
-if( a == 'K' && b == 'D' ) return   -2 ;
-
-if( a == 'K' && b == 'E' ) return    2 ;
-
-if( a == 'K' && b == 'F' ) return   -6 ;
-
-if( a == 'K' && b == 'G' ) return   -4 ;
-
-if( a == 'K' && b == 'H' ) return   -2 ;
-
-if( a == 'K' && b == 'I' ) return   -6 ;
-
-if( a == 'K' && b == 'K' ) return   10 ;
-
-if( a == 'L' && b == 'A' ) return   -2 ;
-
-if( a == 'L' && b == 'B' ) return   -8 ;
-
-if( a == 'L' && b == 'C' ) return   -2 ;
-
-if( a == 'L' && b == 'D' ) return   -8 ;
-
-if( a == 'L' && b == 'E' ) return   -6 ;
-
-if( a == 'L' && b == 'F' ) return    0 ;
-
-if( a == 'L' && b == 'G' ) return   -8 ;
-
-if( a == 'L' && b == 'H' ) return   -6 ;
-
-if( a == 'L' && b == 'I' ) return    4 ;
-
-if( a == 'L' && b == 'K' ) return   -4 ;
-
-if( a == 'L' && b == 'L' ) return    8 ;
-
-if( a == 'M' && b == 'A' ) return   -2 ;
-
-if( a == 'M' && b == 'B' ) return   -6 ;
-
-if( a == 'M' && b == 'C' ) return   -2 ;
-
-if( a == 'M' && b == 'D' ) return   -6 ;
-
-if( a == 'M' && b == 'E' ) return   -4 ;
-
-if( a == 'M' && b == 'F' ) return    0 ;
-
-if( a == 'M' && b == 'G' ) return   -6 ;
-
-if( a == 'M' && b == 'H' ) return   -4 ;
-
-if( a == 'M' && b == 'I' ) return    2 ;
-
-if( a == 'M' && b == 'K' ) return   -2 ;
-
-if( a == 'M' && b == 'L' ) return    4 ;
-
-if( a == 'M' && b == 'M' ) return   10 ;
-
-if( a == 'N' && b == 'A' ) return   -4 ;
-
-if( a == 'N' && b == 'B' ) return    6 ;
-
-if( a == 'N' && b == 'C' ) return   -6 ;
-
-if( a == 'N' && b == 'D' ) return    2 ;
-
-if( a == 'N' && b == 'E' ) return    0 ;
-
-if( a == 'N' && b == 'F' ) return   -6 ;
-
-if( a == 'N' && b == 'G' ) return    0 ;
-
-if( a == 'N' && b == 'H' ) return    2 ;
-
-if( a == 'N' && b == 'I' ) return   -6 ;
-
-if( a == 'N' && b == 'K' ) return    0 ;
-
-if( a == 'N' && b == 'L' ) return   -6 ;
-
-if( a == 'N' && b == 'M' ) return   -4 ;
-
-if( a == 'N' && b == 'N' ) return   12 ;
-
-if( a == 'P' && b == 'A' ) return   -2 ;
-
-if( a == 'P' && b == 'B' ) return   -4 ;
-
-if( a == 'P' && b == 'C' ) return   -6 ;
-
-if( a == 'P' && b == 'D' ) return   -2 ;
-
-if( a == 'P' && b == 'E' ) return   -2 ;
-
-if( a == 'P' && b == 'F' ) return   -8 ;
-
-if( a == 'P' && b == 'G' ) return   -4 ;
-
-if( a == 'P' && b == 'H' ) return   -4 ;
-
-if( a == 'P' && b == 'I' ) return   -6 ;
-
-if( a == 'P' && b == 'K' ) return   -2 ;
-
-if( a == 'P' && b == 'L' ) return   -6 ;
-
-if( a == 'P' && b == 'M' ) return   -4 ;
-
-if( a == 'P' && b == 'N' ) return   -4 ;
-
-if( a == 'P' && b == 'P' ) return   14 ;
-
-if( a == 'Q' && b == 'A' ) return   -2 ;
-
-if( a == 'Q' && b == 'B' ) return    0 ;
-
-if( a == 'Q' && b == 'C' ) return   -6 ;
-
-if( a == 'Q' && b == 'D' ) return    0 ;
-
-if( a == 'Q' && b == 'E' ) return    4 ;
-
-if( a == 'Q' && b == 'F' ) return   -6 ;
-
-if( a == 'Q' && b == 'G' ) return   -4 ;
-
-if( a == 'Q' && b == 'H' ) return    0 ;
-
-if( a == 'Q' && b == 'I' ) return   -6 ;
-
-if( a == 'Q' && b == 'K' ) return    2 ;
-
-if( a == 'Q' && b == 'L' ) return   -4 ;
-
-if( a == 'Q' && b == 'M' ) return    0 ;
-
-if( a == 'Q' && b == 'N' ) return    0 ;
-
-if( a == 'Q' && b == 'P' ) return   -2 ;
-
-if( a == 'Q' && b == 'Q' ) return   10 ;
-
-if( a == 'R' && b == 'A' ) return   -2 ;
-
-if( a == 'R' && b == 'B' ) return   -2 ;
-
-if( a == 'R' && b == 'C' ) return   -6 ;
-
-if( a == 'R' && b == 'D' ) return   -4 ;
-
-if( a == 'R' && b == 'E' ) return    0 ;
-
-if( a == 'R' && b == 'F' ) return   -6 ;
-
-if( a == 'R' && b == 'G' ) return   -4 ;
-
-if( a == 'R' && b == 'H' ) return    0 ;
-
-if( a == 'R' && b == 'I' ) return   -6 ;
-
-if( a == 'R' && b == 'K' ) return    4 ;
-
-if( a == 'R' && b == 'L' ) return   -4 ;
-
-if( a == 'R' && b == 'M' ) return   -2 ;
-
-if( a == 'R' && b == 'N' ) return    0 ;
-
-if( a == 'R' && b == 'P' ) return   -4 ;
-
-if( a == 'R' && b == 'Q' ) return    2 ;
-
-if( a == 'R' && b == 'R' ) return   10 ;
-
-if( a == 'S' && b == 'A' ) return    2 ;
-
-if( a == 'S' && b == 'B' ) return    0 ;
-
-if( a == 'S' && b == 'C' ) return   -2 ;
-
-if( a == 'S' && b == 'D' ) return    0 ;
-
-if( a == 'S' && b == 'E' ) return    0 ;
-
-if( a == 'S' && b == 'F' ) return   -4 ;
-
-if( a == 'S' && b == 'G' ) return    0 ;
-
-if( a == 'S' && b == 'H' ) return   -2 ;
-
-if( a == 'S' && b == 'I' ) return   -4 ;
-
-if( a == 'S' && b == 'K' ) return    0 ;
-
-if( a == 'S' && b == 'L' ) return   -4 ;
-
-if( a == 'S' && b == 'M' ) return   -2 ;
-
-if( a == 'S' && b == 'N' ) return    2 ;
-
-if( a == 'S' && b == 'P' ) return   -2 ;
-
-if( a == 'S' && b == 'Q' ) return    0 ;
-
-if( a == 'S' && b == 'R' ) return   -2 ;
-
-if( a == 'S' && b == 'S' ) return    8 ;
-
-if( a == 'T' && b == 'A' ) return    0 ;
-
-if( a == 'T' && b == 'B' ) return   -2 ;
-
-if( a == 'T' && b == 'C' ) return   -2 ;
-
-if( a == 'T' && b == 'D' ) return   -2 ;
-
-if( a == 'T' && b == 'E' ) return   -2 ;
-
-if( a == 'T' && b == 'F' ) return   -4 ;
-
-if( a == 'T' && b == 'G' ) return   -4 ;
-
-if( a == 'T' && b == 'H' ) return   -4 ;
-
-if( a == 'T' && b == 'I' ) return   -2 ;
-
-if( a == 'T' && b == 'K' ) return   -2 ;
-
-if( a == 'T' && b == 'L' ) return   -2 ;
-
-if( a == 'T' && b == 'M' ) return   -2 ;
-
-if( a == 'T' && b == 'N' ) return    0 ;
-
-if( a == 'T' && b == 'P' ) return   -2 ;
-
-if( a == 'T' && b == 'Q' ) return   -2 ;
-
-if( a == 'T' && b == 'R' ) return   -2 ;
-
-if( a == 'T' && b == 'S' ) return    2 ;
-
-if( a == 'T' && b == 'T' ) return   10 ;
-
-if( a == 'V' && b == 'A' ) return    0 ;
-
-if( a == 'V' && b == 'B' ) return   -6 ;
-
-if( a == 'V' && b == 'C' ) return   -2 ;
-
-if( a == 'V' && b == 'D' ) return   -6 ;
-
-if( a == 'V' && b == 'E' ) return   -4 ;
-
-if( a == 'V' && b == 'F' ) return   -2 ;
-
-if( a == 'V' && b == 'G' ) return   -6 ;
-
-if( a == 'V' && b == 'H' ) return   -6 ;
-
-if( a == 'V' && b == 'I' ) return    6 ;
-
-if( a == 'V' && b == 'K' ) return   -4 ;
-
-if( a == 'V' && b == 'L' ) return    2 ;
-
-if( a == 'V' && b == 'M' ) return    2 ;
-
-if( a == 'V' && b == 'N' ) return   -6 ;
-
-if( a == 'V' && b == 'P' ) return   -4 ;
-
-if( a == 'V' && b == 'Q' ) return   -4 ;
-
-if( a == 'V' && b == 'R' ) return   -6 ;
-
-if( a == 'V' && b == 'S' ) return   -4 ;
-
-if( a == 'V' && b == 'T' ) return    0 ;
-
-if( a == 'V' && b == 'V' ) return    8 ;
-
-if( a == 'W' && b == 'A' ) return   -6 ;
-
-if( a == 'W' && b == 'B' ) return   -8 ;
-
-if( a == 'W' && b == 'C' ) return   -4 ;
-
-if( a == 'W' && b == 'D' ) return   -8 ;
-
-if( a == 'W' && b == 'E' ) return   -6 ;
-
-if( a == 'W' && b == 'F' ) return    2 ;
-
-if( a == 'W' && b == 'G' ) return   -4 ;
-
-if( a == 'W' && b == 'H' ) return   -4 ;
-
-if( a == 'W' && b == 'I' ) return   -6 ;
-
-if( a == 'W' && b == 'K' ) return   -6 ;
-
-if( a == 'W' && b == 'L' ) return   -4 ;
-
-if( a == 'W' && b == 'M' ) return   -2 ;
-
-if( a == 'W' && b == 'N' ) return   -8 ;
-
-if( a == 'W' && b == 'P' ) return   -8 ;
-
-if( a == 'W' && b == 'Q' ) return   -4 ;
-
-if( a == 'W' && b == 'R' ) return   -6 ;
-
-if( a == 'W' && b == 'S' ) return   -6 ;
-
-if( a == 'W' && b == 'T' ) return   -4 ;
-
-if( a == 'W' && b == 'V' ) return   -6 ;
-
-if( a == 'W' && b == 'W' ) return   22 ;
-
-if( a == 'X' && b == 'A' ) return    0 ;
-
-if( a == 'X' && b == 'B' ) return   -2 ;
-
-if( a == 'X' && b == 'C' ) return   -4 ;
-
-if( a == 'X' && b == 'D' ) return   -2 ;
-
-if( a == 'X' && b == 'E' ) return   -2 ;
-
-if( a == 'X' && b == 'F' ) return   -2 ;
-
-if( a == 'X' && b == 'G' ) return   -2 ;
-
-if( a == 'X' && b == 'H' ) return   -2 ;
-
-if( a == 'X' && b == 'I' ) return   -2 ;
-
-if( a == 'X' && b == 'K' ) return   -2 ;
-
-if( a == 'X' && b == 'L' ) return   -2 ;
-
-if( a == 'X' && b == 'M' ) return   -2 ;
-
-if( a == 'X' && b == 'N' ) return   -2 ;
-
-if( a == 'X' && b == 'P' ) return   -4 ;
+  return (double)DSQRTABS(d);
+} /* bestfit */
 
-if( a == 'X' && b == 'Q' ) return   -2 ;
+int check_eq(int *iina, int *jinb, int *iina_sav, int *jinb_sav, int nentry) {
+  int i;
 
-if( a == 'X' && b == 'R' ) return   -2 ;
+  for (i=0; i<=nentry; i++) {
+    if ((iina[i] != iina_sav[i]) || (jinb[i] != jinb_sav[i]))
+      return i+1; /* hack to return what was different - Allen */
+  }
 
-if( a == 'X' && b == 'S' ) return    0 ;
+  return 0;
+} /* check_eq */
 
-if( a == 'X' && b == 'T' ) return    0 ;
+double distrms(CoordType *a, CoordType *b, int npts) {
+  int i, j;
+  LDBL ad, bd, sum;
 
-if( a == 'X' && b == 'V' ) return   -2 ;
+  sum = 0.0;
 
-if( a == 'X' && b == 'W' ) return   -4 ;
+  for (i = 0; i < npts; i++) {
+    for (j = 0; j < i; j++) {
+      ad = DSQRT(SQR(a[i].x-a[j].x) + SQR(a[i].y-a[j].y) +
+		 SQR(a[i].z-a[j].z));
+      bd = DSQRT(SQR(b[i].x-b[j].x) + SQR(b[i].y-b[j].y) +
+		 SQR(b[i].z-b[j].z));
 
-if( a == 'X' && b == 'X' ) return   -2 ;
+      sum += DSQR(ad-bd);
+    }
+  }
 
-if( a == 'Y' && b == 'A' ) return   -4 ;
+  return (double)DSQRT(2*sum/(npts*(npts-1)));
+} /* distrms */
 
-if( a == 'Y' && b == 'B' ) return   -6 ;
+double findCM(double **x_str, int Npts, double *Tcm_str) {
+  int i;
+  LDBL SumX=0, SumY=0, SumZ=0;
 
-if( a == 'Y' && b == 'C' ) return   -4 ;
+  for (i=0; i<Npts; i++) {
+    SumX+=x_str[1][i];
+    SumY+=x_str[2][i];
+    SumZ+=x_str[3][i];
+  } /* for(i<Npts) */
 
-if( a == 'Y' && b == 'D' ) return   -6 ;
+  Tcm_str[1] = (double)(SumX/Npts);
+  Tcm_str[2] = (double)(SumY/Npts);
+  Tcm_str[3] = (double)(SumZ/Npts);
 
-if( a == 'Y' && b == 'E' ) return   -4 ;
+  return (double)(SumZ/Npts);
+} /* findCM */
 
-if( a == 'Y' && b == 'F' ) return    6 ;
+double rotrans(double **x_str, int size_str, rotate_t u, xlate_t t) {
+  int i;
+  double xx, yy, zz;
 
-if( a == 'Y' && b == 'G' ) return   -6 ;
+  for (i=0; i<size_str; i++) {
+    xx = x_str[1][i];
+    yy = x_str[2][i];
+    zz = x_str[3][i]; 
 
-if( a == 'Y' && b == 'H' ) return    4 ;
+    x_str[1][i] = u[0][0]*xx + u[0][1]*yy + u[0][2]*zz;
+    x_str[2][i] = u[1][0]*xx + u[1][1]*yy + u[1][2]*zz;
+    x_str[3][i] = u[2][0]*xx + u[2][1]*yy + u[2][2]*zz;
 
-if( a == 'Y' && b == 'I' ) return   -2 ;
+    x_str[1][i] +=  t[0];
+    x_str[2][i] +=  t[1];
+    x_str[3][i] +=  t[2];
+  } /* for (i<size_str) */
 
-if( a == 'Y' && b == 'K' ) return   -4 ;
+  printf("Rotating query: %.10f %.10f %.10f; %.10f %.10f %.10f; %.10f %.10f %.10f\n",
+	 u[0][0],u[0][1],u[0][2],
+	 u[1][0],u[1][1],u[1][2],
+	 u[2][0],u[2][1],u[2][2]);
+  printf("Moving query: %.10f %.10f %.10f\n", t[0], t[1], t[2]);
 
-if( a == 'Y' && b == 'L' ) return   -2 ;
+  return 7;
+} /* rotrans */
 
-if( a == 'Y' && b == 'M' ) return   -2 ;
+static double TRvec(double *TransVec, double **RotMatr, double *Vec) {
+  double x,y,z;
 
-if( a == 'Y' && b == 'N' ) return   -4 ;
+  x = Vec[1];
+  y = Vec[2];
+  z = Vec[3];
 
-if( a == 'Y' && b == 'P' ) return   -6 ;
+  Vec[1] = RotMatr[1][1]*x + RotMatr[1][2]*y + RotMatr[1][3]*z;
+  Vec[2] = RotMatr[2][1]*x + RotMatr[2][2]*y + RotMatr[2][3]*z;
+  Vec[3] = RotMatr[3][1]*x + RotMatr[3][2]*y + RotMatr[3][3]*z;
 
-if( a == 'Y' && b == 'Q' ) return   -2 ;
+  Vec[1] += TransVec[1];
+  Vec[2] += TransVec[2];
+  Vec[3] += TransVec[3];
 
-if( a == 'Y' && b == 'R' ) return   -4 ;
+  return Vec[3];
+}
 
-if( a == 'Y' && b == 'S' ) return   -4 ;
+double TRmoveXYZstruc(double *TransVec, double **RotMatr,
+		      double **x_str, int Npts) {
+  int i;
+  double ret_val;
+  double *tempVec;
 
-if( a == 'Y' && b == 'T' ) return   -4 ;
+  tempVec = dVector(1,3);
 
-if( a == 'Y' && b == 'V' ) return   -2 ;
+  for (i=0; i<Npts; i++) {
+    tempVec[1] = x_str[1][i]; 
+    tempVec[2] = x_str[2][i]; 
+    tempVec[3] = x_str[3][i];
 
-if( a == 'Y' && b == 'W' ) return    4 ;
+    ret_val = TRvec(TransVec, RotMatr, tempVec);
 
-if( a == 'Y' && b == 'X' ) return   -2 ;
+    x_str[1][i] = tempVec[1];
+    x_str[2][i] = tempVec[2];
+    x_str[3][i] = tempVec[3];
+  }
 
-if( a == 'Y' && b == 'Y' ) return   14 ;
+  free_dVector(tempVec,1,3);
 
-if( a == 'Z' && b == 'A' ) return   -2 ;
+  return ret_val;
+} /* TRmoveXYZstruc */
 
-if( a == 'Z' && b == 'B' ) return    2 ;
+int FindMaxXYZDistIdxLast(double **x_str, int Npts) {
+   int i, iMaxDist=0;
+   LDBL MaxDist, dist;
 
-if( a == 'Z' && b == 'C' ) return   -6 ;
+   MaxDist = DSQRT(SQR(x_str[1][0]) + SQR(x_str[2][0]) + SQR(x_str[3][0]));
 
-if( a == 'Z' && b == 'D' ) return    2 ;
+   for (i=1; i<Npts; i++) {
+     dist = DSQRT(SQR(x_str[1][i]) + SQR(x_str[2][i]) + SQR(x_str[3][i]));
+     if (dist > MaxDist) {
+       iMaxDist = i;
+       MaxDist = dist;
+     }
+   }
 
-if( a == 'Z' && b == 'E' ) return    8 ;
+   return iMaxDist;
+} /* FindMaxXYZDistIdxLast */
 
-if( a == 'Z' && b == 'F' ) return   -6 ;
+int FindMaxXYDistIdxLast(double **x_str, int Npts) {
+   int i, iMaxDist=0;
+   LDBL MaxDist, dist;
 
-if( a == 'Z' && b == 'G' ) return   -4 ;
+   MaxDist = DSQRT(SQR(x_str[1][0]) + SQR(x_str[2][0]) );
 
-if( a == 'Z' && b == 'H' ) return    0 ;
+   for (i=1; i<Npts; i++) {
+     dist  = DSQRT(SQR(x_str[1][i]) + SQR(x_str[2][i]) );
+     if (dist > MaxDist) {
+       iMaxDist = i;
+       MaxDist = dist;
+     }
+   }
 
-if( a == 'Z' && b == 'I' ) return   -6 ;
+   return iMaxDist;
+} /* FindMaxXYDistIdxLast */
 
-if( a == 'Z' && b == 'K' ) return    2 ;
+double AlignZ(double x, double y, double z, double *angle_b, double *angle_c) {
+  LDBL tmp_angle_b;
 
-if( a == 'Z' && b == 'L' ) return   -6 ;
+  tmp_angle_b = DATAN(-x/z);
 
-if( a == 'Z' && b == 'M' ) return   -2 ;
+  *angle_b = (double)tmp_angle_b;
 
-if( a == 'Z' && b == 'N' ) return    0 ;
+  *angle_c = (double)DATAN(-y/(z*DCOS(tmp_angle_b)-x*DCOS(tmp_angle_b)));
 
-if( a == 'Z' && b == 'P' ) return   -2 ;
+  return (double)DCOS(tmp_angle_b);
+}
 
-if( a == 'Z' && b == 'Q' ) return    6 ;
+double FormRotMatrZ(double **Rtemp, double angle_a) {
+  Rtemp[1][1] = cos(angle_a);
+  Rtemp[1][2] = sin(angle_a);
+  Rtemp[1][3] = 0.0e0; 
 
-if( a == 'Z' && b == 'R' ) return    0 ;
+  Rtemp[2][1] = -Rtemp[1][2]; /* sin(angle_a) */
+  Rtemp[2][2] = Rtemp[1][1]; /* cos(angle_a) */
+  Rtemp[2][3] = 0.0e0; 
 
-if( a == 'Z' && b == 'S' ) return    0 ;
+  Rtemp[3][1] = 0.0e0;
+  Rtemp[3][2] = 0.0e0;
+  Rtemp[3][3] = 1.0e0;
 
-if( a == 'Z' && b == 'T' ) return   -2 ;
+  return Rtemp[1][1]+Rtemp[2][2]+Rtemp[3][3];
+} /* FormRotMatrZ */
 
-if( a == 'Z' && b == 'V' ) return   -4 ;
+double FormRotMatrY(double **Rtemp, double angle_a) {
+  Rtemp[1][1] = cos(angle_a);
+  Rtemp[1][2] = 0.0e0;
+  Rtemp[1][3] = sin(angle_a); 
 
-if( a == 'Z' && b == 'W' ) return   -6 ;
+  Rtemp[2][1] = 0.0e0;
+  Rtemp[2][2] = 1.0e0;
+  Rtemp[2][3] = 0.0e0; 
 
-if( a == 'Z' && b == 'X' ) return   -2 ;
+  Rtemp[3][1] = -Rtemp[1][3]; /* sin(angle_a) */
+  Rtemp[3][2] = 0.0e0;
+  Rtemp[3][3] = Rtemp[1][1]; /* cos(angle_a) */
 
-if( a == 'Z' && b == 'Y' ) return   -4 ;
+  return Rtemp[1][1]+Rtemp[2][2]+Rtemp[3][3];
+} /* FormRotMatrY */
 
-if( a == 'Z' && b == 'Z' ) return    8 ;
+double FormRotMatrX(double **Rtemp, double angle_a) {
+  Rtemp[1][1] = 1.0e0;
+  Rtemp[1][2] = 0.0e0;
+  Rtemp[1][3] = 0.0e0; 
 
-
+  Rtemp[2][1] = 0.0e0;
+  Rtemp[2][2] = cos(angle_a);
+  Rtemp[2][3] = sin(angle_a); 
 
-  return -8.8;  
+  Rtemp[3][1] = 0.0e0;
+  Rtemp[3][2] = -Rtemp[2][3]; /* sin(angle_a) */
+  Rtemp[3][3] = Rtemp[2][2]; /* cos(angle_a) */
 
-} /* blossom62 */
+  return Rtemp[1][1]+Rtemp[2][2]+Rtemp[3][3];
+} /* FormRotMatrX */
 
-
+/* double MAX2(double a, double b) { */
+/*   if ( a>b ) return a; */
+/*   return b; */
+/* } */
 
-double findCM(double **x_str, int Npts, double *Tcm_str) {
+/* double MIN2(double a, double b) { */
+/*   if ( a<b ) return a; */
+/*   return b; */
+/* } */
 
-  int i;
+/*=====================================================================*/
+/* Returns sum(i=0..n-1, v[3*i]) */
+static LDBL vsumby3(double v[], int n) {
+  LDBL sum;
+  int i;
 
-  double SumX, SumY, SumZ;
+  sum = *v;
+  n--;
+  v += 3;
 
-  SumX=0; SumY=0; SumZ=0;
+  for (i = 0; i < n; i++, v += 3)
+    sum += *v;
 
-  for(i=0; i<Npts; i++) {
+  return sum;
+}
 
-    SumX+=x_str[1][i]; SumY+=x_str[2][i]; SumZ+=x_str[3][i];
+/*=====================================================================*/
+/* Returns sum(i=0..n-1, v[i]^2) */
+static LDBL vsumsqr(double v[], int n) {
+  LDBL sum;
+  int i;
 
-  } /* for */
+  sum = DSQR(*v);
+  n--;
+  v++;
 
-  Tcm_str[1] = SumX/Npts;
+  for (i = 0; i < n; i++, v++)
+    sum += DSQR(*v);
 
-  Tcm_str[2] = SumY/Npts;
+  return sum;
+}
 
-  Tcm_str[3] = SumZ/Npts;
+/*=====================================================================*/
+/* Returns sum(i=0..n-1, a[3*i]*b[3*i]) */
+static LDBL vdotby3(double a[], double b[],  int n) {
+  LDBL sum;
+  int i;
 
-  return SumZ/Npts;
+  sum = (LDBL)(*a) * (LDBL)(*b);
+  n--;
+  a += 3;
+  b += 3;
 
-}
+  for (i = 0; i < n; i++, a += 3, b += 3)
+    sum += (LDBL)(*a) * (LDBL)(*b);
 
-
+  return sum;
+}
 
-double TRvec(double *TransVec, double **RotMatr, double *Vec) {
+/*=====================================================================*/
 
-  double x,y,z;
+/* Translation table from ASTRAL (http://astral.berkeley.edu) - 11/12/04
+  ala a val v phe f pro p met m ile i leu l asp d glu e lys k
+  arg r ser s thr t tyr y his h cys c asn n gln q trp w gly g
+  2as d 3ah h 5hp e acl r aib a alm a alo t aly k arm r asa d
+  asb d ask d asl d asq d aya a bcs c bhd d bmt t bnn a buc c
+  bug l c5c c c6c c ccs c cea c chg a cle l cme c csd a cso c
+  csp c css c csw c cxm m cy1 c cy3 c cyg c cym c cyq c dah f
+  dal a dar r das d dcy c dgl e dgn q dha a dhi h dil i div v
+  dle l dly k dnp a dpn f dpr p dsn s dsp d dth t dtr w dty y
+  dva v efc c fla a fme m ggl e glz g gma e gsc g hac a har r 
+  hic h hip h hmr r hpq f htr w hyp p iil i iyr y kcx k llp k
+  lly k ltr w lym k lyz k maa a men n mhs h mis s mle l mpq g
+  msa g mse m mva v nem h nep h nle l nln l nlp l nmc g oas s
+  ocs c omt m paq y pca e pec c phi f phl f pr3 c prr a ptr y
+  sac s sar g sch c scs c scy c sel s sep s set s shc c shr k
+  soc c sty y sva s tih a tpl w tpo t tpq a trg k tro w tyb y
+  tyq y tys y tyy y agm r gl3 g smc c asx b cgu e csx c glx z
 
-  x = Vec[1]; y = Vec[2]; z = Vec[3]; 
+  Some also added from .raf edits file (those noted as done automatically).
 
-  Vec[1] = RotMatr[1][1]*x + RotMatr[1][2]*y + RotMatr[1][3]*z;
+  pca changed to z due to sometimes being Q (GLN) instead of E (GLU)
 
-  Vec[2] = RotMatr[2][1]*x + RotMatr[2][2]*y + RotMatr[2][3]*z;
+*/
 
-  Vec[3] = RotMatr[3][1]*x + RotMatr[3][2]*y + RotMatr[3][3]*z;
+char convert321(char *s, int warn, int altered) {
+  switch (s[0]) {
 
-  Vec[1] += TransVec[1];
+  case 'A':
+    if (s[1] == 'L') {
+      if (s[2] == 'A') return 'A';
+      if (s[2] == 'O') return 'T';
+      if (s[2] == 'Y') return 'K';
+      break;
+    }
+    if (s[1] == 'R') {
+      if (s[2] == 'G') return 'R';
+      if (s[2] == 'M') return 'R';
+      break;
+    }
+    if (s[1] == 'S') {
+      if (s[2] == 'N') return 'N';
+      if (s[2] == 'X') return 'B';
+      if ((s[2] == 'P') ||
+	  (s[2] == 'A') ||
+	  (s[2] == 'B') ||
+	  (s[2] == 'K') ||
+	  (s[2] == 'L') ||
+	  (s[2] == 'Q'))
+	return 'D';
+      break;
+    }
+    if (s[1] == 'C') {
+      if (s[2] == 'L') return 'R';
+      if (s[2] == 'A') return 'A';
+      if (s[2] == 'Y') return 'G';
+      break;
+    }
+    if (s[1] == 'G' && s[2] == 'M') return 'R';
+    if (s[1] == 'I' && s[2] == 'B') return 'A';
+    if (s[1] == 'Y' && s[2] == 'A') return 'A';
+    if (s[1] == 'A' && s[2] == 'R') return 'R';
+    if (s[1] == 'B' && s[2] == 'A') return 'B';
+    break;
 
-  Vec[2] += TransVec[2];
+  case 'B':
+    if (s[1] == 'C' && s[2] == 'S') return 'C';
+    if (s[1] == 'H' && s[2] == 'D') return 'D';
+    if (s[1] == 'M' && s[2] == 'T') return 'T';
+    if (s[1] == 'N' && s[2] == 'N') return 'A';
+    if (s[1] == 'T') {
+      if (s[2] == 'A') return 'E';
+      if (s[2] == 'C') return 'G';
+      break;
+    }
+    if (s[1] == 'U') {
+      if (s[2] == 'C') return 'C';
+      if (s[2] == 'G') return 'L';
+      break;
+    }
+    break;
 
-  Vec[3] += TransVec[3];
+  case 'C':
+    if (s[1] == 'Y') {
+      if ((s[2] == 'S') ||
+	  (s[2] == '1') ||
+	  (s[2] == '3') ||
+	  (s[2] == 'G') ||
+	  (s[2] == 'M') ||
+	  (s[2] == 'Q'))
+	return 'C';
+      break;
+    }
+    if (s[1] == 'S') {
+      if ((s[2] == 'B') ||
+	  (s[2] == 'E') ||
+	  (s[2] == 'O') ||
+	  (s[2] == 'P') ||
+	  (s[2] == 'S') ||
+	  (s[2] == 'W') ||
+	  (s[2] == 'X'))
+	return 'C';
+      if (s[2] == 'D') return 'A';
+      break;
+    }
+    if (s[1] == 'L') {
+      if ((s[2] == 'B') ||
+	  (s[2] == 'D'))
+	return 'S';
+      if (s[2] == 'E')
+	return 'L';
+      break;
+    }
+    if (s[1] == '5' && s[2] == 'C') return 'C';
+    if (s[1] == '6' && s[2] == 'C') return 'C';
+    if (s[1] == 'A' && s[2] == 'S') return 'C';
+    if (s[1] == 'A' && s[2] == 'Y') return 'C';
+    if (s[1] == 'C' && s[2] == 'S') return 'C';
+    if (s[1] == 'E' && s[2] == 'A') return 'C';
+    if (s[1] == 'G' && s[2] == 'U') return 'E';
+    if (s[1] == 'H' && s[2] == 'G') return 'A';
+    if (s[1] == 'M' && s[2] == 'E') return 'C';
+    if (s[1] == 'X' && s[2] == 'M') return 'M';
+    break;
 
-  return Vec[3];
+  case 'D':
+    if (s[1] == 'A') {
+      if (s[2] == 'H') return 'F';
+      if (s[2] == 'L') return 'A';
+      if (s[2] == 'R') return 'R';
+      if (s[2] == 'S') return 'D';
+      break;
+    }
+    if (s[1] == 'T') {
+      if (s[2] == 'H') return 'T';
+      if (s[2] == 'R') return 'W';
+      if (s[2] == 'Y') return 'Y';
+      break;
+    }
+    if (s[1] == 'C' && s[2] == 'Y') return 'C';
+    if (s[1] == 'G' && s[2] == 'L') return 'E';
+    if (s[1] == 'G' && s[2] == 'N') return 'Q';
+    if (s[1] == 'H' && s[2] == 'A') return 'A';
+    if (s[1] == 'H' && s[2] == 'I') return 'H';
+    if (s[1] == 'I' && s[2] == 'L') return 'I';
+    if (s[1] == 'I' && s[2] == 'V') return 'V';
+    if (s[1] == 'L' && s[2] == 'E') return 'L';
+    if (s[1] == 'L' && s[2] == 'Y') return 'K';
+    if (s[1] == 'N' && s[2] == 'P') return 'A';
+    if (s[1] == 'O' && s[2] == 'H') return 'D';
+    if (s[1] == 'P' && s[2] == 'N') return 'F';
+    if (s[1] == 'P' && s[2] == 'R') return 'P';
+    if (s[1] == 'S' && s[2] == 'N') return 'S';
+    if (s[1] == 'S' && s[2] == 'P') return 'D';
+    if (s[1] == 'V' && s[2] == 'A') return 'V';
+    break;
 
-}
+  case 'F':
+    if (s[1] == 'G' && s[2] == 'L') return 'C';
+    if (s[1] == 'L' && s[2] == 'A') return 'A';
+    if (s[1] == 'M' && s[2] == 'E') return 'M';
+    break;
 
-
+  case 'G':
+    if (s[1] == 'L') {
+      if (s[2] == 'N') return 'Q';    
+      if (s[2] == 'U') return 'E';
+      if (s[2] == 'Y') return 'G';
+      if (s[2] == 'X') return 'Z';
+      if ((s[2] == 'Y') ||
+	  (s[2] == '3') ||
+	  (s[2] == 'Z'))
+	return 'G';
+      break;
+    }
+    if (s[1] == 'G' && s[2] == 'L') return 'E';
+    if (s[1] == 'M' && s[2] == 'A') return 'E';
+    if (s[1] == 'S' && s[2] == 'C') return 'G';
+    break;
 
-double TRmoveXYZstruc(double *TransVec, double **RotMatr, double **x_str, int Npts) {
+  case 'H':
+    if (s[1] == 'I') {
+      if ((s[2] == 'S') ||
+	  (s[2] == 'C') ||
+	  (s[2] == 'P'))
+	return 'H';
+      break;
+    }
+    if (s[1] == 'A' && s[2] == 'C') return 'A';
+    if (s[1] == 'A' && s[2] == 'R') return 'R';
+    if (s[1] == 'M' && s[2] == 'R') return 'R';
+    if (s[1] == 'P' && s[2] == 'Q') return 'F';
+    if (s[1] == 'T' && s[2] == 'R') return 'W';
+    if (s[1] == 'Y' && s[2] == 'P') return 'P';
+    break;
 
-  int i;
+  case 'I':
+    if (s[1] == 'A' && s[2] == 'S') return 'B';
+    if (s[1] == 'I' && s[2] == 'L') return 'I';
+    if (s[1] == 'N' && s[2] == 'I') return 'K';
+    if (s[1] == 'Y' && s[2] == 'R') return 'Y';
+    if (s[1] == 'L' && s[2] == 'E') return 'I';
+    break;
 
-  double ret_val;
+  case 'L':
+    if (s[1] == 'Y') {
+      if ((s[2] == 'S') ||
+	  (s[2] == 'M') ||
+	  (s[2] == 'X') ||
+	  (s[2] == 'Z'))
+	return 'K';
+      break;
+    }
+    if (s[1] == 'E' && s[2] == 'U') return 'L';    
+    if (s[1] == 'L') {
+      if ((s[2] == 'P') ||
+	  (s[2] == 'Y'))
+	return 'K';
+      break;
+    }
+    if (s[1] == 'T' && s[2] == 'R') return 'W';
+    break;
 
-  double *tempVec;
+  case 'M':
+    if (s[1] == 'E' && s[2] == 'T') return 'M';
+    if (s[1] == 'L') {
+      if ((s[2] == 'Y') ||
+	  (s[2] == 'Z'))
+	return 'K';
+      if (s[2] == 'E') return 'L';
+      break;
+    }
+    if (s[1] == '3' && s[2] == 'L') return 'K';
+    if (s[1] == 'A' && s[2] == 'A') return 'A';
+    if (s[1] == 'E' && s[2] == 'N') return 'N';
+    if (s[1] == 'H' && s[2] == 'O') return 'M';
+    if (s[1] == 'H' && s[2] == 'S') return 'H';
+    if (s[1] == 'I' && s[2] == 'S') return 'S';
+    if (s[1] == 'P' && s[2] == 'Q') return 'G';
+    if (s[1] == 'S' && s[2] == 'A') return 'G';
+    if (s[1] == 'S' && s[2] == 'E') return 'M';
+    if (s[1] == 'V' && s[2] == 'A') return 'V';
+    break;
 
-  tempVec = dVector(1,3);
+  case 'N':
+    if (s[1] == 'E') {
+      if ((s[2] == 'M') ||
+	  (s[2] == 'P'))
+	return 'H';
+      break;
+    }
+    if (s[1] == 'L') {
+      if ((s[2] == 'E') ||
+	  (s[2] == 'N') ||
+	  (s[2] == 'P'))
+	return 'L';
+      break;
+    }
+    if (s[1] == 'M' && s[2] == 'C') return 'G';
+    if (s[1] == 'P' && s[2] == 'H') return 'C';
+    break;
 
-  for(i=0; i<Npts; i++) {
+  case 'O':
+    if (s[1] == 'A' && s[2] == 'S') return 'S';
+    if (s[1] == 'C') {
+      if ((s[2] == 'S') ||
+	  (s[2] == 'Y'))
+	return 'C';
+      break;
+    }
+    if (s[1] == 'M' && s[2] == 'T') return 'M';
+    break;
 
-    tempVec[1] = x_str[1][i]; 
+  case 'P':
+    if (s[1] == 'H') {
+      if ((s[2] == 'E') ||
+	  (s[2] == 'I') ||
+	  (s[2] == 'L'))
+	return 'F';
+      break;
+    }
+    if (s[1] == 'R') {
+      if (s[2] == 'O') return 'P';
+      if (s[2] == 'S') return 'P';
+      if (s[2] == '3') return 'C';
+      if (s[2] == 'R') return 'A';
+      break;
+    }
+    if (s[1] == 'A' && s[2] == 'Q') return 'Y';
+    if (s[1] == 'C' && s[2] == 'A') return 'Z';
+    if (s[1] == 'E' && s[2] == 'C') return 'C';
+    if (s[1] == 'T' && s[2] == 'R') return 'Y';
+    if (s[1] == 'Y' && s[2] == 'X') return 'C';
+    break;
 
-	tempVec[2] = x_str[2][i]; 
+  case 'S':
+    if (s[1] == 'E') {
+      if ((s[2] == 'R') ||
+	  (s[2] == 'L') ||
+	  (s[2] == 'P') ||
+	  (s[2] == 'T'))
+	return 'S';
+      break;
+    }
+    if (s[1] == 'C') {
+      if ((s[2] == 'H') ||
+	  (s[2] == 'S') ||
+	  (s[2] == 'Y'))
+	return 'C';
+      break;
+    }
+    if (s[1] == 'B') {
+      if ((s[2] == 'D') ||
+	  (s[2] == 'L'))
+	return 'S';
+      break;
+    }
+    if (s[1] == 'A' && s[2] == 'C') return 'S';
+    if (s[1] == 'A' && s[2] == 'R') return 'G';
+    if (s[1] == 'H' && s[2] == 'C') return 'C';
+    if (s[1] == 'H' && s[2] == 'R') return 'K';
+    if (s[1] == 'M' && s[2] == 'C') return 'C';
+    if (s[1] == 'M' && s[2] == 'E') return 'M';
+    if (s[1] == 'N' && s[2] == 'N') return 'D';
+    if (s[1] == 'O' && s[2] == 'C') return 'C';
+    if (s[1] == 'T' && s[2] == 'Y') return 'Y';
+    if (s[1] == 'V' && s[2] == 'A') return 'S';
+    break;
 
-	tempVec[3] = x_str[3][i];
+  case 'T':
+    if (s[1] == 'Y') {
+      if ((s[2] == 'R') ||
+	  (s[2] == 'B') ||
+	  (s[2] == 'Q') ||
+	  (s[2] == 'S') ||
+	  (s[2] == 'I') ||
+	  (s[2] == 'Y'))
+	return 'Y';
+      break;
+    }
+    if (s[1] == 'R') {
+      if ((s[2] == 'P') ||
+	  (s[2] == 'N') ||
+	  (s[2] == 'O'))
+	return 'W';
+      if (s[2] == 'G') return 'K';
+      break;
+    }
+    if (s[1] == 'H' && s[2] == 'R') return 'T';   
+    if (s[1] == 'P') {
+      if (s[2] == 'L') return 'W';
+      if (s[2] == 'O') return 'T';
+      if (s[2] == 'Q') return 'A';
+      break;
+    }
+    if (s[1] == 'I' && s[2] == 'H') return 'A';
+    break;
 
-    ret_val = TRvec(TransVec, RotMatr, tempVec);
+  default:
+    if (s[0] == 'V' && s[1] == 'A' && s[2] == 'L') return 'V';
+    if (s[0] == '2' && s[1] == 'A' && s[2] == 'S') return 'D';
+    if (s[0] == '3' && s[1] == 'A' && s[2] == 'H') return 'H';
+    if (s[0] == '5' && s[1] == 'H' && s[2] == 'P') return 'E';
+    if (s[0] == 'E' && s[1] == 'F' && s[2] == 'C') return 'C';
+    if (s[0] == 'K' && s[1] == 'C' && s[2] == 'X') return 'K';
+    if (s[0] == 'U' && s[1] == 'N' && s[2] == 'K') return 'X';
+    if (altered && s[0] == '_' && s[1] == '_' && (! isalpha(s[2])))
+      return s[2];
+    break;
+  }
 
-	x_str[1][i] = tempVec[1]; x_str[2][i] = tempVec[2]; x_str[3][i] = tempVec[3];
+  if (warn) {
+    fprintf(stderr, "convert321: conversion of %s did not succeed!\n", s);
+    return 'X';
+  } else
+    return '?';
+} /* convert321 */
 
-  }
+/* from "Amino Acid Exchange Matrices" article, page 826 */
 
-  free_dVector(tempVec,1,3);
+double gonnet_p(char a, char b, int altered, int use_carbonyl) {
+  if (use_carbonyl) {
+    if (isascii(a) != isascii(b))
+      return -1000;
+    else {
+      if (! isascii(a)) {
+	a = toascii(a);
+	b = toascii(b);
+	if (isalpha(a) != isalpha(b))
+	  return -1000;
+      }
+      if (isalpha(a) && isalpha(b)) {
+	if (isupper(a) != isupper(b))
+	  return -1000;
+	else if (islower(a)) {
+	  a = _toupper(a);
+	  b = _toupper(b);
+	}
+      }
+    }
+  }
 
-  return ret_val;
+  if (altered && (! (isalpha(a) && isalpha(b)))) {
+    if (a == b)
+      return 1000;
+    else
+      return -1000;
+  }
 
-}
+  if (a < b) return gonnet_p(b,a,0,0);
 
-
+  if ((a == 'A') && (b == 'A')) return 7.6;
 
-int FindMaxXYZDistIdxLast(double **x_str, int Npts) {
+  if ((a == 'B') && (b == 'A')) return 4.9;
+  if ((a == 'B') && (b == 'B')) return 9.9;
 
-   int i, iMaxDist;
+  if ((a == 'C') && (b == 'A')) return 5.7;
+  if ((a == 'C') && (b == 'B')) return 2.7;
+  if ((a == 'C') && (b == 'C')) return 16.7;
 
-   double MaxDist, dist;
+  if ((a == 'D') && (b == 'A')) return 4.9;
+  if ((a == 'D') && (b == 'B')) return 8.65;
+  if ((a == 'D') && (b == 'C')) return 2;
+  if ((a == 'D') && (b == 'D')) return 9;
 
-   MaxDist  = sqrt( SQR(x_str[1][0]) + SQR(x_str[2][0]) + SQR(x_str[3][0]));
+  if ((a == 'E') && (b == 'A')) return 5.2;
+  if ((a == 'E') && (b == 'B')) return 7;
+  if ((a == 'E') && (b == 'C')) return 2.2;
+  if ((a == 'E') && (b == 'D')) return 7.9;
+  if ((a == 'E') && (b == 'E')) return 8.8;
 
-   iMaxDist = 0;
+  if ((a == 'F') && (b == 'A')) return 2.9;
+  if ((a == 'F') && (b == 'B')) return 1.4;
+  if ((a == 'F') && (b == 'C')) return 4.4;
+  if ((a == 'F') && (b == 'D')) return 0.7;
+  if ((a == 'F') && (b == 'E')) return 1.3;
+  if ((a == 'F') && (b == 'F')) return 12.2;
 
-   for(i=1; i<Npts; i++) {
+  if ((a == 'G') && (b == 'A')) return 5.7;
+  if ((a == 'G') && (b == 'B')) return 5.45;
+  if ((a == 'G') && (b == 'C')) return 3.2;
+  if ((a == 'G') && (b == 'D')) return 5.3;
+  if ((a == 'G') && (b == 'E')) return 4.4;
+  if ((a == 'G') && (b == 'F')) return 0;
+  if ((a == 'G') && (b == 'G')) return 11.8;
 
-     dist  = sqrt( SQR(x_str[1][i]) + SQR(x_str[2][i]) + SQR(x_str[3][i]));
+  if ((a == 'H') && (b == 'A')) return 4.4;
+  if ((a == 'H') && (b == 'B')) return 6;
+  if ((a == 'H') && (b == 'C')) return 3.9;
+  if ((a == 'H') && (b == 'D')) return 5.6;
+  if ((a == 'H') && (b == 'E')) return 5.6;
+  if ((a == 'H') && (b == 'F')) return 5.1;
+  if ((a == 'H') && (b == 'G')) return 3.8;
+  if ((a == 'H') && (b == 'H')) return 11.2;
 
-	 if( dist > MaxDist) {
+  if ((a == 'I') && (b == 'A')) return 4.4;
+  if ((a == 'I') && (b == 'B')) return 1.9;
+  if ((a == 'I') && (b == 'C')) return 4.1;
+  if ((a == 'I') && (b == 'D')) return 1.4;
+  if ((a == 'I') && (b == 'E')) return 2.5;
+  if ((a == 'I') && (b == 'F')) return 6.2;
+  if ((a == 'I') && (b == 'G')) return 0.7;
+  if ((a == 'I') && (b == 'H')) return 3;
+  if ((a == 'I') && (b == 'I')) return 9.2;
 
-	   iMaxDist = i;
+  if ((a == 'K') && (b == 'A')) return 4.8;
+  if ((a == 'K') && (b == 'B')) return 5.85;
+  if ((a == 'K') && (b == 'C')) return 2.4;
+  if ((a == 'K') && (b == 'D')) return 5.7;
+  if ((a == 'K') && (b == 'E')) return 6.4;
+  if ((a == 'K') && (b == 'F')) return 1.9;
+  if ((a == 'K') && (b == 'G')) return 4.1;
+  if ((a == 'K') && (b == 'H')) return 5.8;
+  if ((a == 'K') && (b == 'I')) return 3.1;
+  if ((a == 'K') && (b == 'K')) return 8.4;
 
-       MaxDist = dist;
+  if ((a == 'L') && (b == 'A')) return 4;
+  if ((a == 'L') && (b == 'B')) return 1.7;
+  if ((a == 'L') && (b == 'C')) return 3.7;
+  if ((a == 'L') && (b == 'D')) return 1.2;
+  if ((a == 'L') && (b == 'E')) return 2.4;
+  if ((a == 'L') && (b == 'F')) return 7.2;
+  if ((a == 'L') && (b == 'G')) return 0.8;
+  if ((a == 'L') && (b == 'H')) return 3.3;
+  if ((a == 'L') && (b == 'I')) return 8;
+  if ((a == 'L') && (b == 'K')) return 3.1;
+  if ((a == 'L') && (b == 'L')) return 9.2;
 
-	 } 
+  if ((a == 'M') && (b == 'A')) return 4.5;
+  if ((a == 'M') && (b == 'B')) return 2.6;
+  if ((a == 'M') && (b == 'C')) return 4.3;
+  if ((a == 'M') && (b == 'D')) return 2.2;
+  if ((a == 'M') && (b == 'E')) return 3.2;
+  if ((a == 'M') && (b == 'F')) return 6.8;
+  if ((a == 'M') && (b == 'G')) return 1.7;
+  if ((a == 'M') && (b == 'H')) return 3.9;
+  if ((a == 'M') && (b == 'I')) return 7.7;
+  if ((a == 'M') && (b == 'K')) return 3.8;
+  if ((a == 'M') && (b == 'L')) return 8.8;
+  if ((a == 'M') && (b == 'M')) return 9.5;
 
-   }
+  if ((a == 'N') && (b == 'A')) return 4.9;
+  if ((a == 'N') && (b == 'B')) return 8.2;
+  if ((a == 'N') && (b == 'C')) return 3.4;
+  if ((a == 'N') && (b == 'D')) return 7.4;
+  if ((a == 'N') && (b == 'E')) return 6.1;
+  if ((a == 'N') && (b == 'F')) return 2.1;
+  if ((a == 'N') && (b == 'G')) return 5.6;
+  if ((a == 'N') && (b == 'H')) return 6.4;
+  if ((a == 'N') && (b == 'I')) return 2.4;
+  if ((a == 'N') && (b == 'K')) return 6;
+  if ((a == 'N') && (b == 'L')) return 2.2;
+  if ((a == 'N') && (b == 'M')) return 3;
+  if ((a == 'N') && (b == 'N')) return 9;
 
-   return iMaxDist;
+  if ((a == 'P') && (b == 'A')) return 5.5;
+  if ((a == 'P') && (b == 'B')) return 4.4;
+  if ((a == 'P') && (b == 'C')) return 2.1;
+  if ((a == 'P') && (b == 'D')) return 4.5;
+  if ((a == 'P') && (b == 'E')) return 4.7;
+  if ((a == 'P') && (b == 'F')) return 1.4;
+  if ((a == 'P') && (b == 'G')) return 3.6;
+  if ((a == 'P') && (b == 'H')) return 4.1;
+  if ((a == 'P') && (b == 'I')) return 2.6;
+  if ((a == 'P') && (b == 'K')) return 4.6;
+  if ((a == 'P') && (b == 'L')) return 2.9;
+  if ((a == 'P') && (b == 'M')) return 2.8;
+  if ((a == 'P') && (b == 'N')) return 4.3;
+  if ((a == 'P') && (b == 'P')) return 12.8;
 
-}
+  if ((a == 'Q') && (b == 'A')) return 5;
+  if ((a == 'Q') && (b == 'B')) return 6;
+  if ((a == 'Q') && (b == 'C')) return 2.8;
+  if ((a == 'Q') && (b == 'D')) return 6.1;
+  if ((a == 'Q') && (b == 'E')) return 6.9;
+  if ((a == 'Q') && (b == 'F')) return 2.6;
+  if ((a == 'Q') && (b == 'G')) return 4.2;
+  if ((a == 'Q') && (b == 'H')) return 6.4;
+  if ((a == 'Q') && (b == 'I')) return 3.3;
+  if ((a == 'Q') && (b == 'K')) return 6.7;
+  if ((a == 'Q') && (b == 'L')) return 3.6;
+  if ((a == 'Q') && (b == 'M')) return 4.2;
+  if ((a == 'Q') && (b == 'N')) return 5.9;
+  if ((a == 'Q') && (b == 'P')) return 5;
+  if ((a == 'Q') && (b == 'Q')) return 7.9;
 
-
+  if ((a == 'R') && (b == 'A')) return 4.6;
+  if ((a == 'R') && (b == 'B')) return 5.2;
+  if ((a == 'R') && (b == 'C')) return 3;
+  if ((a == 'R') && (b == 'D')) return 4.9;
+  if ((a == 'R') && (b == 'E')) return 5.6;
+  if ((a == 'R') && (b == 'F')) return 2;
+  if ((a == 'R') && (b == 'G')) return 4.2;
+  if ((a == 'R') && (b == 'H')) return 5.8;
+  if ((a == 'R') && (b == 'I')) return 2.8;
+  if ((a == 'R') && (b == 'K')) return 7.9;
+  if ((a == 'R') && (b == 'L')) return 3;
+  if ((a == 'R') && (b == 'M')) return 3.5;
+  if ((a == 'R') && (b == 'N')) return 5.5;
+  if ((a == 'R') && (b == 'P')) return 4.3;
+  if ((a == 'R') && (b == 'Q')) return 6.7;
+  if ((a == 'R') && (b == 'R')) return 9.9;
 
-int FindMaxXYDistIdxLast(double **x_str, int Npts) {
+  if ((a == 'S') && (b == 'A')) return 6.3;
+  if ((a == 'S') && (b == 'B')) return 5.9;
+  if ((a == 'S') && (b == 'C')) return 5.3;
+  if ((a == 'S') && (b == 'D')) return 5.7;
+  if ((a == 'S') && (b == 'E')) return 5.4;
+  if ((a == 'S') && (b == 'F')) return 2.4;
+  if ((a == 'S') && (b == 'G')) return 5.6;
+  if ((a == 'S') && (b == 'H')) return 5;
+  if ((a == 'S') && (b == 'I')) return 3.4;
+  if ((a == 'S') && (b == 'K')) return 5.3;
+  if ((a == 'S') && (b == 'L')) return 3.1;
+  if ((a == 'S') && (b == 'M')) return 3.8;
+  if ((a == 'S') && (b == 'N')) return 6.1;
+  if ((a == 'S') && (b == 'P')) return 5.6;
+  if ((a == 'S') && (b == 'Q')) return 5.4;
+  if ((a == 'S') && (b == 'R')) return 5;
+  if ((a == 'S') && (b == 'S')) return 7.4;
 
-   int i, iMaxDist;
+  if ((a == 'T') && (b == 'A')) return 5.8;
+  if ((a == 'T') && (b == 'B')) return 5.45;
+  if ((a == 'T') && (b == 'C')) return 4.7;
+  if ((a == 'T') && (b == 'D')) return 5.2;
+  if ((a == 'T') && (b == 'E')) return 5.1;
+  if ((a == 'T') && (b == 'F')) return 3;
+  if ((a == 'T') && (b == 'G')) return 4.1;
+  if ((a == 'T') && (b == 'H')) return 4.9;
+  if ((a == 'T') && (b == 'I')) return 4.6;
+  if ((a == 'T') && (b == 'K')) return 5.3;
+  if ((a == 'T') && (b == 'L')) return 3.9;
+  if ((a == 'T') && (b == 'M')) return 4.6;
+  if ((a == 'T') && (b == 'N')) return 5.7;
+  if ((a == 'T') && (b == 'P')) return 5.3;
+  if ((a == 'T') && (b == 'Q')) return 5.2;
+  if ((a == 'T') && (b == 'R')) return 5;
+  if ((a == 'T') && (b == 'S')) return 6.7;
+  if ((a == 'T') && (b == 'T')) return 7.7;
 
-   double MaxDist, dist;
+  if ((a == 'V') && (b == 'A')) return 5.3;
+  if ((a == 'V') && (b == 'B')) return 2.65;
+  if ((a == 'V') && (b == 'C')) return 5.2;
+  if ((a == 'V') && (b == 'D')) return 2.3;
+  if ((a == 'V') && (b == 'E')) return 3.3;
+  if ((a == 'V') && (b == 'F')) return 5.3;
+  if ((a == 'V') && (b == 'G')) return 1.9;
+  if ((a == 'V') && (b == 'H')) return 3.2;
+  if ((a == 'V') && (b == 'I')) return 8.3;
+  if ((a == 'V') && (b == 'K')) return 3.5;
+  if ((a == 'V') && (b == 'L')) return 7;
+  if ((a == 'V') && (b == 'M')) return 6.8;
+  if ((a == 'V') && (b == 'N')) return 3;
+  if ((a == 'V') && (b == 'P')) return 3.4;
+  if ((a == 'V') && (b == 'Q')) return 3.7;
+  if ((a == 'V') && (b == 'R')) return 3.2;
+  if ((a == 'V') && (b == 'S')) return 4.2;
+  if ((a == 'V') && (b == 'T')) return 5.2;
+  if ((a == 'V') && (b == 'V')) return 8.6;
 
-   MaxDist  = sqrt( SQR(x_str[1][0]) + SQR(x_str[2][0]) );
+  if ((a == 'W') && (b == 'A')) return 1.6;
+  if ((a == 'W') && (b == 'B')) return 0.8;
+  if ((a == 'W') && (b == 'C')) return 4.2;
+  if ((a == 'W') && (b == 'D')) return 0;
+  if ((a == 'W') && (b == 'E')) return 0.9;
+  if ((a == 'W') && (b == 'F')) return 8.8;
+  if ((a == 'W') && (b == 'G')) return 1.2;
+  if ((a == 'W') && (b == 'H')) return 4.4;
+  if ((a == 'W') && (b == 'I')) return 3.4;
+  if ((a == 'W') && (b == 'K')) return 1.7;
+  if ((a == 'W') && (b == 'L')) return 4.5;
+  if ((a == 'W') && (b == 'M')) return 4.2;
+  if ((a == 'W') && (b == 'N')) return 1.6;
+  if ((a == 'W') && (b == 'P')) return 0.2;
+  if ((a == 'W') && (b == 'Q')) return 2.5;
+  if ((a == 'W') && (b == 'R')) return 3.6;
+  if ((a == 'W') && (b == 'S')) return 1.9;
+  if ((a == 'W') && (b == 'T')) return 1.7;
+  if ((a == 'W') && (b == 'V')) return 2.6;
+  if ((a == 'W') && (b == 'W')) return 19.4;
 
-   iMaxDist = 0;
+  if ((a == 'Y') && (b == 'A')) return 3;
+  if ((a == 'Y') && (b == 'B')) return 3.1;
+  if ((a == 'Y') && (b == 'C')) return 4.7;
+  if ((a == 'Y') && (b == 'D')) return 2.4;
+  if ((a == 'Y') && (b == 'E')) return 2.5;
+  if ((a == 'Y') && (b == 'F')) return 10.3;
+  if ((a == 'Y') && (b == 'G')) return 1.2;
+  if ((a == 'Y') && (b == 'H')) return 7.4;
+  if ((a == 'Y') && (b == 'I')) return 4.5;
+  if ((a == 'Y') && (b == 'K')) return 3.1;
+  if ((a == 'Y') && (b == 'L')) return 5.2;
+  if ((a == 'Y') && (b == 'M')) return 5;
+  if ((a == 'Y') && (b == 'N')) return 3.8;
+  if ((a == 'Y') && (b == 'P')) return 2.1;
+  if ((a == 'Y') && (b == 'Q')) return 3.5;
+  if ((a == 'Y') && (b == 'R')) return 3.4;
+  if ((a == 'Y') && (b == 'S')) return 3.3;
+  if ((a == 'Y') && (b == 'T')) return 3.3;
+  if ((a == 'Y') && (b == 'V')) return 4.1;
+  if ((a == 'Y') && (b == 'W')) return 9.3;
+  if ((a == 'Y') && (b == 'Y')) return 13;
 
-   for(i=1; i<Npts; i++) {
+  if ((a == 'Z') && (b == 'A')) return 5.1;
+  if ((a == 'Z') && (b == 'C')) return 2.5;
+  if ((a == 'Z') && (b == 'D')) return 7;
+  if ((a == 'Z') && (b == 'E')) return 7.85;
+  if ((a == 'Z') && (b == 'F')) return 1.95;
+  if ((a == 'Z') && (b == 'G')) return 4.3;
+  if ((a == 'Z') && (b == 'H')) return 6;
+  if ((a == 'Z') && (b == 'I')) return 2.9;
+  if ((a == 'Z') && (b == 'K')) return 6.55;
+  if ((a == 'Z') && (b == 'L')) return 3;
+  if ((a == 'Z') && (b == 'M')) return 3.7;
+  if ((a == 'Z') && (b == 'N')) return 6;
+  if ((a == 'Z') && (b == 'P')) return 4.85;
+  if ((a == 'Z') && (b == 'Q')) return 7.4;
+  if ((a == 'Z') && (b == 'R')) return 6.15;
+  if ((a == 'Z') && (b == 'S')) return 5.4;
+  if ((a == 'Z') && (b == 'T')) return 5.15;
+  if ((a == 'Z') && (b == 'V')) return 3.5;
+  if ((a == 'Z') && (b == 'W')) return 1.7;
+  if ((a == 'Z') && (b == 'Y')) return 3;
+  if ((a == 'Z') && (b == 'Z')) return 7.9;
 
-     dist  = sqrt( SQR(x_str[1][i]) + SQR(x_str[2][i]) );
+  if (a == b)
+    return 12;
+  else
+    return 0;
+} /* gonnet_p */
 
-	 if( dist > MaxDist) {
+double pam120_p(char a, char b, int altered, int use_carbonyl) {
+  if (use_carbonyl) {
+    if (isascii(a) != isascii(b))
+      return -1000;
+    else {
+      if (! isascii(a)) {
+	a = toascii(a);
+	b = toascii(b);
+	if (isalpha(a) != isalpha(b))
+	  return -1000;
+      }
+      if (isalpha(a) && isalpha(b)) {
+	if (isupper(a) != isupper(b))
+	  return -1000;
+	else if (islower(a)) {
+	  a = _toupper(a);
+	  b = _toupper(b);
+	}
+      }
+    }
+  }
 
-	   iMaxDist = i;
+  if (altered && (! (isalpha(a) && isalpha(b)))) {
+    if (a == b)
+      return 1000;
+    else
+      return -1000;
+  }
 
-       MaxDist = dist;
+  if (a < b) return pam120_p(b,a,0,0);
 
-	 } 
+  if ((a == 'A') && (b == 'A')) return 11.0;
 
-   }
+  if ((a == 'B') && (b == 'A')) return 8.0;
+  if ((a == 'B') && (b == 'B')) return 12.0;
 
-   return iMaxDist;
+  if ((a == 'C') && (b == 'A')) return 5.0;
+  if ((a == 'C') && (b == 'B')) return 2.0;
+  if ((a == 'C') && (b == 'C')) return 17.0;
 
-}
+  if ((a == 'D') && (b == 'A')) return 8.0;
+  if ((a == 'D') && (b == 'B')) return 12.0;
+  if ((a == 'D') && (b == 'C')) return 1.0;
+  if ((a == 'D') && (b == 'D')) return 13.0;
 
-
+  if ((a == 'E') && (b == 'A')) return 8.0;
+  if ((a == 'E') && (b == 'B')) return 11.0;
+  if ((a == 'E') && (b == 'C')) return 1.0;
+  if ((a == 'E') && (b == 'D')) return 11.0;
+  if ((a == 'E') && (b == 'E')) return 13.0;
 
-double AlignZ(double x, double y, double z, double *angle_b, double *angle_c){
+  if ((a == 'F') && (b == 'A')) return 4.0;
+  if ((a == 'F') && (b == 'B')) return 3.0;
+  if ((a == 'F') && (b == 'C')) return 2.0;
+  if ((a == 'F') && (b == 'D')) return 1.0;
+  if ((a == 'F') && (b == 'E')) return 1.0;
+  if ((a == 'F') && (b == 'F')) return 16.0;
 
-  *angle_b = atan( -x/z );
+  if ((a == 'G') && (b == 'A')) return 9.0;
+  if ((a == 'G') && (b == 'B')) return 8.0;
+  if ((a == 'G') && (b == 'C')) return 4.0;
+  if ((a == 'G') && (b == 'D')) return 8.0;
+  if ((a == 'G') && (b == 'E')) return 7.0;
+  if ((a == 'G') && (b == 'F')) return 3.0;
+  if ((a == 'G') && (b == 'G')) return 13.0;
 
-  *angle_c = atan( -y/(z*cos( *angle_b)-x*sin( *angle_b)) );
+  if ((a == 'H') && (b == 'A')) return 5.0;
+  if ((a == 'H') && (b == 'B')) return 9.0;
+  if ((a == 'H') && (b == 'C')) return 4.0;
+  if ((a == 'H') && (b == 'D')) return 8.0;
+  if ((a == 'H') && (b == 'E')) return 7.0;
+  if ((a == 'H') && (b == 'F')) return 5.0;
+  if ((a == 'H') && (b == 'G')) return 4.0;
+  if ((a == 'H') && (b == 'H')) return 15.0;
 
-  return cos( *angle_b);
+  if ((a == 'I') && (b == 'A')) return 7.0;
+  if ((a == 'I') && (b == 'B')) return 5.0;
+  if ((a == 'I') && (b == 'C')) return 5.0;
+  if ((a == 'I') && (b == 'D')) return 5.0;
+  if ((a == 'I') && (b == 'E')) return 5.0;
+  if ((a == 'I') && (b == 'F')) return 8.0;
+  if ((a == 'I') && (b == 'G')) return 4.0;
+  if ((a == 'I') && (b == 'H')) return 4.0;
+  if ((a == 'I') && (b == 'I')) return 14.0;
 
-}
+  if ((a == 'K') && (b == 'A')) return 6.0;
+  if ((a == 'K') && (b == 'B')) return 8.0;
+  if ((a == 'K') && (b == 'C')) return 1.0;
+  if ((a == 'K') && (b == 'D')) return 7.0;
+  if ((a == 'K') && (b == 'E')) return 7.0;
+  if ((a == 'K') && (b == 'F')) return 1.0;
+  if ((a == 'K') && (b == 'G')) return 5.0;
+  if ((a == 'K') && (b == 'H')) return 6.0;
+  if ((a == 'K') && (b == 'I')) return 5.0;
+  if ((a == 'K') && (b == 'K')) return 13.0;
 
-
+  if ((a == 'L') && (b == 'A')) return 5.0;
+  if ((a == 'L') && (b == 'B')) return 4.0;
+  if ((a == 'L') && (b == 'C')) return 1.0;
+  if ((a == 'L') && (b == 'D')) return 3.0;
+  if ((a == 'L') && (b == 'E')) return 4.0;
+  if ((a == 'L') && (b == 'F')) return 8.0;
+  if ((a == 'L') && (b == 'G')) return 3.0;
+  if ((a == 'L') && (b == 'H')) return 5.0;
+  if ((a == 'L') && (b == 'I')) return 9.0;
+  if ((a == 'L') && (b == 'K')) return 4.0;
+  if ((a == 'L') && (b == 'L')) return 13.0;
 
-double FormRotMatrZ(double **Rtemp, double angle_a){
+  if ((a == 'M') && (b == 'A')) return 6.0;
+  if ((a == 'M') && (b == 'B')) return 4.0;
+  if ((a == 'M') && (b == 'C')) return 2.0;
+  if ((a == 'M') && (b == 'D')) return 4.0;
+  if ((a == 'M') && (b == 'E')) return 5.0;
+  if ((a == 'M') && (b == 'F')) return 7.0;
+  if ((a == 'M') && (b == 'G')) return 4.0;
+  if ((a == 'M') && (b == 'H')) return 4.0;
+  if ((a == 'M') && (b == 'I')) return 9.0;
+  if ((a == 'M') && (b == 'K')) return 8.0;
+  if ((a == 'M') && (b == 'L')) return 11.0;
+  if ((a == 'M') && (b == 'M')) return 16.0;
 
-  Rtemp[1][1] = cos(angle_a);  Rtemp[1][2] = sin(angle_a); Rtemp[1][3] = 0.0e0; 
+  if ((a == 'N') && (b == 'A')) return 7.0;
+  if ((a == 'N') && (b == 'B')) return 11.0;
+  if ((a == 'N') && (b == 'C')) return 3.0;
+  if ((a == 'N') && (b == 'D')) return 10.0;
+  if ((a == 'N') && (b == 'E')) return 9.0;
+  if ((a == 'N') && (b == 'F')) return 4.0;
+  if ((a == 'N') && (b == 'G')) return 8.0;
+  if ((a == 'N') && (b == 'H')) return 10.0;
+  if ((a == 'N') && (b == 'I')) return 6.0;
+  if ((a == 'N') && (b == 'K')) return 9.0;
+  if ((a == 'N') && (b == 'L')) return 4.0;
+  if ((a == 'N') && (b == 'M')) return 5.0;
+  if ((a == 'N') && (b == 'N')) return 12.0;
 
-  Rtemp[2][1] = -sin(angle_a); Rtemp[2][2] = cos(angle_a); Rtemp[2][3] = 0.0e0; 
+  if ((a == 'P') && (b == 'A')) return 9.0;
+  if ((a == 'P') && (b == 'B')) return 6.0;
+  if ((a == 'P') && (b == 'C')) return 4.0;
+  if ((a == 'P') && (b == 'D')) return 5.0;
+  if ((a == 'P') && (b == 'E')) return 6.0;
+  if ((a == 'P') && (b == 'F')) return 3.0;
+  if ((a == 'P') && (b == 'G')) return 6.0;
+  if ((a == 'P') && (b == 'H')) return 7.0;
+  if ((a == 'P') && (b == 'I')) return 5.0;
+  if ((a == 'P') && (b == 'K')) return 6.0;
+  if ((a == 'P') && (b == 'L')) return 5.0;
+  if ((a == 'P') && (b == 'M')) return 5.0;
+  if ((a == 'P') && (b == 'N')) return 6.0;
+  if ((a == 'P') && (b == 'P')) return 14.0;
 
-  Rtemp[3][1] = 0.0e0;         Rtemp[3][2] = 0.0e0;        Rtemp[3][3] = 1.0e0; 
+  if ((a == 'Q') && (b == 'A')) return 7.0;
+  if ((a == 'Q') && (b == 'B')) return 8.0;
+  if ((a == 'Q') && (b == 'C')) return 1.0;
+  if ((a == 'Q') && (b == 'D')) return 9.0;
+  if ((a == 'Q') && (b == 'E')) return 10.0;
+  if ((a == 'Q') && (b == 'F')) return 2.0;
+  if ((a == 'Q') && (b == 'G')) return 5.0;
+  if ((a == 'Q') && (b == 'H')) return 11.0;
+  if ((a == 'Q') && (b == 'I')) return 5.0;
+  if ((a == 'Q') && (b == 'K')) return 8.0;
+  if ((a == 'Q') && (b == 'L')) return 6.0;
+  if ((a == 'Q') && (b == 'M')) return 7.0;
+  if ((a == 'Q') && (b == 'N')) return 8.0;
+  if ((a == 'Q') && (b == 'P')) return 8.0;
+  if ((a == 'Q') && (b == 'Q')) return 14.0;
 
-  return Rtemp[1][1]+Rtemp[2][2]+Rtemp[3][3];
+  if ((a == 'R') && (b == 'A')) return 5.0;
+  if ((a == 'R') && (b == 'B')) return 6.0;
+  if ((a == 'R') && (b == 'C')) return 4.0;
+  if ((a == 'R') && (b == 'D')) return 5.0;
+  if ((a == 'R') && (b == 'E')) return 5.0;
+  if ((a == 'R') && (b == 'F')) return 3.0;
+  if ((a == 'R') && (b == 'G')) return 4.0;
+  if ((a == 'R') && (b == 'H')) return 9.0;
+  if ((a == 'R') && (b == 'I')) return 6.0;
+  if ((a == 'R') && (b == 'K')) return 10.0;
+  if ((a == 'R') && (b == 'L')) return 4.0;
+  if ((a == 'R') && (b == 'M')) return 7.0;
+  if ((a == 'R') && (b == 'N')) return 7.0;
+  if ((a == 'R') && (b == 'P')) return 7.0;
+  if ((a == 'R') && (b == 'Q')) return 9.0;
+  if ((a == 'R') && (b == 'R')) return 14.0;
 
-}
+  if ((a == 'S') && (b == 'A')) return 9.0;
+  if ((a == 'S') && (b == 'B')) return 8.0;
+  if ((a == 'S') && (b == 'C')) return 8.0;
+  if ((a == 'S') && (b == 'D')) return 8.0;
+  if ((a == 'S') && (b == 'E')) return 7.0;
+  if ((a == 'S') && (b == 'F')) return 5.0;
+  if ((a == 'S') && (b == 'G')) return 9.0;
+  if ((a == 'S') && (b == 'H')) return 6.0;
+  if ((a == 'S') && (b == 'I')) return 6.0;
+  if ((a == 'S') && (b == 'K')) return 7.0;
+  if ((a == 'S') && (b == 'L')) return 4.0;
+  if ((a == 'S') && (b == 'M')) return 6.0;
+  if ((a == 'S') && (b == 'N')) return 9.0;
+  if ((a == 'S') && (b == 'P')) return 9.0;
+  if ((a == 'S') && (b == 'Q')) return 6.0;
+  if ((a == 'S') && (b == 'R')) return 7.0;
+  if ((a == 'S') && (b == 'S')) return 11.0;
 
-
+  if ((a == 'T') && (b == 'A')) return 9.0;
+  if ((a == 'T') && (b == 'B')) return 8.0;
+  if ((a == 'T') && (b == 'C')) return 5.0;
+  if ((a == 'T') && (b == 'D')) return 7.0;
+  if ((a == 'T') && (b == 'E')) return 6.0;
+  if ((a == 'T') && (b == 'F')) return 4.0;
+  if ((a == 'T') && (b == 'G')) return 7.0;
+  if ((a == 'T') && (b == 'H')) return 5.0;
+  if ((a == 'T') && (b == 'I')) return 8.0;
+  if ((a == 'T') && (b == 'K')) return 7.0;
+  if ((a == 'T') && (b == 'L')) return 5.0;
+  if ((a == 'T') && (b == 'M')) return 7.0;
+  if ((a == 'T') && (b == 'N')) return 8.0;
+  if ((a == 'T') && (b == 'P')) return 7.0;
+  if ((a == 'T') && (b == 'Q')) return 6.0;
+  if ((a == 'T') && (b == 'R')) return 6.0;
+  if ((a == 'T') && (b == 'S')) return 10.0;
+  if ((a == 'T') && (b == 'T')) return 12.0;
 
-double FormRotMatrY(double **Rtemp, double angle_a){
+  if ((a == 'V') && (b == 'A')) return 8.0;
+  if ((a == 'V') && (b == 'B')) return 5.0;
+  if ((a == 'V') && (b == 'C')) return 5.0;
+  if ((a == 'V') && (b == 'D')) return 5.0;
+  if ((a == 'V') && (b == 'E')) return 5.0;
+  if ((a == 'V') && (b == 'F')) return 5.0;
+  if ((a == 'V') && (b == 'G')) return 6.0;
+  if ((a == 'V') && (b == 'H')) return 5.0;
+  if ((a == 'V') && (b == 'I')) return 11.0;
+  if ((a == 'V') && (b == 'K')) return 4.0;
+  if ((a == 'V') && (b == 'L')) return 9.0;
+  if ((a == 'V') && (b == 'M')) return 9.0;
+  if ((a == 'V') && (b == 'N')) return 5.0;
+  if ((a == 'V') && (b == 'P')) return 6.0;
+  if ((a == 'V') && (b == 'Q')) return 5.0;
+  if ((a == 'V') && (b == 'R')) return 5.0;
+  if ((a == 'V') && (b == 'S')) return 6.0;
+  if ((a == 'V') && (b == 'T')) return 8.0;
+  if ((a == 'V') && (b == 'V')) return 13.0;
 
-  Rtemp[1][1] = cos(angle_a);  Rtemp[1][2] = 0.0e0; Rtemp[1][3] = sin(angle_a); 
+  if ((a == 'W') && (b == 'A')) return 1.0;
+  if ((a == 'W') && (b == 'B')) return 2.0;
+  if ((a == 'W') && (b == 'C')) return 0.0;
+  if ((a == 'W') && (b == 'D')) return 0.0;
+  if ((a == 'W') && (b == 'E')) return 0.0;
+  if ((a == 'W') && (b == 'F')) return 7.0;
+  if ((a == 'W') && (b == 'G')) return 0.0;
+  if ((a == 'W') && (b == 'H')) return 5.0;
+  if ((a == 'W') && (b == 'I')) return 2.0;
+  if ((a == 'W') && (b == 'K')) return 3.0;
+  if ((a == 'W') && (b == 'L')) return 5.0;
+  if ((a == 'W') && (b == 'M')) return 2.0;
+  if ((a == 'W') && (b == 'N')) return 4.0;
+  if ((a == 'W') && (b == 'P')) return 1.0;
+  if ((a == 'W') && (b == 'Q')) return 2.0;
+  if ((a == 'W') && (b == 'R')) return 9.0;
+  if ((a == 'W') && (b == 'S')) return 6.0;
+  if ((a == 'W') && (b == 'T')) return 2.0;
+  if ((a == 'W') && (b == 'V')) return 0.0;
+  if ((a == 'W') && (b == 'W')) return 20.0;
 
-  Rtemp[2][1] = 0.0e0;         Rtemp[2][2] = 1.0e0; Rtemp[2][3] = 0.0e0; 
+/*   if ((a == 'X') && (b == 'A')) return 2; */
+/*   if ((a == 'X') && (b == 'B')) return 4; */
+/*   if ((a == 'X') && (b == 'C')) return 0; */
+/*   if ((a == 'X') && (b == 'D')) return 0; */
+/*   if ((a == 'X') && (b == 'E')) return 0; */
+/*   if ((a == 'X') && (b == 'F')) return 2; */
+/*   if ((a == 'X') && (b == 'G')) return 0; */
+/*   if ((a == 'X') && (b == 'H')) return 8; */
+/*   if ((a == 'X') && (b == 'I')) return 4; */
+/*   if ((a == 'X') && (b == 'K')) return 2; */
+/*   if ((a == 'X') && (b == 'L')) return 2; */
+/*   if ((a == 'X') && (b == 'M')) return 4; */
+/*   if ((a == 'X') && (b == 'N')) return 6; */
+/*   if ((a == 'X') && (b == 'P')) return 2; */
+/*   if ((a == 'X') && (b == 'Q')) return 2; */
+/*   if ((a == 'X') && (b == 'R')) return 6; */
+/*   if ((a == 'X') && (b == 'S')) return 8; */
+/*   if ((a == 'X') && (b == 'T')) return 4; */
+/*   if ((a == 'X') && (b == 'V')) return 0; */
+/*   if ((a == 'X') && (b == 'W')) return 0; */
+/*   if ((a == 'X') && (b == 'X')) return 12; */
 
-  Rtemp[3][1] = -sin(angle_a); Rtemp[3][2] = 0.0e0; Rtemp[3][3] = cos(angle_a); 
+  if ((a == 'Y') && (b == 'A')) return 4.0;
+  if ((a == 'Y') && (b == 'B')) return 5.0;
+  if ((a == 'Y') && (b == 'C')) return 7.0;
+  if ((a == 'Y') && (b == 'D')) return 3.0;
+  if ((a == 'Y') && (b == 'E')) return 3.0;
+  if ((a == 'Y') && (b == 'F')) return 12.0;
+  if ((a == 'Y') && (b == 'G')) return 2.0;
+  if ((a == 'Y') && (b == 'H')) return 7.0;
+  if ((a == 'Y') && (b == 'I')) return 6.0;
+  if ((a == 'Y') && (b == 'K')) return 3.0;
+  if ((a == 'Y') && (b == 'L')) return 6.0;
+  if ((a == 'Y') && (b == 'M')) return 4.0;
+  if ((a == 'Y') && (b == 'N')) return 6.0;
+  if ((a == 'Y') && (b == 'P')) return 2.0;
+  if ((a == 'Y') && (b == 'Q')) return 3.0;
+  if ((a == 'Y') && (b == 'R')) return 3.0;
+  if ((a == 'Y') && (b == 'S')) return 5.0;
+  if ((a == 'Y') && (b == 'T')) return 5.0;
+  if ((a == 'Y') && (b == 'V')) return 5.0;
+  if ((a == 'Y') && (b == 'W')) return 6.0;
+/*   if ((a == 'Y') && (b == 'X')) return 4; */
+  if ((a == 'Y') && (b == 'Y')) return 16.0;
 
-  return Rtemp[1][1]+Rtemp[2][2]+Rtemp[3][3];
+  if ((a == 'Z') && (b == 'A')) return 7.0;
+  if ((a == 'Z') && (b == 'B')) return 10.0;
+  if ((a == 'Z') && (b == 'C')) return 1.0;
+  if ((a == 'Z') && (b == 'D')) return 11.0;
+  if ((a == 'Z') && (b == 'E')) return 12.0;
+  if ((a == 'Z') && (b == 'F')) return 2.0;
+  if ((a == 'Z') && (b == 'G')) return 6.0;
+  if ((a == 'Z') && (b == 'H')) return 9.0;
+  if ((a == 'Z') && (b == 'I')) return 5.0;
+  if ((a == 'Z') && (b == 'K')) return 7.0;
+  if ((a == 'Z') && (b == 'L')) return 5.0;
+  if ((a == 'Z') && (b == 'M')) return 6.0;
+  if ((a == 'Z') && (b == 'N')) return 8.0;
+  if ((a == 'Z') && (b == 'P')) return 7.0;
+  if ((a == 'Z') && (b == 'Q')) return 12.0;
+  if ((a == 'Z') && (b == 'R')) return 7.0;
+  if ((a == 'Z') && (b == 'S')) return 7.0;
+  if ((a == 'Z') && (b == 'T')) return 6.0;
+  if ((a == 'Z') && (b == 'V')) return 5.0;
+  if ((a == 'Z') && (b == 'W')) return 1.0;
+/*   if ((a == 'Z') && (b == 'X')) return 2; */
+  if ((a == 'Z') && (b == 'Y')) return 3.0;
+  if ((a == 'Z') && (b == 'Z')) return 12.0;
 
-}
+  if (a == b)
+    return 6.0;
+  else
+    return 0.0;
+} /* pam120_p */
 
-
+/* citeseer.ist.psu.edu/naor96amino.html - Amino Acid Pair Interchanges at
+ * Spatially Conserved Locations - Nussinov
+ */
 
-double FormRotMatrX(double **Rtemp, double angle_a){
+double nussinov(char a, char b, int altered, int use_carbonyl) {
 
-  Rtemp[1][1] = 1.0e0; Rtemp[1][2] = 0.0e0;         Rtemp[1][3] = 0.0e0; 
+  if (use_carbonyl) {
+    if (isascii(a) != isascii(b))
+      return -1000;
+    else {
+      if (! isascii(a)) {
+	a = toascii(a);
+	b = toascii(b);
+	if (isalpha(a) != isalpha(b))
+	  return -1000;
+      }
+      if (isalpha(a) && isalpha(b)) {
+	if (isupper(a) != isupper(b))
+	  return -1000;
+	else if (islower(a)) {
+	  a = _toupper(a);
+	  b = _toupper(b);
+	}
+      }
+    }
+  }
 
-  Rtemp[2][1] = 0.0e0; Rtemp[2][2] = cos(angle_a);  Rtemp[2][3] = sin(angle_a); 
+  if (altered && (! (isalpha(a) && isalpha(b)))) {
+    if (a == b)
+      return 1000;
+    else
+      return -1000;
+  }
 
-  Rtemp[3][1] = 0.0e0; Rtemp[3][2] = -sin(angle_a); Rtemp[3][3] = cos(angle_a); 
+  if (a < b) return nussinov(b,a,0,0);
 
-  return Rtemp[1][1]+Rtemp[2][2]+Rtemp[3][3];
+  if ((a == 'A') && (b == 'A')) return 13;
 
-}
+  if ((a == 'B') && (b == 'A')) return 9;
+  if ((a == 'B') && (b == 'B')) return 18.5;
 
-
+  if ((a == 'C') && (b == 'A')) return 11;
+  if ((a == 'C') && (b == 'B')) return 4.5;
+  if ((a == 'C') && (b == 'C')) return 23;
 
-double MAX2(double a, double b){
+  if ((a == 'D') && (b == 'A')) return 9;
+  if ((a == 'D') && (b == 'B')) return 18.5;
+  if ((a == 'D') && (b == 'C')) return 5;
+  if ((a == 'D') && (b == 'D')) return 20;
 
-  if( a>b ) return a;
+  if ((a == 'E') && (b == 'A')) return 9;
+  if ((a == 'E') && (b == 'B')) return 15.5;
+  if ((a == 'E') && (b == 'C')) return 3;
+  if ((a == 'E') && (b == 'D')) return 16;
+  if ((a == 'E') && (b == 'E')) return 20;
 
-  return b;
+  if ((a == 'F') && (b == 'A')) return 8;
+  if ((a == 'F') && (b == 'B')) return 3;
+  if ((a == 'F') && (b == 'C')) return 12;
+  if ((a == 'F') && (b == 'D')) return 3;
+  if ((a == 'F') && (b == 'E')) return 3;
+  if ((a == 'F') && (b == 'F')) return 15;
 
-}
+  if ((a == 'G') && (b == 'A')) return 9;
+  if ((a == 'G') && (b == 'B')) return 13.5;
+  if ((a == 'G') && (b == 'C')) return 9;
+  if ((a == 'G') && (b == 'D')) return 13;
+  if ((a == 'G') && (b == 'E')) return 9;
+  if ((a == 'G') && (b == 'F')) return 6;
+  if ((a == 'G') && (b == 'G')) return 21;
 
-
+  if ((a == 'H') && (b == 'A')) return 8;
+  if ((a == 'H') && (b == 'B')) return 11.5;
+  if ((a == 'H') && (b == 'C')) return 7;
+  if ((a == 'H') && (b == 'D')) return 12;
+  if ((a == 'H') && (b == 'E')) return 11;
+  if ((a == 'H') && (b == 'F')) return 7;
+  if ((a == 'H') && (b == 'G')) return 12;
+  if ((a == 'H') && (b == 'H')) return 14;
 
-double MIN2(double a, double b){
+  if ((a == 'I') && (b == 'A')) return 7;
+  if ((a == 'I') && (b == 'B')) return 0;
+  if ((a == 'I') && (b == 'C')) return 13;
+  if ((a == 'I') && (b == 'D')) return 0;
+  if ((a == 'I') && (b == 'E')) return 0;
+  if ((a == 'I') && (b == 'F')) return 15;
+  if ((a == 'I') && (b == 'G')) return 2;
+  if ((a == 'I') && (b == 'H')) return 6;
+  if ((a == 'I') && (b == 'I')) return 19;
 
-  if( a<b ) return a;
+  if ((a == 'K') && (b == 'A')) return 9;
+  if ((a == 'K') && (b == 'B')) return 15.5;
+  if ((a == 'K') && (b == 'C')) return 2;
+  if ((a == 'K') && (b == 'D')) return 16;
+  if ((a == 'K') && (b == 'E')) return 18;
+  if ((a == 'K') && (b == 'F')) return 2;
+  if ((a == 'K') && (b == 'G')) return 9;
+  if ((a == 'K') && (b == 'H')) return 10;
+  if ((a == 'K') && (b == 'I')) return 0;
+  if ((a == 'K') && (b == 'K')) return 22;
 
-  return b;
+  if ((a == 'L') && (b == 'A')) return 9;
+  if ((a == 'L') && (b == 'B')) return 1.5;
+  if ((a == 'L') && (b == 'C')) return 11;
+  if ((a == 'L') && (b == 'D')) return 1;
+  if ((a == 'L') && (b == 'E')) return 3;
+  if ((a == 'L') && (b == 'F')) return 15;
+  if ((a == 'L') && (b == 'G')) return 3;
+  if ((a == 'L') && (b == 'H')) return 6;
+  if ((a == 'L') && (b == 'I')) return 16;
+  if ((a == 'L') && (b == 'K')) return 2;
+  if ((a == 'L') && (b == 'L')) return 18;
 
-}
+  if ((a == 'M') && (b == 'A')) return 9;
+  if ((a == 'M') && (b == 'B')) return 5.5;
+  if ((a == 'M') && (b == 'C')) return 11;
+  if ((a == 'M') && (b == 'D')) return 5;
+  if ((a == 'M') && (b == 'E')) return 7;
+  if ((a == 'M') && (b == 'F')) return 12;
+  if ((a == 'M') && (b == 'G')) return 6;
+  if ((a == 'M') && (b == 'H')) return 8;
+  if ((a == 'M') && (b == 'I')) return 12;
+  if ((a == 'M') && (b == 'K')) return 5;
+  if ((a == 'M') && (b == 'L')) return 14;
+  if ((a == 'M') && (b == 'M')) return 13;
 
-
+  if ((a == 'N') && (b == 'A')) return 9;
+  if ((a == 'N') && (b == 'B')) return 17;
+  if ((a == 'N') && (b == 'C')) return 4;
+  if ((a == 'N') && (b == 'D')) return 17;
+  if ((a == 'N') && (b == 'E')) return 15;
+  if ((a == 'N') && (b == 'F')) return 3;
+  if ((a == 'N') && (b == 'G')) return 14;
+  if ((a == 'N') && (b == 'H')) return 11;
+  if ((a == 'N') && (b == 'I')) return 0;
+  if ((a == 'N') && (b == 'K')) return 15;
+  if ((a == 'N') && (b == 'L')) return 2;
+  if ((a == 'N') && (b == 'M')) return 6;
+  if ((a == 'N') && (b == 'N')) return 17;
 
-/*=====================================================================*/
+  if ((a == 'P') && (b == 'A')) return 9;
+  if ((a == 'P') && (b == 'B')) return 15;
+  if ((a == 'P') && (b == 'C')) return 8;
+  if ((a == 'P') && (b == 'D')) return 15;
+  if ((a == 'P') && (b == 'E')) return 9;
+  if ((a == 'P') && (b == 'F')) return 5;
+  if ((a == 'P') && (b == 'G')) return 15;
+  if ((a == 'P') && (b == 'H')) return 11;
+  if ((a == 'P') && (b == 'I')) return 1;
+  if ((a == 'P') && (b == 'K')) return 12;
+  if ((a == 'P') && (b == 'L')) return 1;
+  if ((a == 'P') && (b == 'M')) return 3;
+  if ((a == 'P') && (b == 'N')) return 15;
+  if ((a == 'P') && (b == 'P')) return 28;
 
-/* Returns sum(i=0..n-1, v[3*i]) */
+  if ((a == 'Q') && (b == 'A')) return 9;
+  if ((a == 'Q') && (b == 'B')) return 14.5;
+  if ((a == 'Q') && (b == 'C')) return 5;
+  if ((a == 'Q') && (b == 'D')) return 15;
+  if ((a == 'Q') && (b == 'E')) return 17;
+  if ((a == 'Q') && (b == 'F')) return 4;
+  if ((a == 'Q') && (b == 'G')) return 9;
+  if ((a == 'Q') && (b == 'H')) return 10;
+  if ((a == 'Q') && (b == 'I')) return 2;
+  if ((a == 'Q') && (b == 'K')) return 16;
+  if ((a == 'Q') && (b == 'L')) return 4;
+  if ((a == 'Q') && (b == 'M')) return 7;
+  if ((a == 'Q') && (b == 'N')) return 14;
+  if ((a == 'Q') && (b == 'P')) return 10;
+  if ((a == 'Q') && (b == 'Q')) return 16;
 
-
+  if ((a == 'R') && (b == 'A')) return 9;
+  if ((a == 'R') && (b == 'B')) return 13;
+  if ((a == 'R') && (b == 'C')) return 4;
+  if ((a == 'R') && (b == 'D')) return 13;
+  if ((a == 'R') && (b == 'E')) return 17;
+  if ((a == 'R') && (b == 'F')) return 4;
+  if ((a == 'R') && (b == 'G')) return 9;
+  if ((a == 'R') && (b == 'H')) return 12;
+  if ((a == 'R') && (b == 'I')) return 2;
+  if ((a == 'R') && (b == 'K')) return 18;
+  if ((a == 'R') && (b == 'L')) return 4;
+  if ((a == 'R') && (b == 'M')) return 7;
+  if ((a == 'R') && (b == 'N')) return 13;
+  if ((a == 'R') && (b == 'P')) return 10;
+  if ((a == 'R') && (b == 'Q')) return 14;
+  if ((a == 'R') && (b == 'R')) return 16;
 
-double vsumby3(double v[],  int n)
+  if ((a == 'S') && (b == 'A')) return 9;
+  if ((a == 'S') && (b == 'B')) return 13;
+  if ((a == 'S') && (b == 'C')) return 6;
+  if ((a == 'S') && (b == 'D')) return 13;
+  if ((a == 'S') && (b == 'E')) return 12;
+  if ((a == 'S') && (b == 'F')) return 5;
+  if ((a == 'S') && (b == 'G')) return 13;
+  if ((a == 'S') && (b == 'H')) return 11;
+  if ((a == 'S') && (b == 'I')) return 4;
+  if ((a == 'S') && (b == 'K')) return 12;
+  if ((a == 'S') && (b == 'L')) return 4;
+  if ((a == 'S') && (b == 'M')) return 6;
+  if ((a == 'S') && (b == 'N')) return 13;
+  if ((a == 'S') && (b == 'P')) return 12;
+  if ((a == 'S') && (b == 'Q')) return 11;
+  if ((a == 'S') && (b == 'R')) return 11;
+  if ((a == 'S') && (b == 'S')) return 14;
 
-  {
+  if ((a == 'T') && (b == 'A')) return 9;
+  if ((a == 'T') && (b == 'B')) return 11;
+  if ((a == 'T') && (b == 'C')) return 7;
+  if ((a == 'T') && (b == 'D')) return 11;
+  if ((a == 'T') && (b == 'E')) return 12;
+  if ((a == 'T') && (b == 'F')) return 7;
+  if ((a == 'T') && (b == 'G')) return 9;
+  if ((a == 'T') && (b == 'H')) return 9;
+  if ((a == 'T') && (b == 'I')) return 6;
+  if ((a == 'T') && (b == 'K')) return 11;
+  if ((a == 'T') && (b == 'L')) return 6;
+  if ((a == 'T') && (b == 'M')) return 7;
+  if ((a == 'T') && (b == 'N')) return 11;
+  if ((a == 'T') && (b == 'P')) return 10;
+  if ((a == 'T') && (b == 'Q')) return 10;
+  if ((a == 'T') && (b == 'R')) return 10;
+  if ((a == 'T') && (b == 'S')) return 11;
+  if ((a == 'T') && (b == 'T')) return 12;
 
-  double sum, temp;
+  if ((a == 'V') && (b == 'A')) return 7;
+  if ((a == 'V') && (b == 'B')) return 0.5;
+  if ((a == 'V') && (b == 'C')) return 13;
+  if ((a == 'V') && (b == 'D')) return 0;
+  if ((a == 'V') && (b == 'E')) return 0;
+  if ((a == 'V') && (b == 'F')) return 14;
+  if ((a == 'V') && (b == 'G')) return 4;
+  if ((a == 'V') && (b == 'H')) return 7;
+  if ((a == 'V') && (b == 'I')) return 18;
+  if ((a == 'V') && (b == 'K')) return 1;
+  if ((a == 'V') && (b == 'L')) return 14;
+  if ((a == 'V') && (b == 'M')) return 11;
+  if ((a == 'V') && (b == 'N')) return 1;
+  if ((a == 'V') && (b == 'P')) return 4;
+  if ((a == 'V') && (b == 'Q')) return 1;
+  if ((a == 'V') && (b == 'R')) return 3;
+  if ((a == 'V') && (b == 'S')) return 5;
+  if ((a == 'V') && (b == 'T')) return 8;
+  if ((a == 'V') && (b == 'V')) return 18;
 
-  int i; 
+  if ((a == 'W') && (b == 'A')) return 9;
+  if ((a == 'W') && (b == 'B')) return 5;
+  if ((a == 'W') && (b == 'C')) return 9;
+  if ((a == 'W') && (b == 'D')) return 5;
+  if ((a == 'W') && (b == 'E')) return 6;
+  if ((a == 'W') && (b == 'F')) return 12;
+  if ((a == 'W') && (b == 'G')) return 8;
+  if ((a == 'W') && (b == 'H')) return 8;
+  if ((a == 'W') && (b == 'I')) return 13;
+  if ((a == 'W') && (b == 'K')) return 4;
+  if ((a == 'W') && (b == 'L')) return 11;
+  if ((a == 'W') && (b == 'M')) return 10;
+  if ((a == 'W') && (b == 'N')) return 5;
+  if ((a == 'W') && (b == 'P')) return 4;
+  if ((a == 'W') && (b == 'Q')) return 7;
+  if ((a == 'W') && (b == 'R')) return 6;
+  if ((a == 'W') && (b == 'S')) return 7;
+  if ((a == 'W') && (b == 'T')) return 9;
+  if ((a == 'W') && (b == 'V')) return 13;
+  if ((a == 'W') && (b == 'W')) return 18;
 
-
+  if ((a == 'Y') && (b == 'A')) return 9;
+  if ((a == 'Y') && (b == 'B')) return 6.5;
+  if ((a == 'Y') && (b == 'C')) return 9;
+  if ((a == 'Y') && (b == 'D')) return 6;
+  if ((a == 'Y') && (b == 'E')) return 7;
+  if ((a == 'Y') && (b == 'F')) return 11;
+  if ((a == 'Y') && (b == 'G')) return 8;
+  if ((a == 'Y') && (b == 'H')) return 9;
+  if ((a == 'Y') && (b == 'I')) return 11;
+  if ((a == 'Y') && (b == 'K')) return 6;
+  if ((a == 'Y') && (b == 'L')) return 10;
+  if ((a == 'Y') && (b == 'M')) return 10;
+  if ((a == 'Y') && (b == 'N')) return 7;
+  if ((a == 'Y') && (b == 'P')) return 6;
+  if ((a == 'Y') && (b == 'Q')) return 8;
+  if ((a == 'Y') && (b == 'R')) return 7;
+  if ((a == 'Y') && (b == 'S')) return 8;
+  if ((a == 'Y') && (b == 'T')) return 9;
+  if ((a == 'Y') && (b == 'V')) return 11;
+  if ((a == 'Y') && (b == 'W')) return 11;
+  if ((a == 'Y') && (b == 'Y')) return 12;
 
-  sum = *v; n--; v += 3;
+  if ((a == 'Z') && (b == 'A')) return 9;
+  if ((a == 'Z') && (b == 'B')) return 15;
+  if ((a == 'Z') && (b == 'C')) return 4;
+  if ((a == 'Z') && (b == 'D')) return 15.5;
+  if ((a == 'Z') && (b == 'E')) return 18.5;
+  if ((a == 'Z') && (b == 'F')) return 3.5;
+  if ((a == 'Z') && (b == 'G')) return 9;
+  if ((a == 'Z') && (b == 'H')) return 10.5;
+  if ((a == 'Z') && (b == 'I')) return 1;
+  if ((a == 'Z') && (b == 'K')) return 17;
+  if ((a == 'Z') && (b == 'L')) return 3.5;
+  if ((a == 'Z') && (b == 'M')) return 7;
+  if ((a == 'Z') && (b == 'N')) return 14.5;
+  if ((a == 'Z') && (b == 'P')) return 9.5;
+  if ((a == 'Z') && (b == 'Q')) return 16.5;
+  if ((a == 'Z') && (b == 'R')) return 15.5;
+  if ((a == 'Z') && (b == 'S')) return 11.5;
+  if ((a == 'Z') && (b == 'T')) return 11;
+  if ((a == 'Z') && (b == 'V')) return 0.5;
+  if ((a == 'Z') && (b == 'W')) return 6.5;
+  if ((a == 'Z') && (b == 'Y')) return 7.5;
+  if ((a == 'Z') && (b == 'Z')) return 17;
 
-  for (i = 0; i != n; i++, v += 3) {
+  if (a == b)
+    return 12;
+  else
+    return 0;
+} /* nussinov */
 
-	  temp = *v;
+double blosum62(char a, char b, int altered, int use_carbonyl) {
 
-	  sum += *v;
+  if (use_carbonyl) {
+    if (isascii(a) != isascii(b))
+      return -1000;
+    else {
+      if (! isascii(a)) {
+	a = toascii(a);
+	b = toascii(b);
+	if (isalpha(a) != isalpha(b))
+	  return -1000;
+      }
+      if (isalpha(a) && isalpha(b)) {
+	if (isupper(a) != isupper(b))
+	  return -1000;
+	else if (islower(a)) {
+	  a = _toupper(a);
+	  b = _toupper(b);
+	}
+      }
+    }
+  }
 
-  }
+  if (altered && (! (isalpha(a) && isalpha(b)))) {
+    if (a == b)
+      return 1000;
+    else
+      return -1000;
+  }
 
-  return sum;
+  if (a < b) return blosum62(b,a,0,0);
 
-  }
+  if ( a == 'A' && b == 'A' ) return    7;
 
-
+  if ( a == 'B' && b == 'A' ) return   -4;
+  if ( a == 'B' && b == 'B' ) return    7;
 
-/*=====================================================================*/
+  if ( a == 'C' && b == 'A' ) return    0;
+  if ( a == 'C' && b == 'B' ) return   -6;
+  if ( a == 'C' && b == 'C' ) return   17;
 
-/* Returns sum(i=0..n-1, v[i]^2) */
+  if ( a == 'D' && b == 'A' ) return   -4;
+  if ( a == 'D' && b == 'B' ) return    8;
+  if ( a == 'D' && b == 'C' ) return   -6;
+  if ( a == 'D' && b == 'D' ) return   11;
 
-  
+  if ( a == 'E' && b == 'A' ) return   -2;
+  if ( a == 'E' && b == 'B' ) return    2;
+  if ( a == 'E' && b == 'C' ) return   -8;
+  if ( a == 'E' && b == 'D' ) return    4;
+  if ( a == 'E' && b == 'E' ) return    9;
 
-double vsumsqr(double v[],  int n)
+  if ( a == 'F' && b == 'A' ) return   -4;
+  if ( a == 'F' && b == 'B' ) return   -6;
+  if ( a == 'F' && b == 'C' ) return   -4;
+  if ( a == 'F' && b == 'D' ) return   -6;
+  if ( a == 'F' && b == 'E' ) return   -6;
+  if ( a == 'F' && b == 'F' ) return   11;
 
-  {
+  if ( a == 'G' && b == 'A' ) return    0;
+  if ( a == 'G' && b == 'B' ) return   -2;
+  if ( a == 'G' && b == 'C' ) return   -6;
+  if ( a == 'G' && b == 'D' ) return   -2;
+  if ( a == 'G' && b == 'E' ) return   -4;
+  if ( a == 'G' && b == 'F' ) return   -6;
+  if ( a == 'G' && b == 'G' ) return   11;
 
-  double sum;
+  if ( a == 'H' && b == 'A' ) return   -4;
+  if ( a == 'H' && b == 'B' ) return    0;
+  if ( a == 'H' && b == 'C' ) return   -6;
+  if ( a == 'H' && b == 'D' ) return   -2;
+  if ( a == 'H' && b == 'E' ) return    0;
+  if ( a == 'H' && b == 'F' ) return   -2;
+  if ( a == 'H' && b == 'G' ) return   -4;
+  if ( a == 'H' && b == 'H' ) return   15;
 
-  int i; 
+  if ( a == 'I' && b == 'A' ) return   -2;
+  if ( a == 'I' && b == 'B' ) return   -6;
+  if ( a == 'I' && b == 'C' ) return   -2;
+  if ( a == 'I' && b == 'D' ) return   -6;
+  if ( a == 'I' && b == 'E' ) return   -6;
+  if ( a == 'I' && b == 'F' ) return    0;
+  if ( a == 'I' && b == 'G' ) return   -8;
+  if ( a == 'I' && b == 'H' ) return   -6;
+  if ( a == 'I' && b == 'I' ) return    7;
 
-   
+  if ( a == 'K' && b == 'A' ) return   -2;
+  if ( a == 'K' && b == 'B' ) return    0;
+  if ( a == 'K' && b == 'C' ) return   -6;
+  if ( a == 'K' && b == 'D' ) return   -2;
+  if ( a == 'K' && b == 'E' ) return    2;
+  if ( a == 'K' && b == 'F' ) return   -6;
+  if ( a == 'K' && b == 'G' ) return   -4;
+  if ( a == 'K' && b == 'H' ) return   -2;
+  if ( a == 'K' && b == 'I' ) return   -6;
+  if ( a == 'K' && b == 'K' ) return    9;
 
-  sum = DSQR(*v); n--; v++;
+  if ( a == 'L' && b == 'A' ) return   -2;
+  if ( a == 'L' && b == 'B' ) return   -8;
+  if ( a == 'L' && b == 'C' ) return   -2;
+  if ( a == 'L' && b == 'D' ) return   -8;
+  if ( a == 'L' && b == 'E' ) return   -6;
+  if ( a == 'L' && b == 'F' ) return    0;
+  if ( a == 'L' && b == 'G' ) return   -8;
+  if ( a == 'L' && b == 'H' ) return   -6;
+  if ( a == 'L' && b == 'I' ) return    4;
+  if ( a == 'L' && b == 'K' ) return   -4;
+  if ( a == 'L' && b == 'L' ) return    7;
 
-  for (i = 0; i != n; i++, v++) sum += DSQR(*v);
+  if ( a == 'M' && b == 'A' ) return   -2;
+  if ( a == 'M' && b == 'B' ) return   -6;
+  if ( a == 'M' && b == 'C' ) return   -2;
+  if ( a == 'M' && b == 'D' ) return   -6;
+  if ( a == 'M' && b == 'E' ) return   -4;
+  if ( a == 'M' && b == 'F' ) return    0;
+  if ( a == 'M' && b == 'G' ) return   -6;
+  if ( a == 'M' && b == 'H' ) return   -4;
+  if ( a == 'M' && b == 'I' ) return    2;
+  if ( a == 'M' && b == 'K' ) return   -2;
+  if ( a == 'M' && b == 'L' ) return    4;
+  if ( a == 'M' && b == 'M' ) return    9;
 
-  return sum;
+  if ( a == 'N' && b == 'A' ) return   -4;
+  if ( a == 'N' && b == 'B' ) return    6;
+  if ( a == 'N' && b == 'C' ) return   -6;
+  if ( a == 'N' && b == 'D' ) return    2;
+  if ( a == 'N' && b == 'E' ) return    0;
+  if ( a == 'N' && b == 'F' ) return   -6;
+  if ( a == 'N' && b == 'G' ) return    0;
+  if ( a == 'N' && b == 'H' ) return    2;
+  if ( a == 'N' && b == 'I' ) return   -6;
+  if ( a == 'N' && b == 'K' ) return    0;
+  if ( a == 'N' && b == 'L' ) return   -6;
+  if ( a == 'N' && b == 'M' ) return   -4;
+  if ( a == 'N' && b == 'N' ) return   11;
 
-  }
+  if ( a == 'P' && b == 'A' ) return   -2;
+  if ( a == 'P' && b == 'B' ) return   -4;
+  if ( a == 'P' && b == 'C' ) return   -6;
+  if ( a == 'P' && b == 'D' ) return   -2;
+  if ( a == 'P' && b == 'E' ) return   -2;
+  if ( a == 'P' && b == 'F' ) return   -8;
+  if ( a == 'P' && b == 'G' ) return   -4;
+  if ( a == 'P' && b == 'H' ) return   -4;
+  if ( a == 'P' && b == 'I' ) return   -6;
+  if ( a == 'P' && b == 'K' ) return   -2;
+  if ( a == 'P' && b == 'L' ) return   -6;
+  if ( a == 'P' && b == 'M' ) return   -4;
+  if ( a == 'P' && b == 'N' ) return   -4;
+  if ( a == 'P' && b == 'P' ) return   13;
 
-
+  if ( a == 'Q' && b == 'A' ) return   -2;
+  if ( a == 'Q' && b == 'B' ) return    0;
+  if ( a == 'Q' && b == 'C' ) return   -6;
+  if ( a == 'Q' && b == 'D' ) return    0;
+  if ( a == 'Q' && b == 'E' ) return    4;
+  if ( a == 'Q' && b == 'F' ) return   -6;
+  if ( a == 'Q' && b == 'G' ) return   -4;
+  if ( a == 'Q' && b == 'H' ) return    0;
+  if ( a == 'Q' && b == 'I' ) return   -6;
+  if ( a == 'Q' && b == 'K' ) return    2;
+  if ( a == 'Q' && b == 'L' ) return   -4;
+  if ( a == 'Q' && b == 'M' ) return    0;
+  if ( a == 'Q' && b == 'N' ) return    0;
+  if ( a == 'Q' && b == 'P' ) return   -2;
+  if ( a == 'Q' && b == 'Q' ) return    9;
 
-/*=====================================================================*/
+  if ( a == 'R' && b == 'A' ) return   -2;
+  if ( a == 'R' && b == 'B' ) return   -2;
+  if ( a == 'R' && b == 'C' ) return   -6;
+  if ( a == 'R' && b == 'D' ) return   -4;
+  if ( a == 'R' && b == 'E' ) return    0;
+  if ( a == 'R' && b == 'F' ) return   -6;
+  if ( a == 'R' && b == 'G' ) return   -4;
+  if ( a == 'R' && b == 'H' ) return    0;
+  if ( a == 'R' && b == 'I' ) return   -6;
+  if ( a == 'R' && b == 'K' ) return    4;
+  if ( a == 'R' && b == 'L' ) return   -4;
+  if ( a == 'R' && b == 'M' ) return   -2;
+  if ( a == 'R' && b == 'N' ) return    0;
+  if ( a == 'R' && b == 'P' ) return   -4;
+  if ( a == 'R' && b == 'Q' ) return    2;
+  if ( a == 'R' && b == 'R' ) return    9;
 
-/* Returns sum(i=0..n-1, a[3*i]*b[3*i]) */
+  if ( a == 'S' && b == 'A' ) return    2;
+  if ( a == 'S' && b == 'B' ) return    0;
+  if ( a == 'S' && b == 'C' ) return   -2;
+  if ( a == 'S' && b == 'D' ) return    0;
+  if ( a == 'S' && b == 'E' ) return    0;
+  if ( a == 'S' && b == 'F' ) return   -4;
+  if ( a == 'S' && b == 'G' ) return    0;
+  if ( a == 'S' && b == 'H' ) return   -2;
+  if ( a == 'S' && b == 'I' ) return   -4;
+  if ( a == 'S' && b == 'K' ) return    0;
+  if ( a == 'S' && b == 'L' ) return   -4;
+  if ( a == 'S' && b == 'M' ) return   -2;
+  if ( a == 'S' && b == 'N' ) return    2;
+  if ( a == 'S' && b == 'P' ) return   -2;
+  if ( a == 'S' && b == 'Q' ) return    0;
+  if ( a == 'S' && b == 'R' ) return   -2;
+  if ( a == 'S' && b == 'S' ) return    7;
 
-  
+  if ( a == 'T' && b == 'A' ) return    0;
+  if ( a == 'T' && b == 'B' ) return   -2;
+  if ( a == 'T' && b == 'C' ) return   -2;
+  if ( a == 'T' && b == 'D' ) return   -2;
+  if ( a == 'T' && b == 'E' ) return   -2;
+  if ( a == 'T' && b == 'F' ) return   -4;
+  if ( a == 'T' && b == 'G' ) return   -4;
+  if ( a == 'T' && b == 'H' ) return   -4;
+  if ( a == 'T' && b == 'I' ) return   -2;
+  if ( a == 'T' && b == 'K' ) return   -2;
+  if ( a == 'T' && b == 'L' ) return   -2;
+  if ( a == 'T' && b == 'M' ) return   -2;
+  if ( a == 'T' && b == 'N' ) return    0;
+  if ( a == 'T' && b == 'P' ) return   -2;
+  if ( a == 'T' && b == 'Q' ) return   -2;
+  if ( a == 'T' && b == 'R' ) return   -2;
+  if ( a == 'T' && b == 'S' ) return    2;
+  if ( a == 'T' && b == 'T' ) return    9;
 
-double vdotby3(double a[], double b[],  int n)
+  if ( a == 'V' && b == 'A' ) return    0;
+  if ( a == 'V' && b == 'B' ) return   -6;
+  if ( a == 'V' && b == 'C' ) return   -2;
+  if ( a == 'V' && b == 'D' ) return   -6;
+  if ( a == 'V' && b == 'E' ) return   -4;
+  if ( a == 'V' && b == 'F' ) return   -2;
+  if ( a == 'V' && b == 'G' ) return   -6;
+  if ( a == 'V' && b == 'H' ) return   -6;
+  if ( a == 'V' && b == 'I' ) return    6;
+  if ( a == 'V' && b == 'K' ) return   -4;
+  if ( a == 'V' && b == 'L' ) return    2;
+  if ( a == 'V' && b == 'M' ) return    2;
+  if ( a == 'V' && b == 'N' ) return   -6;
+  if ( a == 'V' && b == 'P' ) return   -4;
+  if ( a == 'V' && b == 'Q' ) return   -4;
+  if ( a == 'V' && b == 'R' ) return   -6;
+  if ( a == 'V' && b == 'S' ) return   -4;
+  if ( a == 'V' && b == 'T' ) return    0;
+  if ( a == 'V' && b == 'V' ) return    7;
 
-  {
+  if ( a == 'W' && b == 'A' ) return   -6;
+  if ( a == 'W' && b == 'B' ) return   -8;
+  if ( a == 'W' && b == 'C' ) return   -4;
+  if ( a == 'W' && b == 'D' ) return   -8;
+  if ( a == 'W' && b == 'E' ) return   -6;
+  if ( a == 'W' && b == 'F' ) return    2;
+  if ( a == 'W' && b == 'G' ) return   -4;
+  if ( a == 'W' && b == 'H' ) return   -4;
+  if ( a == 'W' && b == 'I' ) return   -6;
+  if ( a == 'W' && b == 'K' ) return   -6;
+  if ( a == 'W' && b == 'L' ) return   -4;
+  if ( a == 'W' && b == 'M' ) return   -2;
+  if ( a == 'W' && b == 'N' ) return   -8;
+  if ( a == 'W' && b == 'P' ) return   -8;
+  if ( a == 'W' && b == 'Q' ) return   -4;
+  if ( a == 'W' && b == 'R' ) return   -6;
+  if ( a == 'W' && b == 'S' ) return   -6;
+  if ( a == 'W' && b == 'T' ) return   -4;
+  if ( a == 'W' && b == 'V' ) return   -6;
+  if ( a == 'W' && b == 'W' ) return   21;
 
-  double sum;
+  if ( a == 'X' && b == 'A' ) return    0;
+  if ( a == 'X' && b == 'B' ) return   -2;
+  if ( a == 'X' && b == 'C' ) return   -4;
+  if ( a == 'X' && b == 'D' ) return   -2;
+  if ( a == 'X' && b == 'E' ) return   -2;
+  if ( a == 'X' && b == 'F' ) return   -2;
+  if ( a == 'X' && b == 'G' ) return   -2;
+  if ( a == 'X' && b == 'H' ) return   -2;
+  if ( a == 'X' && b == 'I' ) return   -2;
+  if ( a == 'X' && b == 'K' ) return   -2;
+  if ( a == 'X' && b == 'L' ) return   -2;
+  if ( a == 'X' && b == 'M' ) return   -2;
+  if ( a == 'X' && b == 'N' ) return   -2;
+  if ( a == 'X' && b == 'P' ) return   -4;
+  if ( a == 'X' && b == 'Q' ) return   -2;
+  if ( a == 'X' && b == 'R' ) return   -2;
+  if ( a == 'X' && b == 'S' ) return    0;
+  if ( a == 'X' && b == 'T' ) return    0;
+  if ( a == 'X' && b == 'V' ) return   -2;
+  if ( a == 'X' && b == 'W' ) return   -4;
+  if ( a == 'X' && b == 'X' ) return   -2;
 
-  int i; 
+  if ( a == 'Y' && b == 'A' ) return   -4;
+  if ( a == 'Y' && b == 'B' ) return   -6;
+  if ( a == 'Y' && b == 'C' ) return   -4;
+  if ( a == 'Y' && b == 'D' ) return   -6;
+  if ( a == 'Y' && b == 'E' ) return   -4;
+  if ( a == 'Y' && b == 'F' ) return    6;
+  if ( a == 'Y' && b == 'G' ) return   -6;
+  if ( a == 'Y' && b == 'H' ) return    4;
+  if ( a == 'Y' && b == 'I' ) return   -2;
+  if ( a == 'Y' && b == 'K' ) return   -4;
+  if ( a == 'Y' && b == 'L' ) return   -2;
+  if ( a == 'Y' && b == 'M' ) return   -2;
+  if ( a == 'Y' && b == 'N' ) return   -4;
+  if ( a == 'Y' && b == 'P' ) return   -6;
+  if ( a == 'Y' && b == 'Q' ) return   -2;
+  if ( a == 'Y' && b == 'R' ) return   -4;
+  if ( a == 'Y' && b == 'S' ) return   -4;
+  if ( a == 'Y' && b == 'T' ) return   -4;
+  if ( a == 'Y' && b == 'V' ) return   -2;
+  if ( a == 'Y' && b == 'W' ) return    4;
+  if ( a == 'Y' && b == 'X' ) return   -2;
+  if ( a == 'Y' && b == 'Y' ) return   13;
 
-  
+  if ( a == 'Z' && b == 'A' ) return   -2;
+  if ( a == 'Z' && b == 'B' ) return    2;
+  if ( a == 'Z' && b == 'C' ) return   -6;
+  if ( a == 'Z' && b == 'D' ) return    2;
+  if ( a == 'Z' && b == 'E' ) return    8;
+  if ( a == 'Z' && b == 'F' ) return   -6;
+  if ( a == 'Z' && b == 'G' ) return   -4;
+  if ( a == 'Z' && b == 'H' ) return    0;
+  if ( a == 'Z' && b == 'I' ) return   -6;
+  if ( a == 'Z' && b == 'K' ) return    2;
+  if ( a == 'Z' && b == 'L' ) return   -6;
+  if ( a == 'Z' && b == 'M' ) return   -2;
+  if ( a == 'Z' && b == 'N' ) return    0;
+  if ( a == 'Z' && b == 'P' ) return   -2;
+  if ( a == 'Z' && b == 'Q' ) return    6;
+  if ( a == 'Z' && b == 'R' ) return    0;
+  if ( a == 'Z' && b == 'S' ) return    0;
+  if ( a == 'Z' && b == 'T' ) return   -2;
+  if ( a == 'Z' && b == 'V' ) return   -4;
+  if ( a == 'Z' && b == 'W' ) return   -6;
+  if ( a == 'Z' && b == 'X' ) return   -2;
+  if ( a == 'Z' && b == 'Y' ) return   -4;
+  if ( a == 'Z' && b == 'Z' ) return    7;
 
-  sum = (double)(*a) * (double)(*b); n--; a += 3; b += 3;
+  if (a == b)
+    return 0;
+  else
+    return -8;
+} /* blosum62 */
 
-  for (i = 0; i != n; i++, a += 3, b += 3)
+double check_carbonyl(char a, char b) {
+  if (isascii(a) != isascii(b))
+    return -1000;
+  else {
+    if (! isascii(a)) {
+      a = toascii(a);
+      b = toascii(b);
+      if (isalpha(a) != isalpha(b))
+	return -1000;
+    }
+    if (isalpha(a) && isalpha(b)) {
+      if (isupper(a) != isupper(b))
+	return -1000;
+    }
+  }
+  return 0;
+}
 
-    sum += (double)(*a) * (double)(*b);
 
-  return sum;
+/* Compromise between blosum62 and _really_ simpleminded version... - Allen */
 
-  }
+double glyproaln(char a, char b, int altered, int use_carbonyl) {
 
-
+  if (use_carbonyl) {
+    if (isascii(a) != isascii(b))
+      return -1000;
+    else {
+      if (! isascii(a)) {
+	a = toascii(a);
+	b = toascii(b);
+	if (isalpha(a) != isalpha(b))
+	  return -1000;
+      }
+      if (isalpha(a) && isalpha(b)) {
+	if (isupper(a) != isupper(b))
+	  return -1000;
+	else if (islower(a)) {
+	  a = _toupper(a);
+	  b = _toupper(b);
+	}
+      }
+    }
+  }
 
-
+  /* 1.0 for original (addition if identical),
+     8.0 for conversion to positive */
 
-/*=====================================================================*/
+  if (a == b) {
+    if ((altered > 0) && (! isalpha(a)))
+      return 1000;
+    else if (a == 'X')
+      return (1.0+8.0);
+    else if (a == 'G')
+      return (1.0+8.0+12.0);
+    else if (a == 'P')
+      return (1.0+8.0+14.0);
+    else
+      return (1.0+8.0+8.0);
+  } else if (altered && (! (isalpha(a) && isalpha(b))))
+    return -1000;
+  else if ((a == 'G') || (b == 'G'))
+    return 0.0;
+  else if ((a == 'P') || (b == 'P'))
+    return 0.0;
+  else if (((a == 'B') && ((b == 'N') || (b == 'D'))) ||
+	   ((b == 'B') && ((a == 'N') || (a == 'D'))))
+    return (4.0+8.0);
+  else if (((a == 'Z') && ((b == 'Q') || (b == 'E'))) ||
+	   ((b == 'Z') && ((a == 'Q') || (a == 'E'))))
+    return (4.0+8.0);
+  else
+    return 8.0;
+} /* glyproaln */
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/matvecutils.h lsqrms-2.0.4b/src/matvecutils.h
--- lsqrms-2.0.4b.old/src/matvecutils.h
+++ lsqrms-2.0.4b/src/matvecutils.h	Sun Feb 24 22:49:50 EST 2008
@@ -0,0 +1,38 @@
+#include "lsqrms.h"
+#include <ctype.h>
+
+#ifndef _toupper
+# define _toupper(x) (toupper((x)))
+#endif
+#ifndef _tolower
+# define _tolower(x) (tolower((x)))
+#endif
+
+#define tohigh(x) ((x) | ~0177)
+
+typedef double rotate_t[3][3];
+typedef double xlate_t[3];
+typedef struct Coord { double x, y, z; } CoordType;
+
+double bestfit(rotate_t , xlate_t , CoordType *, CoordType *, const int );
+double rotrans(double **, int, rotate_t, xlate_t);
+int check_eq(int *, int *, int *, int *, int);
+double distrms(CoordType *a, CoordType *b, int npts);
+
+char convert321(char *, int, int);
+double blosum62(char, char, int, int);
+double nussinov(char, char, int, int);
+double gonnet_p(char, char, int, int);
+double glyproaln(char, char, int, int);
+double pam120_p(char, char, int, int);
+double check_carbonyl(char, char);
+
+double findCM(double **, int, double *);
+/* Below could actually be unified with rotrans - Allen */
+double TRmoveXYZstruc(double *,double **,double **, int);
+int FindMaxXYZDistIdxLast(double **, int);
+int FindMaxXYDistIdxLast(double **, int);
+double AlignZ(double, double, double, double *, double *);
+double FormRotMatrX(double **, double);
+double FormRotMatrY(double **, double);
+double FormRotMatrZ(double **, double);
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/provepdb.c lsqrms-2.0.4b/src/provepdb.c
--- lsqrms-2.0.4b.old/src/provepdb.c	Sun Apr 20 17:34:29 EDT 2003
+++ lsqrms-2.0.4b/src/provepdb.c	Sun Feb 24 22:49:49 EST 2008
@@ -1,13 +1,17 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "lsqrms.h"
 
-char *provepdb (char *filename) {
-  FILE *file_stream = fopen (filename, "r");
+#if HAVE_MEMORY_H
+# include <memory.h>
+#endif
 
-  char *return_string = NULL;
+#include "provepdb.h"
+#include "matvecutils.h"
 
-  int i = 0;
+char *provepdb (char *filename, int altered, int use_carbonyl) {
+  FILE *file_stream;
+  char *return_string = NULL;
+  int i = 0, j = 0;
+  int saw_ter = 0;
   char c;
   char *line_read = NULL;
   int line_length = 0;
@@ -12,76 +16,219 @@
   char *line_read = NULL;
   int line_length = 0;
   int abc = 0;
-
   char *new_string = NULL;
-    
   char *chem = NULL;
+  char *which = NULL;
   double x, y, z;
-
   char *tempstr = NULL;
 
+  file_stream = fopen(filename, "r");
+
   if (file_stream == NULL)
     return NULL;
 
-  chem = malloc (sizeof (char) * 4);
-  tempstr = malloc (sizeof (char) * 9);
-  tempstr[8] = (char) NULL;
+  tempstr = malloc(sizeof (char) * 9);
+  if (!tempstr) {
+    printf("provepdb: Allocation failed!\n");
+    return NULL;
+  }
+  tempstr[8] = (char)NULL;
 
   do {
     abc++;
     do {
-      if ((fread (&c, sizeof (char), 1, file_stream) == 1) &&
-	  (!feof (file_stream))) {
-	line_read = 
-	  (char *) realloc (line_read, sizeof (char) * (line_length + 2));
+      if ((fread(&c, sizeof (char), 1, file_stream) == 1) &&
+	  (!feof(file_stream))) {
+	line_read = (char *)realloc(line_read, sizeof(char)*(line_length + 2));
 	line_read[line_length] = c;
 	line_read[line_length + 1] = (char) 0;
-	line_length = strlen (line_read);
-      }
-      else
+	line_length = strlen(line_read);
+      } else
 	break;
+    } while (c != (char) '\n');
+
+    if ((line_length >= 6) &&
+	(strncmp(line_read, "ENDMDL", 6) == 0))
+      break;
+
+    if (line_length >= 50) {
+      chem = malloc(sizeof (char) * 4);
+      if (!chem) {
+	printf("provepdb: Allocation failed!\n");
+	return NULL;
     }
-    while (c != (char) '\n');
-    if ((line_length >= 50) &&
-	(sscanf (line_read, "ATOM %*d CA %s", chem) == 1)) {
-      new_string = malloc (sizeof (char) * (strlen (line_read) + 1));
+      which = malloc(sizeof (char) * 2);
+      if (!chem) {
+	printf("provepdb: Allocation failed!\n");
+	return NULL;
+      }
+
+      if (sscanf(line_read, "ATOM %*d CA%*[ ] %3[^ ]%*[ ]",
+		 chem) == 1) {
+	new_string = malloc(sizeof(char) * (strlen(line_read) + 1));
+	if (!new_string) {
+	  fprintf(stderr,"provepdb: Allocation failed!\n");
+	  return NULL;
+	}
 
       i++;
+	j++;
       
       line_read[29] = '0';
       line_read[37] = '0';
       line_read[45] = '0';
-      tempstr = memcpy (tempstr, (char *) (line_read + 30), 8);
-      x = strtod (tempstr, NULL);
-      tempstr = memcpy (tempstr, (char *) (line_read + 38), 8);
-      y = strtod (tempstr, NULL);
-      tempstr = memcpy (tempstr, (char *) (line_read + 46), 8);
-      z = strtod (tempstr, NULL);
+	tempstr = memcpy(tempstr, (char *)(line_read + 30), 8);
+	x = strtod(tempstr, NULL);
+	tempstr = memcpy(tempstr, (char *)(line_read + 38), 8);
+	y = strtod(tempstr, NULL);
+	tempstr = memcpy(tempstr, (char *)(line_read + 46), 8);
+	z = strtod(tempstr, NULL);
       
-      sprintf (new_string, "ATOM%7d  CA%5s L%4d%12.3f%8.3f%8.3f\n",
-	       i, chem, i, x, y, z);
-      new_string = (char *) realloc (new_string, strlen (new_string) + 1);
+	sprintf(new_string,
+		"ATOM%7d  CA   %.3s %4d %12.3f %8.3f %8.3f\n",
+		i, chem, j, x, y, z);
+	new_string = (char *)realloc(new_string, strlen (new_string) + 1);
       if (return_string == NULL)
-	return_string = strdup ("");
+	  return_string = strdup("");
+	return_string = (char *)realloc(return_string,
+					sizeof(char)*(strlen(return_string) + 
+						      strlen(new_string) + 1));
+	return_string = strcat(return_string, new_string);
+	free(new_string);
+	new_string = NULL;
+      } else if ((!saw_ter) &&
+		 (sscanf(line_read, "HETATM%*d CA%*[ ] %3[^ ]%*[ ]",
+			 chem) == 1)) {
+	if (convert321(chem, 0, altered) != '?') {
+	  new_string = malloc(sizeof(char) * (strlen(line_read) + 1));
+	  if (!new_string) {
+	    fprintf(stderr,"provepdb: Allocation failed!\n");
+	    return NULL;
+	  }
+	  
+	  i++;
+	  j++;
+	  
+	  line_read[29] = '0';
+	  line_read[37] = '0';
+	  line_read[45] = '0';
+	  tempstr = memcpy(tempstr, (char *)(line_read + 30), 8);
+	  x = strtod(tempstr, NULL);
+	  tempstr = memcpy(tempstr, (char *)(line_read + 38), 8);
+	  y = strtod(tempstr, NULL);
+	  tempstr = memcpy(tempstr, (char *)(line_read + 46), 8);
+	  z = strtod(tempstr, NULL);
+
+	  sprintf(new_string,
+		  "ATOM%7d  CA   %.3s %4d %12.3f %8.3f %8.3f\n",
+		  i, chem, j, x, y, z);
+	  new_string = (char *)realloc(new_string, strlen (new_string) + 1);
+	  if (return_string == NULL)
+	    return_string = strdup("");
       return_string = 
-	(char *) realloc (return_string, 
-			  sizeof (char) * (strlen (return_string) + 
-					   strlen (new_string) + 1));
-      return_string = strcat (return_string, new_string);
-      free (new_string);
+	    (char *)realloc(return_string,
+			    sizeof(char)*(strlen(return_string) + 
+					  strlen(new_string) + 1));
+	  return_string = strcat(return_string, new_string);
+	  free(new_string);
       new_string = NULL;
+	}
+      } else if (use_carbonyl &&
+		 (sscanf(line_read, "ATOM %*d %[OCN]%*[ ] %3[^ ]%*[ ]",
+			 which, chem) == 2)) {
+	new_string = malloc(sizeof(char) * (strlen(line_read) + 1));
+	if (!new_string) {
+	  fprintf(stderr,"provepdb: Allocation failed!\n");
+	  return NULL;
+	}
       
-      if (strncmp (line_read, "ENDMDL", 6) == 0)
-	break;
+	i++;
+	
+	line_read[29] = '0';
+	line_read[37] = '0';
+	line_read[45] = '0';
+	tempstr = memcpy(tempstr, (char *)(line_read + 30), 8);
+	x = strtod(tempstr, NULL);
+	tempstr = memcpy(tempstr, (char *)(line_read + 38), 8);
+	y = strtod(tempstr, NULL);
+	tempstr = memcpy(tempstr, (char *)(line_read + 46), 8);
+	z = strtod(tempstr, NULL);
+
+	if (which[0] == 'N')
+	  sprintf(new_string,
+		"ATOM%7d  %s    %.3s %4d %12.3f %8.3f %8.3f\n",
+		i, which, chem, j+1, x, y, z);
+	else
+	  sprintf(new_string,
+		  "ATOM%7d  %s    %.3s %4d %12.3f %8.3f %8.3f\n",
+		  i, which, chem, j, x, y, z);
+	new_string = (char *)realloc(new_string, strlen (new_string) + 1);
+	if (return_string == NULL)
+	  return_string = strdup("");
+	return_string = (char *)realloc(return_string,
+					sizeof(char)*(strlen(return_string) + 
+						      strlen(new_string) + 1));
+	return_string = strcat(return_string, new_string);
+	free(new_string);
+	new_string = NULL;
+      } else if (use_carbonyl && (! saw_ter) &&
+		 (sscanf(line_read, "HETATM%*d %[OCN]%*[ ] %3[^ ]%*[ ]",
+			 which, chem)
+		  == 2)) {
+	if (convert321(chem, 0, altered) != '?') {
+	  new_string = malloc(sizeof(char) * (strlen(line_read) + 1));
+	  if (!new_string) {
+	    fprintf(stderr,"provepdb: Allocation failed!\n");
+	    return NULL;
     }
-    free (line_read);
+	  
+	  i++;
+	  
+	  line_read[29] = '0';
+	  line_read[37] = '0';
+	  line_read[45] = '0';
+	  tempstr = memcpy(tempstr, (char *)(line_read + 30), 8);
+	  x = strtod(tempstr, NULL);
+	  tempstr = memcpy(tempstr, (char *)(line_read + 38), 8);
+	  y = strtod(tempstr, NULL);
+	  tempstr = memcpy(tempstr, (char *)(line_read + 46), 8);
+	  z = strtod(tempstr, NULL);
+	  
+	  if (which[0] == 'N')
+	    sprintf(new_string,
+		    "ATOM%7d  %s    %.3s %4d %12.3f %8.3f %8.3f\n",
+		    i, which, chem, j+1, x, y, z);
+	  else
+	    sprintf(new_string,
+		    "ATOM%7d  %s    %.3s %4d %12.3f %8.3f %8.3f\n",
+		    i, which, chem, j, x, y, z);
+	  new_string = (char *)realloc(new_string, strlen (new_string) + 1);
+	  if (return_string == NULL)
+	    return_string = strdup("");
+	  return_string =
+	    (char *)realloc(return_string,
+			    sizeof(char)*(strlen(return_string) + 
+					  strlen(new_string) + 1));
+	  return_string = strcat(return_string, new_string);
+	  free(new_string);
+	  new_string = NULL;
+	}
+      }
+      free(chem);
+    }
+    if ((!saw_ter) && (line_length >= 3) &&
+	(strncmp(line_read, "TER", 3) == 0))
+      saw_ter = 1;
+
+    free(line_read);
     line_read = NULL;
     line_length = 0;
-    if (feof (file_stream))
+
+    if (feof(file_stream))
       break;
-  }
-  while (1);
-  fclose (file_stream);
+  } while (1);
+
+  fclose(file_stream);
   file_stream = NULL;
   return return_string;
 }
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/provepdb.h lsqrms-2.0.4b/src/provepdb.h
--- lsqrms-2.0.4b.old/src/provepdb.h	Wed Apr 16 15:06:10 EDT 2003
+++ lsqrms-2.0.4b/src/provepdb.h	Sun Feb 24 22:49:49 EST 2008
@@ -1,6 +1,6 @@
 #ifndef PROVEPDB_H
 #define PROVEPDB_H
 
-char *provepdb (char *filename);
+char *provepdb (char *filename, int altered, int use_carbonyl);
 
 #endif
diff -NaurdbB -xCVS lsqrms-2.0.4b.old/src/umath.h lsqrms-2.0.4b/src/umath.h
--- lsqrms-2.0.4b.old/src/umath.h	Wed Mar 12 17:12:18 EST 2003
+++ lsqrms-2.0.4b/src/umath.h	Sun Feb 24 22:49:49 EST 2008
@@ -1,5 +1,34 @@
-#define FABS(a) ((a) > 0 ? (a) : (-a))
-#define SQRTABS(a) ((a) > 0 ? sqrt(a) : sqrt(-a))
+#ifndef UMATH_H
+#define UMATH_H
+
+#include "lsqrms.h"
+
+#include <math.h>
+
+#if STDC_HEADERS
+# include <float.h>
+#endif
+
+#define FABS(a) ((a) >= 0 ? (a) : (-a))
+#define SQRTABS(a) ((a) >= 0 ? sqrt(a) : sqrt(-a))
+
+#if defined(__EXTENSIONS__) && defined(_MIPS_FPSET) && (_MIPS_FPSET >= 32)
+#  define LDBL long double
+#  define DSQRTABS(a) ((a) >= 0 ? sqrtl(a) : sqrtl(-a))
+#  define DSQRT(a) sqrtl(a)
+#  define DSIN(a) sinl(a)
+#  define DCOS(a) cosl(a)
+#  define DACOS(a) acosl(a)
+#  define DATAN(a) atanl(a)
+#else
+#  define LDBL double
+#  define DSQRTABS(a) ((a) >= 0 ? sqrt(a) : sqrt(-a))
+#  define DSQRT(a) sqrt(a)
+#  define DSIN(a) sin(a)
+#  define DCOS(a) cos(a)
+#  define DACOS(a) acos(a)
+#  define DATAN(a) atan(a)
+#endif
 
 #ifndef __sgi
 #  define fsqrt(a) sqrt(a)
@@ -6,7 +35,7 @@
 #endif
 
 #define SQR(a) ((a)*(a))
-#define DSQR(a) ((double)(a)*(double)(a))
+#define DSQR(a) ((LDBL)(a)*(LDBL)(a))
 #define CUBE(a) ((a)*(a)*(a))
 
 #ifndef MIN
@@ -13,3 +42,15 @@
 #  define MIN(a,b) (((a)<(b))?(a):(b))
 #  define MAX(a,b) (((a)>(b))?(a):(b))
 #endif
+
+#ifdef DBL_EPSILON
+# define epsilon DBL_EPSILON
+#else
+# ifdef __STDC__
+#  define epsilon 1e-9
+# else
+#  define epsilon 1e-7
+# endif
+#endif
+
+#endif /* ! defined(UMATH_H) */
