// $Id: Octree.java,v 1.4 2007/02/18 05:08:05 Sasha Buzko Exp $ // // Copyright (c) 2000-2003 San Diego Supercomputer Center (SDSC), // a facility operated jointly by the University of California, // San Diego (UCSD) and General Atomics, San Diego, California, USA. // // Users and possessors of this source code are hereby granted a // nonexclusive, royalty-free copyright and design patent license to // use this code in individual software. License is not granted for // commercial resale, in whole or in part, without prior written // permission from SDSC. This source is provided "AS IS" without express // or implied warranty of any kind. // // For further information, please see: http://mbt.sdsc.edu // // History: // $Log: Octree.java,v $ // Revision 1.4 2007/02/18 05:08:05 Sasha Buzko // *** empty log message *** // // Revision 1.3 2007/02/07 18:42:57 Sasha Buzko // *** empty log message *** // // Revision 1.2 2007/02/07 02:45:49 Sasha Buzko // *** empty log message *** // // Revision 1.1 2006/05/20 17:02:04 Sasha Buzko // Updated version // // Revision 1.1 2006/04/30 20:13:59 Sasha Buzko // New version of the app // // Revision 1.1 2006/04/15 19:42:26 Sasha Buzko // Initial commit // // Revision 1.2 2005/11/26 04:36:10 Administrator // *** empty log message *** // // Revision 1.1 2005/11/13 04:35:04 Administrator // *** empty log message *** // // Revision 1.5 2003/10/17 18:19:32 moreland // Fixed a javadoc comment. // // Revision 1.4 2003/10/01 21:11:51 agramada // Added methods needed by DerivedInformation class for derivation of // secondary structures. // // Revision 1.3 2003/07/17 16:40:32 agramada // Removed some comments. // // Revision 1.2 2003/07/11 20:23:05 agramada // Made get*Bonds methods return Bond objects instead of BondInfo. Removed // some coments. // // Revision 1.1 2003/07/11 18:17:53 moreland // Modifed Apostol's Octree classes to genate Bonds from the BondFactory // and in turn the StructureMap class. // // Revision 1.3 2003/07/07 23:02:47 agramada // Added a method to return a vector of covalent bonds rather than an array. // // Revision 1.2 2003/06/24 22:19:46 agramada // Reorganized the geometry package. Old classes removed, new classes added. // // Revision 1.1 2003/04/24 18:46:36 agramada // First version of the Octree class to be used for an efficient search of // the set of bonds between a set of atoms. // // Revision 1.2 2003/02/20 17:08:22 agramada // First working version. // // Revision 1.0 2003/02/20 23:38:39 agramada // package edu.sdsc.mbt.util; import java.util.*; import edu.sdsc.mbt.Bond; /** * Octree class constructed with recursion in mind. * Each child is itself a tree. *

* @author Apostol Gramada */ public class Octree { private int dimension; // Keep it general as long as practical. In practice, maximum 3. private int maxNumberOfChildren; private int numberOfChildren; private int childId; // Number from 0 to 2^dimension public String path; // Sequence of digits showing the path from root to this child private Octree parent = null; private Octree root = null; private Octree[] children = null; private OctreeDataItem[] dataItems = null; private double[] firstCorner; private double[] secondCorner; private double[] geometricalCenter; private double[] margin; private int weight; private int leafCutOff = 1; private boolean leaf = false; private double[] cellCenter; private double cellRadius; public int levels; private double[] size; private double[] mid; // Center of the cell private int majorAxis; // Axis with the maximum spatial extension private int minorAxis; // Axis with the minimal spatial extension public static int countChildren = 0; public static int countAppBondOp = 0; public static int rejectedPaths = 0; // // Constructors. // /** * Construct an octree as a child of "parent" in a tree rooted at * "root" with given data and corners. */ public Octree( Octree root, Octree parent, int id, OctreeDataItem[] data, double[] firstCorner, double[] secondCorner ) { this.root = root; this.childId = id; this.path = parent.path + id; this.dimension = root.getDimension(); // Assume dimension passed is the same as dimension of data // this.dataItems = data; this.firstCorner = firstCorner; this.secondCorner = secondCorner; this.parent = parent; this.maxNumberOfChildren = root.getMaxNumberOfChildren( ); // // Set the size in each direction. // double maxSize = 0.0; double minSize = 1.0E6; size = new double[ dimension ]; mid = new double[ dimension ]; cellRadius = 0.0; for ( int j=0; j maxSize ) { maxSize = size[j]; majorAxis = j; } if( size[j] < minSize ) { minSize = size[j]; minorAxis = j; } } cellRadius = Math.sqrt( cellRadius ); cellRadius /= 2.0; } /** * Constructor that is mostly used for instantiating the root tree. */ public Octree( int spaceDimension, OctreeDataItem[] data, double[] offset ) { // // Derive the domain spaned by the coordinates of the elements. // dimension = spaceDimension; // Assume dimension passed is the same as dimension of data dataItems = data; weight = data.length; margin = new double[ dimension ]; // System.out.println( "Root tree data length: " + dataItems.length ); firstCorner = new double[ dimension ]; secondCorner = new double[ dimension ]; for ( int i=0; i 0 ) build( ); } // // Methods. // /** * Build the whole tree recursively. */ public void build( ) { countChildren++; children = new Octree[ maxNumberOfChildren ]; Vector[] dataSets = new Vector[ maxNumberOfChildren ]; // Collects data for each child // double[] mid = new double[ dimension ]; double[] childSize = new double[ dimension ]; double[] corner2; int setFirstBit = 1; // // Determine the center of the parallelepiped. // for ( int i=0; i leafCutOff ) { for ( int i=0; i 0 ) { l = 0; tmpData = new OctreeDataItem[ dataSize ]; dataIterator = dataSets[i].iterator( ); while ( dataIterator.hasNext() ) { tmpData[l] = (OctreeDataItem) dataIterator.next( ); l++; } // // Calculate the second corner of the child // corner2 = new double[ dimension ]; testBit = 1; for ( int j=dimension-1; j>=0; j-- ) { if ( (i & testBit) > 0 ) { corner2[j] = mid[j] - childSize[j]; } else { corner2[j] = mid[j] + childSize[j]; } testBit <<= 1; } children[i] = new Octree( this.root, this, i, null, mid, corner2 ); children[i].build( tmpData ); } numberOfChildren++; } } else { setLeafFlag( true ); // System.out.println( "Warning: Root is also leaf " ); } // // Set the geometrical center of this node. // // setGeometricalCenter( ); // System.out.println( "GC: (" + geometricalCenter[0] + "," + geometricalCenter[1] + "," + geometricalCenter[2] + ")" ); } /** * Build a subtree recursively. */ public void build( OctreeDataItem[] data ) { countChildren++; weight = data.length; if ( data.length <= leafCutOff ) { setData( data ); leaf = true; return; } children = new Octree[ maxNumberOfChildren ]; Vector[] dataSets = new Vector[ maxNumberOfChildren ]; // Collects data for each child // double[] mid = new double[ dimension ]; double[] childSize = new double[ dimension ]; double[] corner2; int setFirstBit = 1; // // Determine the center of the parallelepiped. // for( int i=0; i 0 ) { l = 0; tmpData = new OctreeDataItem[ dataSize ]; dataIterator = dataSets[i].iterator( ); while( dataIterator.hasNext() ) { tmpData[l] = (OctreeDataItem) dataIterator.next( ); l++; } // // Calculate the second corner of the child. // corner2 = new double[ dimension ]; testBit = 1; for( int j=dimension-1; j>=0; j-- ) { if ( (i & testBit) > 0 ) { corner2[j] = mid[j] - childSize[j]; } else { corner2[j] = mid[j] + childSize[j]; } testBit <<= 1; } children[i] = new Octree( this.root, this, i, null, mid, corner2 ); children[i].build( tmpData ); numberOfChildren++; } } } /** * Methods to operate with vectors. */ public final double getDistance( double[] coord1, double[] coord2 ) { // // Assume that the two coords have the same dimensionality. // double distance = 0.0; for( int i = 0; i < coord1.length; i++ ) { distance += (coord2[i] - coord1[i]) * (coord2[i] - coord1[i]); } distance = Math.sqrt( distance ); return distance; } /** * ??? */ public final double[] add( double[] v1, double[] v2 ) { double[] sum = new double[ v1.length ]; for( int i=0; i cutOff ) return; if ( leaf ) { for ( int j=0; j cutOff ) return; if ( leaf ) { for ( int j=0; j