/* * HomologyGraph.hpp * * Created on: Sep 24, 2012 * Author: heber */ #ifndef HOMOLOGYGRAPH_HPP_ #define HOMOLOGYGRAPH_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "Fragmentation/Homology/FragmentEdge.hpp" #include "Fragmentation/Homology/FragmentNode.hpp" class IndexSet; class KeySet; /** This class contains the representation of a molecular fragment as a graph. * * Only, we do not store the full graph in here. We have to include symmetries * such that two hydrogens may switch places. Eventually, we only look for the * set of distances of a fragment. If two hydrogens switch places, then also in * the set of distances some distances are interchanged but the whole fragment * remains the same. Hence, we have to store the bond graph representation in * such a way as to automatically include these symmetries. * * To this end, we use FragmentNode and FragmentEdge to store the vital * information. * */ class HomologyGraph { //!> grant output operator access to internals friend std::ostream& operator<<(std::ostream& ost, const HomologyGraph &graph); public: //!> typedef for a set of nodes representing node information typedef std::map nodes_t; //!> typedef for a set of nodes representing edge information typedef std::map edges_t; public: /** Default constructor for class HomologyGraph. * * This is required to allow placement in STL containers * */ HomologyGraph() {} /** Constructor for class HomologyGraph. * * @param _nodes information on nodes of this graph * @param _edges information on edges of this graph */ HomologyGraph(const nodes_t &_nodes, const edges_t &_edges) : nodes(_nodes), edges(_edges) {} /** Constructor for class HomologyGraph from a keyset (i.e. from atoms in the World). * * @param keyset global ids of atoms to pick */ HomologyGraph(const KeySet &keyset); /** Constructor for class HomologyGraph from a IndexSet (i.e. from atoms in the World). * * @param index global ids of atoms to pick */ HomologyGraph(const IndexSet &index); /** Destructor for class HomologyGraph. * */ ~HomologyGraph() {} // comparators (allows sorting and hence quicker finding in STL containers) bool operator<(const HomologyGraph &graph) const; bool operator>(const HomologyGraph &graph) const; bool operator==(const HomologyGraph &graph) const; bool operator!=(const HomologyGraph &graph) const { return (!(*this == graph)); } /** Checks whether this graph contains a specific \a node. * * @param node node to look for * @param count how often this node must occur * @return true - graph contains this node at least once, false - else */ bool hasNode(const FragmentNode &node, const size_t count = 1) const { nodes_t::const_iterator iter = nodes.find(node); if (iter == nodes.end()) return count == 0; else return (iter->second == count); } /** Checks whether this graph contains a specific \a edge. * * @param edge edge to look for * @param count how often this edge must occur * @return true - graph contains this edge at least once, false - else */ bool hasEdge(const FragmentEdge &edge, const size_t count = 1) const { edges_t::const_iterator iter = edges.find(edge); if (iter == edges.end()) return count == 0; else return (iter->second == count); } /** Checks whether this graph has \b exactly \a _times nodes with \a _number * atomic number. * * @param _number desired atomic number * @param _times number this must occur * @return true - graph has exactly \a _times nodes with \a _number, false - else */ bool hasTimesAtomicNumber(const size_t _number, const size_t _times) const; /** Checks whether this graph has \b greater equal \a _times nodes with \a _number * atomic number. * * @param _number desired atomic number * @param _times number this must occur * @return true - graph has greater equal \a _times nodes with \a _number, false - else */ bool hasGreaterEqualTimesAtomicNumber(const size_t _number, const size_t _times) const; /** Assignment operator for class HomologyGraph. * * This is required to allow placement in STL container as we need to * const_cast override our const member variables. * */ HomologyGraph& operator=(const HomologyGraph &graph); /** Prints the nodes in the graph to stream \a ost. * * \param ost stream to print to */ void printNodes(std::ostream& ost) const; /** Prints the edges in the graph to stream \a ost. * * \param ost stream to print to */ void printEdges(std::ostream& ost) const; /** Getter for the nodes contained in this graph. * * \return const ref to vector of FragmentNode */ const nodes_t &getNodes() const { return nodes; } /** Getter for the edges contained in this graph. * * \return const ref to vector of FragmentEdge */ const edges_t &getEdges() const { return edges; } private: //!> information on the nodes of the graph const nodes_t nodes; //!> information on the edges of the graph const edges_t edges; private: friend class boost::serialization::access; // serialization template void serialize(Archive& ar, const unsigned int version) { ar & const_cast(nodes); ar & const_cast(edges); } }; std::ostream& operator<<(std::ostream& ost, const HomologyGraph &graph); // we need to give this class a unique key for serialization BOOST_CLASS_EXPORT_KEY(HomologyGraph) // define some helpers outside to allow for light-weight unit testing namespace detail { const HomologyGraph::nodes_t getNodesFromKeySet(const KeySet &keyset); const HomologyGraph::edges_t getEdgesFromKeySet(const KeySet &keyset); const HomologyGraph::nodes_t getNodesFromIndexSet(const IndexSet &keyset); const HomologyGraph::edges_t getEdgesFromIndexSet(const IndexSet &keyset); }; #endif /* HOMOLOGYGRAPH_HPP_ */