Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

NamdOneTools.C

Go to the documentation of this file.
00001 
00007 /*
00008    NAMD 1.X functions copied without change for use primarily in WorkDistrib
00009 */
00010 
00011 #include "InfoStream.h"
00012 #include "common.h"
00013 #include "NamdTypes.h"
00014 #include "NamdOneTools.h"
00015 #include "Vector.h"
00016 #include "PDB.h"
00017 #include "Molecule.h"
00018 #define MIN_DEBUG_LEVEL 4
00019 //#define DEBUGM
00020 #include "Debug.h"
00021 
00022 //#define DEBUGM
00023 #include "Debug.h"
00024 
00025 /************************************************************************/
00026 /*   FUNCTION read_binary_coors                                         */
00027 /*   INPUTS:                                                            */
00028 /*      fname - Filename to read coordinates from                       */
00029 /*      pdbobj - PDB object to place coordinates into                   */
00030 /*      This function reads initial coordinates from a binary           */
00031 /*      restart file                                                    */
00032 /************************************************************************/
00033 
00034 void read_binary_coors(char *fname, PDB *pdbobj) {
00035   Vector *newcoords;    //  Array of vectors to hold coordinates from file
00036 
00037   //  Allocate an array to hold the new coordinates
00038   newcoords = new Vector[pdbobj->num_atoms()];
00039 
00040   //  Read the coordinate from the file
00041   read_binary_file(fname,newcoords,pdbobj->num_atoms());
00042 
00043   //  Set the coordinates in the PDB object to the new coordinates
00044   pdbobj->set_all_positions(newcoords);
00045 
00046   //  Clean up
00047   delete [] newcoords;
00048 
00049 } // END OF FUNCTION read_binary_coors()
00050 
00051 
00052 void read_binary_file(const char *fname, Vector *data, int n)
00053 {
00054   int32 filen;          //  Number of atoms read from file
00055   FILE *fp;             //  File descriptor
00056   int needToFlip = 0;
00057 
00058   //  Open the file and die if the open fails
00059   if ( (fp = Fopen(fname, "rb")) == NULL)
00060   {
00061     char errmsg[256];
00062     sprintf(errmsg, "Unable to open binary file %s", fname);
00063     NAMD_die(errmsg);
00064   }
00065 
00066   //  read the number of coordinates in this file
00067   if (fread(&filen, sizeof(int32), 1, fp) != (size_t)1)
00068   {
00069     char errmsg[256];
00070     sprintf(errmsg, "Error reading binary file %s", fname);
00071     NAMD_die(errmsg);
00072   }
00073 
00074   //  read the number of coordinates in this file
00075   //  check for palindromic number of atoms
00076   char lenbuf[4];
00077   memcpy(lenbuf, (const char *)&filen, 4);
00078   char tmpc;
00079   tmpc = lenbuf[0]; lenbuf[0] = lenbuf[3]; lenbuf[3] = tmpc;
00080   tmpc = lenbuf[1]; lenbuf[1] = lenbuf[2]; lenbuf[2] = tmpc;
00081   if ( ! memcmp((const char *)&filen, lenbuf, 4) ) {
00082     iout << iWARN << "Number of atoms in binary file " << fname <<
00083                 " is palindromic, assuming same endian.\n" << endi;
00084   }
00085 
00086   //  Die if this doesn't match the number in our system
00087   if (filen != n)
00088   {
00089     needToFlip = 1;
00090     memcpy((char *)&filen, lenbuf, 4);
00091   }
00092   if (filen != n)
00093   {
00094     char errmsg[256];
00095     sprintf(errmsg, "Incorrect atom count in binary file %s", fname);
00096     NAMD_die(errmsg);
00097   }
00098 
00099   if (fread(data, sizeof(Vector), n, fp) != (size_t)n)
00100   {
00101     char errmsg[256];
00102     sprintf(errmsg, "Error reading binary file %s", fname);
00103     NAMD_die(errmsg);
00104   }
00105 
00106   Fclose(fp);
00107 
00108   if (needToFlip) { 
00109     iout << iWARN << "Converting binary file " << fname << "\n" << endi;
00110     int i;
00111     char *cdata = (char *) data;
00112     for ( i=0; i<3*n; ++i, cdata+=8 ) {
00113       char tmp0, tmp1, tmp2, tmp3;
00114       tmp0 = cdata[0]; tmp1 = cdata[1];
00115       tmp2 = cdata[2]; tmp3 = cdata[3];
00116       cdata[0] = cdata[7]; cdata[1] = cdata[6];
00117       cdata[2] = cdata[5]; cdata[3] = cdata[4];
00118       cdata[7] = tmp0; cdata[6] = tmp1;
00119       cdata[5] = tmp2; cdata[4] = tmp3;
00120     }
00121   }
00122 
00123 }
00124 
00125 
00126 /* 
00127  * Generate a 3x3 transformation matrix for rotation about a given
00128  * vector v by an angle given in degrees
00129  */
00130 void vec_rotation_matrix( BigReal angle, Vector v, BigReal m[] ) {
00131    /* This function contributed by Erich Boleyn (erich@uruk.org) */
00132    BigReal mag, s, c;
00133    BigReal xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
00134 
00135    s = sin(angle * PI/180.0);
00136    c = cos(angle * PI/180.0);
00137 
00138    mag = v.length();
00139 
00140    if (mag == 0.0) {
00141       /* generate an identity matrix and return */
00142       for ( int i = 0; i < 9; ++i ) m[i] = 0.0;
00143       m[0] = m[4] = m[8] = 1.0;
00144       return;
00145    }
00146 
00147    // normalize the vector 
00148    v /= mag;
00149 
00150    /*
00151     *     Arbitrary axis rotation matrix.
00152     *
00153     *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
00154     *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
00155     *  (which is about the X-axis), and the two composite transforms
00156     *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
00157     *  from the arbitrary axis to the X-axis then back.  They are
00158     *  all elementary rotations.
00159     *
00160     *  Rz' is a rotation about the Z-axis, to bring the axis vector
00161     *  into the x-z plane.  Then Ry' is applied, rotating about the
00162     *  Y-axis to bring the axis vector parallel with the X-axis.  The
00163     *  rotation about the X-axis is then performed.  Ry and Rz are
00164     *  simply the respective inverse transforms to bring the arbitrary
00165     *  axis back to it's original orientation.  The first transforms
00166     *  Rz' and Ry' are considered inverses, since the data from the
00167     *  arbitrary axis gives you info on how to get to it, not how
00168     *  to get away from it, and an inverse must be applied.
00169     *
00170     *  The basic calculation used is to recognize that the arbitrary
00171     *  axis vector (x, y, z), since it is of unit length, actually
00172     *  represents the sines and cosines of the angles to rotate the
00173     *  X-axis to the same orientation, with theta being the angle about
00174     *  Z and phi the angle about Y (in the order described above)
00175     *  as follows:
00176     *
00177     *  cos ( theta ) = x / sqrt ( 1 - z^2 )
00178     *  sin ( theta ) = y / sqrt ( 1 - z^2 )
00179     *
00180     *  cos ( phi ) = sqrt ( 1 - z^2 )
00181     *  sin ( phi ) = z
00182     *
00183     *  Note that cos ( phi ) can further be inserted to the above
00184     *  formulas:
00185     *
00186     *  cos ( theta ) = x / cos ( phi )
00187     *  sin ( theta ) = y / sin ( phi )
00188     *
00189     *  ...etc.  Because of those relations and the standard trigonometric
00190     *  relations, it is pssible to reduce the transforms down to what
00191     *  is used below.  It may be that any primary axis chosen will give the
00192     *  same results (modulo a sign convention) using thie method.
00193     *
00194     *  Particularly nice is to notice that all divisions that might
00195     *  have caused trouble when parallel to certain planes or
00196     *  axis go away with care paid to reducing the expressions.
00197     *  After checking, it does perform correctly under all cases, since
00198     *  in all the cases of division where the denominator would have
00199     *  been zero, the numerator would have been zero as well, giving
00200     *  the expected result.
00201     */
00202 
00203    // store matrix in (row, col) form, i.e., m(row,col) = m[row*3+col]
00204 
00205    xx = v.x * v.x;
00206    yy = v.y * v.y;
00207    zz = v.z * v.z;
00208    xy = v.x * v.y;
00209    yz = v.y * v.z;
00210    zx = v.z * v.x;
00211    xs = v.x * s;
00212    ys = v.y * s;
00213    zs = v.z * s;
00214    one_c = 1.0 - c;
00215 
00216    m[0] = (one_c * xx) + c;
00217    m[1] = (one_c * xy) - zs;
00218    m[2] = (one_c * zx) + ys;
00219    
00220    m[3] = (one_c * xy) + zs;
00221    m[4] = (one_c * yy) + c;
00222    m[5] = (one_c * yz) - xs;
00223    
00224    m[6] = (one_c * zx) - ys;
00225    m[7] = (one_c * yz) + xs;
00226    m[8] = (one_c * zz) + c;
00227 }
00228 
00229 // multiply vector v by a 3x3 matrix m stored so that m(row,col) = m[row*3+col]
00230 Vector mat_multiply_vec(const Vector &v, BigReal m[]) {
00231       return Vector( m[0]*v.x + m[1]*v.y + m[2]*v.z,
00232                      m[3]*v.x + m[4]*v.y + m[5]*v.z,
00233                      m[6]*v.x + m[7]*v.y + m[8]*v.z );
00234 }
00235 

Generated on Mon Oct 13 04:07:42 2008 for NAMD by  doxygen 1.3.9.1