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