- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/Actions/FragmentationAction/SubgraphDissectionAction.cpp ¶
r952f38 rbcf653 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 1 8 /* 2 9 * SubgraphDissectionAction.cpp … … 6 13 */ 7 14 15 // include config.h 16 #ifdef HAVE_CONFIG_H 17 #include <config.h> 18 #endif 19 8 20 #include "Helpers/MemDebug.hpp" 9 21 10 22 #include "Actions/FragmentationAction/SubgraphDissectionAction.hpp" 11 23 #include "Actions/ActionRegistry.hpp" 24 #include "Descriptors/AtomIdDescriptor.hpp" 25 #include "Descriptors/MoleculeDescriptor.hpp" 26 12 27 #include "atom.hpp" 28 #include "bond.hpp" 29 #include "bondgraph.hpp" 13 30 #include "config.hpp" 14 31 #include "Helpers/Log.hpp" 32 #include "Helpers/Verbose.hpp" 15 33 #include "molecule.hpp" 16 #include "Descriptors/MoleculeDescriptor.hpp"17 34 #include "stackclass.hpp" 18 35 #include "World.hpp" … … 27 44 #include "Actions/ValueStorage.hpp" 28 45 46 // memento to remember the state when undoing 47 48 typedef std::map< moleculeId_t, std::vector<atomId_t> > MolAtomList; 49 50 class FragmentationSubgraphDissectionState : public ActionState { 51 public: 52 FragmentationSubgraphDissectionState(const MolAtomList &_moleculelist) : 53 moleculelist(_moleculelist) 54 {} 55 MolAtomList moleculelist; 56 }; 57 29 58 const char FragmentationSubgraphDissectionAction::NAME[] = "subgraph-dissect"; 30 59 … … 36 65 {} 37 66 67 /** Dissects given \a *mol into connected subgraphs and inserts them as new molecules but with old atoms into \a this. 68 */ 38 69 void FragmentationSubgraphDissection() { 39 70 ActionRegistry::getInstance().getActionByName(FragmentationSubgraphDissectionAction::NAME)->call(Action::NonInteractive); … … 51 82 Action::state_ptr FragmentationSubgraphDissectionAction::performCall() { 52 83 DoLog(1) && (Log() << Verbose(1) << "Dissecting molecular system into a set of disconnected subgraphs ... " << endl); 53 // @TODO rather do the dissection afterwards 84 85 // first create undo state 86 MolAtomList moleculelist; 87 vector<molecule *> allmolecules = World::getInstance().getAllMolecules(); 88 for (vector<molecule *>::const_iterator moliter = allmolecules.begin(); moliter != allmolecules.end(); ++moliter) { 89 std::vector<atomId_t> atomlist; 90 atomlist.resize((*moliter)->size()); 91 for (molecule::const_iterator atomiter = (*moliter)->begin(); atomiter != (*moliter)->end(); ++atomiter) { 92 atomlist.push_back((*atomiter)->getId()); 93 } 94 moleculelist.insert( std::pair< moleculeId_t, std::vector<atomId_t> > ((*moliter)->getId(), atomlist)); 95 } 96 FragmentationSubgraphDissectionState *UndoState = new FragmentationSubgraphDissectionState(moleculelist); 97 54 98 MoleculeListClass *molecules = World::getInstance().getMolecules(); 55 molecules->DissectMoleculeIntoConnectedSubgraphs(World::getInstance().getPeriode(), World::getInstance().getConfig()); 56 return Action::success; 99 config * const configuration = World::getInstance().getConfig(); 100 101 // 0a. remove all present molecules 102 for (vector<molecule *>::iterator MolRunner = allmolecules.begin(); MolRunner != allmolecules.end(); ++MolRunner) { 103 molecules->erase(*MolRunner); 104 World::getInstance().destroyMolecule(*MolRunner); 105 } 106 107 // 0b. remove all bonds and construct a molecule with all atoms 108 molecule *mol = World::getInstance().createMolecule(); 109 { 110 vector <atom *> allatoms = World::getInstance().getAllAtoms(); 111 for(vector<atom *>::iterator AtomRunner = allatoms.begin(); AtomRunner != allatoms.end(); ++AtomRunner) { 112 for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); !(*AtomRunner)->ListOfBonds.empty(); BondRunner = (*AtomRunner)->ListOfBonds.begin()) 113 delete(*BondRunner); 114 mol->AddAtom(*AtomRunner); 115 } 116 } 117 118 // 1. create the bond structure of the single molecule 119 if (configuration->BG != NULL) { 120 if (!configuration->BG->ConstructBondGraph(mol)) { 121 World::getInstance().destroyMolecule(mol); 122 DoeLog(1) && (eLog()<< Verbose(1) << "There are no bonds." << endl); 123 return Action::failure; 124 } 125 } else { 126 DoeLog(1) && (eLog()<< Verbose(1) << "There is no BondGraph class present to create bonds." << endl); 127 return Action::failure; 128 } 129 130 // 2. scan for connected subgraphs 131 MoleculeLeafClass *Subgraphs = NULL; // list of subgraphs from DFS analysis 132 class StackClass<bond *> *BackEdgeStack = NULL; 133 Subgraphs = mol->DepthFirstSearchAnalysis(BackEdgeStack); 134 delete(BackEdgeStack); 135 if ((Subgraphs == NULL) || (Subgraphs->next == NULL)) { 136 //World::getInstance().destroyMolecule(mol); 137 DoeLog(1) && (eLog()<< Verbose(1) << "There are no atoms." << endl); 138 return Action::failure; 139 } 140 int FragmentCounter = Subgraphs->next->Count(); 141 142 // TODO: When DepthFirstSearchAnalysis does not use AddCopyAtom() anymore, we don't need to delete all original atoms 143 { 144 // 3a. destroy the original molecule 145 for (molecule::iterator AtomRunner = mol->begin(); !mol->empty(); AtomRunner = mol->begin()) 146 World::getInstance().destroyAtom(*AtomRunner); 147 World::getInstance().destroyMolecule(mol); 148 // 3b. correct fathers (AddCopyAtom sets father to original atom, which has been destroyed). 149 vector <atom *> allatoms = World::getInstance().getAllAtoms(); 150 for(vector<atom *>::iterator AtomRunner = allatoms.begin(); AtomRunner != allatoms.end(); ++AtomRunner) { 151 (*AtomRunner)->father = *AtomRunner; 152 } 153 } 154 155 // 4. free Leafs 156 MoleculeLeafClass *MolecularWalker = Subgraphs; 157 while (MolecularWalker->next != NULL) { 158 MolecularWalker->Leaf = NULL; 159 MolecularWalker = MolecularWalker->next; 160 delete(MolecularWalker->previous); 161 } 162 MolecularWalker->Leaf = NULL; 163 delete(MolecularWalker); 164 DoLog(1) && (Log() << Verbose(1) << "I scanned " << FragmentCounter << " molecules." << endl); 165 166 return Action::state_ptr(UndoState); 57 167 } 58 168 59 169 Action::state_ptr FragmentationSubgraphDissectionAction::performUndo(Action::state_ptr _state) { 60 // ParserLoadXyzState *state = assert_cast<ParserLoadXyzState*>(_state.get()); 61 62 return Action::failure; 63 // string newName = state->mol->getName(); 64 // state->mol->setName(state->lastName); 65 // 66 // return Action::state_ptr(new ParserLoadXyzState(state->mol,newName)); 170 FragmentationSubgraphDissectionState *state = assert_cast<FragmentationSubgraphDissectionState*>(_state.get()); 171 172 { 173 // remove all present molecules 174 MoleculeListClass *molecules = World::getInstance().getMolecules(); 175 vector<molecule *> allmolecules = World::getInstance().getAllMolecules(); 176 for (vector<molecule *>::iterator MolRunner = allmolecules.begin(); MolRunner != allmolecules.end(); ++MolRunner) { 177 molecules->erase(*MolRunner); 178 World::getInstance().destroyMolecule(*MolRunner); 179 } 180 } 181 182 { 183 // construct the old state 184 molecule *mol = NULL; 185 for (MolAtomList::const_iterator iter = state->moleculelist.begin(); iter != state->moleculelist.end(); ++iter) { 186 mol = World::getInstance().createMolecule(); 187 if (mol->getId() != (*iter).first) 188 World::getInstance().changeMoleculeId(mol->getId(), (*iter).first); 189 for (std::vector<atomId_t>::const_iterator atomiter = (*iter).second.begin(); atomiter != (*iter).second.end(); ++atomiter) 190 mol->AddAtom(World::getInstance().getAtom(AtomById(*atomiter))); 191 } 192 } 193 194 return Action::state_ptr(_state); 67 195 } 68 196 69 197 Action::state_ptr FragmentationSubgraphDissectionAction::performRedo(Action::state_ptr _state){ 70 return Action::failure;198 return performCall(); 71 199 } 72 200 73 201 bool FragmentationSubgraphDissectionAction::canUndo() { 74 return false;202 return true; 75 203 } 76 204 77 205 bool FragmentationSubgraphDissectionAction::shouldUndo() { 78 return false;206 return true; 79 207 } 80 208
Note:
See TracChangeset
for help on using the changeset viewer.