File: Chirality.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 (429 lines) | stat: -rw-r--r-- 16,223 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
//
//  Copyright (C) 2008-2022 Greg Landrum and other RDKit contributors
//
//   @@ 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.
//
/*! \file Chirality.h

*/
#include <RDGeneral/export.h>
#ifndef RD_CHIRALITY_20AUG2008_H
#define RD_CHIRALITY_20AUG2008_H
#include <RDGeneral/types.h>
#include <GraphMol/Atom.h> /* for Atom:ChiralType enum */
#include <GraphMol/Bond.h> /* for Bond::BondDir enum */
#include <boost/dynamic_bitset.hpp>
#include <limits>

namespace RDKit {
class Atom;
class Bond;
class ROMol;
class Conformer;

namespace Chirality {

//! double bond stereo will be ignored/removed for rings smaller than this:
constexpr unsigned int minRingSizeForDoubleBondStereo = 8;

constexpr auto nonTetrahedralStereoEnvVar = "RDK_ENABLE_NONTETRAHEDRAL_STEREO";
constexpr auto useLegacyStereoEnvVar = "RDK_USE_LEGACY_STEREO_PERCEPTION";
constexpr bool nonTetrahedralStereoDefaultVal =
    true;  //!< whether or not nontetrahedral stereo is perceived by default
constexpr bool useLegacyStereoDefaultVal =
    true;  //!< whether or not the legacy stereo perception code is used by
           //!< default

RDKIT_GRAPHMOL_EXPORT extern void setAllowNontetrahedralChirality(bool val);
RDKIT_GRAPHMOL_EXPORT extern bool getAllowNontetrahedralChirality();

RDKIT_GRAPHMOL_EXPORT extern void setUseLegacyStereoPerception(bool val);
RDKIT_GRAPHMOL_EXPORT extern bool getUseLegacyStereoPerception();

RDKIT_GRAPHMOL_EXPORT void removeNonExplicit3DChirality(ROMol &mol);

RDKIT_GRAPHMOL_EXPORT extern bool
    useLegacyStereoPerception;  //!< Toggle usage of the legacy stereo
                                //!< perception code

RDKIT_GRAPHMOL_EXPORT extern bool
    useLegacyStereoPerception;  //!< Toggle usage of the legacy stereo
                                //!< perception code

/// @cond
/*!
  \param mol the molecule to be altered
  \param ranks  used to return the set of ranks.
                Should be at least mol.getNumAtoms() long.

  <b>Notes:</b>
     - All atoms gain a property common_properties::_CIPRank with their overall
       CIP ranking.

*/
RDKIT_GRAPHMOL_EXPORT void assignAtomCIPRanks(const ROMol &mol,
                                              UINT_VECT &ranks);

RDKIT_GRAPHMOL_EXPORT bool hasStereoBondDir(const Bond *bond);

/**
 *  Returns the first neighboring bond that can be found which has a stereo
 * bond direction set. If no such bond can be found, it returns null. No
 * checks are made to ensure there aren't any other conflicting directed bonds.
 */
RDKIT_GRAPHMOL_EXPORT const Bond *getNeighboringDirectedBond(const ROMol &mol,
                                                             const Atom *atom);

/**
 *  This just translates the labels, setting/translating StereoAtoms or the
 * label is not the responsibility of this function. If the passed label is not
 * E/Z, it will be returned unchanged.
 */
RDKIT_GRAPHMOL_EXPORT Bond::BondStereo translateEZLabelToCisTrans(
    Bond::BondStereo label);
/// @endcond

enum class StereoType {
  Unspecified,
  Atom_Tetrahedral,
  Atom_SquarePlanar,
  Atom_TrigonalBipyramidal,
  Atom_Octahedral,
  Bond_Double,         // single double bond and odd-numbered cumulenes
  Bond_Cumulene_Even,  // even-numbered cumulenes
  Bond_Atropisomer
};

enum class StereoDescriptor {
  None,
  Tet_CW,
  Tet_CCW,
  Bond_Cis,
  Bond_Trans,
  Bond_AtropCW,
  Bond_AtropCCW
};

enum class StereoSpecified {
  Unspecified,  // no information provided
  Specified,
  Unknown  // deliberately marked as unknown
};

struct RDKIT_GRAPHMOL_EXPORT StereoInfo {
  // REVIEW: absolute stereo data member?
#ifdef _MSC_VER
  static const unsigned NOATOM =
      std::numeric_limits<unsigned>::max();  // used to mark missing atoms
#else
  static const unsigned NOATOM;  // used to mark missing atoms
#endif
  StereoType type = StereoType::Unspecified;
  StereoSpecified specified = StereoSpecified::Unspecified;
  unsigned centeredOn = NOATOM;
  StereoDescriptor descriptor = StereoDescriptor::None;
  unsigned permutation = 0;  // for the non-tetrahedral stereo cases
  std::vector<unsigned> controllingAtoms;  // all atoms around the atom or bond.
  // Order is important
  bool operator==(const StereoInfo &other) const {
    return type == other.type && specified == other.specified &&
           centeredOn == other.centeredOn && descriptor == other.descriptor &&
           permutation == other.permutation &&
           controllingAtoms == other.controllingAtoms;
  }
  bool operator!=(const StereoInfo &other) const { return !(*this == other); }
};

//! identifies potential stereoatoms and stereobonds in a molecule
/*!
  Note that this function is still somewhat experimental and the API
  and results may change in a future release.

  \param mol the molecule to look for stereo in
  \param cleanIt remove chirality/stereo specifications from atoms/bonds that
     cannot be chiral/stereo
*/
RDKIT_GRAPHMOL_EXPORT std::vector<StereoInfo> findPotentialStereo(
    ROMol &mol, bool cleanIt, bool flagPossible = true);
//! overload
RDKIT_GRAPHMOL_EXPORT std::vector<StereoInfo> findPotentialStereo(
    const ROMol &mol);

//! removes atoms without specified chirality from stereo groups
RDKIT_GRAPHMOL_EXPORT void cleanupStereoGroups(ROMol &mol);

//! calls the approximate legacy code for assigning CIP labels
RDKIT_GRAPHMOL_EXPORT void assignLegacyCIPLabels(
    ROMol &mol, bool flagPossibleStereoCenters = false);

/// @cond
namespace detail {
RDKIT_GRAPHMOL_EXPORT bool isAtomPotentialNontetrahedralCenter(
    const Atom *atom);
RDKIT_GRAPHMOL_EXPORT bool isAtomPotentialTetrahedralCenter(const Atom *atom);
RDKIT_GRAPHMOL_EXPORT bool isAtomPotentialStereoAtom(const Atom *atom);
RDKIT_GRAPHMOL_EXPORT bool isBondPotentialStereoBond(const Bond *bond);
RDKIT_GRAPHMOL_EXPORT StereoInfo getStereoInfo(const Bond *bond);
RDKIT_GRAPHMOL_EXPORT StereoInfo getStereoInfo(const Atom *atom);
RDKIT_GRAPHMOL_EXPORT bool bondAffectsAtomChirality(const Bond *bond,
                                                    const Atom *atom);
RDKIT_GRAPHMOL_EXPORT unsigned int getAtomNonzeroDegree(const Atom *atom);

RDKIT_GRAPHMOL_EXPORT bool has_protium_neighbor(const ROMol &mol,
                                                const Atom *atom);

}  // namespace detail
/// @endcond

RDKIT_GRAPHMOL_EXPORT INT_VECT findStereoAtoms(const Bond *bond);

//! \name Non-tetrahedral stereochemistry
//! @{
RDKIT_GRAPHMOL_EXPORT bool hasNonTetrahedralStereo(const Atom *center);
RDKIT_GRAPHMOL_EXPORT Bond *getChiralAcrossBond(const Atom *center,
                                                const Bond *qry);
RDKIT_GRAPHMOL_EXPORT Bond *getChiralAcrossBond(const Atom *center,
                                                const Atom *qry);
RDKIT_GRAPHMOL_EXPORT Atom *getChiralAcrossAtom(const Atom *center,
                                                const Bond *qry);
RDKIT_GRAPHMOL_EXPORT Atom *getChiralAcrossAtom(const Atom *center,
                                                const Atom *qry);
//! \param which: if this is -1 then the second axial bond will be returned,
//! otherwise the first
RDKIT_GRAPHMOL_EXPORT Bond *getTrigonalBipyramidalAxialBond(const Atom *center,
                                                            int which = 0);
RDKIT_GRAPHMOL_EXPORT Atom *getTrigonalBipyramidalAxialAtom(const Atom *center,
                                                            int which = 0);

//! \returns 1 if it's the first axial atom, -1 if it's the second
RDKIT_GRAPHMOL_EXPORT int isTrigonalBipyramidalAxialBond(const Atom *center,
                                                         const Bond *qry);
RDKIT_GRAPHMOL_EXPORT int isTrigonalBipyramidalAxialAtom(const Atom *center,
                                                         const Atom *qry);

RDKIT_GRAPHMOL_EXPORT double getIdealAngleBetweenLigands(const Atom *center,
                                                         const Atom *lig1,
                                                         const Atom *lig2);

RDKIT_GRAPHMOL_EXPORT unsigned int getMaxNbors(const Atom::ChiralType tag);

//
// Get the chiral permutation from the storage order of bonds on an atom
// to the desired output order (probe). Missing/implicit neihgbors can be
// represented with (-1). To get the inverse order, i.e. from the probe to the
// current storage order set (inverse=true)
//
RDKIT_GRAPHMOL_EXPORT unsigned int getChiralPermutation(const Atom *center,
                                                        const INT_LIST &probe,
                                                        bool inverse = false);
//! @}

RDKIT_GRAPHMOL_EXPORT std::ostream &operator<<(std::ostream &oss,
                                               const StereoSpecified &s);
RDKIT_GRAPHMOL_EXPORT std::ostream &operator<<(std::ostream &oss,
                                               const StereoType &s);

struct RDKIT_GRAPHMOL_EXPORT BondWedgingParameters {
  bool wedgeTwoBondsIfPossible =
      false;  //!< If this is enabled then two bonds will be wedged at chiral
              //!< centers subject to the following constraints:
              //!<   1. ring bonds will not be wedged
              //!<   2. bonds to chiral centers will not be wedged
              //!<   3. bonds separated by more than 120 degrees will not be
              //!<      wedged
};

enum class WedgeInfoType {
  WedgeInfoTypeChiral,
  WedgeInfoTypeAtropisomer,
};

class WedgeInfoBase {
 public:
  WedgeInfoBase(int idxInit) : idx(idxInit) {};
  virtual ~WedgeInfoBase() {};

  virtual WedgeInfoType getType() const = 0;
  virtual Bond::BondDir getDir() const = 0;

  int getIdx() const { return idx; }

 private:
  int idx = -1;
};

class WedgeInfoChiral : public WedgeInfoBase {
 public:
  WedgeInfoChiral(int atomId) : WedgeInfoBase(atomId) {};
  ~WedgeInfoChiral() {};

  WedgeInfoType getType() const override {
    return Chirality::WedgeInfoType::WedgeInfoTypeChiral;
  }
  Bond::BondDir getDir() const override {
    throw std::runtime_error(
        "BondDir is not stored/used in Chiral type WedgInfos");
  }
};

class WedgeInfoAtropisomer : public WedgeInfoBase {
 public:
  WedgeInfoAtropisomer(int bondId, RDKit::Bond::BondDir dirInit)
      : WedgeInfoBase(bondId) {
    dir = dirInit;
  };
  ~WedgeInfoAtropisomer() {};

  RDKit::Bond::BondDir dir = RDKit::Bond::BondDir::NONE;

  WedgeInfoType getType() const override {
    return Chirality::WedgeInfoType::WedgeInfoTypeAtropisomer;
  }

  Bond::BondDir getDir() const override { return dir; }
};

namespace detail {
RDKIT_GRAPHMOL_EXPORT Bond::BondDir determineBondWedgeState(
    const Bond *bond, unsigned int fromAtomIdx, const Conformer *conf);
RDKIT_GRAPHMOL_EXPORT Bond::BondDir determineBondWedgeState(
    const Bond *bond,
    const std::map<int, std::unique_ptr<RDKit::Chirality::WedgeInfoBase>>
        &wedgeBonds,
    const Conformer *conf);

RDKIT_GRAPHMOL_EXPORT std::pair<bool, INT_VECT> countChiralNbrs(
    const ROMol &mol, int noNbrs);
RDKIT_GRAPHMOL_EXPORT int pickBondToWedge(
    const Atom *atom, const ROMol &mol, const INT_VECT &nChiralNbrs,
    const std::map<int, std::unique_ptr<RDKit::Chirality::WedgeInfoBase>>
        &resSoFar,
    int noNbrs);

//! If useCXSmilesOrdering is true, the stereo will be assigned relative to the
/// lowest-numbered neighbor of each double bond atom.
/// Otherwise it uses the lowest-numbered neighbor on the lower-numbered atom of
/// the double bond and the highest-numbered neighbor on the higher-numbered
/// atom
RDKIT_GRAPHMOL_EXPORT void setStereoForBond(ROMol &mol, Bond *bond,
                                            Bond::BondStereo stereo,
                                            bool useCXSmilesOrdering = false);
}  // namespace detail

//! picks the bonds which should be wedged
/// returns a map from bond idx -> controlling atom idx
RDKIT_GRAPHMOL_EXPORT
std::map<int, std::unique_ptr<Chirality::WedgeInfoBase>> pickBondsToWedge(
    const ROMol &mol, const BondWedgingParameters *params = nullptr);

RDKIT_GRAPHMOL_EXPORT
std::map<int, std::unique_ptr<Chirality::WedgeInfoBase>> pickBondsToWedge(
    const ROMol &mol, const BondWedgingParameters *params,
    const Conformer *conf);

RDKIT_GRAPHMOL_EXPORT void wedgeMolBonds(
    ROMol &mol, const Conformer *conf = nullptr,
    const BondWedgingParameters *params = nullptr);
RDKIT_GRAPHMOL_EXPORT void wedgeBond(Bond *bond, unsigned int fromAtomIdx,
                                     const Conformer *conf);

//! Returns true for double bonds which should be shown as a crossed bonds.
// It always returns false if any adjacent bond is a squiggle bond.
RDKIT_GRAPHMOL_EXPORT bool shouldBeACrossedBond(const Bond *bond);

//! Clears existing bond wedging and forces use of atom wedging from MolBlock.
/*!
 \param mol: molecule to have its wedges altered
 \param allBondTypes: reapply the wedging also on bonds other than single and
 aromatic ones
 */
RDKIT_GRAPHMOL_EXPORT void reapplyMolBlockWedging(ROMol &mol,
                                                  bool allBondTypes = true);
//! Remove MolBlock bond wedging information from molecule.
/*!
 \param mol: molecule to modify
 */
RDKIT_GRAPHMOL_EXPORT void clearMolBlockWedgingInfo(ROMol &mol);
//! Invert bond wedging information read from a mol block (if present).
/*!
 \param mol: molecule to modify
 */
RDKIT_GRAPHMOL_EXPORT void invertMolBlockWedgingInfo(ROMol &mol);

//! gets stereo info for a bond
/*!
 \param bond: bond to check
 \param wedgeBonds - the list of bonds to have wedges
 \param conf -  Conformer to use
 \param dirCode - receives the dircode for the bond
 \param reverse - receives the reverse flag
 only returned if it was exlicility set witha wiggle bond
 */

RDKIT_GRAPHMOL_EXPORT void GetMolFileBondStereoInfo(
    const Bond *bond,
    const std::map<int, std::unique_ptr<RDKit::Chirality::WedgeInfoBase>>
        &wedgeBonds,
    const Conformer *conf, int &dirCode, bool &reverse);

RDKIT_GRAPHMOL_EXPORT void GetMolFileBondStereoInfo(
    const Bond *bond,
    const std::map<int, std::unique_ptr<RDKit::Chirality::WedgeInfoBase>>
        &wedgeBonds,
    const Conformer *conf, Bond::BondDir &dir, bool &reverse);

//! add R/S, relative stereo, and E/Z annotations to atoms and bonds
/*!
 \param mol: molecule to modify
 \param absLabel: label for atoms in an ABS stereo group
 \param orLabel: label for atoms in an OR stereo group
 \param andLabel: label for atoms in an AND stereo group
 \param cipLabel: label for chiral atoms that aren't in a stereo group.
 \param bondLabel: label for CIP stereochemistry on bonds

 If any label is empty, the corresponding annotations will not be added.

 The labels can contain the following placeholders:
   {id} - the stereo group's index
   {cip} - the atom or bond's CIP stereochemistry

 Note that CIP labels will only be added if CIP stereochemistry has been
 assigned to the molecule.

 */
RDKIT_GRAPHMOL_EXPORT void addStereoAnnotations(
    ROMol &mol, std::string absLabel = "abs ({cip})",
    std::string orLabel = "or{id}", std::string andLabel = "and{id}",
    std::string cipLabel = "({cip})", std::string bondLabel = "({cip})");

//! simplifies the stereochemical representation of a molecule where all
//! specified stereocenters are in the same StereoGroup
/*!
 \param mol: molecule to modify
 \param removeAffectedStereoGroups: if set then the affected StereoGroups will
 be removed

If all specified stereocenters are in the same AND or OR stereogroup, a
moleculeNote property will be set on the molecule with the value "AND
enantiomer" or "OR enantiomer". CIP labels, if present, are removed.

*/
RDKIT_GRAPHMOL_EXPORT void simplifyEnhancedStereo(
    ROMol &mol, bool removeAffectedStereoGroups = true);

//! returns the meso centers in a molecule (if any)
/*!
 \param mol: molecule to work with

*/
RDKIT_GRAPHMOL_EXPORT std::vector<std::pair<unsigned int, unsigned int>>
findMesoCenters(const ROMol &mol, bool includeIsotopes = true,
                bool includeAtomMaps = false);

}  // namespace Chirality
}  // namespace RDKit
#endif