1 // $Id$
2 //
3 //  Copyright (C) 2005-2006 Rational Discovery LLC
4 //
5 //   @@ All Rights Reserved @@
6 //  This file is part of the RDKit.
7 //  The contents are covered by the terms of the BSD license
8 //  which is included in the file license.txt, found at the root
9 //  of the RDKit source tree.
10 //
11 #include <RDGeneral/export.h>
12 #include <ForceField/ForceField.h>
13 #include <GraphMol/ForceFieldHelpers/MMFF/AtomTyper.h>
14 #include <ForceField/MMFF/Params.h>
15 #include <GraphMol/Trajectory/Snapshot.h>
16 #include <boost/python/tuple.hpp>
17 #include <boost/shared_ptr.hpp>
18 #include <vector>
19 #include <algorithm>
20 #include <Geometry/point.h>
21 
22 namespace python = boost::python;
23 namespace ForceFields {
24 class PyForceField {
25  public:
PyForceField(ForceField * f)26   PyForceField(ForceField *f) : field(f){};
27 
~PyForceField()28   ~PyForceField() {
29     // std::cerr << " *** destroy PyForce field " << std::endl;
30     field.reset();
31     // std::cerr << " ***       reset DONE" << std::endl;
32     extraPoints.clear();
33     // std::cerr << " *** destroy PyForce field DONE" << std::endl;
34   }
35 
36   int addExtraPoint(double x, double y, double z, bool fixed = true) {
37     PRECONDITION(this->field, "no force field");
38     RDGeom::Point3D *pt = new RDGeom::Point3D(x, y, z);
39     this->extraPoints.push_back(boost::shared_ptr<RDGeom::Point3D>(pt));
40     unsigned int ptIdx = this->extraPoints.size() - 1;
41     RDGeom::Point3D *ptr = this->extraPoints[ptIdx].get();
42     this->field->positions().push_back(ptr);
43     int idx = this->field->positions().size();
44     if (fixed) {
45       this->field->fixedPoints().push_back(idx - 1);
46     }
47     return idx;
48   }
49 
50   double calcEnergyWithPos(const python::object &pos = python::object());
51 
calcEnergy()52   double calcEnergy() { return calcEnergyWithPos(); }
53 
54   PyObject *calcGradWithPos(const python::object &pos = python::object());
55 
56   PyObject *positions();
57 
minimize(int maxIts,double forceTol,double energyTol)58   int minimize(int maxIts, double forceTol, double energyTol) {
59     PRECONDITION(this->field, "no force field");
60     return this->field->minimize(maxIts, forceTol, energyTol);
61   }
62 
63   boost::python::tuple minimizeTrajectory(unsigned int snapshotFreq, int maxIts,
64                                           double forceTol, double energyTol);
65 
initialize()66   void initialize() {
67     PRECONDITION(this->field, "no force field");
68     this->field->initialize();
69   }
70 
dimension()71   unsigned int dimension() {
72     PRECONDITION(this->field, "no force field");
73     return this->field->dimension();
74   }
75 
numPoints()76   unsigned int numPoints() {
77     PRECONDITION(this->field, "no force field");
78     return this->field->numPoints();
79   }
80 
81   // private:
82   std::vector<boost::shared_ptr<RDGeom::Point3D>> extraPoints;
83   boost::shared_ptr<ForceField> field;
84 };
85 
86 class PyMMFFMolProperties {
87  public:
PyMMFFMolProperties(RDKit::MMFF::MMFFMolProperties * mp)88   PyMMFFMolProperties(RDKit::MMFF::MMFFMolProperties *mp)
89       : mmffMolProperties(mp){};
~PyMMFFMolProperties()90   ~PyMMFFMolProperties(){};
91 
getMMFFAtomType(unsigned int idx)92   unsigned int getMMFFAtomType(unsigned int idx) {
93     return (unsigned int)(mmffMolProperties->getMMFFAtomType(idx));
94   };
getMMFFFormalCharge(unsigned int idx)95   double getMMFFFormalCharge(unsigned int idx) {
96     return mmffMolProperties->getMMFFFormalCharge(idx);
97   };
getMMFFPartialCharge(unsigned int idx)98   double getMMFFPartialCharge(unsigned int idx) {
99     return mmffMolProperties->getMMFFPartialCharge(idx);
100   };
101   PyObject *getMMFFBondStretchParams(const RDKit::ROMol &mol,
102                                      const unsigned int idx1,
103                                      const unsigned int idx2);
104   PyObject *getMMFFAngleBendParams(const RDKit::ROMol &mol,
105                                    const unsigned int idx1,
106                                    const unsigned int idx2,
107                                    const unsigned int idx3);
108   PyObject *getMMFFStretchBendParams(const RDKit::ROMol &mol,
109                                      const unsigned int idx1,
110                                      const unsigned int idx2,
111                                      const unsigned int idx3);
112   PyObject *getMMFFTorsionParams(const RDKit::ROMol &mol,
113                                  const unsigned int idx1,
114                                  const unsigned int idx2,
115                                  const unsigned int idx3,
116                                  const unsigned int idx4);
117   PyObject *getMMFFOopBendParams(const RDKit::ROMol &mol,
118                                  const unsigned int idx1,
119                                  const unsigned int idx2,
120                                  const unsigned int idx3,
121                                  const unsigned int idx4);
122   PyObject *getMMFFVdWParams(const unsigned int idx1, const unsigned int idx2);
setMMFFDielectricModel(std::uint8_t dielModel)123   void setMMFFDielectricModel(std::uint8_t dielModel) {
124     mmffMolProperties->setMMFFDielectricModel(dielModel);
125   };
setMMFFDielectricConstant(double dielConst)126   void setMMFFDielectricConstant(double dielConst) {
127     mmffMolProperties->setMMFFDielectricConstant(dielConst);
128   };
setMMFFBondTerm(bool state)129   void setMMFFBondTerm(bool state) {
130     mmffMolProperties->setMMFFBondTerm(state);
131   };
setMMFFAngleTerm(const bool state)132   void setMMFFAngleTerm(const bool state) {
133     mmffMolProperties->setMMFFAngleTerm(state);
134   };
setMMFFStretchBendTerm(const bool state)135   void setMMFFStretchBendTerm(const bool state) {
136     mmffMolProperties->setMMFFStretchBendTerm(state);
137   };
setMMFFOopTerm(const bool state)138   void setMMFFOopTerm(const bool state) {
139     mmffMolProperties->setMMFFOopTerm(state);
140   };
setMMFFTorsionTerm(const bool state)141   void setMMFFTorsionTerm(const bool state) {
142     mmffMolProperties->setMMFFTorsionTerm(state);
143   };
setMMFFVdWTerm(const bool state)144   void setMMFFVdWTerm(const bool state) {
145     mmffMolProperties->setMMFFVdWTerm(state);
146   };
setMMFFEleTerm(const bool state)147   void setMMFFEleTerm(const bool state) {
148     mmffMolProperties->setMMFFEleTerm(state);
149   };
setMMFFVariant(const std::string & mmffVariant)150   void setMMFFVariant(const std::string &mmffVariant) {
151     mmffMolProperties->setMMFFVariant(mmffVariant);
152   };
setMMFFVerbosity(unsigned int verbosity)153   void setMMFFVerbosity(unsigned int verbosity) {
154     mmffMolProperties->setMMFFVerbosity(verbosity);
155   };
156   boost::shared_ptr<RDKit::MMFF::MMFFMolProperties> mmffMolProperties;
157 };
158 PyObject *getUFFBondStretchParams(const RDKit::ROMol &mol,
159                                   const unsigned int idx1,
160                                   const unsigned int idx2);
161 PyObject *getUFFAngleBendParams(const RDKit::ROMol &mol,
162                                 const unsigned int idx1,
163                                 const unsigned int idx2,
164                                 const unsigned int idx3);
165 PyObject *getUFFTorsionParams(const RDKit::ROMol &mol, const unsigned int idx1,
166                               const unsigned int idx2, const unsigned int idx3,
167                               const unsigned int idx4);
168 PyObject *getUFFInversionParams(const RDKit::ROMol &mol,
169                                 const unsigned int idx1,
170                                 const unsigned int idx2,
171                                 const unsigned int idx3,
172                                 const unsigned int idx4);
173 PyObject *getUFFVdWParams(const RDKit::ROMol &mol, const unsigned int idx1,
174                           const unsigned int idx2);
175 }  // namespace ForceFields
176