RDKit
Open-source cheminformatics and machine learning.
MMFF/Params.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2013 Paolo Tosco
3 //
4 // Copyright (C) 2004-2006 Rational Discovery LLC
5 //
6 // @@ All Rights Reserved @@
7 // This file is part of the RDKit.
8 // The contents are covered by the terms of the BSD license
9 // which is included in the file license.txt, found at the root
10 // of the RDKit source tree.
11 //
12 #include <RDGeneral/export.h>
13 #ifndef __RD_MMFFPARAMS_H__
14 #define __RD_MMFFPARAMS_H__
15 
16 #include <RDGeneral/Invariant.h>
17 #include <cmath>
18 #include <string>
19 #include <vector>
20 #include <algorithm>
21 #include <map>
22 #include <iostream>
23 #include <boost/cstdint.hpp>
24 
25 #ifndef M_PI
26 #define M_PI 3.14159265358979323846
27 #endif
28 
29 // binary searches are slightly faster than std::map;
30 // however when I moved to binary searches I had already
31 // written the code for std::map, so the two methods
32 // can be toggled defining RDKIT_MMFF_PARAMS_USE_STD_MAP
33 
34 //#define RDKIT_MMFF_PARAMS_USE_STD_MAP 1
35 
36 namespace ForceFields {
37 namespace MMFF {
38 
39 const double DEG2RAD = M_PI / 180.0;
40 const double RAD2DEG = 180.0 / M_PI;
41 const double MDYNE_A_TO_KCAL_MOL = 143.9325;
42 inline bool isDoubleZero(const double x) {
43  return ((x < 1.0e-10) && (x > -1.0e-10));
44 }
45 inline void clipToOne(double &x) {
46  if (x > 1.0) {
47  x = 1.0;
48  } else if (x < -1.0) {
49  x = -1.0;
50  }
51 }
52 
53 //! class to store MMFF atom type equivalence levels
55  public:
56  boost::uint8_t eqLevel[4];
57 };
58 
59 //! class to store MMFF Properties
61  public:
62  boost::uint8_t atno;
63  boost::uint8_t crd;
64  boost::uint8_t val;
65  boost::uint8_t pilp;
66  boost::uint8_t mltb;
67  boost::uint8_t arom;
68  boost::uint8_t linh;
69  boost::uint8_t sbmb;
70 };
71 
72 //! class to store MMFF Partial Bond Charge Increments
74  public:
75  double pbci;
76  double fcadj;
77 };
78 
79 //! class to store MMFF bond-charge-increment parameters used to
80 //! construct MMFF partial atomic charges
82  public:
83  double bci;
84 };
85 
86 //! class to store MMFF parameters for bond stretching
88  public:
89  double kb;
90  double r0;
91 };
92 
93 //! class to store parameters for Herschbach-Laurie's version
94 //! of Badger's rule
96  public:
97  double a_ij;
98  double d_ij;
99  double dp_ij;
100 };
101 
102 //! class to store covalent radius and Pauling electronegativity
103 //! values for MMFF bond stretching empirical rule
105  public:
106  double r0;
107  double chi;
108 };
109 
110 //! class to store MMFF parameters for angle bending
112  public:
113  double ka;
114  double theta0;
115 };
116 
117 //! class to store MMFF parameters for stretch-bending
119  public:
120  double kbaIJK;
121  double kbaKJI;
122 };
123 
124 //! class to store MMFF parameters for out-of-plane bending
126  public:
127  double koop;
128 };
129 
130 //! class to store MMFF parameters for torsions
132  public:
133  double V1;
134  double V2;
135  double V3;
136 };
137 
138 //! class to store MMFF parameters for non-bonded Van der Waals
140  public:
141  double alpha_i;
142  double N_i;
143  double A_i;
144  double G_i;
145  double R_star;
146  boost::uint8_t DA;
147 };
148 
150  public:
153  double R_ij_star;
154  double epsilon;
155 };
156 
158  public:
159  //! gets a pointer to the singleton MMFFAromCollection
160  /*!
161  \param mmffArom (optional) a string with parameter data. See
162  below for more information about this argument
163 
164  \return a pointer to the singleton MMFFAromCollection
165 
166  <b>Notes:</b>
167  - do <b>not</b> delete the pointer returned here
168  - if the singleton MMFFAromCollection has already been instantiated and
169  \c mmffArom is empty, the singleton will be returned.
170  - if \c mmffArom is empty and the singleton MMFFAromCollection has
171  not yet been instantiated, the default MMFFArom parameters (from
172  Params.cpp)
173  will be used.
174  - if \c mmffArom is supplied, a new singleton will be instantiated.
175  The current instantiation (if there is one) will be deleted.
176  */
177  static MMFFAromCollection *getMMFFArom(
178  const boost::uint8_t *aromatic_types = NULL);
179  //! Looks up the parameters for a particular key and returns them.
180  /*!
181  \return a pointer to the MMFFArom object, NULL on failure.
182  */
183  bool isMMFFAromatic(const unsigned int atomType) const {
184  return ((std::find(d_params.begin(), d_params.end(), atomType) !=
185  d_params.end())
186  ? true
187  : false);
188  }
189 
190  private:
191  //! to force this to be a singleton, the constructor must be private
192  MMFFAromCollection(const boost::uint8_t mmffArom[]);
193  static class MMFFAromCollection *ds_instance; //!< the singleton
194  std::vector<boost::uint8_t> d_params; //!< the aromatic type vector
195 };
196 
198  public:
199  //! gets a pointer to the singleton MMFFDefCollection
200  /*!
201  \param mmffDef (optional) a string with parameter data. See
202  below for more information about this argument
203 
204  \return a pointer to the singleton MMFFDefCollection
205 
206  <b>Notes:</b>
207  - do <b>not</b> delete the pointer returned here
208  - if the singleton MMFFDefCollection has already been instantiated and
209  \c mmffDef is empty, the singleton will be returned.
210  - if \c mmffDef is empty and the singleton MMFFDefCollection has
211  not yet been instantiated, the default MMFFDef parameters (from
212  Params.cpp)
213  will be used.
214  - if \c mmffDef is supplied, a new singleton will be instantiated.
215  The current instantiation (if there is one) will be deleted.
216  */
217  static MMFFDefCollection *getMMFFDef(const std::string &mmffDef = "");
218  //! Looks up the parameters for a particular key and returns them.
219  /*!
220  \return a pointer to the MMFFDef object, NULL on failure.
221  */
222  const MMFFDef *operator()(const unsigned int atomType) const {
223 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
224  std::map<const unsigned int, MMFFDef>::const_iterator res;
225  res = d_params.find(atomType);
226 
227  return ((res != d_params.end()) ? &((*res).second) : NULL);
228 #else
229  return ((atomType && (atomType <= d_params.size()))
230  ? &d_params[atomType - 1]
231  : NULL);
232 #endif
233  }
234 
235  private:
236  //! to force this to be a singleton, the constructor must be private
237  MMFFDefCollection(std::string mmffDef);
238  static class MMFFDefCollection *ds_instance; //!< the singleton
239 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
240  std::map<const unsigned int, MMFFDef> d_params; //!< the parameter map
241 #else
242  std::vector<MMFFDef> d_params; //!< the parameter vector
243 #endif
244 };
245 
247  public:
248  //! gets a pointer to the singleton MMFFPropCollection
249  /*!
250  \param mmffProp (optional) a string with parameter data. See
251  below for more information about this argument
252 
253  \return a pointer to the singleton MMFFPropCollection
254 
255  <b>Notes:</b>
256  - do <b>not</b> delete the pointer returned here
257  - if the singleton MMFFPropCollection has already been instantiated and
258  \c mmffProp is empty, the singleton will be returned.
259  - if \c mmffProp is empty and the singleton MMFFPropCollection has
260  not yet been instantiated, the default parameters (from Params.cpp)
261  will be used.
262  - if \c mmffProp is supplied, a new singleton will be instantiated.
263  The current instantiation (if there is one) will be deleted.
264  */
265  static MMFFPropCollection *getMMFFProp(const std::string &mmffProp = "");
266  //! Looks up the parameters for a particular key and returns them.
267  /*!
268  \return a pointer to the MMFFProp object, NULL on failure.
269  */
270  const MMFFProp *operator()(const unsigned int atomType) const {
271 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
272  std::map<const unsigned int, MMFFProp>::const_iterator res;
273  res = d_params.find(atomType);
274 
275  return ((res != d_params.end()) ? &((*res).second) : NULL);
276 #else
277  std::pair<std::vector<boost::uint8_t>::const_iterator,
278  std::vector<boost::uint8_t>::const_iterator> bounds =
279  std::equal_range(d_iAtomType.begin(), d_iAtomType.end(), atomType);
280 
281  return ((bounds.first != bounds.second)
282  ? &d_params[bounds.first - d_iAtomType.begin()]
283  : NULL);
284 #endif
285  }
286 
287  private:
288  //! to force this to be a singleton, the constructor must be private
289  MMFFPropCollection(std::string mmffProp);
290  static class MMFFPropCollection *ds_instance; //!< the singleton
291 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
292  std::map<const unsigned int, MMFFProp> d_params; //!< the parameter map
293 #else
294  std::vector<MMFFProp> d_params;
295  std::vector<boost::uint8_t> d_iAtomType; //!< the parameter vector
296 #endif
297 };
298 
300  public:
301  //! gets a pointer to the singleton MMFFPBCICollection
302  /*!
303  \param mmffPBCI (optional) a string with parameter data. See
304  below for more information about this argument
305 
306  \return a pointer to the singleton MMFFPBCICollection
307 
308  <b>Notes:</b>
309  - do <b>not</b> delete the pointer returned here
310  - if the singleton MMFFPBCICollection has already been instantiated and
311  \c mmffPBCI is empty, the singleton will be returned.
312  - if \c mmffPBCI is empty and the singleton MMFFPBCICollection has
313  not yet been instantiated, the default parameters (from Params.cpp)
314  will be used.
315  - if \c mmffPBCI is supplied, a new singleton will be instantiated.
316  The current instantiation (if there is one) will be deleted.
317  */
318  static MMFFPBCICollection *getMMFFPBCI(const std::string &mmffPBCI = "");
319  //! Looks up the parameters for a particular key and returns them.
320  /*!
321  \return a pointer to the MMFFPBCI object, NULL on failure.
322  */
323  const MMFFPBCI *operator()(const unsigned int atomType) const {
324 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
325  std::map<const unsigned int, MMFFPBCI>::const_iterator res;
326  res = d_params.find(atomType);
327 
328  return ((res != d_params.end()) ? &((*res).second) : NULL);
329 #else
330  return ((atomType && (atomType <= d_params.size()))
331  ? &d_params[atomType - 1]
332  : NULL);
333 #endif
334  }
335 
336  private:
337  //! to force this to be a singleton, the constructor must be private
338  MMFFPBCICollection(std::string mmffPBCI);
339  static class MMFFPBCICollection *ds_instance; //!< the singleton
340 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
341  std::map<const unsigned int, MMFFPBCI> d_params; //!< the parameter map
342 #else
343  std::vector<MMFFPBCI> d_params; //!< the parameter vector
344 #endif
345 };
346 
348  public:
349  //! gets a pointer to the singleton MMFFChgCollection
350  /*!
351  \param mmffChg (optional) a string with parameter data. See
352  below for more information about this argument
353 
354  \return a pointer to the singleton MMFFChgCollection
355 
356  <b>Notes:</b>
357  - do <b>not</b> delete the pointer returned here
358  - if the singleton MMFFChgCollection has already been instantiated and
359  \c mmffChg is empty, the singleton will be returned.
360  - if \c mmffChg is empty and the singleton MMFFChgCollection has
361  not yet been instantiated, the default parameters (from Params.cpp)
362  will be used.
363  - if \c mmffChg is supplied, a new singleton will be instantiated.
364  The current instantiation (if there is one) will be deleted.
365  */
366  static MMFFChgCollection *getMMFFChg(const std::string &mmffChg = "");
367  //! Looks up the parameters for a particular key and returns them.
368  /*!
369  \return a pointer to the MMFFChg object, NULL on failure.
370  */
371  const std::pair<int, const MMFFChg *> getMMFFChgParams(
372  const unsigned int bondType, const unsigned int iAtomType,
373  const unsigned int jAtomType) {
374  int sign = -1;
375  const MMFFChg *mmffChgParams = NULL;
376  unsigned int canIAtomType = iAtomType;
377  unsigned int canJAtomType = jAtomType;
378  if (iAtomType > jAtomType) {
379  canIAtomType = jAtomType;
380  canJAtomType = iAtomType;
381  sign = 1;
382  }
383 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
384  std::map<const unsigned int,
385  std::map<const unsigned int, MMFFChg> >::const_iterator res1;
386  std::map<const unsigned int, MMFFChg>::const_iterator res2;
387  res1 = d_params[bondType].find(canIAtomType);
388  if (res1 != d_params[bondType].end()) {
389  res2 = ((*res1).second).find(canJAtomType);
390  if (res2 != ((*res1).second).end()) {
391  mmffChgParams = &((*res2).second);
392  }
393  }
394 #else
395  std::pair<std::vector<boost::uint8_t>::const_iterator,
396  std::vector<boost::uint8_t>::const_iterator> bounds;
397 
398  bounds =
399  std::equal_range(d_iAtomType.begin(), d_iAtomType.end(), canIAtomType);
400  if (bounds.first != bounds.second) {
401  bounds = std::equal_range(
402  d_jAtomType.begin() + (bounds.first - d_iAtomType.begin()),
403  d_jAtomType.begin() + (bounds.second - d_iAtomType.begin()),
404  canJAtomType);
405  if (bounds.first != bounds.second) {
406  bounds = std::equal_range(
407  d_bondType.begin() + (bounds.first - d_jAtomType.begin()),
408  d_bondType.begin() + (bounds.second - d_jAtomType.begin()),
409  bondType);
410  if (bounds.first != bounds.second) {
411  mmffChgParams = &d_params[bounds.first - d_bondType.begin()];
412  }
413  }
414  }
415 #endif
416 
417  return std::make_pair(sign, mmffChgParams);
418  }
419 
420  private:
421  //! to force this to be a singleton, the constructor must be private
422  MMFFChgCollection(std::string mmffChg);
423  static class MMFFChgCollection *ds_instance; //!< the singleton
424 //!< the parameter 3D-map
425 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
426  std::map<
427  const unsigned int,
428  std::map<const unsigned int, std::map<const unsigned int, MMFFChg> > >
429  d_params; //!< the parameter 3D-map
430 #else
431  std::vector<MMFFChg> d_params; //! the parameter vector
432  std::vector<boost::uint8_t> d_iAtomType; //! atom type vector for atom i
433  std::vector<boost::uint8_t> d_jAtomType; //! atom type vector for atom j
434  std::vector<boost::uint8_t> d_bondType; //! bond type vector for bond i-j
435 #endif
436 };
437 
439  public:
440  //! gets a pointer to the singleton MMFFBondCollection
441  /*!
442  \param mmffBond (optional) a string with parameter data. See
443  below for more information about this argument
444 
445  \return a pointer to the singleton MMFFBondCollection
446 
447  <b>Notes:</b>
448  - do <b>not</b> delete the pointer returned here
449  - if the singleton MMFFBondCollection has already been instantiated and
450  \c mmffBond is empty, the singleton will be returned.
451  - if \c mmffBond is empty and the singleton MMFFBondCollection has
452  not yet been instantiated, the default parameters (from Params.cpp)
453  will be used.
454  - if \c mmffBond is supplied, a new singleton will be instantiated.
455  The current instantiation (if there is one) will be deleted.
456  */
457  static MMFFBondCollection *getMMFFBond(const std::string &mmffBond = "");
458  //! Looks up the parameters for a particular key and returns them.
459  /*!
460  \return a pointer to the MMFFBond object, NULL on failure.
461  */
462  const MMFFBond *operator()(const unsigned int bondType,
463  const unsigned int atomType,
464  const unsigned int nbrAtomType) {
465  const MMFFBond *mmffBondParams = NULL;
466  unsigned int canAtomType = atomType;
467  unsigned int canNbrAtomType = nbrAtomType;
468  if (atomType > nbrAtomType) {
469  canAtomType = nbrAtomType;
470  canNbrAtomType = atomType;
471  }
472 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
473  std::map<const unsigned int,
474  std::map<const unsigned int,
475  std::map<const unsigned int, MMFFBond> > >::const_iterator
476  res1;
477  std::map<const unsigned int,
478  std::map<const unsigned int, MMFFBond> >::const_iterator res2;
479  std::map<const unsigned int, MMFFBond>::const_iterator res3;
480  res1 = d_params.find(bondType);
481  if (res1 != d_params.end()) {
482  res2 = ((*res1).second).find(canAtomType);
483  if (res2 != ((*res1).second).end()) {
484  res3 = ((*res2).second).find(canNbrAtomType);
485  if (res3 != ((*res2).second).end()) {
486  mmffBondParams = &((*res3).second);
487  }
488  }
489  }
490 #else
491  std::pair<std::vector<boost::uint8_t>::const_iterator,
492  std::vector<boost::uint8_t>::const_iterator> bounds;
493  bounds =
494  std::equal_range(d_iAtomType.begin(), d_iAtomType.end(), canAtomType);
495  if (bounds.first != bounds.second) {
496  bounds = std::equal_range(
497  d_jAtomType.begin() + (bounds.first - d_iAtomType.begin()),
498  d_jAtomType.begin() + (bounds.second - d_iAtomType.begin()),
499  canNbrAtomType);
500  if (bounds.first != bounds.second) {
501  bounds = std::equal_range(
502  d_bondType.begin() + (bounds.first - d_jAtomType.begin()),
503  d_bondType.begin() + (bounds.second - d_jAtomType.begin()),
504  bondType);
505  if (bounds.first != bounds.second) {
506  mmffBondParams = &d_params[bounds.first - d_bondType.begin()];
507  }
508  }
509  }
510 #endif
511 
512  return mmffBondParams;
513  }
514 
515  private:
516  //! to force this to be a singleton, the constructor must be private
517  MMFFBondCollection(std::string mmffBond);
518  static class MMFFBondCollection *ds_instance; //!< the singleton
519 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
520  std::map<
521  const unsigned int,
522  std::map<const unsigned int, std::map<const unsigned int, MMFFBond> > >
523  d_params; //!< the parameter 3D-map
524 #else
525  std::vector<MMFFBond> d_params; //!< the parameter vector
526  std::vector<boost::uint8_t> d_iAtomType; //! atom type vector for atom i
527  std::vector<boost::uint8_t> d_jAtomType; //! atom type vector for atom j
528  std::vector<boost::uint8_t> d_bondType; //! bond type vector for bond i-j
529 #endif
530 };
531 
533  public:
534  //! gets a pointer to the singleton MMFFBndkCollection
535  /*!
536  \param mmffBndk (optional) a string with parameter data. See
537  below for more information about this argument
538 
539  \return a pointer to the singleton MMFFBndkCollection
540 
541  <b>Notes:</b>
542  - do <b>not</b> delete the pointer returned here
543  - if the singleton MMFFBndkCollection has already been instantiated and
544  \c mmffBndk is empty, the singleton will be returned.
545  - if \c mmffBndk is empty and the singleton MMFFBndkCollection has
546  not yet been instantiated, the default parameters (from Params.cpp)
547  will be used.
548  - if \c mmffBndk is supplied, a new singleton will be instantiated.
549  The current instantiation (if there is one) will be deleted.
550  */
551  static MMFFBndkCollection *getMMFFBndk(const std::string &mmffBndk = "");
552  //! Looks up the parameters for a particular key and returns them.
553  /*!
554  \return a pointer to the MMFFBndk object, NULL on failure.
555  */
556  const MMFFBond *operator()(const int atomicNum, const int nbrAtomicNum) {
557  const MMFFBond *mmffBndkParams = NULL;
558  unsigned int canAtomicNum = atomicNum;
559  unsigned int canNbrAtomicNum = nbrAtomicNum;
560  if (atomicNum > nbrAtomicNum) {
561  canAtomicNum = nbrAtomicNum;
562  canNbrAtomicNum = atomicNum;
563  }
564 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
565  std::map<const unsigned int,
566  std::map<const unsigned int, MMFFBond> >::const_iterator res1;
567  std::map<const unsigned int, MMFFBond>::const_iterator res2;
568  res1 = d_params.find(canAtomicNum);
569  if (res1 != d_params.end()) {
570  res2 = ((*res1).second).find(canNbrAtomicNum);
571  if (res2 != ((*res1).second).end()) {
572  mmffBndkParams = &((*res2).second);
573  }
574  }
575 #else
576  std::pair<std::vector<boost::uint8_t>::const_iterator,
577  std::vector<boost::uint8_t>::const_iterator> bounds;
578  bounds = std::equal_range(d_iAtomicNum.begin(), d_iAtomicNum.end(),
579  canAtomicNum);
580  if (bounds.first != bounds.second) {
581  bounds = std::equal_range(
582  d_jAtomicNum.begin() + (bounds.first - d_iAtomicNum.begin()),
583  d_jAtomicNum.begin() + (bounds.second - d_iAtomicNum.begin()),
584  canNbrAtomicNum);
585  if (bounds.first != bounds.second) {
586  mmffBndkParams = &d_params[bounds.first - d_jAtomicNum.begin()];
587  }
588  }
589 #endif
590 
591  return mmffBndkParams;
592  }
593 
594  private:
595  //! to force this to be a singleton, the constructor must be private
596  MMFFBndkCollection(std::string mmffBndk);
597  static class MMFFBndkCollection *ds_instance; //!< the singleton
598 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
599  std::map<const unsigned int, std::map<const unsigned int, MMFFBond> >
600  d_params; //!< the parameter 2D-map
601 #else
602  std::vector<MMFFBond> d_params; //!< the parameter vector
603  std::vector<boost::uint8_t> d_iAtomicNum; //! atomic number vector for atom i
604  std::vector<boost::uint8_t> d_jAtomicNum; //! atomic number vector for atom j
605 #endif
606 };
607 
609  public:
610  //! gets a pointer to the singleton MMFFHerschbachLaurieCollection
611  /*!
612  \param mmffHerschbachLaurie (optional) a string with parameter data. See
613  below for more information about this argument
614 
615  \return a pointer to the singleton MMFFHerschbachLaurieCollection
616 
617  <b>Notes:</b>
618  - do <b>not</b> delete the pointer returned here
619  - if the singleton MMFFHerschbachLaurieCollection has already been
620  instantiated and
621  \c mmffHerschbachLaurie is empty, the singleton will be returned.
622  - if \c mmffHerschbachLaurie is empty and the singleton
623  MMFFHerschbachLaurieCollection has
624  not yet been instantiated, the default parameters (from Params.cpp)
625  will be used.
626  - if \c mmffHerschbachLaurie is supplied, a new singleton will be
627  instantiated.
628  The current instantiation (if there is one) will be deleted.
629  */
630  static MMFFHerschbachLaurieCollection *getMMFFHerschbachLaurie(
631  const std::string &mmffHerschbachLaurie = "");
632  //! Looks up the parameters for a particular key and returns them.
633  /*!
634  \return a pointer to the MMFFHerschbachLaurie object, NULL on failure.
635  */
636  const MMFFHerschbachLaurie *operator()(const int iRow, const int jRow) {
637  const MMFFHerschbachLaurie *mmffHerschbachLaurieParams = NULL;
638  unsigned int canIRow = iRow;
639  unsigned int canJRow = jRow;
640  if (iRow > jRow) {
641  canIRow = jRow;
642  canJRow = iRow;
643  }
644 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
645  std::map<const unsigned int,
646  std::map<const unsigned int,
647  MMFFHerschbachLaurie> >::const_iterator res1;
648  std::map<const unsigned int, MMFFHerschbachLaurie>::const_iterator res2;
649  res1 = d_params.find(canIRow);
650  if (res1 != d_params.end()) {
651  res2 = ((*res1).second).find(canJRow);
652  if (res2 != ((*res1).second).end()) {
653  mmffHerschbachLaurieParams = &((*res2).second);
654  }
655  }
656 #else
657  std::pair<std::vector<boost::uint8_t>::const_iterator,
658  std::vector<boost::uint8_t>::const_iterator> bounds;
659  bounds = std::equal_range(d_iRow.begin(), d_iRow.end(), canIRow);
660  if (bounds.first != bounds.second) {
661  bounds = std::equal_range(
662  d_jRow.begin() + (bounds.first - d_iRow.begin()),
663  d_jRow.begin() + (bounds.second - d_iRow.begin()), canJRow);
664  if (bounds.first != bounds.second) {
665  mmffHerschbachLaurieParams = &d_params[bounds.first - d_jRow.begin()];
666  }
667  }
668 #endif
669 
670  return mmffHerschbachLaurieParams;
671  }
672 
673  private:
674  //! to force this to be a singleton, the constructor must be private
675  MMFFHerschbachLaurieCollection(std::string mmffHerschbachLaurie);
676  static class MMFFHerschbachLaurieCollection *ds_instance; //!< the singleton
677 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
678  std::map<const unsigned int,
679  std::map<const unsigned int, MMFFHerschbachLaurie> >
680  d_params; //!< the parameter 2D-map
681 #else
682  std::vector<MMFFHerschbachLaurie> d_params; //!< the parameter vector
683  std::vector<boost::uint8_t> d_iRow; //! periodic row number vector for atom i
684  std::vector<boost::uint8_t> d_jRow; //! periodic row number vector for atom j
685 #endif
686 };
687 
689  public:
690  //! gets a pointer to the singleton MMFFCovRadPauEleCollection
691  /*!
692  \param mmffCovRadPauEle (optional) a string with parameter data. See
693  below for more information about this argument
694 
695  \return a pointer to the singleton MMFFCovRadPauEleCollection
696 
697  <b>Notes:</b>
698  - do <b>not</b> delete the pointer returned here
699  - if the singleton MMFFCovRadPauEleCollection has already been
700  instantiated and
701  \c mmffCovRadPauEle is empty, the singleton will be returned.
702  - if \c mmffCovRadPauEle is empty and the singleton
703  MMFFCovRadPauEleCollection has
704  not yet been instantiated, the default parameters (from Params.cpp)
705  will be used.
706  - if \c mmffCovRadPauEle is supplied, a new singleton will be
707  instantiated.
708  The current instantiation (if there is one) will be deleted.
709  */
710  static MMFFCovRadPauEleCollection *getMMFFCovRadPauEle(
711  const std::string &mmffCovRadPauEle = "");
712  //! Looks up the parameters for a particular key and returns them.
713  /*!
714  \return a pointer to the MMFFCovRadPauEle object, NULL on failure.
715  */
716  const MMFFCovRadPauEle *operator()(const unsigned int atomicNum) const {
717 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
718  std::map<const unsigned int, MMFFCovRadPauEle>::const_iterator res;
719  res = d_params.find(atomicNum);
720 
721  return ((res != d_params.end()) ? &((*res).second) : NULL);
722 #else
723  std::pair<std::vector<boost::uint8_t>::const_iterator,
724  std::vector<boost::uint8_t>::const_iterator> bounds =
725  std::equal_range(d_atomicNum.begin(), d_atomicNum.end(), atomicNum);
726 
727  return ((bounds.first != bounds.second)
728  ? &d_params[bounds.first - d_atomicNum.begin()]
729  : NULL);
730 #endif
731  }
732 
733  private:
734  //! to force this to be a singleton, the constructor must be private
735  MMFFCovRadPauEleCollection(std::string mmffCovRadPauEle);
736  static class MMFFCovRadPauEleCollection *ds_instance; //!< the singleton
737 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
738  std::map<const unsigned int, MMFFCovRadPauEle>
739  d_params; //!< the parameter map
740 #else
741  std::vector<MMFFCovRadPauEle> d_params; //!< the parameter vector
742  std::vector<boost::uint8_t> d_atomicNum; //!< the atomic number vector
743 #endif
744 };
745 
747  public:
748  //! gets a pointer to the singleton MMFFAngleCollection
749  /*!
750  \param mmffAngle (optional) a string with parameter data. See
751  below for more information about this argument
752 
753  \return a pointer to the singleton MMFFAngleCollection
754 
755  <b>Notes:</b>
756  - do <b>not</b> delete the pointer returned here
757  - if the singleton MMFFAngleCollection has already been instantiated and
758  \c mmffAngle is empty, the singleton will be returned.
759  - if \c mmffAngle is empty and the singleton MMFFAngleCollection has
760  not yet been instantiated, the default parameters (from Params.cpp)
761  will be used.
762  - if \c mmffAngle is supplied, a new singleton will be instantiated.
763  The current instantiation (if there is one) will be deleted.
764  */
765  static MMFFAngleCollection *getMMFFAngle(const std::string &mmffAngle = "");
766  //! Looks up the parameters for a particular key and returns them.
767  /*!
768  \return a pointer to the MMFFAngle object, NULL on failure.
769  */
770  const MMFFAngle *operator()(const unsigned int angleType,
771  const unsigned int iAtomType,
772  const unsigned int jAtomType,
773  const unsigned int kAtomType) {
775  const MMFFAngle *mmffAngleParams = NULL;
776  unsigned int iter = 0;
777 
778 // For bending of the i-j-k angle, a five-stage process based
779 // in the level combinations 1-1-1,2-2-2,3-2-3,4-2-4, and
780 // 5-2-5 is used. (MMFF.I, note 68, page 519)
781 // We skip 1-1-1 since Level 2 === Level 1
782 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
783  std::map<const unsigned int,
784  std::map<const unsigned int,
785  std::map<const unsigned int,
786  std::map<const unsigned int, MMFFAngle> > > >::
787  const_iterator res1;
788  std::map<const unsigned int,
789  std::map<const unsigned int,
790  std::map<const unsigned int, MMFFAngle> > >::
791  const_iterator res2;
792  std::map<const unsigned int,
793  std::map<const unsigned int, MMFFAngle> >::const_iterator res3;
794  std::map<const unsigned int, MMFFAngle>::const_iterator res4;
795  while ((iter < 4) && (!mmffAngleParams)) {
796  unsigned int canIAtomType = (*mmffDef)(iAtomType)->eqLevel[iter];
797  unsigned int canKAtomType = (*mmffDef)(kAtomType)->eqLevel[iter];
798  if (canIAtomType > canKAtomType) {
799  unsigned int temp = canKAtomType;
800  canKAtomType = canIAtomType;
801  canIAtomType = temp;
802  }
803  res1 = d_params.find(angleType);
804  if (res1 != d_params.end()) {
805  res2 = ((*res1).second).find(canIAtomType);
806  if (res2 != ((*res1).second).end()) {
807  res3 = ((*res2).second).find(jAtomType);
808  if (res3 != ((*res2).second).end()) {
809  res4 = ((*res3).second).find(canKAtomType);
810  if (res4 != ((*res3).second).end()) {
811  mmffAngleParams = &((*res4).second);
812  }
813  }
814  }
815  }
816  ++iter;
817  }
818 #else
819  std::pair<std::vector<boost::uint8_t>::const_iterator,
820  std::vector<boost::uint8_t>::const_iterator> jBounds =
821  std::equal_range(d_jAtomType.begin(), d_jAtomType.end(), jAtomType);
822  std::pair<std::vector<boost::uint8_t>::const_iterator,
823  std::vector<boost::uint8_t>::const_iterator> bounds;
824  if (jBounds.first != jBounds.second) {
825  while ((iter < 4) && (!mmffAngleParams)) {
826  unsigned int canIAtomType = (*mmffDef)(iAtomType)->eqLevel[iter];
827  unsigned int canKAtomType = (*mmffDef)(kAtomType)->eqLevel[iter];
828  if (canIAtomType > canKAtomType) {
829  unsigned int temp = canKAtomType;
830  canKAtomType = canIAtomType;
831  canIAtomType = temp;
832  }
833  bounds = std::equal_range(
834  d_iAtomType.begin() + (jBounds.first - d_jAtomType.begin()),
835  d_iAtomType.begin() + (jBounds.second - d_jAtomType.begin()),
836  canIAtomType);
837  if (bounds.first != bounds.second) {
838  bounds = std::equal_range(
839  d_kAtomType.begin() + (bounds.first - d_iAtomType.begin()),
840  d_kAtomType.begin() + (bounds.second - d_iAtomType.begin()),
841  canKAtomType);
842  if (bounds.first != bounds.second) {
843  bounds = std::equal_range(
844  d_angleType.begin() + (bounds.first - d_kAtomType.begin()),
845  d_angleType.begin() + (bounds.second - d_kAtomType.begin()),
846  angleType);
847  if (bounds.first != bounds.second) {
848  mmffAngleParams = &d_params[bounds.first - d_angleType.begin()];
849  }
850  }
851  }
852  ++iter;
853  }
854  }
855 #endif
856 
857  return mmffAngleParams;
858  }
859 
860  private:
861  //! to force this to be a singleton, the constructor must be private
862  MMFFAngleCollection(std::string mmffAngle);
863  static class MMFFAngleCollection *ds_instance; //!< the singleton
864 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
865  std::map<const unsigned int,
866  std::map<const unsigned int,
867  std::map<const unsigned int,
868  std::map<const unsigned int, MMFFAngle> > > >
869  d_params; //!< the parameter 4D-map
870 #else
871  std::vector<MMFFAngle> d_params; //!< the parameter vector
872  std::vector<boost::uint8_t> d_iAtomType; //! atom type vector for atom i
873  std::vector<boost::uint8_t> d_jAtomType; //! atom type vector for atom j
874  std::vector<boost::uint8_t> d_kAtomType; //! atom type vector for atom k
875  std::vector<boost::uint8_t>
876  d_angleType; //! angle type vector for angle i-j-k
877 #endif
878 };
879 
881  public:
882  //! gets a pointer to the singleton MMFFStbnCollection
883  /*!
884  \param mmffStbn (optional) a string with parameter data. See
885  below for more information about this argument
886 
887  \return a pointer to the singleton MMFFStbnCollection
888 
889  <b>Notes:</b>
890  - do <b>not</b> delete the pointer returned here
891  - if the singleton MMFFStbnCollection has already been instantiated and
892  \c mmffStbn is empty, the singleton will be returned.
893  - if \c mmffStbn is empty and the singleton MMFFStbnCollection has
894  not yet been instantiated, the default parameters (from Params.cpp)
895  will be used.
896  - if \c mmffStbn is supplied, a new singleton will be instantiated.
897  The current instantiation (if there is one) will be deleted.
898  */
899  static MMFFStbnCollection *getMMFFStbn(const std::string &mmffStbn = "");
900  //! Looks up the parameters for a particular key and returns them.
901  /*!
902  \return a pointer to the MMFFStbn object, NULL on failure.
903  */
904  const std::pair<bool, const MMFFStbn *> getMMFFStbnParams(
905  const unsigned int stretchBendType, const unsigned int bondType1,
906  const unsigned int bondType2, const unsigned int iAtomType,
907  const unsigned int jAtomType, const unsigned int kAtomType) {
908  const MMFFStbn *mmffStbnParams = NULL;
909  bool swap = false;
910  unsigned int canIAtomType = iAtomType;
911  unsigned int canKAtomType = kAtomType;
912  unsigned int canStretchBendType = stretchBendType;
913  if (iAtomType > kAtomType) {
914  canIAtomType = kAtomType;
915  canKAtomType = iAtomType;
916  swap = true;
917  } else if (iAtomType == kAtomType) {
918  swap = (bondType1 < bondType2);
919  }
920 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
921  std::map<const unsigned int,
922  std::map<const unsigned int,
923  std::map<const unsigned int,
924  std::map<const unsigned int, MMFFStbn> > > >::
925  const_iterator res1;
926  std::map<const unsigned int,
927  std::map<const unsigned int,
928  std::map<const unsigned int, MMFFStbn> > >::const_iterator
929  res2;
930  std::map<const unsigned int,
931  std::map<const unsigned int, MMFFStbn> >::const_iterator res3;
932  std::map<const unsigned int, MMFFStbn>::const_iterator res4;
933  res1 = d_params.find(canStretchBendType);
934  if (res1 != d_params.end()) {
935  res2 = ((*res1).second).find(canIAtomType);
936  if (res2 != ((*res1).second).end()) {
937  res3 = ((*res2).second).find(jAtomType);
938  if (res3 != ((*res2).second).end()) {
939  res4 = ((*res3).second).find(canKAtomType);
940  if (res4 != ((*res3).second).end()) {
941  mmffStbnParams = &((*res4).second);
942  }
943  }
944  }
945  }
946 #else
947  std::pair<std::vector<boost::uint8_t>::const_iterator,
948  std::vector<boost::uint8_t>::const_iterator> jBounds =
949  std::equal_range(d_jAtomType.begin(), d_jAtomType.end(), jAtomType);
950  std::pair<std::vector<boost::uint8_t>::const_iterator,
951  std::vector<boost::uint8_t>::const_iterator> bounds;
952  if (jBounds.first != jBounds.second) {
953  bounds = std::equal_range(
954  d_iAtomType.begin() + (jBounds.first - d_jAtomType.begin()),
955  d_iAtomType.begin() + (jBounds.second - d_jAtomType.begin()),
956  canIAtomType);
957  if (bounds.first != bounds.second) {
958  bounds = std::equal_range(
959  d_kAtomType.begin() + (bounds.first - d_iAtomType.begin()),
960  d_kAtomType.begin() + (bounds.second - d_iAtomType.begin()),
961  canKAtomType);
962  if (bounds.first != bounds.second) {
963  bounds = std::equal_range(
964  d_stretchBendType.begin() + (bounds.first - d_kAtomType.begin()),
965  d_stretchBendType.begin() + (bounds.second - d_kAtomType.begin()),
966  canStretchBendType);
967  if (bounds.first != bounds.second) {
968  mmffStbnParams =
969  &d_params[bounds.first - d_stretchBendType.begin()];
970  }
971  }
972  }
973  }
974 #endif
975 
976  return std::make_pair(swap, mmffStbnParams);
977  }
978 
979  private:
980  //! to force this to be a singleton, the constructor must be private
981  MMFFStbnCollection(std::string mmffStbn);
982  static class MMFFStbnCollection *ds_instance; //!< the singleton
983 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
984  std::map<const unsigned int,
985  std::map<const unsigned int,
986  std::map<const unsigned int,
987  std::map<const unsigned int, MMFFStbn> > > >
988  d_params; //!< the parameter 4D-map
989 #else
990  std::vector<MMFFStbn> d_params; //!< the parameter vector
991  std::vector<boost::uint8_t> d_iAtomType; //! atom type vector for atom i
992  std::vector<boost::uint8_t> d_jAtomType; //! atom type vector for atom j
993  std::vector<boost::uint8_t> d_kAtomType; //! atom type vector for atom k
994  std::vector<boost::uint8_t>
995  d_stretchBendType; //! stretch-bend type vector for angle i-j-k
996 #endif
997 };
998 
1000  public:
1001  //! gets a pointer to the singleton MMFFDfsbCollection
1002  /*!
1003  \param mmffDfsb (optional) a string with parameter data. See
1004  below for more information about this argument
1005 
1006  \return a pointer to the singleton MMFFDfsbCollection
1007 
1008  <b>Notes:</b>
1009  - do <b>not</b> delete the pointer returned here
1010  - if the singleton MMFFDfsbCollection has already been instantiated and
1011  \c mmffDfsb is empty, the singleton will be returned.
1012  - if \c mmffDfsb is empty and the singleton MMFFDfsbCollection has
1013  not yet been instantiated, the default parameters (from Params.cpp)
1014  will be used.
1015  - if \c mmffDfsb is supplied, a new singleton will be instantiated.
1016  The current instantiation (if there is one) will be deleted.
1017  */
1018  static MMFFDfsbCollection *getMMFFDfsb(const std::string &mmffDfsb = "");
1019  //! Looks up the parameters for a particular key and returns them.
1020  /*!
1021  \return a pointer to the MMFFStbn object, NULL on failure.
1022  */
1023  const std::pair<bool, const MMFFStbn *> getMMFFDfsbParams(
1024  const unsigned int periodicTableRow1,
1025  const unsigned int periodicTableRow2,
1026  const unsigned int periodicTableRow3) {
1027  std::map<const unsigned int,
1028  std::map<const unsigned int,
1029  std::map<const unsigned int, MMFFStbn> > >::const_iterator
1030  res1;
1031  std::map<const unsigned int,
1032  std::map<const unsigned int, MMFFStbn> >::const_iterator res2;
1033  std::map<const unsigned int, MMFFStbn>::const_iterator res3;
1034  const MMFFStbn *mmffDfsbParams = NULL;
1035  bool swap = false;
1036  unsigned int canPeriodicTableRow1 = periodicTableRow1;
1037  unsigned int canPeriodicTableRow3 = periodicTableRow3;
1038  if (periodicTableRow1 > periodicTableRow3) {
1039  canPeriodicTableRow1 = periodicTableRow3;
1040  canPeriodicTableRow3 = periodicTableRow1;
1041  swap = true;
1042  }
1043  res1 = d_params.find(canPeriodicTableRow1);
1044  if (res1 != d_params.end()) {
1045  res2 = ((*res1).second).find(periodicTableRow2);
1046  if (res2 != ((*res1).second).end()) {
1047  res3 = ((*res2).second).find(canPeriodicTableRow3);
1048  if (res3 != ((*res2).second).end()) {
1049  mmffDfsbParams = &((*res3).second);
1050  }
1051  }
1052  }
1053 
1054  return std::make_pair(swap, mmffDfsbParams);
1055  }
1056 
1057  private:
1058  //! to force this to be a singleton, the constructor must be private
1059  MMFFDfsbCollection(std::string mmffDfsb);
1060  static class MMFFDfsbCollection *ds_instance; //!< the singleton
1061  std::map<
1062  const unsigned int,
1063  std::map<const unsigned int, std::map<const unsigned int, MMFFStbn> > >
1064  d_params; //!< the parameter 3D-map
1065 };
1066 
1068  public:
1069  //! gets a pointer to the singleton MMFFOopCollection
1070  /*!
1071  \param mmffOop (optional) a string with parameter data. See
1072  below for more information about this argument
1073 
1074  \return a pointer to the singleton MMFFOopCollection
1075 
1076  <b>Notes:</b>
1077  - do <b>not</b> delete the pointer returned here
1078  - if the singleton MMFFOopCollection has already been instantiated and
1079  \c mmffOop is empty, the singleton will be returned.
1080  - if \c mmffOop is empty and the singleton MMFFOopCollection has
1081  not yet been instantiated, the default parameters (from Params.cpp)
1082  will be used.
1083  - if \c mmffOop is supplied, a new singleton will be instantiated.
1084  The current instantiation (if there is one) will be deleted.
1085  */
1086  static MMFFOopCollection *getMMFFOop(const bool isMMFFs = false,
1087  const std::string &mmffOop = "");
1088  //! Looks up the parameters for a particular key and returns them.
1089  /*!
1090  \return a pointer to the MMFFOop object, NULL on failure.
1091  */
1092  const MMFFOop *operator()(const unsigned int iAtomType,
1093  const unsigned int jAtomType,
1094  const unsigned int kAtomType,
1095  const unsigned int lAtomType) {
1097  const MMFFOop *mmffOopParams = NULL;
1098  unsigned int iter = 0;
1099  std::vector<unsigned int> canIKLAtomType(3);
1100 // For out-of-plane bending ijk; I , where j is the central
1101 // atom [cf. eq. (511, the five-stage protocol 1-1-1; 1, 2-2-2; 2,
1102 // 3-2-3;3, 4-2-4;4, 5-2-5;5 is used. The final stage provides
1103 // wild-card defaults for all except the central atom.
1104 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1105  std::map<const unsigned int,
1106  std::map<const unsigned int,
1107  std::map<const unsigned int,
1108  std::map<const unsigned int, MMFFOop> > > >::
1109  const_iterator res1;
1110  std::map<const unsigned int,
1111  std::map<const unsigned int,
1112  std::map<const unsigned int, MMFFOop> > >::const_iterator
1113  res2;
1114  std::map<const unsigned int,
1115  std::map<const unsigned int, MMFFOop> >::const_iterator res3;
1116  std::map<const unsigned int, MMFFOop>::const_iterator res4;
1117  while ((iter < 4) && (!mmffOopParams)) {
1118  canIKLAtomType[0] = (*mmffDef)(iAtomType)->eqLevel[iter];
1119  unsigned int canJAtomType = jAtomType;
1120  canIKLAtomType[1] = (*mmffDef)(kAtomType)->eqLevel[iter];
1121  canIKLAtomType[2] = (*mmffDef)(lAtomType)->eqLevel[iter];
1122  std::sort(canIKLAtomType.begin(), canIKLAtomType.end());
1123  res1 = d_params.find(canIKLAtomType[0]);
1124  if (res1 != d_params.end()) {
1125  res2 = ((*res1).second).find(canJAtomType);
1126  if (res2 != ((*res1).second).end()) {
1127  res3 = ((*res2).second).find(canIKLAtomType[1]);
1128  if (res3 != ((*res2).second).end()) {
1129  res4 = ((*res3).second).find(canIKLAtomType[2]);
1130  if (res4 != ((*res3).second).end()) {
1131  mmffOopParams = &((*res4).second);
1132  }
1133  }
1134  }
1135  }
1136  ++iter;
1137  }
1138 #else
1139  std::pair<std::vector<boost::uint8_t>::const_iterator,
1140  std::vector<boost::uint8_t>::const_iterator> jBounds =
1141  std::equal_range(d_jAtomType.begin(), d_jAtomType.end(), jAtomType);
1142  std::pair<std::vector<boost::uint8_t>::const_iterator,
1143  std::vector<boost::uint8_t>::const_iterator> bounds;
1144  if (jBounds.first != jBounds.second) {
1145  while ((iter < 4) && (!mmffOopParams)) {
1146  canIKLAtomType[0] = (*mmffDef)(iAtomType)->eqLevel[iter];
1147  canIKLAtomType[1] = (*mmffDef)(kAtomType)->eqLevel[iter];
1148  canIKLAtomType[2] = (*mmffDef)(lAtomType)->eqLevel[iter];
1149  std::sort(canIKLAtomType.begin(), canIKLAtomType.end());
1150  bounds = std::equal_range(
1151  d_iAtomType.begin() + (jBounds.first - d_jAtomType.begin()),
1152  d_iAtomType.begin() + (jBounds.second - d_jAtomType.begin()),
1153  canIKLAtomType[0]);
1154  if (bounds.first != bounds.second) {
1155  bounds = std::equal_range(
1156  d_kAtomType.begin() + (bounds.first - d_iAtomType.begin()),
1157  d_kAtomType.begin() + (bounds.second - d_iAtomType.begin()),
1158  canIKLAtomType[1]);
1159  if (bounds.first != bounds.second) {
1160  bounds = std::equal_range(
1161  d_lAtomType.begin() + (bounds.first - d_kAtomType.begin()),
1162  d_lAtomType.begin() + (bounds.second - d_kAtomType.begin()),
1163  canIKLAtomType[2]);
1164  if (bounds.first != bounds.second) {
1165  mmffOopParams = &d_params[bounds.first - d_lAtomType.begin()];
1166  }
1167  }
1168  }
1169  ++iter;
1170  }
1171  }
1172 #endif
1173 
1174  return mmffOopParams;
1175  }
1176 
1177  private:
1178  //! to force this to be a singleton, the constructor must be private
1179  MMFFOopCollection(const bool isMMFFs, std::string mmffOop);
1180  static class MMFFOopCollection *ds_instance[2]; //!< the singleton
1181 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1182  std::map<const unsigned int,
1183  std::map<const unsigned int,
1184  std::map<const unsigned int,
1185  std::map<const unsigned int, MMFFOop> > > >
1186  d_params; //!< the parameter 4D-map
1187 #else
1188  std::vector<MMFFOop> d_params; //!< the parameter vector
1189  std::vector<boost::uint8_t> d_iAtomType; //! atom type vector for atom i
1190  std::vector<boost::uint8_t> d_jAtomType; //! atom type vector for atom j
1191  std::vector<boost::uint8_t> d_kAtomType; //! atom type vector for atom k
1192  std::vector<boost::uint8_t> d_lAtomType; //! atom type vector for atom l
1193 #endif
1194 };
1195 
1197  public:
1198  //! gets a pointer to the singleton MMFFTorCollection
1199  /*!
1200  \param mmffTor (optional) a string with parameter data. See
1201  below for more information about this argument
1202 
1203  \return a pointer to the singleton MMFFTorCollection
1204 
1205  <b>Notes:</b>
1206  - do <b>not</b> delete the pointer returned here
1207  - if the singleton MMFFTorCollection has already been instantiated and
1208  \c mmffTor is empty, the singleton will be returned.
1209  - if \c mmffTor is empty and the singleton MMFFTorCollection has
1210  not yet been instantiated, the default parameters (from Params.cpp)
1211  will be used.
1212  - if \c mmffTor is supplied, a new singleton will be instantiated.
1213  The current instantiation (if there is one) will be deleted.
1214  */
1215  static MMFFTorCollection *getMMFFTor(const bool isMMFFs,
1216  const std::string &mmffTor = "");
1217  //! Looks up the parameters for a particular key and returns them.
1218  /*!
1219  \return a pointer to the MMFFTor object, NULL on failure.
1220  */
1221  const std::pair<const unsigned int, const MMFFTor *> getMMFFTorParams(
1222  const std::pair<unsigned int, unsigned int> torType,
1223  const unsigned int iAtomType, const unsigned int jAtomType,
1224  const unsigned int kAtomType, const unsigned int lAtomType) {
1226  const MMFFTor *mmffTorParams = NULL;
1227  unsigned int iter = 0;
1228  unsigned int iWildCard = 0;
1229  unsigned int lWildCard = 0;
1230  unsigned int canTorType = torType.first;
1231  unsigned int maxIter = 5;
1232 // For i-j-k-2 torsion interactions, a five-stage
1233 // process based on level combinations 1-1-1-1, 2-2-2-2,
1234 // 3-2-2-5, 5-2-2-3, and 5-2-2-5 is used, where stages 3
1235 // and 4 correspond to "half-default" or "half-wild-card" entries.
1236 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1237  std::map<
1238  const unsigned int,
1239  std::map<
1240  const unsigned int,
1241  std::map<const unsigned int,
1242  std::map<const unsigned int,
1243  std::map<const unsigned int, MMFFTor> > > > >::
1244  const_iterator res1;
1245  std::map<const unsigned int,
1246  std::map<const unsigned int,
1247  std::map<const unsigned int,
1248  std::map<const unsigned int, MMFFTor> > > >::
1249  const_iterator res2;
1250  std::map<const unsigned int,
1251  std::map<const unsigned int,
1252  std::map<const unsigned int, MMFFTor> > >::const_iterator
1253  res3;
1254  std::map<const unsigned int,
1255  std::map<const unsigned int, MMFFTor> >::const_iterator res4;
1256  std::map<const unsigned int, MMFFTor>::const_iterator res5;
1257 #else
1258  std::pair<std::vector<boost::uint8_t>::const_iterator,
1259  std::vector<boost::uint8_t>::const_iterator> jBounds;
1260  std::pair<std::vector<boost::uint8_t>::const_iterator,
1261  std::vector<boost::uint8_t>::const_iterator> bounds;
1262 #endif
1263 
1264  while (((iter < maxIter) && ((!mmffTorParams) || (maxIter == 4))) ||
1265  ((iter == 4) && (torType.first == 5) && torType.second)) {
1266  // The rule of setting the torsion type to the value it had
1267  // before being set to 5 as a last resort in case parameters
1268  // could not be found is not mentioned in MMFF.IV; it was
1269  // empirically discovered due to a number of tests in the
1270  // MMFF validation suite otherwise failing
1271  if ((maxIter == 5) && (iter == 4)) {
1272  maxIter = 4;
1273  iter = 0;
1274  canTorType = torType.second;
1275  }
1276  iWildCard = iter;
1277  lWildCard = iter;
1278  if (iter == 1) {
1279  iWildCard = 1;
1280  lWildCard = 3;
1281  } else if (iter == 2) {
1282  iWildCard = 3;
1283  lWildCard = 1;
1284  }
1285  unsigned int canIAtomType = (*mmffDef)(iAtomType)->eqLevel[iWildCard];
1286  unsigned int canJAtomType = jAtomType;
1287  unsigned int canKAtomType = kAtomType;
1288  unsigned int canLAtomType = (*mmffDef)(lAtomType)->eqLevel[lWildCard];
1289  if (canJAtomType > canKAtomType) {
1290  unsigned int temp = canKAtomType;
1291  canKAtomType = canJAtomType;
1292  canJAtomType = temp;
1293  temp = canLAtomType;
1294  canLAtomType = canIAtomType;
1295  canIAtomType = temp;
1296  } else if ((canJAtomType == canKAtomType) &&
1297  (canIAtomType > canLAtomType)) {
1298  unsigned int temp = canLAtomType;
1299  canLAtomType = canIAtomType;
1300  canIAtomType = temp;
1301  }
1302 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1303  res1 = d_params.find(canTorType);
1304  if (res1 != d_params.end()) {
1305  res2 = ((*res1).second).find(canIAtomType);
1306  if (res2 != ((*res1).second).end()) {
1307  res3 = ((*res2).second).find(canJAtomType);
1308  if (res3 != ((*res2).second).end()) {
1309  res4 = ((*res3).second).find(canKAtomType);
1310  if (res4 != ((*res3).second).end()) {
1311  res5 = ((*res4).second).find(canLAtomType);
1312  if (res5 != ((*res4).second).end()) {
1313  mmffTorParams = &((*res5).second);
1314  if (maxIter == 4) {
1315  break;
1316  }
1317  }
1318  }
1319  }
1320  }
1321  }
1322 #else
1323  jBounds = std::equal_range(d_jAtomType.begin(), d_jAtomType.end(),
1324  canJAtomType);
1325  if (jBounds.first != jBounds.second) {
1326  bounds = std::equal_range(
1327  d_kAtomType.begin() + (jBounds.first - d_jAtomType.begin()),
1328  d_kAtomType.begin() + (jBounds.second - d_jAtomType.begin()),
1329  canKAtomType);
1330  if (bounds.first != bounds.second) {
1331  bounds = std::equal_range(
1332  d_iAtomType.begin() + (bounds.first - d_kAtomType.begin()),
1333  d_iAtomType.begin() + (bounds.second - d_kAtomType.begin()),
1334  canIAtomType);
1335  if (bounds.first != bounds.second) {
1336  bounds = std::equal_range(
1337  d_lAtomType.begin() + (bounds.first - d_iAtomType.begin()),
1338  d_lAtomType.begin() + (bounds.second - d_iAtomType.begin()),
1339  canLAtomType);
1340  if (bounds.first != bounds.second) {
1341  bounds = std::equal_range(
1342  d_torType.begin() + (bounds.first - d_lAtomType.begin()),
1343  d_torType.begin() + (bounds.second - d_lAtomType.begin()),
1344  canTorType);
1345  if (bounds.first != bounds.second) {
1346  mmffTorParams = &d_params[bounds.first - d_torType.begin()];
1347  if (maxIter == 4) {
1348  break;
1349  }
1350  }
1351  }
1352  }
1353  }
1354  }
1355 #endif
1356  ++iter;
1357  }
1358 
1359  return std::make_pair(canTorType, mmffTorParams);
1360  }
1361 
1362  private:
1363  //! to force this to be a singleton, the constructor must be private
1364  MMFFTorCollection(const bool isMMFFs, std::string mmffTor);
1365  static class MMFFTorCollection *ds_instance[2]; //!< the singleton
1366 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1367  std::map<const unsigned int,
1368  std::map<const unsigned int,
1369  std::map<const unsigned int,
1370  std::map<const unsigned int,
1371  std::map<const unsigned int,
1372  MMFFTor> > > > >
1373  d_params; //!< the parameter 5D-map
1374 #else
1375  std::vector<MMFFTor> d_params; //!< the parameter vector
1376  std::vector<boost::uint8_t> d_iAtomType; //! atom type vector for atom i
1377  std::vector<boost::uint8_t> d_jAtomType; //! atom type vector for atom j
1378  std::vector<boost::uint8_t> d_kAtomType; //! atom type vector for atom k
1379  std::vector<boost::uint8_t> d_lAtomType; //! atom type vector for atom l
1380  std::vector<boost::uint8_t>
1381  d_torType; //! torsion type vector for angle i-j-k-l
1382 #endif
1383 };
1384 
1386  public:
1387  //! gets a pointer to the singleton MMFFVdWCollection
1388  /*!
1389  \param mmffVdW (optional) a string with parameter data. See
1390  below for more information about this argument
1391 
1392  \return a pointer to the singleton MMFFVdWCollection
1393 
1394  <b>Notes:</b>
1395  - do <b>not</b> delete the pointer returned here
1396  - if the singleton MMFFVdWCollection has already been instantiated and
1397  \c mmffVdW is empty, the singleton will be returned.
1398  - if \c mmffVdW is empty and the singleton MMFFVdWCollection has
1399  not yet been instantiated, the default parameters (from Params.cpp)
1400  will be used.
1401  - if \c mmffVdW is supplied, a new singleton will be instantiated.
1402  The current instantiation (if there is one) will be deleted.
1403  */
1404  double power;
1405  double B;
1406  double Beta;
1407  double DARAD;
1408  double DAEPS;
1409  static MMFFVdWCollection *getMMFFVdW(const std::string &mmffVdW = "");
1410  //! Looks up the parameters for a particular key and returns them.
1411  /*!
1412  \return a pointer to the MMFFVdW object, NULL on failure.
1413  */
1414  const MMFFVdW *operator()(const unsigned int atomType) const {
1415 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1416  std::map<const unsigned int, MMFFVdW>::const_iterator res;
1417  res = d_params.find(atomType);
1418 
1419  return (res != d_params.end() ? &((*res).second) : NULL);
1420 #else
1421  std::pair<std::vector<boost::uint8_t>::const_iterator,
1422  std::vector<boost::uint8_t>::const_iterator> bounds =
1423  std::equal_range(d_atomType.begin(), d_atomType.end(), atomType);
1424 
1425  return ((bounds.first != bounds.second)
1426  ? &d_params[bounds.first - d_atomType.begin()]
1427  : NULL);
1428 #endif
1429  }
1430 
1431  private:
1432  //! to force this to be a singleton, the constructor must be private
1433  MMFFVdWCollection(std::string mmffVdW);
1434  static class MMFFVdWCollection *ds_instance; //!< the singleton
1435 #ifdef RDKIT_MMFF_PARAMS_USE_STD_MAP
1436  std::map<const unsigned int, MMFFVdW> d_params; //!< the parameter map
1437 #else
1438  std::vector<MMFFVdW> d_params; //!< the parameter vector
1439  std::vector<boost::uint8_t> d_atomType; //! atom type vector
1440 #endif
1441 };
1442 }
1443 }
1444 
1445 #endif
class to store MMFF parameters for angle bending
Definition: MMFF/Params.h:111
const MMFFCovRadPauEle * operator()(const unsigned int atomicNum) const
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:716
static MMFFDefCollection * getMMFFDef(const std::string &mmffDef="")
gets a pointer to the singleton MMFFDefCollection
bool isDoubleZero(const double x)
Definition: MMFF/Params.h:42
const MMFFVdW * operator()(const unsigned int atomType) const
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:1414
class to store MMFF parameters for non-bonded Van der Waals
Definition: MMFF/Params.h:139
double power
gets a pointer to the singleton MMFFVdWCollection
Definition: MMFF/Params.h:1404
const MMFFHerschbachLaurie * operator()(const int iRow, const int jRow)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:636
const MMFFOop * operator()(const unsigned int iAtomType, const unsigned int jAtomType, const unsigned int kAtomType, const unsigned int lAtomType)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:1092
const MMFFBond * operator()(const int atomicNum, const int nbrAtomicNum)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:556
const std::pair< int, const MMFFChg * > getMMFFChgParams(const unsigned int bondType, const unsigned int iAtomType, const unsigned int jAtomType)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:371
const double MDYNE_A_TO_KCAL_MOL
Definition: MMFF/Params.h:41
#define RDKIT_FORCEFIELD_EXPORT
Definition: export.h:242
bool isMMFFAromatic(const unsigned int atomType) const
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:183
class to store MMFF parameters for stretch-bending
Definition: MMFF/Params.h:118
void clipToOne(double &x)
Definition: MMFF/Params.h:45
class to store MMFF parameters for bond stretching
Definition: MMFF/Params.h:87
const double RAD2DEG
Definition: MMFF/Params.h:40
class to store MMFF parameters for out-of-plane bending
Definition: MMFF/Params.h:125
const MMFFPBCI * operator()(const unsigned int atomType) const
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:323
const std::pair< const unsigned int, const MMFFTor * > getMMFFTorParams(const std::pair< unsigned int, unsigned int > torType, const unsigned int iAtomType, const unsigned int jAtomType, const unsigned int kAtomType, const unsigned int lAtomType)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:1221
const MMFFProp * operator()(const unsigned int atomType) const
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:270
const MMFFBond * operator()(const unsigned int bondType, const unsigned int atomType, const unsigned int nbrAtomType)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:462
const MMFFDef * operator()(const unsigned int atomType) const
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:222
const std::pair< bool, const MMFFStbn * > getMMFFDfsbParams(const unsigned int periodicTableRow1, const unsigned int periodicTableRow2, const unsigned int periodicTableRow3)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:1023
const double DEG2RAD
Definition: MMFF/Params.h:39
const std::pair< bool, const MMFFStbn * > getMMFFStbnParams(const unsigned int stretchBendType, const unsigned int bondType1, const unsigned int bondType2, const unsigned int iAtomType, const unsigned int jAtomType, const unsigned int kAtomType)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:904
class to store MMFF parameters for torsions
Definition: MMFF/Params.h:131
class to store MMFF atom type equivalence levels
Definition: MMFF/Params.h:54
class to store MMFF Partial Bond Charge Increments
Definition: MMFF/Params.h:73
#define M_PI
Definition: MMFF/Params.h:26
const MMFFAngle * operator()(const unsigned int angleType, const unsigned int iAtomType, const unsigned int jAtomType, const unsigned int kAtomType)
Looks up the parameters for a particular key and returns them.
Definition: MMFF/Params.h:770
class to store MMFF Properties
Definition: MMFF/Params.h:60