/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * AtomByRandomAction.cpp * * Created on: Sep 11, 2020 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif //#include "CodePatterns/MemDebug.hpp" #include "Atom/atom.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" #include "World.hpp" #include "Descriptors/AtomOrderDescriptor.hpp" #include "RandomNumbers/RandomNumberDistributionFactory.hpp" #include "RandomNumbers/RandomNumberDistribution.hpp" #include "RandomNumbers/RandomNumberDistribution_Parameters.hpp" #include "RandomNumbers/RandomNumberGenerator.hpp" #include "RandomNumbers/RandomNumberGeneratorFactory.hpp" #include #include #include #include #include #include "AtomByRandomAction.hpp" using namespace MoleCuilder; // and construct the stuff #include "AtomByRandomAction.def" #include "Action_impl_pre.hpp" /** =========== define the function ====================== */ ActionState::ptr SelectionAtomByRandomAction::performCall() { // get range of ids const int number_atoms = World::getConstInstance().numAtoms(); LOG(2, "DEBUG: There are " << number_atoms << " to choose from."); // sensibility check: atoms present to select? if (number_atoms <= 0) { STATUS("No atoms are present."); return Action::failure; } const int number_requested = params.number_requested.get(); std::vector atom_ids; if (number_requested >= number_atoms) { STATUS("Desired number is equal or exceeds present atom count, selecting all."); // select all atoms World::getInstance().selectAllAtoms(AllAtoms()); // note down set of all ids for undo const std::vector atoms = World::getConstInstance().getAllAtoms(AllAtoms()); std::transform(atoms.begin(), atoms.end(), std::back_inserter(atom_ids), boost::bind( &atom::getId, _1) ); std::sort(atom_ids.begin(), atom_ids.end()); } else { STATUS("Randomly selecting "+toString(number_requested)+" atoms."); // get present type and parameter set for restore const std::string oldtype = RandomNumberDistributionFactory::getConstInstance().getCurrentTypeName(); RandomNumberDistributionFactory::getInstance().setCurrentType("uniform_01"); const RandomNumberGenerator& rng = RandomNumberGeneratorFactory::getConstInstance().makeRandomNumberGenerator(); // randomly generate ids and select std::set unique_ids; while (unique_ids.size() < number_requested) { const int current_id = (int)(rng()*number_atoms)+1; const atom * const Walker = World::getConstInstance().getAtom(AtomByOrder(current_id)); if (Walker != NULL) { LOG(1, "Selecting " << current_id << "th atom " << Walker->getName() << " from [1," << number_atoms << "]"); World::getInstance().selectAtom(Walker); unique_ids.insert( Walker->getId() ); } } atom_ids.insert(atom_ids.begin(), unique_ids.begin(), unique_ids.end()); // restore old type and parameter set RandomNumberDistributionFactory::getInstance().setCurrentType(oldtype); } return ActionState::ptr(new SelectionAtomByRandomState(atom_ids, params)); } ActionState::ptr SelectionAtomByRandomAction::performUndo(ActionState::ptr _state) { SelectionAtomByRandomState *state = assert_cast(_state.get()); for (atomids_t::const_iterator iter = state->undoatomids.begin(); iter != state->undoatomids.end(); ++iter) World::getInstance().unselectAllAtoms(AtomById(*iter)); return ActionState::ptr(_state); } ActionState::ptr SelectionAtomByRandomAction::performRedo(ActionState::ptr _state){ SelectionAtomByRandomState *state = assert_cast(_state.get()); for (atomids_t::const_iterator iter = state->undoatomids.begin(); iter != state->undoatomids.end(); ++iter) World::getInstance().selectAllAtoms(AtomById(*iter)); return ActionState::ptr(_state); } bool SelectionAtomByRandomAction::canUndo() { return true; } bool SelectionAtomByRandomAction::shouldUndo() { return true; } /** =========== end of function ====================== */