RDKit
Open-source cheminformatics and machine learning.
Configuration.h
Go to the documentation of this file.
1 //
2 //
3 // Copyright (C) 2020 Schrödinger, LLC
4 //
5 // @@ All Rights Reserved @@
6 // This file is part of the RDKit.
7 // The contents are covered by the terms of the BSD license
8 // which is included in the file license.txt, found at the root
9 // of the RDKit source tree.
10 //
11 #pragma once
12 
13 #include <memory>
14 #include <vector>
15 
16 #include "../Descriptor.h"
17 #include "../Digraph.h"
18 #include "../CIPMol.h"
19 
20 namespace RDKit {
21 
22 class Atom;
23 class Bond;
24 
25 namespace CIPLabeler {
26 
27 class Rules;
28 
30  public:
31  template <typename T>
32  static int parity4(const std::vector<T> &trg, const std::vector<T> &ref) {
33  if (ref.size() != 4 || trg.size() != ref.size()) {
34  throw std::runtime_error("Parity vectors must have size 4.");
35  }
36 
37  if (ref[0] == trg[0]) {
38  if (ref[1] == trg[1]) {
39  // a,b,c,d -> a,b,c,d
40  if (ref[2] == trg[2] && ref[3] == trg[3]) {
41  return 2;
42  }
43  // a,b,c,d -> a,b,d,c
44  if (ref[2] == trg[3] && ref[3] == trg[2]) {
45  return 1;
46  }
47  } else if (ref[1] == trg[2]) {
48  // a,b,c,d -> a,c,b,d
49  if (ref[2] == trg[1] && ref[3] == trg[3]) {
50  return 1;
51  }
52  // a,b,c,d -> a,c,d,b
53  if (ref[2] == trg[3] && ref[3] == trg[1]) {
54  return 2;
55  }
56  } else if (ref[1] == trg[3]) {
57  // a,b,c,d -> a,d,c,b
58  if (ref[2] == trg[2] && ref[3] == trg[1]) {
59  return 1;
60  }
61  // a,b,c,d -> a,d,b,c
62  if (ref[2] == trg[1] && ref[3] == trg[2]) {
63  return 2;
64  }
65  }
66  } else if (ref[0] == trg[1]) {
67  if (ref[1] == trg[0]) {
68  // a,b,c,d -> b,a,c,d
69  if (ref[2] == trg[2] && ref[3] == trg[3]) {
70  return 1;
71  }
72  // a,b,c,d -> b,a,d,c
73  if (ref[2] == trg[3] && ref[3] == trg[2]) {
74  return 2;
75  }
76  } else if (ref[1] == trg[2]) {
77  // a,b,c,d -> b,c,a,d
78  if (ref[2] == trg[0] && ref[3] == trg[3]) {
79  return 2;
80  }
81  // a,b,c,d -> b,c,d,a
82  if (ref[2] == trg[3] && ref[3] == trg[0]) {
83  return 1;
84  }
85  } else if (ref[1] == trg[3]) {
86  // a,b,c,d -> b,d,c,a
87  if (ref[2] == trg[2] && ref[3] == trg[0]) {
88  return 2;
89  }
90  // a,b,c,d -> b,d,a,c
91  if (ref[2] == trg[0] && ref[3] == trg[2]) {
92  return 1;
93  }
94  }
95  } else if (ref[0] == trg[2]) {
96  if (ref[1] == trg[1]) {
97  // a,b,c,d -> c,b,a,d
98  if (ref[2] == trg[0] && ref[3] == trg[3]) {
99  return 1;
100  }
101  // a,b,c,d -> c,b,d,a
102  if (ref[2] == trg[3] && ref[3] == trg[0]) {
103  return 2;
104  }
105  } else if (ref[1] == trg[0]) {
106  // a,b,c,d -> c,a,b,d
107  if (ref[2] == trg[1] && ref[3] == trg[3]) {
108  return 2;
109  }
110  // a,b,c,d -> c,a,d,b
111  if (ref[2] == trg[3] && ref[3] == trg[1]) {
112  return 1;
113  }
114  } else if (ref[1] == trg[3]) {
115  // a,b,c,d -> c,d,a,b
116  if (ref[2] == trg[0] && ref[3] == trg[1]) {
117  return 2;
118  }
119  // a,b,c,d -> c,d,b,a
120  if (ref[2] == trg[1] && ref[3] == trg[0]) {
121  return 1;
122  }
123  }
124  } else if (ref[0] == trg[3]) {
125  if (ref[1] == trg[1]) {
126  // a,b,c,d -> d,b,c,a
127  if (ref[2] == trg[2] && ref[3] == trg[0]) {
128  return 1;
129  }
130  // a,b,c,d -> d,b,a,c
131  if (ref[2] == trg[0] && ref[3] == trg[2]) {
132  return 2;
133  }
134  } else if (ref[1] == trg[2]) {
135  // a,b,c,d -> d,c,b,a
136  if (ref[2] == trg[1] && ref[3] == trg[0]) {
137  return 2;
138  }
139  // a,b,c,d -> d,c,a,b
140  if (ref[2] == trg[0] && ref[3] == trg[1]) {
141  return 1;
142  }
143  } else if (ref[1] == trg[0]) {
144  // a,b,c,d -> d,a,c,b
145  if (ref[2] == trg[2] && ref[3] == trg[1]) {
146  return 2;
147  }
148  // a,b,c,d -> d,a,b,c
149  if (ref[2] == trg[1] && ref[3] == trg[2]) {
150  return 1;
151  }
152  }
153  }
154 
155  // We should never hit this, but the compiler still complains
156  // about a missing return statement.
157  return 0;
158  }
159 
160  Configuration() = delete;
161 
162  Configuration(const CIPMol &mol, Atom *focus);
163 
164  Configuration(const CIPMol &mol, std::vector<Atom *> &&foci);
165 
166  virtual ~Configuration();
167 
168  Atom *getFocus() const;
169 
170  const std::vector<Atom *> &getFoci() const;
171 
172  const std::vector<Atom *> &getCarriers() const;
173 
175 
176  virtual Descriptor label(Node *node, Digraph &digraph, const Rules &comp);
177 
178  virtual Descriptor label(const Rules &comp) = 0;
179 
180  virtual void setPrimaryLabel(Descriptor desc) = 0;
181 
182  protected:
183  Edge *findInternalEdge(const std::vector<Edge *> &edges, Atom *f1, Atom *f2);
184 
185  bool isInternalEdge(const Edge *edge, Atom *f1, Atom *f2);
186 
187  void removeInternalEdges(std::vector<Edge *> &edges, Atom *f1, Atom *f2);
188 
189  void setCarriers(std::vector<Atom *> &&carriers);
190 
191  private:
192  /**
193  * Foci are the atoms on which the configuration is based,
194  * and which will carry the label. E.g., the chiral atom in
195  * a tetrahedral chirality, or the bond ends in a double bond.
196  */
197  std::vector<Atom *> d_foci;
198 
199  /**
200  * Carriers are the atoms neighboring the foci that define the
201  * configuration. E.g., for a chiral atom, its four neighbors
202  * define a parity; for a double bond, one neighbor on each
203  * side of the bond defines it as Cis or Trans.
204  */
205  std::vector<Atom *> d_carriers;
206 
207  Digraph d_digraph;
208 
209 }; // namespace CIPLabeler
210 
211 } // namespace CIPLabeler
212 } // namespace RDKit
The class for representing atoms.
Definition: Atom.h:68
void setCarriers(std::vector< Atom * > &&carriers)
virtual Descriptor label(Node *node, Digraph &digraph, const Rules &comp)
Edge * findInternalEdge(const std::vector< Edge * > &edges, Atom *f1, Atom *f2)
virtual void setPrimaryLabel(Descriptor desc)=0
void removeInternalEdges(std::vector< Edge * > &edges, Atom *f1, Atom *f2)
const std::vector< Atom * > & getFoci() const
bool isInternalEdge(const Edge *edge, Atom *f1, Atom *f2)
Configuration(const CIPMol &mol, Atom *focus)
virtual Descriptor label(const Rules &comp)=0
Configuration(const CIPMol &mol, std::vector< Atom * > &&foci)
const std::vector< Atom * > & getCarriers() const
static int parity4(const std::vector< T > &trg, const std::vector< T > &ref)
Definition: Configuration.h:32
Std stuff.
Definition: Abbreviations.h:19