[f5ea10] | 1 | /*
|
---|
| 2 | * Project: MoleCuilder
|
---|
| 3 | * Description: creates and alters molecular systems
|
---|
| 4 | * Copyright (C) 2017 Frederik Heber. 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 | * ChemicalSpaceEvaluator.cpp
|
---|
| 25 | *
|
---|
| 26 | * Created on: Sep 26, 2017
|
---|
| 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 <iostream>
|
---|
| 38 | #include <string>
|
---|
| 39 | #include <vector>
|
---|
| 40 |
|
---|
| 41 | #include "CodePatterns/Log.hpp"
|
---|
| 42 |
|
---|
| 43 | #include "Actions/GraphAction/ChemicalSpaceEvaluatorAction.hpp"
|
---|
| 44 |
|
---|
| 45 | #include "Element/element.hpp"
|
---|
| 46 | #include "Graph/BoostGraphCreator.hpp"
|
---|
| 47 | #include "Fragmentation/Homology/HomologyContainer.hpp"
|
---|
| 48 | #include "FunctionApproximation/Extractors.hpp"
|
---|
| 49 | #include "World.hpp"
|
---|
| 50 |
|
---|
| 51 | #include <boost/graph/adjacency_list.hpp>
|
---|
| 52 |
|
---|
| 53 | using namespace MoleCuilder;
|
---|
| 54 |
|
---|
| 55 | // and construct the stuff
|
---|
| 56 | #include "ChemicalSpaceEvaluatorAction.def"
|
---|
| 57 | #include "Action_impl_pre.hpp"
|
---|
| 58 | /** =========== define the function ====================== */
|
---|
| 59 | ActionState::ptr GraphChemicalSpaceEvaluatorAction::performCall() {
|
---|
| 60 | // create boost::graph from graph6 string
|
---|
| 61 | BoostGraphCreator BGC;
|
---|
| 62 | BGC.createFromGraph6String(params.graph_string.get());
|
---|
| 63 |
|
---|
| 64 | BoostGraphCreator::UndirectedGraph graph = BGC.get();
|
---|
| 65 |
|
---|
| 66 | Extractors::index_map_t index_map = boost::get(boost::vertex_index, graph);
|
---|
| 67 | LOG(2, "DEBUG: We have " << boost::num_vertices(graph) << " nodes in the fragment graph.");
|
---|
| 68 |
|
---|
| 69 | // associate type with a node index
|
---|
| 70 | Extractors::type_index_lookup_t type_index_lookup;
|
---|
| 71 | std::vector<unsigned int> elementnumbers;
|
---|
| 72 | elementnumbers.reserve(params.graph_elements.get().size());
|
---|
| 73 | for (std::vector<const element *>::const_iterator iter = params.graph_elements.get().begin();
|
---|
| 74 | iter != params.graph_elements.get().end(); ++iter) {
|
---|
| 75 | elementnumbers.push_back((*iter)->getAtomicNumber());
|
---|
| 76 | type_index_lookup.left.insert(
|
---|
| 77 | std::make_pair(
|
---|
| 78 | std::distance(iter, params.graph_elements.get().begin()),
|
---|
| 79 | Extractors::ParticleType_t(elementnumbers.back())));
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | // create all induced subgraphs
|
---|
| 83 | const size_t nodes_in_graph = boost::num_vertices(graph);
|
---|
| 84 | LOG(2, "DEBUG: There are " << nodes_in_graph << " nodes in the graph.");
|
---|
| 85 | Extractors::set_of_nodes_t set_of_nodes;
|
---|
| 86 | for (size_t nodeid = 0; nodeid < nodes_in_graph; ++nodeid) {
|
---|
| 87 | const size_t &rootindex = nodeid;
|
---|
| 88 | LOG(2, "DEBUG: Current root index is " << rootindex);
|
---|
| 89 |
|
---|
| 90 | /// 5a. from node in graph (with this index) perform BFS till n-1 (#nodes in binding model)
|
---|
| 91 | std::vector<size_t> distances(boost::num_vertices(graph));
|
---|
| 92 | boost::breadth_first_search(
|
---|
| 93 | graph,
|
---|
| 94 | boost::vertex(rootindex, graph),
|
---|
| 95 | boost::visitor(Extractors::record_distance(&distances[0])));
|
---|
| 96 | LOG(3, "DEBUG: BFS discovered the following distances " << distances);
|
---|
| 97 |
|
---|
| 98 | /// 5b. and store all node in map with distance to root as key
|
---|
| 99 | Extractors::nodes_per_level_t nodes_per_level;
|
---|
| 100 | for (size_t i=0;i<distances.size();++i) {
|
---|
| 101 | nodes_per_level.insert( std::make_pair(Extractors::level_t(distances[i]), Extractors::node_t(i)) );
|
---|
| 102 | }
|
---|
| 103 | LOG(3, "DEBUG: Nodes per level are " << nodes_per_level);
|
---|
| 104 |
|
---|
| 105 | /// 6. construct all possible induced connected subgraphs with this map (see fragmentation)
|
---|
| 106 | Extractors::nodes_t nodes;
|
---|
| 107 | // rootindex is always contained
|
---|
| 108 | nodes.insert( rootindex );
|
---|
| 109 | Extractors::level_t level = 0;
|
---|
| 110 |
|
---|
| 111 | Extractors::generateAllInducedConnectedSubgraphs(
|
---|
| 112 | nodes_in_graph-1, level, nodes, set_of_nodes, nodes_per_level, graph, distances, index_map);
|
---|
| 113 | LOG(2, "DEBUG: We have found " << set_of_nodes.size() << " unique induced, connected subgraphs.");
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | const HomologyContainer &container = World::getInstance().getHomologies();
|
---|
| 117 | /// go through each induced, connected subgraph
|
---|
| 118 | for (Extractors::set_of_nodes_t::const_iterator nodesiter = set_of_nodes.begin();
|
---|
| 119 | nodesiter != set_of_nodes.end(); ++nodesiter) {
|
---|
| 120 | /// convert its nodes into a HomologyGraph using the graph and elements (types for index)
|
---|
| 121 | const Extractors::nodes_t &nodes = *nodesiter;
|
---|
| 122 | const HomologyGraph nodes_graph =
|
---|
| 123 | Extractors::createHomologyGraphFromNodes(nodes, type_index_lookup, graph, index_map);
|
---|
| 124 |
|
---|
| 125 | /// Query HomologyContainer for this HomologyGraph.
|
---|
| 126 | HomologyContainer::range_t range = container.getHomologousGraphs(nodes_graph);
|
---|
| 127 |
|
---|
| 128 | if (range.first == range.second) {
|
---|
| 129 | // range is empty, the fragment is unknown
|
---|
| 130 | ELOG(1, "Cannot find fragment graph " << nodes_graph << " to graph " << elementnumbers);
|
---|
| 131 | } else {
|
---|
| 132 | // list first energy
|
---|
| 133 | LOG(1, "Fragment graph " << nodes_graph << " has energy " << range.first->second.energy);
|
---|
| 134 | }
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | return Action::success;
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | ActionState::ptr GraphChemicalSpaceEvaluatorAction::performUndo(ActionState::ptr _state) {
|
---|
| 141 | return Action::success;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | ActionState::ptr GraphChemicalSpaceEvaluatorAction::performRedo(ActionState::ptr _state){
|
---|
| 145 | return Action::success;
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | bool GraphChemicalSpaceEvaluatorAction::canUndo() {
|
---|
| 149 | return true;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | bool GraphChemicalSpaceEvaluatorAction::shouldUndo() {
|
---|
| 153 | return true;
|
---|
| 154 | }
|
---|
| 155 | /** =========== end of function ====================== */
|
---|