ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/openbabel/grid.cpp
Revision: 2440
Committed: Wed Nov 16 19:42:11 2005 UTC (18 years, 8 months ago) by tim
File size: 14864 byte(s)
Log Message:
adding openbabel

File Contents

# User Rev Content
1 tim 2440 /**********************************************************************
2     grid.cpp - Handle grids of values.
3    
4     Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
5     Some portions Copyright (C) 2001-2005 by Geoffrey R. Hutchison
6    
7     This file is part of the Open Babel project.
8     For more information, see <http://openbabel.sourceforge.net/>
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     #include "mol.hpp"
21     #include "grid.hpp"
22    
23     using namespace std;
24    
25     namespace OpenBabel
26     {
27    
28     void OBProxGrid::Setup(OBMol &mol,OBMol &box,double cutoff,double res)
29     {
30     OBAtom *atom;
31     vector<OBNodeBase*>::iterator i;
32    
33     for (atom = box.BeginAtom(i);atom;atom = box.NextAtom(i))
34     if (atom->GetIdx() == 1)
35     {
36     _xmin = atom->GetX();
37     _xmax = atom->GetX();
38     _ymin = atom->GetY();
39     _ymax = atom->GetY();
40     _zmin = atom->GetZ();
41     _zmax = atom->GetZ();
42     }
43     else
44     {
45     if (atom->GetX() < _xmin)
46     _xmin = atom->GetX();
47     if (atom->GetX() > _xmax)
48     _xmax = atom->GetX();
49     if (atom->GetY() < _ymin)
50     _ymin = atom->GetY();
51     if (atom->GetY() > _ymax)
52     _ymax = atom->GetY();
53     if (atom->GetZ() < _zmin)
54     _zmin = atom->GetZ();
55     if (atom->GetZ() > _zmax)
56     _zmax = atom->GetZ();
57     }
58    
59     _inc = res; // 1/2 angstrom resolution
60    
61     _nxinc = (int) floor((_xmax - _xmin)/0.5);
62     _nyinc = (int) floor((_ymax - _ymin)/0.5);
63     _nzinc = (int) floor((_zmax - _zmin)/0.5);
64     _maxinc = _nxinc*_nyinc*_nzinc;
65    
66     int j,size = _nxinc*_nyinc*_nzinc;
67     cell.resize(size);
68     for (unsigned int num = 0; num < cell.size(); num++)
69     cell[num].resize(0);
70    
71     cutoff *= cutoff; //don't do sqrts
72    
73     int k,l,m;
74     double x,y,z,dx_2,dy_2;
75     double *c = mol.GetCoordinates();
76     size = mol.NumAtoms()*3;
77    
78     for (atom = mol.BeginAtom(i),j=0;atom;atom = mol.NextAtom(i),j+=3)
79     if (PointIsInBox(c[j],c[j+1],c[j+2]))
80     for (x = _xmin+(_inc/2.0),k=0;k < _nxinc;x+=_inc,k++)
81     if ((dx_2 = SQUARE(c[j]-x)) < cutoff)
82     for (y = _ymin+(_inc/2.0),l=0;l < _nyinc;y+=_inc,l++)
83     if ((dx_2+(dy_2 = SQUARE(c[j+1]-y))) < cutoff)
84     for (z = _zmin+(_inc/2.0),m=0;m < _nzinc;z+=_inc,m++)
85     if ((dx_2+dy_2+SQUARE(c[j+2]-z)) < cutoff)
86     cell[(k*_nyinc*_nzinc)+(l*_nzinc)+m].push_back(atom->GetIdx());
87    
88     _inc = 1/_inc;
89     }
90    
91     void OBProxGrid::Setup(OBMol &mol,OBMol &box,double cutoff,vector<bool> &use,
92     double res)
93     {
94     OBAtom *atom;
95     vector<OBNodeBase*>::iterator i;
96    
97     for (atom = box.BeginAtom(i);atom;atom = box.NextAtom(i))
98     if (atom->GetIdx() == 1)
99     {
100     _xmin = atom->GetX();
101     _xmax = atom->GetX();
102     _ymin = atom->GetY();
103     _ymax = atom->GetY();
104     _zmin = atom->GetZ();
105     _zmax = atom->GetZ();
106     }
107     else
108     {
109     if (atom->GetX() < _xmin)
110     _xmin = atom->GetX();
111     if (atom->GetX() > _xmax)
112     _xmax = atom->GetX();
113     if (atom->GetY() < _ymin)
114     _ymin = atom->GetY();
115     if (atom->GetY() > _ymax)
116     _ymax = atom->GetY();
117     if (atom->GetZ() < _zmin)
118     _zmin = atom->GetZ();
119     if (atom->GetZ() > _zmax)
120     _zmax = atom->GetZ();
121     }
122    
123     _inc = res; // 1/2 angstrom resolution
124    
125     _nxinc = (int) floor((_xmax - _xmin)/0.5);
126     _nyinc = (int) floor((_ymax - _ymin)/0.5);
127     _nzinc = (int) floor((_zmax - _zmin)/0.5);
128     _maxinc = _nxinc*_nyinc*_nzinc;
129    
130     int j,size = _nxinc*_nyinc*_nzinc;
131     cell.resize(size);
132     cutoff *= cutoff; //don't do sqrts
133    
134     int k,l,m;
135     double x,y,z,dx_2,dy_2;
136     double *c = mol.GetCoordinates();
137     size = mol.NumAtoms()*3;
138    
139     for (atom = mol.BeginAtom(i),j=0;atom;atom = mol.NextAtom(i),j+=3)
140     if (use[atom->GetIdx()])
141     if (PointIsInBox(c[j],c[j+1],c[j+2]))
142     for (x = _xmin+(_inc/2.0),k=0;k < _nxinc;x+=_inc,k++)
143     if ((dx_2 = SQUARE(c[j]-x)) < cutoff)
144     for (y = _ymin+(_inc/2.0),l=0;l < _nyinc;y+=_inc,l++)
145     if ((dx_2+(dy_2 = SQUARE(c[j+1]-y))) < cutoff)
146     for (z = _zmin+(_inc/2.0),m=0;m < _nzinc;z+=_inc,m++)
147     if ((dx_2+dy_2+SQUARE(c[j+2]-z)) < cutoff)
148     cell[(k*_nyinc*_nzinc)+(l*_nzinc)+m].push_back(atom->GetIdx());
149    
150     _inc = 1/_inc;
151     }
152    
153     vector<int> *OBProxGrid::GetProxVector(double x,double y,double z)
154     {
155     if (x < _xmin || x > _xmax)
156     return(NULL);
157     if (y < _ymin || y > _ymax)
158     return(NULL);
159     if (z < _zmin || z > _zmax)
160     return(NULL);
161    
162     x -= _xmin;
163     y -= _ymin;
164     z -= _zmin;
165     int i,j,k,idx;
166     i = (int) (x*_inc);
167     j = (int) (y*_inc);
168     k = (int) (z*_inc);
169     idx = (i*_nyinc*_nzinc)+(j*_nzinc)+k;
170     if (idx >= _maxinc)
171     return(NULL);
172    
173     return(&cell[idx]);
174     }
175    
176     vector<int> *OBProxGrid::GetProxVector(double *c)
177     {
178     double x,y,z;
179     x = c[0];
180     y = c[1];
181     z = c[2];
182    
183     return( GetProxVector(x, y, z) );
184     }
185    
186     void OBFloatGrid::Init(OBMol &box,double spacing, double pad)
187     {
188     OBAtom *atom;
189     vector<OBNodeBase*>::iterator i;
190    
191     for (atom = box.BeginAtom(i);atom;atom = box.NextAtom(i))
192     if (atom->GetIdx() == 1)
193     {
194     _xmin = atom->GetX();
195     _xmax = atom->GetX();
196     _ymin = atom->GetY();
197     _ymax = atom->GetY();
198     _zmin = atom->GetZ();
199     _zmax = atom->GetZ();
200     }
201     else
202     {
203     if (atom->GetX() < _xmin)
204     _xmin = atom->GetX();
205     if (atom->GetX() > _xmax)
206     _xmax = atom->GetX();
207     if (atom->GetY() < _ymin)
208     _ymin = atom->GetY();
209     if (atom->GetY() > _ymax)
210     _ymax = atom->GetY();
211     if (atom->GetZ() < _zmin)
212     _zmin = atom->GetZ();
213     if (atom->GetZ() > _zmax)
214     _zmax = atom->GetZ();
215     }
216    
217     _xmin -= pad;
218     _xmax += pad;
219     _ymin -= pad;
220     _ymax += pad;
221     _zmin -= pad;
222     _zmax += pad;
223     double midx,midy,midz;
224     int xdim,ydim,zdim;
225    
226     midx=0.5*(_xmax+_xmin);
227     midy=0.5*(_ymax+_ymin);
228     midz=0.5*(_zmax+_zmin);
229    
230     xdim=3+(int) ((_xmax-_xmin)/spacing);
231     ydim=3+(int) ((_ymax-_ymin)/spacing);
232     zdim=3+(int) ((_zmax-_zmin)/spacing);
233    
234     /* store in Grid */
235     _midx=midx;
236     _midy=midy;
237     _midz=midz;
238     _xdim=xdim;
239     _ydim=ydim;
240     _zdim=zdim;
241     _spacing=spacing;
242     _halfSpace= _spacing/2.0;
243     _inv_spa=1.0/spacing;
244     _val=NULL;
245     _ival=NULL;
246    
247     int size = _xdim*_ydim*_zdim;
248     _val = new double [size];
249     memset(_val,'\0',sizeof(double)*size);
250    
251     //return(true);
252     }
253    
254     double OBFloatGrid::Inject(double x,double y,double z)
255     {
256     if((x<=_xmin)||(x>=_xmax))
257     return(0.0);
258     if((y<=_ymin)||(y>=_ymax))
259     return(0.0);
260     if((z<=_zmin)||(z>=_zmax))
261     return(0.0);
262    
263     int gx=(int)((x-_xmin)*_inv_spa);
264     int gy=(int)((y-_ymin)*_inv_spa);
265     int gz=(int)((z-_zmin)*_inv_spa);
266    
267     return(_val[(gz*_ydim*_xdim)+(gy*_xdim)+gx]);
268     }
269    
270     void OBFloatGrid::IndexToCoords(int idx, double &x, double &y, double &z)
271     {
272     long int grid_x,grid_y,grid_z;
273    
274     grid_x = idx % (int)_xdim;
275     grid_z = (int)(idx /(_xdim * _ydim));
276     grid_y = (int)((idx - (grid_z * _xdim * _ydim))/_xdim);
277    
278     x = ((double)grid_x * _spacing + _xmin) + this->_halfSpace;
279     y = ((double)grid_y * _spacing + _ymin) + this->_halfSpace;
280     z = ((double)grid_z * _spacing + _zmin) + this->_halfSpace;
281     }
282    
283     int OBFloatGrid::CoordsToIndex(double &x, double &y, double &z)
284     {
285     int gx=(int)((x-_xmin)*_inv_spa);
286     int gy=(int)((y-_ymin)*_inv_spa);
287     int gz=(int)((z-_zmin)*_inv_spa);
288    
289     return((gz*_ydim*_xdim)+(gy*_xdim)+gx);
290     }
291    
292     void OBFloatGrid::CoordsToIndex(int *idx,double *c)
293     {
294     idx[0]=(int)((c[0]-_xmin)*_inv_spa);
295     idx[1]=(int)((c[1]-_ymin)*_inv_spa);
296     idx[2]=(int)((c[2]-_zmin)*_inv_spa);
297     }
298    
299     double OBFloatGrid::Interpolate(double x,double y,double z)
300     {
301     int n,igx,igy,igz;
302     double xydim;
303     double gx,gy,gz,fgx,fgy,fgz;
304     double ax,ay,az,bx,by,bz;
305     double AyA,ByA,AyB,ByB,Az,Bz;
306    
307     if((x<=_xmin)||(x>=_xmax))
308     return(0.0);
309     if((y<=_ymin)||(y>=_ymax))
310     return(0.0);
311     if((z<=_zmin)||(z>=_zmax))
312     return(0.0);
313    
314     xydim = _xdim*_ydim;
315    
316     /* calculate grid voxel and fractional offsets */
317     gx=(x-_xmin-_halfSpace)*_inv_spa;
318     if (gx<0)
319     gx=0;
320     igx=(int)gx;
321     fgx=gx-(double)igx;
322     gy=(y-_ymin-_halfSpace)*_inv_spa;
323     if (gy<0)
324     gy=0;
325     igy=(int) gy;
326     fgy= gy - (double) igy;
327     gz=(z-_zmin-_halfSpace)*_inv_spa;
328     if (gz<0)
329     gz=0;
330     igz=(int) gz;
331     fgz= gz - (double) igz;
332    
333     n=(int)(igx+ _xdim*igy + xydim*igz);
334     /* calculate linear weightings */
335     ax=1.0-fgx;
336     bx=fgx;
337     ay=1.0-fgy;
338     by=fgy;
339     az=1.0-fgz;
340     bz=fgz;
341    
342     /* calculate interpolated value */
343     AyA=ax*_val[n ]+bx*_val[(int)(n+1) ];
344     ByA=ax*_val[n+_xdim]+bx*_val[(int)(n+1+_xdim) ];
345    
346     Az=ay*AyA+by*ByA;
347    
348     AyB=ax*_val[(int)(n +xydim)]+bx*_val[(int)(n+1 +xydim)];
349     ByB=ax*_val[(int)(n+_xdim+xydim)]+bx*_val[(int)(n+1+_xdim+xydim)];
350     Bz=ay*AyB+by*ByB;
351    
352     return(az*Az+bz*Bz);
353     }
354    
355    
356     double OBFloatGrid::InterpolateDerivatives(double x,double y,double z,double *derivatives)
357     {
358     int n,igx,igy,igz;
359     double xydim;
360     double gx,gy,gz,fgx,fgy,fgz;
361     double ax,ay,az,bx,by,bz;
362     double AyA,ByA,AyB,ByB,Az,Bz;
363     double energy,fx,fy,fz;
364    
365     if((x<=_xmin)||(x>=_xmax))
366     return(0.0);
367     if((y<=_ymin)||(y>=_ymax))
368     return(0.0);
369     if((z<=_zmin)||(z>=_zmax))
370     return(0.0);
371    
372     xydim = _xdim*_ydim;
373    
374     /* calculate grid voxel and fractional offsets */
375     gx=(x-_xmin-_halfSpace)*_inv_spa;
376     if (gx<0)
377     gx=0;
378     igx=(int)gx;
379     fgx=gx-(double)igx;
380     gy=(y-_ymin-_halfSpace)*_inv_spa;
381     if (gy<0)
382     gy=0;
383     igy=(int) gy;
384     fgy= gy - (double) igy;
385     gz=(z-_zmin-_halfSpace)*_inv_spa;
386     if (gz<0)
387     gz=0;
388     igz=(int) gz;
389     fgz= gz - (double) igz;
390    
391     n=(int)(igx+ _xdim*igy + xydim*igz);
392     /* calculate linear weightings */
393     ax=1.0-fgx;
394     bx=fgx;
395     ay=1.0-fgy;
396     by=fgy;
397     az=1.0-fgz;
398     bz=fgz;
399    
400     /* calculate interpolated value */
401     AyA=ax*_val[n ]+bx*_val[(int)(n+1) ];
402     ByA=ax*_val[n+_xdim]+bx*_val[(int)(n+1+_xdim) ];
403    
404     Az=ay*AyA+by*ByA;
405    
406     AyB=ax*_val[(int)(n +xydim)]+bx*_val[(int)(n+1 +xydim)];
407     ByB=ax*_val[(int)(n+_xdim+xydim)]+bx*_val[(int)(n+1+_xdim+xydim)];
408     Bz=ay*AyB+by*ByB;
409    
410     energy = az*Az+bz*Bz;
411    
412     //calculate derivatives
413    
414     fz=-Az+Bz;
415    
416     Az=-AyA+ByA;
417     Bz=-AyB+ByB;
418    
419     fy=az*Az+bz*Bz;
420    
421     AyA=-_val[n ]+_val[(int)(n+1) ];
422     ByA=-_val[n+_xdim ]+_val[(int)(n+1+_xdim)];
423    
424     Az=ay*AyA+by*ByA;
425    
426     AyB=-_val[(int)(n +xydim)]+_val[(int)(n+1 +xydim)];
427     ByB=-_val[(int)(n+_xdim+xydim)]+_val[(int)(n+1+_xdim+xydim)];
428    
429     Bz=ay*AyB+by*ByB;
430    
431     fx=az*Az+bz*Bz;
432    
433     derivatives[0] += fx;
434     derivatives[1] += fy;
435     derivatives[2] += fz;
436    
437     return(energy);
438    
439     }
440    
441    
442     ostream& operator<< ( ostream &os, const OBFloatGrid& fg)
443     {
444     os.write((const char*)&fg._xmin,sizeof(double));
445     os.write((const char*)&fg._xmax,sizeof(double));
446     os.write((const char*)&fg._ymin,sizeof(double));
447     os.write((const char*)&fg._ymax,sizeof(double));
448     os.write((const char*)&fg._zmin,sizeof(double));
449     os.write((const char*)&fg._zmax,sizeof(double));
450    
451     os.write((const char*)&fg._midx,sizeof(double));
452     os.write((const char*)&fg._midy,sizeof(double));
453     os.write((const char*)&fg._midz,sizeof(double));
454     os.write((const char*)&fg._inv_spa,sizeof(double));
455     os.write((const char*)&fg._spacing,sizeof(double));
456     os.write((const char*)&fg._xdim,sizeof(int));
457     os.write((const char*)&fg._ydim,sizeof(int));
458     os.write((const char*)&fg._zdim,sizeof(int));
459     os.write((const char*)&fg._val[0],
460     (sizeof(double)*(fg._xdim*fg._ydim*fg._zdim)));
461    
462     return(os);
463     }
464    
465     istream& operator>> ( istream &is,OBFloatGrid& fg)
466     {
467     is.read((char*)&fg._xmin,sizeof(double));
468     is.read((char*)&fg._xmax,sizeof(double));
469     is.read((char*)&fg._ymin,sizeof(double));
470     is.read((char*)&fg._ymax,sizeof(double));
471     is.read((char*)&fg._zmin,sizeof(double));
472     is.read((char*)&fg._zmax,sizeof(double));
473    
474     is.read((char*)&fg._midx,sizeof(double));
475     is.read((char*)&fg._midy,sizeof(double));
476     is.read((char*)&fg._midz,sizeof(double));
477     is.read((char*)&fg._inv_spa,sizeof(double));
478     is.read((char*)&fg._spacing,sizeof(double));
479     is.read((char*)&fg._xdim,sizeof(int));
480     is.read((char*)&fg._ydim,sizeof(int));
481     is.read((char*)&fg._zdim,sizeof(int));
482     int size = fg._xdim*fg._ydim*fg._zdim;
483     fg._val = new double [size];
484     size *= (int) sizeof(double);
485    
486     is.read((char*)&fg._val[0],size);
487     fg._halfSpace= fg._spacing/2.0;
488    
489     return(is);
490     }
491    
492     #ifdef FOO
493     //linear interpolation routine
494     double Interpolate(double x,double y,double z)
495     {
496     int n;
497     int igx,igy,igz;
498     double scale,gx,gy,gz,fgx,fgy,fgz;
499     double qzpypx,qzpynx,qznynx,qznypx,qznyx,qzpyx;
500    
501     scale=_inv_spa;
502    
503     if((x<=_xmin)||(x>=_xmax))
504     return(0.0);
505     if((y<=_ymin)||(y>=_ymax))
506     return(0.0);
507     if((z<=_zmin)||(z>=_zmax))
508     return(0.0);
509    
510     gx=(x-_xmin-_halfSpace)*scale;
511     igx=(int) gx;
512     fgx= gx - (double) igx;
513     gy=(y-_ymin-_halfSpace)*scale;
514     igy=(int) gy;
515     fgy= gy - (double) igy;
516     gz=(z-_zmin-_halfSpace)*scale;
517     igz=(int) gz;
518     fgz= gz - (double) igz;
519    
520     int xydim=_xdim*_ydim;
521     n=igx+ _xdim*igy + xydim*igz;
522     qzpypx=fgx*(_val[n+1+_xdim+xydim]-_val[n+_xdim+xydim]) + _val[n+_xdim+xydim];
523     qzpynx=fgx*(_val[n+1+xydim] -_val[n+xydim]) + _val[n+xydim];
524     qznypx=fgx*(_val[n+1+_xdim] -_val[n+_xdim]) + _val[n+_xdim];
525     qznynx=fgx*(_val[n+1] -_val[n]) + _val[n];
526     qzpyx =fgy*(-qzpynx+qzpypx)+qzpynx;
527     qznyx =fgy*(-qznynx+qznypx)+qznynx;
528    
529     return(fgz*(qzpyx-qznyx)+qznyx);
530     }
531     #endif
532    
533     } // end namespace OpenBabel
534    
535     //! \file grid.cpp
536     //! \brief Handle grids of values.
537