source: src/Graph/CheckAgainstAdjacencyFile.cpp@ 0aa122

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 0aa122 was 0aa122, checked in by Frederik Heber <heber@…>, 13 years ago

Updated all source files's copyright note to current year 2012.

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * CheckAgainstAdjacencyFile.cpp
10 *
11 * Created on: Mar 3, 2011
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include <iostream>
23#include <map>
24#include <set>
25#include <utility>
26
27#include "CheckAgainstAdjacencyFile.hpp"
28
29#include "Atom/atom.hpp"
30#include "Bond/bond.hpp"
31#include "CodePatterns/Assert.hpp"
32#include "CodePatterns/Log.hpp"
33#include "CodePatterns/Range.hpp"
34#include "Descriptors/AtomIdDescriptor.hpp"
35#include "Helpers/defs.hpp"
36#include "World.hpp"
37
38CheckAgainstAdjacencyFile::CheckAgainstAdjacencyFile(World::AtomSet::const_iterator AtomMapBegin, World::AtomSet::const_iterator AtomMapEnd) :
39 status(true),
40 NonMatchNumber(0)
41{
42 CreateInternalMap(AtomMapBegin, AtomMapEnd);
43}
44
45CheckAgainstAdjacencyFile::~CheckAgainstAdjacencyFile()
46{
47 ExternalAtomBondMap.clear();
48 InternalAtomBondMap.clear();
49}
50
51/** Parses the bond partners of each atom from an external file into \a AtomBondMap.
52 *
53 * @param File file to parse
54 * @return true - everything ok, false - error while parsing
55 */
56bool CheckAgainstAdjacencyFile::ParseInExternalMap(std::istream &File)
57{
58 if (File.fail()) {
59 LOG(1, "STATUS: Adjacency file not found." << endl);
60 return false;
61 }
62
63 ExternalAtomBondMap.clear();
64 char buffer[MAXSTRINGSIZE];
65 int tmp;
66 // Parse the file line by line and count the bonds
67 while (!File.eof()) {
68 File.getline(buffer, MAXSTRINGSIZE);
69 stringstream line;
70 line.str(buffer);
71 int AtomNr = -1;
72 line >> AtomNr;
73 // parse into structure
74 if (AtomNr >= 0) {
75 const atom *Walker = World::getInstance().getAtom(AtomById(AtomNr));
76 ASSERT(Walker != NULL,
77 "CheckAgainstAdjacencyFile::ParseInExternalMap() - there is no atom with id "+toString(AtomNr)+".");
78 if (Walker == NULL)
79 return false;
80 // parse bond partner ids associated to AtomNr
81 while (line >> ws >> tmp) {
82 LOG(3, "INFO: Recognized bond partner " << tmp);
83 ExternalAtomBondMap.insert( std::make_pair(AtomNr, tmp) );
84 }
85 } else {
86 if (AtomNr != -1) {
87 ELOG(2, AtomNr << " is negative.");
88 return false;
89 }
90 }
91 }
92 return true;
93}
94
95/** Fills the InternalAtomBondMap from the atoms given by the two iterators.
96 *
97 * @param AtomMapBegin iterator pointing to begin of map (think of World's SelectionIterator)
98 * @param AtomMapEnd iterator pointing past end of map (think of World's SelectionIterator)
99 */
100void CheckAgainstAdjacencyFile::CreateInternalMap(World::AtomSet::const_iterator &AtomMapBegin, World::AtomSet::const_iterator &AtomMapEnd)
101{
102 InternalAtomBondMap.clear();
103 // go through each atom in the list
104 for (World::AtomSet::const_iterator iter = AtomMapBegin; iter != AtomMapEnd; ++iter) {
105 const atom *Walker = iter->second;
106 const atomId_t WalkerId = Walker->getId();
107 ASSERT(WalkerId != (size_t)-1,
108 "CheckAgainstAdjacencyFile::CreateInternalMap() - Walker has no id.");
109 const BondList& ListOfBonds = Walker->getListOfBonds();
110 // go through each of its bonds
111 for (BondList::const_iterator Runner = ListOfBonds.begin();
112 Runner != ListOfBonds.end();
113 ++Runner) {
114 const atomId_t id = (*Runner)->GetOtherAtom(Walker)->getId();
115 ASSERT(id != (size_t)-1,
116 "CheckAgainstAdjacencyFile::CreateInternalMap() - OtherAtom has not id.");
117 InternalAtomBondMap.insert( std::make_pair(WalkerId, id) );
118 }
119 }
120}
121
122/** Checks contents of adjacency file against bond structure in structure molecule.
123 * \param File file to parser
124 * \return true - structure is equal, false - not equivalence
125 */
126bool CheckAgainstAdjacencyFile::operator()(std::istream &File)
127{
128 LOG(0, "STATUS: Looking at bond structure stored in adjacency file and comparing to present one ... ");
129
130 bool status = true;
131
132 status = status && ParseInExternalMap(File);
133 status = status && CompareInternalExternalMap();
134
135 if (status) { // if equal we parse the KeySetFile
136 LOG(0, "STATUS: Equal.");
137 } else
138 LOG(0, "STATUS: Not equal by " << NonMatchNumber << " atoms.");
139 return status;
140}
141
142CheckAgainstAdjacencyFile::KeysSet CheckAgainstAdjacencyFile::getKeys(const CheckAgainstAdjacencyFile::AtomBondRange &_range) const
143{
144 KeysSet Keys;
145 for (AtomBondMap::const_iterator iter = _range.first;
146 iter != _range.second;
147 ++iter) {
148 Keys.insert( iter->first );
149 }
150 return Keys;
151}
152
153CheckAgainstAdjacencyFile::ValuesSet CheckAgainstAdjacencyFile::getValues(const CheckAgainstAdjacencyFile::AtomBondRange&_range) const
154{
155 ValuesSet Values;
156 for (AtomBondMap::const_iterator iter = _range.first;
157 iter != _range.second;
158 ++iter) {
159 Values.insert( iter->second );
160 }
161 return Values;
162}
163
164/** Counts the number of mismatching items in each set.
165 *
166 * @param firstset first set
167 * @param secondset second set
168 * @return number of items that don't match between first and second set
169 */
170template <class T>
171size_t getMismatchingItems(const T &firstset, const T &secondset)
172{
173 size_t Mismatch = 0;
174 typename T::const_iterator firstiter = firstset.begin();
175 typename T::const_iterator seconditer = secondset.begin();
176 for (; (firstiter != firstset.end()) && (seconditer != secondset.end());
177 ++firstiter, ++seconditer) {
178 if (*firstiter != *seconditer)
179 ++Mismatch;
180 }
181 return Mismatch;
182}
183
184/** Compares InternalAtomBondMap and ExternalAtomBondMap and sets NonMatchNumber.
185 *
186 * @return true - both maps are the same, false - both maps diverge by NonMatchNumber counts.
187 */
188bool CheckAgainstAdjacencyFile::CompareInternalExternalMap()
189{
190 NonMatchNumber = 0;
191 // check whether sizes match
192 if (ExternalAtomBondMap.size() != InternalAtomBondMap.size()) {
193 NonMatchNumber = abs((int)ExternalAtomBondMap.size() - (int)InternalAtomBondMap.size());
194 LOG(2, "INFO: " << NonMatchNumber << " entries don't match.");
195 return false;
196 }
197 // extract keys and check whether they match
198 const AtomBondRange Intrange(InternalAtomBondMap.begin(), InternalAtomBondMap.end());
199 const AtomBondRange Extrange(ExternalAtomBondMap.begin(), ExternalAtomBondMap.end());
200 KeysSet InternalKeys( getKeys(Intrange) );
201 KeysSet ExternalKeys( getKeys(Extrange) );
202
203// std::cout << "InternalKeys: " << InternalKeys << std::endl;
204// std::cout << "ExternalKeys: " << ExternalKeys << std::endl;
205
206 // check for same amount of keys
207 if (InternalKeys.size() != ExternalKeys.size()) {
208 NonMatchNumber = abs((int)ExternalKeys.size() - (int)InternalKeys.size());
209 LOG(2, "INFO: Number of keys don't match: "
210 << InternalKeys.size() << " != " << ExternalKeys.size());
211 return false;
212 }
213
214 // check items against one another
215 NonMatchNumber = getMismatchingItems(InternalKeys, ExternalKeys);
216
217 if (NonMatchNumber != 0) {
218 LOG(2, "INFO: " << NonMatchNumber << " keys are not the same.");
219 return false;
220 }
221
222 // now check each map per key
223 for (KeysSet::const_iterator keyIter = InternalKeys.begin();
224 keyIter != InternalKeys.end();
225 ++keyIter) {
226// std::cout << "Current key is " << *keyIter << std::endl;
227 const AtomBondRange IntRange( InternalAtomBondMap.equal_range(*keyIter) );
228 const AtomBondRange ExtRange( ExternalAtomBondMap.equal_range(*keyIter) );
229 ValuesSet InternalValues( getValues(IntRange) );
230 ValuesSet ExternalValues( getValues(ExtRange) );
231// std::cout << "InternalValues: " << InternalValues << std::endl;
232// std::cout << "ExternalValues: " << ExternalValues << std::endl;
233 NonMatchNumber += getMismatchingItems(InternalValues, ExternalValues);
234 }
235 if (NonMatchNumber != 0) {
236 LOG(2, "INFO: " << NonMatchNumber << " keys are not the same.");
237 return false;
238 } else {
239 LOG(2, "INFO: All keys are the same.");
240 return true;
241 }
242}
Note: See TracBrowser for help on using the repository browser.