1 /**********************************************************************
2 grid.h - Handle grids of values.
3 
4 Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5 Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison
6 Some Portions Copyright (C) 2008 by Marcus D. Hanwell
7 
8 This file is part of the Open Babel project.
9 For more information, see <http://openbabel.org/>
10 
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation version 2 of the License.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19 ***********************************************************************/
20 
21 #ifndef OB_GRID_H
22 #define OB_GRID_H
23 
24 #include <openbabel/babelconfig.h>
25 #include <openbabel/math/vector3.h>
26 #include <openbabel/base.h>
27 
28 // Necessary evil for 2.x series -- should use OBMol* below
29 #include <openbabel/mol.h>
30 
31 #include <iosfwd>
32 #include <algorithm>
33 #include <vector>
34 #include <string>
35 
36 namespace OpenBabel
37 {
38 
39   // Forward declaration
40   class OBMol;
41 
42   //! \class OBGrid grid.h <openbabel/grid.h>
43   //! \brief A base grid class
44  class OBAPI OBGrid: public OBBase
45   {
46   protected:
47     double _xmin,_xmax,_ymin,_ymax,_zmin,_zmax; //!< the min/max axes in XYZ axes (i.e., the box)
48 
49   public:
OBGrid()50     OBGrid() {}
51 
52     //! \brief Initialize the grid based on a box around the molecule @p box
53     //! Subclasses should overload this method -- this only tracks the
54     //! dimension of the box itself
55     virtual void Init(OBMol &box);
56 
57     //! \return the minimum x point of the grid
GetXmin()58     double GetXmin() const    { return(_xmin);    }
59     //! \return the minimum y point of the grid
GetYmin()60     double GetYmin() const    { return(_ymin);    }
61     //! \return the minimum z point of the grid
GetZmin()62     double GetZmin() const    { return(_zmin);    }
63     //! \return the maximum x point of the grid
GetXmax()64     double GetXmax() const    { return(_xmax);    }
65     //! \return the maximum y point of the grid
GetYmax()66     double GetYmax() const    { return(_ymax);    }
67     //! \return the maximum z point of the grid
GetZmax()68     double GetZmax() const    { return(_zmax);    }
69 
70     //! \return whether the supplied XYZ coordinates fall within the box
PointIsInBox(double x,double y,double z)71     bool PointIsInBox(double x,double y,double z)
72     {
73       return (x>=_xmin) && (x<=_xmax) &&
74         (y>=_ymin) && (y<=_ymax) &&
75         (z>=_zmin) && (z<=_zmax);
76     }
77     //! \return true if the point falls within the box
PointIsInBox(double * c)78     bool PointIsInBox(double *c)
79     {
80       return (c[0]>=_xmin) && (c[0]<=_xmax) &&
81         (c[1]>=_ymin) && (c[1]<=_ymax) &&
82         (c[2]>=_zmin) && (c[2]<=_zmax);
83     }
84 
85     //! \return true if the point falls within the box
PointIsInBox(vector3 v)86     bool PointIsInBox(vector3 v)
87     {
88       return (v.x() >= _xmin) && (v.x() <=_xmax) &&
89       (v.y()>=_ymin) && (v.y()<=_ymax) &&
90       (v.z()>=_zmin) && (v.z()<=_zmax);
91     }
92   };
93 
94   //! \class OBFloatGrid grid.h <openbabel/grid.h>
95   //! \brief Handle double precision floating point 3D grids (e.g., charge density around an OBMol)
96   //!
97   //! Supports input/output and base functionality for simple 3D discrete grids
98   //! of some function -- typically around a molecule. Typically you will want
99   //! to use OBGridData which uses OBFloatGrid to store its data.
100   //! \sa OBGridData
101  class OBAPI OBFloatGrid: public OBGrid
102   {
103   protected:
104     std::vector<double> _values;   //!< floating point values
105     int   *_ival;             //!< for integer values (deprecated)
106     double _midz,_midx,_midy; //!< center of grid in world coordinates
107     int _ydim,_xdim,_zdim;    //!< grid dimensions
108     double _spacing,_inv_spa; //!< spacing between grid points and its inverse
109     double _halfSpace;        //!< half of the grid spacing
110     //! Three axes (i.e., translation vectors like a unit cell)
111     vector3 _xAxis, _yAxis, _zAxis;
112 
113   public:
114 
OBFloatGrid()115     OBFloatGrid() : _ival(nullptr), _halfSpace(0.0) {}
~OBFloatGrid()116     ~OBFloatGrid()
117     {
118       if (_ival) delete [] _ival;
119     }
120 
121     //! Initialize the grid using this molecule as a box (plus a padding)
122     //! with the supplied spacing between points.
123     void Init(OBMol &box,double spacing, double pad=0.0);
124 
125     //! \return the minimum point in the grid.
GetMin()126     vector3 GetMin() { return vector3(_xmin, _ymin, _zmin); }
127 
128     //! Get the minimum point in the grid.
129     //! \deprecated Will be removed.
130     //! Use \sa GetMin()
GetMin(double * a)131     void GetMin(double *a)
132     {
133       a[0]=_xmin;
134       a[1]=_ymin;
135       a[2]=_zmin;
136     }
137 
138     //! \return the minimum point in the grid.
GetMax()139     vector3 GetMax() { return vector3(_xmax, _ymax, _zmax); }
140 
141     //! Get the maximum point in the grid.
142     //! \deprecated Will be removed.
143     //! \sa GetMax()
GetMax(double * a)144     void GetMax(double *a)
145     {
146       a[0]=_xmax;
147       a[1]=_ymax;
148       a[2]=_zmax;
149     }
150 
151     //! \return The grid spacing.
GetSpacing()152     double GetSpacing() const { return(_spacing); }
153     //! Get the grid spacing.
154     //! \deprecated Will be removed.
155     //! \sa GetSpacing()
GetSpacing(double & s)156     void GetSpacing(double &s)
157     {
158       s=_spacing;
159     }
160     //! \return Inverse of the grid spacing.
GetScale()161     double GetScale() const   { return(_inv_spa); }
162     //! \return Half of the spacing between grid points.
GetHalfSpace()163     double GetHalfSpace() const {return(_halfSpace);}
164     //! \return Size of the grid in the x dimension.
GetXdim()165     int GetXdim() const       { return(_xdim);    }
166     //! \return Size of the grid in the y dimension.
GetYdim()167     int GetYdim() const       { return(_ydim);    }
168     //! \return Size of the grid in the z dimension.
GetZdim()169     int GetZdim() const       { return(_zdim);    }
170     //! Get the x, y and z dimensions (must pass an double[3] at least).
171     //! \deprecated May be removed in future.
172     //! \sa GetXdim() \sa GetYdim() \sa GetZdim()
GetDim(int * a)173     void GetDim(int *a)
174     {
175       a[0]=_xdim;
176       a[1]=_ydim;
177       a[2]=_zdim;
178     }
179 
180     //! \return Position of the center of the grid.
GetMidpointVector()181     vector3 GetMidpointVector()
182     {
183       vector3 v;
184       v.Set(_midx,_midy,_midz);
185       return(v);
186     }
187 
188     //! \return X axis direction.
GetXAxis()189     vector3 GetXAxis() const
190     {
191       return _xAxis;
192     }
193 
194     //! \return Y axis direction.
GetYAxis()195     vector3 GetYAxis() const
196     {
197       return _yAxis;
198     }
199 
200     //! \return Z axis direction.
GetZAxis()201     vector3 GetZAxis() const
202     {
203       return _zAxis;
204     }
205 
206     //! Sets the number of points in the x, y and z directions.
207     void SetNumberOfPoints(int nx, int ny, int nz);
208 
209     //! Set the direction of the x axis.
210     void SetXAxis(vector3);
211     //! Set the direction of the y axis.
212     void SetYAxis(vector3);
213     //! Set the direction of the z axis.
214     void SetZAxis(vector3);
215 
216     //! Set the limits (i.e., the origin point and the axes)
217     //! NOTE: You must set the number of points first,
218     //!       with SetNumberOfPoints
219     //!       so the grid spacing can be calculated
220     void SetLimits(const vector3& origin, const vector3& x, const vector3& y,
221                    const vector3& z);
222     //! \deprecated Will be removed.
223     //! \sa SetLimits(const vector3& origin, const vector3& x, const vector3& y, const vector3& z)
224     void SetLimits(const double origin[3], const double x[3], const double y[3],
225                    const double z[3]);
226 
227     //! Get a copy of the vector that stores the points in the grid.
228     std::vector<double> GetDataVector();
229     //! Set the values in the grid to those in the vector passed. Note that the
230     //! vector must be of the same dimensions as the grid based on the values
231     //! given in SetNumberOfPoints(int nx, int ny, int nz).
232     void SetVals(const std::vector<double> & vals);
233 
234     //! \return Pointer to the first element of the grid point data stored as a
235     //! one dimensional array.
236     //! \deprecated Will be removed.
237     //! \sa GetDataVector()
GetVals()238     double *GetVals()    {        return(&_values[0]);    }
239 
240     //! \return Value at the point in the grid specified by i, j and k.
GetValue(int i,int j,int k)241     double GetValue(int i, int j, int k)
242     {
243       if (i*_ydim*_zdim + j*_zdim + k > _xdim*_ydim*_zdim)
244         return 0.0;
245       else
246         return _values[i*_ydim*_zdim + j*_zdim + k];
247     }
248 
249     //! \deprecated Will be removed.
250     //! \sa SetVals(const std::vector<double> & vals)
SetVals(double * ptr)251     void SetVals(double *ptr)
252     {
253      for (int i = 0; i < _xdim*_ydim*_zdim; ++i)
254        _values[i] = ptr[i];
255     }
256 
257     //! Set the value at the grid point specified by i, j and k to val.
SetValue(int i,int j,int k,double val)258     bool SetValue(int i, int j, int k, double val)
259     {
260       if (i*_ydim*_zdim + j*_zdim + k > _xdim*_ydim*_zdim)
261         return false;
262 
263       _values[i*_ydim*_zdim + j*_zdim + k] = val;
264       return true;
265     }
266 
267     //! \return Position of the center of the grid.
Center()268     vector3 Center()
269     {
270       return vector3(_midx,_midy,_midz);
271     }
272 
273     friend std::ostream& operator<< ( std::ostream&, const OBFloatGrid& ) ;
274     friend std::istream& operator>> ( std::istream&,OBFloatGrid& ) ;
275 
276     //! \return the value at the given point (rounding as needed)
277     double Inject(double x,double y,double z);
278     void IndexToCoords(int idx, double &x, double &y, double &z);
279     void CoordsToIndex(int*,double*);
280     int CoordsToIndex(double x, double y, double z);
281     //! \return the interpolated value for the given point
282     double Interpolate(double,double,double);
283     //! \return the interpolated value for the given point and set the dx, dy, dz derivatives
284     double InterpolateDerivatives(double,double,double,double *derivatives);
285   };
286 
287 #ifndef OBPolarGrid
288 #define OBPolarGrid 0x01 /* polar interactions? */
289 #endif //OBPolarGrid
290 
291 #ifndef OBLipoGrid
292 #define OBLipoGrid 0x02 /* lipophilicity? */
293 #endif //OBLipoGrid
294 
295   //! \class OBProxGrid grid.h <openbabel/grid.h>
296   //! \brief A grid for determining the proximity of a given point to atoms in an OBMol
297   //! \deprecated May be removed in the future, since docking is not a key feature
298  class OBAPI OBProxGrid: public OBGrid
299   {
300   protected:
301     int _gridtype;
302     int _nxinc,_nyinc,_nzinc,_maxinc;
303     double _inc;
304     std::vector<std::vector<int> > cell;
305 
306   public:
307 
308     OBProxGrid(int gridtype=0)
309       {
310         _gridtype=gridtype;
311       }
~OBProxGrid()312     ~OBProxGrid()
313       {}
314     void Setup(OBMol &mol,OBMol &box, double cutoff,double resolution = 0.5);
315     void Setup(OBMol &mol,OBMol &box, double cutoff,
316                std::vector<bool> &use,double resolution = 0.5);
317     std::vector<int> *GetProxVector(double,double,double);
318     std::vector<int> *GetProxVector(double*);
319 
LipoGrid()320     bool LipoGrid()
321     {
322       return((_gridtype&OBLipoGrid) ? true : false);
323     }
PolarGrid()324     bool PolarGrid()
325     {
326       return(_gridtype&OBPolarGrid);
327     }
SetGridType(int gridtype)328     void SetGridType(int gridtype)
329     {
330       _gridtype = gridtype;
331     }
332   };
333 
334   // scoring function used: PLP = Piecewise Linear Potential or ChemScore algorithm
335   typedef enum { Undefined = -1, PLP, ChemScore } score_t;
336 
337   //! \class OBScoreGrid grid.h <openbabel/grid.h>
338   //! \brief A base class for scoring docking interactions between multiple molecules
339   //! \deprecated Will disappear in future versions. Use your own code.
340   class OBAPI OBScoreGrid
341   {
342   protected:
343     score_t gridtype;
344     bool verbose;
345 
346   public:
347 
348     double score;
349 
OBScoreGrid(void)350     OBScoreGrid(void)                 {  verbose = false;      }
~OBScoreGrid(void)351     virtual ~OBScoreGrid(void) {}
352 
SetVerbose(bool v)353     void    SetVerbose(bool v)        {      verbose = v;      }
SetType(score_t type)354     void    SetType(score_t type)     {      gridtype = type;  }
GetType(void)355     score_t GetType(void)             {    return gridtype;    }
356 
Clear(void)357     virtual void   Clear(void)        { }
Eval(double *)358     virtual double  Eval(double *)    {       return -1;       }
Eval(OBMol & mol)359     virtual double  Eval(OBMol &mol){return Eval(mol.GetCoordinates());}
Init(OBMol &,OBMol &,std::string &,double)360     virtual void   Init(OBMol &, OBMol &, std::string &, double){}
Setup(OBMol &)361     virtual void   Setup(OBMol &) {}
Setup(OBMol &,std::vector<int> &)362     virtual void   Setup(OBMol &, std::vector<int> &){}
Setup(std::vector<int> &)363     virtual void   Setup(std::vector<int> &) {}
Config(std::string)364     virtual void   Config(std::string) {}
Read(std::string)365     virtual bool   Read(std::string)   {      return false;    }
Write(std::string)366     virtual bool   Write(std::string)  {      return false;    }
Center()367     virtual vector3 Center()           {      return VZero;    }
CenterMol(OBMol &)368     virtual vector3 CenterMol(OBMol &) {      return VZero;    }
369   };
370 
371 } // end namespace OpenBabel
372 
373 #endif // OB_GRID_H
374 
375 //! \file grid.h
376 //! \brief Handle grids of values.
377