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