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, 7 months ago) by tim
File size: 14864 byte(s)
Log Message:
adding openbabel

File Contents

# Content
1 /**********************************************************************
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