Coverage Report

Created: 2025-12-14 06:43

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
39
#include <math.h>
40
41
#ifndef M_PI
42
#define M_PI 3.14159265358979323846
43
#endif
44
45
namespace OpenBabel
46
{
47
48
  // class introduction in obutil.cpp
49
  class OBAPI OBStopwatch
50
  {
51
#if HAVE_CLOCK_T
52
    clock_t start; //!< the start of timing
53
    clock_t stop;  //!< the current time
54
#else
55
    timeval start; //!< the start of timing
56
    timeval stop;  //!< the current time
57
#endif
58
59
  public:
60
#if HAVE_CLOCK_T
61
62
    //! Mark the start of "stopwatch" timing
63
    void  Start()
64
0
    {
65
0
      start= clock();
66
0
    }
67
    //! \return The time since calling OBStopwatch::Start() in seconds.
68
    double Lap()
69
0
    {
70
0
      stop= clock();
71
0
      return((stop - start) / (double) CLOCKS_PER_SEC);
72
0
    }
73
#else
74
    //! Mark the start of "stopwatch" timing
75
    void Start()
76
    {
77
      gettimeofday(&start, nullptr);
78
    }
79
    //! \return The time since calling OBStopwatch::Start() in seconds.
80
    double Lap()
81
    {
82
      gettimeofday(&stop, nullptr);
83
      return((stop.tv_sec - start.tv_sec)
84
             + (stop.tv_usec - start.tv_usec)/1000000.0);
85
    }
86
#endif
87
88
    //! \return The time since calling OBStopwatch::Start() in seconds.
89
    double Elapsed()
90
0
    {
91
0
      return(Lap());
92
0
    }
93
  };
94
95
96
  //! \class OBSqrtTbl obutil.h <openbabel/obutil.h>
97
  //! \brief Square Root lookup table - given a distance squared returns distance
98
  class OBAPI OBSqrtTbl
99
  {
100
    double _max,_incr,*_tbl;
101
  public:
102
  OBSqrtTbl():
103
    _max(0.0), _incr(0.0),  _tbl(nullptr)
104
0
      { }
105
    //! \brief Create a square root table to handle up to the square root of @p max
106
    //! (e.g., if you want the square root of 144, supply 12 for max)
107
    //! \param max The maximum square root stored in the lookup table
108
    //! \param incr The floating point resolution of the lookup table
109
  OBSqrtTbl(const double max, const double incr):
110
    _max(max*max), _incr(incr), _tbl(nullptr)
111
0
      {
112
0
        Init(max,incr);
113
0
      }
114
    ~OBSqrtTbl()
115
0
      {
116
0
        if (_tbl)
117
0
          {
118
0
            delete [] _tbl;
119
0
            _tbl = nullptr;
120
0
          }
121
0
      }
122
    //! \brief Fast square root calculation using a lookup table
123
    //! \return Square root of @p d2
124
    double Sqrt(double d2) const
125
0
    {
126
0
      if (_tbl)
127
0
        return((d2 < _max) ? _tbl[static_cast<int>(d2*_incr)]:sqrt(d2));
128
0
      else
129
0
        return 0.0;
130
0
    }
131
    //! \brief Initialize the square root lookup table
132
    //! \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)
133
    //! \param incr The floating point resolution of the lookup table
134
    void Init(double max,double incr)
135
0
    {
136
0
      // parameters are potentially unneeded, but let's do this until we can
137
0
      // deprecate them
138
0
      _max = max * max;
139
0
      _incr = incr;
140
0
141
0
      //array size needs to be large enough to account for fp error
142
0
      int i;
143
0
      double r;
144
0
      _tbl = new double [static_cast<int>((_max/_incr)+10)];
145
0
      for (r = (_incr/2.0),i=0;r <= _max;r += _incr,++i)
146
0
        _tbl[i] = sqrt(r);
147
0
148
0
      _incr = 1/_incr;
149
0
    }
150
  };
151
152
  //***RMS helper methods***/
153
#ifndef __KCC
154
  extern "C" {
155
  OBAPI void  rotate_coords(double*,double m[3][3],unsigned);
156
  OBAPI double calc_rms(double*,double*,unsigned int);
157
  }
158
#else
159
  OBAPI void  rotate_coords(double*,double m[3][3],unsigned);
160
  OBAPI double calc_rms(double*,double*,unsigned int);
161
#endif
162
163
#ifndef SWIG
164
  //! \name  String conversion utilities
165
  //@{
166
  // Documentation in obutil.cpp
167
  OBAPI void ToUpper(std::string&);
168
  OBAPI void ToUpper(char*);
169
  OBAPI void ToLower(std::string&);
170
  OBAPI void ToLower(char *);
171
  OBAPI void InvertCase(std::string&, int);
172
  OBAPI void InvertCase(char *);
173
  //! "Clean" the supplied atom type
174
  OBAPI void CleanAtomType(char*);
175
  //@}
176
177
  //! Comparison -- returns true if first parameter less than second
178
  //! \return True if @p a < @p b, False otherwise.
179
  OBAPI bool OBCompareInt(const int &a,const int &b);
180
  //! Comparison -- returns true if first parameter less than second
181
  //! \return True if @p a < @p b, False otherwise.
182
  OBAPI bool OBCompareUnsigned(const unsigned int &a,const unsigned int &b);
183
  /*! "Safe" comparison for floats/doubles: returns fabs(a - b) < epsilon
184
   * This function really doesn't make any sense w.r.t. floating-point
185
   * representation, so you should never use it. It is provided only for
186
   * backwards compatibility.
187
   * \deprecated Use IsApprox() instead
188
   */
189
  OB_DEPRECATED_MSG("Use IsApprox() instead")
190
  OBAPI bool IsNear(const double &, const double &, const double epsilon=2e-6);
191
  /*! "Safe" comparison for floats/doubles: true if a is less than epsilon
192
   * This function really doesn't make any sense w.r.t. floating-point
193
   * representation, so you should never use it. It is provided only for
194
   * backwards compatibility.
195
   * \deprecated
196
   */
197
  OB_DEPRECATED
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.