1 /* Copyright (C) 2005-2007 The Chemistry Development Kit (CDK) project 2 * 3 * Contact: cdk-devel@lists.sourceforge.net 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public License 7 * as published by the Free Software Foundation; either version 2.1 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 package org.openscience.cdk.tools; 21 22 import java.io.BufferedWriter; 23 import java.io.FileWriter; 24 import java.io.IOException; 25 26 import javax.vecmath.Point3d; 27 28 /** 29 * Generates a grid of points in 3D space within given boundaries. 30 * 31 * @author cho 32 * @cdk.githash 33 * @cdk.created 2005-09-30 34 */ 35 public class GridGenerator { 36 37 double latticeConstant = 0.5; 38 double extendGrid = 2; 39 double[][][] grid = null; 40 double[] gridArray = null; 41 double maxx = 0; 42 double maxy = 0; 43 double maxz = 0; 44 double minx = 0; 45 double miny = 0; 46 double minz = 0; 47 int[] dim = {0, 0, 0}; 48 GridGenerator()49 public GridGenerator() {} 50 GridGenerator(double min, double max)51 public GridGenerator(double min, double max) { 52 setDimension(min, max); 53 generateGrid(); 54 } 55 56 /** 57 * @param initialValue used as initial value for the grid points 58 */ GridGenerator(double min, double max, double initialValue)59 public GridGenerator(double min, double max, double initialValue) { 60 setDimension(min, max); 61 generateGrid(); 62 initializeGrid(initialValue); 63 } 64 GridGenerator(double[] minMax, double initialValue, boolean cubicGridFlag)65 public GridGenerator(double[] minMax, double initialValue, boolean cubicGridFlag) { 66 setDimension(minMax, cubicGridFlag); 67 generateGrid(); 68 initializeGrid(initialValue); 69 } 70 71 /** 72 * Method sets the maximal 3d dimensions to given min and max values. 73 */ setDimension(double min, double max)74 public void setDimension(double min, double max) { 75 this.minx = min; 76 this.maxx = max; 77 this.miny = min; 78 this.maxy = max; 79 this.minz = min; 80 this.maxz = max; 81 } 82 83 /** 84 * Method sets the maximal 3d dimensions to given min and max values. 85 */ setDimension(double[] minMax, boolean cubicGridFlag)86 public void setDimension(double[] minMax, boolean cubicGridFlag) { 87 if (cubicGridFlag) { 88 double min = minMax[0]; 89 double max = minMax[0]; 90 for (int i = 0; i < minMax.length; i++) { 91 if (minMax[i] < min) { 92 min = minMax[i]; 93 } else if (minMax[i] > max) { 94 max = minMax[i]; 95 } 96 } 97 setDimension(min, max); 98 } else { 99 this.minx = minMax[0]; 100 this.maxx = minMax[1]; 101 this.miny = minMax[2]; 102 this.maxy = minMax[3]; 103 this.minz = minMax[4]; 104 this.maxz = minMax[5]; 105 } 106 } 107 108 /** 109 * Method sets the maximal 3d dimensions to given min and max values. 110 */ setDimension(double minx, double maxx, double miny, double maxy, double minz, double maxz)111 public void setDimension(double minx, double maxx, double miny, double maxy, double minz, double maxz) { 112 this.minx = minx; 113 this.maxx = maxx; 114 this.miny = miny; 115 this.maxy = maxy; 116 this.minz = minz; 117 this.maxz = maxz; 118 } 119 120 /** 121 * Main method creates a grid between given boundaries (dimensions). 122 * The grid my be extended over the given boundaries with the 123 * variable extendGrid. 124 */ generateGrid()125 public void generateGrid() { 126 minx = minx - extendGrid; 127 maxx = maxx + extendGrid; 128 miny = miny - extendGrid; 129 maxy = maxy + extendGrid; 130 minz = minz - extendGrid; 131 maxz = maxz + extendGrid; 132 133 dim[0] = (int) Math.round(Math.abs(maxx - minx) / latticeConstant); 134 dim[1] = (int) Math.round(Math.abs(maxy - miny) / latticeConstant); 135 dim[2] = (int) Math.round(Math.abs(maxz - minz) / latticeConstant); 136 137 grid = new double[dim[0] + 1][dim[1] + 1][dim[2] + 1]; 138 } 139 140 /** 141 * Method initialise the given grid points with a value. 142 */ initializeGrid(double value)143 public void initializeGrid(double value) { 144 for (int i = 0; i < grid.length; i++) { 145 for (int j = 0; j < grid[0].length; j++) { 146 for (int k = 0; k < grid[0][0].length; k++) { 147 grid[k][j][i] = value; 148 } 149 } 150 } 151 } 152 153 /** 154 * Method initialise the given grid points with a value. 155 */ initializeGrid(double grid[][][], double value)156 public double[][][] initializeGrid(double grid[][][], double value) { 157 for (int i = 0; i < grid.length; i++) { 158 for (int j = 0; j < grid[0].length; j++) { 159 for (int k = 0; k < grid[0][0].length; k++) { 160 grid[k][j][i] = value; 161 } 162 } 163 } 164 return grid; 165 } 166 167 /** 168 * Method transforms the grid to an array. 169 */ gridToGridArray(double[][][] grid)170 public double[] gridToGridArray(double[][][] grid) { 171 if (grid == null) { 172 grid = this.grid; 173 } 174 gridArray = new double[dim[0] * dim[1] * dim[2] + 3]; 175 int dimCounter = 0; 176 for (int z = 0; z < grid[0][0].length; z++) { 177 for (int y = 0; y < grid[0].length; y++) { 178 for (int x = 0; x < grid.length; x++) { 179 gridArray[dimCounter] = grid[x][y][z]; 180 dimCounter++; 181 } 182 } 183 } 184 return gridArray; 185 } 186 187 /** 188 * Method calculates coordinates from a given grid point. 189 */ getCoordinatesFromGridPoint(Point3d gridPoint)190 public Point3d getCoordinatesFromGridPoint(Point3d gridPoint) { 191 double dx = minx + latticeConstant * gridPoint.x; 192 double dy = miny + latticeConstant * gridPoint.y; 193 double dz = minz + latticeConstant * gridPoint.z; 194 return new Point3d(dx, dy, dz); 195 } 196 197 /** 198 * Method calculates coordinates from a given grid array position. 199 */ getCoordinatesFromGridPoint(int gridPoint)200 public Point3d getCoordinatesFromGridPoint(int gridPoint) { 201 int dimCounter = 0; 202 Point3d point = new Point3d(0, 0, 0); 203 for (int z = 0; z < grid[0][0].length; z++) { 204 for (int y = 0; y < grid[0].length; y++) { 205 for (int x = 0; x < grid.length; x++) { 206 if (dimCounter == gridPoint) { 207 point.x = minx + latticeConstant * x; 208 point.y = miny + latticeConstant * y; 209 point.z = minz + latticeConstant * z; 210 return point; 211 } 212 dimCounter++; 213 } 214 } 215 } 216 return point; 217 } 218 219 /** 220 * Method calculates the nearest grid point from given coordinates. 221 */ getGridPointFrom3dCoordinates(Point3d coord)222 public Point3d getGridPointFrom3dCoordinates(Point3d coord) throws Exception { 223 Point3d gridPoint = new Point3d(); 224 225 if (coord.x >= minx & coord.x <= maxx) { 226 gridPoint.x = (int) Math.round(Math.abs(minx - coord.x) / latticeConstant); 227 } else { 228 throw new Exception("CDKGridError: Given coordinates are not in grid"); 229 } 230 if (coord.y >= miny & coord.y <= maxy) { 231 gridPoint.y = (int) Math.round(Math.abs(miny - coord.y) / latticeConstant); 232 } else { 233 throw new Exception("CDKGridError: Given coordinates are not in grid"); 234 } 235 if (coord.z >= minz & coord.z <= maxz) { 236 gridPoint.z = (int) Math.round(Math.abs(minz - coord.z) / latticeConstant); 237 } else { 238 throw new Exception("CDKGridError: Given coordinates are not in grid"); 239 } 240 241 return gridPoint; 242 } 243 244 /** 245 * Method transforms the grid into pmesh format. 246 */ writeGridInPmeshFormat(String outPutFileName)247 public void writeGridInPmeshFormat(String outPutFileName) throws IOException { 248 BufferedWriter writer = new BufferedWriter(new FileWriter(outPutFileName + ".pmesh")); 249 int numberOfGridPoints = grid.length * grid[0].length * grid[0][0].length; 250 writer.write(numberOfGridPoints + "\n"); 251 for (int z = 0; z < grid[0][0].length; z++) { 252 for (int y = 0; y < grid[0].length; y++) { 253 for (int x = 0; x < grid.length; x++) { 254 Point3d coords = getCoordinatesFromGridPoint(new Point3d(x, y, z)); 255 writer.write(coords.x + "\t" + coords.y + "\t" + coords.z + "\n"); 256 } 257 } 258 } 259 writer.close(); 260 } 261 262 /** 263 * Method transforms the grid into pmesh format. Only grid points 264 * with specific value defined with cutoff are considered. 265 * <pre>{@code 266 * cutoff <0, the values considered must be <=cutoff 267 * cutoff >0, the values considered must be >=cutoff 268 * }</pre> 269 */ writeGridInPmeshFormat(String outPutFileName, double cutOff)270 public void writeGridInPmeshFormat(String outPutFileName, double cutOff) throws IOException { 271 BufferedWriter writer = new BufferedWriter(new FileWriter(outPutFileName + ".pmesh")); 272 boolean negative = false; 273 if (cutOff < 0) { 274 negative = true; 275 } else { 276 negative = false; 277 } 278 int numberOfGridPoints = 0; 279 for (int z = 0; z < grid[0][0].length; z++) { 280 for (int y = 0; y < grid[0].length; y++) { 281 for (int x = 0; x < grid.length; x++) { 282 if (negative) { 283 if (grid[x][y][z] <= cutOff) { 284 numberOfGridPoints++; 285 } 286 } else { 287 if (grid[x][y][z] >= cutOff) { 288 numberOfGridPoints++; 289 } 290 } 291 } 292 } 293 } 294 writer.write(numberOfGridPoints + "\n"); 295 for (int z = 0; z < grid[0][0].length; z++) { 296 for (int y = 0; y < grid[0].length; y++) { 297 for (int x = 0; x < grid.length; x++) { 298 Point3d coords = getCoordinatesFromGridPoint(new Point3d(x, y, z)); 299 if (negative) { 300 if (grid[x][y][z] <= cutOff) { 301 writer.write(coords.x + "\t" + coords.y + "\t" + coords.z + "\n"); 302 } 303 } else { 304 if (grid[x][y][z] >= cutOff) { 305 writer.write(coords.x + "\t" + coords.y + "\t" + coords.z + "\n"); 306 } 307 } 308 } 309 } 310 } 311 writer.close(); 312 } 313 314 @Override toString()315 public String toString() { 316 return "Dim:" + dim + " SizeX:" + grid.length + " SizeY:" + grid[0].length + " SizeZ:" + grid[0][0].length 317 + "\nminx:" + minx + " maxx:" + maxx + "\nminy:" + miny + " maxy:" + maxy + "\nminz:" + minz + " maxz:" 318 + maxz; 319 } 320 321 /** 322 * @return Returns the dim. 323 */ getDim()324 public int[] getDim() { 325 return dim; 326 } 327 328 /** 329 * @param dim The dim to set. 330 */ setDim(int[] dim)331 public void setDim(int[] dim) { 332 this.dim = dim; 333 } 334 335 /** 336 * @return Returns the extendGrid. 337 */ getExtendGrid()338 public double getExtendGrid() { 339 return extendGrid; 340 } 341 342 /** 343 * @param extendGrid The extendGrid to set. 344 */ setExtendGrid(double extendGrid)345 public void setExtendGrid(double extendGrid) { 346 this.extendGrid = extendGrid; 347 } 348 349 /** 350 * @return Returns the grid. 351 */ getGrid()352 public double[][][] getGrid() { 353 return grid; 354 } 355 356 /** 357 * @param grid The grid to set. 358 */ setGrid(double[][][] grid)359 public void setGrid(double[][][] grid) { 360 this.grid = grid; 361 } 362 363 /** 364 * @return Returns the latticeConstant. 365 */ getLatticeConstant()366 public double getLatticeConstant() { 367 return latticeConstant; 368 } 369 370 /** 371 * @param latticeConstant The latticeConstant to set. 372 */ setLatticeConstant(double latticeConstant)373 public void setLatticeConstant(double latticeConstant) { 374 this.latticeConstant = latticeConstant; 375 } 376 377 /** 378 * @return Returns the gridArray. 379 */ getGridArray()380 public double[] getGridArray() { 381 return gridArray; 382 } 383 384 /** 385 * @return Returns the maxx. 386 */ getMaxx()387 public double getMaxx() { 388 return maxx; 389 } 390 391 /** 392 * @return Returns the maxy. 393 */ getMaxy()394 public double getMaxy() { 395 return maxy; 396 } 397 398 /** 399 * @return Returns the maxz. 400 */ getMaxz()401 public double getMaxz() { 402 return maxz; 403 } 404 405 /** 406 * @return Returns the minx. 407 */ getMinx()408 public double getMinx() { 409 return minx; 410 } 411 412 /** 413 * @return Returns the miny. 414 */ getMiny()415 public double getMiny() { 416 return miny; 417 } 418 419 /** 420 * @return Returns the minz. 421 */ getMinz()422 public double getMinz() { 423 return minz; 424 } 425 426 } 427