Changes in src/molecule.cpp [f8e486:bab12a]
- File:
-
- 1 edited
-
src/molecule.cpp (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/molecule.cpp
rf8e486 rbab12a 4 4 * 5 5 */ 6 7 #include "Helpers/MemDebug.hpp"8 6 9 7 #include <cstring> … … 37 35 * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero. 38 36 */ 39 molecule::molecule(const periodentafel * const teil) : 40 Observable("molecule"), 41 elemente(teil), MDSteps(0), BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0), 42 NoCyclicBonds(0), BondDistance(0.), ActiveFlag(false), IndexNr(-1), 43 formula(this,boost::bind(&molecule::calcFormula,this),"formula"), 44 AtomCount(this,boost::bind(&molecule::doCountAtoms,this),"AtomCount"), last_atom(0), InternalPointer(begin()) 45 { 37 molecule::molecule(const periodentafel * const teil) : elemente(teil), start(World::getInstance().createAtom()), end(World::getInstance().createAtom()), 38 first(new bond(start, end, 1, -1)), last(new bond(start, end, 1, -1)), MDSteps(0), AtomCount(0), 39 BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0), NoCyclicBonds(0), BondDistance(0.), 40 ActiveFlag(false), IndexNr(-1), 41 formula(this,boost::bind(&molecule::calcFormula,this)), 42 last_atom(0), 43 InternalPointer(start) 44 { 45 // init atom chain list 46 start->father = NULL; 47 end->father = NULL; 48 link(start,end); 49 50 // init bond chain list 51 link(first,last); 46 52 47 53 // other stuff … … 61 67 { 62 68 CleanupMolecule(); 69 delete(first); 70 delete(last); 71 end->getWorld()->destroyAtom(end); 72 start->getWorld()->destroyAtom(start); 63 73 }; 64 74 … … 73 83 } 74 84 75 int molecule::getAtomCount() const{76 return *AtomCount;77 }78 79 85 void molecule::setName(const std::string _name){ 80 86 OBSERVE; … … 98 104 stringstream sstr; 99 105 periodentafel *periode = World::getInstance().getPeriode(); 100 for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {101 counts[ (*iter)->type->getNumber()]++;106 for(atom *Walker = start; Walker != end; Walker = Walker->next) { 107 counts[Walker->type->getNumber()]++; 102 108 } 103 109 std::map<atomicNumber_t,unsigned int>::reverse_iterator iter; … … 109 115 } 110 116 111 /************************** Access to the List of Atoms ****************/112 113 114 molecule::iterator molecule::begin(){115 return molecule::iterator(atoms.begin(),this);116 }117 118 molecule::const_iterator molecule::begin() const{119 return atoms.begin();120 }121 122 molecule::iterator molecule::end(){123 return molecule::iterator(atoms.end(),this);124 }125 126 molecule::const_iterator molecule::end() const{127 return atoms.end();128 }129 130 bool molecule::empty() const131 {132 return (begin() == end());133 }134 135 size_t molecule::size() const136 {137 size_t counter = 0;138 for (molecule::const_iterator iter = begin(); iter != end (); ++iter)139 counter++;140 return counter;141 }142 143 molecule::const_iterator molecule::erase( const_iterator loc )144 {145 molecule::const_iterator iter = loc;146 iter--;147 atom* atom = *loc;148 atoms.erase( loc );149 atom->removeFromMolecule();150 return iter;151 }152 153 molecule::const_iterator molecule::erase( atom * key )154 {155 cout << "trying to erase atom" << endl;156 molecule::const_iterator iter = find(key);157 if (iter != end()){158 atoms.erase( iter++ );159 key->removeFromMolecule();160 }161 return iter;162 }163 164 molecule::const_iterator molecule::find ( atom * key ) const165 {166 return atoms.find( key );167 }168 169 pair<molecule::iterator,bool> molecule::insert ( atom * const key )170 {171 pair<atomSet::iterator,bool> res = atoms.insert(key);172 return pair<iterator,bool>(iterator(res.first,this),res.second);173 }174 175 bool molecule::containsAtom(atom* key){176 return atoms.count(key);177 }178 117 179 118 /** Adds given atom \a *pointer from molecule list. … … 184 123 bool molecule::AddAtom(atom *pointer) 185 124 { 125 bool retval = false; 186 126 OBSERVE; 187 127 if (pointer != NULL) { 188 128 pointer->sort = &pointer->nr; 129 pointer->nr = last_atom++; // increase number within molecule 130 AtomCount++; 189 131 if (pointer->type != NULL) { 190 132 if (ElementsInMolecule[pointer->type->Z] == 0) … … 199 141 } 200 142 } 201 insert(pointer); 202 pointer->setMolecule(this); 203 } 204 return true; 143 retval = add(pointer, end); 144 } 145 return retval; 205 146 }; 206 147 … … 216 157 if (pointer != NULL) { 217 158 atom *walker = pointer->clone(); 218 walker->setName(pointer->getName()); 159 stringstream sstr; 160 sstr << pointer->getName(); 161 walker->setName(sstr.str()); 219 162 walker->nr = last_atom++; // increase number within molecule 220 insert(walker);163 add(walker, end); 221 164 if ((pointer->type != NULL) && (pointer->type->Z != 1)) 222 165 NoNonHydrogen++; 166 AtomCount++; 223 167 retval=walker; 224 168 } … … 298 242 Orthovector1.MatrixMultiplication(matrix); 299 243 InBondvector -= Orthovector1; // subtract just the additional translation 300 delete[](matrix);244 Free(&matrix); 301 245 bondlength = InBondvector.Norm(); 302 246 // Log() << Verbose(4) << "Corrected InBondvector is now: "; … … 307 251 InBondvector.Normalize(); 308 252 // get typical bond length and store as scale factor for later 309 ASSERT(TopOrigin->type != NULL, "AddHydrogenReplacementAtom: element of TopOrigin is not given.");310 253 BondRescale = TopOrigin->type->HBondDistance[TopBond->BondDegree-1]; 311 254 if (BondRescale == -1) { … … 529 472 break; 530 473 } 531 delete[](matrix);474 Free(&matrix); 532 475 533 476 // Log() << Verbose(3) << "End of AddHydrogenReplacementAtom." << endl; … … 612 555 613 556 // copy all bonds 614 bond *Binder = NULL;557 bond *Binder = first; 615 558 bond *NewBond = NULL; 616 for(molecule::iterator AtomRunner = begin(); AtomRunner != end(); ++AtomRunner) 617 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin()) 618 if ((*BondRunner)->leftatom == *AtomRunner) { 619 Binder = (*BondRunner); 620 621 // get the pendant atoms of current bond in the copy molecule 622 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 623 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 624 625 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 626 NewBond->Cyclic = Binder->Cyclic; 627 if (Binder->Cyclic) 628 copy->NoCyclicBonds++; 629 NewBond->Type = Binder->Type; 630 } 559 while(Binder->next != last) { 560 Binder = Binder->next; 561 562 // get the pendant atoms of current bond in the copy molecule 563 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->leftatom, (const atom **)&LeftAtom ); 564 copy->ActOnAllAtoms( &atom::EqualsFather, (const atom *)Binder->rightatom, (const atom **)&RightAtom ); 565 566 NewBond = copy->AddBond(LeftAtom, RightAtom, Binder->BondDegree); 567 NewBond->Cyclic = Binder->Cyclic; 568 if (Binder->Cyclic) 569 copy->NoCyclicBonds++; 570 NewBond->Type = Binder->Type; 571 } 631 572 // correct fathers 632 573 ActOnAllAtoms( &atom::CorrectFather ); 633 574 634 575 // copy values 576 copy->CountAtoms(); 635 577 copy->CountElements(); 636 if ( hasBondStructure()) { // if adjaceny list is present578 if (first->next != last) { // if adjaceny list is present 637 579 copy->BondDistance = BondDistance; 638 580 } … … 666 608 bond * molecule::AddBond(atom *atom1, atom *atom2, int degree) 667 609 { 668 OBSERVE;669 610 bond *Binder = NULL; 670 671 // some checks to make sure we are able to create the bond 672 ASSERT(atom1, "First atom in bond-creation was an invalid pointer"); 673 ASSERT(atom2, "Second atom in bond-creation was an invalid pointer"); 674 ASSERT(FindAtom(atom1->nr),"First atom in bond-creation was not part of molecule"); 675 ASSERT(FindAtom(atom2->nr),"Second atom in bond-creation was not parto of molecule"); 676 677 Binder = new bond(atom1, atom2, degree, BondCount++); 678 atom1->RegisterBond(Binder); 679 atom2->RegisterBond(Binder); 680 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1)) 681 NoNonBonds++; 682 611 if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) { 612 Binder = new bond(atom1, atom2, degree, BondCount++); 613 atom1->RegisterBond(Binder); 614 atom2->RegisterBond(Binder); 615 if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1)) 616 NoNonBonds++; 617 add(Binder, last); 618 } else { 619 DoeLog(1) && (eLog()<< Verbose(1) << "Could not add bond between " << atom1->getName() << " and " << atom2->getName() << " as one or both are not present in the molecule." << endl); 620 } 683 621 return Binder; 684 622 }; … … 692 630 { 693 631 //DoeLog(1) && (eLog()<< Verbose(1) << "molecule::RemoveBond: Function not implemented yet." << endl); 694 delete(pointer); 632 pointer->leftatom->RegisterBond(pointer); 633 pointer->rightatom->RegisterBond(pointer); 634 removewithoutcheck(pointer); 695 635 return true; 696 636 }; … … 752 692 bool molecule::RemoveAtom(atom *pointer) 753 693 { 754 ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom().");755 OBSERVE;756 694 if (ElementsInMolecule[pointer->type->Z] != 0) { // this would indicate an error 757 695 ElementsInMolecule[pointer->type->Z]--; // decrease number of atom of this element 696 AtomCount--; 758 697 } else 759 698 DoeLog(1) && (eLog()<< Verbose(1) << "Atom " << pointer->getName() << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl); … … 761 700 ElementCount--; 762 701 RemoveBonds(pointer); 763 erase(pointer); 764 return true; 702 return remove(pointer, start, end); 765 703 }; 766 704 … … 779 717 if (ElementsInMolecule[pointer->type->Z] == 0) // was last atom of this element? 780 718 ElementCount--; 781 erase(pointer);719 unlink(pointer); 782 720 return true; 783 721 }; … … 788 726 bool molecule::CleanupMolecule() 789 727 { 790 for (molecule::iterator iter = begin(); !empty(); iter = begin()) 791 erase(iter); 728 return (cleanup(first,last) && cleanup(start,end)); 792 729 }; 793 730 … … 796 733 * \return pointer to atom or NULL 797 734 */ 798 atom * molecule::FindAtom(int Nr) const 799 { 800 molecule::const_iterator iter = begin(); 801 for (; iter != end(); ++iter) 802 if ((*iter)->nr == Nr) 803 break; 804 if (iter != end()) { 735 atom * molecule::FindAtom(int Nr) const{ 736 atom * walker = find(&Nr, start,end); 737 if (walker != NULL) { 805 738 //Log() << Verbose(0) << "Found Atom Nr. " << walker->nr << endl; 806 return (*iter);739 return walker; 807 740 } else { 808 741 DoLog(0) && (Log() << Verbose(0) << "Atom not found in list." << endl); … … 934 867 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 935 868 for (int step=0;step<MDSteps;step++) { 936 *output << getAtomCount()<< "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);869 *output << AtomCount << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now); 937 870 ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step ); 938 871 } … … 951 884 if (output != NULL) { 952 885 now = time((time_t *)NULL); // Get the system time and put it into 'now' as 'calender time' 953 *output << getAtomCount()<< "\n\tCreated by molecuilder on " << ctime(&now);886 *output << AtomCount << "\n\tCreated by molecuilder on " << ctime(&now); 954 887 ActOnAllAtoms( &atom::OutputXYZLine, output ); 955 888 return true; … … 961 894 * \param *out output stream for debugging 962 895 */ 963 int molecule::doCountAtoms() 964 { 965 int res = size(); 896 void molecule::CountAtoms() 897 { 966 898 int i = 0; 967 NoNonHydrogen = 0; 968 for (molecule::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) { 969 (*iter)->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 970 if ((*iter)->type->Z != 1) // count non-hydrogen atoms whilst at it 971 NoNonHydrogen++; 972 stringstream sstr; 973 sstr << (*iter)->type->symbol << (*iter)->nr+1; 974 (*iter)->setName(sstr.str()); 975 DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl); 899 atom *Walker = start; 900 while (Walker->next != end) { 901 Walker = Walker->next; 976 902 i++; 977 903 } 978 return res; 904 if ((AtomCount == 0) || (i != AtomCount)) { 905 DoLog(3) && (Log() << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl); 906 AtomCount = i; 907 908 // count NonHydrogen atoms and give each atom a unique name 909 if (AtomCount != 0) { 910 i=0; 911 NoNonHydrogen = 0; 912 Walker = start; 913 while (Walker->next != end) { 914 Walker = Walker->next; 915 Walker->nr = i; // update number in molecule (for easier referencing in FragmentMolecule lateron) 916 if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it 917 NoNonHydrogen++; 918 stringstream sstr; 919 sstr << Walker->type->symbol << Walker->nr+1; 920 Walker->setName(sstr.str()); 921 DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << Walker->nr << " " << Walker->getName() << "." << endl); 922 i++; 923 } 924 } else 925 DoLog(3) && (Log() << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl); 926 } 979 927 }; 980 928 … … 1038 986 /// first count both their atoms and elements and update lists thereby ... 1039 987 //Log() << Verbose(0) << "Counting atoms, updating list" << endl; 988 CountAtoms(); 989 OtherMolecule->CountAtoms(); 1040 990 CountElements(); 1041 991 OtherMolecule->CountElements(); … … 1044 994 /// -# AtomCount 1045 995 if (result) { 1046 if ( getAtomCount() != OtherMolecule->getAtomCount()) {1047 DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount()<< endl);996 if (AtomCount != OtherMolecule->AtomCount) { 997 DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl); 1048 998 result = false; 1049 } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount()<< endl;999 } else Log() << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl; 1050 1000 } 1051 1001 /// -# ElementCount … … 1084 1034 if (result) { 1085 1035 DoLog(5) && (Log() << Verbose(5) << "Calculating distances" << endl); 1086 Distances = new double[getAtomCount()];1087 OtherDistances = new double[getAtomCount()];1036 Distances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: Distances"); 1037 OtherDistances = Calloc<double>(AtomCount, "molecule::IsEqualToWithinThreshold: OtherDistances"); 1088 1038 SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity); 1089 1039 SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity); 1090 for(int i=0;i<getAtomCount();i++) {1091 Distances[i] = 0.;1092 OtherDistances[i] = 0.;1093 }1094 1040 1095 1041 /// ... sort each list (using heapsort (o(N log N)) from GSL) 1096 1042 DoLog(5) && (Log() << Verbose(5) << "Sorting distances" << endl); 1097 PermMap = new size_t[getAtomCount()]; 1098 OtherPermMap = new size_t[getAtomCount()]; 1099 for(int i=0;i<getAtomCount();i++) { 1100 PermMap[i] = 0; 1101 OtherPermMap[i] = 0; 1102 } 1103 gsl_heapsort_index (PermMap, Distances, getAtomCount(), sizeof(double), CompareDoubles); 1104 gsl_heapsort_index (OtherPermMap, OtherDistances, getAtomCount(), sizeof(double), CompareDoubles); 1105 PermutationMap = new int[getAtomCount()]; 1106 for(int i=0;i<getAtomCount();i++) 1107 PermutationMap[i] = 0; 1043 PermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermMap"); 1044 OtherPermMap = Calloc<size_t>(AtomCount, "molecule::IsEqualToWithinThreshold: *OtherPermMap"); 1045 gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles); 1046 gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles); 1047 PermutationMap = Calloc<int>(AtomCount, "molecule::IsEqualToWithinThreshold: *PermutationMap"); 1108 1048 DoLog(5) && (Log() << Verbose(5) << "Combining Permutation Maps" << endl); 1109 for(int i= getAtomCount();i--;)1049 for(int i=AtomCount;i--;) 1110 1050 PermutationMap[PermMap[i]] = (int) OtherPermMap[i]; 1111 1051 … … 1113 1053 DoLog(4) && (Log() << Verbose(4) << "Comparing distances" << endl); 1114 1054 flag = 0; 1115 for (int i=0;i< getAtomCount();i++) {1055 for (int i=0;i<AtomCount;i++) { 1116 1056 DoLog(5) && (Log() << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " << threshold << endl); 1117 1057 if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold) … … 1120 1060 1121 1061 // free memory 1122 delete[](PermMap);1123 delete[](OtherPermMap);1124 delete[](Distances);1125 delete[](OtherDistances);1062 Free(&PermMap); 1063 Free(&OtherPermMap); 1064 Free(&Distances); 1065 Free(&OtherDistances); 1126 1066 if (flag) { // if not equal 1127 delete[](PermutationMap);1067 Free(&PermutationMap); 1128 1068 result = false; 1129 1069 } … … 1149 1089 int * molecule::GetFatherSonAtomicMap(molecule *OtherMolecule) 1150 1090 { 1091 atom *Walker = NULL, *OtherWalker = NULL; 1151 1092 DoLog(3) && (Log() << Verbose(3) << "Begin of GetFatherAtomicMap." << endl); 1152 int *AtomicMap = new int[getAtomCount()];1153 for (int i= getAtomCount();i--;)1093 int *AtomicMap = Malloc<int>(AtomCount, "molecule::GetAtomicMap: *AtomicMap"); 1094 for (int i=AtomCount;i--;) 1154 1095 AtomicMap[i] = -1; 1155 1096 if (OtherMolecule == this) { // same molecule 1156 for (int i= getAtomCount();i--;) // no need as -1 means already that there is trivial correspondence1097 for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence 1157 1098 AtomicMap[i] = i; 1158 1099 DoLog(4) && (Log() << Verbose(4) << "Map is trivial." << endl); 1159 1100 } else { 1160 1101 DoLog(4) && (Log() << Verbose(4) << "Map is "); 1161 for (molecule::const_iterator iter = begin(); iter != end(); ++iter) { 1162 if ((*iter)->father == NULL) { 1163 AtomicMap[(*iter)->nr] = -2; 1102 Walker = start; 1103 while (Walker->next != end) { 1104 Walker = Walker->next; 1105 if (Walker->father == NULL) { 1106 AtomicMap[Walker->nr] = -2; 1164 1107 } else { 1165 for (molecule::const_iterator runner = OtherMolecule->begin(); runner != OtherMolecule->end(); ++runner) { 1108 OtherWalker = OtherMolecule->start; 1109 while (OtherWalker->next != OtherMolecule->end) { 1110 OtherWalker = OtherWalker->next; 1166 1111 //for (int i=0;i<AtomCount;i++) { // search atom 1167 //for (int j=0;j<OtherMolecule-> getAtomCount();j++) {1168 //Log() << Verbose(4) << "Comparing father " << (*iter)->father << " with the other one " << (*runner)->father << "." << endl;1169 if ( (*iter)->father == (*runner))1170 AtomicMap[ (*iter)->nr] = (*runner)->nr;1112 //for (int j=0;j<OtherMolecule->AtomCount;j++) { 1113 //Log() << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl; 1114 if (Walker->father == OtherWalker) 1115 AtomicMap[Walker->nr] = OtherWalker->nr; 1171 1116 } 1172 1117 } 1173 DoLog(0) && (Log() << Verbose(0) << AtomicMap[ (*iter)->nr] << "\t");1118 DoLog(0) && (Log() << Verbose(0) << AtomicMap[Walker->nr] << "\t"); 1174 1119 } 1175 1120 DoLog(0) && (Log() << Verbose(0) << endl); … … 1205 1150 void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::*index) const 1206 1151 { 1207 for (molecule::const_iterator iter = begin(); iter != end(); ++iter) { 1208 array[((*iter)->*index)] = (*iter); 1152 atom *Walker = start; 1153 while (Walker->next != end) { 1154 Walker = Walker->next; 1155 array[(Walker->*index)] = Walker; 1209 1156 } 1210 1157 };
Note:
See TracChangeset
for help on using the changeset viewer.
