Coverage Report

Created: 2026-09-04 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openbabel/include/openbabel/obutil.h
Line
Count
Source
1
/**********************************************************************
2
obutil.h - Various utility methods.
3
4
Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5
Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
6
7
This file is part of the Open Babel project.
8
For more information, see <http://openbabel.org/>
9
10
This program is free software; you can redistribute it and/or modify
11
it under the terms of the GNU General Public License as published by
12
the Free Software Foundation version 2 of the License.
13
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
***********************************************************************/
19
20
#ifndef OB_UTIL_H
21
#define OB_UTIL_H
22
23
#include <openbabel/babelconfig.h>
24
25
#include <string>
26
#include <iosfwd>
27
28
#if TIME_WITH_SYS_TIME
29
#include <sys/time.h>
30
#include <time.h>
31
#else
32
#if HAVE_SYS_TIME_H
33
#include <sys/time.h>
34
#else
35
#include <time.h>
36
#endif
37
#endif
38
// Include C++ version for clock() and CLOCKS_PER_SEC (required for GCC 12+ with C++17)
39
#include <ctime>
40
#include <math.h>
41
42
#ifndef M_PI
43
#define M_PI 3.14159265358979323846
44
#endif
45
46
namespace OpenBabel
47
{
48
49
  // class introduction in obutil.cpp
50
  class OBAPI OBStopwatch
51
  {
52
#if HAVE_CLOCK_T
53
    clock_t start; //!< the start of timing
54
    clock_t stop;  //!< the current time
55
#else
56
    timeval start; //!< the start of timing
57
    timeval stop;  //!< the current time
58
#endif
59
60
  public:
61
#if HAVE_CLOCK_T
62
63
    //! Mark the start of "stopwatch" timing
64
    void  Start()
65
0
    {
66
0
      start= clock();
67
0
    }
68
    //! \return The time since calling OBStopwatch::Start() in seconds.
69
    double Lap()
70
0
    {
71
0
      stop= clock();
72
0
      return((stop - start) / (double) CLOCKS_PER_SEC);
73
0
    }
74
#else
75
    //! Mark the start of "stopwatch" timing
76
    void Start()
77
    {
78
      gettimeofday(&start, nullptr);
79
    }
80
    //! \return The time since calling OBStopwatch::Start() in seconds.
81
    double Lap()
82
    {
83
      gettimeofday(&stop, nullptr);
84
      return((stop.tv_sec - start.tv_sec)
85
             + (stop.tv_usec - start.tv_usec)/1000000.0);
86
    }
87
#endif
88
89
    //! \return The time since calling OBStopwatch::Start() in seconds.
90
    double Elapsed()
91
0
    {
92
0
      return(Lap());
93
0
    }
94
  };
95
96
97
  //! \class OBSqrtTbl obutil.h <openbabel/obutil.h>
98
  //! \brief Square Root lookup table - given a distance squared returns distance
99
  class OBAPI OBSqrtTbl
100
  {
101
    double _max,_incr,*_tbl;
102
  public:
103
  OBSqrtTbl():
104
    _max(0.0), _incr(0.0),  _tbl(nullptr)
105
0
      { }
106
    //! \brief Create a square root table to handle up to the square root of @p max
107
    //! (e.g., if you want the square root of 144, supply 12 for max)
108
    //! \param max The maximum square root stored in the lookup table
109
    //! \param incr The floating point resolution of the lookup table
110
  OBSqrtTbl(const double max, const double incr):
111
    _max(max*max), _incr(incr), _tbl(nullptr)
112
0
      {
113
0
        Init(max,incr);
114
0
      }
115
    ~OBSqrtTbl()
116
0
      {
117
0
        if (_tbl)
118
0
          {
119
0
            delete [] _tbl;
120
0
            _tbl = nullptr;
121
0
          }
122
0
      }
123
    //! \brief Fast square root calculation using a lookup table
124
    //! \return Square root of @p d2
125
    double Sqrt(double d2) const
126
0
    {
127
0
      if (_tbl)
128
0
        return((d2 < _max) ? _tbl[static_cast<int>(d2*_incr)]:sqrt(d2));
129
0
      else
130
0
        return 0.0;
131
0
    }
132
    //! \brief Initialize the square root lookup table
133
    //! \param max The maximum square root stored in the lookup table (e.g., if you want the square root of 144, supply 12 for max)
134
    //! \param incr The floating point resolution of the lookup table
135
    void Init(double max,double incr)
136
0
    {
137
0
      // parameters are potentially unneeded, but let's do this until we can
138
0
      // deprecate them
139
0
      _max = max * max;
140
0
      _incr = incr;
141
0
142
0
      //array size needs to be large enough to account for fp error
143
0
      int i;
144
0
      double r;
145
0
      _tbl = new double [static_cast<int>((_max/_incr)+10)];
146
0
      for (r = (_incr/2.0),i=0;r <= _max;r += _incr,++i)
147
0
        _tbl[i] = sqrt(r);
148
0
149
0
      _incr = 1/_incr;
150
0
    }
151
  };
152
153
  //***RMS helper methods***/
154
#ifndef __KCC
155
  extern "C" {
156
  OBAPI void  rotate_coords(double*,double m[3][3],unsigned);
157
  OBAPI double calc_rms(double*,double*,unsigned int);
158
  }
159
#else
160
  OBAPI void  rotate_coords(double*,double m[3][3],unsigned);
161
  OBAPI double calc_rms(double*,double*,unsigned int);
162
#endif
163
164
#ifndef SWIG
165
  //! \name  String conversion utilities
166
  //@{
167
  // Documentation in obutil.cpp
168
  OBAPI void ToUpper(std::string&);
169
  OBAPI void ToUpper(char*);
170
  OBAPI void ToLower(std::string&);
171
  OBAPI void ToLower(char *);
172
  OBAPI void InvertCase(std::string&, int);
173
  OBAPI void InvertCase(char *);
174
  //! "Clean" the supplied atom type
175
  OBAPI void CleanAtomType(char*);
176
  //@}
177
178
  //! Comparison -- returns true if first parameter less than second
179
  //! \return True if @p a < @p b, False otherwise.
180
  OBAPI bool OBCompareInt(const int &a,const int &b);
181
  //! Comparison -- returns true if first parameter less than second
182
  //! \return True if @p a < @p b, False otherwise.
183
  OBAPI bool OBCompareUnsigned(const unsigned int &a,const unsigned int &b);
184
  /*! Absolute-tolerance comparison for floats/doubles: returns fabs(a - b) < epsilon
185
   * Provided for backwards compatibility. For relative-tolerance comparisons,
186
   * see IsApprox(); for absolute checks, prefer an inline std::fabs(a - b) < eps.
187
   * \deprecated Prefer std::fabs(a - b) < eps (absolute) or IsApprox() (relative)
188
   */
189
  OB_DEPRECATED_MSG("Prefer std::fabs(a - b) < eps, or IsApprox() for relative comparisons")
190
  OBAPI bool IsNear(const double &, const double &, const double epsilon=2e-6);
191
  /*! Absolute-tolerance comparison against zero: returns fabs(a) < epsilon
192
   * Provided for backwards compatibility. Prefer an inline std::fabs(a) < eps.
193
   * Note: IsApprox(a, 0.0) is not a valid replacement; the relative
194
   * tolerance collapses to zero when one operand is zero.
195
   * \deprecated Prefer std::fabs(a) < eps
196
   */
197
  OB_DEPRECATED_MSG("Prefer std::fabs(a) < eps")
198
  OBAPI bool IsNearZero(const double &, const double epsilon=2e-6);
199
  OBAPI bool IsNan(const double &);
200
  /**
201
   * \return true if \a a is much smaller than \a b. More precisely:
202
   * @code
203
   return( fabs(a) <= precision * fabs(b) );
204
   * @endcode
205
   */
206
  OBAPI inline bool IsNegligible(const double & a, const double & b,
207
                                 const double precision = 1e-11)
208
0
  {
209
0
    return( fabs(a) <= precision * fabs(b) );
210
0
  }
211
  /*! Safe comparison for floats/doubles: true if
212
   * fabs(a - b) <= precision * std::min( fabs(a), fabs(b) )
213
   * The parameter precision plays the role of 10^-N where N is the number of
214
   * significant digits to consider.
215
   * This is the correct way to replace operator== for doubles. For new code,
216
   * use this function instead of the old IsNear() function.
217
   *
218
   * \note To check
219
   * if x is zero, use
220
   * @code
221
   IsNegligible( x, 1.0)
222
   * @endcode
223
   * instead of
224
   * @code
225
   IsApprox( x, 0.0 )
226
   * @endcode
227
   */
228
  OBAPI inline bool IsApprox(const double & a, const double & b,
229
                             const double precision = 1e-11)
230
0
  {
231
0
    return( fabs(a - b) <= precision * std::min<const double>( fabs(a), fabs(b) ) );
232
0
  }
233
  //! Same as IsApprox(), but only for positive numbers. Faster.
234
  OBAPI inline bool IsApprox_pos(const double &a, const double &b,
235
                                 const double precision = 1e-11)
236
0
  {
237
0
    return( fabs(a - b) <= precision * std::min<const double>( a, b ) );
238
0
  }
239
  /*! \brief Tests whether its argument can be squared without triggering
240
    an overflow or underflow.
241
  */
242
  OBAPI bool CanBeSquared(const double &);
243
244
  OBAPI bool SafeOpen(std::ifstream &fs, const char *filename);
245
  OBAPI bool SafeOpen(std::ofstream &fs, const char *filename);
246
#endif
247
  // (end part to be skipped by SWIG)
248
249
  //******************triple template*************************
250
  //! \class triple obutil.h <openbabel/obutil.h>
251
  //! \brief A 3-element templated, based on the design of the STL pair<>
252
  template <class T1, class T2, class T3>
253
    struct triple
254
    {
255
      //type names for the values
256
      typedef T1 first_type;
257
      typedef T2 second_type;
258
      typedef T3 third_type;
259
260
      //member
261
      T1 first;
262
      T2 second;
263
      T3 third;
264
265
      /** Default constructor
266
       *  T1() and T2() and T3() force initialization for built in types
267
       **/
268
    triple():
269
0
      first(T1()),second(T2()),third(T3())
270
0
      {}
271
272
      //! Constructor for 3 values
273
    triple(const T1 &a, const T2 &b, const T3 &c):
274
0
      first(a), second(b), third(c)
275
0
      {}
276
277
      //! Copy constructor with implicit conversions
278
      template<class U, class V, class W>
279
        triple(const triple<U,V,W> &t):
280
        first(t.first), second(t.second), third(t.third)
281
      {}
282
283
    };
284
285
  //**************quad template********************
286
  //! \class quad obutil.h <openbabel/obutil.h>
287
  //! \brief A 4-element templated, based on the design of the STL pair<>
288
  template <class T1, class T2, class T3, class T4>
289
    struct quad
290
    {
291
      //type names for the values
292
      typedef T1 first_type;
293
      typedef T2 second_type;
294
      typedef T3 third_type;
295
      typedef T4 fourth_type;
296
297
      //member
298
      T1 first;
299
      T2 second;
300
      T3 third;
301
      T4 fourth;
302
303
      /*! default constructor
304
       *  T1() and T2() and T3() force initialization for built in types
305
       */
306
    quad():
307
0
      first(T1()),second(T2()),third(T3()),fourth(T4())
308
0
      {}
309
310
      //! constructor for 3 values
311
    quad(const T1 &a, const T2 &b, const T3 &c, const T4 &d):
312
      first(a), second(b), third(c), fourth(d)
313
      {}
314
315
      //! copy constructor with implicit conversions
316
      template<class U, class V, class W, class X>
317
        quad(const quad<U,V,W,X> &q):
318
        first(q.first), second(q.second), third(q.third), fourth(q.fourth)
319
      {}
320
321
    };
322
323
} // end namespace OpenBabel
324
325
#endif // OBUTIL_H
326
327
//! \file obutil.h
328
//! \brief Various utility methods.