1 //
2 //   Copyright (C) 2003-2006 Rational Discovery LLC
3 //
4 //   @@ All Rights Reserved @@
5 //  This file is part of the RDKit.
6 //  The contents are covered by the terms of the BSD license
7 //  which is included in the file license.txt, found at the root
8 //  of the RDKit source tree.
9 //
10 #include <RDGeneral/export.h>
11 #ifndef _RD_MOLTRANSFORMS_H_
12 #define _RD_MOLTRANSFORMS_H_
13 
14 #include <Geometry/point.h>
15 #include <Numerics/SymmMatrix.h>
16 
17 #ifdef RDK_HAS_EIGEN3
18 #include <Eigen/Dense>
19 #endif
20 
21 namespace RDKit {
22 class ROMol;
23 class Atom;
24 class Conformer;
25 }  // namespace RDKit
26 
27 namespace RDGeom {
28 class Transform3D;
29 }
30 
31 namespace MolTransforms {
32 RDKIT_MOLTRANSFORMS_EXPORT void transformMolsAtoms(RDKit::ROMol *mol,
33                                                    RDGeom::Transform3D &tform);
34 RDKIT_MOLTRANSFORMS_EXPORT void transformAtom(RDKit::Atom *atom,
35                                               RDGeom::Transform3D &tform);
36 
37 //! Compute the centroid of a conformer
38 /*!
39   This is simple the average of the heavy atom locations in the conformer,
40   not attention is paid to hydrogens or the differences in atomic radii
41 
42   \param conf     Conformer of interest
43   \param ignoreHs If true, ignore hydrogen atoms
44 */
45 RDKIT_MOLTRANSFORMS_EXPORT RDGeom::Point3D computeCentroid(
46     const RDKit::Conformer &conf, bool ignoreHs = true);
47 
48 #ifdef RDK_HAS_EIGEN3
49 //! Compute principal axes and moments of inertia for a conformer
50 /*!
51   These values are calculated from the inertia tensor:
52     Iij = - sum_{s=1..N}(w_s * r_{si} * r_{sj}) i != j
53     Iii = sum_{s=1..N} sum_{j!=i} (w_s * r_{sj} * r_{sj})
54   where the coordinates are relative to the center of mass.
55 
56 
57   \param conf       Conformer of interest
58   \param axes       used to return the principal axes
59   \param  moments    used to return the principal moments
60   \param ignoreHs   If true, ignore hydrogen atoms
61   \param force      If true, the calculation will be carried out even if a
62   cached value is present
63   \param weights    If present used to weight the atomic coordinates
64 
65   \returns whether or not the calculation was successful
66 */
67 RDKIT_MOLTRANSFORMS_EXPORT bool computePrincipalAxesAndMoments(
68     const RDKit::Conformer &conf, Eigen::Matrix3d &axes,
69     Eigen::Vector3d &moments, bool ignoreHs = false, bool force = false,
70     const std::vector<double> *weights = nullptr);
71 //! Compute principal axes and moments from the gyration matrix of a conformer
72 /*!
73 
74   These values are calculated from the gyration matrix/tensor:
75     Iij = sum_{s=1..N}(w_s * r_{si} * r_{sj}) i != j
76     Iii = sum_{s=1..N} sum_{t!=s}(w_s * r_{si} * r_{ti})
77   where the coordinates are relative to the center of mass.
78 
79   \param conf       Conformer of interest
80   \param axes       used to return the principal axes
81   \param  moments    used to return the principal moments
82   \param ignoreHs   If true, ignore hydrogen atoms
83   \param force      If true, the calculation will be carried out even if a
84   cached value is present
85   \param weights    If present used to weight the atomic coordinates
86 
87   \returns whether or not the calculation was successful
88 */
89 RDKIT_MOLTRANSFORMS_EXPORT bool
90 computePrincipalAxesAndMomentsFromGyrationMatrix(
91     const RDKit::Conformer &conf, Eigen::Matrix3d &axes,
92     Eigen::Vector3d &moments, bool ignoreHs = false, bool force = false,
93     const std::vector<double> *weights = nullptr);
94 #endif
95 
96 //! Compute the transformation require to orient the conformation
97 //! along the principal axes about the center; i.e. center is made to coincide
98 // with the
99 //! origin, the largest principal axis with the x-axis, the next largest with
100 // the y-axis
101 //! and the smallest with the z-axis
102 /*!
103   If center is not specified the centroid of the conformer will be used
104   \param conf                Conformer of interest
105   \param center              Center to be used for canonicalization, defaults to
106   the centroid of the
107                              conformation
108   \param normalizeCovar      Normalize the covariance matrix with the number of
109   atoms
110   \param ignoreHs            Optionally ignore hydrogens
111 */
112 RDKIT_MOLTRANSFORMS_EXPORT RDGeom::Transform3D *computeCanonicalTransform(
113     const RDKit::Conformer &conf, const RDGeom::Point3D *center = nullptr,
114     bool normalizeCovar = false, bool ignoreHs = true);
115 
116 //! Transform the conformation using the specified transformation
117 RDKIT_MOLTRANSFORMS_EXPORT void transformConformer(
118     RDKit::Conformer &conf, const RDGeom::Transform3D &trans);
119 
120 //! Transforms coordinates in a molecule's substance groups
121 RDKIT_MOLTRANSFORMS_EXPORT void transformMolSubstanceGroups(
122     RDKit::ROMol &mol, const RDGeom::Transform3D &trans);
123 
124 //! Canonicalize the orientation of a conformer so that its principal axes
125 //! around the specified center point coincide with the x, y, z axes
126 /*!
127   \param conf           The conformer of interest
128   \param center         Optional center point about which the principal axes are
129   computed
130                         if not specified the centroid of the conformer will be
131   used
132   \param normalizeCovar Optionally normalize the covariance matrix by the number
133   of atoms
134   \param ignoreHs       If true, ignore hydrogen atoms
135 
136 */
137 RDKIT_MOLTRANSFORMS_EXPORT void canonicalizeConformer(
138     RDKit::Conformer &conf, const RDGeom::Point3D *center = nullptr,
139     bool normalizeCovar = false, bool ignoreHs = true);
140 
141 //! Canonicalize all the conformations in a molecule
142 /*!
143   \param mol            the molecule of interest
144   \param normalizeCovar Optionally normalize the covariance matrix by the number
145   of atoms
146   \param ignoreHs       If true, ignore hydrogens
147 */
148 RDKIT_MOLTRANSFORMS_EXPORT void canonicalizeMol(RDKit::ROMol &mol,
149                                                 bool normalizeCovar = false,
150                                                 bool ignoreHs = true);
151 
152 //! Get the bond length between the specified atoms i, j
153 RDKIT_MOLTRANSFORMS_EXPORT double getBondLength(const RDKit::Conformer &conf,
154                                                 unsigned int iAtomId,
155                                                 unsigned int jAtomId);
156 
157 //! Set the bond length between the specified atoms i, j
158 //! (all atoms bonded to atom j are moved)
159 RDKIT_MOLTRANSFORMS_EXPORT void setBondLength(RDKit::Conformer &conf,
160                                               unsigned int iAtomId,
161                                               unsigned int jAtomId,
162                                               double value);
163 
164 //! Get the angle in radians among the specified atoms i, j, k
165 RDKIT_MOLTRANSFORMS_EXPORT double getAngleRad(const RDKit::Conformer &conf,
166                                               unsigned int iAtomId,
167                                               unsigned int jAtomId,
168                                               unsigned int kAtomId);
169 
170 //! Get the angle in degrees among the specified atoms i, j, k
getAngleDeg(const RDKit::Conformer & conf,unsigned int iAtomId,unsigned int jAtomId,unsigned int kAtomId)171 inline double getAngleDeg(const RDKit::Conformer &conf, unsigned int iAtomId,
172                           unsigned int jAtomId, unsigned int kAtomId) {
173   return (180. / M_PI * getAngleRad(conf, iAtomId, jAtomId, kAtomId));
174 }
175 
176 //! Set the angle in radians among the specified atoms i, j, k
177 //! (all atoms bonded to atom k are moved)
178 RDKIT_MOLTRANSFORMS_EXPORT void setAngleRad(RDKit::Conformer &conf,
179                                             unsigned int iAtomId,
180                                             unsigned int jAtomId,
181                                             unsigned int kAtomId, double value);
182 
183 //! Set the angle in degrees among the specified atoms i, j, k
184 //! (all atoms bonded to atom k are moved)
setAngleDeg(RDKit::Conformer & conf,unsigned int iAtomId,unsigned int jAtomId,unsigned int kAtomId,double value)185 inline void setAngleDeg(RDKit::Conformer &conf, unsigned int iAtomId,
186                         unsigned int jAtomId, unsigned int kAtomId,
187                         double value) {
188   setAngleRad(conf, iAtomId, jAtomId, kAtomId, value / 180. * M_PI);
189 }
190 
191 //! Get the dihedral angle in radians among the specified atoms i, j, k, l
192 RDKIT_MOLTRANSFORMS_EXPORT double getDihedralRad(const RDKit::Conformer &conf,
193                                                  unsigned int iAtomId,
194                                                  unsigned int jAtomId,
195                                                  unsigned int kAtomId,
196                                                  unsigned int lAtomId);
197 
198 //! Get the dihedral angle in degrees among the specified atoms i, j, k, l
getDihedralDeg(const RDKit::Conformer & conf,unsigned int iAtomId,unsigned int jAtomId,unsigned int kAtomId,unsigned int lAtomId)199 inline double getDihedralDeg(const RDKit::Conformer &conf, unsigned int iAtomId,
200                              unsigned int jAtomId, unsigned int kAtomId,
201                              unsigned int lAtomId) {
202   return (180. / M_PI *
203           getDihedralRad(conf, iAtomId, jAtomId, kAtomId, lAtomId));
204 }
205 
206 //! Set the dihedral angle in radians among the specified atoms i, j, k, l
207 //! (all atoms bonded to atom l are moved)
208 RDKIT_MOLTRANSFORMS_EXPORT void setDihedralRad(
209     RDKit::Conformer &conf, unsigned int iAtomId, unsigned int jAtomId,
210     unsigned int kAtomId, unsigned int lAtomId, double value);
211 
212 //! Set the dihedral angle in degrees among the specified atoms i, j, k, l
213 //! (all atoms bonded to atom l are moved)
setDihedralDeg(RDKit::Conformer & conf,unsigned int iAtomId,unsigned int jAtomId,unsigned int kAtomId,unsigned int lAtomId,double value)214 inline void setDihedralDeg(RDKit::Conformer &conf, unsigned int iAtomId,
215                            unsigned int jAtomId, unsigned int kAtomId,
216                            unsigned int lAtomId, double value) {
217   setDihedralRad(conf, iAtomId, jAtomId, kAtomId, lAtomId, value / 180. * M_PI);
218 }
219 }  // namespace MolTransforms
220 #endif
221