RDKit
Open-source cheminformatics and machine learning.
MMFF.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2015-2018 Greg Landrum
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_MMFFCONVENIENCE_H
12 #define RD_MMFFCONVENIENCE_H
13 #include <ForceField/ForceField.h>
14 #include <RDGeneral/RDThreads.h>
15 #include "AtomTyper.h"
16 #include "Builder.h"
17 
18 namespace RDKit {
19 class ROMol;
20 namespace MMFF {
21 //! Convenience function for optimizing a molecule using MMFF
22 /*
23  \param mol the molecule to use
24  \param maxIters the maximum number of force-field iterations
25  \param mmffVariant the MMFF variant to use, should be "MMFF94" or "MMFF94S"
26  \param nonBondedThresh the threshold to be used in adding non-bonded terms
27  to the force field. Any non-bonded contact whose
28  current
29  distance is greater than \c nonBondedThresh * the minimum
30  value
31  for that contact will not be included.
32  \param confId the optional conformer id, if this isn't provided, the
33  molecule's
34  default confId will be used.
35  \param ignoreInterfragInteractions if true, nonbonded terms will not be added
36  between
37  fragments
38 
39  \return a pair with:
40  first: -1 if parameters were missing, 0 if the optimization converged, 1 if
41  more iterations are required.
42  second: the energy
43 */
44 std::pair<int, double> MMFFOptimizeMolecule(
45  ROMol &mol, int maxIters = 1000, std::string mmffVariant = "MMFF94",
46  double nonBondedThresh = 10.0, int confId = -1,
47  bool ignoreInterfragInteractions = true) {
48  int res = -1;
49  double e = -1;
50  MMFF::MMFFMolProperties mmffMolProperties(mol, mmffVariant);
51  if (mmffMolProperties.isValid()) {
53  mol, nonBondedThresh, confId, ignoreInterfragInteractions);
54  ff->initialize();
55  res = ff->minimize(maxIters);
56  e = ff->calcEnergy();
57  delete ff;
58  }
59  return std::make_pair(res, e);
60 }
61 #ifdef RDK_THREADSAFE_SSS
62 namespace detail {
63 void MMFFOptimizeMoleculeConfsHelper_(ForceFields::ForceField ff, ROMol *mol,
64  std::vector<std::pair<int, double>> *res,
65  unsigned int threadIdx,
66  unsigned int numThreads, int maxIters) {
67  unsigned int i = 0;
68  ff.positions().resize(mol->getNumAtoms());
69  for (ROMol::ConformerIterator cit = mol->beginConformers();
70  cit != mol->endConformers(); ++cit, ++i) {
71  if (i % numThreads != threadIdx) continue;
72  for (unsigned int aidx = 0; aidx < mol->getNumAtoms(); ++aidx) {
73  ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
74  }
75  ff.initialize();
76  int needsMore = ff.minimize(maxIters);
77  double e = ff.calcEnergy();
78  (*res)[i] = std::make_pair(needsMore, e);
79  }
80 }
81 } // end of detail namespace
82 #endif
83 //! Convenience function for optimizing all of a molecule's conformations using
84 // MMFF
85 /*
86  \param mol the molecule to use
87  \param res vector of (needsMore,energy) pairs
88  \param numThreads the number of simultaneous threads to use (only has an
89  effect if the RDKit is compiled with thread support).
90  If set to zero, the max supported by the system will be
91  used.
92  \param maxIters the maximum number of force-field iterations
93  \param mmffVariant the MMFF variant to use, should be "MMFF94" or "MMFF94S"
94  \param nonBondedThresh the threshold to be used in adding non-bonded terms
95  to the force field. Any non-bonded contact whose
96  current
97  distance is greater than \c nonBondedThresh * the minimum
98  value
99  for that contact will not be included.
100  \param ignoreInterfragInteractions if true, nonbonded terms will not be added
101  between
102  fragments
103 
104 */
106  std::vector<std::pair<int, double>> &res,
107  int numThreads = 1, int maxIters = 1000,
108  std::string mmffVariant = "MMFF94",
109  double nonBondedThresh = 10.0,
110  bool ignoreInterfragInteractions = true) {
111  res.resize(mol.getNumConformers());
112  numThreads = getNumThreadsToUse(numThreads);
113  MMFF::MMFFMolProperties mmffMolProperties(mol, mmffVariant);
114  if (mmffMolProperties.isValid()) {
116  mol, nonBondedThresh, -1, ignoreInterfragInteractions);
117  if (numThreads == 1) {
118  unsigned int i = 0;
119  for (ROMol::ConformerIterator cit = mol.beginConformers();
120  cit != mol.endConformers(); ++cit, ++i) {
121  for (unsigned int aidx = 0; aidx < mol.getNumAtoms(); ++aidx) {
122  ff->positions()[aidx] = &(*cit)->getAtomPos(aidx);
123  }
124  ff->initialize();
125  int needsMore = ff->minimize(maxIters);
126  double e = ff->calcEnergy();
127  res[i] = std::make_pair(needsMore, e);
128  }
129  }
130 #ifdef RDK_THREADSAFE_SSS
131  else {
132  std::vector<std::thread> tg;
133  for (int ti = 0; ti < numThreads; ++ti) {
134  tg.emplace_back(std::thread(detail::MMFFOptimizeMoleculeConfsHelper_,
135  *ff, &mol, &res, ti, numThreads, maxIters));
136  }
137  for (auto &thread : tg) {
138  if (thread.joinable()) thread.join();
139  }
140  }
141 #endif
142  delete ff;
143  } else {
144  for (unsigned int i = 0; i < mol.getNumConformers(); ++i) {
145  res[i] = std::make_pair(static_cast<int>(-1), static_cast<double>(-1));
146  }
147  }
148 }
149 } // end of namespace UFF
150 } // end of namespace RDKit
151 #endif
int minimize(unsigned int snapshotFreq, RDKit::SnapshotVect *snapshotVect, unsigned int maxIts=200, double forceTol=1e-4, double energyTol=1e-6)
minimizes the energy of the system by following gradients
unsigned int getNumAtoms(bool onlyExplicit=1) const
returns our number of atoms
RDGeom::PointPtrVect & positions()
returns a reference to our points (a PointPtrVect)
Definition: ForceField.h:161
double calcEnergy(std::vector< double > *contribs=NULL) const
calculates and returns the energy (in kcal/mol) based on existing
unsigned int getNumConformers() const
Definition: ROMol.h:435
std::pair< int, double > MMFFOptimizeMolecule(ROMol &mol, int maxIters=1000, std::string mmffVariant="MMFF94", double nonBondedThresh=10.0, int confId=-1, bool ignoreInterfragInteractions=true)
Convenience function for optimizing a molecule using MMFF.
Definition: MMFF.h:44
void initialize()
does initialization
RDKIT_FORCEFIELDHELPERS_EXPORT ForceFields::ForceField * constructForceField(ROMol &mol, double nonBondedThresh=100.0, int confId=-1, bool ignoreInterfragInteractions=true)
Builds and returns a MMFF force field for a molecule.
Std stuff.
Definition: Atom.h:30
unsigned int getNumThreadsToUse(int target)
Definition: RDThreads.h:37
void MMFFOptimizeMoleculeConfs(ROMol &mol, std::vector< std::pair< int, double >> &res, int numThreads=1, int maxIters=1000, std::string mmffVariant="MMFF94", double nonBondedThresh=10.0, bool ignoreInterfragInteractions=true)
Convenience function for optimizing all of a molecule&#39;s conformations using.
Definition: MMFF.h:105
ConformerIterator endConformers()
Definition: ROMol.h:611
ConformerIterator beginConformers()
Definition: ROMol.h:609
A class to store forcefields and handle minimization.
Definition: ForceField.h:58