Changes in src/molecule.cpp [83f176:952f38]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/molecule.cpp
r83f176 r952f38 1 /*2 * Project: MoleCuilder3 * Description: creates and alters molecular systems4 * 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 8 1 /** \file molecules.cpp 9 2 * … … 12 5 */ 13 6 14 // include config.h15 7 #ifdef HAVE_CONFIG_H 16 8 #include <config.h> … … 97 89 } 98 90 99 bool molecule::changeId(moleculeId_t newId){100 // first we move ourselves in the world101 // the world lets us know if that succeeded102 if(World::getInstance().changeMoleculeId(id,newId,this)){103 id = newId;104 return true;105 }106 else{107 return false;108 }109 }110 111 112 91 moleculeId_t molecule::getId(){ 113 92 return id; … … 172 151 molecule::const_iterator molecule::erase( const_iterator loc ) 173 152 { 174 OBSERVE;175 153 molecule::const_iterator iter = loc; 176 154 iter--; … … 178 156 atomIds.erase( atom->getId() ); 179 157 atoms.remove( atom ); 180 formula-=atom->getType();181 158 atom->removeFromMolecule(); 182 159 return iter; … … 185 162 molecule::const_iterator molecule::erase( atom * key ) 186 163 { 187 OBSERVE;188 164 molecule::const_iterator iter = find(key); 189 165 if (iter != end()){ 190 166 atomIds.erase( key->getId() ); 191 167 atoms.remove( key ); 192 formula-=key->getType();193 168 key->removeFromMolecule(); 194 169 } … … 208 183 pair<molecule::iterator,bool> molecule::insert ( atom * const key ) 209 184 { 210 OBSERVE;211 185 pair<atomIdSet::iterator,bool> res = atomIds.insert(key->getId()); 212 186 if (res.second) { // push atom if went well 213 187 atoms.push_back(key); 214 formula+=key->getType();215 188 return pair<iterator,bool>(molecule::iterator(--end()),res.second); 216 189 } else { … … 233 206 if (pointer != NULL) { 234 207 pointer->sort = &pointer->nr; 235 if (pointer->getType() != NULL) { 236 if (pointer->getType()->getAtomicNumber() != 1) 208 if (pointer->type != NULL) { 209 formula += pointer->type; 210 if (pointer->type->Z != 1) 237 211 NoNonHydrogen++; 238 212 if(pointer->getName() == "Unknown"){ 239 213 stringstream sstr; 240 sstr << pointer-> getType()->getSymbol()<< pointer->nr+1;214 sstr << pointer->type->symbol << pointer->nr+1; 241 215 pointer->setName(sstr.str()); 242 216 } … … 262 236 walker->nr = last_atom++; // increase number within molecule 263 237 insert(walker); 264 if ((pointer-> getType() != NULL) && (pointer->getType()->getAtomicNumber()!= 1))238 if ((pointer->type != NULL) && (pointer->type->Z != 1)) 265 239 NoNonHydrogen++; 266 240 retval=walker; … … 320 294 // Log() << Verbose(3) << "Begin of AddHydrogenReplacementAtom." << endl; 321 295 // create vector in direction of bond 322 InBondvector = TopReplacement-> getPosition() - TopOrigin->getPosition();296 InBondvector = TopReplacement->x - TopOrigin->x; 323 297 bondlength = InBondvector.Norm(); 324 298 … … 332 306 Orthovector1.Zero(); 333 307 for (int i=NDIM;i--;) { 334 l = TopReplacement-> at(i) - TopOrigin->at(i);308 l = TopReplacement->x[i] - TopOrigin->x[i]; 335 309 if (fabs(l) > BondDistance) { // is component greater than bond distance 336 310 Orthovector1[i] = (l < 0) ? -1. : +1.; … … 347 321 InBondvector.Normalize(); 348 322 // get typical bond length and store as scale factor for later 349 ASSERT(TopOrigin-> getType()!= NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given.");350 BondRescale = TopOrigin-> getType()->getHBondDistance(TopBond->BondDegree-1);323 ASSERT(TopOrigin->type != NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given."); 324 BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1]; 351 325 if (BondRescale == -1) { 352 326 DoeLog(1) && (eLog()<< Verbose(1) << "There is no typical hydrogen bond distance in replacing bond (" << TopOrigin->getName() << "<->" << TopReplacement->getName() << ") of degree " << TopBond->BondDegree << "!" << endl); … … 362 336 case 1: 363 337 FirstOtherAtom = World::getInstance().createAtom(); // new atom 364 FirstOtherAtom-> setType(1); // element is Hydrogen365 FirstOtherAtom-> AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity338 FirstOtherAtom->type = elemente->FindElement(1); // element is Hydrogen 339 FirstOtherAtom->v = TopReplacement->v; // copy velocity 366 340 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 367 if (TopReplacement-> getType()->getAtomicNumber()== 1) { // neither rescale nor replace if it's already hydrogen341 if (TopReplacement->type->Z == 1) { // neither rescale nor replace if it's already hydrogen 368 342 FirstOtherAtom->father = TopReplacement; 369 343 BondRescale = bondlength; … … 372 346 } 373 347 InBondvector *= BondRescale; // rescale the distance vector to Hydrogen bond length 374 FirstOtherAtom->setPosition(TopOrigin->getPosition() + InBondvector); // set coordination to origin and add distance vector to replacement atom 348 FirstOtherAtom->x = TopOrigin->x; // set coordination to origin ... 349 FirstOtherAtom->x += InBondvector; // ... and add distance vector to replacement atom 375 350 AllWentWell = AllWentWell && AddAtom(FirstOtherAtom); 376 351 // Log() << Verbose(4) << "Added " << *FirstOtherAtom << " at: "; … … 405 380 // determine the plane of these two with the *origin 406 381 try { 407 Orthovector1 =Plane(TopOrigin-> getPosition(), FirstOtherAtom->getPosition(), SecondOtherAtom->getPosition()).getNormal();382 Orthovector1 =Plane(TopOrigin->x, FirstOtherAtom->x, SecondOtherAtom->x).getNormal(); 408 383 } 409 384 catch(LinearDependenceException &excp){ … … 426 401 FirstOtherAtom = World::getInstance().createAtom(); 427 402 SecondOtherAtom = World::getInstance().createAtom(); 428 FirstOtherAtom-> setType(1);429 SecondOtherAtom-> setType(1);430 FirstOtherAtom-> AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity403 FirstOtherAtom->type = elemente->FindElement(1); 404 SecondOtherAtom->type = elemente->FindElement(1); 405 FirstOtherAtom->v = TopReplacement->v; // copy velocity 431 406 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 432 SecondOtherAtom-> AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity407 SecondOtherAtom->v = TopReplacement->v; // copy velocity 433 408 SecondOtherAtom->FixedIon = TopReplacement->FixedIon; 434 409 FirstOtherAtom->father = NULL; // we are just an added hydrogen with no father 435 410 SecondOtherAtom->father = NULL; // we are just an added hydrogen with no father 436 bondangle = TopOrigin-> getType()->getHBondAngle(1);411 bondangle = TopOrigin->type->HBondAngle[1]; 437 412 if (bondangle == -1) { 438 413 DoeLog(1) && (eLog()<< Verbose(1) << "There is no typical hydrogen bond angle in replacing bond (" << TopOrigin->getName() << "<->" << TopReplacement->getName() << ") of degree " << TopBond->BondDegree << "!" << endl); … … 448 423 // Log() << Verbose(0) << endl; 449 424 // Log() << Verbose(3) << "Half the bond angle is " << bondangle << ", sin and cos of it: " << sin(bondangle) << ", " << cos(bondangle) << endl; 450 FirstOtherAtom-> Zero();451 SecondOtherAtom-> Zero();425 FirstOtherAtom->x.Zero(); 426 SecondOtherAtom->x.Zero(); 452 427 for(int i=NDIM;i--;) { // rotate by half the bond angle in both directions (InBondvector is bondangle = 0 direction) 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 BondDistance457 SecondOtherAtom-> Scale(BondRescale);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 BondDistance 432 SecondOtherAtom->x *= BondRescale; 458 433 //Log() << Verbose(3) << "ReScaleCheck: " << FirstOtherAtom->x.Norm() << " and " << SecondOtherAtom->x.Norm() << "." << endl; 459 *FirstOtherAtom += TopOrigin->getPosition(); 460 *SecondOtherAtom += TopOrigin->getPosition(); 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 } 461 438 // ... and add to molecule 462 439 AllWentWell = AllWentWell && AddAtom(FirstOtherAtom); … … 480 457 SecondOtherAtom = World::getInstance().createAtom(); 481 458 ThirdOtherAtom = World::getInstance().createAtom(); 482 FirstOtherAtom-> setType(1);483 SecondOtherAtom-> setType(1);484 ThirdOtherAtom-> setType(1);485 FirstOtherAtom-> AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity459 FirstOtherAtom->type = elemente->FindElement(1); 460 SecondOtherAtom->type = elemente->FindElement(1); 461 ThirdOtherAtom->type = elemente->FindElement(1); 462 FirstOtherAtom->v = TopReplacement->v; // copy velocity 486 463 FirstOtherAtom->FixedIon = TopReplacement->FixedIon; 487 SecondOtherAtom-> AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity464 SecondOtherAtom->v = TopReplacement->v; // copy velocity 488 465 SecondOtherAtom->FixedIon = TopReplacement->FixedIon; 489 ThirdOtherAtom-> AtomicVelocity = TopReplacement->AtomicVelocity; // copy velocity466 ThirdOtherAtom->v = TopReplacement->v; // copy velocity 490 467 ThirdOtherAtom->FixedIon = TopReplacement->FixedIon; 491 468 FirstOtherAtom->father = NULL; // we are just an added hydrogen with no father … … 510 487 511 488 // create correct coordination for the three atoms 512 alpha = (TopOrigin-> getType()->getHBondAngle(2))/180.*M_PI/2.; // retrieve triple bond angle from database489 alpha = (TopOrigin->type->HBondAngle[2])/180.*M_PI/2.; // retrieve triple bond angle from database 513 490 l = BondRescale; // desired bond length 514 491 b = 2.*l*sin(alpha); // base length of isosceles triangle … … 521 498 factors[1] = f; 522 499 factors[2] = 0.; 523 FirstOtherAtom-> LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);500 FirstOtherAtom->x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 524 501 factors[1] = -0.5*f; 525 502 factors[2] = g; 526 SecondOtherAtom-> LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);503 SecondOtherAtom->x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 527 504 factors[2] = -g; 528 ThirdOtherAtom-> LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors);505 ThirdOtherAtom->x.LinearCombinationOfVectors(InBondvector, Orthovector1, Orthovector2, factors); 529 506 530 507 // rescale each to correct BondDistance … … 534 511 535 512 // and relative to *origin atom 536 *FirstOtherAtom += TopOrigin->getPosition();537 *SecondOtherAtom += TopOrigin->getPosition();538 *ThirdOtherAtom += TopOrigin->getPosition();513 FirstOtherAtom->x += TopOrigin->x; 514 SecondOtherAtom->x += TopOrigin->x; 515 ThirdOtherAtom->x += TopOrigin->x; 539 516 540 517 // ... and add to molecule … … 612 589 *item >> x[1]; 613 590 *item >> x[2]; 614 Walker-> setType(elemente->FindElement(shorthand));615 if (Walker-> getType()== NULL) {591 Walker->type = elemente->FindElement(shorthand); 592 if (Walker->type == NULL) { 616 593 DoeLog(1) && (eLog()<< Verbose(1) << "Could not parse the element at line: '" << line << "', setting to H."); 617 Walker-> setType(1);594 Walker->type = elemente->FindElement(1); 618 595 } 619 596 if (Walker->Trajectory.R.size() <= (unsigned int)MDSteps) { … … 622 599 Walker->Trajectory.F.resize(MDSteps+10); 623 600 } 624 Walker->setPosition(Vector(x));625 601 for(j=NDIM;j--;) { 602 Walker->x[j] = x[j]; 626 603 Walker->Trajectory.R.at(MDSteps-1)[j] = x[j]; 627 604 Walker->Trajectory.U.at(MDSteps-1)[j] = 0; … … 642 619 { 643 620 molecule *copy = World::getInstance().createMolecule(); 621 atom *LeftAtom = NULL, *RightAtom = NULL; 644 622 645 623 // copy all atoms 646 for_each(atoms.begin(),atoms.end(),bind1st(mem_fun(&molecule::AddCopyAtom),copy));624 ActOnCopyWithEachAtom ( &molecule::AddCopyAtom, copy ); 647 625 648 626 // copy all bonds 627 bond *Binder = NULL; 628 bond *NewBond = NULL; 649 629 for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) 650 630 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin()) 651 631 if ((*BondRunner)->leftatom == *AtomRunner) { 652 bond *Binder = (*BondRunner);632 Binder = (*BondRunner); 653 633 654 634 // get the pendant atoms of current bond in the copy molecule 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); 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); 663 639 NewBond->Cyclic = Binder->Cyclic; 664 640 if (Binder->Cyclic) … … 667 643 } 668 644 // correct fathers 669 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::CorrectFather));645 ActOnAllAtoms( &atom::CorrectFather ); 670 646 671 647 // copy values … … 718 694 atom1->RegisterBond(Binder); 719 695 atom2->RegisterBond(Binder); 720 if ((atom1-> getType() != NULL) && (atom1->getType()->getAtomicNumber() != 1) && (atom2->getType() != NULL) && (atom2->getType()->getAtomicNumber()!= 1))696 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1)) 721 697 NoNonBonds++; 722 698 … … 784 760 }; 785 761 786 /** Removes atom from molecule list and removes all of its bonds.762 /** Removes atom from molecule list and deletes it. 787 763 * \param *pointer atom to be removed 788 764 * \return true - succeeded, false - atom not found in list … … 792 768 ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom()."); 793 769 OBSERVE; 770 formula-=pointer->type; 794 771 RemoveBonds(pointer); 795 772 erase(pointer); … … 805 782 if (pointer == NULL) 806 783 return false; 784 formula-=pointer->type; 807 785 erase(pointer); 808 786 return true; … … 815 793 { 816 794 for (molecule::iterator iter = begin(); !empty(); iter = begin()) 817 erase(*iter);795 erase(iter); 818 796 return empty(); 819 797 }; … … 874 852 * \param *out output stream 875 853 */ 876 bool molecule::Output(ostream * const output) 877 { 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 } 878 862 if (output == NULL) { 879 863 return false; 880 864 } 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 }888 865 *output << "#Ion_TypeNr._Nr.R[0] R[1] R[2] MoveType (0 MoveIon, 1 FixedIon)" << endl; 889 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputArrayIndexed,_1,output,elementLookup,AtomNo,(const char*)0)); 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 ); 890 873 return true; 891 874 } … … 912 895 ElementNo[i] = 0; 913 896 } 914 for(molecule::iterator iter = begin(); iter != end(); ++iter) { 915 ElementNo[(*iter)->getType()->getAtomicNumber()] = 1; 916 } 897 SetIndexedArrayForEachAtomTo ( ElementNo, &element::Z, &AbsoluteValue, 1); 917 898 int current=1; 918 899 for (int i=0;i<MAX_ELEMENTS;++i) { … … 932 913 { 933 914 DoLog(2) && (Log() << Verbose(2) << endl << "From Contents of ListOfBonds, all non-hydrogen atoms:" << endl); 934 for_each(atoms.begin(),atoms.end(),mem_fun(&atom::OutputBondOfAtom));915 ActOnAllAtoms (&atom::OutputBondOfAtom ); 935 916 DoLog(0) && (Log() << Verbose(0) << endl); 936 917 }; … … 955 936 for (int step=0;step<MDSteps;step++) { 956 937 *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now); 957 for_each(atoms.begin(),atoms.end(),boost::bind(&atom::OutputTrajectoryXYZ,_1,output,step));938 ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step ); 958 939 } 959 940 return true; … … 972 953 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 973 954 *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now); 974 for_each(atoms.begin(),atoms.end(),bind2nd(mem_fun(&atom::OutputXYZLine),output));955 ActOnAllAtoms( &atom::OutputXYZLine, output ); 975 956 return true; 976 957 } else … … 988 969 for (molecule::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 989 970 (*iter)->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 990 if ((*iter)-> getType()->getAtomicNumber()!= 1) // count non-hydrogen atoms whilst at it971 if ((*iter)->type->Z != 1) // count non-hydrogen atoms whilst at it 991 972 NoNonHydrogen++; 992 973 stringstream sstr; 993 sstr << (*iter)-> getType()->getSymbol()<< (*iter)->nr+1;974 sstr << (*iter)->type->symbol << (*iter)->nr+1; 994 975 (*iter)->setName(sstr.str()); 995 976 DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl); … … 997 978 } 998 979 return res; 980 }; 981 982 /** Determines whether two molecules actually contain the same atoms and coordination. 983 * \param *out output stream for debugging 984 * \param *OtherMolecule the molecule to compare this one to 985 * \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 comparison 996 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 /// -# AtomCount 1003 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 /// -# Formula 1010 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 molecules 1030 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 all 1059 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 memory 1068 delete[](PermMap); 1069 delete[](OtherPermMap); 1070 delete[](Distances); 1071 delete[](OtherDistances); 1072 if (flag) { // if not equal 1073 delete[](PermutationMap); 1074 result = false; 1075 } 1076 } 1077 /// return pointer to map if all distances were below \a threshold 1078 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 } 999 1086 }; 1000 1087
Note:
See TracChangeset
for help on using the changeset viewer.