00001 #include <algorithm>
00002 #include "CompressPsf.h"
00003 #include "strlib.h"
00004 #include "Molecule.h"
00005 #include "Parameters.h"
00006 #include "SimParameters.h"
00007 #include "InfoStream.h"
00008 #include "UniqueSet.h"
00009 #include "UniqueSetIter.h"
00010
00011
00030
00031 Molecule *g_mol = NULL;
00032 Parameters *g_param = NULL;
00033 SimParameters *g_simParam = NULL;
00034 ConfigList *g_cfgList = NULL;
00035
00036 struct BasicAtomInfo
00037 {
00038 Index segNameIdx;
00039 Index resNameIdx;
00040 Index atomNameIdx;
00041 Index atomTypeIdx;
00042 Index chargeIdx;
00043 Index massIdx;
00044 Index atomSigIdx;
00045 Index exclSigIdx;
00046 int resID;
00047 };
00048
00049 typedef unsigned short SigIndex;
00050 struct AtomSigInfo
00051 {
00052 vector<SigIndex> bondSigIndices;
00053 vector<SigIndex> angleSigIndices;
00054 vector<SigIndex> dihedralSigIndices;
00055 vector<SigIndex> improperSigIndices;
00056 vector<SigIndex> crosstermSigIndices;
00057
00058 AtomSigInfo()
00059 {}
00060 AtomSigInfo(const AtomSigInfo& sig)
00061 {
00062 bondSigIndices.clear();
00063 for(int i=0; i<sig.bondSigIndices.size(); i++)
00064 bondSigIndices.push_back(sig.bondSigIndices[i]);
00065
00066 angleSigIndices.clear();
00067 for(int i=0; i<sig.angleSigIndices.size(); i++)
00068 angleSigIndices.push_back(sig.angleSigIndices[i]);
00069
00070 dihedralSigIndices.clear();
00071 for(int i=0; i<sig.dihedralSigIndices.size(); i++)
00072 dihedralSigIndices.push_back(sig.dihedralSigIndices[i]);
00073
00074 improperSigIndices.clear();
00075 for(int i=0; i<sig.improperSigIndices.size(); i++)
00076 improperSigIndices.push_back(sig.improperSigIndices[i]);
00077
00078 crosstermSigIndices.clear();
00079 for(int i=0; i<sig.crosstermSigIndices.size(); i++)
00080 crosstermSigIndices.push_back(sig.crosstermSigIndices[i]);
00081 }
00082
00083 ~AtomSigInfo()
00084 {
00085 bondSigIndices.clear();
00086 angleSigIndices.clear();
00087 dihedralSigIndices.clear();
00088 improperSigIndices.clear();
00089 crosstermSigIndices.clear();
00090 }
00091
00092 void sortTupleSigIndices()
00093 {
00094 sort(bondSigIndices.begin(), bondSigIndices.end());
00095 sort(angleSigIndices.begin(), angleSigIndices.end());
00096 sort(dihedralSigIndices.begin(), dihedralSigIndices.end());
00097 sort(improperSigIndices.begin(), improperSigIndices.end());
00098 sort(crosstermSigIndices.begin(), crosstermSigIndices.end());
00099 }
00100
00101 inline CkHashCode hash() const {
00102
00103
00104
00105
00106
00107
00108 const int maxlen = 32;
00109 unsigned char keydata[maxlen+1];
00110 const int maxchar = 256;
00111 int i,j;
00112 for(j=0;j<=maxlen;j++) keydata[j] = 0;
00113 j=0;
00114 for(i=0; i<bondSigIndices.size(); i++,j++) {
00115 keydata[j % maxlen] ^= (bondSigIndices[i] % maxchar);
00116 }
00117 for(i=0; i<angleSigIndices.size(); i++,j++) {
00118 keydata[j % maxlen] ^= (angleSigIndices[i] % maxchar);
00119 }
00120 for(i=0; i<dihedralSigIndices.size(); i++,j++) {
00121 keydata[j % maxlen] ^= (dihedralSigIndices[i] % maxchar);
00122 }
00123 for(i=0; i<improperSigIndices.size(); i++,j++) {
00124 keydata[j % maxlen] ^= (improperSigIndices[i] % maxchar);
00125 }
00126 for(i=0; i<crosstermSigIndices.size(); i++,j++) {
00127 keydata[j % maxlen] ^= (crosstermSigIndices[i] % maxchar);
00128 }
00129
00130 if (j > maxlen) j = maxlen;
00131
00132
00133
00134
00135
00136 return CkHashFunction_default((const void*)keydata,(size_t)j);
00137 }
00138 };
00139
00140 int operator==(const AtomSigInfo &s1, const AtomSigInfo& s2)
00141 {
00142 if(s1.bondSigIndices.size() != s2.bondSigIndices.size())
00143 return 0;
00144 if(s1.angleSigIndices.size() != s2.angleSigIndices.size())
00145 return 0;
00146 if(s1.dihedralSigIndices.size() != s2.dihedralSigIndices.size())
00147 return 0;
00148 if(s1.improperSigIndices.size() != s2.improperSigIndices.size())
00149 return 0;
00150 if(s1.crosstermSigIndices.size() != s2.crosstermSigIndices.size())
00151 return 0;
00152
00153 int equalCnt;
00154 equalCnt=0;
00155 int bondSigCnt = s1.bondSigIndices.size();
00156 for(int i=0; i<bondSigCnt; i++)
00157 equalCnt += (s1.bondSigIndices[i]==s2.bondSigIndices[i]);
00158 if(equalCnt!=bondSigCnt)
00159 return 0;
00160
00161 equalCnt=0;
00162 int angleSigCnt = s1.angleSigIndices.size();
00163 for(int i=0; i<angleSigCnt; i++)
00164 equalCnt += (s1.angleSigIndices[i]==s2.angleSigIndices[i]);
00165 if(equalCnt!=angleSigCnt)
00166 return 0;
00167
00168 equalCnt=0;
00169 int dihedralSigCnt = s1.dihedralSigIndices.size();
00170 for(int i=0; i<dihedralSigCnt; i++)
00171 equalCnt += (s1.dihedralSigIndices[i]==s2.dihedralSigIndices[i]);
00172 if(equalCnt!=dihedralSigCnt)
00173 return 0;
00174
00175 equalCnt=0;
00176 int improperSigCnt = s1.improperSigIndices.size();
00177 for(int i=0; i<improperSigCnt; i++)
00178 equalCnt += (s1.improperSigIndices[i]==s2.improperSigIndices[i]);
00179 if(equalCnt!=improperSigCnt)
00180 return 0;
00181
00182 equalCnt=0;
00183 int crosstermSigCnt = s1.crosstermSigIndices.size();
00184 for(int i=0; i<crosstermSigCnt; i++)
00185 equalCnt += (s1.crosstermSigIndices[i]==s2.crosstermSigIndices[i]);
00186 if(equalCnt!=crosstermSigCnt)
00187 return 0;
00188
00189 return 1;
00190 }
00191
00192 struct ExclSigInfo
00193 {
00194 vector<int> fullExclOffset;
00195 vector<int> modExclOffset;
00196
00197 ExclSigInfo()
00198 {}
00199 ExclSigInfo(const ExclSigInfo& sig)
00200 {
00201 fullExclOffset.clear();
00202 for(int i=0; i<sig.fullExclOffset.size(); i++)
00203 fullExclOffset.push_back(sig.fullExclOffset[i]);
00204
00205 modExclOffset.clear();
00206 for(int i=0; i<sig.modExclOffset.size(); i++)
00207 modExclOffset.push_back(sig.modExclOffset[i]);
00208 }
00209
00210 ~ExclSigInfo()
00211 {
00212 fullExclOffset.clear();
00213 modExclOffset.clear();
00214 }
00215
00216 void sortExclOffset()
00217 {
00218 sort(fullExclOffset.begin(), fullExclOffset.end());
00219 sort(modExclOffset.begin(), modExclOffset.end());
00220 }
00221
00222 int hash() const {
00223 unsigned int code = 0x1234;
00224 unsigned int codesz = 8 * sizeof(int);
00225 const unsigned int numFoffset = fullExclOffset.size();
00226 const unsigned int numMoffset = modExclOffset.size();
00227 const unsigned int numOffsets = numFoffset + numMoffset;
00228
00229
00230 if (numOffsets == 0)
00231 return 0;
00232
00233 unsigned int shift = codesz / numOffsets;
00234 if (shift == 0) shift=1;
00235 unsigned int i;
00236 for(i=0; i < numFoffset; i++) {
00237 code = circShift(code,shift);
00238 code ^= fullExclOffset[i];
00239 }
00240 for(i=0; i < numMoffset; i++) {
00241 code = circShift(code,shift);
00242 code ^= modExclOffset[i];
00243 }
00244 return code;
00245 }
00246 };
00247 int operator==(const ExclSigInfo &s1, const ExclSigInfo &s2)
00248 {
00249 if(s1.fullExclOffset.size()!=s2.fullExclOffset.size())
00250 return 0;
00251 if(s1.modExclOffset.size()!=s2.modExclOffset.size())
00252 return 0;
00253
00254 for(int i=0; i<s1.fullExclOffset.size(); i++)
00255 {
00256 if(s1.fullExclOffset[i] != s2.fullExclOffset[i])
00257 return 0;
00258 }
00259
00260 for(int i=0; i<s1.modExclOffset.size(); i++)
00261 {
00262 if(s1.modExclOffset[i] != s2.modExclOffset[i])
00263 return 0;
00264 }
00265 return 1;
00266 }
00267
00268 class HashString : public string {
00269 public:
00270 int hash() const {
00271 const char* d = this->c_str();
00272 int ret=0;
00273 for (int i=0;d[i]!=0;i++) {
00274 int shift1=((5*i)%16)+0;
00275 int shift2=((6*i)%16)+8;
00276 ret+=((0xa5^d[i])<<shift2)+(d[i]<<shift1);
00277 }
00278 return ret;
00279 }
00280 };
00281
00282 class HashReal {
00283 Real val;
00284 public:
00285 HashReal(Real v) : val(v) {}
00286 operator Real & () { return val; }
00287 operator const Real & () const { return val; }
00288
00289 int hash() const {
00290 const char* d = (const char *)&val;
00291 int ret=0;
00292 for (int i=0;i < sizeof(Real);i++) {
00293 int shift1=((5*i)%16)+0;
00294 int shift2=((6*i)%16)+8;
00295 ret+=((0xa5^d[i])<<shift2)+(d[i]<<shift1);
00296 }
00297 return ret;
00298 };
00299 };
00300
00301 HashPool<HashString> segNamePool;
00302 HashPool<HashString> resNamePool;
00303 HashPool<HashString> atomNamePool;
00304 HashPool<HashString> atomTypePool;
00305 HashPool<HashReal> chargePool;
00306 HashPool<HashReal> massPool;
00307 HashPool<AtomSigInfo> atomSigPool;
00308 BasicAtomInfo *atomData;
00309
00310
00311 int *eachAtomClusterID = NULL;
00312 vector<int> eachClusterSize;
00313 int g_numClusters = 0;
00314
00315 int g_isClusterContiguous = 0;
00316
00317 HashPool<TupleSignature> sigsOfBonds;
00318 HashPool<TupleSignature> sigsOfAngles;
00319 HashPool<TupleSignature> sigsOfDihedrals;
00320 HashPool<TupleSignature> sigsOfImpropers;
00321 HashPool<TupleSignature> sigsOfCrossterms;
00322 AtomSigInfo *eachAtomSigs;
00323
00324 HashPool<ExclSigInfo> sigsOfExclusions;
00325 ExclSigInfo *eachAtomExclSigs;
00326
00327
00328 vector<Bond> extraBonds;
00329 vector<Angle> extraAngles;
00330 vector<Dihedral> extraDihedrals;
00331 vector<Improper> extraImpropers;
00332
00333 vector<BondValue> extraBondParams;
00334 vector<AngleValue> extraAngleParams;
00335 vector<DihedralValue> extraDihedralParams;
00336 vector<ImproperValue> extraImproperParams;
00337
00338 int operator==(const BondValue &b1, const BondValue &b2)
00339 {
00340 return (b1.k==b2.k) && (b1.x0==b2.x0);
00341 }
00342
00343 int operator==(const AngleValue &a1, const AngleValue &a2)
00344 {
00345 return (a1.k==a2.k) && (a1.k_ub==a2.k_ub) && (a1.r_ub==a2.r_ub) && (a1.theta0==a2.theta0);
00346 }
00347
00348 int operator!=(const FourBodyConsts& f1, const FourBodyConsts& f2)
00349 {
00350 return (f1.delta!=f2.delta) || (f1.k!=f2.k) || (f1.n!=f2.n);
00351 }
00352
00353 int operator==(const DihedralValue &d1, const DihedralValue &d2)
00354 {
00355 if(d1.multiplicity != d2.multiplicity)
00356 return 0;
00357 for(int i=0; i<MAX_MULTIPLICITY; i++)
00358 {
00359 if(d1.values[i] != d2.values[i])
00360 return 0;
00361 }
00362 return 1;
00363 }
00364
00365 int operator==(const ImproperValue &d1, const ImproperValue &d2)
00366 {
00367 if(d1.multiplicity != d2.multiplicity)
00368 return 0;
00369 for(int i=0; i<MAX_MULTIPLICITY; i++)
00370 {
00371 if(d1.values[i] != d2.values[i])
00372 return 0;
00373 }
00374 return 1;
00375 }
00376
00377 void readPsfFile(char *psfFileName);
00378 void loadMolInfo();
00379
00380 void integrateAllAtomSigs();
00381 void outputPsfFile(FILE *ofp);
00382 void outputCompressedFile(FILE *txtOfp, FILE *binOfp);
00383
00384
00385 void getExtraBonds(StringList *file);
00386
00387
00388 void getAtomData(FILE *ifp);
00389 void getBondData(FILE *ifp);
00390 void getAngleData(FILE *ifp);
00391 void getDihedralData(FILE *ifp);
00392 void getImproperData(FILE *ifp);
00393 void getDonorData(FILE *ifp);
00394 void getAcceptorData(FILE *ifp);
00395 void getExclusionData(FILE *ifp);
00396 void getCrosstermData(FILE *ifp);
00397
00398 void buildAtomData();
00399 void buildBondData();
00400 void buildAngleData();
00401 void buildDihedralData();
00402 void buildImproperData();
00403 void buildCrosstermData();
00404
00405 void buildExclusionData();
00406 void buildParamData();
00407
00408
00409 void buildExclusions();
00410 void build12Excls(UniqueSet<Exclusion>&, vector<int> *);
00411 void build13Excls(UniqueSet<Exclusion>&, vector<int> *);
00412 void build14Excls(UniqueSet<Exclusion>&, vector<int> *, int);
00413
00414
00415 void flipNum(char *elem, int elemSize, int numElems){
00416 int mid = elemSize/2;
00417 char *ptr = elem;
00418 for(int i=0; i<numElems; i++) {
00419 for(int j=0; j<mid; j++) {
00420 char tmp = ptr[j];
00421 ptr[j] = ptr[elemSize-1-j];
00422 ptr[elemSize-1-j] = tmp;
00423 }
00424 ptr += elemSize;
00425 }
00426 }
00427
00428 void clearGlobalVectors()
00429 {
00430 segNamePool.clear();
00431 resNamePool.clear();
00432 atomNamePool.clear();
00433 atomTypePool.clear();
00434 chargePool.clear();
00435 massPool.clear();
00436 sigsOfBonds.clear();
00437 sigsOfAngles.clear();
00438 sigsOfDihedrals.clear();
00439 sigsOfImpropers.clear();
00440 sigsOfExclusions.clear();
00441
00442 eachClusterSize.clear();
00443 }
00444
00445 void compress_psf_file(Molecule *mol, char *psfFileName, Parameters *param, SimParameters *simParam, ConfigList *cfgList)
00446 {
00447
00448 g_mol = mol;
00449 g_param = param;
00450 g_simParam = simParam;
00451 g_cfgList = cfgList;
00452
00453
00454 readPsfFile(psfFileName);
00455
00456 integrateAllAtomSigs();
00457
00458 buildExclusions();
00459
00460
00461 char *outFileName = new char[strlen(psfFileName)+10];
00462 sprintf(outFileName, "%s.inter", psfFileName);
00463 FILE *ofp = fopen(outFileName, "w");
00464 delete [] outFileName;
00465
00466 outputPsfFile(ofp);
00467 fclose(ofp);
00468 }
00469
00470 void compress_molecule_info(Molecule *mol, char *psfFileName, Parameters *param, SimParameters *simParam, ConfigList* cfgList)
00471 {
00472 g_mol = mol;
00473 g_param = param;
00474 g_simParam = simParam;
00475 g_cfgList = cfgList;
00476
00477
00478
00479 loadMolInfo();
00480
00481 integrateAllAtomSigs();
00482
00483 buildExclusions();
00484
00485
00486
00487 char *outFileName = new char[strlen(psfFileName)+20];
00488 sprintf(outFileName, "%s.inter", psfFileName);
00489
00490 FILE *txtOfp = fopen(outFileName, "w");
00491 sprintf(outFileName, "%s.inter.bin", psfFileName);
00492
00493 FILE *binOfp = fopen(outFileName, "wb");
00494 delete [] outFileName;
00495
00496
00497 outputCompressedFile(txtOfp, binOfp);
00498
00499 fclose(txtOfp);
00500 fclose(binOfp);
00501 }
00502
00503
00504 void readPsfFile(char *fname)
00505 {
00506 char err_msg[512];
00507 char buffer[512];
00508 int i;
00509 int NumTitle;
00510 int ret_code;
00511 FILE *psf_file;
00512 Parameters *params = g_param;
00513
00514
00515 if ( (psf_file = fopen(fname, "r")) == NULL)
00516 {
00517 sprintf(err_msg, "UNABLE TO OPEN .psf FILE %s", fname);
00518 NAMD_die(err_msg);
00519 }
00520
00521
00522 ret_code = NAMD_read_line(psf_file, buffer);
00523
00524 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00525 {
00526 ret_code = NAMD_read_line(psf_file, buffer);
00527 }
00528
00529
00530
00531 if (ret_code!=0)
00532 {
00533 sprintf(err_msg, "EMPTY .psf FILE %s", fname);
00534 NAMD_die(err_msg);
00535 }
00536
00537
00538
00539 if (!NAMD_find_word(buffer, "psf"))
00540 {
00541 sprintf(err_msg, "UNABLE TO FIND \"PSF\" STRING IN PSF FILE %s",
00542 fname);
00543 NAMD_die(err_msg);
00544 }
00545
00546
00547 ret_code = NAMD_read_line(psf_file, buffer);
00548
00549 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00550 {
00551 ret_code = NAMD_read_line(psf_file, buffer);
00552 }
00553
00554
00555
00556
00557 if (ret_code!=0)
00558 {
00559 sprintf(err_msg, "MISSING EVERYTHING BUT PSF FROM %s", fname);
00560 NAMD_die(err_msg);
00561 }
00562
00563
00564
00565 if (!NAMD_find_word(buffer, "NTITLE"))
00566 {
00567 sprintf(err_msg,"CAN NOT FIND \"NTITLE\" STRING IN PSF FILE %s",
00568 fname);
00569 NAMD_die(err_msg);
00570 }
00571
00572 sscanf(buffer, "%d", &NumTitle);
00573
00574
00575
00576 i=0;
00577
00578 while ( ((ret_code=NAMD_read_line(psf_file, buffer)) == 0) &&
00579 (i<NumTitle) )
00580 {
00581 if (!NAMD_blank_string(buffer))
00582 i++;
00583 }
00584
00585
00586 if (ret_code!=0)
00587 {
00588 sprintf(err_msg, "FOUND EOF INSTEAD OF NATOM IN PSF FILE %s",
00589 fname);
00590 NAMD_die(err_msg);
00591 }
00592
00593 while (NAMD_blank_string(buffer))
00594 {
00595 NAMD_read_line(psf_file, buffer);
00596 }
00597
00598
00599 if (!NAMD_find_word(buffer, "NATOM"))
00600 {
00601 sprintf(err_msg, "DIDN'T FIND \"NATOM\" IN PSF FILE %s",
00602 fname);
00603 NAMD_die(err_msg);
00604 }
00605
00606
00607 sscanf(buffer, "%d", &g_mol->numAtoms);
00608
00609 getAtomData(psf_file);
00610
00611
00612
00613 if(g_simParam->extraBondsOn)
00614 {
00615 getExtraBonds(g_cfgList->find("extraBondsFile"));
00616 }
00617
00618
00619 eachAtomSigs = new AtomSigInfo[g_mol->numAtoms];
00620
00621
00622 ret_code = NAMD_read_line(psf_file, buffer);
00623
00624 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00625 {
00626 ret_code = NAMD_read_line(psf_file, buffer);
00627 }
00628
00629
00630 if (ret_code != 0)
00631 {
00632 NAMD_die("EOF ENCOUNTERED LOOKING FOR NBONDS IN PSF");
00633 }
00634
00635
00636 if (!NAMD_find_word(buffer, "NBOND"))
00637 {
00638 NAMD_die("DID NOT FIND NBOND AFTER ATOM LIST IN PSF");
00639 }
00640
00641
00642 sscanf(buffer, "%d", &g_mol->numBonds);
00643
00644 if (g_mol->numBonds)
00645 getBondData(psf_file);
00646
00647
00648 ret_code = NAMD_read_line(psf_file, buffer);
00649
00650 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00651 {
00652 ret_code = NAMD_read_line(psf_file, buffer);
00653 }
00654
00655
00656 if (ret_code != 0)
00657 {
00658 NAMD_die("EOF ENCOUNTERED LOOKING FOR NTHETA IN PSF");
00659 }
00660
00661
00662 if (!NAMD_find_word(buffer, "NTHETA"))
00663 {
00664 NAMD_die("DID NOT FIND NTHETA AFTER BOND LIST IN PSF");
00665 }
00666
00667
00668 sscanf(buffer, "%d", &g_mol->numAngles);
00669
00670 if (g_mol->numAngles)
00671 getAngleData(psf_file);
00672
00673
00674 ret_code = NAMD_read_line(psf_file, buffer);
00675
00676 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00677 {
00678 ret_code = NAMD_read_line(psf_file, buffer);
00679 }
00680
00681
00682 if (ret_code != 0)
00683 {
00684 NAMD_die("EOF ENCOUNTERED LOOKING FOR NPHI IN PSF");
00685 }
00686
00687
00688 if (!NAMD_find_word(buffer, "NPHI"))
00689 {
00690 NAMD_die("DID NOT FIND NPHI AFTER ANGLE LIST IN PSF");
00691 }
00692
00693
00694 sscanf(buffer, "%d", &g_mol->numDihedrals);
00695
00696 if (g_mol->numDihedrals)
00697 getDihedralData(psf_file);
00698
00699
00700 ret_code = NAMD_read_line(psf_file, buffer);
00701
00702 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00703 {
00704 ret_code = NAMD_read_line(psf_file, buffer);
00705 }
00706
00707
00708 if (ret_code != 0)
00709 {
00710 NAMD_die("EOF ENCOUNTERED LOOKING FOR NIMPHI IN PSF");
00711 }
00712
00713
00714 if (!NAMD_find_word(buffer, "NIMPHI"))
00715 {
00716 NAMD_die("DID NOT FIND NIMPHI AFTER ATOM LIST IN PSF");
00717 }
00718
00719
00720 sscanf(buffer, "%d", &g_mol->numImpropers);
00721
00722 if (g_mol->numImpropers)
00723 getImproperData(psf_file);
00724
00725
00726 ret_code = NAMD_read_line(psf_file, buffer);
00727
00728 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00729 {
00730 ret_code = NAMD_read_line(psf_file, buffer);
00731 }
00732
00733
00734 if (ret_code != 0)
00735 {
00736 NAMD_die("EOF ENCOUNTERED LOOKING FOR NDON IN PSF");
00737 }
00738
00739
00740 if (!NAMD_find_word(buffer, "NDON"))
00741 {
00742 NAMD_die("DID NOT FIND NDON AFTER ATOM LIST IN PSF");
00743 }
00744
00745
00746 sscanf(buffer, "%d", &g_mol->numDonors);
00747
00748 if (g_mol->numDonors)
00749 getDonorData(psf_file);
00750
00751
00752 ret_code = NAMD_read_line(psf_file, buffer);
00753
00754 while ( (ret_code==0) && (NAMD_blank_string(buffer)) )
00755 {
00756 ret_code = NAMD_read_line(psf_file, buffer);
00757 }
00758
00759
00760 if (ret_code != 0)
00761 {
00762 NAMD_die("EOF ENCOUNTERED LOOKING FOR NACC IN PSF");
00763 }
00764
00765
00766 if (!NAMD_find_word(buffer, "NACC"))
00767 {
00768 NAMD_die("DID NOT FIND NACC AFTER ATOM LIST IN PSF");
00769 }
00770
00771
00772 sscanf(buffer, "%d", &g_mol->numAcceptors);
00773
00774 if (g_mol->numAcceptors)
00775 getAcceptorData(psf_file);
00776
00777
00778 while (!NAMD_find_word(buffer, "NNB"))
00779 {
00780 ret_code = NAMD_read_line(psf_file, buffer);
00781
00782 if (ret_code != 0)
00783 {
00784 NAMD_die("EOF ENCOUNTERED LOOKING FOR NNB IN PSF FILE");
00785 }
00786 }
00787
00788
00789 sscanf(buffer, "%d", &g_mol->numExclusions);
00790
00791 if (g_mol->numExclusions)
00792 getExclusionData(psf_file);
00793
00794
00795 int crossterms_present = 1;
00796 while (!NAMD_find_word(buffer, "NCRTERM"))
00797 {
00798 ret_code = NAMD_read_line(psf_file, buffer);
00799
00800 if (ret_code != 0)
00801 {
00802
00803 crossterms_present = 0;
00804 break;
00805 }
00806 }
00807
00808 if ( crossterms_present)
00809 {
00810
00811
00812 sscanf(buffer, "%d", &g_mol->numCrossterms);
00813
00814 if (g_mol->numCrossterms)
00815 getCrosstermData(psf_file);
00816
00817 }
00818
00819
00820
00821
00822 fclose(psf_file);
00823 }
00824
00829 void loadMolInfo()
00830 {
00831 char err_msg[512];
00832 char buffer[512];
00833 int i;
00834 int NumTitle;
00835 int ret_code;
00836 FILE *psf_file;
00837 Parameters *params = g_param;
00838
00839 buildAtomData();
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 eachAtomSigs = new AtomSigInfo[g_mol->numAtoms];
00850
00851 if (g_mol->numBonds)
00852 buildBondData();
00853
00854 if (g_mol->numAngles)
00855 buildAngleData();
00856
00857 if (g_mol->numDihedrals)
00858 buildDihedralData();
00859
00860 if (g_mol->numImpropers)
00861 buildImproperData();
00862
00863 if (g_mol->numCrossterms)
00864 buildCrosstermData();
00865
00866
00867
00868 }
00869
00870 void integrateAllAtomSigs()
00871 {
00872 printf("Bond sigs: %d\n", (int)sigsOfBonds.size());
00873 printf("Angle sigs: %d\n", (int)sigsOfAngles.size());
00874 printf("Dihedral sigs: %d\n", (int)sigsOfDihedrals.size());
00875 printf("Improper sigs: %d\n", (int)sigsOfImpropers.size());
00876 printf("Crossterm sigs: %d\n", (int)sigsOfCrossterms.size());
00877
00878
00879 for(int i=0; i<g_mol->numAtoms; i++)
00880 {
00881 eachAtomSigs[i].sortTupleSigIndices();
00882 int poolIndex = atomSigPool.lookupCstPool(eachAtomSigs[i]);
00883 if(poolIndex==-1)
00884 {
00885 atomSigPool.push_back(eachAtomSigs[i]);
00886 poolIndex = atomSigPool.size()-1;
00887 }
00888 atomData[i].atomSigIdx = poolIndex;
00889 }
00890
00891 printf("Atom's sigs: %d\n", (int)atomSigPool.size());
00892
00893 delete[] eachAtomSigs;
00894 }
00895
00896 void outputPsfFile(FILE *ofp)
00897 {
00898 fprintf(ofp, "FORMAT VERSION: %f\n", COMPRESSED_PSF_VER);
00899
00900 fprintf(ofp, "%d !NSEGMENTNAMES\n", segNamePool.size());
00901 for(int i=0; i<segNamePool.size(); i++)
00902 {
00903 fprintf(ofp, "%s\n", segNamePool[i].c_str());
00904 }
00905
00906 fprintf(ofp, "%d !NRESIDUENAMES\n", resNamePool.size());
00907 for(int i=0; i<resNamePool.size(); i++)
00908 {
00909 fprintf(ofp, "%s\n", resNamePool[i].c_str());
00910 }
00911
00912 fprintf(ofp, "%d !NATOMNAMES\n", atomNamePool.size());
00913 for(int i=0; i<atomNamePool.size(); i++)
00914 {
00915 fprintf(ofp, "%s\n", atomNamePool[i].c_str());
00916 }
00917
00918 fprintf(ofp, "%d !NATOMTYPES\n", atomTypePool.size());
00919 for(int i=0; i<atomTypePool.size(); i++)
00920 {
00921 fprintf(ofp, "%s\n", atomTypePool[i].c_str());
00922 }
00923
00924 fprintf(ofp, "%d !NCHARGES\n", chargePool.size());
00925 for(int i=0; i<chargePool.size(); i++)
00926 {
00927 const Real charge = chargePool[i];
00928 fprintf(ofp, "%f\n", charge);
00929 }
00930
00931 fprintf(ofp, "%d !NMASSES\n", massPool.size());
00932 for(int i=0; i<massPool.size(); i++)
00933 {
00934 const Real mass = massPool[i];
00935 fprintf(ofp, "%f\n", mass);
00936 }
00937
00938
00939 fprintf(ofp, "%d !NATOMSIGS\n", atomSigPool.size());
00940 for(int i=0; i<atomSigPool.size(); i++)
00941 {
00942 AtomSigInfo& oneAtomSig = atomSigPool[i];
00943 int oneTypeCnt = oneAtomSig.bondSigIndices.size();
00944 fprintf(ofp, "%d !%sSIGS\n", oneTypeCnt, "NBOND");
00945 for(int j=0; j<oneTypeCnt; j++)
00946 {
00947 SigIndex idx = oneAtomSig.bondSigIndices[j];
00948 TupleSignature& tSig = sigsOfBonds[idx];
00949 tSig.output(ofp);
00950 }
00951
00952 oneTypeCnt = oneAtomSig.angleSigIndices.size();
00953 fprintf(ofp, "%d !%sSIGS\n", oneTypeCnt, "NTHETA");
00954 for(int j=0; j<oneTypeCnt; j++)
00955 {
00956 SigIndex idx = oneAtomSig.angleSigIndices[j];
00957 TupleSignature& tSig = sigsOfAngles[idx];
00958 tSig.output(ofp);
00959 }
00960
00961 oneTypeCnt = oneAtomSig.dihedralSigIndices.size();
00962 fprintf(ofp, "%d !%sSIGS\n", oneTypeCnt, "NPHI");
00963 for(int j=0; j<oneTypeCnt; j++)
00964 {
00965 SigIndex idx = oneAtomSig.dihedralSigIndices[j];
00966 TupleSignature& tSig = sigsOfDihedrals[idx];
00967 tSig.output(ofp);
00968 }
00969
00970 oneTypeCnt = oneAtomSig.improperSigIndices.size();
00971 fprintf(ofp, "%d !%sSIGS\n", oneTypeCnt, "NIMPHI");
00972 for(int j=0; j<oneTypeCnt; j++)
00973 {
00974 SigIndex idx = oneAtomSig.improperSigIndices[j];
00975 TupleSignature& tSig = sigsOfImpropers[idx];
00976 tSig.output(ofp);
00977 }
00978
00979 oneTypeCnt = oneAtomSig.crosstermSigIndices.size();
00980 fprintf(ofp, "%d !%sSIGS\n", oneTypeCnt, "NCRTERM");
00981 for(int j=0; j<oneTypeCnt; j++)
00982 {
00983 SigIndex idx = oneAtomSig.crosstermSigIndices[j];
00984 TupleSignature& tSig = sigsOfCrossterms[idx];
00985 tSig.output(ofp);
00986 }
00987 }
00988
00989
00990 int exclSigCnt = sigsOfExclusions.size();
00991 fprintf(ofp, "%d !NEXCLSIGS\n", exclSigCnt);
00992 for(int i=0; i<exclSigCnt; i++)
00993 {
00994 ExclSigInfo *sig = &sigsOfExclusions[i];
00995
00996 fprintf(ofp, "%d", sig->fullExclOffset.size());
00997 for(int j=0; j<sig->fullExclOffset.size(); j++)
00998 fprintf(ofp, " %d", sig->fullExclOffset[j]);
00999 fprintf(ofp, "\n");
01000
01001
01002 fprintf(ofp, "%d", sig->modExclOffset.size());
01003 for(int j=0; j<sig->modExclOffset.size(); j++)
01004 fprintf(ofp, " %d", sig->modExclOffset[j]);
01005 fprintf(ofp, "\n");
01006 }
01007
01008
01009 fprintf(ofp, "%d !NCLUSTERS\n", g_numClusters);
01010 fprintf(ofp, "%d !CLUSTERCONTIGUITY\n", g_isClusterContiguous);
01011
01012
01013 fprintf(ofp, "%d !NATOM\n", g_mol->numAtoms);
01014 const float *atomOccupancy = g_mol->getOccupancyData();
01015 const float *atomBFactor = g_mol->getBFactorData();
01016 fprintf(ofp, "%d !OCCUPANCYVALID\n", (atomOccupancy==NULL)?0:1);
01017 fprintf(ofp, "%d !TEMPFACTORVALID\n", (atomBFactor==NULL)?0:1);
01018
01019 float *zeroFloats = NULL;
01020 if(atomOccupancy==NULL || atomBFactor==NULL) {
01021 zeroFloats = new float[g_mol->numAtoms];
01022 memcpy(zeroFloats, 0, sizeof(float)*g_mol->numAtoms);
01023 if(atomOccupancy==NULL) atomOccupancy = (const float *)zeroFloats;
01024 if(atomBFactor==NULL) atomBFactor = (const float *)zeroFloats;
01025 }
01026
01027 for(int i=0; i<g_mol->numAtoms; i++)
01028 {
01029 BasicAtomInfo &one = atomData[i];
01030 fprintf(ofp, "%d %d %d %d %d %d %d %d %d %d %f %f\n", one.segNameIdx, one.resID, one.resNameIdx, one.atomNameIdx,
01031 one.atomTypeIdx, one.chargeIdx, one.massIdx, one.atomSigIdx, one.exclSigIdx,
01032 eachAtomClusterID[i], atomOccupancy[i], atomBFactor[i]);
01033 }
01034
01035
01036 if(zeroFloats) delete[] zeroFloats;
01037 delete[] atomData;
01038 delete[] eachAtomClusterID;
01039
01040
01041 if(g_simParam->extraBondsOn)
01042 {
01043
01044 int numExtraParams = extraBondParams.size();
01045 fprintf(ofp, "%d!NEXTRABONDPARAMS\n", numExtraParams);
01046 if(numExtraParams>0)
01047 {
01048 vector<BondValue>::iterator bpIter;
01049 for(bpIter=extraBondParams.begin(); bpIter!=extraBondParams.end(); bpIter++)
01050 {
01051 fprintf(ofp, "%f %f\n", bpIter->k, bpIter->x0);
01052 }
01053 }
01054
01055
01056 numExtraParams = extraAngleParams.size();
01057 fprintf(ofp, "%d!NEXTRAANGLEPARAMS\n", numExtraParams);
01058 if(numExtraParams>0)
01059 {
01060 vector<AngleValue>::iterator apIter;
01061 for(apIter=extraAngleParams.begin(); apIter!=extraAngleParams.end(); apIter++)
01062 {
01063 fprintf(ofp, "%f %f %f %f\n", apIter->k, apIter->theta0, apIter->k_ub, apIter->r_ub);
01064 }
01065 }
01066
01067
01068 numExtraParams = extraDihedralParams.size();
01069 fprintf(ofp, "%d!NEXTRADIHEDRALPARAMS\n", numExtraParams);
01070 if(numExtraParams>0)
01071 {
01072 vector<DihedralValue>::iterator dpIter;
01073 for(dpIter=extraDihedralParams.begin(); dpIter!=extraDihedralParams.end(); dpIter++)
01074 {
01075 fprintf(ofp, "%d\n", dpIter->multiplicity);
01076 for(int i=0; i<dpIter->multiplicity; i++) {
01077 fprintf(ofp, "%f %d %f\n", dpIter->values[i].k, dpIter->values[i].n, dpIter->values[i].delta);
01078 }
01079 }
01080 }
01081
01082
01083 numExtraParams = extraImproperParams.size();
01084 fprintf(ofp, "%d!NEXTRAIMPROPERPARAMS\n", numExtraParams);
01085 if(numExtraParams>0)
01086 {
01087 vector<ImproperValue>::iterator ipIter;
01088 for(ipIter=extraImproperParams.begin(); ipIter!=extraImproperParams.end(); ipIter++)
01089 {
01090 fprintf(ofp, "%d\n", ipIter->multiplicity);
01091 for(int i=0; i<ipIter->multiplicity; i++) {
01092 fprintf(ofp, "%f %d %f\n", ipIter->values[i].k, ipIter->values[i].n, ipIter->values[i].delta);
01093 }
01094 }
01095 }
01096 }
01097
01098
01099 fprintf(ofp, "!DIHEDRALPARAMARRAY\n");
01100 for(int i=0; i<g_param->NumDihedralParams; i++)
01101 {
01102 fprintf(ofp, "%d ", g_param->dihedral_array[i].multiplicity);
01103 }
01104 fprintf(ofp, "\n");
01105 fprintf(ofp, "!IMPROPERPARAMARRAY\n");
01106 for(int i=0; i<g_param->NumImproperParams; i++)
01107 {
01108 fprintf(ofp, "%d ", g_param->improper_array[i].multiplicity);
01109 }
01110 fprintf(ofp, "\n");
01111 }
01112
01142 void outputCompressedFile(FILE *txtOfp, FILE *binOfp)
01143 {
01144 #ifndef MEM_OPT_VERSION
01145 fprintf(txtOfp, "FORMAT VERSION: %f\n", COMPRESSED_PSF_VER);
01146
01147 fprintf(txtOfp, "%d !NSEGMENTNAMES\n", segNamePool.size());
01148 for(int i=0; i<segNamePool.size(); i++)
01149 {
01150 fprintf(txtOfp, "%s\n", segNamePool[i].c_str());
01151 }
01152
01153 fprintf(txtOfp, "%d !NRESIDUENAMES\n", resNamePool.size());
01154 for(int i=0; i<resNamePool.size(); i++)
01155 {
01156 fprintf(txtOfp, "%s\n", resNamePool[i].c_str());
01157 }
01158
01159 fprintf(txtOfp, "%d !NATOMNAMES\n", atomNamePool.size());
01160 for(int i=0; i<atomNamePool.size(); i++)
01161 {
01162 fprintf(txtOfp, "%s\n", atomNamePool[i].c_str());
01163 }
01164
01165 fprintf(txtOfp, "%d !NATOMTYPES\n", atomTypePool.size());
01166 for(int i=0; i<atomTypePool.size(); i++)
01167 {
01168 fprintf(txtOfp, "%s\n", atomTypePool[i].c_str());
01169 }
01170
01171 fprintf(txtOfp, "%d !NCHARGES\n", chargePool.size());
01172 for(int i=0; i<chargePool.size(); i++)
01173 {
01174 const Real charge = chargePool[i];
01175 fprintf(txtOfp, "%f\n", charge);
01176 }
01177
01178 fprintf(txtOfp, "%d !NMASSES\n", massPool.size());
01179 for(int i=0; i<massPool.size(); i++)
01180 {
01181 const Real mass = massPool[i];
01182 fprintf(txtOfp, "%f\n", mass);
01183 }
01184
01185
01186 fprintf(txtOfp, "%d !NATOMSIGS\n", atomSigPool.size());
01187 for(int i=0; i<atomSigPool.size(); i++)
01188 {
01189 AtomSigInfo& oneAtomSig = atomSigPool[i];
01190 int oneTypeCnt = oneAtomSig.bondSigIndices.size();
01191 fprintf(txtOfp, "%d !%sSIGS\n", oneTypeCnt, "NBOND");
01192 for(int j=0; j<oneTypeCnt; j++)
01193 {
01194 SigIndex idx = oneAtomSig.bondSigIndices[j];
01195 TupleSignature& tSig = sigsOfBonds[idx];
01196 tSig.output(txtOfp);
01197 }
01198
01199 oneTypeCnt = oneAtomSig.angleSigIndices.size();
01200 fprintf(txtOfp, "%d !%sSIGS\n", oneTypeCnt, "NTHETA");
01201 for(int j=0; j<oneTypeCnt; j++)
01202 {
01203 SigIndex idx = oneAtomSig.angleSigIndices[j];
01204 TupleSignature& tSig = sigsOfAngles[idx];
01205 tSig.output(txtOfp);
01206 }
01207
01208 oneTypeCnt = oneAtomSig.dihedralSigIndices.size();
01209 fprintf(txtOfp, "%d !%sSIGS\n", oneTypeCnt, "NPHI");
01210 for(int j=0; j<oneTypeCnt; j++)
01211 {
01212 SigIndex idx = oneAtomSig.dihedralSigIndices[j];
01213 TupleSignature& tSig = sigsOfDihedrals[idx];
01214 tSig.output(txtOfp);
01215 }
01216
01217 oneTypeCnt = oneAtomSig.improperSigIndices.size();
01218 fprintf(txtOfp, "%d !%sSIGS\n", oneTypeCnt, "NIMPHI");
01219 for(int j=0; j<oneTypeCnt; j++)
01220 {
01221 SigIndex idx = oneAtomSig.improperSigIndices[j];
01222 TupleSignature& tSig = sigsOfImpropers[idx];
01223 tSig.output(txtOfp);
01224 }
01225
01226 oneTypeCnt = oneAtomSig.crosstermSigIndices.size();
01227 fprintf(txtOfp, "%d !%sSIGS\n", oneTypeCnt, "NCRTERM");
01228 for(int j=0; j<oneTypeCnt; j++)
01229 {
01230 SigIndex idx = oneAtomSig.crosstermSigIndices[j];
01231 TupleSignature& tSig = sigsOfCrossterms[idx];
01232 tSig.output(txtOfp);
01233 }
01234 }
01235
01236
01237 int exclSigCnt = sigsOfExclusions.size();
01238 fprintf(txtOfp, "%d !NEXCLSIGS\n", exclSigCnt);
01239 for(int i=0; i<exclSigCnt; i++)
01240 {
01241 ExclSigInfo *sig = &sigsOfExclusions[i];
01242
01243 fprintf(txtOfp, "%d", sig->fullExclOffset.size());
01244 for(int j=0; j<sig->fullExclOffset.size(); j++)
01245 fprintf(txtOfp, " %d", sig->fullExclOffset[j]);
01246 fprintf(txtOfp, "\n");
01247
01248
01249 fprintf(txtOfp, "%d", sig->modExclOffset.size());
01250 for(int j=0; j<sig->modExclOffset.size(); j++)
01251 fprintf(txtOfp, " %d", sig->modExclOffset[j]);
01252 fprintf(txtOfp, "\n");
01253 }
01254
01255
01256 fprintf(txtOfp, "%d !NCLUSTERS\n", g_numClusters);
01257 fprintf(txtOfp, "%d !CLUSTERCONTIGUITY\n", g_isClusterContiguous);
01258
01259
01260 fprintf(txtOfp, "%d !NATOM\n", g_mol->numAtoms);
01261 fprintf(txtOfp, "%d !NHYDROGENGROUP\n", g_mol->numHydrogenGroups);
01262 const float *atomOccupancy = g_mol->getOccupancyData();
01263 const float *atomBFactor = g_mol->getBFactorData();
01264 fprintf(txtOfp, "%d !OCCUPANCYVALID\n", (atomOccupancy==NULL)?0:1);
01265 fprintf(txtOfp, "%d !TEMPFACTORVALID\n", (atomBFactor==NULL)?0:1);
01266
01267 float *zeroFloats = NULL;
01268 if(atomOccupancy==NULL || atomBFactor==NULL) {
01269 zeroFloats = new float[g_mol->numAtoms];
01270 memset(zeroFloats, 0, sizeof(float)*g_mol->numAtoms);
01271 if(atomOccupancy==NULL) atomOccupancy = (const float *)zeroFloats;
01272 if(atomBFactor==NULL) atomBFactor = (const float *)zeroFloats;
01273 }
01274
01275 Atom *atoms = g_mol->getAtoms();
01276 HydrogenGroupID *hg = g_mol->hydrogenGroup.begin();
01277
01278 #if BINARY_PERATOM_OUTPUT
01279
01280 int magicNum = COMPRESSED_PSF_MAGICNUM;
01281 fwrite(&magicNum, sizeof(int), 1, binOfp);
01282
01283 float verNum = (float)COMPRESSED_PSF_VER;
01284 fwrite(&verNum, sizeof(float), 1, binOfp);
01285
01286 Index sIdx[8];
01287 int iIdx[7];
01288 float tmpf[2];
01289 for(int i=0; i<g_mol->numAtoms; i++)
01290 {
01291 sIdx[0] = atomData[i].segNameIdx;
01292 sIdx[1] = atomData[i].resNameIdx;
01293 sIdx[2] = atomData[i].atomNameIdx;
01294 sIdx[3] = atomData[i].atomTypeIdx;
01295 sIdx[4] = atomData[i].chargeIdx;
01296 sIdx[5] = atomData[i].massIdx;
01297 sIdx[6] = atomData[i].atomSigIdx;
01298 sIdx[7] = atomData[i].exclSigIdx;
01299
01300 iIdx[0] = atomData[i].resID;
01301 iIdx[1] = eachAtomClusterID[i];
01302 iIdx[2] = atoms[i].partner;
01303 iIdx[3] = atoms[i].hydrogenList;
01304 iIdx[4] = hg[iIdx[3]].atomsInGroup;
01305 iIdx[5] = hg[iIdx[3]].GPID;
01306 iIdx[6] = hg[iIdx[3]].sortVal;
01307 tmpf[0] = atomOccupancy[i];
01308 tmpf[1] = atomBFactor[i];
01309 fwrite(sIdx, sizeof(Index), 8, binOfp);
01310 fwrite(iIdx, sizeof(int), 7, binOfp);
01311 fwrite(tmpf, sizeof(float), 2, binOfp);
01312 }
01313 #else
01314 for(int i=0; i<g_mol->numAtoms; i++)
01315 {
01316 BasicAtomInfo &one = atomData[i];
01317 int hgIdx = atoms[i].hydrogenList;
01318 fprintf(txtOfp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %f %f\n",
01319 one.segNameIdx, one.resNameIdx, one.atomNameIdx,
01320 one.atomTypeIdx, one.chargeIdx, one.massIdx, one.atomSigIdx, one.exclSigIdx, one.resID,
01321 eachAtomClusterID[i], atoms[i].partner, hgIdx,
01322 hg[hgIdx].atomsInGroup, hg[hgIdx].GPID, hg[hgIdx].sortVal,
01323 atomOccupancy[i], atomBFactor[i]);
01324 }
01325 #endif
01326
01327
01328 if(zeroFloats) delete[] zeroFloats;
01329 delete[] atoms;
01330 g_mol->hydrogenGroup.resize(0);
01331 delete[] atomData;
01332 delete[] eachAtomClusterID;
01333
01334
01335
01336
01337
01338
01339 fprintf(txtOfp, "!DIHEDRALPARAMARRAY\n");
01340 for(int i=0; i<g_param->NumDihedralParams; i++)
01341 {
01342 fprintf(txtOfp, "%d ", g_param->dihedral_array[i].multiplicity);
01343 }
01344 fprintf(txtOfp, "\n");
01345 fprintf(txtOfp, "!IMPROPERPARAMARRAY\n");
01346 for(int i=0; i<g_param->NumImproperParams; i++)
01347 {
01348 fprintf(txtOfp, "%d ", g_param->improper_array[i].multiplicity);
01349 }
01350 fprintf(txtOfp, "\n");
01351 #endif
01352 }
01353
01354 void getAtomData(FILE *ifp)
01355 {
01356 char buffer[512];
01357 int atomID=0;
01358 int lastAtomID=0;
01359 char segmentName[11];
01360 int residueID;
01361 char residueName[11];
01362 char atomName[11];
01363 char atomType[11];
01364 Real charge;
01365 Real mass;
01366 int fieldsCnt;
01367
01368 int numAtoms = g_mol->numAtoms;
01369
01370
01371 atomData = new BasicAtomInfo[numAtoms];
01372 while(atomID < numAtoms)
01373 {
01374 NAMD_read_line(ifp, buffer);
01375
01376 if(NAMD_blank_string(buffer) || buffer[0]=='!')
01377 continue;
01378
01379
01380
01381 fieldsCnt = sscanf(buffer, "%d %s %d %s %s %s %f %f",
01382 &atomID, segmentName, &residueID, residueName,
01383 atomName, atomType, &charge, &mass);
01384
01385
01386 if(fieldsCnt!=8)
01387 {
01388 char errMsg[128];
01389 sprintf(errMsg, "BAD ATOM LINE FORMAT IN PSF FILE FOR ATOM %d (%s)", lastAtomID+1, buffer);
01390 NAMD_die(errMsg);
01391 }
01392
01393
01394 int atomTypeNum;
01395 if(sscanf(atomType, "%d", &atomTypeNum)>0)
01396 NAMD_die("Structure (psf) file is either in CHARMM format (with numbers for atoms types, the X-PLOR format using names is required) or the segment name field is empty.");
01397
01398
01399 if(atomID!=lastAtomID+1)
01400 {
01401 char errMsg[128];
01402 sprintf(errMsg, "ATOM NUMBERS OUT OF ORDER AT ATOM #%d IN FSF FILE",
01403 lastAtomID+1);
01404 NAMD_die(errMsg);
01405 }
01406
01407 lastAtomID++;
01408
01409
01410 int poolIndex;
01411 HashString fieldName;
01412 fieldName.assign(segmentName);
01413 poolIndex = segNamePool.lookupCstPool(fieldName);
01414 if(poolIndex==-1)
01415 {
01416 segNamePool.push_back(fieldName);
01417 poolIndex = segNamePool.size()-1;
01418 }
01419 atomData[atomID-1].segNameIdx = poolIndex;
01420
01421
01422
01423
01424 atomData[atomID-1].resID = residueID;
01425
01426 fieldName.assign(residueName);
01427 poolIndex = resNamePool.lookupCstPool(fieldName);
01428 if(poolIndex==-1)
01429 {
01430 resNamePool.push_back(fieldName);
01431 poolIndex = resNamePool.size()-1;
01432 }
01433 atomData[atomID-1].resNameIdx = poolIndex;
01434
01435 fieldName.assign(atomName);
01436 poolIndex = atomNamePool.lookupCstPool(fieldName);
01437 if(poolIndex==-1)
01438 {
01439 atomNamePool.push_back(fieldName);
01440 poolIndex = atomNamePool.size()-1;
01441 }
01442 atomData[atomID-1].atomNameIdx = poolIndex;
01443
01444 fieldName.assign(atomType);
01445 poolIndex = atomTypePool.lookupCstPool(fieldName);
01446 if(poolIndex==-1)
01447 {
01448 atomTypePool.push_back(fieldName);
01449 poolIndex = atomTypePool.size()-1;
01450 }
01451 atomData[atomID-1].atomTypeIdx = poolIndex;
01452
01453 poolIndex = chargePool.lookupCstPool(charge);
01454 if(poolIndex==-1)
01455 {
01456 chargePool.push_back(charge);
01457 poolIndex = chargePool.size()-1;
01458 }
01459 atomData[atomID-1].chargeIdx = poolIndex;
01460
01461 poolIndex = massPool.lookupCstPool(mass);
01462 if(poolIndex==-1)
01463 {
01464 massPool.push_back(mass);
01465 poolIndex = massPool.size()-1;
01466 }
01467 atomData[atomID-1].massIdx = poolIndex;
01468 }
01469 }
01470
01471 void buildAtomData()
01472 {
01473 #ifndef MEM_OPT_VERSION
01474 int numAtoms = g_mol->numAtoms;
01475
01476
01477 atomData = new BasicAtomInfo[numAtoms];
01478 Atom *atoms = g_mol->getAtoms();
01479 AtomNameInfo *atomNames = g_mol->getAtomNames();
01480 AtomSegResInfo *atomSegResids = g_mol->getAtomSegResInfo();
01481
01482 for(int atomID=0; atomID < numAtoms; atomID++)
01483 {
01484
01485 int poolIndex;
01486 HashString fieldName;
01487 fieldName.assign(atomSegResids[atomID].segname);
01488 poolIndex = segNamePool.lookupCstPool(fieldName);
01489 if(poolIndex==-1)
01490 {
01491 segNamePool.push_back(fieldName);
01492 poolIndex = segNamePool.size()-1;
01493 }
01494 atomData[atomID].segNameIdx = poolIndex;
01495
01496 atomData[atomID].resID = atomSegResids[atomID].resid;
01497
01498 fieldName.assign(atomNames[atomID].resname);
01499 poolIndex = resNamePool.lookupCstPool(fieldName);
01500 if(poolIndex==-1)
01501 {
01502 resNamePool.push_back(fieldName);
01503 poolIndex = resNamePool.size()-1;
01504 }
01505 atomData[atomID].resNameIdx = poolIndex;
01506
01507 fieldName.assign(atomNames[atomID].atomname);
01508 poolIndex = atomNamePool.lookupCstPool(fieldName);
01509 if(poolIndex==-1)
01510 {
01511 atomNamePool.push_back(fieldName);
01512 poolIndex = atomNamePool.size()-1;
01513 }
01514 atomData[atomID].atomNameIdx = poolIndex;
01515
01516 fieldName.assign(atomNames[atomID].atomtype);
01517 poolIndex = atomTypePool.lookupCstPool(fieldName);
01518 if(poolIndex==-1)
01519 {
01520 atomTypePool.push_back(fieldName);
01521 poolIndex = atomTypePool.size()-1;
01522 }
01523 atomData[atomID].atomTypeIdx = poolIndex;
01524
01525 poolIndex = chargePool.lookupCstPool(atoms[atomID].charge);
01526 if(poolIndex==-1)
01527 {
01528 chargePool.push_back(atoms[atomID].charge);
01529 poolIndex = chargePool.size()-1;
01530 }
01531 atomData[atomID].chargeIdx = poolIndex;
01532
01533 poolIndex = massPool.lookupCstPool(atoms[atomID].mass);
01534 if(poolIndex==-1)
01535 {
01536 massPool.push_back(atoms[atomID].mass);
01537 poolIndex = massPool.size()-1;
01538 }
01539 atomData[atomID].massIdx = poolIndex;
01540 }
01541
01542
01543
01544 delete [] atomNames;
01545 delete [] atomSegResids;
01546 #endif
01547 }
01548
01549
01550 void getExtraBonds(StringList *file)
01551 {
01552 char err_msg[512];
01553 int a1, a2, a3, a4;
01554 float k, ref;
01555
01556 int numAtoms = g_mol->numAtoms;
01557
01558 if(!file)
01559 {
01560 NAMD_die("NO EXTRA BONDS FILES SPECIFIED");
01561 }
01562
01563 for ( ; file; file = file->next )
01564 {
01565 FILE *f = fopen(file->data,"r");
01566 if ( ! f )
01567 {
01568 sprintf(err_msg, "UNABLE TO OPEN EXTRA BONDS FILE %s", file->data);
01569 NAMD_err(err_msg);
01570 }
01571 else
01572 {
01573 iout << iINFO << "READING EXTRA BONDS FILE " << file->data <<"\n"<<endi;
01574 }
01575
01576 while ( 1 )
01577 {
01578 char buffer[512];
01579 int ret_code;
01580 int poolIndex;
01581 do
01582 {
01583 ret_code = NAMD_read_line(f, buffer);
01584 }
01585 while ( (ret_code==0) && (NAMD_blank_string(buffer)) );
01586 if (ret_code!=0)
01587 break;
01588
01589 char type[512];
01590 sscanf(buffer,"%s",type);
01591
01592 #define CHECKATOMID(ATOMID) if ( ATOMID < 0 || ATOMID >= numAtoms ) badatom = 1;
01593
01594 int badline = 0;
01595 int badatom = 0;
01596 if ( ! strncasecmp(type,"bond",4) )
01597 {
01598 if ( sscanf(buffer, "%s %d %d %f %f %s",
01599 type, &a1, &a2, &k, &ref, err_msg) != 5 )
01600 badline = 1;
01601 else
01602 {
01603 CHECKATOMID(a1)
01604 CHECKATOMID(a2)
01605 }
01606 Bond tmp;
01607 tmp.atom1 = a1;
01608 tmp.atom2 = a2;
01609
01610 BondValue tmpv;
01611 tmpv.k = k;
01612 tmpv.x0 = ref;
01613
01614 poolIndex = lookupCstPool(extraBondParams, tmpv);
01615 if(poolIndex==-1){
01616 extraBondParams.push_back(tmpv);
01617 poolIndex = extraBondParams.size()-1;
01618 }
01619 tmp.bond_type = g_param->NumBondParams + poolIndex;
01620 extraBonds.push_back(tmp);
01621 }
01622 else if ( ! strncasecmp(type,"angle",4) )
01623 {
01624 if ( sscanf(buffer, "%s %d %d %d %f %f %s",
01625 type, &a1, &a2, &a3, &k, &ref, err_msg) != 6 )
01626 badline = 1;
01627 else
01628 {
01629 CHECKATOMID(a1)
01630 CHECKATOMID(a2)
01631 CHECKATOMID(a3)
01632 }
01633 Angle tmp;
01634 tmp.atom1 = a1;
01635 tmp.atom2 = a2;
01636 tmp.atom3 = a3;
01637
01638 AngleValue tmpv;
01639 tmpv.k = k;
01640 tmpv.theta0 = ref / 180. * PI;
01641 tmpv.k_ub = 0;
01642 tmpv.r_ub = 0;
01643
01644 poolIndex = lookupCstPool(extraAngleParams, tmpv);
01645 if(poolIndex==-1){
01646 extraAngleParams.push_back(tmpv);
01647 poolIndex = extraAngleParams.size()-1;
01648 }
01649 tmp.angle_type = g_param->NumAngleParams + poolIndex;
01650 extraAngles.push_back(tmp);
01651 }
01652 else if ( ! strncasecmp(type,"dihedral",4) )
01653 {
01654 if ( sscanf(buffer, "%s %d %d %d %d %f %f %s",
01655 type, &a1, &a2, &a3, &a4, &k, &ref, err_msg) != 7 )
01656 badline = 1;
01657 else
01658 {
01659 CHECKATOMID(a1)
01660 CHECKATOMID(a2)
01661 CHECKATOMID(a3)
01662 CHECKATOMID(a4)
01663 }
01664 Dihedral tmp;
01665 tmp.atom1 = a1;
01666 tmp.atom2 = a2;
01667 tmp.atom3 = a3;
01668 tmp.atom4 = a4;
01669
01670 DihedralValue tmpv;
01671 tmpv.multiplicity = 1;
01672 tmpv.values[0].n = 0;
01673 tmpv.values[0].k = k;
01674 tmpv.values[0].delta = ref / 180. * PI;
01675
01676 poolIndex = lookupCstPool(extraDihedralParams, tmpv);
01677 if(poolIndex==-1){
01678 extraDihedralParams.push_back(tmpv);
01679 poolIndex = extraDihedralParams.size()-1;
01680 }
01681 tmp.dihedral_type = g_param->NumDihedralParams + poolIndex;
01682 extraDihedrals.push_back(tmp);
01683 }
01684 else if ( ! strncasecmp(type,"improper",4) )
01685 {
01686 if ( sscanf(buffer, "%s %d %d %d %d %f %f %s",
01687 type, &a1, &a2, &a3, &a4, &k, &ref, err_msg) != 7 )
01688 badline = 1;
01689 else
01690 {
01691 CHECKATOMID(a1)
01692 CHECKATOMID(a2)
01693 CHECKATOMID(a3)
01694 CHECKATOMID(a4)
01695 }
01696 Improper tmp;
01697 tmp.atom1 = a1;
01698 tmp.atom2 = a2;
01699 tmp.atom3 = a3;
01700 tmp.atom4 = a4;
01701
01702 ImproperValue tmpv;
01703 tmpv.multiplicity = 1;
01704 tmpv.values[0].n = 0;
01705 tmpv.values[0].k = k;
01706 tmpv.values[0].delta = ref / 180. * PI;
01707
01708 poolIndex = lookupCstPool(extraImproperParams, tmpv);
01709 if(poolIndex==-1){
01710 extraImproperParams.push_back(tmpv);
01711 poolIndex = extraImproperParams.size()-1;
01712 }
01713 tmp.improper_type = g_param->NumImproperParams + poolIndex;
01714 extraImpropers.push_back(tmp);
01715 }
01716 else if ( ! strncasecmp(type,"#",1) )
01717 {
01718 continue;
01719 }
01720 else
01721 {
01722 badline = 1;
01723 }
01724 #undef CHECKATOMID
01725 if ( badline )
01726 {
01727 sprintf(err_msg, "BAD LINE IN EXTRA BONDS FILE %s: %s",
01728 file->data, buffer);
01729 NAMD_die(err_msg);
01730 }
01731 if ( badatom )
01732 {
01733 sprintf(err_msg, "BAD ATOM ID IN EXTRA BONDS FILE %s: %s",
01734 file->data, buffer);
01735 NAMD_die(err_msg);
01736 }
01737 }
01738 fclose(f);
01739 }
01740 }
01741
01742 void buildParamData()
01743 {
01744
01745 }
01746
01747
01748
01749 void getBondData(FILE *fd)
01750 {
01751
01752
01753 int atom_nums[2];
01754 char atom1name[11];
01755 char atom2name[11];
01756 register int j;
01757 int num_read=0;
01758
01759 int numBonds = g_mol->numBonds;
01760 int origNumBonds = numBonds;
01761
01762
01763 Bond *bonds=new Bond[numBonds + extraBonds.size()];
01764
01765 if (bonds == NULL)
01766 {
01767 NAMD_die("memory allocations failed in Molecule::read_bonds");
01768 }
01769
01770
01771 while (num_read < numBonds)
01772 {
01773
01774 for (j=0; j<2; j++)
01775 {
01776
01777
01778
01779
01780 atom_nums[j]=NAMD_read_int(fd, "BONDS")-1;
01781
01782
01783 if (atom_nums[j] >= g_mol->numAtoms)
01784 {
01785 char err_msg[128];
01786
01787 sprintf(err_msg, "BOND INDEX %d GREATER THAN NATOM %d IN BOND # %d IN PSF FILE", atom_nums[j]+1, g_mol->numAtoms, num_read+1);
01788 NAMD_die(err_msg);
01789 }
01790 }
01791
01792 if(atom_nums[0] == atom_nums[1])
01793 {
01794 char err_msg[128];
01795 sprintf(err_msg, "ATOM %d is bonded to itself!", atom_nums[0]+1);
01796 NAMD_die(err_msg);
01797 }
01798
01799
01800
01801
01802 const char *atom1Type = atomTypePool[atomData[atom_nums[0]].atomTypeIdx].c_str();
01803 const char *atom2Type = atomTypePool[atomData[atom_nums[1]].atomTypeIdx].c_str();
01804 if (strcasecmp(atom1Type,atom2Type) < 0)
01805 {
01806 strcpy(atom1name, atom1Type);
01807 strcpy(atom2name, atom2Type);
01808 }
01809 else
01810 {
01811 strcpy(atom2name, atom1Type);
01812 strcpy(atom1name, atom2Type);
01813 }
01814
01815
01816
01817 Bond *b = &(bonds[num_read]);
01818 g_param->assign_bond_index(atom1name, atom2name, b);
01819
01820
01821 b->atom1=atom_nums[0];
01822 b->atom2=atom_nums[1];
01823
01824
01825 Real k, x0;
01826 g_param->get_bond_params(&k,&x0,b->bond_type);
01827 if ( k == 0. )
01828 --numBonds;
01829 else
01830 ++num_read;
01831 }
01832
01833
01834 if ( numBonds != origNumBonds )
01835 {
01836 iout << iWARN << "Ignored " << origNumBonds - numBonds <<
01837 " bonds with zero force constants.\n" << endi;
01838 iout << iWARN <<
01839 "Will get H-H distance in rigid H2O from H-O-H angle.\n" << endi;
01840 }
01841
01842
01843 int numRealBonds = numBonds;
01844 for(int i=0; i<extraBonds.size(); i++)
01845 bonds[numBonds+i] = extraBonds[i];
01846 numBonds += extraBonds.size();
01847 extraBonds.clear();
01848
01849 g_mol->numBonds = numBonds;
01850
01851
01852 for(int i=0; i<numBonds; i++)
01853 {
01854 Bond *b = bonds+i;
01855 TupleSignature oneSig(1,BOND,b->bond_type);
01856 oneSig.offset[0] = b->atom2 - b->atom1;
01857 oneSig.isReal = (i<numRealBonds );
01858
01859 int poolIndex = sigsOfBonds.lookupCstPool(oneSig);
01860 int newSig=0;
01861 if(poolIndex == -1)
01862 {
01863 sigsOfBonds.push_back(oneSig);
01864 poolIndex = (SigIndex)sigsOfBonds.size()-1;
01865 newSig=1;
01866 }
01867
01868 if(!newSig)
01869 {
01870 CkPrintf("Checking %d\n",poolIndex);
01871 int dupIdx = lookupCstPool(eachAtomSigs[b->atom1].bondSigIndices, (SigIndex)poolIndex);
01872 if(dupIdx!=-1)
01873 {
01874 char err_msg[128];
01875 sprintf(err_msg, "Duplicate bond %d-%d!", b->atom1+1, b->atom2+1);
01876 NAMD_die(err_msg);
01877 }
01878 }
01879 eachAtomSigs[b->atom1].bondSigIndices.push_back(poolIndex);
01880 }
01881
01882
01883 for(int i=0; i<numBonds; i++)
01884 {
01885 Bond *b=bonds+i;
01886 int atom2 = b->atom2;
01887 int thisOffset = atom2 - b->atom1;
01888 for(int j=0; j<eachAtomSigs[atom2].bondSigIndices.size(); j++)
01889 {
01890 SigIndex atom2BondId = eachAtomSigs[atom2].bondSigIndices[j];
01891 TupleSignature *secSig = &(sigsOfBonds[atom2BondId]);
01892 if(thisOffset== -(secSig->offset[0]))
01893 {
01894 char err_msg[128];
01895 sprintf(err_msg, "Duplicate bond %d-%d because two atoms are just reversed!", b->atom1+1, atom2+1);
01896 NAMD_die(err_msg);
01897 }
01898 }
01899 }
01900
01901
01902
01903 vector<int> *atomListOfBonded = new vector<int>[g_mol->numAtoms];
01904
01905 for(int i=0; i<numRealBonds; i++)
01906 {
01907 Bond *b=bonds+i;
01908 int atom1 = b->atom1;
01909 int atom2 = b->atom2;
01910 atomListOfBonded[atom1].push_back(atom2);
01911 atomListOfBonded[atom2].push_back(atom1);
01912 }
01913
01914 delete [] bonds;
01915
01916
01917
01918
01919
01920
01921 eachAtomClusterID = new int[g_mol->numAtoms];
01922 for(int i=0; i<g_mol->numAtoms; i++)
01923 eachAtomClusterID[i] = -1;
01924
01925 for(int i=0; i<g_mol->numAtoms; i++)
01926 {
01927 int curClusterID=eachAtomClusterID[i];
01928 if(curClusterID==-1)
01929 {
01930 curClusterID=i;
01931 }
01932
01933 deque<int> toVisitAtoms;
01934 toVisitAtoms.push_back(i);
01935 while(!toVisitAtoms.empty())
01936 {
01937 int visAtomID = toVisitAtoms.front();
01938 toVisitAtoms.pop_front();
01939 eachAtomClusterID[visAtomID] = curClusterID;
01940 for(int j=0; j<atomListOfBonded[visAtomID].size(); j++)
01941 {
01942 int otherAtom = atomListOfBonded[visAtomID][j];
01943 if(eachAtomClusterID[otherAtom]!=curClusterID)
01944 toVisitAtoms.push_back(otherAtom);
01945 }
01946 }
01947 }
01948
01949
01950
01951
01952
01953
01954
01955 int curClusterID;
01956 int prevClusterID=eachAtomClusterID[0];
01957 int curClusterSize=1;
01958 g_isClusterContiguous = 1;
01959 for(int i=1; i<g_mol->numAtoms; i++)
01960 {
01961 curClusterID = eachAtomClusterID[i];
01962 if(curClusterID > prevClusterID)
01963 {
01964 eachClusterSize.push_back(curClusterSize);
01965 curClusterSize=1;
01966 }
01967 else if(curClusterID == prevClusterID)
01968 {
01969 curClusterSize++;
01970 }
01971 else
01972 {
01973 g_isClusterContiguous = 0;
01974 break;
01975 }
01976 prevClusterID = curClusterID;
01977 }
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990 if(g_isClusterContiguous) {
01991 eachClusterSize.push_back(curClusterSize);
01992 int aid=0;
01993 for(int clusterIdx=0; clusterIdx<eachClusterSize.size(); clusterIdx++)
01994 {
01995 int curSize = eachClusterSize[clusterIdx];
01996 eachAtomClusterID[aid] = curSize;
01997 for(int i=aid+1; i<aid+curSize; i++)
01998 eachAtomClusterID[i] = -1;
01999 aid += curSize;
02000 }
02001 g_numClusters = eachClusterSize.size();
02002 eachClusterSize.clear();
02003 }else{
02004 eachClusterSize.clear();
02005
02006 char *clusters = new char[g_mol->numAtoms];
02007 memset(clusters, 0, sizeof(char)*g_mol->numAtoms);
02008 for(int i=0; i<g_mol->numAtoms; i++) {
02009 clusters[eachAtomClusterID[i]] = 1;
02010 }
02011
02012 for(int zeroPos=0; zeroPos<g_mol->numAtoms; zeroPos++) {
02013 if(clusters[zeroPos]==0) {
02014
02015
02016 g_numClusters = zeroPos;
02017 break;
02018 }
02019 }
02020 delete [] clusters;
02021 }
02022
02023
02024
02025
02026
02027
02028
02029
02030 for(int i=0; i<g_mol->numAtoms; i++)
02031 atomListOfBonded[i].clear();
02032 delete [] atomListOfBonded;
02033 }
02034
02035 void buildBondData()
02036 {
02037 #ifndef MEM_OPT_VERSION
02038 Bond *bonds = g_mol->getAllBonds();
02039
02040
02041 for(int i=0; i<g_mol->numBonds; i++)
02042 {
02043 Bond *b = bonds+i;
02044 TupleSignature oneSig(1,BOND,b->bond_type);
02045 oneSig.offset[0] = b->atom2 - b->atom1;
02046 oneSig.isReal = (i<g_mol->numRealBonds);
02047
02048 int poolIndex = sigsOfBonds.lookupCstPool(oneSig);
02049 int newSig=0;
02050 if(poolIndex == -1)
02051 {
02052 sigsOfBonds.push_back(oneSig);
02053 poolIndex = (SigIndex)sigsOfBonds.size()-1;
02054 newSig=1;
02055 }
02056
02057 if(!newSig)
02058 {
02059 int dupIdx = lookupCstPool(eachAtomSigs[b->atom1].bondSigIndices, (SigIndex)poolIndex);
02060 if(dupIdx!=-1)
02061 {
02062 char err_msg[128];
02063 sprintf(err_msg, "Duplicate bond %d-%d!", b->atom1+1, b->atom2+1);
02064 NAMD_die(err_msg);
02065 }
02066 }
02067 eachAtomSigs[b->atom1].bondSigIndices.push_back(poolIndex);
02068 }
02069
02070
02071 for(int i=0; i<g_mol->numBonds; i++)
02072 {
02073 Bond *b=bonds+i;
02074 int atom2 = b->atom2;
02075 int thisOffset = atom2 - b->atom1;
02076 for(int j=0; j<eachAtomSigs[atom2].bondSigIndices.size(); j++)
02077 {
02078 SigIndex atom2BondId = eachAtomSigs[atom2].bondSigIndices[j];
02079 TupleSignature *secSig = &(sigsOfBonds[atom2BondId]);
02080 if(thisOffset== -(secSig->offset[0]))
02081 {
02082 char err_msg[128];
02083 sprintf(err_msg, "Duplicate bond %d-%d because two atoms are just reversed!", b->atom1+1, atom2+1);
02084 NAMD_die(err_msg);
02085 }
02086 }
02087 }
02088
02089
02090
02091 vector<int> *atomListOfBonded = new vector<int>[g_mol->numAtoms];
02092
02093 for(int i=0; i<g_mol->numRealBonds; i++)
02094 {
02095 Bond *b=bonds+i;
02096 int atom1 = b->atom1;
02097 int atom2 = b->atom2;
02098 atomListOfBonded[atom1].push_back(atom2);
02099 atomListOfBonded[atom2].push_back(atom1);
02100 }
02101
02102 delete [] bonds;
02103
02104
02105
02106
02107
02108
02109 eachAtomClusterID = new int[g_mol->numAtoms];
02110 for(int i=0; i<g_mol->numAtoms; i++)
02111 eachAtomClusterID[i] = -1;
02112
02113 for(int i=0; i<g_mol->numAtoms; i++)
02114 {
02115 int curClusterID=eachAtomClusterID[i];
02116 if(curClusterID==-1)
02117 {
02118 curClusterID=i;
02119 }
02120
02121 deque<int> toVisitAtoms;
02122 toVisitAtoms.push_back(i);
02123 while(!toVisitAtoms.empty())
02124 {
02125 int visAtomID = toVisitAtoms.front();
02126 toVisitAtoms.pop_front();
02127 eachAtomClusterID[visAtomID] = curClusterID;
02128 for(int j=0; j<atomListOfBonded[visAtomID].size(); j++)
02129 {
02130 int otherAtom = atomListOfBonded[visAtomID][j];
02131 if(eachAtomClusterID[otherAtom]!=curClusterID)
02132 toVisitAtoms.push_back(otherAtom);
02133 }
02134 }
02135 }
02136
02137
02138
02139
02140
02141
02142
02143 int curClusterID;
02144 int prevClusterID=eachAtomClusterID[0];
02145 int curClusterSize=1;
02146 g_isClusterContiguous = 1;
02147 for(int i=1; i<g_mol->numAtoms; i++)
02148 {
02149 curClusterID = eachAtomClusterID[i];
02150 if(curClusterID > prevClusterID)
02151 {
02152 eachClusterSize.push_back(curClusterSize);
02153 curClusterSize=1;
02154 }
02155 else if(curClusterID == prevClusterID)
02156 {
02157 curClusterSize++;
02158 }
02159 else
02160 {
02161 g_isClusterContiguous = 0;
02162 break;
02163 }
02164 prevClusterID = curClusterID;
02165 }
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178 if(g_isClusterContiguous) {
02179 eachClusterSize.push_back(curClusterSize);
02180 int aid=0;
02181 for(int clusterIdx=0; clusterIdx<eachClusterSize.size(); clusterIdx++)
02182 {
02183 int curSize = eachClusterSize[clusterIdx];
02184 eachAtomClusterID[aid] = curSize;
02185 for(int i=aid+1; i<aid+curSize; i++)
02186 eachAtomClusterID[i] = -1;
02187 aid += curSize;
02188 }
02189 g_numClusters = eachClusterSize.size();
02190 eachClusterSize.clear();
02191 }else{
02192 eachClusterSize.clear();
02193
02194 char *clusters = new char[g_mol->numAtoms];
02195 memset(clusters, 0, sizeof(char)*g_mol->numAtoms);
02196 for(int i=0; i<g_mol->numAtoms; i++) {
02197 clusters[eachAtomClusterID[i]] = 1;
02198 }
02199
02200 for(int zeroPos=0; zeroPos<g_mol->numAtoms; zeroPos++) {
02201 if(clusters[zeroPos]==0) {
02202
02203
02204 g_numClusters = zeroPos;
02205 break;
02206 }
02207 }
02208 delete [] clusters;
02209 }
02210
02211
02212
02213
02214
02215
02216
02217
02218 for(int i=0; i<g_mol->numAtoms; i++)
02219 atomListOfBonded[i].clear();
02220 delete [] atomListOfBonded;
02221 #endif
02222 }
02223
02224 void getAngleData(FILE *fd)
02225 {
02226
02227 int atom_nums[3];
02228 char atom1name[11];
02229 char atom2name[11];
02230 char atom3name[11];
02231 register int j;
02232 int num_read=0;
02233
02234 int numAngles = g_mol->numAngles;
02235 int origNumAngles = numAngles;
02236
02237 Angle *angles=new Angle[numAngles + extraAngles.size()];
02238
02239 if (angles == NULL)
02240 {
02241 NAMD_die("memory allocation failed in Molecule::read_angles");
02242 }
02243
02244
02245 while (num_read < numAngles)
02246 {
02247
02248 for (j=0; j<3; j++)
02249 {
02250
02251
02252
02253
02254 atom_nums[j]=NAMD_read_int(fd, "ANGLES")-1;
02255
02256
02257
02258 if (atom_nums[j] >= g_mol->numAtoms)
02259 {
02260 char err_msg[128];
02261
02262 sprintf(err_msg, "ANGLES INDEX %d GREATER THAN NATOM %d IN ANGLES # %d IN PSF FILE", atom_nums[j]+1, g_mol->numAtoms, num_read+1);
02263 NAMD_die(err_msg);
02264 }
02265 }
02266
02267
02268
02269
02270
02271
02272
02273 const char *atom1Type = atomTypePool[atomData[atom_nums[0]].atomTypeIdx].c_str();
02274 const char *atom2Type = atomTypePool[atomData[atom_nums[1]].atomTypeIdx].c_str();
02275 const char *atom3Type = atomTypePool[atomData[atom_nums[2]].atomTypeIdx].c_str();
02276
02277 if (strcasecmp(atom1Type,atom2Type) < 0)
02278 {
02279 strcpy(atom1name, atom1Type);
02280 strcpy(atom2name, atom2Type);
02281 strcpy(atom3name, atom3Type);
02282 }
02283 else
02284 {
02285 strcpy(atom1name, atom1Type);
02286 strcpy(atom2name, atom2Type);
02287 strcpy(atom3name, atom3Type);
02288 }
02289
02290
02291
02292 g_param->assign_angle_index(atom1name, atom2name,
02293 atom3name, &(angles[num_read]));
02294
02295
02296 angles[num_read].atom1=atom_nums[0];
02297 angles[num_read].atom2=atom_nums[1];
02298 angles[num_read].atom3=atom_nums[2];
02299
02300
02301 Real k, t0, k_ub, r_ub;
02302 g_param->get_angle_params(&k,&t0,&k_ub,&r_ub,angles[num_read].angle_type);
02303 if ( k == 0. && k_ub == 0. )
02304 --numAngles;
02305 else
02306 ++num_read;
02307 }
02308
02309
02310 if ( numAngles != origNumAngles )
02311 {
02312 iout << iWARN << "Ignored " << origNumAngles - numAngles <<
02313 " angles with zero force constants.\n" << endi;
02314 }
02315
02316
02317 for(int i=0; i<extraAngles.size(); i++)
02318 angles[numAngles+i] = extraAngles[i];
02319 numAngles += extraAngles.size();
02320 extraAngles.clear();
02321
02322 g_mol->numAngles = numAngles;
02323
02324
02325 for(int i=0; i<numAngles; i++)
02326 {
02327 Angle *tuple = angles+i;
02328 TupleSignature oneSig(2,ANGLE,tuple->angle_type);
02329 int offset[2];
02330 offset[0] = tuple->atom2 - tuple->atom1;
02331 offset[1] = tuple->atom3 - tuple->atom1;
02332 oneSig.setOffsets(offset);
02333
02334 int poolIndex = sigsOfAngles.lookupCstPool(oneSig);
02335 if(poolIndex == -1)
02336 {
02337 sigsOfAngles.push_back(oneSig);
02338 poolIndex = (SigIndex)sigsOfAngles.size()-1;
02339 }
02340 eachAtomSigs[tuple->atom1].angleSigIndices.push_back(poolIndex);
02341 }
02342
02343 delete [] angles;
02344
02345 }
02346
02347 void buildAngleData()
02348 {
02349 #ifndef MEM_OPT_VERSION
02350 Angle *angles = g_mol->getAllAngles();
02351
02352 for(int i=0; i<g_mol->numAngles; i++)
02353 {
02354 Angle *tuple = angles+i;
02355 TupleSignature oneSig(2,ANGLE,tuple->angle_type);
02356 int offset[2];
02357 offset[0] = tuple->atom2 - tuple->atom1;
02358 offset[1] = tuple->atom3 - tuple->atom1;
02359 oneSig.setOffsets(offset);
02360
02361 int poolIndex = sigsOfAngles.lookupCstPool(oneSig);
02362 if(poolIndex == -1)
02363 {
02364 sigsOfAngles.push_back(oneSig);
02365 poolIndex = (SigIndex)sigsOfAngles.size()-1;
02366 }
02367 eachAtomSigs[tuple->atom1].angleSigIndices.push_back(poolIndex);
02368 }
02369 delete [] angles;
02370 #endif
02371 }
02372
02373 void getDihedralData(FILE *fd)
02374 {
02375
02376 int atom_nums[4];
02377 int last_atom_nums[4];
02378 char atom1name[11];
02379 char atom2name[11];
02380 char atom3name[11];
02381 char atom4name[11];
02382 register int j;
02383 int num_read=0;
02384 int multiplicity=1;
02385 Bool duplicate_bond;
02386 int num_unique=0;
02387
02388
02389 for (j=0; j<4; j++)
02390 last_atom_nums[j] = -1;
02391
02392 int numDihedrals = g_mol->numDihedrals;
02393 int numAtoms = g_mol->numAtoms;
02394
02395
02396 Dihedral *dihedrals = new Dihedral[numDihedrals + extraDihedrals.size()];
02397
02398 if (dihedrals == NULL)
02399 {
02400 NAMD_die("memory allocation failed in Molecule::read_dihedrals");
02401 }
02402
02403
02404 while (num_read < numDihedrals)
02405 {
02406 duplicate_bond = TRUE;
02407
02408
02409 for (j=0; j<4; j++)
02410 {
02411
02412
02413
02414
02415 atom_nums[j]=NAMD_read_int(fd, "DIHEDRALS")-1;
02416
02417
02418 if (atom_nums[j] >= numAtoms)
02419 {
02420 char err_msg[128];
02421
02422 sprintf(err_msg, "DIHEDRALS INDEX %d GREATER THAN NATOM %d IN DIHEDRALS # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
02423 NAMD_die(err_msg);
02424 }
02425
02426
02427 if (atom_nums[j] != last_atom_nums[j])
02428 {
02429 duplicate_bond = FALSE;
02430 }
02431
02432 last_atom_nums[j] = atom_nums[j];
02433 }
02434
02435
02436
02437 const char *atom1Type = atomTypePool[atomData[atom_nums[0]].atomTypeIdx].c_str();
02438 const char *atom2Type = atomTypePool[atomData[atom_nums[1]].atomTypeIdx].c_str();
02439 const char *atom3Type = atomTypePool[atomData[atom_nums[2]].atomTypeIdx].c_str();
02440 const char *atom4Type = atomTypePool[atomData[atom_nums[3]].atomTypeIdx].c_str();
02441 strcpy(atom1name, atom1Type);
02442 strcpy(atom2name, atom2Type);
02443 strcpy(atom3name, atom3Type);
02444 strcpy(atom4name, atom4Type);
02445
02446
02447
02448 if (duplicate_bond)
02449 {
02450
02451 multiplicity++;
02452
02453 if (multiplicity == 2)
02454 {
02455 g_mol->numMultipleDihedrals++;
02456 }
02457 }
02458 else
02459 {
02460 multiplicity=1;
02461 num_unique++;
02462 }
02463
02464
02465 g_param->assign_dihedral_index(atom1name, atom2name,
02466 atom3name, atom4name, &(dihedrals[num_unique-1]),
02467 multiplicity);
02468
02469
02470 dihedrals[num_unique-1].atom1=atom_nums[0];
02471 dihedrals[num_unique-1].atom2=atom_nums[1];
02472 dihedrals[num_unique-1].atom3=atom_nums[2];
02473 dihedrals[num_unique-1].atom4=atom_nums[3];
02474
02475 num_read++;
02476 }
02477
02478
02479 if(extraDihedrals.size()>0){
02480 iout << iWARN << "It's your responsibility to ensure there is no duplicates among these extra dihedrals\n" << endi;
02481 }
02482 for(int i=0; i<extraDihedrals.size(); i++)
02483 dihedrals[num_unique+i] = extraDihedrals[i];
02484 num_unique += extraDihedrals.size();
02485 extraDihedrals.clear();
02486
02487 g_mol->numDihedrals = num_unique;
02488
02489
02490 for(int i=0; i<num_unique; i++)
02491 {
02492 Dihedral *tuple = dihedrals+i;
02493 TupleSignature oneSig(3,DIHEDRAL,tuple->dihedral_type);
02494 int offset[3];
02495 offset[0] = tuple->atom2 - tuple->atom1;
02496 offset[1] = tuple->atom3 - tuple->atom1;
02497 offset[2] = tuple->atom4 - tuple->atom1;
02498 oneSig.setOffsets(offset);
02499
02500 int poolIndex = sigsOfDihedrals.lookupCstPool(oneSig);
02501 if(poolIndex == -1)
02502 {
02503 sigsOfDihedrals.push_back(oneSig);
02504 poolIndex = (SigIndex)sigsOfDihedrals.size()-1;
02505 }
02506 eachAtomSigs[tuple->atom1].dihedralSigIndices.push_back(poolIndex);
02507 }
02508
02509 delete[] dihedrals;
02510
02511 }
02512
02513 void buildDihedralData()
02514 {
02515 #ifndef MEM_OPT_VERSION
02516 Dihedral *dihedrals = g_mol->getAllDihedrals();
02517
02518
02519 for(int i=0; i<g_mol->numDihedrals; i++)
02520 {
02521 Dihedral *tuple = dihedrals+i;
02522 TupleSignature oneSig(3,DIHEDRAL,tuple->dihedral_type);
02523 int offset[3];
02524 offset[0] = tuple->atom2 - tuple->atom1;
02525 offset[1] = tuple->atom3 - tuple->atom1;
02526 offset[2] = tuple->atom4 - tuple->atom1;
02527 oneSig.setOffsets(offset);
02528
02529 int poolIndex = sigsOfDihedrals.lookupCstPool(oneSig);
02530 if(poolIndex == -1)
02531 {
02532 sigsOfDihedrals.push_back(oneSig);
02533 poolIndex = (SigIndex)sigsOfDihedrals.size()-1;
02534 }
02535 eachAtomSigs[tuple->atom1].dihedralSigIndices.push_back(poolIndex);
02536 }
02537
02538 delete[] dihedrals;
02539 #endif
02540 }
02541
02542 void getImproperData(FILE *fd)
02543 {
02544 int atom_nums[4];
02545 int last_atom_nums[4];
02546 char atom1name[11];
02547 char atom2name[11];
02548 char atom3name[11];
02549 char atom4name[11];
02550 register int j;
02551 int num_read=0;
02552 int multiplicity=1;
02553 Bool duplicate_bond;
02554 int num_unique=0;
02555
02556
02557
02558 for (j=0; j<4; j++)
02559 last_atom_nums[j] = -1;
02560
02561 int numImpropers = g_mol->numImpropers;
02562 int numAtoms = g_mol->numAtoms;
02563
02564
02565 Improper *impropers=new Improper[numImpropers];
02566
02567 if (impropers == NULL)
02568 {
02569 NAMD_die("memory allocation failed in Molecule::read_impropers");
02570 }
02571
02572
02573 while (num_read < numImpropers)
02574 {
02575 duplicate_bond = TRUE;
02576
02577
02578 for (j=0; j<4; j++)
02579 {
02580
02581
02582
02583
02584 atom_nums[j]=NAMD_read_int(fd, "IMPROPERS")-1;
02585
02586
02587 if (atom_nums[j] >= numAtoms)
02588 {
02589 char err_msg[128];
02590
02591 sprintf(err_msg, "IMPROPERS INDEX %d GREATER THAN NATOM %d IN IMPROPERS # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
02592 NAMD_die(err_msg);
02593 }
02594
02595 if (atom_nums[j] != last_atom_nums[j])
02596 {
02597 duplicate_bond = FALSE;
02598 }
02599
02600 last_atom_nums[j] = atom_nums[j];
02601 }
02602
02603
02604 const char *atom1Type = atomTypePool[atomData[atom_nums[0]].atomTypeIdx].c_str();
02605 const char *atom2Type = atomTypePool[atomData[atom_nums[1]].atomTypeIdx].c_str();
02606 const char *atom3Type = atomTypePool[atomData[atom_nums[2]].atomTypeIdx].c_str();
02607 const char *atom4Type = atomTypePool[atomData[atom_nums[3]].atomTypeIdx].c_str();
02608 strcpy(atom1name, atom1Type);
02609 strcpy(atom2name, atom2Type);
02610 strcpy(atom3name, atom3Type);
02611 strcpy(atom4name, atom4Type);
02612
02613
02614 if (duplicate_bond)
02615 {
02616
02617
02618
02619 multiplicity++;
02620
02621 if (multiplicity == 2)
02622 {
02623
02624 g_mol->numMultipleImpropers++;
02625 }
02626 }
02627 else
02628 {
02629
02630 multiplicity = 1;
02631 num_unique++;
02632 }
02633
02634
02635 g_param->assign_improper_index(atom1name, atom2name,
02636 atom3name, atom4name, &(impropers[num_unique-1]),
02637 multiplicity);
02638
02639
02640 impropers[num_unique-1].atom1=atom_nums[0];
02641 impropers[num_unique-1].atom2=atom_nums[1];
02642 impropers[num_unique-1].atom3=atom_nums[2];
02643 impropers[num_unique-1].atom4=atom_nums[3];
02644
02645 num_read++;
02646 }
02647
02648
02649 if(extraImpropers.size()>0){
02650 iout << iWARN << "It's your responsibility to ensure there is no duplicates among these extra impropers\n" << endi;
02651 }
02652 for(int i=0; i<extraImpropers.size(); i++)
02653 impropers[num_unique+i] = extraImpropers[i];
02654 num_unique += extraImpropers.size();
02655 extraImpropers.clear();
02656
02657
02658
02659
02660 g_mol->numImpropers = num_unique;
02661
02662
02663 for(int i=0; i<num_unique; i++)
02664 {
02665 Improper *tuple = impropers+i;
02666 TupleSignature oneSig(3,IMPROPER,tuple->improper_type);
02667 int offset[3];
02668 offset[0] = tuple->atom2 - tuple->atom1;
02669 offset[1] = tuple->atom3 - tuple->atom1;
02670 offset[2] = tuple->atom4 - tuple->atom1;
02671 oneSig.setOffsets(offset);
02672
02673 int poolIndex = sigsOfImpropers.lookupCstPool(oneSig);
02674 if(poolIndex == -1)
02675 {
02676 sigsOfImpropers.push_back(oneSig);
02677 poolIndex = (SigIndex)sigsOfImpropers.size()-1;
02678 }
02679 eachAtomSigs[tuple->atom1].improperSigIndices.push_back(poolIndex);
02680 }
02681
02682 delete[] impropers;
02683
02684 }
02685
02686 void buildImproperData()
02687 {
02688 #ifndef MEM_OPT_VERSION
02689 Improper *impropers=g_mol->getAllImpropers();
02690
02691
02692 for(int i=0; i<g_mol->numImpropers; i++)
02693 {
02694 Improper *tuple = impropers+i;
02695 TupleSignature oneSig(3,IMPROPER,tuple->improper_type);
02696 int offset[3];
02697 offset[0] = tuple->atom2 - tuple->atom1;
02698 offset[1] = tuple->atom3 - tuple->atom1;
02699 offset[2] = tuple->atom4 - tuple->atom1;
02700 oneSig.setOffsets(offset);
02701
02702 int poolIndex = sigsOfImpropers.lookupCstPool(oneSig);
02703 if(poolIndex == -1)
02704 {
02705 sigsOfImpropers.push_back(oneSig);
02706 poolIndex = (SigIndex)sigsOfImpropers.size()-1;
02707 }
02708 eachAtomSigs[tuple->atom1].improperSigIndices.push_back(poolIndex);
02709 }
02710
02711 delete[] impropers;
02712 #endif
02713 }
02714
02715 void getDonorData(FILE *fd)
02716 {
02717 int d[2];
02718 register int j;
02719 int num_read=0;
02720 int num_no_hydr=0;
02721
02722
02723 int numDonors = g_mol->numDonors;
02724 int numAtoms = g_mol->numAtoms;
02725 Bond *donors=new Bond[numDonors];
02726
02727 if (donors == NULL)
02728 {
02729 NAMD_die("memory allocations failed in Molecule::read_donors");
02730 }
02731
02732
02733 while (num_read < numDonors)
02734 {
02735
02736 for (j=0; j<2; j++)
02737 {
02738
02739
02740
02741
02742 d[j]=NAMD_read_int(fd, "DONORS")-1;
02743
02744
02745 if (d[j] >= numAtoms)
02746 {
02747 char err_msg[128];
02748
02749 sprintf(err_msg,
02750 "DONOR INDEX %d GREATER THAN NATOM %d IN DONOR # %d IN PSF FILE",
02751 d[j]+1, numAtoms, num_read+1);
02752 NAMD_die(err_msg);
02753 }
02754
02755
02756 if (d[j] < 0)
02757 num_no_hydr++;
02758 }
02759
02760
02761 Bond *b = &(donors[num_read]);
02762 b->atom1=d[0];
02763 b->atom2=d[1];
02764
02765 num_read++;
02766 }
02767
02768 delete [] donors;
02769 }
02770
02771 void getAcceptorData(FILE *fd)
02772 {
02773 int d[2];
02774 register int j;
02775 int num_read=0;
02776 int num_no_ante=0;
02777
02778 int numAcceptors = g_mol->numAcceptors;
02779
02780
02781 Bond *acceptors=new Bond[numAcceptors];
02782
02783 if (acceptors == NULL)
02784 {
02785 NAMD_die("memory allocations failed in Molecule::read_acceptors");
02786 }
02787
02788
02789 while (num_read < numAcceptors)
02790 {
02791
02792 for (j=0; j<2; j++)
02793 {
02794
02795
02796
02797
02798 d[j]=NAMD_read_int(fd, "ACCEPTORS")-1;
02799
02800
02801 if (d[j] >= g_mol->numAtoms)
02802 {
02803 char err_msg[128];
02804
02805 sprintf(err_msg, "ACCEPTOR INDEX %d GREATER THAN NATOM %d IN DONOR # %d IN PSF FILE", d[j]+1, g_mol->numAtoms, num_read+1);
02806 NAMD_die(err_msg);
02807 }
02808
02809
02810 if (d[j] < 0)
02811 num_no_ante++;
02812 }
02813
02814
02815 Bond *b = &(acceptors[num_read]);
02816 b->atom1=d[0];
02817 b->atom2=d[1];
02818
02819 num_read++;
02820 }
02821
02822 delete [] acceptors;
02823 }
02824
02825 void getExclusionData(FILE *fd)
02826 {
02827
02828
02829
02830 printf("ERROR: The current compression doesn't support explicit exclusions!\n");
02831 NAMD_die("Compressing .psf file is not finished!\n");
02832 }
02833
02834 void getCrosstermData(FILE *fd)
02835 {
02836 int atom_nums[8];
02837 int last_atom_nums[8];
02838 char atom1name[11];
02839 char atom2name[11];
02840 char atom3name[11];
02841 char atom4name[11];
02842 char atom5name[11];
02843 char atom6name[11];
02844 char atom7name[11];
02845 char atom8name[11];
02846 int j;
02847 int num_read=0;
02848 Bool duplicate_bond;
02849
02850
02851
02852 for (j=0; j<8; j++)
02853 last_atom_nums[j] = -1;
02854
02855 int numCrossterms = g_mol->numCrossterms;
02856 int numAtoms = g_mol->numAtoms;
02857
02858
02859 Crossterm* crossterms=new Crossterm[numCrossterms];
02860
02861 if (crossterms == NULL)
02862 {
02863 NAMD_die("memory allocation failed in getCrosstermData when compressing psf file");
02864 }
02865
02866
02867 while (num_read < numCrossterms)
02868 {
02869 duplicate_bond = TRUE;
02870
02871
02872 for (j=0; j<8; j++)
02873 {
02874
02875
02876
02877
02878 atom_nums[j]=NAMD_read_int(fd, "CROSS-TERMS")-1;
02879
02880
02881 if (atom_nums[j] >= numAtoms)
02882 {
02883 char err_msg[128];
02884
02885 sprintf(err_msg, "CROSS-TERM INDEX %d GREATER THAN NATOM %d IN CROSS-TERMS # %d IN PSF FILE", atom_nums[j]+1, numAtoms, num_read+1);
02886 NAMD_die(err_msg);
02887 }
02888
02889 if (atom_nums[j] != last_atom_nums[j]){
02890 duplicate_bond = FALSE;
02891 }
02892
02893 last_atom_nums[j] = atom_nums[j];
02894 }
02895
02896
02897 const char *atom1Type = atomTypePool[atomData[atom_nums[0]].atomTypeIdx].c_str();
02898 const char *atom2Type = atomTypePool[atomData[atom_nums[1]].atomTypeIdx].c_str();
02899 const char *atom3Type = atomTypePool[atomData[atom_nums[2]].atomTypeIdx].c_str();
02900 const char *atom4Type = atomTypePool[atomData[atom_nums[3]].atomTypeIdx].c_str();
02901 const char *atom5Type = atomTypePool[atomData[atom_nums[4]].atomTypeIdx].c_str();
02902 const char *atom6Type = atomTypePool[atomData[atom_nums[5]].atomTypeIdx].c_str();
02903 const char *atom7Type = atomTypePool[atomData[atom_nums[6]].atomTypeIdx].c_str();
02904 const char *atom8Type = atomTypePool[atomData[atom_nums[7]].atomTypeIdx].c_str();
02905 strcpy(atom1name, atom1Type);
02906 strcpy(atom2name, atom2Type);
02907 strcpy(atom3name, atom3Type);
02908 strcpy(atom4name, atom4Type);
02909 strcpy(atom5name, atom5Type);
02910 strcpy(atom6name, atom6Type);
02911 strcpy(atom7name, atom7Type);
02912 strcpy(atom8name, atom8Type);
02913
02914
02915 if (duplicate_bond)
02916 {
02917 iout << iWARN << "Duplicate cross-term detected.\n" << endi;
02918 }
02919
02920
02921 g_param->assign_crossterm_index(atom1name, atom2name,
02922 atom3name, atom4name, atom5name, atom6name,
02923 atom7name, atom8name, &(crossterms[num_read]));
02924
02925
02926 crossterms[num_read].atom1=atom_nums[0];
02927 crossterms[num_read].atom2=atom_nums[1];
02928 crossterms[num_read].atom3=atom_nums[2];
02929 crossterms[num_read].atom4=atom_nums[3];
02930 crossterms[num_read].atom5=atom_nums[4];
02931 crossterms[num_read].atom6=atom_nums[5];
02932 crossterms[num_read].atom7=atom_nums[6];
02933 crossterms[num_read].atom8=atom_nums[7];
02934
02935 num_read++;
02936 }
02937
02938 numCrossterms = num_read;
02939
02940
02941 for(int i=0; i<numCrossterms; i++)
02942 {
02943 Crossterm *tuple = crossterms+i;
02944 TupleSignature oneSig(7, CROSSTERM, tuple->crossterm_type);
02945 int offset[7];
02946 offset[0] = tuple->atom2 - tuple->atom1;
02947 offset[1] = tuple->atom3 - tuple->atom1;
02948 offset[2] = tuple->atom4 - tuple->atom1;
02949 offset[3] = tuple->atom5 - tuple->atom1;
02950 offset[4] = tuple->atom6 - tuple->atom1;
02951 offset[5] = tuple->atom7 - tuple->atom1;
02952 offset[6] = tuple->atom8 - tuple->atom1;
02953 oneSig.setOffsets(offset);
02954
02955 int poolIndex = sigsOfCrossterms.lookupCstPool(oneSig);
02956 if(poolIndex == -1)
02957 {
02958 sigsOfCrossterms.push_back(oneSig);
02959 poolIndex = (SigIndex)sigsOfCrossterms.size()-1;
02960 }
02961 eachAtomSigs[tuple->atom1].crosstermSigIndices.push_back(poolIndex);
02962 }
02963
02964 delete[] crossterms;
02965 }
02966
02967 void buildCrosstermData()
02968 {
02969 #ifndef MEM_OPT_VERSION
02970 Crossterm *crossterms = g_mol->getAllCrossterms();
02971
02972 for(int i=0; i<g_mol->numCrossterms; i++)
02973 {
02974 Crossterm *tuple = crossterms+i;
02975 TupleSignature oneSig(7, CROSSTERM, tuple->crossterm_type);
02976 int offset[7];
02977 offset[0] = tuple->atom2 - tuple->atom1;
02978 offset[1] = tuple->atom3 - tuple->atom1;
02979 offset[2] = tuple->atom4 - tuple->atom1;
02980 offset[3] = tuple->atom5 - tuple->atom1;
02981 offset[4] = tuple->atom6 - tuple->atom1;
02982 offset[5] = tuple->atom7 - tuple->atom1;
02983 offset[6] = tuple->atom8 - tuple->atom1;
02984 oneSig.setOffsets(offset);
02985
02986 int poolIndex = sigsOfCrossterms.lookupCstPool(oneSig);
02987 if(poolIndex == -1)
02988 {
02989 sigsOfCrossterms.push_back(oneSig);
02990 poolIndex = (SigIndex)sigsOfCrossterms.size()-1;
02991 }
02992 eachAtomSigs[tuple->atom1].crosstermSigIndices.push_back(poolIndex);
02993 }
02994
02995 delete[] crossterms;
02996 #endif
02997 }
02998
02999 void buildExclusions()
03000 {
03001
03002
03003 UniqueSet<Exclusion> allExclusions;
03004
03005 int exclude_flag;
03006 exclude_flag = g_simParam->exclude;
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024 vector<int> *eachAtomNeighbors = new vector<int>[g_mol->numAtoms];
03025 for(int atom1=0; atom1<g_mol->numAtoms; atom1++)
03026 {
03027 AtomSigInfo *aSig = &atomSigPool[atomData[atom1].atomSigIdx];
03028 for(int j=0; j<aSig->bondSigIndices.size(); j++)
03029 {
03030 TupleSignature *tSig = &sigsOfBonds[aSig->bondSigIndices[j]];
03031 if(!tSig->isReal) continue;
03032 int atom2 = atom1+tSig->offset[0];
03033 eachAtomNeighbors[atom1].push_back(atom2);
03034 eachAtomNeighbors[atom2].push_back(atom1);
03035 }
03036 }
03037
03038 if (!g_simParam->amberOn || !g_simParam->readExclusions)
03039 {
03040 switch (exclude_flag)
03041 {
03042 case NONE:
03043 break;
03044 case ONETWO:
03045 build12Excls(allExclusions, eachAtomNeighbors);
03046 break;
03047 case ONETHREE:
03048 build12Excls(allExclusions, eachAtomNeighbors);
03049 build13Excls(allExclusions, eachAtomNeighbors);
03050
03051 break;
03052 case ONEFOUR:
03053 build12Excls(allExclusions, eachAtomNeighbors);
03054 build13Excls(allExclusions, eachAtomNeighbors);
03055 build14Excls(allExclusions, eachAtomNeighbors, 0);
03056
03057 break;
03058 case SCALED14:
03059 build12Excls(allExclusions, eachAtomNeighbors);
03060 build13Excls(allExclusions, eachAtomNeighbors);
03061 build14Excls(allExclusions, eachAtomNeighbors, 1);
03062
03063 break;
03064 }
03065 }
03066
03067
03068
03069
03070
03071
03072 for(int i=0; i<g_mol->numAtoms; i++)
03073 eachAtomNeighbors[i].clear();
03074 delete [] eachAtomNeighbors;
03075
03076
03077 UniqueSetIter<Exclusion> exclIter(allExclusions);
03078 eachAtomExclSigs = new ExclSigInfo[g_mol->numAtoms];
03079 for(exclIter=exclIter.begin(); exclIter!=exclIter.end(); exclIter++)
03080 {
03081 int atom1 = exclIter->atom1;
03082 int atom2 = exclIter->atom2;
03083 int offset21 = atom2-atom1;
03084 if(exclIter->modified)
03085 {
03086 eachAtomExclSigs[atom1].modExclOffset.push_back(offset21);
03087 eachAtomExclSigs[atom2].modExclOffset.push_back(-offset21);
03088 }
03089 else
03090 {
03091 eachAtomExclSigs[atom1].fullExclOffset.push_back(offset21);
03092 eachAtomExclSigs[atom2].fullExclOffset.push_back(-offset21);
03093 }
03094 }
03095 allExclusions.clear();
03096
03097
03098
03099 for(int i=0; i<g_mol->numAtoms; i++)
03100 {
03101 eachAtomExclSigs[i].sortExclOffset();
03102 int poolIndex = sigsOfExclusions.lookupCstPool(eachAtomExclSigs[i]);
03103 if(poolIndex==-1)
03104 {
03105 poolIndex = sigsOfExclusions.size();
03106 sigsOfExclusions.push_back(eachAtomExclSigs[i]);
03107 }
03108 atomData[i].exclSigIdx = poolIndex;
03109 }
03110 delete [] eachAtomExclSigs;
03111 eachAtomExclSigs = NULL;
03112 printf("Exclusion signatures: %d\n", (int)sigsOfExclusions.size());
03113 }
03114
03115 void build12Excls(UniqueSet<Exclusion>& allExcls, vector<int> *eachAtomNeighbors)
03116 {
03117 for(int atom1=0; atom1<g_mol->numAtoms; atom1++)
03118 {
03119 vector<int> *atom1List = &eachAtomNeighbors[atom1];
03120 for(int j=0; j<atom1List->size(); j++)
03121 {
03122 int atom2 = atom1List->at(j);
03123 if(atom1<atom2)
03124 allExcls.add(Exclusion(atom1, atom2));
03125 else
03126 allExcls.add(Exclusion(atom2, atom1));
03127 }
03128 }
03129 }
03130
03131 void build13Excls(UniqueSet<Exclusion>& allExcls, vector<int> *eachAtomNeighbors)
03132 {
03133 for(int atom1=0; atom1<g_mol->numAtoms; atom1++)
03134 {
03135 vector<int> *atom1List = &eachAtomNeighbors[atom1];
03136 for(int j=0; j<atom1List->size(); j++)
03137 {
03138 int atom2 = atom1List->at(j);
03139 vector<int> *atom2List = &eachAtomNeighbors[atom2];
03140 for(int k=0; k<atom2List->size(); k++)
03141 {
03142 int atom3 = atom2List->at(k);
03143
03144 if(atom3 == atom1)
03145 continue;
03146 if(atom1<atom3)
03147 allExcls.add(Exclusion(atom1, atom3));
03148 else
03149 allExcls.add(Exclusion(atom3, atom1));
03150 }
03151 }
03152 }
03153 }
03154
03155 void build14Excls(UniqueSet<Exclusion>& allExcls, vector<int> *eachAtomNeighbors, int modified)
03156 {
03157 for(int atom1=0; atom1<g_mol->numAtoms; atom1++)
03158 {
03159 vector<int> *atom1List = &eachAtomNeighbors[atom1];
03160 for(int j=0; j<atom1List->size(); j++)
03161 {
03162 int atom2 = atom1List->at(j);
03163 vector<int> *atom2List = &eachAtomNeighbors[atom2];
03164 for(int k=0; k<atom2List->size(); k++)
03165 {
03166 int atom3 = atom2List->at(k);
03167
03168 if(atom3 == atom1)
03169 continue;
03170 vector<int> *atom3List = &eachAtomNeighbors[atom3];
03171 for(int l=0; l<atom3List->size(); l++)
03172 {
03173 int atom4 = atom3List->at(l);
03174
03175 if(atom4 == atom2)
03176 continue;
03177 if(atom1<atom4)
03178 allExcls.add(Exclusion(atom1, atom4, modified));
03179 else
03180 allExcls.add(Exclusion(atom4, atom1, modified));
03181 }
03182 }
03183 }
03184 }
03185 }
03186
03187 template <class T> void HashPool<T>::dump_tables()
03188 {
03189 for(int j=0; j < pool.size(); j++) {
03190 HashPoolAdaptorT<T>* pval = pool[j];
03191 CmiPrintf("Pool[%d]=%p %p hash = %d\n",j,pool[j],pval,pval->hash());
03192 }
03193 CkHashtableIterator *iter = index_table.iterator();
03194 void *key,*indx;
03195 while (iter->hasNext()) {
03196 indx = iter->next(&key);
03197 HashPoolAdaptorT<T> *pkey = (HashPoolAdaptorT<T>*)key;
03198 CmiPrintf("key %p indx %p %d hash=%d\n",key,indx,*((int *)indx),pkey->hash());
03199 }
03200 }