source: src/Fragmentation/Exporters/ExportGraph.cpp@ 8652a30

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 8652a30 was 8652a30, checked in by Frederik Heber <heber@…>, 12 years ago

Moved some functions from ExportGraph_ToFiles into ExportGraph.

  • this is preparatory for ExportGraph_ToJobs as the functions for creating molecules are needed there, too.
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2011 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 * ExportGraph.cpp
25 *
26 * Created on: 08.03.2012
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 "ExportGraph.hpp"
38
39#include "CodePatterns/Info.hpp"
40#include "CodePatterns/Log.hpp"
41
42#include "Bond/bond.hpp"
43#include "Element/element.hpp"
44#include "Fragmentation/Graph.hpp"
45#include "Fragmentation/KeySet.hpp"
46#include "Fragmentation/SortIndex.hpp"
47#include "Graph/ListOfLocalAtoms.hpp"
48#include "molecule.hpp"
49#include "MoleculeListClass.hpp"
50#include "World.hpp"
51
52/** Constructor for class ExportGraph.
53 *
54 * @param _graph
55 */
56ExportGraph::ExportGraph(
57 const Graph &_graph,
58 const enum HydrogenTreatment _treatment,
59 const enum HydrogenSaturation _saturation) :
60 TotalGraph(_graph),
61 BondFragments(World::getPointer()),
62 treatment(_treatment),
63 saturation(_saturation)
64{
65}
66
67/** Destructor for class ExportGraph.
68 *
69 */
70ExportGraph::~ExportGraph()
71{
72 // remove all create molecules again from the World including their atoms
73 for (MoleculeList::iterator iter = BondFragments.ListOfMolecules.begin();
74 !BondFragments.ListOfMolecules.empty();
75 iter = BondFragments.ListOfMolecules.begin()) {
76 // remove copied atoms and molecule again
77 molecule *mol = *iter;
78 mol->removeAtomsinMolecule();
79 World::getInstance().destroyMolecule(mol);
80 BondFragments.ListOfMolecules.erase(iter);
81 }
82}
83
84void ExportGraph::operator()()
85{
86 if (BondFragments.ListOfMolecules.size() == 0)
87 prepareMolecule();
88}
89
90/** Internal helper to create from each keyset a molecule
91 *
92 */
93void ExportGraph::prepareMolecule()
94{
95 size_t count = 0;
96 for(Graph::const_iterator runner = TotalGraph.begin(); runner != TotalGraph.end(); runner++) {
97 KeySet test = (*runner).first;
98 LOG(2, "DEBUG: Fragment No." << (*runner).second.first << " with TEFactor "
99 << (*runner).second.second << ".");
100 BondFragments.insert(StoreFragmentFromKeySet(test, World::getInstance().getConfig()));
101 ++count;
102 }
103 LOG(1, "INFO: " << count << "/" << BondFragments.ListOfMolecules.size()
104 << " fragments generated from the keysets.");
105}
106
107/** Stores a fragment from \a KeySet into \a molecule.
108 * First creates the minimal set of atoms from the KeySet, then creates the bond structure from the complete
109 * molecule and adds missing hydrogen where bonds were cut.
110 * \param &Leaflet pointer to KeySet structure
111 * \param IsAngstroem whether we have Ansgtroem or bohrradius
112 * \return pointer to constructed molecule
113 */
114molecule * ExportGraph::StoreFragmentFromKeySet(KeySet &Leaflet, bool IsAngstroem)
115{
116 Info info(__func__);
117 ListOfLocalAtoms_t SonList;
118 molecule *Leaf = World::getInstance().createMolecule();
119
120 StoreFragmentFromKeySet_Init(Leaf, Leaflet, SonList);
121 // create the bonds between all: Make it an induced subgraph and add hydrogen
122// LOG(2, "Creating bonds from father graph (i.e. induced subgraph creation).");
123 CreateInducedSubgraphOfFragment(Leaf, SonList, IsAngstroem);
124
125 //Leaflet->Leaf->ScanForPeriodicCorrection(out);
126 return Leaf;
127}
128
129/** Initializes some value for putting fragment of \a *mol into \a *Leaf.
130 * \param *Leaf fragment molecule
131 * \param &Leaflet pointer to KeySet structure
132 * \param SonList calloc'd list which atom of \a *Leaf is a son of which atom in \a *mol
133 * \return number of atoms in fragment
134 */
135int ExportGraph::StoreFragmentFromKeySet_Init(molecule *Leaf, KeySet &Leaflet, ListOfLocalAtoms_t &SonList)
136{
137 atom *FatherOfRunner = NULL;
138
139 // first create the minimal set of atoms from the KeySet
140 World &world = World::getInstance();
141 int size = 0;
142 for(KeySet::const_iterator runner = Leaflet.begin(); runner != Leaflet.end(); runner++) {
143 FatherOfRunner = world.getAtom(AtomById(*runner)); // find the id
144 SonList.insert( std::make_pair(FatherOfRunner->getNr(), Leaf->AddCopyAtom(FatherOfRunner) ) );
145 size++;
146 }
147 return size;
148}
149
150/** Creates an induced subgraph out of a fragmental key set, adding bonds and hydrogens (if treated specially).
151 * \param *Leaf fragment molecule
152 * \param IsAngstroem whether we have Ansgtroem or bohrradius
153 * \param SonList list which atom of \a *Leaf is another atom's son
154 */
155void ExportGraph::CreateInducedSubgraphOfFragment(molecule *Leaf, ListOfLocalAtoms_t &SonList, bool IsAngstroem)
156{
157 bool LonelyFlag = false;
158 atom *OtherFather = NULL;
159 atom *FatherOfRunner = NULL;
160
161 // we increment the iter just before skipping the hydrogen
162 // as we use AddBond, we cannot have a const_iterator here
163 for (molecule::iterator iter = Leaf->begin(); iter != Leaf->end();) {
164 LonelyFlag = true;
165 FatherOfRunner = (*iter)->father;
166 ASSERT(FatherOfRunner,"Atom without father found");
167 if (SonList.find(FatherOfRunner->getNr()) != SonList.end()) { // check if this, our father, is present in list
168 // create all bonds
169 const BondList& ListOfBonds = FatherOfRunner->getListOfBonds();
170 for (BondList::const_iterator BondRunner = ListOfBonds.begin();
171 BondRunner != ListOfBonds.end();
172 ++BondRunner) {
173 OtherFather = (*BondRunner)->GetOtherAtom(FatherOfRunner);
174 if (SonList.find(OtherFather->getNr()) != SonList.end()) {
175// LOG(2, "INFO: Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->getNr()]
176// << " is bound to " << *OtherFather << ", whose son is "
177// << *SonList[OtherFather->getNr()] << ".");
178 if (OtherFather->getNr() > FatherOfRunner->getNr()) { // add bond (Nr check is for adding only one of both variants: ab, ba)
179 std::stringstream output;
180// output << "ACCEPT: Adding Bond: "
181 output << Leaf->AddBond((*iter), SonList[OtherFather->getNr()], (*BondRunner)->BondDegree);
182// LOG(3, output.str());
183 //NumBonds[(*iter)->getNr()]++;
184 } else {
185// LOG(3, "REJECY: Not adding bond, labels in wrong order.");
186 }
187 LonelyFlag = false;
188 } else {
189// LOG(2, "INFO: Father " << *FatherOfRunner << " of son " << *SonList[FatherOfRunner->getNr()]
190// << " is bound to " << *OtherFather << ", who has no son in this fragment molecule.");
191 if (saturation == DoSaturate) {
192// LOG(3, "ACCEPT: Adding Hydrogen to " << (*iter)->Name << " and a bond in between.");
193 if (!Leaf->AddHydrogenReplacementAtom((*BondRunner), (*iter), FatherOfRunner, OtherFather, IsAngstroem))
194 exit(1);
195 } else if ((treatment == ExcludeHydrogen) && (OtherFather->getElementNo() == (atomicNumber_t)1)) {
196 // just copy the atom if it's a hydrogen
197 atom * const OtherWalker = Leaf->AddCopyAtom(OtherFather);
198 Leaf->AddBond((*iter), OtherWalker, (*BondRunner)->BondDegree);
199 }
200 //NumBonds[(*iter)->getNr()] += Binder->BondDegree;
201 }
202 }
203 } else {
204 ELOG(1, "Son " << (*iter)->getName() << " has father " << FatherOfRunner->getName() << " but its entry in SonList is " << SonList[FatherOfRunner->getNr()] << "!");
205 }
206 if ((LonelyFlag) && (Leaf->getAtomCount() > 1)) {
207 LOG(0, **iter << "has got bonds only to hydrogens!");
208 }
209 ++iter;
210 if (saturation == DoSaturate) {
211 while ((iter != Leaf->end()) && ((*iter)->getType()->getAtomicNumber() == 1)){ // skip added hydrogen
212 iter++;
213 }
214 }
215 }
216}
Note: See TracBrowser for help on using the repository browser.