RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
FFConvenience.h
Go to the documentation of this file.
1//
2// Copyright (C) 2019 Paolo Tosco
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_FFCONVENIENCE_H
12#define RD_FFCONVENIENCE_H
13#include <GraphMol/ROMol.h>
15#include <RDGeneral/RDThreads.h>
16
17namespace RDKit {
18class ROMol;
20namespace detail {
21#ifdef RDK_BUILD_THREADSAFE_SSS
22inline void OptimizeMoleculeConfsHelper_(
24 std::vector<std::pair<int, double>> *res, unsigned int threadIdx,
25 unsigned int numThreads, int maxIters) {
26 PRECONDITION(mol, "mol must not be nullptr");
27 PRECONDITION(res, "res must not be nullptr");
28 PRECONDITION(res->size() >= mol->getNumConformers(),
29 "res->size() must be >= mol->getNumConformers()");
30 unsigned int i = 0;
31 ff.positions().resize(mol->getNumAtoms());
32 for (ROMol::ConformerIterator cit = mol->beginConformers();
33 cit != mol->endConformers(); ++cit, ++i) {
34 if (i % numThreads != threadIdx) {
35 continue;
36 }
37 for (unsigned int aidx = 0; aidx < mol->getNumAtoms(); ++aidx) {
38 ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
39 }
40 ff.initialize();
41 int needsMore = ff.minimize(maxIters);
42 double e = ff.calcEnergy();
43 (*res)[i] = std::make_pair(needsMore, e);
44 }
45}
46
47inline void OptimizeMoleculeConfsMT(ROMol &mol,
49 std::vector<std::pair<int, double>> &res,
50 int numThreads, int maxIters) {
51 std::vector<std::thread> tg;
52 for (int ti = 0; ti < numThreads; ++ti) {
53 tg.emplace_back(std::thread(detail::OptimizeMoleculeConfsHelper_, ff, &mol,
54 &res, ti, numThreads, maxIters));
55 }
56 for (auto &thread : tg) {
57 if (thread.joinable()) {
58 thread.join();
59 }
60 }
61}
62#endif
63
65 std::vector<std::pair<int, double>> &res,
66 int maxIters) {
67 PRECONDITION(res.size() >= mol.getNumConformers(),
68 "res.size() must be >= mol.getNumConformers()");
69 unsigned int i = 0;
70 for (ROMol::ConformerIterator cit = mol.beginConformers();
71 cit != mol.endConformers(); ++cit, ++i) {
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} // namespace detail
82
83//! Convenience function for optimizing a molecule using a pre-generated
84//! force-field
85/*
86 \param ff the force-field
87 \param res vector of (needsMore,energy) pairs
88 \param maxIters the maximum number of force-field iterations
89
90 \return a pair with:
91 first: -1 if parameters were missing, 0 if the optimization converged, 1 if
92 more iterations are required.
93 second: the energy
94*/
95inline std::pair<int, double> OptimizeMolecule(ForceFields::ForceField &ff,
96 int maxIters = 1000) {
97 ff.initialize();
98 int res = ff.minimize(maxIters);
99 double e = ff.calcEnergy();
100 return std::make_pair(res, e);
101}
102
103//! Convenience function for optimizing all of a molecule's conformations using
104/// a pre-generated force-field
105/*
106 \param mol the molecule to use
107 \param ff the force-field
108 \param res vector of (needsMore,energy) pairs
109 \param numThreads the number of simultaneous threads to use (only has an
110 effect if the RDKit is compiled with thread support).
111 If set to zero, the max supported by the system will be
112 used.
113 \param maxIters the maximum number of force-field iterations
114
115*/
117 std::vector<std::pair<int, double>> &res,
118 int numThreads = 1, int maxIters = 1000) {
119 res.resize(mol.getNumConformers());
120 numThreads = getNumThreadsToUse(numThreads);
121 if (numThreads == 1) {
122 detail::OptimizeMoleculeConfsST(mol, ff, res, maxIters);
123 }
124#ifdef RDK_BUILD_THREADSAFE_SSS
125 else {
126 detail::OptimizeMoleculeConfsMT(mol, ff, res, numThreads, maxIters);
127 }
128#endif
129}
130
131//! Convenience Function for generating an empty force Field with just
132/// the molecules' atoms position.
133/*
134 \param mol The molecule which positions should be added to the force field.
135 \param confId Id of the conformer which positions are used in the force field.
136
137*/
138inline std::unique_ptr<ForceFields::ForceField> createEmptyForceFieldForMol(
139 ROMol &mol, int confId = -1) {
140 auto res = std::make_unique<ForceFields::ForceField>();
141 auto &conf = mol.getConformer(confId);
142 for (auto &pt : conf.getPositions()) {
143 res->positions().push_back(&pt);
144 }
145 return res;
146}
147} // end of namespace ForceFieldsHelper
148} // end of namespace RDKit
149#endif
#define PRECONDITION(expr, mess)
Definition Invariant.h:108
Defines the primary molecule class ROMol as well as associated typedefs.
A class to store forcefields and handle minimization.
Definition ForceField.h:79
double calcEnergy(std::vector< double > *contribs=nullptr) const
RDGeom::PointPtrVect & positions()
returns a reference to our points (a PointPtrVect)
Definition ForceField.h:181
void initialize()
does initialization
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 getNumConformers() const
Definition ROMol.h:765
unsigned int getNumAtoms() const
returns our number of atoms
Definition ROMol.h:618
const Conformer & getConformer(int id=-1) const
ConformerIterator beginConformers()
Definition ROMol.h:940
ConformerIterator endConformers()
Definition ROMol.h:942
void OptimizeMoleculeConfsST(ROMol &mol, ForceFields::ForceField &ff, std::vector< std::pair< int, double > > &res, int maxIters)
void OptimizeMoleculeConfs(ROMol &mol, ForceFields::ForceField &ff, std::vector< std::pair< int, double > > &res, int numThreads=1, int maxIters=1000)
std::unique_ptr< ForceFields::ForceField > createEmptyForceFieldForMol(ROMol &mol, int confId=-1)
std::pair< int, double > OptimizeMolecule(ForceFields::ForceField &ff, int maxIters=1000)
Std stuff.
unsigned int getNumThreadsToUse(int target)
Definition RDThreads.h:37