File: Digraph.h

package info (click to toggle)
rdkit 202503.1-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 220,160 kB
  • sloc: cpp: 399,240; python: 77,453; ansic: 25,517; java: 8,173; javascript: 4,005; sql: 2,389; yacc: 1,565; lex: 1,263; cs: 1,081; makefile: 580; xml: 229; fortran: 183; sh: 105
file content (122 lines) | stat: -rw-r--r-- 2,952 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//
// Digraph is the core data structure for determining
// Cahn–Ingold–Prelog (CIP) chirality of a molecule.
//
// It's a "directed graph" - meaning that each bond
// has a start and an end. For CIP determination,
// the start points back towards the atom that is
// being labelled.
//
//  Copyright (C) 2020 Schrödinger, LLC
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#pragma once

#include <list>
#include <vector>

#include <RDGeneral/BoostStartInclude.h>
#include <boost/rational.hpp>
#include <RDGeneral/BoostEndInclude.h>

#include "TooManyNodesException.h"

namespace RDKit {

class Atom;
class Bond;

namespace CIPLabeler {

class Node;
class Edge;
class CIPMol;

/**
 * A class to hold directed acyclic graphs representing the molecule.
 *
 * The root of the DAG is one of the foci of the configuration for
 * which the label is being calculated. The tmproot may be set to
 * other nodes that may become relevant in the calculation.
 *
 */
class Digraph {
 public:
  Digraph() = delete;
  Digraph(const Digraph &) = delete;
  Digraph &operator=(const Digraph &) = delete;

  Digraph(const CIPMol &mol, Atom *atom, bool atropsomerMode = false);

  const CIPMol &getMol() const;

  Node *getOriginalRoot() const;

  Node *getCurrentRoot() const;

  int getNumNodes() const;

  /**
   * Get all nodes which refer to `atom` in order of
   * distance from the root.
   */
  std::vector<Node *> getNodes(Atom *atom) const;

  /**
   * Access the reference atom for Rule 6 (if one is set).
   */
  Atom *getRule6Ref() const;

  /**
   * Used exclusively for Rule 6, we set one atom as the reference.
   * @param ref reference atom
   */
  void setRule6Ref(Atom *ref);

  /**
   * Sets the root node of this digraph by flipping the directions
   * of edges as required.
   *
   * This is more efficient than building a new Digraph, but is
   * only valid for neighboring Nodes.
   *
   * @param newroot the new root
   */
  void changeRoot(Node *newroot);

  void expand(Node *beg);

  Node &addNode(std::vector<char> &&visit, Atom *atom,
                boost::rational<int> &&frac, int dist, int flags);

 private:
  const CIPMol &d_mol;

  // The node from which the Digraph is first initialized.
  // It matches the atom that is being labeled.
  Node *dp_origin = nullptr;

  // in atropisomer mode, we expand the two atoms of the atrop bond

  bool d_atropisomerMode = false;

  // The current root of the Digraph
  Node *dp_root = nullptr;

  Atom *dp_rule6Ref = nullptr;

  // We can't store these in a vector, as adding new items will
  // cause it to reallocate and invalidate the references
  std::list<Node> d_nodes;
  std::list<Edge> d_edges;

  void addEdge(Node *beg, Bond *bond, Node *end);
};

}  // namespace CIPLabeler
}  // namespace RDKit