RDKit
Open-source cheminformatics and machine learning.
Digraph.h
Go to the documentation of this file.
1 //
2 // Digraph is the core data structure for determining
3 // Cahn–Ingold–Prelog (CIP) chirality of a molecule.
4 //
5 // It's a "directed graph" - meaning that each bond
6 // has a start and an end. For CIP determination,
7 // the start points back towards the atom that is
8 // being labelled.
9 //
10 // Copyright (C) 2020 Schrödinger, LLC
11 //
12 // @@ All Rights Reserved @@
13 // This file is part of the RDKit.
14 // The contents are covered by the terms of the BSD license
15 // which is included in the file license.txt, found at the root
16 // of the RDKit source tree.
17 //
18 #pragma once
19 
20 #include <list>
21 #include <vector>
22 
23 #include <boost/rational.hpp>
24 
25 #include "TooManyNodesException.h"
26 
27 namespace RDKit {
28 
29 class Atom;
30 class Bond;
31 
32 namespace CIPLabeler {
33 
34 class Node;
35 class Edge;
36 class CIPMol;
37 
38 /**
39  * A class to hold directed acyclic graphs representing the molecule.
40  *
41  * The root of the DAG is one of the foci of the configuration for
42  * which the label is being calculated. The tmproot may be set to
43  * other nodes that may become relevant in the calculation.
44  *
45  */
46 class Digraph {
47 
48 public:
49  Digraph() = delete;
50  Digraph(const Digraph &) = delete;
51  Digraph &operator=(const Digraph &) = delete;
52 
53  Digraph(const CIPMol &mol, Atom *atom);
54 
55  const CIPMol &getMol() const;
56 
58 
59  Node *getCurrentRoot() const;
60 
61  int getNumNodes() const;
62 
63  /**
64  * Get all nodes which refer to `atom` in order of
65  * distance from the root.
66  */
67  std::vector<Node *> getNodes(Atom *atom) const;
68 
69  /**
70  * Access the reference atom for Rule 6 (if one is set).
71  */
72  Atom *getRule6Ref() const;
73 
74  /**
75  * Used exclusively for Rule 6, we set one atom as the reference.
76  * @param ref reference atom
77  */
78  void setRule6Ref(Atom *ref);
79 
80  /**
81  * Sets the root node of this digraph by flipping the directions
82  * of edges as required.
83  *
84  * This is more efficient than building a new Digraph, but is
85  * only valid for neighboring Nodes.
86  *
87  * @param newroot the new root
88  */
89  void changeRoot(Node *newroot);
90 
91  void expand(Node *beg);
92 
93  Node &addNode(std::vector<char> &&visit, Atom *atom,
94  boost::rational<int> &&frac, int dist, int flags);
95 
96 private:
97  const CIPMol &d_mol;
98 
99  // The node from which the Digraph is first initialized.
100  // It matches the atom that is being labeled.
101  Node *dp_origin = nullptr;
102 
103  // The current root of the Digraph
104  Node *dp_root = nullptr;
105 
106  Atom *dp_rule6Ref = nullptr;
107 
108  // We can't store these in a vector, as adding new items will
109  // cause it to reallocate and invalidate the references
110  std::list<Node> d_nodes;
111  std::list<Edge> d_edges;
112 
113  void addEdge(Node *beg, Bond *bond, Node *end);
114 };
115 
116 } // namespace CIPLabeler
117 } // namespace RDKit
The class for representing atoms.
Definition: Atom.h:69
class for representing a bond
Definition: Bond.h:47
Node * getOriginalRoot() const
void changeRoot(Node *newroot)
Digraph & operator=(const Digraph &)=delete
const CIPMol & getMol() const
Node & addNode(std::vector< char > &&visit, Atom *atom, boost::rational< int > &&frac, int dist, int flags)
void setRule6Ref(Atom *ref)
Node * getCurrentRoot() const
Digraph(const CIPMol &mol, Atom *atom)
Atom * getRule6Ref() const
std::vector< Node * > getNodes(Atom *atom) const
Digraph(const Digraph &)=delete
Std stuff.
Definition: Abbreviations.h:17