/src/openbabel/src/grid.cpp
Line | Count | Source |
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-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 | | #include <openbabel/babelconfig.h> |
21 | | |
22 | | #include <openbabel/mol.h> |
23 | | #include <openbabel/atom.h> |
24 | | #include <openbabel/grid.h> |
25 | | |
26 | | using namespace std; |
27 | | |
28 | | namespace OpenBabel |
29 | | { |
30 | | void OBGrid::Init(OBMol &box) |
31 | 0 | { |
32 | 0 | OBAtom *atom; |
33 | 0 | vector<OBAtom*>::iterator i; |
34 | |
|
35 | 0 | for (atom = box.BeginAtom(i); atom; atom = box.NextAtom(i)) { |
36 | 0 | if (atom->GetIdx() == 1) { |
37 | 0 | _xmin = atom->GetX(); |
38 | 0 | _xmax = atom->GetX(); |
39 | 0 | _ymin = atom->GetY(); |
40 | 0 | _ymax = atom->GetY(); |
41 | 0 | _zmin = atom->GetZ(); |
42 | 0 | _zmax = atom->GetZ(); |
43 | 0 | } |
44 | 0 | else { |
45 | 0 | if (atom->GetX() < _xmin) |
46 | 0 | _xmin = atom->GetX(); |
47 | 0 | if (atom->GetX() > _xmax) |
48 | 0 | _xmax = atom->GetX(); |
49 | 0 | if (atom->GetY() < _ymin) |
50 | 0 | _ymin = atom->GetY(); |
51 | 0 | if (atom->GetY() > _ymax) |
52 | 0 | _ymax = atom->GetY(); |
53 | 0 | if (atom->GetZ() < _zmin) |
54 | 0 | _zmin = atom->GetZ(); |
55 | 0 | if (atom->GetZ() > _zmax) |
56 | 0 | _zmax = atom->GetZ(); |
57 | 0 | } |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | | void OBFloatGrid::Init(OBMol &box, double spacing, double pad) |
62 | 0 | { |
63 | 0 | OBGrid::Init(box); // handle in the base class |
64 | |
|
65 | 0 | _xmin -= pad; |
66 | 0 | _xmax += pad; |
67 | 0 | _ymin -= pad; |
68 | 0 | _ymax += pad; |
69 | 0 | _zmin -= pad; |
70 | 0 | _zmax += pad; |
71 | | |
72 | | /* store in Grid */ |
73 | 0 | _midx=0.5*(_xmax+_xmin); |
74 | 0 | _midy=0.5*(_ymax+_ymin); |
75 | 0 | _midz=0.5*(_zmax+_zmin); |
76 | 0 | _xdim=static_cast<int>((_xmax-_xmin)/spacing) + 1; |
77 | 0 | _ydim=static_cast<int>((_ymax-_ymin)/spacing) + 1; |
78 | 0 | _zdim=static_cast<int>((_zmax-_zmin)/spacing) + 1; |
79 | 0 | _spacing=spacing; |
80 | 0 | _halfSpace=_spacing/2.0; |
81 | 0 | _inv_spa=1.0/_spacing; |
82 | 0 | _ival=nullptr; |
83 | | |
84 | | // Calculate the size needed, resize the vector and initialise it to 0.0 |
85 | 0 | int size = _xdim*_ydim*_zdim; |
86 | 0 | _values.resize(size, 0.0); |
87 | 0 | } |
88 | | |
89 | | void OBFloatGrid::SetLimits(const double origin[3], const double v1[3], const double v2[3], |
90 | | const double v3[3]) |
91 | 0 | { |
92 | | // Convert to vectors and call the vector form of the function |
93 | 0 | vector3 originv(origin[0], origin[1], origin[2]); |
94 | 0 | vector3 x(v1[0], v1[1], v1[2]); |
95 | 0 | vector3 y(v2[0], v2[1], v2[2]); |
96 | 0 | vector3 z(v3[0], v3[1], v3[2]); |
97 | 0 | SetLimits(originv, x, y, z); |
98 | 0 | } |
99 | | |
100 | | void OBFloatGrid::SetLimits(const vector3& origin, const vector3& x, |
101 | | const vector3& y, const vector3& z) |
102 | 0 | { |
103 | | // Using vectors instead of arrays of doubles |
104 | 0 | _xmin = origin.x(); |
105 | 0 | _ymin = origin.y(); |
106 | 0 | _zmin = origin.z(); |
107 | | |
108 | | // Set the axes |
109 | 0 | SetXAxis(x); |
110 | 0 | SetYAxis(y); |
111 | 0 | SetZAxis(z); |
112 | | |
113 | | // Now set the max and mid as well as spacing |
114 | 0 | _xmax = _xmin + (_xdim-1) * (x.x() + y.x() + z.x()); |
115 | 0 | _ymax = _ymin + (_ydim-1) * (x.y() + y.y() + z.y()); |
116 | 0 | _zmax = _zmin + (_zdim-1) * (x.z() + y.z() + z.z()); |
117 | | // FIXME If we want support for cubes aligned along arbitrary axes then |
118 | | // averaging the x, y and z directions will not work. Just use x for now. |
119 | 0 | _spacing = (_xmax - _xmin)/(_xdim-1); |
120 | 0 | _halfSpace= _spacing/2.0; |
121 | 0 | _inv_spa=1.0/_spacing; |
122 | 0 | } |
123 | | |
124 | | void OBFloatGrid::SetNumberOfPoints(int nx, int ny, int nz) |
125 | 0 | { |
126 | 0 | _xdim = nx; |
127 | 0 | _ydim = ny; |
128 | 0 | _zdim = nz; |
129 | 0 | _values.resize(nx*ny*nz); |
130 | 0 | } |
131 | | |
132 | | void OBFloatGrid::SetXAxis(vector3 v) |
133 | 0 | { |
134 | 0 | _xAxis = v; |
135 | 0 | } |
136 | | |
137 | | void OBFloatGrid::SetYAxis(vector3 v) |
138 | 0 | { |
139 | 0 | _yAxis = v; |
140 | 0 | } |
141 | | |
142 | | void OBFloatGrid::SetZAxis(vector3 v) |
143 | 0 | { |
144 | 0 | _zAxis = v; |
145 | 0 | } |
146 | | |
147 | | double OBFloatGrid::Inject(double x, double y, double z) |
148 | 0 | { |
149 | 0 | if (_values.empty()) |
150 | 0 | return 0.0; |
151 | | |
152 | 0 | if( x<=_xmin || x>=_xmax |
153 | 0 | || y<=_ymin || y>=_ymax |
154 | 0 | || z<=_zmin || z>=_zmax ) return 0.0; |
155 | | |
156 | 0 | return(_values[CoordsToIndex(x, y, z)]); |
157 | 0 | } |
158 | | |
159 | | void OBFloatGrid::IndexToCoords(int idx, double &x, double &y, double &z) |
160 | 0 | { |
161 | 0 | int grid_x, grid_y, grid_z; |
162 | |
|
163 | 0 | grid_z = idx % _zdim; |
164 | 0 | grid_x = static_cast<int>(idx / (_ydim * _zdim)); |
165 | 0 | grid_y = static_cast<int>((idx - (grid_x * _ydim * _zdim)) / _zdim); |
166 | |
|
167 | 0 | x = (grid_x * _spacing + _xmin) + _halfSpace; |
168 | 0 | y = (grid_y * _spacing + _ymin) + _halfSpace; |
169 | 0 | z = (grid_z * _spacing + _zmin) + _halfSpace; |
170 | 0 | } |
171 | | |
172 | | int OBFloatGrid::CoordsToIndex(double x, double y, double z) |
173 | 0 | { |
174 | 0 | int gx=static_cast<int>((x-_xmin)*_inv_spa); |
175 | 0 | int gy=static_cast<int>((y-_ymin)*_inv_spa); |
176 | 0 | int gz=static_cast<int>((z-_zmin)*_inv_spa); |
177 | |
|
178 | 0 | return((gx*_ydim*_zdim) + (gy*_zdim) + gz); |
179 | 0 | } |
180 | | |
181 | | void OBFloatGrid::CoordsToIndex(int *idx,double *c) |
182 | 0 | { |
183 | 0 | idx[0]=static_cast<int>((c[0]-_xmin)*_inv_spa); |
184 | 0 | idx[1]=static_cast<int>((c[1]-_ymin)*_inv_spa); |
185 | 0 | idx[2]=static_cast<int>((c[2]-_zmin)*_inv_spa); |
186 | 0 | } |
187 | | |
188 | | double OBFloatGrid::Interpolate(double x, double y, double z) |
189 | 0 | { |
190 | 0 | if (_values.empty()) |
191 | 0 | return 0.0; |
192 | | |
193 | 0 | int n,igx,igy,igz; |
194 | 0 | double yzdim; |
195 | 0 | double gx,gy,gz,fgx,fgy,fgz; |
196 | 0 | double ax,ay,az,bx,by,bz; |
197 | 0 | double AyA,ByA,AyB,ByB,Az,Bz; |
198 | |
|
199 | 0 | if( x<=_xmin || x>=_xmax |
200 | 0 | || y<=_ymin || y>=_ymax |
201 | 0 | || z<=_zmin || z>=_zmax ) return 0.0; |
202 | | |
203 | 0 | yzdim = _ydim*_zdim; |
204 | | |
205 | | /* calculate grid voxel and fractional offsets */ |
206 | 0 | gx=(x-_xmin-_halfSpace)*_inv_spa; |
207 | 0 | if (gx<0) |
208 | 0 | gx=0; |
209 | 0 | igx=static_cast<int>(gx); |
210 | 0 | fgx=gx-static_cast<double>(igx); |
211 | 0 | gy=(y-_ymin-_halfSpace)*_inv_spa; |
212 | 0 | if (gy<0) |
213 | 0 | gy=0; |
214 | 0 | igy=static_cast<int>(gy); |
215 | 0 | fgy= gy - static_cast<double>(igy); |
216 | 0 | gz=(z-_zmin-_halfSpace)*_inv_spa; |
217 | 0 | if (gz<0) |
218 | 0 | gz=0; |
219 | 0 | igz=static_cast<int>(gz); |
220 | 0 | fgz= gz - static_cast<double>(igz); |
221 | | |
222 | | // Calculate the index of the nearest point |
223 | 0 | n=static_cast<int>(igx*yzdim + igy*_zdim + igz); |
224 | |
|
225 | 0 | if ((n+1+_zdim+yzdim) >= (yzdim*_xdim)) |
226 | 0 | return 0.0; |
227 | | |
228 | | /* calculate linear weightings */ |
229 | 0 | ax=1.0-fgx; |
230 | 0 | bx=fgx; |
231 | 0 | ay=1.0-fgy; |
232 | 0 | by=fgy; |
233 | 0 | az=1.0-fgz; |
234 | 0 | bz=fgz; |
235 | | |
236 | | /* calculate interpolated value */ |
237 | 0 | AyA=az*_values[n ]+bz*_values[(n+1) ]; |
238 | 0 | ByA=az*_values[n+_zdim]+bz*_values[(n+1+_zdim) ]; |
239 | |
|
240 | 0 | Az=ay*AyA+by*ByA; |
241 | |
|
242 | 0 | AyB=az*_values[static_cast<int>(n +yzdim)] + |
243 | 0 | bz*_values[static_cast<int>(n+1 +yzdim)]; |
244 | 0 | ByB=az*_values[static_cast<int>(n+_zdim+yzdim)] + |
245 | 0 | bz*_values[static_cast<int>(n+1+_zdim+yzdim)]; |
246 | 0 | Bz=ay*AyB+by*ByB; |
247 | |
|
248 | 0 | return(ax*Az+bx*Bz); |
249 | 0 | } |
250 | | |
251 | | std::vector<double> OBFloatGrid::GetDataVector() |
252 | 0 | { |
253 | 0 | return _values; |
254 | 0 | } |
255 | | |
256 | | void OBFloatGrid::SetVals(const std::vector<double> & vals) |
257 | 0 | { |
258 | 0 | _values.clear(); |
259 | 0 | _values = vals; |
260 | 0 | } |
261 | | |
262 | | double OBFloatGrid::InterpolateDerivatives(double x,double y,double z,double *derivatives) |
263 | 0 | { |
264 | 0 | int n,igx,igy,igz; |
265 | 0 | double yzdim; |
266 | 0 | double gx,gy,gz,fgx,fgy,fgz; |
267 | 0 | double ax,ay,az,bx,by,bz; |
268 | 0 | double AyA,ByA,AyB,ByB,Az,Bz; |
269 | 0 | double energy,fx,fy,fz; |
270 | |
|
271 | 0 | if( x<=_xmin || x>=_xmax |
272 | 0 | || y<=_ymin || y>=_ymax |
273 | 0 | || z<=_zmin || z>=_zmax ) return 0.0; |
274 | | |
275 | 0 | yzdim = _ydim*_zdim; |
276 | | |
277 | | /* calculate grid voxel and fractional offsets */ |
278 | 0 | gx=(x-_xmin-_halfSpace)*_inv_spa; |
279 | 0 | if (gx<0) |
280 | 0 | gx=0; |
281 | 0 | igx=static_cast<int>(gx); |
282 | 0 | fgx=gx-(double)igx; |
283 | 0 | gy=(y-_ymin-_halfSpace)*_inv_spa; |
284 | 0 | if (gy<0) |
285 | 0 | gy=0; |
286 | 0 | igy=static_cast<int>(gy); |
287 | 0 | fgy= gy - (double) igy; |
288 | 0 | gz=(z-_zmin-_halfSpace)*_inv_spa; |
289 | 0 | if (gz<0) |
290 | 0 | gz=0; |
291 | 0 | igz=static_cast<int>(gz); |
292 | 0 | fgz= gz - (double) igz; |
293 | |
|
294 | 0 | n=static_cast<int>(igx*yzdim + igy*_zdim + igz); |
295 | | /* calculate linear weightings */ |
296 | 0 | ax=1.0-fgx; |
297 | 0 | bx=fgx; |
298 | 0 | ay=1.0-fgy; |
299 | 0 | by=fgy; |
300 | 0 | az=1.0-fgz; |
301 | 0 | bz=fgz; |
302 | | |
303 | | /* calculate interpolated value */ |
304 | 0 | AyA=az*_values[n ]+bx*_values[n+1 ]; |
305 | 0 | ByA=az*_values[n+_zdim]+bx*_values[(n+1+_zdim) ]; |
306 | |
|
307 | 0 | Az=ay*AyA+by*ByA; |
308 | |
|
309 | 0 | AyB=az*_values[static_cast<int>(n +yzdim)]+ |
310 | 0 | bz*_values[static_cast<int>(n+1 +yzdim)]; |
311 | 0 | ByB=az*_values[static_cast<int>(n+_zdim+yzdim)]+ |
312 | 0 | bz*_values[static_cast<int>(n+1+_zdim+yzdim)]; |
313 | 0 | Bz=ay*AyB+by*ByB; |
314 | |
|
315 | 0 | energy = ax*Az+bx*Bz; |
316 | | |
317 | | //calculate derivatives |
318 | |
|
319 | 0 | fz=-Az+Bz; |
320 | |
|
321 | 0 | Az=-AyA+ByA; |
322 | 0 | Bz=-AyB+ByB; |
323 | |
|
324 | 0 | fy=az*Az+bz*Bz; |
325 | |
|
326 | 0 | AyA=-_values[n ]+_values[(n+1) ]; |
327 | 0 | ByA=-_values[n+_zdim ]+_values[(n+1+_zdim)]; |
328 | |
|
329 | 0 | Az=ay*AyA+by*ByA; |
330 | |
|
331 | 0 | AyB=-_values[static_cast<int>(n +yzdim)]+ |
332 | 0 | _values[static_cast<int>(n+1 +yzdim)]; |
333 | 0 | ByB=-_values[static_cast<int>(n+_zdim+yzdim)]+ |
334 | 0 | _values[static_cast<int>(n+1+_zdim+yzdim)]; |
335 | |
|
336 | 0 | Bz=ay*AyB+by*ByB; |
337 | |
|
338 | 0 | fx=ax*Az+bx*Bz; |
339 | |
|
340 | 0 | derivatives[0] += fx; |
341 | 0 | derivatives[1] += fy; |
342 | 0 | derivatives[2] += fz; |
343 | |
|
344 | 0 | return(energy); |
345 | 0 | } |
346 | | |
347 | | ostream& operator<< ( ostream &os, const OBFloatGrid& fg) |
348 | 0 | { |
349 | | //@todo: this code stores the data in way that depends on |
350 | | // the bit representation of floating-point numbers. One can say |
351 | | // it's OK because IEEE754 is a widely accepted standard, but then |
352 | | // one should at least make it write the data in an endianness- |
353 | | // independent way. Of course this comment applies also to |
354 | | // the operator>> below. |
355 | 0 | os.write((const char*)&fg._xmin,sizeof(double)); |
356 | 0 | os.write((const char*)&fg._xmax,sizeof(double)); |
357 | 0 | os.write((const char*)&fg._ymin,sizeof(double)); |
358 | 0 | os.write((const char*)&fg._ymax,sizeof(double)); |
359 | 0 | os.write((const char*)&fg._zmin,sizeof(double)); |
360 | 0 | os.write((const char*)&fg._zmax,sizeof(double)); |
361 | |
|
362 | 0 | os.write((const char*)&fg._midx,sizeof(double)); |
363 | 0 | os.write((const char*)&fg._midy,sizeof(double)); |
364 | 0 | os.write((const char*)&fg._midz,sizeof(double)); |
365 | 0 | os.write((const char*)&fg._inv_spa,sizeof(double)); |
366 | 0 | os.write((const char*)&fg._spacing,sizeof(double)); |
367 | 0 | os.write((const char*)&fg._xdim,sizeof(int)); |
368 | 0 | os.write((const char*)&fg._ydim,sizeof(int)); |
369 | 0 | os.write((const char*)&fg._zdim,sizeof(int)); |
370 | 0 | os.write((const char*)&fg._values[0], |
371 | 0 | (sizeof(double)*(fg._xdim*fg._ydim*fg._zdim))); |
372 | |
|
373 | 0 | return(os); |
374 | 0 | } |
375 | | |
376 | | istream& operator>> ( istream &is,OBFloatGrid& fg) |
377 | 0 | { |
378 | 0 | is.read((char*)&fg._xmin,sizeof(double)); |
379 | 0 | is.read((char*)&fg._xmax,sizeof(double)); |
380 | 0 | is.read((char*)&fg._ymin,sizeof(double)); |
381 | 0 | is.read((char*)&fg._ymax,sizeof(double)); |
382 | 0 | is.read((char*)&fg._zmin,sizeof(double)); |
383 | 0 | is.read((char*)&fg._zmax,sizeof(double)); |
384 | |
|
385 | 0 | is.read((char*)&fg._midx,sizeof(double)); |
386 | 0 | is.read((char*)&fg._midy,sizeof(double)); |
387 | 0 | is.read((char*)&fg._midz,sizeof(double)); |
388 | 0 | is.read((char*)&fg._inv_spa,sizeof(double)); |
389 | 0 | is.read((char*)&fg._spacing,sizeof(double)); |
390 | 0 | is.read((char*)&fg._xdim,sizeof(int)); |
391 | 0 | is.read((char*)&fg._ydim,sizeof(int)); |
392 | 0 | is.read((char*)&fg._zdim,sizeof(int)); |
393 | 0 | int size = fg._xdim*fg._ydim*fg._zdim; |
394 | 0 | fg._values.resize(size); |
395 | 0 | size *= (int) sizeof(double); |
396 | |
|
397 | 0 | is.read((char*)&fg._values[0],size); |
398 | 0 | fg._halfSpace= fg._spacing/2.0; |
399 | |
|
400 | 0 | return(is); |
401 | 0 | } |
402 | | |
403 | | void OBProxGrid::Setup(OBMol &mol,OBMol &box,double cutoff,double res) |
404 | 0 | { |
405 | 0 | this->Init(box); // handle in the base class |
406 | |
|
407 | 0 | _inc = res; // 1/2 angstrom resolution |
408 | |
|
409 | 0 | _nxinc = (int) floor((_xmax - _xmin)/0.5); |
410 | 0 | _nyinc = (int) floor((_ymax - _ymin)/0.5); |
411 | 0 | _nzinc = (int) floor((_zmax - _zmin)/0.5); |
412 | 0 | _maxinc = _nxinc*_nyinc*_nzinc; |
413 | |
|
414 | 0 | int j,size = _nxinc*_nyinc*_nzinc; |
415 | 0 | cell.resize(size); |
416 | 0 | for (unsigned int num = 0; num < cell.size(); ++num) |
417 | 0 | cell[num].resize(0); |
418 | |
|
419 | 0 | cutoff *= cutoff; //don't do sqrts |
420 | |
|
421 | 0 | int k,l,m; |
422 | 0 | double x,y,z,dx_2,dy_2; |
423 | 0 | double *c = mol.GetCoordinates(); |
424 | 0 | size = mol.NumAtoms()*3; |
425 | |
|
426 | 0 | OBAtom *atom; |
427 | 0 | vector<OBAtom*>::iterator i; |
428 | 0 | for (atom = mol.BeginAtom(i),j=0;atom;atom = mol.NextAtom(i),j+=3) |
429 | 0 | if (PointIsInBox(c[j],c[j+1],c[j+2])) |
430 | 0 | for (x = _xmin+(_inc/2.0),k=0;k < _nxinc;x+=_inc,++k) |
431 | 0 | if ((dx_2 = SQUARE(c[j]-x)) < cutoff) |
432 | 0 | for (y = _ymin+(_inc/2.0),l=0;l < _nyinc;y+=_inc,++l) |
433 | 0 | if ((dx_2+(dy_2 = SQUARE(c[j+1]-y))) < cutoff) |
434 | 0 | for (z = _zmin+(_inc/2.0),m=0;m < _nzinc;z+=_inc,++m) |
435 | 0 | if ((dx_2+dy_2+SQUARE(c[j+2]-z)) < cutoff) |
436 | 0 | cell[(k*_nyinc*_nzinc)+(l*_nzinc)+m].push_back(atom->GetIdx()); |
437 | |
|
438 | 0 | _inc = 1/_inc; |
439 | 0 | } |
440 | | |
441 | | void OBProxGrid::Setup(OBMol &mol,OBMol &box,double cutoff,vector<bool> &use, |
442 | | double res) |
443 | 0 | { |
444 | 0 | this->Init(box); // handle in the base class |
445 | |
|
446 | 0 | _inc = res; // 1/2 angstrom resolution |
447 | |
|
448 | 0 | _nxinc = (int) floor((_xmax - _xmin)/0.5); |
449 | 0 | _nyinc = (int) floor((_ymax - _ymin)/0.5); |
450 | 0 | _nzinc = (int) floor((_zmax - _zmin)/0.5); |
451 | 0 | _maxinc = _nxinc*_nyinc*_nzinc; |
452 | |
|
453 | 0 | int j,size = _nxinc*_nyinc*_nzinc; |
454 | 0 | cell.resize(size); |
455 | 0 | cutoff *= cutoff; //don't do sqrts |
456 | |
|
457 | 0 | int k,l,m; |
458 | 0 | double x,y,z,dx_2,dy_2; |
459 | 0 | double *c = mol.GetCoordinates(); |
460 | 0 | size = mol.NumAtoms()*3; |
461 | |
|
462 | 0 | OBAtom *atom; |
463 | 0 | vector<OBAtom*>::iterator i; |
464 | 0 | for (atom = mol.BeginAtom(i),j=0;atom;atom = mol.NextAtom(i),j+=3) |
465 | 0 | if (use[atom->GetIdx()]) |
466 | 0 | if (PointIsInBox(c[j],c[j+1],c[j+2])) |
467 | 0 | for (x = _xmin+(_inc/2.0),k=0;k < _nxinc;x+=_inc,++k) |
468 | 0 | if ((dx_2 = SQUARE(c[j]-x)) < cutoff) |
469 | 0 | for (y = _ymin+(_inc/2.0),l=0;l < _nyinc;y+=_inc,++l) |
470 | 0 | if ((dx_2+(dy_2 = SQUARE(c[j+1]-y))) < cutoff) |
471 | 0 | for (z = _zmin+(_inc/2.0),m=0;m < _nzinc;z+=_inc,++m) |
472 | 0 | if ((dx_2+dy_2+SQUARE(c[j+2]-z)) < cutoff) |
473 | 0 | cell[(k*_nyinc*_nzinc)+(l*_nzinc)+m].push_back(atom->GetIdx()); |
474 | |
|
475 | 0 | _inc = 1/_inc; |
476 | 0 | } |
477 | | |
478 | | vector<int> *OBProxGrid::GetProxVector(double x,double y,double z) |
479 | 0 | { |
480 | 0 | if (x < _xmin || x > _xmax) |
481 | 0 | return nullptr; |
482 | 0 | if (y < _ymin || y > _ymax) |
483 | 0 | return nullptr; |
484 | 0 | if (z < _zmin || z > _zmax) |
485 | 0 | return nullptr; |
486 | | |
487 | 0 | x -= _xmin; |
488 | 0 | y -= _ymin; |
489 | 0 | z -= _zmin; |
490 | 0 | int i,j,k,idx; |
491 | 0 | i = (int) (x*_inc); |
492 | 0 | j = (int) (y*_inc); |
493 | 0 | k = (int) (z*_inc); |
494 | 0 | idx = (i*_nyinc*_nzinc)+(j*_nzinc)+k; |
495 | 0 | if (idx >= _maxinc) |
496 | 0 | return nullptr; |
497 | | |
498 | 0 | return(&cell[idx]); |
499 | 0 | } |
500 | | |
501 | | vector<int> *OBProxGrid::GetProxVector(double *c) |
502 | 0 | { |
503 | 0 | double x,y,z; |
504 | 0 | x = c[0]; |
505 | 0 | y = c[1]; |
506 | 0 | z = c[2]; |
507 | |
|
508 | 0 | return( GetProxVector(x, y, z) ); |
509 | 0 | } |
510 | | |
511 | | } // end namespace OpenBabel |
512 | | |
513 | | //! \file grid.cpp |
514 | | //! \brief Handle grids of values. |
515 | | |