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