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  public:
48  Digraph() = delete;
49  Digraph(const Digraph &) = delete;
50  Digraph &operator=(const Digraph &) = delete;
51 
52  Digraph(const CIPMol &mol, Atom *atom);
53 
54  const CIPMol &getMol() const;
55 
57 
58  Node *getCurrentRoot() const;
59 
60  int getNumNodes() const;
61 
62  /**
63  * Get all nodes which refer to `atom` in order of
64  * distance from the root.
65  */
66  std::vector<Node *> getNodes(Atom *atom) const;
67 
68  /**
69  * Access the reference atom for Rule 6 (if one is set).
70  */
71  Atom *getRule6Ref() const;
72 
73  /**
74  * Used exclusively for Rule 6, we set one atom as the reference.
75  * @param ref reference atom
76  */
77  void setRule6Ref(Atom *ref);
78 
79  /**
80  * Sets the root node of this digraph by flipping the directions
81  * of edges as required.
82  *
83  * This is more efficient than building a new Digraph, but is
84  * only valid for neighboring Nodes.
85  *
86  * @param newroot the new root
87  */
88  void changeRoot(Node *newroot);
89 
90  void expand(Node *beg);
91 
92  Node &addNode(std::vector<char> &&visit, Atom *atom,
93  boost::rational<int> &&frac, int dist, int flags);
94 
95  private:
96  const CIPMol &d_mol;
97 
98  // The node from which the Digraph is first initialized.
99  // It matches the atom that is being labeled.
100  Node *dp_origin = nullptr;
101 
102  // The current root of the Digraph
103  Node *dp_root = nullptr;
104 
105  Atom *dp_rule6Ref = nullptr;
106 
107  // We can't store these in a vector, as adding new items will
108  // cause it to reallocate and invalidate the references
109  std::list<Node> d_nodes;
110  std::list<Edge> d_edges;
111 
112  void addEdge(Node *beg, Bond *bond, Node *end);
113 };
114 
115 } // namespace CIPLabeler
116 } // namespace RDKit
The class for representing atoms.
Definition: Atom.h:68
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:19