1 // $Id$
2 //
3 // Copyright (C) 2004-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
12 #include <RDBoost/python.h>
13 #include <RDBoost/Wrap.h>
14 #include <RDGeneral/Exceptions.h>
15 #include <GraphMol/GraphMol.h>
16 #include <ForceField/ForceField.h>
17 #include <ForceField/UFF/DistanceConstraint.h>
18 #include <ForceField/UFF/AngleConstraint.h>
19 #include <ForceField/UFF/TorsionConstraint.h>
20 #include <ForceField/UFF/PositionConstraint.h>
21 #include <ForceField/MMFF/DistanceConstraint.h>
22 #include <ForceField/MMFF/AngleConstraint.h>
23 #include <ForceField/MMFF/TorsionConstraint.h>
24 #include <ForceField/MMFF/PositionConstraint.h>
25 #include "PyForceField.h"
26
27 using namespace ForceFields;
28 namespace python = boost::python;
29
ForceFieldAddDistanceConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,double minLen,double maxLen,double forceConstant)30 void ForceFieldAddDistanceConstraint(PyForceField *self, unsigned int idx1,
31 unsigned int idx2, double minLen,
32 double maxLen, double forceConstant) {
33 UFF::DistanceConstraintContrib *constraint;
34 constraint = new UFF::DistanceConstraintContrib(
35 self->field.get(), idx1, idx2, minLen, maxLen, forceConstant);
36 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
37 }
38
ForceFieldAddFixedPoint(PyForceField * self,unsigned int idx)39 void ForceFieldAddFixedPoint(PyForceField *self, unsigned int idx) {
40 self->field->fixedPoints().push_back(idx);
41 }
42
UFFAddDistanceConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,bool relative,double minLen,double maxLen,double forceConstant)43 void UFFAddDistanceConstraint(PyForceField *self, unsigned int idx1,
44 unsigned int idx2, bool relative, double minLen,
45 double maxLen, double forceConstant) {
46 auto *constraint = new UFF::DistanceConstraintContrib(
47 self->field.get(), idx1, idx2, relative, minLen, maxLen, forceConstant);
48 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
49 }
50
UFFAddAngleConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,unsigned int idx3,bool relative,double minAngleDeg,double maxAngleDeg,double forceConstant)51 void UFFAddAngleConstraint(PyForceField *self, unsigned int idx1,
52 unsigned int idx2, unsigned int idx3, bool relative,
53 double minAngleDeg, double maxAngleDeg,
54 double forceConstant) {
55 auto *constraint = new UFF::AngleConstraintContrib(
56 self->field.get(), idx1, idx2, idx3, relative, minAngleDeg, maxAngleDeg,
57 forceConstant);
58 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
59 }
60
UFFAddTorsionConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,unsigned int idx3,unsigned int idx4,bool relative,double minDihedralDeg,double maxDihedralDeg,double forceConstant)61 void UFFAddTorsionConstraint(PyForceField *self, unsigned int idx1,
62 unsigned int idx2, unsigned int idx3,
63 unsigned int idx4, bool relative,
64 double minDihedralDeg, double maxDihedralDeg,
65 double forceConstant) {
66 auto *constraint = new UFF::TorsionConstraintContrib(
67 self->field.get(), idx1, idx2, idx3, idx4, relative, minDihedralDeg,
68 maxDihedralDeg, forceConstant);
69 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
70 }
71
UFFAddPositionConstraint(PyForceField * self,unsigned int idx,double maxDispl,double forceConstant)72 void UFFAddPositionConstraint(PyForceField *self, unsigned int idx,
73 double maxDispl, double forceConstant) {
74 auto *constraint = new UFF::PositionConstraintContrib(
75 self->field.get(), idx, maxDispl, forceConstant);
76 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
77 }
78
MMFFAddDistanceConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,bool relative,double minLen,double maxLen,double forceConstant)79 void MMFFAddDistanceConstraint(PyForceField *self, unsigned int idx1,
80 unsigned int idx2, bool relative, double minLen,
81 double maxLen, double forceConstant) {
82 auto *constraint = new MMFF::DistanceConstraintContrib(
83 self->field.get(), idx1, idx2, relative, minLen, maxLen, forceConstant);
84 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
85 }
86
MMFFAddAngleConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,unsigned int idx3,bool relative,double minAngleDeg,double maxAngleDeg,double forceConstant)87 void MMFFAddAngleConstraint(PyForceField *self, unsigned int idx1,
88 unsigned int idx2, unsigned int idx3, bool relative,
89 double minAngleDeg, double maxAngleDeg,
90 double forceConstant) {
91 auto *constraint = new MMFF::AngleConstraintContrib(
92 self->field.get(), idx1, idx2, idx3, relative, minAngleDeg, maxAngleDeg,
93 forceConstant);
94 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
95 }
96
MMFFAddTorsionConstraint(PyForceField * self,unsigned int idx1,unsigned int idx2,unsigned int idx3,unsigned int idx4,bool relative,double minDihedralDeg,double maxDihedralDeg,double forceConstant)97 void MMFFAddTorsionConstraint(PyForceField *self, unsigned int idx1,
98 unsigned int idx2, unsigned int idx3,
99 unsigned int idx4, bool relative,
100 double minDihedralDeg, double maxDihedralDeg,
101 double forceConstant) {
102 auto *constraint = new MMFF::TorsionConstraintContrib(
103 self->field.get(), idx1, idx2, idx3, idx4, relative, minDihedralDeg,
104 maxDihedralDeg, forceConstant);
105 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
106 }
107
MMFFAddPositionConstraint(PyForceField * self,unsigned int idx,double maxDispl,double forceConstant)108 void MMFFAddPositionConstraint(PyForceField *self, unsigned int idx,
109 double maxDispl, double forceConstant) {
110 auto *constraint = new MMFF::PositionConstraintContrib(
111 self->field.get(), idx, maxDispl, forceConstant);
112 self->field->contribs().push_back(ForceFields::ContribPtr(constraint));
113 }
114
ForceFieldGetExtraPointLoc(PyForceField * self,unsigned int idx)115 PyObject *ForceFieldGetExtraPointLoc(PyForceField *self, unsigned int idx) {
116 if (idx >= self->extraPoints.size()) {
117 throw IndexErrorException(idx);
118 }
119 PyObject *res = PyTuple_New(3);
120 PyTuple_SetItem(res, 0, PyFloat_FromDouble(self->extraPoints[idx]->x));
121 PyTuple_SetItem(res, 1, PyFloat_FromDouble(self->extraPoints[idx]->y));
122 PyTuple_SetItem(res, 2, PyFloat_FromDouble(self->extraPoints[idx]->z));
123 return res;
124 }
125
calcEnergyWithPos(const python::object & pos)126 double PyForceField::calcEnergyWithPos(const python::object &pos) {
127 PRECONDITION(this->field, "no force field");
128 if (pos != python::object()) {
129 size_t s = this->field->dimension() * this->field->numPoints();
130 size_t numElements = python::extract<size_t>(pos.attr("__len__")());
131 if (s != numElements) {
132 throw ValueErrorException("The Python container must have length equal to Dimension() * NumPoints()");
133 }
134 std::vector<double> c(s);
135 for (size_t i = 0; i < s; ++i) {
136 c[i] = python::extract<double>(pos[i]);
137 }
138 return this->field->calcEnergy(c.data());
139 } else {
140 return this->field->calcEnergy();
141 }
142 }
143
positions()144 PyObject *PyForceField::positions() {
145 PRECONDITION(this->field, "no force field");
146 size_t s = this->field->dimension() * this->field->numPoints();
147 PyObject *coordTuple = PyTuple_New(s);
148 const RDGeom::PointPtrVect &p = this->field->positions();
149 size_t i = 0;
150 PyObject *coordItem;
151 for (const auto pptr: p) {
152 for (size_t j = 0; j < 3; ++j) {
153 coordItem = PyFloat_FromDouble((*pptr)[j]);
154 PyTuple_SetItem(coordTuple, i++, coordItem);
155 }
156 }
157 return coordTuple;
158 }
159
calcGradWithPos(const python::object & pos)160 PyObject *PyForceField::calcGradWithPos(const python::object &pos) {
161 PRECONDITION(this->field, "no force field");
162 size_t s = this->field->dimension() * this->field->numPoints();
163 std::vector<double> g(s, 0.0);
164 PyObject *gradTuple = PyTuple_New(s);
165 if (pos != python::object()) {
166 size_t numElements = python::extract<size_t>(pos.attr("__len__")());
167 if (s != numElements) {
168 throw ValueErrorException("The Python container must have length equal to Dimension() * NumPoints()");
169 }
170 std::vector<double> c(s);
171 for (size_t i = 0; i < s; ++i) {
172 c[i] = python::extract<double>(pos[i]);
173 }
174 this->field->calcGrad(c.data(), g.data());
175 } else {
176 this->field->calcGrad(g.data());
177 }
178 for (size_t i = 0; i < s; ++i) {
179 PyObject *coordItem = PyFloat_FromDouble(g[i]);
180 PyTuple_SetItem(gradTuple, i, coordItem);
181 }
182 return gradTuple;
183 }
184
minimizeTrajectory(unsigned int snapshotFreq,int maxIts,double forceTol,double energyTol)185 python::tuple PyForceField::minimizeTrajectory(unsigned int snapshotFreq, int maxIts, double forceTol, double energyTol) {
186 PRECONDITION(this->field, "no force field");
187 RDKit::SnapshotVect snapshotVect;
188 int resInt = this->field->minimize(snapshotFreq, &snapshotVect,
189 maxIts, forceTol, energyTol);
190 python::list l;
191 for (RDKit::SnapshotVect::const_iterator it = snapshotVect.begin();
192 it != snapshotVect.end(); ++it) {
193 l.append(new RDKit::Snapshot(*it));
194 }
195 return python::make_tuple(resInt, l);
196
197 }
198
getMMFFBondStretchParams(const RDKit::ROMol & mol,const unsigned int idx1,const unsigned int idx2)199 PyObject *PyMMFFMolProperties::getMMFFBondStretchParams(
200 const RDKit::ROMol &mol, const unsigned int idx1, const unsigned int idx2) {
201 PyObject *res = nullptr;
202 unsigned int bondType;
203 ForceFields::MMFF::MMFFBond mmffBondStretchParams;
204 if (mmffMolProperties->getMMFFBondStretchParams(mol, idx1, idx2, bondType,
205 mmffBondStretchParams)) {
206 res = PyTuple_New(3);
207 PyTuple_SetItem(res, 0, PyInt_FromLong(bondType));
208 PyTuple_SetItem(res, 1, PyFloat_FromDouble(mmffBondStretchParams.kb));
209 PyTuple_SetItem(res, 2, PyFloat_FromDouble(mmffBondStretchParams.r0));
210 }
211 return res;
212 };
213
getMMFFAngleBendParams(const RDKit::ROMol & mol,const unsigned int idx1,const unsigned int idx2,const unsigned int idx3)214 PyObject *PyMMFFMolProperties::getMMFFAngleBendParams(const RDKit::ROMol &mol,
215 const unsigned int idx1,
216 const unsigned int idx2,
217 const unsigned int idx3) {
218 PyObject *res = nullptr;
219 unsigned int angleType;
220 ForceFields::MMFF::MMFFAngle mmffAngleBendParams;
221 if (mmffMolProperties->getMMFFAngleBendParams(
222 mol, idx1, idx2, idx3, angleType, mmffAngleBendParams)) {
223 res = PyTuple_New(3);
224 PyTuple_SetItem(res, 0, PyInt_FromLong(angleType));
225 PyTuple_SetItem(res, 1, PyFloat_FromDouble(mmffAngleBendParams.ka));
226 PyTuple_SetItem(res, 2, PyFloat_FromDouble(mmffAngleBendParams.theta0));
227 }
228 return res;
229 };
230
getMMFFStretchBendParams(const RDKit::ROMol & mol,const unsigned int idx1,const unsigned int idx2,const unsigned int idx3)231 PyObject *PyMMFFMolProperties::getMMFFStretchBendParams(
232 const RDKit::ROMol &mol, const unsigned int idx1, const unsigned int idx2,
233 const unsigned int idx3) {
234 PyObject *res = nullptr;
235 unsigned int stretchBendType;
236 ForceFields::MMFF::MMFFStbn mmffStretchBendParams;
237 ForceFields::MMFF::MMFFBond mmffBondStretchParams[2];
238 ForceFields::MMFF::MMFFAngle mmffAngleBendParams;
239 if (mmffMolProperties->getMMFFStretchBendParams(
240 mol, idx1, idx2, idx3, stretchBendType, mmffStretchBendParams,
241 mmffBondStretchParams, mmffAngleBendParams)) {
242 res = PyTuple_New(3);
243 PyTuple_SetItem(res, 0, PyInt_FromLong(stretchBendType));
244 PyTuple_SetItem(res, 1, PyFloat_FromDouble(mmffStretchBendParams.kbaIJK));
245 PyTuple_SetItem(res, 2, PyFloat_FromDouble(mmffStretchBendParams.kbaKJI));
246 }
247 return res;
248 };
249
getMMFFTorsionParams(const RDKit::ROMol & mol,const unsigned int idx1,const unsigned int idx2,const unsigned int idx3,const unsigned int idx4)250 PyObject *PyMMFFMolProperties::getMMFFTorsionParams(const RDKit::ROMol &mol,
251 const unsigned int idx1,
252 const unsigned int idx2,
253 const unsigned int idx3,
254 const unsigned int idx4) {
255 PyObject *res = nullptr;
256 unsigned int torType;
257 ForceFields::MMFF::MMFFTor mmffTorsionParams;
258 if (mmffMolProperties->getMMFFTorsionParams(mol, idx1, idx2, idx3, idx4,
259 torType, mmffTorsionParams)) {
260 res = PyTuple_New(4);
261 PyTuple_SetItem(res, 0, PyInt_FromLong(torType));
262 PyTuple_SetItem(res, 1, PyFloat_FromDouble(mmffTorsionParams.V1));
263 PyTuple_SetItem(res, 2, PyFloat_FromDouble(mmffTorsionParams.V2));
264 PyTuple_SetItem(res, 3, PyFloat_FromDouble(mmffTorsionParams.V3));
265 }
266 return res;
267 };
268
getMMFFOopBendParams(const RDKit::ROMol & mol,const unsigned int idx1,const unsigned int idx2,const unsigned int idx3,const unsigned int idx4)269 PyObject *PyMMFFMolProperties::getMMFFOopBendParams(const RDKit::ROMol &mol,
270 const unsigned int idx1,
271 const unsigned int idx2,
272 const unsigned int idx3,
273 const unsigned int idx4) {
274 PyObject *res = nullptr;
275 ForceFields::MMFF::MMFFOop mmffOopBendParams;
276 if (mmffMolProperties->getMMFFOopBendParams(mol, idx1, idx2, idx3, idx4,
277 mmffOopBendParams)) {
278 res = PyFloat_FromDouble(mmffOopBendParams.koop);
279 }
280 return res;
281 };
282
getMMFFVdWParams(const unsigned int idx1,const unsigned int idx2)283 PyObject *PyMMFFMolProperties::getMMFFVdWParams(const unsigned int idx1,
284 const unsigned int idx2) {
285 PyObject *res = nullptr;
286 ForceFields::MMFF::MMFFVdWRijstarEps mmffVdWParams;
287 if (mmffMolProperties->getMMFFVdWParams(idx1, idx2, mmffVdWParams)) {
288 res = PyTuple_New(4);
289 PyTuple_SetItem(res, 0,
290 PyFloat_FromDouble(mmffVdWParams.R_ij_starUnscaled));
291 PyTuple_SetItem(res, 1, PyFloat_FromDouble(mmffVdWParams.epsilonUnscaled));
292 PyTuple_SetItem(res, 2, PyFloat_FromDouble(mmffVdWParams.R_ij_star));
293 PyTuple_SetItem(res, 3, PyFloat_FromDouble(mmffVdWParams.epsilon));
294 }
295 return res;
296 };
297
BOOST_PYTHON_MODULE(rdForceField)298 BOOST_PYTHON_MODULE(rdForceField) {
299 python::scope().attr("__doc__") = "Exposes the ForceField class";
300
301 std::string docString;
302
303 python::class_<PyForceField>("ForceField", "A force field", python::no_init)
304 .def("CalcEnergy",
305 (double (PyForceField::*)(const python::object &) const) &PyForceField::calcEnergyWithPos,
306 (python::arg("pos") = python::object()),
307 "Returns the energy (in kcal/mol) of the current arrangement\n"
308 "or of the supplied coordinate list (if non-empty)")
309 .def("CalcGrad", &PyForceField::calcGradWithPos,
310 (python::arg("pos") = python::object()),
311 "Returns a tuple filled with the per-coordinate gradients\n"
312 "of the current arrangement or of the supplied coordinate list (if non-empty)")
313 .def("Positions", &PyForceField::positions,
314 "Returns a tuple filled with the coordinates of the\n"
315 "points the ForceField is handling")
316 .def("Dimension",
317 (unsigned int (PyForceField::*)() const) &PyForceField::dimension,
318 "Returns the dimension of the ForceField")
319 .def("NumPoints",
320 (unsigned int (PyForceField::*)() const) &PyForceField::numPoints,
321 "Returns the number of points the ForceField is handling")
322 .def("Minimize", &PyForceField::minimize,
323 (python::arg("maxIts") = 200, python::arg("forceTol") = 1e-4,
324 python::arg("energyTol") = 1e-6),
325 "Runs some minimization iterations.\n\n Returns 0 if the "
326 "minimization succeeded.")
327 .def("MinimizeTrajectory", &PyForceField::minimizeTrajectory,
328 (python::arg("snapshotFreq"), python::arg("maxIts") = 200,
329 python::arg("forceTol") = 1e-4, python::arg("energyTol") = 1e-6),
330 "Runs some minimization iterations, recording the minimization "
331 "trajectory every snapshotFreq steps.\n\n"
332 "Returns a (int, []) tuple; the int is 0 if the minimization succeeded, "
333 "while the list contains Snapshot objects.")
334 .def("AddDistanceConstraint", ForceFieldAddDistanceConstraint,
335 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
336 python::arg("minLen"), python::arg("maxLen"),
337 python::arg("forceConstant")),
338 "Adds a distance constraint to the UFF force field "
339 "(deprecated, use UFFAddDistanceConstraint instead).")
340 .def("AddFixedPoint", ForceFieldAddFixedPoint,
341 (python::arg("self"), python::arg("idx")),
342 "Adds a fixed point to the force field.")
343 .def("UFFAddDistanceConstraint", UFFAddDistanceConstraint,
344 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
345 python::arg("relative"), python::arg("minLen"),
346 python::arg("maxLen"), python::arg("forceConstant")),
347 "Adds a distance constraint to the UFF force field; if relative == "
348 "True, "
349 "then minLen and maxLen are intended as relative to the current "
350 "distance.")
351 .def("UFFAddAngleConstraint", UFFAddAngleConstraint,
352 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
353 python::arg("idx3"), python::arg("relative"),
354 python::arg("minAngleDeg"), python::arg("maxAngleDeg"),
355 python::arg("forceConstant")),
356 "Adds an angle constraint to the UFF force field; if relative == "
357 "True, "
358 "then minAngleDeg and maxAngleDeg are intended as relative to the "
359 "current angle.")
360 .def("UFFAddTorsionConstraint", UFFAddTorsionConstraint,
361 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
362 python::arg("idx3"), python::arg("idx4"), python::arg("relative"),
363 python::arg("minDihedralDeg"), python::arg("maxDihedralDeg"),
364 python::arg("forceConstant")),
365 "Adds a dihedral angle constraint to the UFF force field; if "
366 "relative == True, "
367 "then minDihedralDeg and maxDihedralDeg are intended as relative to "
368 "the current "
369 "dihedral angle.")
370 .def("UFFAddPositionConstraint", UFFAddPositionConstraint,
371 (python::arg("self"), python::arg("idx"), python::arg("maxDispl"),
372 python::arg("forceConstant")),
373 "Adds a position constraint to the UFF force field.")
374 .def("MMFFAddDistanceConstraint", MMFFAddDistanceConstraint,
375 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
376 python::arg("relative"), python::arg("minLen"),
377 python::arg("maxLen"), python::arg("forceConstant")),
378 "Adds a distance constraint to the MMFF force field; if relative == "
379 "True, "
380 "then minLen and maxLen are intended as relative to the current "
381 "distance.")
382 .def("MMFFAddAngleConstraint", MMFFAddAngleConstraint,
383 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
384 python::arg("idx3"), python::arg("relative"),
385 python::arg("minAngleDeg"), python::arg("maxAngleDeg"),
386 python::arg("forceConstant")),
387 "Adds an angle constraint to the MMFF force field; if relative == "
388 "True, "
389 "then minAngleDeg and maxAngleDeg are intended as relative to the "
390 "current angle.")
391 .def("MMFFAddTorsionConstraint", MMFFAddTorsionConstraint,
392 (python::arg("self"), python::arg("idx1"), python::arg("idx2"),
393 python::arg("idx3"), python::arg("idx4"), python::arg("relative"),
394 python::arg("minDihedralDeg"), python::arg("maxDihedralDeg"),
395 python::arg("forceConstant")),
396 "Adds a dihedral angle constraint to the MMFF force field; if "
397 "relative == True, "
398 "then minDihedralDeg and maxDihedralDeg are intended as relative to "
399 "the current "
400 "dihedral angle.")
401 .def("MMFFAddPositionConstraint", MMFFAddPositionConstraint,
402 (python::arg("self"), python::arg("idx"), python::arg("maxDispl"),
403 python::arg("forceConstant")),
404 "Adds a position constraint to the MMFF force field.")
405 .def("Initialize", &PyForceField::initialize,
406 "initializes the force field (call this before minimizing)")
407 .def("AddExtraPoint", &PyForceField::addExtraPoint,
408 (python::arg("self"), python::arg("x"), python::arg("y"),
409 python::arg("z"), python::arg("fixed") = true),
410 "Adds an extra point, this can be useful for adding constraints.")
411 .def("GetExtraPointPos", ForceFieldGetExtraPointLoc,
412 (python::arg("self"), python::arg("idx")),
413 "returns the location of an extra point as a tuple");
414 python::class_<PyMMFFMolProperties>(
415 "MMFFMolProperties", "MMFF molecular properties", python::no_init)
416 .def("GetMMFFAtomType", &PyMMFFMolProperties::getMMFFAtomType,
417 (python::arg("self"), python::arg("idx")),
418 "Retrieves MMFF atom type for atom with index idx")
419 .def("GetMMFFFormalCharge", &PyMMFFMolProperties::getMMFFFormalCharge,
420 (python::arg("self"), python::arg("idx")),
421 "Retrieves MMFF formal charge for atom with index idx")
422 .def("GetMMFFPartialCharge", &PyMMFFMolProperties::getMMFFPartialCharge,
423 (python::arg("self"), python::arg("idx")),
424 "Retrieves MMFF partial charge for atom with index idx")
425 .def("GetMMFFBondStretchParams",
426 &PyMMFFMolProperties::getMMFFBondStretchParams,
427 (python::arg("self"), python::arg("mol"), python::arg("idx1"),
428 python::arg("idx2")),
429 "Retrieves MMFF bond stretch parameters for atoms with indexes "
430 "idx1, idx2 "
431 "as a (bondType, kb, r0) tuple, or None if no parameters could be "
432 "found")
433 .def("GetMMFFAngleBendParams",
434 &PyMMFFMolProperties::getMMFFAngleBendParams,
435 (python::arg("self"), python::arg("mol"), python::arg("idx1"),
436 python::arg("idx2"), python::arg("idx3")),
437 "Retrieves MMFF angle bend parameters for atoms with indexes idx1, "
438 "idx2, idx3 "
439 "as a (angleType, ka, theta0) tuple, or None if no parameters could "
440 "be found")
441 .def("GetMMFFStretchBendParams",
442 &PyMMFFMolProperties::getMMFFStretchBendParams,
443 (python::arg("self"), python::arg("mol"), python::arg("idx1"),
444 python::arg("idx2"), python::arg("idx3")),
445 "Retrieves MMFF stretch-bend parameters for atoms with indexes "
446 "idx1, idx2, idx3 "
447 "as a (stretchBendType, kbaIJK, kbaKJI) tuple, or None if no "
448 "parameters could be found")
449 .def("GetMMFFTorsionParams", &PyMMFFMolProperties::getMMFFTorsionParams,
450 (python::arg("self"), python::arg("mol"), python::arg("idx1"),
451 python::arg("idx2"), python::arg("idx3"), python::arg("idx4")),
452 "Retrieves MMFF torsion parameters for atoms with indexes idx1, "
453 "idx2, idx3, idx4 "
454 "as a (torsionType, V1, V2, V3) tuple, or None if no parameters "
455 "could be found")
456 .def("GetMMFFOopBendParams", &PyMMFFMolProperties::getMMFFOopBendParams,
457 (python::arg("self"), python::arg("mol"), python::arg("idx1"),
458 python::arg("idx2"), python::arg("idx3"), python::arg("idx4")),
459 "Retrieves MMFF out-of-plane bending force constant for atoms with "
460 "indexes "
461 "idx1, idx2, idx3, idx4 as a koop float value")
462 .def("GetMMFFVdWParams", &PyMMFFMolProperties::getMMFFVdWParams,
463 (python::arg("self"), python::arg("idx1"), python::arg("idx2")),
464 "Retrieves MMFF van der Waals parameters for atoms with indexes "
465 "idx1, idx2 as a (R_ij_starUnscaled, epsilonUnscaled, R_ij_star, "
466 "epsilon) tuple, "
467 "or None if no parameters could be found")
468 .def("SetMMFFDielectricModel",
469 &PyMMFFMolProperties::setMMFFDielectricModel,
470 (python::arg("self"), python::arg("dielModel") = 1),
471 "Sets the DielModel MMFF property (1: constant; 2: "
472 "distance-dependent; "
473 "defaults to constant)")
474 .def("SetMMFFDielectricConstant",
475 &PyMMFFMolProperties::setMMFFDielectricConstant,
476 (python::arg("self"), python::arg("dielConst") = 1.0),
477 "Sets the DielConst MMFF property (defaults to 1.0)")
478 .def("SetMMFFBondTerm", &PyMMFFMolProperties::setMMFFBondTerm,
479 (python::arg("self"), python::arg("state") = true),
480 "Sets the bond term to be included in the MMFF equation (defaults "
481 "to True)")
482 .def("SetMMFFAngleTerm", &PyMMFFMolProperties::setMMFFAngleTerm,
483 (python::arg("self"), python::arg("state") = true),
484 "Sets the angle term to be included in the MMFF equation (defaults "
485 "to True)")
486 .def("SetMMFFStretchBendTerm",
487 &PyMMFFMolProperties::setMMFFStretchBendTerm,
488 (python::arg("self"), python::arg("state") = true),
489 "Sets the stretch-bend term to be included in the MMFF equation "
490 "(defaults to True)")
491 .def("SetMMFFOopTerm", &PyMMFFMolProperties::setMMFFOopTerm,
492 (python::arg("self"), python::arg("state") = true),
493 "Sets the out-of-plane bend term to be included in the MMFF "
494 "equation (defaults to True)")
495 .def("SetMMFFTorsionTerm", &PyMMFFMolProperties::setMMFFTorsionTerm,
496 (python::arg("self"), python::arg("state") = true),
497 "Sets the torsional term to be included in the MMFF equation "
498 "(defaults to True)")
499 .def("SetMMFFVdWTerm", &PyMMFFMolProperties::setMMFFVdWTerm,
500 (python::arg("self"), python::arg("state") = true),
501 "Sets the Van der Waals term to be included in the MMFF equation "
502 "(defaults to True)")
503 .def("SetMMFFEleTerm", &PyMMFFMolProperties::setMMFFEleTerm,
504 (python::arg("self"), python::arg("state") = true),
505 "Sets the electrostatic term to be included in the MMFF equation "
506 "(defaults to True)")
507 .def("SetMMFFVariant", &PyMMFFMolProperties::setMMFFVariant,
508 (python::arg("self"), python::arg("mmffVariant") = "MMFF94"),
509 "Sets the MMFF variant to be used (\"MMFF94\" or \"MMFF94s\"; "
510 "defaults to \"MMFF94\")")
511 .def("SetMMFFVerbosity", &PyMMFFMolProperties::setMMFFVerbosity,
512 (python::arg("self"), python::arg("verbosity") = 0),
513 "Sets the MMFF verbosity (0: none; 1: low; 2: high; defaults to 0)");
514 }
515 /*
516 (python::arg("self"), python::arg("mol"), python::arg("idx1"),
517 python::arg("idx2")),
518 "Retrieves MMFF bond stretch parameters for atoms with indexes idx1, idx2; "
519 "as a tuple (bondType, kb, r0)")
520 */
521