Changes in src/molecule.cpp [952f38:83f176]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecule.cpp
r952f38 r83f176 1 /* 2 * Project: MoleCuilder 3 * Description: creates and alters molecular systems 4 * Copyright (C) 2010 University of Bonn. All rights reserved. 5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. 6 */ 7 1 8 /** \file molecules.cpp 2 9 * … … 5 12 */ 6 13 14 // include config.h 7 15 #ifdef HAVE_CONFIG_H 8 16 #include <config.h> … … 89 97 } 90 98 99 bool molecule::changeId(moleculeId_t newId){ 100 // first we move ourselves in the world 101 // the world lets us know if that succeeded 102 if(World::getInstance().changeMoleculeId(id,newId,this)){ 103 id = newId; 104 return true; 105 } 106 else{ 107 return false; 108 } 109 } 110 111 91 112 moleculeId_t molecule::getId(){ 92 113 return id; … … 151 172 molecule::const_iterator molecule::erase( const_iterator loc ) 152 173 { 174 OBSERVE; 153 175 molecule::const_iterator iter = loc; 154 176 iter--; … … 156 178 atomIds.erase( atom->getId() ); 157 179 atoms.remove( atom ); 180 formula-=atom->getType(); 158 181 atom->removeFromMolecule(); 159 182 return iter; … … 162 185 molecule::const_iterator molecule::erase( atom * key ) 163 186 { 187 OBSERVE; 164 188 molecule::const_iterator iter = find(key); 165 189 if (iter != end()){ 166 190 atomIds.erase( key->getId() ); 167 191 atoms.remove( key ); 192 formula-=key->getType(); 168 193 key->removeFromMolecule(); 169 194 } … … 183 208 pair<molecule::iterator,bool> molecule::insert ( atom * const key ) 184 209 { 210 OBSERVE; 185 211 pair<atomIdSet::iterator,bool> res = atomIds.insert(key->getId()); 186 212 if (res.second) { // push atom if went well 187 213 atoms.push_back(key); 214 formula+=key->getType(); 188 215 return pair<iterator,bool>(molecule::iterator(--end()),res.second); 189 216 } else { … … 206 233 if (pointer != NULL) { 207 234 pointer->sort = &pointer->nr; 208 if (pointer->type != NULL) { 209 formula += pointer->type; 210 if (pointer->type->Z != 1) 235 if (pointer->getType() != NULL) { 236 if (pointer->getType()->getAtomicNumber() != 1) 211 237 NoNonHydrogen++; 212 238 if(pointer->getName() == "Unknown"){ 213 239 stringstream sstr; 214 sstr << pointer-> type->symbol<< pointer->nr+1;240 sstr << pointer->getType()->getSymbol() << pointer->nr+1; 215 241 pointer->setName(sstr.str()); 216 242 } … … 236 262 walker->nr = last_atom++; // increase number within molecule 237 263 insert(walker); 238 if ((pointer-> type != NULL) && (pointer->type->Z!= 1))264 if ((pointer->getType() != NULL) && (pointer->getType()->getAtomicNumber() != 1)) 239 265 NoNonHydrogen++; 240 266 retval=walker; … … 294 320 // Log() << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl; 295 321 // create vector in direction of bond 296 InBondvector = TopReplacement-> x - TopOrigin->x;322 InBondvector = TopReplacement->getPosition() - TopOrigin->getPosition(); 297 323 bondlength = InBondvector.Norm(); 298 324 … … 306 332 Orthovector1.Zero(); 307 333 for (int i=NDIM;i--;) { 308 l = TopReplacement-> x[i] - TopOrigin->x[i];334 l = TopReplacement->at(i) - TopOrigin->at(i); 309 335 if (fabs(l) > BondDistance) { // is component greater than bond distance 310 336 Orthovector1[i] = (l < 0) ? -1. : +1.; … … 321 347 InBondvector.Normalize(); 322 348 // get typical bond length and store as scale factor for later 323 ASSERT(TopOrigin-> type!= NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given.");324 BondRescale = TopOrigin-> type->HBondDistance[TopBond->BondDegree-1];349 ASSERT(TopOrigin->getType() != NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given."); 350 BondRescale = TopOrigin->getType()->getHBondDistance(TopBond->BondDegree-1); 325 351 if (BondRescale == -1) { 326 352 DoeLog(1) && (eLog()<< Verbose(1) << "There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->getName() << "<->" << TopReplacement->getName() << ") of degree " << TopBond->BondDegree << "!" << endl); … … 336 362 case 1: 337 363 FirstOtherAtom = World::getInstance().createAtom(); // new atom 338 FirstOtherAtom-> type = elemente->FindElement(1); // element is Hydrogen339 FirstOtherAtom-> v = TopReplacement->v; // copy velocity364 FirstOtherAtom->setType(1); // element is Hydrogen 365 FirstOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 340 366 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 341 if (TopReplacement-> type->Z== 1) { // neither rescale nor replace if it's already hydrogen367 if (TopReplacement->getType()->getAtomicNumber() == 1) { // neither rescale nor replace if it's already hydrogen 342 368 FirstOtherAtom->father = TopReplacement; 343 369 BondRescale = bondlength; … … 346 372 } 347 373 InBondvector *= BondRescale; // rescale the distance vector to Hydrogen bond length 348 FirstOtherAtom->x = TopOrigin->x; // set coordination to origin ... 349 FirstOtherAtom->x += InBondvector; // ... and add distance vector to replacement atom 374 FirstOtherAtom->setPosition(TopOrigin->getPosition() + InBondvector); // set coordination to origin and add distance vector to replacement atom 350 375 AllWentWell = AllWentWell && AddAtom(FirstOtherAtom); 351 376 // Log() << Verbose(4) << "Added " << *FirstOtherAtom << " at: "; … … 380 405 // determine the plane of these two with the *origin 381 406 try { 382 Orthovector1 =Plane(TopOrigin-> x, FirstOtherAtom->x, SecondOtherAtom->x).getNormal();407 Orthovector1 =Plane(TopOrigin->getPosition(), FirstOtherAtom->getPosition(), SecondOtherAtom->getPosition()).getNormal(); 383 408 } 384 409 catch(LinearDependenceException &excp){ … … 401 426 FirstOtherAtom = World::getInstance().createAtom(); 402 427 SecondOtherAtom = World::getInstance().createAtom(); 403 FirstOtherAtom-> type = elemente->FindElement(1);404 SecondOtherAtom-> type = elemente->FindElement(1);405 FirstOtherAtom-> v = TopReplacement->v; // copy velocity428 FirstOtherAtom->setType(1); 429 SecondOtherAtom->setType(1); 430 FirstOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 406 431 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 407 SecondOtherAtom-> v = TopReplacement->v; // copy velocity432 SecondOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 408 433 SecondOtherAtom->FixedIon = TopReplacement->FixedIon; 409 434 FirstOtherAtom->father = NULL; // we are just an added hydrogen with no father 410 435 SecondOtherAtom->father = NULL; // we are just an added hydrogen with no father 411 bondangle = TopOrigin-> type->HBondAngle[1];436 bondangle = TopOrigin->getType()->getHBondAngle(1); 412 437 if (bondangle == -1) { 413 438 DoeLog(1) && (eLog()<< Verbose(1) << "There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->getName() << "<->" << TopReplacement->getName() << ") of degree " << TopBond->BondDegree << "!" << endl); … … 423 448 // Log() << Verbose(0) << endl; 424 449 // Log() << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl; 425 FirstOtherAtom-> x.Zero();426 SecondOtherAtom-> x.Zero();450 FirstOtherAtom->Zero(); 451 SecondOtherAtom->Zero(); 427 452 for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction) 428 FirstOtherAtom-> x[i] = InBondvector[i] * cos(bondangle) + Orthovector1[i] * (sin(bondangle));429 SecondOtherAtom-> x[i] = InBondvector[i] * cos(bondangle) + Orthovector1[i] * (-sin(bondangle));430 } 431 FirstOtherAtom-> x *= BondRescale; // rescale by correct BondDistance432 SecondOtherAtom-> x *= BondRescale;453 FirstOtherAtom->set(i, InBondvector[i] * cos(bondangle) + Orthovector1[i] * (sin(bondangle))); 454 SecondOtherAtom->set(i, InBondvector[i] * cos(bondangle) + Orthovector1[i] * (-sin(bondangle))); 455 } 456 FirstOtherAtom->Scale(BondRescale); // rescale by correct BondDistance 457 SecondOtherAtom->Scale(BondRescale); 433 458 //Log() << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl; 434 for(int i=NDIM;i--;) { // and make relative to origin atom 435 FirstOtherAtom->x[i] += TopOrigin->x[i]; 436 SecondOtherAtom->x[i] += TopOrigin->x[i]; 437 } 459 *FirstOtherAtom += TopOrigin->getPosition(); 460 *SecondOtherAtom += TopOrigin->getPosition(); 438 461 // ... and add to molecule 439 462 AllWentWell = AllWentWell && AddAtom(FirstOtherAtom); … … 457 480 SecondOtherAtom = World::getInstance().createAtom(); 458 481 ThirdOtherAtom = World::getInstance().createAtom(); 459 FirstOtherAtom-> type = elemente->FindElement(1);460 SecondOtherAtom-> type = elemente->FindElement(1);461 ThirdOtherAtom-> type = elemente->FindElement(1);462 FirstOtherAtom-> v = TopReplacement->v; // copy velocity482 FirstOtherAtom->setType(1); 483 SecondOtherAtom->setType(1); 484 ThirdOtherAtom->setType(1); 485 FirstOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 463 486 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 464 SecondOtherAtom-> v = TopReplacement->v; // copy velocity487 SecondOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 465 488 SecondOtherAtom->FixedIon = TopReplacement->FixedIon; 466 ThirdOtherAtom-> v = TopReplacement->v; // copy velocity489 ThirdOtherAtom->AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity 467 490 ThirdOtherAtom->FixedIon = TopReplacement->FixedIon; 468 491 FirstOtherAtom->father = NULL; // we are just an added hydrogen with no father … … 487 510 488 511 // create correct coordination for the three atoms 489 alpha = (TopOrigin-> type->HBondAngle[2])/180.*M_PI/2.; // retrieve triple bond angle from database512 alpha = (TopOrigin->getType()->getHBondAngle(2))/180.*M_PI/2.; // retrieve triple bond angle from database 490 513 l = BondRescale; // desired bond length 491 514 b = 2.*l*sin(alpha); // base length of isosceles triangle … … 498 521 factors[1] = f; 499 522 factors[2] = 0.; 500 FirstOtherAtom-> x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);523 FirstOtherAtom->LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 501 524 factors[1] = -0.5*f; 502 525 factors[2] = g; 503 SecondOtherAtom-> x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);526 SecondOtherAtom->LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 504 527 factors[2] = -g; 505 ThirdOtherAtom-> x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);528 ThirdOtherAtom->LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 506 529 507 530 // rescale each to correct BondDistance … … 511 534 512 535 // and relative to *origin atom 513 FirstOtherAtom->x += TopOrigin->x;514 SecondOtherAtom->x += TopOrigin->x;515 ThirdOtherAtom->x += TopOrigin->x;536 *FirstOtherAtom += TopOrigin->getPosition(); 537 *SecondOtherAtom += TopOrigin->getPosition(); 538 *ThirdOtherAtom += TopOrigin->getPosition(); 516 539 517 540 // ... and add to molecule … … 589 612 *item >> x[1]; 590 613 *item >> x[2]; 591 Walker-> type = elemente->FindElement(shorthand);592 if (Walker-> type== NULL) {614 Walker->setType(elemente->FindElement(shorthand)); 615 if (Walker->getType() == NULL) { 593 616 DoeLog(1) && (eLog()<< Verbose(1) << "Could not parse the element at line: '" << line << "', setting to H."); 594 Walker-> type = elemente->FindElement(1);617 Walker->setType(1); 595 618 } 596 619 if (Walker->Trajectory.R.size() <= (unsigned int)MDSteps) { … … 599 622 Walker->Trajectory.F.resize(MDSteps+10); 600 623 } 624 Walker->setPosition(Vector(x)); 601 625 for(j=NDIM;j--;) { 602 Walker->x[j] = x[j];603 626 Walker->Trajectory.R.at(MDSteps-1)[j] = x[j]; 604 627 Walker->Trajectory.U.at(MDSteps-1)[j] = 0; … … 619 642 { 620 643 molecule *copy = World::getInstance().createMolecule(); 621 atom *LeftAtom = NULL, *RightAtom = NULL;622 644 623 645 // copy all atoms 624 ActOnCopyWithEachAtom ( &molecule::AddCopyAtom, copy);646 for_each(atoms.begin(),atoms.end(),bind1st(mem_fun(&molecule::AddCopyAtom),copy)); 625 647 626 648 // copy all bonds 627 bond *Binder = NULL;628 bond *NewBond = NULL;629 649 for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) 630 650 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin()) 631 651 if ((*BondRunner)->leftatom == *AtomRunner) { 632 Binder = (*BondRunner);652 bond *Binder = (*BondRunner); 633 653 634 654 // get the pendant atoms of current bond in the copy molecule 635 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 636 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 637 638 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 655 atomSet::iterator leftiter=find_if(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::isFather),Binder->leftatom)); 656 atomSet::iterator rightiter=find_if(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::isFather),Binder->rightatom)); 657 ASSERT(leftiter!=atoms.end(),"No original left atom for bondcopy found"); 658 ASSERT(leftiter!=atoms.end(),"No original right atom for bondcopy found"); 659 atom *LeftAtom = *leftiter; 660 atom *RightAtom = *rightiter; 661 662 bond *NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 639 663 NewBond->Cyclic = Binder->Cyclic; 640 664 if (Binder->Cyclic) … … 643 667 } 644 668 // correct fathers 645 ActOnAllAtoms( &atom::CorrectFather);669 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::CorrectFather)); 646 670 647 671 // copy values … … 694 718 atom1->RegisterBond(Binder); 695 719 atom2->RegisterBond(Binder); 696 if ((atom1-> type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z!= 1))720 if ((atom1->getType() != NULL) && (atom1->getType()->getAtomicNumber() != 1) && (atom2->getType() != NULL) && (atom2->getType()->getAtomicNumber() != 1)) 697 721 NoNonBonds++; 698 722 … … 760 784 }; 761 785 762 /** Removes atom from molecule list and deletes it.786 /** Removes atom from molecule list and removes all of its bonds. 763 787 * \param *pointer atom to be removed 764 788 * \return true - succeeded, false - atom not found in list … … 768 792 ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom()."); 769 793 OBSERVE; 770 formula-=pointer->type;771 794 RemoveBonds(pointer); 772 795 erase(pointer); … … 782 805 if (pointer == NULL) 783 806 return false; 784 formula-=pointer->type;785 807 erase(pointer); 786 808 return true; … … 793 815 { 794 816 for (molecule::iterator iter = begin(); !empty(); iter = begin()) 795 erase(iter);817 erase(*iter); 796 818 return empty(); 797 819 }; … … 852 874 * \param *out output stream 853 875 */ 854 bool molecule::Output(ofstream * const output) 855 { 856 int ElementNo[MAX_ELEMENTS], AtomNo[MAX_ELEMENTS]; 857 858 for (int i=0;i<MAX_ELEMENTS;++i) { 859 AtomNo[i] = 0; 860 ElementNo[i] = 0; 861 } 876 bool molecule::Output(ostream * const output) 877 { 862 878 if (output == NULL) { 863 879 return false; 864 880 } else { 881 int AtomNo[MAX_ELEMENTS]; 882 memset(AtomNo,0,(MAX_ELEMENTS-1)*sizeof(*AtomNo)); 883 enumeration<const element*> elementLookup = formula.enumerateElements(); 884 for(map<const element*,unsigned int>::iterator iter=elementLookup.there.begin(); 885 iter!=elementLookup.there.end();++iter){ 886 cout << "Enumerated element " << *iter->first << " with number " << iter->second << endl; 887 } 865 888 *output << "#Ion_TypeNr._Nr.R[0] R[1] R[2] MoveType (0 MoveIon, 1 FixedIon)" << endl; 866 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 867 int current=1; 868 for (int i=0;i<MAX_ELEMENTS;++i) { 869 if (ElementNo[i] == 1) 870 ElementNo[i] = current++; 871 } 872 ActOnAllAtoms( &atom::OutputArrayIndexed, (ostream * const) output, (const int *)ElementNo, (int *)AtomNo, (const char *) NULL ); 889 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputArrayIndexed,_1,output,elementLookup,AtomNo,(const char*)0)); 873 890 return true; 874 891 } … … 895 912 ElementNo[i] = 0; 896 913 } 897 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 914 for(molecule::iterator iter = begin(); iter != end(); ++iter) { 915 ElementNo[(*iter)->getType()->getAtomicNumber()] = 1; 916 } 898 917 int current=1; 899 918 for (int i=0;i<MAX_ELEMENTS;++i) { … … 913 932 { 914 933 DoLog(2) && (Log() << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl); 915 ActOnAllAtoms (&atom::OutputBondOfAtom);934 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::OutputBondOfAtom)); 916 935 DoLog(0) && (Log() << Verbose(0) << endl); 917 936 }; … … 936 955 for (int step=0;step<MDSteps;step++) { 937 956 *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now); 938 ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step);957 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputTrajectoryXYZ,_1,output,step)); 939 958 } 940 959 return true; … … 953 972 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 954 973 *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now); 955 ActOnAllAtoms( &atom::OutputXYZLine, output);974 for_each(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::OutputXYZLine),output)); 956 975 return true; 957 976 } else … … 969 988 for (molecule::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 970 989 (*iter)->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 971 if ((*iter)-> type->Z!= 1) // count non-hydrogen atoms whilst at it990 if ((*iter)->getType()->getAtomicNumber() != 1) // count non-hydrogen atoms whilst at it 972 991 NoNonHydrogen++; 973 992 stringstream sstr; 974 sstr << (*iter)-> type->symbol<< (*iter)->nr+1;993 sstr << (*iter)->getType()->getSymbol() << (*iter)->nr+1; 975 994 (*iter)->setName(sstr.str()); 976 995 DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl); … … 978 997 } 979 998 return res; 980 };981 982 /** Determines whether two molecules actually contain the same atoms and coordination.983 * \param *out output stream for debugging984 * \param *OtherMolecule the molecule to compare this one to985 * \param threshold upper limit of difference when comparing the coordination.986 * \return NULL - not equal, otherwise an allocated (molecule::AtomCount) permutation map of the atom numbers (which corresponds to which)987 */988 int * molecule::IsEqualToWithinThreshold(molecule *OtherMolecule, double threshold)989 {990 int flag;991 double *Distances = NULL, *OtherDistances = NULL;992 Vector CenterOfGravity, OtherCenterOfGravity;993 size_t *PermMap = NULL, *OtherPermMap = NULL;994 int *PermutationMap = NULL;995 bool result = true; // status of comparison996 997 DoLog(3) && (Log() << Verbose(3) << "Begin of IsEqualToWithinThreshold." << endl);998 /// first count both their atoms and elements and update lists thereby ...999 //Log() << Verbose(0) << "Counting atoms, updating list" << endl;1000 1001 /// ... and compare:1002 /// -# AtomCount1003 if (result) {1004 if (getAtomCount() != OtherMolecule->getAtomCount()) {1005 DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl);1006 result = false;1007 } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl;1008 }1009 /// -# Formula1010 if (result) {1011 if (formula != OtherMolecule->formula) {1012 DoLog(4) && (Log() << Verbose(4) << "Formulas don't match: " << formula << " == " << OtherMolecule->formula << endl);1013 result = false;1014 } else Log() << Verbose(4) << "Formulas match: " << formula << " == " << OtherMolecule->formula << endl;1015 }1016 /// then determine and compare center of gravity for each molecule ...1017 if (result) {1018 DoLog(5) && (Log() << Verbose(5) << "Calculating Centers of Gravity" << endl);1019 DeterminePeriodicCenter(CenterOfGravity);1020 OtherMolecule->DeterminePeriodicCenter(OtherCenterOfGravity);1021 DoLog(5) && (Log() << Verbose(5) << "Center of Gravity: " << CenterOfGravity << endl);1022 DoLog(5) && (Log() << Verbose(5) << "Other Center of Gravity: " << OtherCenterOfGravity << endl);1023 if (CenterOfGravity.DistanceSquared(OtherCenterOfGravity) > threshold*threshold) {1024 DoLog(4) && (Log() << Verbose(4) << "Centers of gravity don't match." << endl);1025 result = false;1026 }1027 }1028 1029 /// ... then make a list with the euclidian distance to this center for each atom of both molecules1030 if (result) {1031 DoLog(5) && (Log() << Verbose(5) << "Calculating distances" << endl);1032 Distances = new double[getAtomCount()];1033 OtherDistances = new double[getAtomCount()];1034 SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);1035 SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);1036 for(int i=0;i<getAtomCount();i++) {1037 Distances[i] = 0.;1038 OtherDistances[i] = 0.;1039 }1040 1041 /// ... sort each list (using heapsort (o(N log N)) from GSL)1042 DoLog(5) && (Log() << Verbose(5) << "Sorting distances" << endl);1043 PermMap = new size_t[getAtomCount()];1044 OtherPermMap = new size_t[getAtomCount()];1045 for(int i=0;i<getAtomCount();i++) {1046 PermMap[i] = 0;1047 OtherPermMap[i] = 0;1048 }1049 gsl_heapsort_index (PermMap, Distances, getAtomCount(), sizeof(double), CompareDoubles);1050 gsl_heapsort_index (OtherPermMap, OtherDistances, getAtomCount(), sizeof(double), CompareDoubles);1051 PermutationMap = new int[getAtomCount()];1052 for(int i=0;i<getAtomCount();i++)1053 PermutationMap[i] = 0;1054 DoLog(5) && (Log() << Verbose(5) << "Combining Permutation Maps" << endl);1055 for(int i=getAtomCount();i--;)1056 PermutationMap[PermMap[i]] = (int) OtherPermMap[i];1057 1058 /// ... and compare them step by step, whether the difference is individually(!) below \a threshold for all1059 DoLog(4) && (Log() << Verbose(4) << "Comparing distances" << endl);1060 flag = 0;1061 for (int i=0;i<getAtomCount();i++) {1062 DoLog(5) && (Log() << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " << threshold << endl);1063 if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)1064 flag = 1;1065 }1066 1067 // free memory1068 delete[](PermMap);1069 delete[](OtherPermMap);1070 delete[](Distances);1071 delete[](OtherDistances);1072 if (flag) { // if not equal1073 delete[](PermutationMap);1074 result = false;1075 }1076 }1077 /// return pointer to map if all distances were below \a threshold1078 DoLog(3) && (Log() << Verbose(3) << "End of IsEqualToWithinThreshold." << endl);1079 if (result) {1080 DoLog(3) && (Log() << Verbose(3) << "Result: Equal." << endl);1081 return PermutationMap;1082 } else {1083 DoLog(3) && (Log() << Verbose(3) << "Result: Not equal." << endl);1084 return NULL;1085 }1086 999 }; 1087 1000
Note:
See TracChangeset
for help on using the changeset viewer.