Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

fitrms.c

Go to the documentation of this file.
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 

Generated on Fri Apr 19 02:44:24 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002