source: src/Graph/CheckAgainstAdjacencyFile.cpp@ 8b58ac

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 8b58ac was 94d5ac6, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

  • GNU Scientific Library is used at every place in the code, especially the sub-package LinearAlgebra is based on it which in turn is used really everywhere in the remainder of MoleCuilder. Hence, we have to use the GPL license for the whole of MoleCuilder. In effect, GPL's COPYING was present all along and stated the terms of the GPL v2 license.
  • Hence, I added the default GPL v2 disclaimer to every source file and removed the note about a (actually missing) LICENSE file.
  • also, I added a help-redistribute action which again gives the disclaimer of the GPL v2.
  • also, I changed in the disclaimer that is printed at every program start in builder_init.cpp.
  • TEST: Added check on GPL statement present in every module to test CodeChecks project-disclaimer.
  • Property mode set to 100644
File size: 8.5 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 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * CheckAgainstAdjacencyFile.cpp
25 *
26 * Created on: Mar 3, 2011
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include "CodePatterns/MemDebug.hpp"
36
37#include <iostream>
38#include <map>
39#include <set>
40#include <utility>
41
42#include "CheckAgainstAdjacencyFile.hpp"
43
44#include "Atom/atom.hpp"
45#include "Bond/bond.hpp"
46#include "CodePatterns/Assert.hpp"
47#include "CodePatterns/Log.hpp"
48#include "CodePatterns/Range.hpp"
49#include "Descriptors/AtomIdDescriptor.hpp"
50#include "Helpers/defs.hpp"
51#include "World.hpp"
52
53CheckAgainstAdjacencyFile::CheckAgainstAdjacencyFile(World::AtomSet::const_iterator AtomMapBegin, World::AtomSet::const_iterator AtomMapEnd) :
54 status(true),
55 NonMatchNumber(0)
56{
57 CreateInternalMap(AtomMapBegin, AtomMapEnd);
58}
59
60CheckAgainstAdjacencyFile::~CheckAgainstAdjacencyFile()
61{
62 ExternalAtomBondMap.clear();
63 InternalAtomBondMap.clear();
64}
65
66/** Parses the bond partners of each atom from an external file into \a AtomBondMap.
67 *
68 * @param File file to parse
69 * @return true - everything ok, false - error while parsing
70 */
71bool CheckAgainstAdjacencyFile::ParseInExternalMap(std::istream &File)
72{
73 if (File.fail()) {
74 LOG(1, "STATUS: Adjacency file not found." << endl);
75 return false;
76 }
77
78 ExternalAtomBondMap.clear();
79 char buffer[MAXSTRINGSIZE];
80 int tmp;
81 // Parse the file line by line and count the bonds
82 while (!File.eof()) {
83 File.getline(buffer, MAXSTRINGSIZE);
84 stringstream line;
85 line.str(buffer);
86 int AtomNr = -1;
87 line >> AtomNr;
88 // parse into structure
89 if (AtomNr > 0) {
90 const atom *Walker = World::getInstance().getAtom(AtomById(AtomNr-1));
91 ASSERT(Walker != NULL,
92 "CheckAgainstAdjacencyFile::ParseInExternalMap() - there is no atom with id "+toString(AtomNr-1)+".");
93 if (Walker == NULL)
94 return false;
95 // parse bond partner ids associated to AtomNr
96 while (line >> ws >> tmp) {
97 LOG(3, "INFO: Recognized bond partner " << tmp-1);
98 ExternalAtomBondMap.insert( std::make_pair(Walker->getId(), tmp-1) );
99 }
100 } else {
101 if (AtomNr != -1) {
102 ELOG(2, AtomNr << " is negative.");
103 return false;
104 }
105 }
106 }
107 return true;
108}
109
110/** Fills the InternalAtomBondMap from the atoms given by the two iterators.
111 *
112 * @param AtomMapBegin iterator pointing to begin of map (think of World's SelectionIterator)
113 * @param AtomMapEnd iterator pointing past end of map (think of World's SelectionIterator)
114 */
115void CheckAgainstAdjacencyFile::CreateInternalMap(World::AtomSet::const_iterator &AtomMapBegin, World::AtomSet::const_iterator &AtomMapEnd)
116{
117 InternalAtomBondMap.clear();
118 // go through each atom in the list
119 for (World::AtomSet::const_iterator iter = AtomMapBegin; iter != AtomMapEnd; ++iter) {
120 const atom *Walker = iter->second;
121 const atomId_t WalkerId = Walker->getId();
122 ASSERT(WalkerId != (size_t)-1,
123 "CheckAgainstAdjacencyFile::CreateInternalMap() - Walker has no id.");
124 const BondList& ListOfBonds = Walker->getListOfBonds();
125 // go through each of its bonds
126 for (BondList::const_iterator Runner = ListOfBonds.begin();
127 Runner != ListOfBonds.end();
128 ++Runner) {
129 const atomId_t id = (*Runner)->GetOtherAtom(Walker)->getId();
130 ASSERT(id != (size_t)-1,
131 "CheckAgainstAdjacencyFile::CreateInternalMap() - OtherAtom has not id.");
132 InternalAtomBondMap.insert( std::make_pair(WalkerId, id) );
133 }
134 }
135}
136
137/** Checks contents of adjacency file against bond structure in structure molecule.
138 * \param File file to parser
139 * \return true - structure is equal, false - not equivalence
140 */
141bool CheckAgainstAdjacencyFile::operator()(std::istream &File)
142{
143 LOG(0, "STATUS: Looking at bond structure stored in adjacency file and comparing to present one ... ");
144
145 bool status = true;
146
147 status = status && ParseInExternalMap(File);
148 status = status && CompareInternalExternalMap();
149
150 if (status) { // if equal we parse the KeySetFile
151 LOG(0, "STATUS: Equal.");
152 } else
153 LOG(0, "STATUS: Not equal by " << NonMatchNumber << " atoms.");
154 return status;
155}
156
157CheckAgainstAdjacencyFile::KeysSet CheckAgainstAdjacencyFile::getKeys(const CheckAgainstAdjacencyFile::AtomBondRange &_range) const
158{
159 KeysSet Keys;
160 for (AtomBondMap::const_iterator iter = _range.first;
161 iter != _range.second;
162 ++iter) {
163 Keys.insert( iter->first );
164 }
165 return Keys;
166}
167
168CheckAgainstAdjacencyFile::ValuesSet CheckAgainstAdjacencyFile::getValues(const CheckAgainstAdjacencyFile::AtomBondRange&_range) const
169{
170 ValuesSet Values;
171 for (AtomBondMap::const_iterator iter = _range.first;
172 iter != _range.second;
173 ++iter) {
174 Values.insert( iter->second );
175 }
176 return Values;
177}
178
179/** Counts the number of mismatching items in each set.
180 *
181 * @param firstset first set
182 * @param secondset second set
183 * @return number of items that don't match between first and second set
184 */
185template <class T>
186size_t getMismatchingItems(const T &firstset, const T &secondset)
187{
188 size_t Mismatch = 0;
189 typename T::const_iterator firstiter = firstset.begin();
190 typename T::const_iterator seconditer = secondset.begin();
191 for (; (firstiter != firstset.end()) && (seconditer != secondset.end());
192 ++firstiter, ++seconditer) {
193 if (*firstiter != *seconditer)
194 ++Mismatch;
195 }
196 return Mismatch;
197}
198
199/** Compares InternalAtomBondMap and ExternalAtomBondMap and sets NonMatchNumber.
200 *
201 * @return true - both maps are the same, false - both maps diverge by NonMatchNumber counts.
202 */
203bool CheckAgainstAdjacencyFile::CompareInternalExternalMap()
204{
205 NonMatchNumber = 0;
206 // check whether sizes match
207 if (ExternalAtomBondMap.size() != InternalAtomBondMap.size()) {
208 NonMatchNumber = abs((int)ExternalAtomBondMap.size() - (int)InternalAtomBondMap.size());
209 LOG(2, "INFO: " << NonMatchNumber << " entries don't match.");
210 return false;
211 }
212 // extract keys and check whether they match
213 const AtomBondRange Intrange(InternalAtomBondMap.begin(), InternalAtomBondMap.end());
214 const AtomBondRange Extrange(ExternalAtomBondMap.begin(), ExternalAtomBondMap.end());
215 KeysSet InternalKeys( getKeys(Intrange) );
216 KeysSet ExternalKeys( getKeys(Extrange) );
217
218// std::cout << "InternalKeys: " << InternalKeys << std::endl;
219// std::cout << "ExternalKeys: " << ExternalKeys << std::endl;
220
221 // check for same amount of keys
222 if (InternalKeys.size() != ExternalKeys.size()) {
223 NonMatchNumber = abs((int)ExternalKeys.size() - (int)InternalKeys.size());
224 LOG(2, "INFO: Number of keys don't match: "
225 << InternalKeys.size() << " != " << ExternalKeys.size());
226 return false;
227 }
228
229 // check items against one another
230 NonMatchNumber = getMismatchingItems(InternalKeys, ExternalKeys);
231
232 if (NonMatchNumber != 0) {
233 LOG(2, "INFO: " << NonMatchNumber << " keys are not the same.");
234 return false;
235 }
236
237 // now check each map per key
238 for (KeysSet::const_iterator keyIter = InternalKeys.begin();
239 keyIter != InternalKeys.end();
240 ++keyIter) {
241// std::cout << "Current key is " << *keyIter << std::endl;
242 const AtomBondRange IntRange( InternalAtomBondMap.equal_range(*keyIter) );
243 const AtomBondRange ExtRange( ExternalAtomBondMap.equal_range(*keyIter) );
244 ValuesSet InternalValues( getValues(IntRange) );
245 ValuesSet ExternalValues( getValues(ExtRange) );
246// std::cout << "InternalValues: " << InternalValues << std::endl;
247// std::cout << "ExternalValues: " << ExternalValues << std::endl;
248 NonMatchNumber += getMismatchingItems(InternalValues, ExternalValues);
249 }
250 if (NonMatchNumber != 0) {
251 LOG(2, "INFO: " << NonMatchNumber << " keys are not the same.");
252 return false;
253 } else {
254 LOG(2, "INFO: All keys are the same.");
255 return true;
256 }
257}
Note: See TracBrowser for help on using the repository browser.