source: src/Fragmentation/fragmentation_helpers.cpp@ 23fb72

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 23fb72 was a03d25, checked in by Frederik Heber <heber@…>, 13 years ago

Placed all routines working on UniqueFragments struct inside this class.

  • changed struct to class.
  • Property mode set to 100644
File size: 24.6 KB
RevLine 
[ba1823]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
8/*
9 * fragmentation_helpers.cpp
10 *
11 * Created on: Oct 18, 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 "fragmentation_helpers.hpp"
23
24#include <sstream>
25
26#include "CodePatterns/Log.hpp"
27
28#include "atom.hpp"
29#include "Bond/bond.hpp"
30#include "Element/element.hpp"
31#include "Helpers/defs.hpp"
32#include "Helpers/helpers.hpp"
33#include "molecule.hpp"
34
35using namespace std;
36
37/** Scans a single line for number and puts them into \a KeySet.
38 * \param *out output stream for debugging
39 * \param *buffer buffer to scan
40 * \param &CurrentSet filled KeySet on return
41 * \return true - at least one valid atom id parsed, false - CurrentSet is empty
42 */
43bool ScanBufferIntoKeySet(char *buffer, KeySet &CurrentSet)
44{
45 stringstream line;
46 int AtomNr;
47 int status = 0;
48
49 line.str(buffer);
50 while (!line.eof()) {
51 line >> AtomNr;
52 if (AtomNr >= 0) {
53 CurrentSet.insert(AtomNr); // insert at end, hence in same order as in file!
54 status++;
55 } // else it's "-1" or else and thus must not be added
56 }
57 DoLog(1) && (Log() << Verbose(1) << "The scanned KeySet is ");
58 for(KeySet::iterator runner = CurrentSet.begin(); runner != CurrentSet.end(); runner++) {
59 DoLog(0) && (Log() << Verbose(0) << (*runner) << "\t");
60 }
61 DoLog(0) && (Log() << Verbose(0) << endl);
62 return (status != 0);
63};
64
65/** Parses the KeySet file and fills \a *FragmentList from the known molecule structure.
66 * Does two-pass scanning:
67 * -# Scans the keyset file and initialises a temporary graph
68 * -# Scans TEFactors file and sets the TEFactor of each key set in the temporary graph accordingly
69 * Finally, the temporary graph is inserted into the given \a FragmentList for return.
70 * \param &path path to file
71 * \param *FragmentList empty, filled on return
72 * \return true - parsing successfully, false - failure on parsing (FragmentList will be NULL)
73 */
74bool ParseKeySetFile(std::string &path, Graph *&FragmentList)
75{
76 bool status = true;
77 ifstream InputFile;
78 stringstream line;
79 GraphTestPair testGraphInsert;
80 int NumberOfFragments = 0;
81 string filename;
82
83 if (FragmentList == NULL) { // check list pointer
84 FragmentList = new Graph;
85 }
86
87 // 1st pass: open file and read
88 DoLog(1) && (Log() << Verbose(1) << "Parsing the KeySet file ... " << endl);
89 filename = path + KEYSETFILE;
90 InputFile.open(filename.c_str());
91 if (InputFile.good()) {
92 // each line represents a new fragment
93 char buffer[MAXSTRINGSIZE];
94 // 1. parse keysets and insert into temp. graph
95 while (!InputFile.eof()) {
96 InputFile.getline(buffer, MAXSTRINGSIZE);
97 KeySet CurrentSet;
98 if ((strlen(buffer) > 0) && (ScanBufferIntoKeySet(buffer, CurrentSet))) { // if at least one valid atom was added, write config
99 testGraphInsert = FragmentList->insert(GraphPair (CurrentSet,pair<int,double>(NumberOfFragments++,1))); // store fragment number and current factor
100 if (!testGraphInsert.second) {
101 DoeLog(0) && (eLog()<< Verbose(0) << "KeySet file must be corrupt as there are two equal key sets therein!" << endl);
102 performCriticalExit();
103 }
104 }
105 }
106 // 2. Free and done
107 InputFile.close();
108 InputFile.clear();
109 DoLog(1) && (Log() << Verbose(1) << "\t ... done." << endl);
110 } else {
111 DoLog(1) && (Log() << Verbose(1) << "\t ... File " << filename << " not found." << endl);
112 status = false;
113 }
114
115 return status;
116};
117
118/** Parses the TE factors file and fills \a *FragmentList from the known molecule structure.
119 * -# Scans TEFactors file and sets the TEFactor of each key set in the temporary graph accordingly
120 * \param *out output stream for debugging
121 * \param *path path to file
122 * \param *FragmentList graph whose nodes's TE factors are set on return
123 * \return true - parsing successfully, false - failure on parsing
124 */
125bool ParseTEFactorsFile(char *path, Graph *FragmentList)
126{
127 bool status = true;
128 ifstream InputFile;
129 stringstream line;
130 GraphTestPair testGraphInsert;
131 int NumberOfFragments = 0;
132 double TEFactor;
133 char filename[MAXSTRINGSIZE];
134
135 if (FragmentList == NULL) { // check list pointer
136 FragmentList = new Graph;
137 }
138
139 // 2nd pass: open TEFactors file and read
140 DoLog(1) && (Log() << Verbose(1) << "Parsing the TEFactors file ... " << endl);
141 sprintf(filename, "%s/%s%s", path, FRAGMENTPREFIX, TEFACTORSFILE);
142 InputFile.open(filename);
143 if (InputFile != NULL) {
144 // 3. add found TEFactors to each keyset
145 NumberOfFragments = 0;
146 for(Graph::iterator runner = FragmentList->begin();runner != FragmentList->end(); runner++) {
147 if (!InputFile.eof()) {
148 InputFile >> TEFactor;
149 (*runner).second.second = TEFactor;
150 DoLog(2) && (Log() << Verbose(2) << "Setting " << ++NumberOfFragments << " fragment's TEFactor to " << (*runner).second.second << "." << endl);
151 } else {
152 status = false;
153 break;
154 }
155 }
156 // 4. Free and done
157 InputFile.close();
158 DoLog(1) && (Log() << Verbose(1) << "done." << endl);
159 } else {
160 DoLog(1) && (Log() << Verbose(1) << "File " << filename << " not found." << endl);
161 status = false;
162 }
163
164 return status;
165};
166
167/** Stores key sets to file.
168 * \param KeySetList Graph with Keysets
169 * \param &path path to file
170 * \return true - file written successfully, false - writing failed
171 */
172bool StoreKeySetFile(Graph &KeySetList, std::string &path)
173{
174 bool status = true;
175 string line = path + KEYSETFILE;
176 ofstream output(line.c_str());
177
178 // open KeySet file
179 DoLog(1) && (Log() << Verbose(1) << "Saving key sets of the total graph ... ");
180 if(output.good()) {
181 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++) {
182 for (KeySet::iterator sprinter = (*runner).first.begin();sprinter != (*runner).first.end(); sprinter++) {
183 if (sprinter != (*runner).first.begin())
184 output << "\t";
185 output << *sprinter;
186 }
187 output << endl;
188 }
189 DoLog(0) && (Log() << Verbose(0) << "done." << endl);
190 } else {
191 DoeLog(0) && (eLog()<< Verbose(0) << "Unable to open " << line << " for writing keysets!" << endl);
192 performCriticalExit();
193 status = false;
194 }
195 output.close();
196 output.clear();
197
198 return status;
199};
200
201
202/** Stores TEFactors to file.
203 * \param *out output stream for debugging
204 * \param KeySetList Graph with factors
205 * \param *path path to file
206 * \return true - file written successfully, false - writing failed
207 */
208bool StoreTEFactorsFile(Graph &KeySetList, char *path)
209{
210 ofstream output;
211 bool status = true;
212 string line;
213
214 // open TEFactors file
215 line = path;
216 line.append("/");
217 line += FRAGMENTPREFIX;
218 line += TEFACTORSFILE;
219 output.open(line.c_str(), ios::out);
220 DoLog(1) && (Log() << Verbose(1) << "Saving TEFactors of the total graph ... ");
221 if(output != NULL) {
222 for(Graph::iterator runner = KeySetList.begin(); runner != KeySetList.end(); runner++)
223 output << (*runner).second.second << endl;
224 DoLog(1) && (Log() << Verbose(1) << "done." << endl);
225 } else {
226 DoLog(1) && (Log() << Verbose(1) << "failed to open " << line << "." << endl);
227 status = false;
228 }
229 output.close();
230
231 return status;
232};
233
234/** For a given graph, sorts KeySets into a (index, keyset) map.
235 * \param *GlobalKeySetList list of keysets with global ids (valid in "this" molecule) needed for adaptive increase
236 * \return map from index to keyset
237 */
238std::map<int,KeySet> * GraphToIndexedKeySet(Graph *GlobalKeySetList)
239{
240 map<int,KeySet> *IndexKeySetList = new map<int,KeySet>;
241 for(Graph::iterator runner = GlobalKeySetList->begin(); runner != GlobalKeySetList->end(); runner++) {
242 IndexKeySetList->insert( pair<int,KeySet>(runner->second.first,runner->first) );
243 }
244 return IndexKeySetList;
245};
246
247/** Inserts a (\a No, \a value) pair into the list, overwriting present one.
248 * Note if values are equal, No will decided on which is first
249 * \param *out output stream for debugging
250 * \param &AdaptiveCriteriaList list to insert into
251 * \param &IndexedKeySetList list to find key set for a given index \a No
252 * \param FragOrder current bond order of fragment
253 * \param No index of keyset
254 * \param value energy value
255 */
256void InsertIntoAdaptiveCriteriaList(std::map<int, pair<double,int> > *AdaptiveCriteriaList, std::map<int,KeySet> &IndexKeySetList, int FragOrder, int No, double Value)
257{
258 map<int,KeySet>::iterator marker = IndexKeySetList.find(No); // find keyset to Frag No.
259 if (marker != IndexKeySetList.end()) { // if found
260 Value *= 1 + MYEPSILON*(*((*marker).second.begin())); // in case of equal energies this makes them not equal without changing anything actually
261 // as the smallest number in each set has always been the root (we use global id to keep the doubles away), seek smallest and insert into AtomMask
262 pair <map<int, pair<double,int> >::iterator, bool> InsertedElement = AdaptiveCriteriaList->insert( make_pair(*((*marker).second.begin()), pair<double,int>( fabs(Value), FragOrder) ));
263 map<int, pair<double,int> >::iterator PresentItem = InsertedElement.first;
264 if (!InsertedElement.second) { // this root is already present
265 if ((*PresentItem).second.second < FragOrder) // if order there is lower, update entry with higher-order term
266 //if ((*PresentItem).second.first < (*runner).first) // as higher-order terms are not always better, we skip this part (which would always include this site into adaptive increase)
267 { // if value is smaller, update value and order
268 (*PresentItem).second.first = fabs(Value);
269 (*PresentItem).second.second = FragOrder;
270 DoLog(2) && (Log() << Verbose(2) << "Updated element (" << (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl);
271 } else {
272 DoLog(2) && (Log() << Verbose(2) << "Did not update element " << (*PresentItem).first << " as " << FragOrder << " is less than or equal to " << (*PresentItem).second.second << "." << endl);
273 }
274 } else {
275 DoLog(2) && (Log() << Verbose(2) << "Inserted element (" << (*PresentItem).first << ",[" << (*PresentItem).second.first << "," << (*PresentItem).second.second << "])." << endl);
276 }
277 } else {
278 DoLog(1) && (Log() << Verbose(1) << "No Fragment under No. " << No << "found." << endl);
279 }
280};
281
282/** Counts lines in file.
283 * Note we are scanning lines from current position, not from beginning.
284 * \param InputFile file to be scanned.
285 */
286int CountLinesinFile(std::ifstream &InputFile)
287{
288 char *buffer = new char[MAXSTRINGSIZE];
289 int lines=0;
290
291 int PositionMarker = InputFile.tellg(); // not needed as Inputfile is copied, given by value, not by ref
292 // count the number of lines, i.e. the number of fragments
293 InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
294 InputFile.getline(buffer, MAXSTRINGSIZE);
295 while(!InputFile.eof()) {
296 InputFile.getline(buffer, MAXSTRINGSIZE);
297 lines++;
298 }
299 InputFile.seekg(PositionMarker, ios::beg);
300 delete[](buffer);
301 return lines;
302};
303
304
305/** Scans the adaptive order file and insert (index, value) into map.
306 * \param &path path to ENERGYPERFRAGMENT file (may be NULL if Order is non-negative)
307 * \param &IndexedKeySetList list to find key set for a given index \a No
308 * \return adaptive criteria list from file
309 */
310std::map<int, std::pair<double,int> > * ScanAdaptiveFileIntoMap(std::string &path, std::map<int,KeySet> &IndexKeySetList)
311{
312 map<int, pair<double,int> > *AdaptiveCriteriaList = new map<int, pair<double,int> >;
313 int No = 0, FragOrder = 0;
314 double Value = 0.;
315 char buffer[MAXSTRINGSIZE];
316 string filename = path + ENERGYPERFRAGMENT;
317 ifstream InputFile(filename.c_str());
318
319 if (InputFile.fail()) {
320 DoeLog(1) && (eLog() << Verbose(1) << "Cannot find file " << filename << "." << endl);
321 return AdaptiveCriteriaList;
322 }
323
324 if (CountLinesinFile(InputFile) > 0) {
325 // each line represents a fragment root (Atom::Nr) id and its energy contribution
326 InputFile.getline(buffer, MAXSTRINGSIZE); // skip comment lines
327 InputFile.getline(buffer, MAXSTRINGSIZE);
328 while(!InputFile.eof()) {
329 InputFile.getline(buffer, MAXSTRINGSIZE);
330 if (strlen(buffer) > 2) {
331 //Log() << Verbose(2) << "Scanning: " << buffer << endl;
332 stringstream line(buffer);
333 line >> FragOrder;
334 line >> ws >> No;
335 line >> ws >> Value; // skip time entry
336 line >> ws >> Value;
337 No -= 1; // indices start at 1 in file, not 0
338 //Log() << Verbose(2) << " - yields (" << No << "," << Value << ", " << FragOrder << ")" << endl;
339
340 // clean the list of those entries that have been superceded by higher order terms already
341 InsertIntoAdaptiveCriteriaList(AdaptiveCriteriaList, IndexKeySetList, FragOrder, No, Value);
342 }
343 }
344 // close and done
345 InputFile.close();
346 InputFile.clear();
347 }
348
349 return AdaptiveCriteriaList;
350};
351
352/** Maps adaptive criteria list back onto (Value, (Root Nr., Order))
353 * (i.e. sorted by value to pick the highest ones)
354 * \param *out output stream for debugging
355 * \param &AdaptiveCriteriaList list to insert into
356 * \param *mol molecule with atoms
357 * \return remapped list
358 */
359std::map<double, std::pair<int,int> > * ReMapAdaptiveCriteriaListToValue(std::map<int, std::pair<double,int> > *AdaptiveCriteriaList, molecule *mol)
360{
361 atom *Walker = NULL;
362 map<double, pair<int,int> > *FinalRootCandidates = new map<double, pair<int,int> > ;
363 DoLog(1) && (Log() << Verbose(1) << "Root candidate list is: " << endl);
364 for(map<int, pair<double,int> >::iterator runner = AdaptiveCriteriaList->begin(); runner != AdaptiveCriteriaList->end(); runner++) {
365 Walker = mol->FindAtom((*runner).first);
366 if (Walker != NULL) {
367 //if ((*runner).second.second >= Walker->AdaptiveOrder) { // only insert if this is an "active" root site for the current order
368 if (!Walker->MaxOrder) {
369 DoLog(2) && (Log() << Verbose(2) << "(" << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "])" << endl);
370 FinalRootCandidates->insert( make_pair( (*runner).second.first, pair<int,int>((*runner).first, (*runner).second.second) ) );
371 } else {
372 DoLog(2) && (Log() << Verbose(2) << "Excluding (" << *Walker << ", " << (*runner).first << ",[" << (*runner).second.first << "," << (*runner).second.second << "]), as it has reached its maximum order." << endl);
373 }
374 } else {
375 DoeLog(0) && (eLog()<< Verbose(0) << "Atom No. " << (*runner).second.first << " was not found in this molecule." << endl);
376 performCriticalExit();
377 }
378 }
379 return FinalRootCandidates;
380};
381
382/** Marks all candidate sites for update if below adaptive threshold.
383 * Picks a given number of highest values and set *AtomMask to true.
384 * \param *out output stream for debugging
385 * \param *AtomMask defines true/false per global Atom::Nr to mask in/out each nuclear site, used to activate given number of site to increment order adaptively
386 * \param FinalRootCandidates list candidates to check
387 * \param Order desired order
388 * \param *mol molecule with atoms
389 * \return true - if update is necessary, false - not
390 */
391bool MarkUpdateCandidates(bool *AtomMask, std::map<double, std::pair<int,int> > &FinalRootCandidates, int Order, molecule *mol)
392{
393 atom *Walker = NULL;
394 int No = -1;
395 bool status = false;
396 for(map<double, pair<int,int> >::iterator runner = FinalRootCandidates.upper_bound(pow(10.,Order)); runner != FinalRootCandidates.end(); runner++) {
397 No = (*runner).second.first;
398 Walker = mol->FindAtom(No);
399 //if (Walker->AdaptiveOrder < MinimumRingSize[Walker->getNr()]) {
400 DoLog(2) && (Log() << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", setting entry " << No << " of Atom mask to true." << endl);
401 AtomMask[No] = true;
402 status = true;
403 //} else
404 //Log() << Verbose(2) << "Root " << No << " is still above threshold (10^{" << Order <<"}: " << runner->first << ", however MinimumRingSize of " << MinimumRingSize[Walker->getNr()] << " does not allow further adaptive increase." << endl;
405 }
406 return status;
407};
408
409/** print atom mask for debugging.
410 * \param *out output stream for debugging
411 * \param *AtomMask defines true/false per global Atom::Nr to mask in/out each nuclear site, used to activate given number of site to increment order adaptively
412 * \param AtomCount number of entries in \a *AtomMask
413 */
414void PrintAtomMask(bool *AtomMask, int AtomCount)
415{
416 DoLog(2) && (Log() << Verbose(2) << " ");
417 for(int i=0;i<AtomCount;i++)
418 DoLog(0) && (Log() << Verbose(0) << (i % 10));
419 DoLog(0) && (Log() << Verbose(0) << endl);
420 DoLog(2) && (Log() << Verbose(2) << "Atom mask is: ");
421 for(int i=0;i<AtomCount;i++)
422 DoLog(0) && (Log() << Verbose(0) << (AtomMask[i] ? "t" : "f"));
423 DoLog(0) && (Log() << Verbose(0) << endl);
424};
425
426
427
428/** Clears the touched list
429 * \param *out output stream for debugging
430 * \param verbosity verbosity level
431 * \param *&TouchedList touched list
432 * \param SubOrder current suborder
433 * \param TouchedIndex currently touched
434 */
435void SPFragmentGenerator_ClearingTouched(int verbosity, int *&TouchedList, int SubOrder, int &TouchedIndex)
436{
437 Log() << Verbose(1+verbosity) << "Clearing touched list." << endl;
438 for (TouchedIndex=SubOrder+1;TouchedIndex--;) // empty touched list
439 TouchedList[TouchedIndex] = -1;
440 TouchedIndex = 0;
441
442}
443
444/** Adds the current combination of the power set to the snake stack.
445 * \param *out output stream for debugging
446 * \param verbosity verbosity level
447 * \param CurrentCombination
448 * \param SetDimension maximum number of bits in power set
449 * \param *FragmentSet snake stack to remove from
450 * \param &BondsSet set of bonds
451 * \param *&TouchedList touched list
452 * \param TouchedIndex currently touched
453 * \return number of set bits
454 */
455int AddPowersetToSnakeStack(int verbosity, int CurrentCombination, int SetDimension, KeySet *FragmentSet, std::vector<bond *> &BondsSet, int *&TouchedList, int &TouchedIndex)
456{
457 atom *OtherWalker = NULL;
458 bool bit = false;
459 KeySetTestPair TestKeySetInsert;
460
461 int Added = 0;
462 for (int j=0;j<SetDimension;j++) { // pull out every bit by shifting
463 bit = ((CurrentCombination & (1 << j)) != 0); // mask the bit for the j-th bond
464 if (bit) { // if bit is set, we add this bond partner
465 OtherWalker = BondsSet[j]->rightatom; // rightatom is always the one more distant, i.e. the one to add
466 //Log() << Verbose(1+verbosity) << "Current Bond is " << BondsSet[j] << ", checking on " << *OtherWalker << "." << endl;
467 Log() << Verbose(2+verbosity) << "Adding " << *OtherWalker << " with nr " << OtherWalker->getNr() << "." << endl;
468 TestKeySetInsert = FragmentSet->insert(OtherWalker->getNr());
469 if (TestKeySetInsert.second) {
470 TouchedList[TouchedIndex++] = OtherWalker->getNr(); // note as added
471 Added++;
472 } else {
473 Log() << Verbose(2+verbosity) << "This was item was already present in the keyset." << endl;
474 }
475 } else {
476 Log() << Verbose(2+verbosity) << "Not adding." << endl;
477 }
478 }
479 return Added;
480};
481
482/** Counts the number of elements in a power set.
483 * \param SetFirst begin iterator first bond
484 * \param SetLast end iterator
485 * \param *&TouchedList touched list
486 * \param TouchedIndex currently touched
487 * \return number of elements
488 */
489int CountSetMembers(std::list<bond *>::const_iterator SetFirst, std::list<bond *>::const_iterator SetLast, int *&TouchedList, int TouchedIndex)
490{
491 int SetDimension = 0;
492 for( std::list<bond *>::const_iterator Binder = SetFirst;
493 Binder != SetLast;
494 ++Binder) {
495 for (int k=TouchedIndex;k--;) {
496 if ((*Binder)->Contains(TouchedList[k])) // if we added this very endpiece
497 SetDimension++;
498 }
499 }
500 return SetDimension;
501};
502
503/** Fills a list of bonds from another
504 * \param *BondsList bonds array/vector to fill
505 * \param SetFirst begin iterator first bond
506 * \param SetLast end iterator
507 * \param *&TouchedList touched list
508 * \param TouchedIndex currently touched
509 * \return number of elements
510 */
511int FillBondsList(std::vector<bond *> &BondsList, std::list<bond *>::const_iterator SetFirst, std::list<bond *>::const_iterator SetLast, int *&TouchedList, int TouchedIndex)
512{
513 int SetDimension = 0;
514 for( std::list<bond *>::const_iterator Binder = SetFirst;
515 Binder != SetLast;
516 ++Binder) {
517 for (int k=0;k<TouchedIndex;k++) {
518 if ((*Binder)->leftatom->getNr() == TouchedList[k]) // leftatom is always the closer one
519 BondsList[SetDimension++] = (*Binder);
520 }
521 }
522 return SetDimension;
523};
524
525/** Remove all items that were added on this SP level.
526 * \param *out output stream for debugging
527 * \param verbosity verbosity level
528 * \param *FragmentSet snake stack to remove from
529 * \param *&TouchedList touched list
530 * \param TouchedIndex currently touched
531 */
532void RemoveAllTouchedFromSnakeStack(int verbosity, KeySet *FragmentSet, int *&TouchedList, int &TouchedIndex)
533{
534 int Removal = 0;
535 for(int j=0;j<TouchedIndex;j++) {
536 Removal = TouchedList[j];
537 Log() << Verbose(2+verbosity) << "Removing item nr. " << Removal << " from snake stack." << endl;
538 FragmentSet->erase(Removal);
539 TouchedList[j] = -1;
540 }
541 DoLog(2) && (Log() << Verbose(2) << "Remaining local nr.s on snake stack are: ");
542 for(KeySet::iterator runner = FragmentSet->begin(); runner != FragmentSet->end(); runner++)
543 DoLog(0) && (Log() << Verbose(0) << (*runner) << " ");
544 DoLog(0) && (Log() << Verbose(0) << endl);
545 TouchedIndex = 0; // set Index to 0 for list of atoms added on this level
546};
547
548
549bool KeyCompare::operator() (const KeySet SubgraphA, const KeySet SubgraphB) const
550{
551 //Log() << Verbose(0) << "my check is used." << endl;
552 if (SubgraphA.size() < SubgraphB.size()) {
553 return true;
554 } else {
555 if (SubgraphA.size() > SubgraphB.size()) {
556 return false;
557 } else {
558 KeySet::iterator IteratorA = SubgraphA.begin();
559 KeySet::iterator IteratorB = SubgraphB.begin();
560 while ((IteratorA != SubgraphA.end()) && (IteratorB != SubgraphB.end())) {
561 if ((*IteratorA) < (*IteratorB))
562 return true;
563 else if ((*IteratorA) > (*IteratorB)) {
564 return false;
565 } // else, go on to next index
566 IteratorA++;
567 IteratorB++;
568 } // end of while loop
569 }// end of check in case of equal sizes
570 }
571 return false; // if we reach this point, they are equal
572};
573
574/** Combines all KeySets from all orders into single ones (with just unique entries).
575 * \param *out output stream for debugging
576 * \param *&FragmentList list to fill
577 * \param ***FragmentLowerOrdersList
578 * \param &RootStack stack with all root candidates (unequal to each atom in complete molecule if adaptive scheme is applied)
579 * \param *mol molecule with atoms and bonds
580 */
581int CombineAllOrderListIntoOne(Graph *&FragmentList, Graph ***FragmentLowerOrdersList, KeyStack &RootStack, molecule *mol)
582{
583 int RootNr = 0;
584 int RootKeyNr = 0;
585 int StartNr = 0;
586 int counter = 0;
587 int NumLevels = 0;
588 atom *Walker = NULL;
589
590 DoLog(0) && (Log() << Verbose(0) << "Combining the lists of all orders per order and finally into a single one." << endl);
591 if (FragmentList == NULL) {
592 FragmentList = new Graph;
593 counter = 0;
594 } else {
595 counter = FragmentList->size();
596 }
597
598 StartNr = RootStack.back();
599 do {
600 RootKeyNr = RootStack.front();
601 RootStack.pop_front();
602 Walker = mol->FindAtom(RootKeyNr);
603 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
604 for(int i=0;i<NumLevels;i++) {
605 if (FragmentLowerOrdersList[RootNr][i] != NULL) {
606 InsertGraphIntoGraph(*FragmentList, (*FragmentLowerOrdersList[RootNr][i]), &counter);
607 }
608 }
609 RootStack.push_back(Walker->getNr());
610 RootNr++;
611 } while (RootKeyNr != StartNr);
612 return counter;
613};
614
615/** Free's memory allocated for all KeySets from all orders.
616 * \param *out output stream for debugging
617 * \param ***FragmentLowerOrdersList
618 * \param &RootStack stack with all root candidates (unequal to each atom in complete molecule if adaptive scheme is applied)
619 * \param *mol molecule with atoms and bonds
620 */
621void FreeAllOrdersList(Graph ***FragmentLowerOrdersList, KeyStack &RootStack, molecule *mol)
622{
623 DoLog(1) && (Log() << Verbose(1) << "Free'ing the lists of all orders per order." << endl);
624 int RootNr = 0;
625 int RootKeyNr = 0;
626 int NumLevels = 0;
627 atom *Walker = NULL;
628 while (!RootStack.empty()) {
629 RootKeyNr = RootStack.front();
630 RootStack.pop_front();
631 Walker = mol->FindAtom(RootKeyNr);
632 NumLevels = 1 << (Walker->AdaptiveOrder - 1);
633 for(int i=0;i<NumLevels;i++) {
634 if (FragmentLowerOrdersList[RootNr][i] != NULL) {
635 delete(FragmentLowerOrdersList[RootNr][i]);
636 }
637 }
638 delete[](FragmentLowerOrdersList[RootNr]);
639 RootNr++;
640 }
641 delete[](FragmentLowerOrdersList);
642};
643
Note: See TracBrowser for help on using the repository browser.