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

GlobalMasterSymmetry.C

Go to the documentation of this file.
00001 
00007 #include "InfoStream.h"
00008 #include "Node.h"
00009 #include "Molecule.h"
00010 #include "NamdTypes.h"
00011 
00012 #include "SimParameters.h"
00013 #include "GlobalMasterSymmetry.h"
00014 #include "PDB.h"
00015 #include "PDBData.h"
00016 #include "fitrms.h"
00017 #include <fstream>
00018 #include <sstream>
00019 #include <algorithm>
00020 #include <iterator>
00021 #include <stdlib.h>
00022 //#define DEBUGM
00023 #define MIN_DEBUG_LEVEL 1
00024 #include "Debug.h"
00025 //using namespace __gnu_cxx;
00026 using namespace std;
00027 //Read in and parse matrix file
00028 void GlobalMasterSymmetry::parseMatrix(int id, char fileName []){
00029   int count = 1;
00030   string line;
00031   ifstream matrixFile (fileName);
00032   if (matrixFile.is_open()){
00033     while (!matrixFile.eof()){
00034       vector <string> tmp;
00035       for (int i = 0; i < 4; i++){
00036       getline(matrixFile, line);
00037       istringstream iss(line);
00038       copy(istream_iterator<string>(iss),
00039             istream_iterator<string>(),
00040             back_inserter<vector <string>  >(tmp));
00041       }
00042       getline(matrixFile, line);
00043       Matrix4Symmetry tmpmatrix;
00044       if (tmp.size() < 16){NAMD_die("Error reading matrix file.  Please check layout of the matrix file(s).");}
00045       for(int j = 0; j < 16; j++){
00046         tmpmatrix.mat[j] = atof(tmp[j].c_str());
00047       }
00048       tmpmatrix.transpose();
00049       matrices.push_back(tmpmatrix);
00050       count++;
00051     }
00052     matrixFile.close();
00053   } 
00054 }
00055 GlobalMasterSymmetry::GlobalMasterSymmetry() {
00056   DebugM(3,"initialize called\n");
00057   SimParameters *params = Node::Object()->simParameters;
00058   currentStep = params->firstTimestep;
00059   firstStep = params->symmetryFirstStep;
00060   lastStep = params->symmetryLastStep;
00061   firstFullStep = params->symmetryFirstFullStep;
00062   lastFullStep = params->symmetryLastFullStep;
00063   K = params->symmetryk;
00064 
00065   StringList *klist = Node::Object()->configList->find("symmetrykfile");
00066   if (!K){
00067     //if (!params->symmetrykfile){NAMD_die("A pdb file containing per-atom force constants must be specified if symmetryk is not in configuration file!");}
00068     if (!klist){NAMD_die("A pdb file containing per-atom force constants must be specified if symmetryk is not in configuration file!");}
00069     //symmetrykfile = params->symmetrykfile;
00070   }
00071   scaleForces = params->symmetryScaleForces;
00072   if (scaleForces && lastStep == -1){
00073     NAMD_die("symmetryLastStep must be specified if symmetryScaleForces is enabled!");
00074   }
00075   StringList *matrixList = Node::Object()->configList->find("symmetryMatrixFile");
00076   StringList *symmetryList = Node::Object()->configList->find("symmetryFile");
00077   int symfileindex = 0;
00078   if (!K) {symmetrykfile = klist->data;}
00079   for (; symmetryList; symmetryList = symmetryList->next) {  
00080     parseAtoms(symmetryList->data, Node::Object()->molecule->numAtoms, symfileindex);
00081     if(!K){
00082       klist = klist->next;
00083      if (klist){ symmetrykfile = klist->data;}
00084     }
00085   }
00086 
00087   map<int, vector<int> >::iterator it = simmap.begin();
00088   if (!matrixList) {initialTransform();}
00089   for (; matrixList; matrixList = matrixList->next, ++it){
00090       parseMatrix(it->first, matrixList->data);
00091   }
00092 
00093   DebugM(1,"done with initialize\n");
00094 }
00095 
00096 //Aligns monomers based on transformation matrices
00097 //found in matrix file
00098 /*
00099 void GlobalMasterSymmetry::alignMonomers(){
00100   //this is assuming the matrices are written
00101   //in order of monomer id designation (0, 1, 2,..etc)
00102   map<int, vector<int> >::iterator simit = simmap.begin();
00103   for (; simit!=simmap.end(); ++simit){
00104     for(int x = 0; x < simit->second.size(); x++){
00105     map<int, vector<int> >::iterator mit = dmap.find(simit->second[x]);
00106     for (int i = 0; i < mit->second.size(); i++){
00107       map<int, BigReal *>::iterator it = posmap.find(mit->second[i]);
00108       matrices[(mit->first)-1].multpoint(it->second);
00109     }
00110   }
00111   }
00112 }
00113 */
00114 bool GlobalMasterSymmetry::gluInvertMatrix(const BigReal m[16], BigReal invOut[16])
00115 {
00116   BigReal inv[16], det;
00117   int i;
00118 
00119   inv[0] =   m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
00120   + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
00121   inv[4] =  -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
00122   - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
00123   inv[8] =   m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
00124   + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
00125   inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
00126   - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
00127   inv[1] =  -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
00128   - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
00129   inv[5] =   m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
00130   + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
00131   inv[9] =  -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
00132   - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
00133   inv[13] =  m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
00134   + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
00135   inv[2] =   m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
00136   + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
00137   inv[6] =  -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
00138   - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
00139   inv[10] =  m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
00140   + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
00141   inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
00142   - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
00143   inv[3] =  -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
00144   - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
00145   inv[7] =   m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
00146   + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
00147   inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
00148   - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
00149   inv[15] =  m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
00150   + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
00151 
00152   det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
00153   if (det == 0)
00154             return false;
00155 
00156             det = 1.0 / det;
00157 
00158             for (i = 0; i < 16; i++)
00159                       invOut[i] = inv[i] * det;
00160 
00161                       return true;
00162 }
00163 
00164 void GlobalMasterSymmetry::initialTransform(){
00165   map<int, vector<int> >::iterator simit = simmap.begin();
00166 
00167   for (; simit!=simmap.end(); ++simit){
00168   map<int, vector<int> >::iterator fit = dmap.find(simit->second[0]);
00169   BigReal * first = new BigReal [3*fit->second.size()];
00170   for(int i = 0; i < fit->second.size(); i++){
00171     map<int, BigReal *>::iterator sit = posmap.find(fit->second[i]);
00172     first[3*i] = sit->second[0];
00173     first[3*i+1] = sit->second[1];
00174     first[3*i+2] = sit->second[2];  
00175   }
00176 
00177   map<int, vector<int> >::iterator it = dmap.begin();
00178   for(; it != dmap.end(); ++it){
00179   if (std::find(simit->second.begin(), simit->second.end(), it->first)!=simit->second.end()){
00180   BigReal * arr = new BigReal [3*it->second.size()];
00181     for (int i = 0; i<it->second.size(); i++){
00182       map<int, BigReal *>::iterator sit = posmap.find(it->second[i]);
00183       arr[3*i] = sit->second[0];
00184       arr[3*i+1] = sit->second[1];
00185       arr[3*i+2] = sit->second[2];  
00186     }  
00187       BigReal ttt[16], pre[3], post[3];
00188       BigReal curRMS = MatrixFitRMS(it->second.size(), arr, first, NULL, ttt);
00189       int j;
00190       for (j=0; j<3; j++) {
00191         post[j] = ttt[4*j+3];
00192         ttt[4*j+3] = 0;
00193         pre[j] = ttt[12+j];
00194         ttt[12+j] = 0;
00195       }
00196       Matrix4Symmetry result;
00197       result.translate(pre);
00198       result.multmatrix(Matrix4Symmetry(ttt));
00199       result.translate(post);
00200       matrices.push_back(result);
00201 
00202       delete [] arr;
00203   }
00204   }
00205   delete [] first;
00206   }
00207 
00208   for (int i = 0; i < matrices.size(); i++) {
00209     matrices[i].transpose();
00210     //iout << "Matrix: " << i << " " << matrices[i].mat[0] << " " << matrices[i].mat[1] << " " << matrices[i].mat[2] << " "<<matrices[i].mat[3] << "\n";
00211     //iout << "Matrix: " << i << " " << matrices[i].mat[4] << " " << matrices[i].mat[5] << " " << matrices[i].mat[6] << " "<<matrices[i].mat[7] << "\n";  
00212     //iout << "Matrix: " << i << " " << matrices[i].mat[8] << " " << matrices[i].mat[9] << " " << matrices[i].mat[10] << " "<<matrices[i].mat[11] << "\n";
00213     //iout << "Matrix: " << i << " " << matrices[i].mat[12] << " " << matrices[i].mat[13] << " " << matrices[i].mat[14] << " "<<matrices[i].mat[15] << "\n";
00214     //iout <<"\n"<<endi;
00215     matrices[i].transpose();
00216   }
00217 }
00218 
00219 void GlobalMasterSymmetry::parseAtoms(const char *file, int numTotalAtoms, int symfileindex) {
00220   DebugM(3,"parseAtoms called\n");
00221   PDB tmdpdb(file);
00222   int numatoms = tmdpdb.num_atoms();
00223   if (numatoms < 1) 
00224     NAMD_die("No atoms found in symmetryFile\n");
00225   if (numatoms != numTotalAtoms)
00226     NAMD_die("The number of atoms in symmetryFile must be equal to the total number of atoms in the structure!");
00227  // if ( modifyRequestedAtoms().size() )
00228  //   NAMD_bug("GlobalMasterSymmetry::parseAtoms() modifyRequestedAtoms() not empty");
00229 
00230   Vector * atompos = new Vector[numatoms];  
00231   tmdpdb.get_all_positions(atompos);
00232   if (K){symmetrykfile = file;} 
00233   PDB kpdb(symmetrykfile);
00234 
00235   int i;
00236   for (i=0; i<numatoms; i++) {
00237 #ifdef MEM_OPT_VERSION
00238     PDBCoreData *atom = tmdpdb.atom(i);
00239 #else
00240     PDBAtom *atom = tmdpdb.atom(i); // get an atom from the file
00241 #endif
00242 
00243     if (atom->occupancy() && atom->temperaturefactor()) { // if occupancy and beta are not 0, then add it!
00244       // add the atom to the list
00245       modifyRequestedAtoms().add(i);
00246       if(!K){
00247         #ifdef MEM_OPT_VERSION
00248           PDBCoreData *atomk = kpdb.atom(i);
00249         #else
00250           PDBAtom *atomk = kpdb.atom(i); // get an atom from the file
00251         #endif 
00252         //kmap[i] = atomk->occupancy();
00253         kdmap[atom->temperaturefactor()][i] = atomk->occupancy();
00254       }
00255       BigReal *arr = new BigReal [3];
00256       arr[0] = atompos[i].x;
00257       arr[1] = atompos[i].y;
00258       arr[2] = atompos[i].z;
00259       posmap[i] = arr;
00260 
00261       bmap[atom->temperaturefactor()] = atom->occupancy();
00262         //check to see if monomer id is already in the map
00263       map <int, vector<int> >::iterator it = dmap.find((int)atom->temperaturefactor());
00264       map <int, vector<int> >::iterator simit = simmap.find((int)atom->occupancy());
00265       if (it != dmap.end()){
00266         it->second.push_back(i); //add atomid to vector in proper existing monomer id
00267       }
00268       else{
00269          dmap[(int)atom->temperaturefactor()] = vector <int> (1,i); //create new monomer id with atomid
00270       }
00271       if (simit != simmap.end()){
00272         if (std::find(simit->second.begin(), simit->second.end(), atom->temperaturefactor()) == simit->second.end()){
00273         simit->second.push_back(atom->temperaturefactor()); 
00274         }
00275       }
00276       else {
00277         simmap[(int)atom->occupancy()] = vector <int> (1, atom->temperaturefactor());
00278       }
00279     }
00280   }
00281 
00282    map <int, vector<int> >::iterator simit = simmap.begin();
00283    for (; simit != simmap.end(); ++simit){
00284     map <int, vector<int> >::iterator sit = dmap.find(simit->second[0]);
00285     int numatoms = sit->second.size();
00286     for (int i = 0; i<simit->second.size(); i++){
00287       map <int, vector<int> >::iterator fit = dmap.find(simit->second[i]);
00288       if (fit->second.size() != numatoms){
00289         NAMD_die("Every monomer must contain the same number of atoms!");
00290       }
00291     }
00292    }  
00293   delete [] atompos;
00294 }
00295 
00296 void GlobalMasterSymmetry::determineAverage() {
00297 
00298    map <int, vector<BigReal *> >::iterator delit = averagePos.begin();
00299    for (; delit != averagePos.end(); ++delit){
00300      for (int i = 0; i < delit->second.size(); i++){
00301        delete [] delit->second[i];
00302      }
00303      delit->second.erase(delit->second.begin(), delit->second.end());
00304    }
00305    //std::map <int, BigReal * > posmap;
00306    map <int, BigReal *>::iterator posit;
00307    map <int, vector<int> >::iterator simit = simmap.begin();
00308    for (; simit != simmap.end(); ++simit){     
00309     
00310 
00311     map <int, BigReal *>::iterator pit = posmap.begin();
00312     for (; pit != posmap.end(); ++pit){delete [] pit->second;}
00313     posmap.clear();
00314 
00315     map <int, vector<int> >::iterator dit = dmap.begin();
00316     for (; dit!=dmap.end(); ++dit){
00317       for (int i = 0; i < dit->second.size(); i++){
00318         if (std::find(simit->second.begin(), simit->second.end(), dit->first)!=simit->second.end()){
00319 
00320           BigReal* arr = new BigReal[3];
00321           arr[0] = positions[dit->second[i]].x;
00322           arr[1] = positions[dit->second[i]].y;
00323           arr[2] = positions[dit->second[i]].z;
00324 
00325           posmap[dit->second[i]] = arr;
00326         }
00327       } 
00328     }
00329     averagePos[simit->first] = vector <BigReal *> (); 
00330     map <int, vector<int> >::iterator it = dmap.begin();
00331     map <int, vector<int> >::iterator sit = dmap.find(simit->second[0]);
00332     int numatoms = sit->second.size();
00333     for (int i = 0; i < numatoms; i++){
00334        BigReal *arr = new BigReal [3];
00335       arr[0] = 0;
00336       arr[1] = 0;
00337       arr[2] = 0;
00338       for (; it!=dmap.end(); ++it){
00339         if (std::find(simit->second.begin(), simit->second.end(), it->first)!=simit->second.end()){
00340           posit = posmap.find(it->second[i]);
00341           matrices[(it->first)-1].multpoint(posit->second);
00342           arr[0] += posit->second[0];
00343           arr[1] += posit->second[1];
00344           arr[2] += posit->second[2];
00345         }
00346       }
00347       it = dmap.begin();
00348       BigReal *avg = new BigReal[3];
00349       avg[0] = arr[0]/(simit->second.size());
00350       avg[1] = arr[1]/(simit->second.size());
00351       avg[2] = arr[2]/(simit->second.size());
00352       averagePos[simit->first].push_back(avg);
00353       delete [] arr;
00354     }
00355     
00356    }
00357 
00358 }
00359 
00360 void GlobalMasterSymmetry::backTransform(){
00361   map <int, BigReal *>::iterator bit = backavg.begin();
00362   for (; bit != backavg.end(); ++bit){delete [] bit->second;}
00363   backavg.clear();
00364 
00365   map <int, vector<int> >::iterator it = dmap.begin();
00366   for (; it!=dmap.end(); ++it){
00367     map<int, int >::iterator bmit = bmap.find(it->first);
00368     int bm = bmit->second;
00369     map<int, vector <BigReal *> >::iterator avit = averagePos.find(bmit->second);
00370     int numatoms = it->second.size();
00371     BigReal *avg = new BigReal [3*numatoms];
00372     for (int i = 0; i < numatoms; i++){
00373       avg[3*i] = avit->second[i][0];
00374       avg[3*i+1] = avit->second[i][1];
00375       avg[3*i+2] = avit->second[i][2];
00376     }
00377     BigReal inverse[16];
00378     matrices[it->first-1].transpose();
00379     gluInvertMatrix(matrices[it->first-1].mat, inverse);
00380     Matrix4Symmetry inv(inverse);
00381     inv.transpose();
00382     matrices[it->first-1].transpose();
00383  
00384     for (int k = 0; k < numatoms; k++){
00385       inv.multpoint(avg+3*k);
00386     }
00387     backavg[it->first] = avg;
00388    }
00389 
00390 }
00391 GlobalMasterSymmetry::~GlobalMasterSymmetry() { 
00392   map <int, BigReal *>::iterator pit = posmap.begin();
00393   for (; pit != posmap.end(); ++pit){delete pit->second;}
00394 }
00395 void GlobalMasterSymmetry::calculate() {
00396   // have to reset my forces every time.  
00397   modifyAppliedForces().resize(0);
00398   modifyForcedAtoms().resize(0);
00399 
00400   // see if symmetry restraints should be active
00401   if (currentStep < firstStep || (currentStep >= lastStep && lastStep != -1)) {
00402     currentStep++;
00403     return;
00404   }
00405 
00406   //map<int, Position> positions;
00407   AtomIDList::const_iterator a_i = getAtomIdBegin();
00408   AtomIDList::const_iterator a_e = getAtomIdEnd();
00409   PositionList::const_iterator p_i = getAtomPositionBegin();
00410 
00411   //create mapping of positions now to avoid
00412   //going through these iterators for each domain
00413   for ( ; a_i != a_e; ++a_i, ++p_i ){
00414     positions[*a_i] = *p_i;
00415   }
00416 
00417   map <int, vector<int> >::iterator it;
00418   //map <int, BigReal *>::iterator pit = posmap.begin();
00419   //for (; pit != posmap.end(); ++pit){delete [] pit->second;}
00420 
00421  // posmap.clear();
00422   //for (it = dmap.begin(); it != dmap.end(); ++it){
00423     // fetch the current coordinates
00424     
00425     //for (int i = 0; i < it->second.size(); i++){
00426 
00427       //BigReal* arr = new BigReal[3];
00428       //arr[0] = positions[it->second[i]].x;
00429       //arr[1] = positions[it->second[i]].y;
00430       //arr[2] = positions[it->second[i]].z;
00431 
00432      // posmap[it->second[i]] = arr;
00433    // } 
00434 //}
00435 
00436 //  alignMonomers();
00437   determineAverage();
00438   backTransform();
00439 
00440   //iterate through all domains
00441   for (it = dmap.begin(); it != dmap.end(); ++it){
00442 
00443   // fetch the current coordinates
00444   BigReal *curpos = new BigReal[3*(it->second.size())];
00445   for (int i = 0; i < it->second.size(); i++){
00446     curpos[3*i  ] = positions[it->second[i]].x;
00447     curpos[3*i+1] = positions[it->second[i]].y;
00448     curpos[3*i+2] = positions[it->second[i]].z;  
00449   }
00450 
00451 
00452   BigReal *tmpavg = backavg[it->first];
00453 
00454   for (int i=0; i<it->second.size(); i++) {
00455     BigReal k; 
00456     if(!K){
00457      //k = kmap[it->second[i]];  
00458      k = kdmap[it->first][it->second[i]];
00459     }
00460     else{
00461      k = K/it->second.size();  
00462     }
00463     BigReal maxforce2 = 0.;
00464     BigReal frac = -k;
00465     if (scaleForces){
00466 
00467     if (currentStep < firstFullStep){
00468       BigReal linear_evolve = (BigReal(currentStep-firstStep)) /
00469                             (firstFullStep-firstStep);
00470       frac = frac*(linear_evolve);
00471     }
00472     if (currentStep > lastFullStep)
00473     {
00474       BigReal linear_evolve = (BigReal(currentStep-lastFullStep)) /
00475                             (lastStep-lastFullStep);
00476       frac = frac*(1-linear_evolve);
00477     }
00478 
00479     }
00480     BigReal dx = curpos[3*i  ] - tmpavg[3*i];
00481 //    iout << "DX: " << dx << "\n" << endi;
00482     BigReal dy = curpos[3*i+1] - tmpavg[3*i+1];
00483     BigReal dz = curpos[3*i+2] - tmpavg[3*i+2];
00484     BigReal fvec[3] = { dx, dy, dz };
00485     Vector force(fvec[0]*frac, fvec[1]*frac, fvec[2]*frac);
00486     modifyForcedAtoms().add(it->second[i]);
00487     modifyAppliedForces().add(force);
00488     BigReal force2 = force.length2();
00489     if ( force2 > maxforce2 ) maxforce2 = force2;
00490   } 
00491   delete [] curpos;
00492  }
00493    
00494   currentStep++;
00495 }

Generated on Fri May 25 04:07:15 2012 for NAMD by  doxygen 1.3.9.1