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