Ignore:
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
    18/*
    29 * SubgraphDissectionAction.cpp
     
    613 */
    714
     15// include config.h
     16#ifdef HAVE_CONFIG_H
     17#include <config.h>
     18#endif
     19
    820#include "Helpers/MemDebug.hpp"
    921
    1022#include "Actions/FragmentationAction/SubgraphDissectionAction.hpp"
    1123#include "Actions/ActionRegistry.hpp"
     24#include "Descriptors/AtomIdDescriptor.hpp"
     25#include "Descriptors/MoleculeDescriptor.hpp"
     26
    1227#include "atom.hpp"
     28#include "bond.hpp"
     29#include "bondgraph.hpp"
    1330#include "config.hpp"
    1431#include "Helpers/Log.hpp"
     32#include "Helpers/Verbose.hpp"
    1533#include "molecule.hpp"
    16 #include "Descriptors/MoleculeDescriptor.hpp"
    1734#include "stackclass.hpp"
    1835#include "World.hpp"
     
    2744#include "Actions/ValueStorage.hpp"
    2845
     46// memento to remember the state when undoing
     47
     48typedef std::map< moleculeId_t, std::vector<atomId_t> > MolAtomList;
     49
     50class FragmentationSubgraphDissectionState : public ActionState {
     51public:
     52  FragmentationSubgraphDissectionState(const MolAtomList &_moleculelist) :
     53   moleculelist(_moleculelist)
     54  {}
     55  MolAtomList moleculelist;
     56};
     57
    2958const char FragmentationSubgraphDissectionAction::NAME[] = "subgraph-dissect";
    3059
     
    3665{}
    3766
     67/** Dissects given \a *mol into connected subgraphs and inserts them as new molecules but with old atoms into \a this.
     68 */
    3869void FragmentationSubgraphDissection() {
    3970  ActionRegistry::getInstance().getActionByName(FragmentationSubgraphDissectionAction::NAME)->call(Action::NonInteractive);
     
    5182Action::state_ptr FragmentationSubgraphDissectionAction::performCall() {
    5283  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
    5498  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);
    57167}
    58168
    59169Action::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);
    67195}
    68196
    69197Action::state_ptr FragmentationSubgraphDissectionAction::performRedo(Action::state_ptr _state){
    70   return Action::failure;
     198  return performCall();
    71199}
    72200
    73201bool FragmentationSubgraphDissectionAction::canUndo() {
    74   return false;
     202  return true;
    75203}
    76204
    77205bool FragmentationSubgraphDissectionAction::shouldUndo() {
    78   return false;
     206  return true;
    79207}
    80208
Note: See TracChangeset for help on using the changeset viewer.