00001 /*
00002
00003 Code in this file was taken from PyMol v0.90 and used by permissing under
00004 the following license agreement contained in the PyMol distribution.
00005 Trivial modifications have been made to permit incorporation into VMD.
00006
00007
00008
00009 PyMOL Copyright Notice
00010 ======================
00011
00012 The PyMOL source code is copyrighted, but you can freely use and copy
00013 it as long as you don't change or remove any of the copyright notices.
00014
00015 ----------------------------------------------------------------------
00016 PyMOL is Copyright 1998-2003 by Warren L. DeLano of
00017 DeLano Scientific LLC, San Carlos, CA, USA (www.delanoscientific.com).
00018
00019 All Rights Reserved
00020
00021 Permission to use, copy, modify, distribute, and distribute modified
00022 versions of this software and its documentation for any purpose and
00023 without fee is hereby granted, provided that the above copyright
00024 notice appear in all copies and that both the copyright notice and
00025 this permission notice appear in supporting documentation, and that
00026 the names of Warren L. DeLano or DeLano Scientific LLC not be used in
00027 advertising or publicity pertaining to distribution of the software
00028 without specific, written prior permission.
00029
00030 WARREN LYFORD DELANO AND DELANO SCIENTIFIC LLC DISCLAIM ALL WARRANTIES
00031 WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
00032 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL WARREN LYFORD DELANO
00033 OR DELANO SCIENTIFIC LLC BE LIABLE FOR ANY SPECIAL, INDIRECT OR
00034 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
00035 OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00036 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
00037 USE OR PERFORMANCE OF THIS SOFTWARE.
00038 ----------------------------------------------------------------------
00039
00040 Where indicated, portions of the PyMOL system are instead protected
00041 under the copyrights of the respective authors. However, all code in
00042 the PyMOL system is released as non-restrictive open-source software
00043 under the above license or an equivalent license.
00044
00045 PyMOL Trademark Notice
00046 ======================
00047
00048 PyMOL(TM) is a trademark of DeLano Scientific LLC. Derivate software
00049 which contains PyMOL source code must be plainly distinguished from
00050 the PyMOL package distributed by DeLano Scientific LLC in all publicity,
00051 advertising, and documentation.
00052
00053 The slogans, "Includes PyMOL(TM).", "Based on PyMOL(TM) technology.",
00054 "Contains PyMOL(TM) source code.", and "Built using PyMOL(TM).", may
00055 be used in advertising, publicity, and documentation of derivate
00056 software provided that the notice, "PyMOL is a trademark of DeLano
00057 Scientific LLC.", is included in a footnote or at the end of the document.
00058
00059 All other endorsements employing the PyMOL trademark require specific,
00060 written prior permission.
00061
00062 --Warren L. DeLano (warren@delanoscientific.com)
00063
00064 */
00065
00066 #include <stdio.h>
00067 #include <math.h>
00068 #include <stdlib.h>
00069
00070
00071 #ifdef __cplusplus
00072 extern "C" {
00073 #endif
00074
00075 #ifdef R_SMALL
00076 #undef R_SMALL
00077 #endif
00078 #define R_SMALL 0.000000001
00079
00080 static void normalize3d(double *v) {
00081 double vlen;
00082 vlen = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00083 if (vlen > R_SMALL) {
00084 v[0] /= vlen;
00085 v[1] /= vlen;
00086 v[2] /= vlen;
00087 } else {
00088 v[0] = 0;
00089 v[1] = 0;
00090 v[2] = 0;
00091 }
00092 }
00093
00094 /*========================================================================*/
00095 void MatrixFitRMS(int n, float *v1, float *v2, const float *wt, float *ttt)
00096 {
00097 /*
00098 Subroutine to do the actual RMS fitting of two sets of vector coordinates
00099 This routine does not rotate the actual coordinates, but instead returns
00100 the RMS fitting value, along with the center-of-mass translation vectors
00101 T1 and T2 and the rotation vector M, which rotates the translated
00102 coordinates of molecule 2 onto the translated coordinates of molecule 1.
00103 */
00104
00105 float *vv1,*vv2;
00106 double m[3][3],aa[3][3];
00107 double sumwt, tol, sig, gam;
00108 double sg, bb, cc, tmp;
00109 int a, b, c, maxiter, iters, /* ix, */ iy, iz;
00110 double t1[3],t2[3];
00111 double aatmp[9];
00112 char *TOL;
00113
00114 /* Initialize arrays. */
00115
00116 for(a=0;a<3;a++) {
00117 for(b=0;b<3;b++) {
00118 m[a][b] = 0.0F;
00119 aa[a][b] = 0.0F;
00120 aatmp[3*a+b] = 0;
00121 }
00122 m[a][a] = 1.0F;
00123 t1[a]=0.0F;
00124 t2[a]=0.0F;
00125 }
00126
00127 sumwt = 0.0F;
00128
00129 /* RMS fit tolerance */
00130 TOL = getenv( "VMDFITRMSTOLERANCE" );
00131 if (TOL) {
00132 tol = atof(TOL);
00133 } else {
00134 tol = 1e-15;
00135 }
00136
00137 /* maximum number of fitting iterations */
00138 maxiter = 1000;
00139
00140 /* Calculate center-of-mass vectors */
00141
00142 vv1=v1;
00143 vv2=v2;
00144
00145 for(c=0;c<n;c++) {
00146 double w = wt ? wt[c] : 1;
00147 t1[0] += w * vv1[0];
00148 t1[1] += w * vv1[1];
00149 t1[2] += w * vv1[2];
00150 t2[0] += w * vv2[0];
00151 t2[1] += w * vv2[1];
00152 t2[2] += w * vv2[2];
00153 sumwt += w;
00154 vv1+=3;
00155 vv2+=3;
00156 }
00157 for(a=0;a<3;a++) {
00158 t1[a] /= sumwt;
00159 t2[a] /= sumwt;
00160 }
00161 /* Calculate correlation matrix */
00162 vv1=v1;
00163 vv2=v2;
00164 for(c=0;c<n;c++) {
00165 double w = wt ? wt[c] : 1;
00166 double x1 = w * (vv1[0] - t1[0]);
00167 double y1 = w * (vv1[1] - t1[1]);
00168 double z1 = w * (vv1[2] - t1[2]);
00169
00170 /* don't multply x2/y2/z2 by w, otherwise weights get squared */
00171 double x2 = (vv2[0] - t2[0]);
00172 double y2 = (vv2[1] - t2[1]);
00173 double z2 = (vv2[2] - t2[2]);
00174 aatmp[0] += x2 * x1;
00175 aatmp[1] += x2 * y1;
00176 aatmp[2] += x2 * z1;
00177 aatmp[3] += y2 * x1;
00178 aatmp[4] += y2 * y1;
00179 aatmp[5] += y2 * z1;
00180 aatmp[6] += z2 * x1;
00181 aatmp[7] += z2 * y1;
00182 aatmp[8] += z2 * z1;
00183 vv1+=3;
00184 vv2+=3;
00185 }
00186 for (a=0; a<3; a++) for (b=0; b<3; b++) aa[a][b] = aatmp[3*a+b];
00187
00188 if(n>1) {
00189 /* Primary iteration scheme to determine rotation matrix for molecule 2 */
00190 iters = 0;
00191 while(1) {
00192 /* IX, IY, and IZ rotate 1-2-3, 2-3-1, 3-1-2, etc.*/
00193 iz = (iters+1) % 3;
00194 iy = (iz+1) % 3;
00195 /* ix = (iy+1) % 3; */
00196 sig = aa[iz][iy] - aa[iy][iz];
00197 gam = aa[iy][iy] + aa[iz][iz];
00198
00199 if(iters>=maxiter)
00200 {
00201 fprintf(stderr,
00202 " Matrix: Warning: no convergence (%1.8f<%1.8f after %d iterations).\n",(float)tol,(float)gam,iters);
00203 break;
00204 }
00205
00206 /* Determine size of off-diagonal element. If off-diagonals exceed the
00207 diagonal elements * tolerance, perform Jacobi rotation. */
00208 tmp = sig*sig + gam*gam;
00209 sg = sqrt(tmp);
00210 if((sg!=0.0F) &&(fabs(sig)>(tol*fabs(gam)))) {
00211 sg = 1.0F / sg;
00212 for(a=0;a<3;a++)
00213 {
00214 bb = gam*aa[iy][a] + sig*aa[iz][a];
00215 cc = gam*aa[iz][a] - sig*aa[iy][a];
00216 aa[iy][a] = bb*sg;
00217 aa[iz][a] = cc*sg;
00218
00219 bb = gam*m[iy][a] + sig*m[iz][a];
00220 cc = gam*m[iz][a] - sig*m[iy][a];
00221 m[iy][a] = bb*sg;
00222 m[iz][a] = cc*sg;
00223 }
00224 } else {
00225 break;
00226 }
00227 iters++;
00228 }
00229 }
00230 /* At this point, we should have a converged rotation matrix (M). Calculate
00231 the weighted RMS error. */
00232 vv1=v1;
00233 vv2=v2;
00234
00235 normalize3d(m[0]);
00236 normalize3d(m[1]);
00237 normalize3d(m[2]);
00238
00239 ttt[0]=(float)m[0][0];
00240 ttt[1]=(float)m[0][1];
00241 ttt[2]=(float)m[0][2];
00242 ttt[3]=(float)-t1[0];
00243 ttt[4]=(float)m[1][0];
00244 ttt[5]=(float)m[1][1];
00245 ttt[6]=(float)m[1][2];
00246 ttt[7]=(float)-t1[1];
00247 ttt[8]=(float)m[2][0];
00248 ttt[9]=(float)m[2][1];
00249 ttt[10]=(float)m[2][2];
00250 ttt[11]=(float)-t1[2];
00251 ttt[12]=(float)t2[0];
00252 ttt[13]=(float)t2[1];
00253 ttt[14]=(float)t2[2];
00254 ttt[15]=1.0F; /* for compatibility with normal 4x4 matrices */
00255 }
00256
00257 #ifdef __cplusplus
00258 }
00259 #endif
00260
1.2.14 written by Dimitri van Heesch,
© 1997-2002