/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2017 Frederik Heber. 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 .
*/
/*
* BoostGraphCreator.cpp
*
* Created on: May 17, 2017
* Author: heber
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
//#include "CodePatterns/MemDebug.hpp"
#include "BoostGraphCreator.hpp"
#include
#include "CodePatterns/Assert.hpp"
#include "Atom/atom.hpp"
#include "molecule.hpp"
void BoostGraphCreator::createFromMolecule(
const molecule &_mol,
const predicate_t &_pred)
{
createFromRange(_mol.begin(), _mol.end(), _mol.getAtomCount(), _pred);
}
static bool predicateAnd(
const BoostGraphCreator::predicate_t &_pred1,
const BoostGraphCreator::predicate_t &_pred2,
const bond &_bond)
{ return (_pred1(_bond) && _pred2(_bond)); }
static atomId_t getAtomId(
const atom *_atom
)
{ return _atom->getId(); }
static bool inSetPredicate(
const std::vector &_atomids,
const bond &_bond)
{
const atomId_t leftid = _bond.leftatom->getId();
const atomId_t rightid = _bond.rightatom->getId();
return std::binary_search(_atomids.begin(), _atomids.end(), leftid)
&& std::binary_search(_atomids.begin(), _atomids.end(), rightid);
}
void BoostGraphCreator::createFromAtoms(
const std::vector &_atoms,
const predicate_t &_pred)
{
// sort makes binary_search possible
std::vector atomids;
std::transform(_atoms.begin(), _atoms.end(),
std::back_inserter(atomids), getAtomId);
ASSERT( _atoms.size() == atomids.size(),
"BoostGraphCreator::createFromAtom() - atomids "
+toString(atomids.size())+" and atoms "+toString(_atoms.size())
+" differ in size?");
std::sort(atomids.begin(), atomids.end());
const predicate_t predicate = boost::bind(inSetPredicate, boost::ref(atomids), _1);
createFromRange::const_iterator>(
const_cast &>(_atoms).begin(),
const_cast &>(_atoms).end(),
_atoms.size(),
boost::bind(predicateAnd, _pred, predicate, _1));
}
BoostGraphCreator::nodeId_t BoostGraphCreator::getNodeId(
const atomId_t &_atomid) const
{
atomids_nodeids_t::const_iterator iter =
atomids_nodeids.find(_atomid);
return (iter == atomids_nodeids.end()) ? (nodeId_t)-1 : iter->second;
}
BoostGraphCreator::Edge BoostGraphCreator::findEdge(const atomId_t &_firstid, const atomId_t &_secondid)
{
edge_iter i, end;
const name_map_t name_map = boost::get(boost::vertex_name, graph);
for (boost::tie(i, end) = boost::edges(graph); i != end; ++i) {
const BoostGraphCreator::Edge &e = *i;
const Vertex u = source(e, graph);
const Vertex v = target(e, graph);
const atomId_t atomid_u = boost::get(name_map, u);
const atomId_t atomid_v = boost::get(name_map, v);
if (atomid_u == _firstid) {
if (atomid_v == _secondid)
break;
} else if (atomid_u == _secondid) {
if (atomid_v == _firstid)
break;
}
}
if (i != end) {
BoostGraphCreator::Edge e = *i;
return e;
}
return BoostGraphCreator::Edge();
}
bool BoostGraphCreator::removeEdge(const atomId_t &_firstid, const atomId_t &_secondid)
{
// look through all edges
BoostGraphCreator::Edge e = findEdge(_firstid, _secondid);
// edge was found
if (e != BoostGraphCreator::Edge()) {
const Vertex u = source(e, graph);
const Vertex v = target(e, graph);
if (DoLog(3)) {
const name_map_t name_map = boost::get(boost::vertex_name, graph);
LOG(3, "DEBUG: Found edge " << boost::get(name_map, u) << " <-> "
<< boost::get(name_map, v) << ", removing.");
}
boost::remove_edge(e, graph);
return true;
}
return false;
}
bool BoostGraphCreator::addEdge(const atomId_t &_firstid, const atomId_t &_secondid)
{
// look through all edges
BoostGraphCreator::Edge e = findEdge(_firstid, _secondid);
if (e != BoostGraphCreator::Edge()) {
return false;
} else {
const nodeId_t leftnodeid = getNodeId(_firstid);
const nodeId_t rightnodeid = getNodeId(_secondid);
boost::add_edge(leftnodeid, rightnodeid, graph);
return true;
}
}