FFConvenience.h
Go to the documentation of this file.
//
// Copyright (C) 2019 Paolo Tosco
//
// @@ 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.
//
#include <RDGeneral/export.h>
#ifndef RD_FFCONVENIENCE_H
#define RD_FFCONVENIENCE_H
#include <ForceField/ForceField.h>
#include <RDGeneral/RDThreads.h>
namespace RDKit {
class ROMol;
namespace ForceFieldsHelper {
namespace detail {
#ifdef RDK_THREADSAFE_SSS
void OptimizeMoleculeConfsHelper_(ForceFields::ForceField ff, ROMol *mol,
std::vector<std::pair<int, double>> *res,
unsigned int threadIdx,
unsigned int numThreads, int maxIters) {
PRECONDITION(mol, "mol must not be nullptr");
PRECONDITION(res, "res must not be nullptr");
PRECONDITION(res->size() >= mol->getNumConformers(),
"res->size() must be >= mol->getNumConformers()");
unsigned int i = 0;
ff.positions().resize(mol->getNumAtoms());
for (ROMol::ConformerIterator cit = mol->beginConformers();
cit != mol->endConformers(); ++cit, ++i) {
if (i % numThreads != threadIdx) continue;
for (unsigned int aidx = 0; aidx < mol->getNumAtoms(); ++aidx) {
ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
}
ff.initialize();
int needsMore = ff.minimize(maxIters);
double e = ff.calcEnergy();
(*res)[i] = std::make_pair(needsMore, e);
}
}
void OptimizeMoleculeConfsMT(ROMol &mol, const ForceFields::ForceField &ff,
std::vector<std::pair<int, double>> &res,
int numThreads, int maxIters) {
std::vector<std::thread> tg;
for (int ti = 0; ti < numThreads; ++ti) {
tg.emplace_back(std::thread(detail::OptimizeMoleculeConfsHelper_, ff, &mol,
&res, ti, numThreads, maxIters));
}
for (auto &thread : tg) {
if (thread.joinable()) thread.join();
}
}
#endif
void OptimizeMoleculeConfsST(ROMol &mol, ForceFields::ForceField &ff,
std::vector<std::pair<int, double>> &res,
int maxIters) {
PRECONDITION(res.size() >= mol.getNumConformers(),
"res.size() must be >= mol.getNumConformers()");
unsigned int i = 0;
for (ROMol::ConformerIterator cit = mol.beginConformers();
cit != mol.endConformers(); ++cit, ++i) {
for (unsigned int aidx = 0; aidx < mol.getNumAtoms(); ++aidx) {
ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
}
ff.initialize();
int needsMore = ff.minimize(maxIters);
double e = ff.calcEnergy();
res[i] = std::make_pair(needsMore, e);
}
}
} // namespace detail
//! Convenience function for optimizing a molecule using a pre-generated
//! force-field
/*
\param ff the force-field
\param res vector of (needsMore,energy) pairs
\param maxIters the maximum number of force-field iterations
\return a pair with:
first: -1 if parameters were missing, 0 if the optimization converged, 1 if
more iterations are required.
second: the energy
*/
std::pair<int, double> OptimizeMolecule(ForceFields::ForceField &ff,
int maxIters = 1000) {
ff.initialize();
int res = ff.minimize(maxIters);
double e = ff.calcEnergy();
return std::make_pair(res, e);
}
//! Convenience function for optimizing all of a molecule's conformations using
/// a pre-generated force-field
/*
\param mol the molecule to use
\param ff the force-field
\param res vector of (needsMore,energy) pairs
\param numThreads the number of simultaneous threads to use (only has an
effect if the RDKit is compiled with thread support).
If set to zero, the max supported by the system will be
used.
\param maxIters the maximum number of force-field iterations
*/
void OptimizeMoleculeConfs(ROMol &mol, ForceFields::ForceField &ff,
std::vector<std::pair<int, double>> &res,
int numThreads = 1, int maxIters = 1000) {
res.resize(mol.getNumConformers());
numThreads = getNumThreadsToUse(numThreads);
if (numThreads == 1) {
detail::OptimizeMoleculeConfsST(mol, ff, res, maxIters);
}
#ifdef RDK_THREADSAFE_SSS
else {
detail::OptimizeMoleculeConfsMT(mol, ff, res, numThreads, maxIters);
}
#endif
}
} // end of namespace ForceFieldsHelper
} // end of namespace RDKit
#endif
ForceField.h
PRECONDITION
#define PRECONDITION(expr, mess)
Definition: Invariant.h:109
RDThreads.h
ForceFields::ForceField
A class to store forcefields and handle minimization.
Definition: ForceField.h:79
ForceFields::ForceField::calcEnergy
double calcEnergy(std::vector< double > *contribs=nullptr) const
ForceFields::ForceField::initialize
void initialize()
does initialization
ForceFields::ForceField::positions
RDGeom::PointPtrVect & positions()
returns a reference to our points (a PointPtrVect)
Definition: ForceField.h:181
ForceFields::ForceField::minimize
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
RDKit::ROMol
Definition: ROMol.h:178
RDKit::ROMol::getNumConformers
unsigned int getNumConformers() const
Definition: ROMol.h:479
RDKit::ROMol::getNumAtoms
unsigned int getNumAtoms() const
returns our number of atoms
Definition: ROMol.h:332
RDKit::ROMol::beginConformers
ConformerIterator beginConformers()
Definition: ROMol.h:651
RDKit::ROMol::endConformers
ConformerIterator endConformers()
Definition: ROMol.h:653
export.h
RDKit::ForceFieldsHelper::detail::OptimizeMoleculeConfsST
void OptimizeMoleculeConfsST(ROMol &mol, ForceFields::ForceField &ff, std::vector< std::pair< int, double >> &res, int maxIters)
Definition: FFConvenience.h:58
RDKit::ForceFieldsHelper::OptimizeMolecule
std::pair< int, double > OptimizeMolecule(ForceFields::ForceField &ff, int maxIters=1000)
Definition: FFConvenience.h:89
RDKit::ForceFieldsHelper::OptimizeMoleculeConfs
void OptimizeMoleculeConfs(ROMol &mol, ForceFields::ForceField &ff, std::vector< std::pair< int, double >> &res, int numThreads=1, int maxIters=1000)
Definition: FFConvenience.h:110
RDKit
Std stuff.
Definition: Abbreviations.h:18
RDKit::getNumThreadsToUse
unsigned int getNumThreadsToUse(int target)
Definition: RDThreads.h:37