// @(#)root/mathcore:$Id$
// Authors: Marian Ivanov and Alexandru Bercuci 04/03/2005

/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TKDTree.h"
#include "TRandom.h"

#include "TString.h"
#include <string.h>
#include <limits>

templateClassImp(TKDTree)


//////////////////////////////////////////////////////////////////////////
//
//                      kd-tree and its implementation in TKDTree
//
// Contents:
// 1. What is kd-tree
// 2. How to cosntruct kdtree - Pseudo code
// 3. Using TKDTree
//    a. Creating the kd-tree and setting the data
//    b. Navigating the kd-tree
// 4. TKDTree implementation - technical details
//    a. The order of nodes in internal arrays
//    b. Division algorithm
//    c. The order of nodes in boundary related arrays
//
//
//
// 1. What is kdtree ? ( http://en.wikipedia.org/wiki/Kd-tree )
//
// In computer science, a kd-tree (short for k-dimensional tree) is a space-partitioning data structure
// for organizing points in a k-dimensional space. kd-trees are a useful data structure for several
// applications, such as searches involving a multidimensional search key (e.g. range searches and
// nearest neighbour searches). kd-trees are a special case of BSP trees.
//
// A kd-tree uses only splitting planes that are perpendicular to one of the coordinate system axes.
// This differs from BSP trees, in which arbitrary splitting planes can be used.
// In addition, in the typical definition every node of a kd-tree, from the root to the leaves, stores a point.
// This differs from BSP trees, in which leaves are typically the only nodes that contain points
// (or other geometric primitives). As a consequence, each splitting plane must go through one of
// the points in the kd-tree. kd-trees are a variant that store data only in leaf nodes.
//
// 2. Constructing a classical kd-tree ( Pseudo code)
//
// Since there are many possible ways to choose axis-aligned splitting planes, there are many different ways
// to construct kd-trees. The canonical method of kd-tree construction has the following constraints:
//
//     * As one moves down the tree, one cycles through the axes used to select the splitting planes.
//      (For example, the root would have an x-aligned plane, the root's children would both have y-aligned
//       planes, the root's grandchildren would all have z-aligned planes, and so on.)
//     * At each step, the point selected to create the splitting plane is the median of the points being
//       put into the kd-tree, with respect to their coordinates in the axis being used. (Note the assumption
//       that we feed the entire set of points into the algorithm up-front.)
//
// This method leads to a balanced kd-tree, in which each leaf node is about the same distance from the root.
// However, balanced trees are not necessarily optimal for all applications.
// The following pseudo-code illustrates this canonical construction procedure (NOTE, that the procedure used
// by the TKDTree class is a bit different, the following pseudo-code is given as a simple illustration of the
// concept):
//
// function kdtree (list of points pointList, int depth)
// {
//     if pointList is empty
//         return nil;
//     else
//     {
//         // Select axis based on depth so that axis cycles through all valid values
//         var int axis := depth mod k;
//
//         // Sort point list and choose median as pivot element
//         select median from pointList;
//
//         // Create node and construct subtrees
//         var tree_node node;
//         node.location := median;
//         node.leftChild := kdtree(points in pointList before median, depth+1);
//         node.rightChild := kdtree(points in pointList after median, depth+1);
//         return node;
//     }
// }
//
// Our construction method is optimized to save memory, and differs a bit from the constraints above.
// In particular, the division axis is chosen as the one with the biggest spread, and the point to create the
// splitting plane is chosen so, that one of the two subtrees contains exactly 2^k terminal nodes and is a
// perfectly balanced binary tree, and, while at the same time, trying to keep the number of terminal nodes
// in the 2 subtrees as close as possible. The following section gives more details about our implementation.
//
// 3. Using TKDTree
//
// 3a. Creating the tree and setting the data
//     The interface of the TKDTree, that allows to set input data, has been developped to simplify using it
//     together with TTree::Draw() functions. That's why the data has to be provided column-wise. For example:
//     {
//     TTree *datatree = ...
//     ...
//     datatree->Draw("x:y:z", "selection", "goff");
//     //now make a kd-tree on the drawn variables
//     TKDTreeID *kdtree = new TKDTreeID(npoints, 3, 1);
//     kdtree->SetData(0, datatree->GetV1());
//     kdtree->SetData(1, datatree->GetV2());
//     kdtree->SetData(2, datatree->GetV3());
//     kdtree->Build();
//     }
//     NOTE, that this implementation of kd-tree doesn't support adding new points after the tree has been built
//     Of course, it's not necessary to use TTree::Draw(). What is important, is to have data columnwise.
//     An example with regular arrays:
//     {
//     Int_t npoints = 100000;
//     Int_t ndim = 3;
//     Int_t bsize = 1;
//     Double_t xmin = -0.5;
//     Double_t xmax = 0.5;
//     Double_t *data0 = new Double_t[npoints];
//     Double_t *data1 = new Double_t[npoints];
//     Double_t *data2 = new Double_t[npoints];
//     Double_t *y     = new Double_t[npoints];
//     for (Int_t i=0; i<npoints; i++){
//        data0[i]=gRandom->Uniform(xmin, xmax);
//        data1[i]=gRandom->Uniform(xmin, xmax);
//        data2[i]=gRandom->Uniform(xmin, xmax);
//     }
//     TKDTreeID *kdtree = new TKDTreeID(npoints, ndim, bsize);
//     kdtree->SetData(0, data0);
//     kdtree->SetData(1, data1);
//     kdtree->SetData(2, data2);
//     kdtree->Build();
//     }
//
//     By default, the kd-tree doesn't own the data and doesn't delete it with itself. If you want the
//     data to be deleted together with the kd-tree, call TKDTree::SetOwner(kTRUE).
//
//     Most functions of the kd-tree don't require the original data to be present after the tree
//     has been built. Check the functions documentation for more details.
//
// 3b. Navigating the kd-tree
//
//     Nodes of the tree are indexed top to bottom, left to right. The root node has index 0. Functions
//     TKDTree::GetLeft(Index inode), TKDTree::GetRight(Index inode) and TKDTree::GetParent(Index inode)
//     allow to find the children and the parent of a given node.
//
//     For a given node, one can find the indexes of the original points, contained in this node,
//     by calling the GetNodePointsIndexes(Index inode) function. Additionally, for terminal nodes,
//     there is a function GetPointsIndexes(Index inode) that returns a pointer to the relevant
//     part of the index array. To find the number of point in the node
//     (not only terminal), call TKDTree::GetNpointsNode(Index inode).
//
// 4.  TKDtree implementation details - internal information, not needed to use the kd-tree.
//     4a. Order of nodes in the node information arrays:
//
// TKDtree is optimized to minimize memory consumption.
// Nodes of the TKDTree do not store pointers to the left and right children or to the parent node,
// but instead there are several 1-d arrays of size fNNodes with information about the nodes.
// The order of the nodes information in the arrays is described below. It's important to understand
// it, if one's class needs to store some kind of additional information on the per node basis, for
// example, the fit function parameters.
//
// Drawback:   Insertion to the TKDtree is not supported.
// Advantage:  Random access is supported
//
// As noted above, the construction of the kd-tree involves choosing the axis and the point on
// that axis to divide the remaining points approximately in half. The exact algorithm for choosing
// the division point is described in the next section. The sequence of divisions is
// recorded in the following arrays:
// fAxix[fNNodes]  - Division axis (0,1,2,3 ...)
// fValue[fNNodes] - Division value
//
// Given the index of a node in those arrays, it's easy to find the indices, corresponding to
// children nodes or the parent node:
// Suppose, the parent node is stored under the index inode. Then:
// Left child index  = inode*2+1
// Right child index =  (inode+1)*2
// Suppose, that the child node is stored under the index inode. Then:
// Parent index = inode/2
//
// Number of division nodes and number of terminals :
// fNNodes = (fNPoints/fBucketSize)
//
// The nodes are filled always from left side to the right side:
// Let inode be the index of a node, and irow - the index of a row
// The TKDTree looks the following way:
// Ideal case:
// Number of _terminal_ nodes = 2^N,  N=3
//
//            INode
// irow 0     0                                                                   -  1 inode
// irow 1     1                              2                                    -  2 inodes
// irow 2     3              4               5               6                    -  4 inodes
// irow 3     7       8      9      10       11     12       13      14           -  8 inodes
//
//
// Non ideal case:
// Number of _terminal_ nodes = 2^N+k,  N=3  k=1
//
//           INode
// irow 0     0                                                                   - 1 inode
// irow 1     1                              2                                    - 2 inodes
// irow 2     3              4               5               6                    - 3 inodes
// irow 3     7       8      9      10       11     12       13      14           - 8 inodes
// irow 4     15  16                                                              - 2 inodes
//
//
// 3b. The division algorithm:
//
// As described above, the kd-tree is built by repeatingly dividing the given set of points into
// 2 smaller sets. The cut is made on the axis with the biggest spread, and the value on the axis,
// on which the cut is performed, is chosen based on the following formula:
// Suppose, we want to divide n nodes into 2 groups, left and right. Then the left and right
// will have the following number of nodes:
//
// n=2^k+rest
//
// Left  = 2^k-1 +  ((rest>2^k-2) ?  2^k-2      : rest)
// Right = 2^k-1 +  ((rest>2^k-2) ?  rest-2^k-2 : 0)
//
// For example, let n_nodes=67. Then, the closest 2^k=64, 2^k-1=32, 2^k-2=16.
// Left node gets 32+3=35 sub-nodes, and the right node gets 32 sub-nodes
//
// The division process continues until all the nodes contain not more than a predefined number
// of points.
//
// 3c. The order of nodes in boundary-related arrays
//
// Some kd-tree based algorithms need to know the boundaries of each node. This information can
// be computed by calling the TKDTree::MakeBoundaries() function. It fills the following arrays:
//
// fRange : array containing the boundaries of the domain:
// | 1st dimension (min + max) | 2nd dimension (min + max) | ...
// fBoundaries : nodes boundaries
// | 1st node {1st dim * 2 elements | 2nd dim * 2 elements | ...} | 2nd node {...} | ...
// The nodes are arranged in the order described in section 3a.
//
//
// Note: the storage of the TKDTree in a file which include also the contained data is not
//       supported. One must store the data separatly in a file (e.g. using a TTree) and then
//       re-creating the TKDTree from the data, after having read them from the file
//////////////////////////////////////////////////////////////////////////


//_________________________________________________________________
template <typename  Index, typename Value>
TKDTree<Index, Value>::TKDTree() :
   TObject()
   ,fDataOwner(kFALSE)
   ,fNNodes(0)
   ,fTotalNodes(0)
   ,fNDim(0)
   ,fNDimm(0)
   ,fNPoints(0)
   ,fBucketSize(0)
   ,fAxis(0x0)
   ,fValue(0x0)
   ,fRange(0x0)
   ,fData(0x0)
   ,fBoundaries(0x0)
   ,fIndPoints(0x0)
   ,fRowT0(0)
   ,fCrossNode(0)
   ,fOffset(0)
{
// Default constructor. Nothing is built
}

template <typename  Index, typename Value>
TKDTree<Index, Value>::TKDTree(Index npoints, Index ndim, UInt_t bsize) :
   TObject()
   ,fDataOwner(0)
   ,fNNodes(0)
   ,fTotalNodes(0)
   ,fNDim(ndim)
   ,fNDimm(2*ndim)
   ,fNPoints(npoints)
   ,fBucketSize(bsize)
   ,fAxis(0x0)
   ,fValue(0x0)
   ,fRange(0x0)
   ,fData(0x0)
   ,fBoundaries(0x0)
   ,fIndPoints(0x0)
   ,fRowT0(0)
   ,fCrossNode(0)
   ,fOffset(0)
{
// Create the kd-tree of npoints from ndim-dimensional space. Parameter bsize stands for the
// maximal number of points in the terminal nodes (buckets).
// Proceed by calling one of the SetData() functions and then the Build() function
// Note, that updating the tree with new data after the Build() function has been called is
// not possible!

}

//_________________________________________________________________
template <typename  Index, typename Value>
TKDTree<Index, Value>::TKDTree(Index npoints, Index ndim, UInt_t bsize, Value **data) :
   TObject()
   ,fDataOwner(0)
   ,fNNodes(0)
   ,fTotalNodes(0)
   ,fNDim(ndim)
   ,fNDimm(2*ndim)
   ,fNPoints(npoints)
   ,fBucketSize(bsize)
   ,fAxis(0x0)
   ,fValue(0x0)
   ,fRange(0x0)
   ,fData(data) //Columnwise!!!!!
   ,fBoundaries(0x0)
   ,fIndPoints(0x0)
   ,fRowT0(0)
   ,fCrossNode(0)
   ,fOffset(0)
{
   // Create a kd-tree from the provided data array. This function only sets the data,
   // call Build() to build the tree!!!
   // Parameteres:
   // - npoints - total number of points. Adding points after the tree is built is not supported
   // - ndim    - number of dimensions
   // - bsize   - maximal number of points in the terminal nodes
   // - data    - the data array
   //
   // The data should be placed columnwise (like in a TTree).
   // The columnwise orientation is chosen to simplify the usage together with TTree::GetV1() like functions.
   // An example of filling such an array for a 2d case:
   // Double_t **data = new Double_t*[2];
   // data[0] = new Double_t[npoints];
   // data[1] = new Double_t[npoints];
   // for (Int_t i=0; i<npoints; i++){
   //    data[0][i]=gRandom->Uniform(-1, 1); //fill the x-coordinate
   //    data[1][i]=gRandom->Uniform(-1, 1); //fill the y-coordinate
   // }
   //
   // By default, the kd-tree doesn't own the data. If you want the kd-tree to delete the data array, call
   // kdtree->SetOwner(kTRUE).
   //


   //Build();
}

//_________________________________________________________________
template <typename  Index, typename Value>
TKDTree<Index, Value>::~TKDTree()
{
   // Destructor
   // By default, the original data is not owned by kd-tree and is not deleted with it.
   // If you want to delete the data along with the kd-tree, call SetOwner(kTRUE).

   if (fAxis) delete [] fAxis;
   if (fValue) delete [] fValue;
   if (fIndPoints) delete [] fIndPoints;
   if (fRange) delete [] fRange;
   if (fBoundaries) delete [] fBoundaries;
   if (fData) {
      if (fDataOwner==1){
         //the tree owns all the data
         for(int idim=0; idim<fNDim; idim++) delete [] fData[idim];
      }
      if (fDataOwner>0) {
         //the tree owns the array of pointers
         delete [] fData;
      }
   }
//   if (fDataOwner && fData){
//      for(int idim=0; idim<fNDim; idim++) delete [] fData[idim];
//      delete [] fData;
//   }
}


//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::Build()
{
   //
   // Build the kd-tree
   //
   // 1. calculate number of nodes
   // 2. calculate first terminal row
   // 3. initialize index array
   // 4. non recursive building of the binary tree
   //
   //
   // The tree is divided recursively. See class description, section 4b for the details
   // of the division alogrithm

   //1.
   fNNodes = fNPoints/fBucketSize-1;
   if (fNPoints%fBucketSize) fNNodes++;
   fTotalNodes = fNNodes + fNPoints/fBucketSize + ((fNPoints%fBucketSize)?1:0);
   //2.
   fRowT0=0;
   for ( ;(fNNodes+1)>(1<<fRowT0);fRowT0++) {}
   fRowT0-=1;
   //         2 = 2**0 + 1
   //         3 = 2**1 + 1
   //         4 = 2**1 + 2
   //         5 = 2**2 + 1
   //         6 = 2**2 + 2
   //         7 = 2**2 + 3
   //         8 = 2**2 + 4

   //3.
   // allocate space for boundaries
   fRange = new Value[2*fNDim];
   fIndPoints= new Index[fNPoints];
   for (Index i=0; i<fNPoints; i++) fIndPoints[i] = i;
   fAxis  = new UChar_t[fNNodes];
   fValue = new Value[fNNodes];
   //
   fCrossNode = (1<<(fRowT0+1))-1;
   if (fCrossNode<fNNodes) fCrossNode = 2*fCrossNode+1;
   //
   //  fOffset = (((fNNodes+1)-(1<<fRowT0)))*2;
   Int_t   over   = (fNNodes+1)-(1<<fRowT0);
   Int_t   filled = ((1<<fRowT0)-over)*fBucketSize;
   fOffset = fNPoints-filled;

   //
   //    printf("Row0      %d\n", fRowT0);
   //    printf("CrossNode %d\n", fCrossNode);
   //    printf("Offset    %d\n", fOffset);
   //
   //
   //4.
   //    stack for non recursive build - size 128 bytes enough
   Int_t rowStack[128];
   Int_t nodeStack[128];
   Int_t npointStack[128];
   Int_t posStack[128];
   Int_t currentIndex = 0;
   Int_t iter =0;
   rowStack[0]    = 0;
   nodeStack[0]   = 0;
   npointStack[0] = fNPoints;
   posStack[0]   = 0;
   //
   Int_t nbucketsall =0;
   while (currentIndex>=0){
      iter++;
      //
      Int_t npoints  = npointStack[currentIndex];
      if (npoints<=fBucketSize) {
         //printf("terminal node : index %d iter %d\n", currentIndex, iter);
         currentIndex--;
         nbucketsall++;
         continue; // terminal node
      }
      Int_t crow     = rowStack[currentIndex];
      Int_t cpos     = posStack[currentIndex];
      Int_t cnode    = nodeStack[currentIndex];
      //printf("currentIndex %d npoints %d node %d\n", currentIndex, npoints, cnode);
      //
      // divide points
      Int_t nbuckets0 = npoints/fBucketSize;           //current number of  buckets
      if (npoints%fBucketSize) nbuckets0++;            //
      Int_t restRows = fRowT0-rowStack[currentIndex];  // rest of fully occupied node row
      if (restRows<0) restRows =0;
      for (;nbuckets0>(2<<restRows); restRows++) {}
      Int_t nfull = 1<<restRows;
      Int_t nrest = nbuckets0-nfull;
      Int_t nleft =0, nright =0;
      //
      if (nrest>(nfull/2)){
         nleft  = nfull*fBucketSize;
         nright = npoints-nleft;
      }else{
         nright = nfull*fBucketSize/2;
         nleft  = npoints-nright;
      }

      //
      //find the axis with biggest spread
      Value maxspread=0;
      Value tempspread, min, max;
      Index axspread=0;
      Value *array;
      for (Int_t idim=0; idim<fNDim; idim++){
         array = fData[idim];
         Spread(npoints, array, fIndPoints+cpos, min, max);
         tempspread = max - min;
         if (maxspread < tempspread) {
            maxspread=tempspread;
            axspread = idim;
         }
         if(cnode) continue;
         //printf("set %d %6.3f %6.3f\n", idim, min, max);
         fRange[2*idim] = min; fRange[2*idim+1] = max;
      }
      array = fData[axspread];
      KOrdStat(npoints, array, nleft, fIndPoints+cpos);
      fAxis[cnode]  = axspread;
      fValue[cnode] = array[fIndPoints[cpos+nleft]];
      //printf("Set node %d : ax %d val %f\n", cnode, node->fAxis, node->fValue);
      //
      //
      npointStack[currentIndex] = nleft;
      rowStack[currentIndex]    = crow+1;
      posStack[currentIndex]    = cpos;
      nodeStack[currentIndex]   = cnode*2+1;
      currentIndex++;
      npointStack[currentIndex] = nright;
      rowStack[currentIndex]    = crow+1;
      posStack[currentIndex]    = cpos+nleft;
      nodeStack[currentIndex]   = (cnode*2)+2;
      //
      if (0){
         // consistency check
         Info("Build()", "%s", Form("points %d left %d right %d", npoints, nleft, nright));
         if (nleft<nright) Warning("Build", "Problem Left-Right");
         if (nleft<0 || nright<0) Warning("Build()", "Problem Negative number");
      }
   }
}

//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::FindNearestNeighbors(const Value *point, const Int_t kNN, Index *ind, Value *dist)
{
   //Find kNN nearest neighbors to the point in the first argument
   //Returns 1 on success, 0 on failure
   //Arrays ind and dist are provided by the user and are assumed to be at least kNN elements long


   if (!ind || !dist) {
      Error("FindNearestNeighbors", "Working arrays must be allocated by the user!");
      return;
   }
   for (Int_t i=0; i<kNN; i++){
      dist[i]=std::numeric_limits<Value>::max();
      ind[i]=-1;
   }
   MakeBoundariesExact();
   UpdateNearestNeighbors(0, point, kNN, ind, dist);

}

//_________________________________________________________________
template <typename Index, typename Value>
void TKDTree<Index, Value>::UpdateNearestNeighbors(Index inode, const Value *point, Int_t kNN, Index *ind, Value *dist)
{
   //Update the nearest neighbors values by examining the node inode

   Value min=0;
   Value max=0;
   DistanceToNode(point, inode, min, max);
   if (min > dist[kNN-1]){
      //there are no closer points in this node
      return;
   }
   if (IsTerminal(inode)) {
      //examine points one by one
      Index f1, l1, f2, l2;
      GetNodePointsIndexes(inode, f1, l1, f2, l2);
      for (Int_t ipoint=f1; ipoint<=l1; ipoint++){
         Double_t d = Distance(point, fIndPoints[ipoint]);
         if (d<dist[kNN-1]){
            //found a closer point
            Int_t ishift=0;
            while(ishift<kNN && d>dist[ishift])
               ishift++;
            //replace the neighbor #ishift with the found point
            //and shift the rest 1 index value to the right
            for (Int_t i=kNN-1; i>ishift; i--){
               dist[i]=dist[i-1];
               ind[i]=ind[i-1];
            }
            dist[ishift]=d;
            ind[ishift]=fIndPoints[ipoint];
         }
      }
      return;
   }
   if (point[fAxis[inode]]<fValue[inode]){
      //first examine the node that contains the point
      UpdateNearestNeighbors(GetLeft(inode), point, kNN, ind, dist);
      UpdateNearestNeighbors(GetRight(inode), point, kNN, ind, dist);
   } else {
      UpdateNearestNeighbors(GetRight(inode), point, kNN, ind, dist);
      UpdateNearestNeighbors(GetLeft(inode), point, kNN, ind, dist);
   }
}

//_________________________________________________________________
template <typename Index, typename Value>
Double_t TKDTree<Index, Value>::Distance(const Value *point, Index ind, Int_t type) const
{
//Find the distance between point of the first argument and the point at index value ind
//Type argument specifies the metric: type=2 - L2 metric, type=1 - L1 metric

   Double_t dist = 0;
   if (type==2){
      for (Int_t idim=0; idim<fNDim; idim++){
         dist+=(point[idim]-fData[idim][ind])*(point[idim]-fData[idim][ind]);
      }
      return TMath::Sqrt(dist);
   } else {
      for (Int_t idim=0; idim<fNDim; idim++){
         dist+=TMath::Abs(point[idim]-fData[idim][ind]);
      }

      return dist;
   }
   return -1;

}

//_________________________________________________________________
template <typename Index, typename Value>
void TKDTree<Index, Value>::DistanceToNode(const Value *point, Index inode, Value &min, Value &max, Int_t type)
{
//Find the minimal and maximal distance from a given point to a given node.
//Type argument specifies the metric: type=2 - L2 metric, type=1 - L1 metric
//If the point is inside the node, both min and max are set to 0.

   Value *bound = GetBoundaryExact(inode);
   min = 0;
   max = 0;
   Double_t dist1, dist2;

   if (type==2){
      for (Int_t idim=0; idim<fNDimm; idim+=2){
         dist1 = (point[idim/2]-bound[idim])*(point[idim/2]-bound[idim]);
         dist2 = (point[idim/2]-bound[idim+1])*(point[idim/2]-bound[idim+1]);
         //min+=TMath::Min(dist1, dist2);
         if (point[idim/2]<bound[idim] || point[idim/2]>bound[idim+1])
            min+= (dist1>dist2)? dist2 : dist1;
         // max+=TMath::Max(dist1, dist2);
         max+= (dist1>dist2)? dist1 : dist2;
      }
      min = TMath::Sqrt(min);
      max = TMath::Sqrt(max);
   } else {
      for (Int_t idim=0; idim<fNDimm; idim+=2){
         dist1 = TMath::Abs(point[idim/2]-bound[idim]);
         dist2 = TMath::Abs(point[idim/2]-bound[idim+1]);
         //min+=TMath::Min(dist1, dist2);
         min+= (dist1>dist2)? dist2 : dist1;
         // max+=TMath::Max(dist1, dist2);
         max+= (dist1>dist2)? dist1 : dist2;
      }
   }
}

//_________________________________________________________________
template <typename  Index, typename Value>
Index TKDTree<Index, Value>::FindNode(const Value * point) const
{
   // returns the index of the terminal node to which point belongs
   // (index in the fAxis, fValue, etc arrays)
   // returns -1 in case of failure

   Index stackNode[128], inode;
   Int_t currentIndex =0;
   stackNode[0] = 0;
   while (currentIndex>=0){
      inode    = stackNode[currentIndex];
      if (IsTerminal(inode)) return inode;

      currentIndex--;
      if (point[fAxis[inode]]<=fValue[inode]){
         currentIndex++;
         stackNode[currentIndex]=(inode<<1)+1; //GetLeft()
      }
      if (point[fAxis[inode]]>=fValue[inode]){
         currentIndex++;
         stackNode[currentIndex]=(inode+1)<<1; //GetRight()
      }
   }

   return -1;
}



//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::FindPoint(Value * point, Index &index, Int_t &iter){
  //
  // find the index of point
  // works only if we keep fData pointers

   Int_t stackNode[128];
   Int_t currentIndex =0;
   stackNode[0] = 0;
   iter =0;
   //
   while (currentIndex>=0){
      iter++;
      Int_t inode    = stackNode[currentIndex];
      currentIndex--;
      if (IsTerminal(inode)){
         // investigate terminal node
         Int_t indexIP  = (inode >= fCrossNode) ? (inode-fCrossNode)*fBucketSize : (inode-fNNodes)*fBucketSize+fOffset;
         printf("terminal %d indexP %d\n", inode, indexIP);
         for (Int_t ibucket=0;ibucket<fBucketSize;ibucket++){
            Bool_t isOK    = kTRUE;
            indexIP+=ibucket;
            printf("ibucket %d index %d\n", ibucket, indexIP);
            if (indexIP>=fNPoints) continue;
            Int_t index0   = fIndPoints[indexIP];
            for (Int_t idim=0;idim<fNDim;idim++) if (fData[idim][index0]!=point[idim]) isOK = kFALSE;
            if (isOK) index = index0;
         }
         continue;
      }

      if (point[fAxis[inode]]<=fValue[inode]){
         currentIndex++;
         stackNode[currentIndex]=(inode*2)+1;
      }
      if (point[fAxis[inode]]>=fValue[inode]){
         currentIndex++;
         stackNode[currentIndex]=(inode*2)+2;
    }
  }
  //
  //  printf("Iter\t%d\n",iter);
}

//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::FindInRange(Value * point, Value range, std::vector<Index> &res)
{
//Find all points in the sphere of a given radius "range" around the given point
//1st argument - the point
//2nd argument - radius of the shere
//3rd argument - a vector, in which the results will be returned

   MakeBoundariesExact();
   UpdateRange(0, point, range, res);
}

//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::UpdateRange(Index inode, Value* point, Value range, std::vector<Index> &res)
{
//Internal recursive function with the implementation of range searches

   Value min, max;
   DistanceToNode(point, inode, min, max);
   if (min>range) {
      //all points of this node are outside the range
      return;
   }
   if (max<range && max>0) {
      //all points of this node are inside the range

      Index f1, l1, f2, l2;
      GetNodePointsIndexes(inode, f1, l1, f2, l2);

      for (Int_t ipoint=f1; ipoint<=l1; ipoint++){
         res.push_back(fIndPoints[ipoint]);
      }
      for (Int_t ipoint=f2; ipoint<=l2; ipoint++){
         res.push_back(fIndPoints[ipoint]);
      }
      return;
   }

   //this node intersects with the range
   if (IsTerminal(inode)){
      //examine the points one by one
      Index f1, l1, f2, l2;
      Double_t d;
      GetNodePointsIndexes(inode, f1, l1, f2, l2);
      for (Int_t ipoint=f1; ipoint<=l1; ipoint++){
         d = Distance(point, fIndPoints[ipoint]);
         if (d <= range){
            res.push_back(fIndPoints[ipoint]);
         }
      }
      return;
   }
   if (point[fAxis[inode]]<=fValue[inode]){
      //first examine the node that contains the point
      UpdateRange(GetLeft(inode),point, range, res);
      UpdateRange(GetRight(inode),point, range, res);
   } else {
      UpdateRange(GetLeft(inode),point, range, res);
      UpdateRange(GetRight(inode),point, range, res);
   }
}

//_________________________________________________________________
template <typename Index, typename Value>
Index*  TKDTree<Index, Value>::GetPointsIndexes(Int_t node) const
{
   //return the indices of the points in that terminal node
   //for all the nodes except last, the size is fBucketSize
   //for the last node it's fOffset%fBucketSize

   if (!IsTerminal(node)){
      printf("GetPointsIndexes() only for terminal nodes, use GetNodePointsIndexes() instead\n");
      return 0;
   }
   Int_t offset = (node >= fCrossNode) ? (node-fCrossNode)*fBucketSize : fOffset+(node-fNNodes)*fBucketSize;
   return &fIndPoints[offset];
}

//_________________________________________________________________
template <typename Index, typename Value>
void  TKDTree<Index, Value>::GetNodePointsIndexes(Int_t node, Int_t &first1, Int_t &last1, Int_t &first2, Int_t &last2) const
{
   //Return the indices of points in that node
   //Indices are returned as the first and last value of the part of indices array, that belong to this node
   //Sometimes points are in 2 intervals, then the first and last value for the second one are returned in
   //third and fourth parameter, otherwise first2 is set to 0 and last2 is set to -1
   //To iterate over all the points of the node #inode, one can do, for example:
   //Index *indices = kdtree->GetPointsIndexes();
   //Int_t first1, last1, first2, last2;
   //kdtree->GetPointsIndexes(inode, first1, last1, first2, last2);
   //for (Int_t ipoint=first1; ipoint<=last1; ipoint++){
   //   point = indices[ipoint];
   //   //do something with point;
   //}
   //for (Int_t ipoint=first2; ipoint<=last2; ipoint++){
   //   point = indices[ipoint];
   //   //do something with point;
   //}


   if (IsTerminal(node)){
      //the first point in the node is computed by the following formula:
      Index offset = (node >= fCrossNode) ? (node-fCrossNode)*fBucketSize : fOffset+(node-fNNodes)*fBucketSize;
      first1 = offset;
      last1 = offset + GetNPointsNode(node)-1;
      first2 = 0;
      last2 = -1;
      return;
   }

   Index firsttermnode = fNNodes;
   Index ileft = node;
   Index iright = node;
   Index f1, l1, f2, l2;
//this is the left-most node
   while (ileft<firsttermnode)
      ileft = GetLeft(ileft);
//this is the right-most node
   while (iright<firsttermnode)
      iright = GetRight(iright);

   if (ileft>iright){
//      first1 = firsttermnode;
//      last1 = iright;
//      first2 = ileft;
//      last2 = fTotalNodes-1;
      GetNodePointsIndexes(firsttermnode, f1, l1, f2, l2);
      first1 = f1;
      GetNodePointsIndexes(iright, f1, l1, f2, l2);
      last1 = l1;
      GetNodePointsIndexes(ileft, f1, l1, f2, l2);
      first2 = f1;
      GetNodePointsIndexes(fTotalNodes-1, f1, l1, f2, l2);
      last2 = l1;

   }  else {
      GetNodePointsIndexes(ileft, f1, l1, f2, l2);
      first1 = f1;
      GetNodePointsIndexes(iright, f1, l1, f2, l2);
      last1 = l1;
      first2 = 0;
      last2 = -1;
   }
}

//_________________________________________________________________
template <typename Index, typename Value>
Index TKDTree<Index, Value>::GetNPointsNode(Int_t inode) const
{
   //Get number of points in this node
   //for all the terminal nodes except last, the size is fBucketSize
   //for the last node it's fOffset%fBucketSize, or if fOffset%fBucketSize==0, it's also fBucketSize

   if (IsTerminal(inode)){

      if (inode!=fTotalNodes-1) return fBucketSize;
      else {
         if (fOffset%fBucketSize==0) return fBucketSize;
         else return fOffset%fBucketSize;
      }
   }

   Int_t f1, l1, f2, l2;
   GetNodePointsIndexes(inode, f1, l1, f2, l2);
   Int_t sum = l1-f1+1;
   sum += l2-f2+1;
   return sum;
}


//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::SetData(Index npoints, Index ndim, UInt_t bsize, Value **data)
{
// Set the data array. See the constructor function comments for details

// TO DO
//
// Check reconstruction/reallocation of memory of data. Maybe it is not
// necessary to delete and realocate space but only to use the same space

   Clear();

   //Columnwise!!!!
   fData = data;
   fNPoints = npoints;
   fNDim = ndim;
   fBucketSize = bsize;

   Build();
}

//_________________________________________________________________
template <typename  Index, typename Value>
Int_t TKDTree<Index, Value>::SetData(Index idim, Value *data)
{
   //Set the coordinate #ndim of all points (the column #ndim of the data matrix)
   //After setting all the data columns, proceed by calling Build() function
   //Note, that calling this function after Build() is not possible
   //Note also, that no checks on the array sizes is performed anywhere

   if (fAxis || fValue) {
      Error("SetData", "The tree has already been built, no updates possible");
      return 0;
   }

   if (!fData) {
      fData = new Value*[fNDim];
   }
   fData[idim]=data;
   fDataOwner = 2;
   return 1;
}


//_________________________________________________________________
template <typename  Index, typename Value>
void TKDTree<Index, Value>::Spread(Index ntotal, Value *a, Index *index, Value &min, Value &max) const
{
   //Calculate spread of the array a

   Index i;
   min = a[index[0]];
   max = a[index[0]];
   for (i=0; i<ntotal; i++){
      if (a[index[i]]<min) min = a[index[i]];
      if (a[index[i]]>max) max = a[index[i]];
   }
}


//_________________________________________________________________
template <typename  Index, typename Value>
Value TKDTree<Index, Value>::KOrdStat(Index ntotal, Value *a, Index k, Index *index) const
{
   //
   //copy of the TMath::KOrdStat because I need an Index work array

   Index i, ir, j, l, mid;
   Index arr;
   Index temp;

   Index rk = k;
   l=0;
   ir = ntotal-1;
   for(;;) {
      if (ir<=l+1) { //active partition contains 1 or 2 elements
         if (ir == l+1 && a[index[ir]]<a[index[l]])
         {temp = index[l]; index[l]=index[ir]; index[ir]=temp;}
         Value tmp = a[index[rk]];
         return tmp;
      } else {
         mid = (l+ir) >> 1; //choose median of left, center and right
         {temp = index[mid]; index[mid]=index[l+1]; index[l+1]=temp;}//elements as partitioning element arr.
          if (a[index[l]]>a[index[ir]])  //also rearrange so that a[l]<=a[l+1]
          {temp = index[l]; index[l]=index[ir]; index[ir]=temp;}

          if (a[index[l+1]]>a[index[ir]])
          {temp=index[l+1]; index[l+1]=index[ir]; index[ir]=temp;}

          if (a[index[l]]>a[index[l+1]])
          {temp = index[l]; index[l]=index[l+1]; index[l+1]=temp;}

          i=l+1;        //initialize pointers for partitioning
          j=ir;
          arr = index[l+1];
          for (;;) {
             do i++; while (a[index[i]]<a[arr]);
             do j--; while (a[index[j]]>a[arr]);
             if (j<i) break;  //pointers crossed, partitioning complete
             {temp=index[i]; index[i]=index[j]; index[j]=temp;}
          }
          index[l+1]=index[j];
          index[j]=arr;
          if (j>=rk) ir = j-1; //keep active the partition that
          if (j<=rk) l=i;      //contains the k_th element
      }
   }
}

//_________________________________________________________________
template <typename Index, typename Value>
void TKDTree<Index, Value>::MakeBoundaries(Value *range)
{
// Build boundaries for each node. Note, that the boundaries here are built
// based on the splitting planes of the kd-tree, and don't necessarily pass
// through the points of the original dataset. For the latter functionality
// see function MakeBoundariesExact()
// Boundaries can be retrieved by calling GetBoundary(inode) function that would
// return an array of boundaries for the specified node, or GetBoundaries() function
// that would return the complete array.


   if(range) memcpy(fRange, range, fNDimm*sizeof(Value));
   // total number of nodes including terminal nodes
   Int_t totNodes = fNNodes + fNPoints/fBucketSize + ((fNPoints%fBucketSize)?1:0);
   fBoundaries = new Value[totNodes*fNDimm];
   //Info("MakeBoundaries(Value*)", Form("Allocate boundaries for %d nodes", totNodes));


   // loop
   Value *tbounds = 0x0, *cbounds = 0x0;
   Int_t cn;
   for(int inode=fNNodes-1; inode>=0; inode--){
      tbounds = &fBoundaries[inode*fNDimm];
      memcpy(tbounds, fRange, fNDimm*sizeof(Value));

      // check left child node
      cn = (inode<<1)+1;
      if(IsTerminal(cn)) CookBoundaries(inode, kTRUE);
      cbounds = &fBoundaries[fNDimm*cn];
      for(int idim=0; idim<fNDim; idim++) tbounds[idim<<1] = cbounds[idim<<1];

      // check right child node
      cn = (inode+1)<<1;
      if(IsTerminal(cn)) CookBoundaries(inode, kFALSE);
      cbounds = &fBoundaries[fNDimm*cn];
      for(int idim=0; idim<fNDim; idim++) tbounds[(idim<<1)+1] = cbounds[(idim<<1)+1];
   }
}

//_________________________________________________________________
template <typename Index, typename Value>
void TKDTree<Index, Value>::CookBoundaries(const Int_t node, Bool_t LEFT)
{
   // define index of this terminal node
   Int_t index = (node<<1) + (LEFT ? 1 : 2);
   //Info("CookBoundaries()", Form("Node %d", index));

   // build and initialize boundaries for this node
   Value *tbounds = &fBoundaries[fNDimm*index];
   memcpy(tbounds, fRange, fNDimm*sizeof(Value));
   Bool_t flag[256];  // cope with up to 128 dimensions
   memset(flag, kFALSE, fNDimm);
   Int_t nvals = 0;

   // recurse parent nodes
   Int_t pn = node;
   while(pn >= 0 && nvals < fNDimm){
      if(LEFT){
         index = (fAxis[pn]<<1)+1;
         if(!flag[index]) {
            tbounds[index] = fValue[pn];
            flag[index] = kTRUE;
            nvals++;
         }
      } else {
         index = fAxis[pn]<<1;
         if(!flag[index]) {
            tbounds[index] = fValue[pn];
            flag[index] = kTRUE;
            nvals++;
         }
      }
      LEFT = pn&1;
      pn =  (pn - 1)>>1;
   }
}

//______________________________________________________________________
template <typename Index, typename Value>
void TKDTree<Index, Value>::MakeBoundariesExact()
{
// Build boundaries for each node. Unlike MakeBoundaries() function
// the boundaries built here always pass through a point of the original dataset
// So, for example, for a terminal node with just one point minimum and maximum for each
// dimension are the same.
// Boundaries can be retrieved by calling GetBoundaryExact(inode) function that would
// return an array of boundaries for the specified node, or GetBoundaries() function
// that would return the complete array.


   // total number of nodes including terminal nodes
   //Int_t totNodes = fNNodes + fNPoints/fBucketSize + ((fNPoints%fBucketSize)?1:0);
   if (fBoundaries){
      //boundaries were already computed for this tree
      return;
   }
   fBoundaries = new Value[fTotalNodes*fNDimm];
   Value *min = new Value[fNDim];
   Value *max = new Value[fNDim];
   for (Index inode=fNNodes; inode<fTotalNodes; inode++){
      //go through the terminal nodes
      for (Index idim=0; idim<fNDim; idim++){
         min[idim]= std::numeric_limits<Value>::max();
         max[idim]=-std::numeric_limits<Value>::max();
      }
      Index *points = GetPointsIndexes(inode);
      Index npoints = GetNPointsNode(inode);
      //find max and min in each dimension
      for (Index ipoint=0; ipoint<npoints; ipoint++){
         for (Index idim=0; idim<fNDim; idim++){
            if (fData[idim][points[ipoint]]<min[idim])
               min[idim]=fData[idim][points[ipoint]];
            if (fData[idim][points[ipoint]]>max[idim])
               max[idim]=fData[idim][points[ipoint]];
         }
      }
      for (Index idim=0; idim<fNDimm; idim+=2){
         fBoundaries[inode*fNDimm + idim]=min[idim/2];
         fBoundaries[inode*fNDimm + idim+1]=max[idim/2];
      }
   }

   delete [] min;
   delete [] max;

   Index left, right;
   for (Index inode=fNNodes-1; inode>=0; inode--){
      //take the min and max of left and right
      left = GetLeft(inode)*fNDimm;
      right = GetRight(inode)*fNDimm;
      for (Index idim=0; idim<fNDimm; idim+=2){
         //take the minimum on each dimension
         fBoundaries[inode*fNDimm+idim]=TMath::Min(fBoundaries[left+idim], fBoundaries[right+idim]);
         //take the maximum on each dimension
         fBoundaries[inode*fNDimm+idim+1]=TMath::Max(fBoundaries[left+idim+1], fBoundaries[right+idim+1]);

      }
   }
}

//_________________________________________________________________
template <typename  Index, typename Value>
   void TKDTree<Index, Value>::FindBNodeA(Value *point, Value *delta, Int_t &inode){
   //
   // find the smallest node covering the full range - start
   //
   inode =0;
   for (;inode<fNNodes;){
      if (TMath::Abs(point[fAxis[inode]] - fValue[inode])<delta[fAxis[inode]]) break;
      inode = (point[fAxis[inode]] < fValue[inode]) ? (inode*2)+1: (inode*2)+2;
   }
}

//_________________________________________________________________
template <typename  Index, typename Value>
   Value* TKDTree<Index, Value>::GetBoundaries()
{
   // Get the boundaries
   if(!fBoundaries) MakeBoundaries();
   return fBoundaries;
}


//_________________________________________________________________
template <typename  Index, typename Value>
   Value* TKDTree<Index, Value>::GetBoundariesExact()
{
   // Get the boundaries
   if(!fBoundaries) MakeBoundariesExact();
   return fBoundaries;
}

//_________________________________________________________________
template <typename  Index, typename Value>
   Value* TKDTree<Index, Value>::GetBoundary(const Int_t node)
{
   // Get a boundary
   if(!fBoundaries) MakeBoundaries();
   return &fBoundaries[node*2*fNDim];
}

//_________________________________________________________________
template <typename  Index, typename Value>
Value* TKDTree<Index, Value>::GetBoundaryExact(const Int_t node)
{
   // Get a boundary
   if(!fBoundaries) MakeBoundariesExact();
   return &fBoundaries[node*2*fNDim];
}


//______________________________________________________________________
TKDTreeIF *TKDTreeTestBuild(const Int_t npoints, const Int_t bsize){
   //
   // Example function to
   //
   Float_t *data0 =  new Float_t[npoints*2];
   Float_t *data[2];
   data[0] = &data0[0];
   data[1] = &data0[npoints];
   for (Int_t i=0;i<npoints;i++) {
      data[1][i]= gRandom->Rndm();
      data[0][i]= gRandom->Rndm();
   }
   TKDTree<Int_t, Float_t> *kdtree = new TKDTreeIF(npoints, 2, bsize, data);
   return kdtree;
}



template class TKDTree<Int_t, Float_t>;
template class TKDTree<Int_t, Double_t>;
 TKDTree.cxx:1
 TKDTree.cxx:2
 TKDTree.cxx:3
 TKDTree.cxx:4
 TKDTree.cxx:5
 TKDTree.cxx:6
 TKDTree.cxx:7
 TKDTree.cxx:8
 TKDTree.cxx:9
 TKDTree.cxx:10
 TKDTree.cxx:11
 TKDTree.cxx:12
 TKDTree.cxx:13
 TKDTree.cxx:14
 TKDTree.cxx:15
 TKDTree.cxx:16
 TKDTree.cxx:17
 TKDTree.cxx:18
 TKDTree.cxx:19
 TKDTree.cxx:20
 TKDTree.cxx:21
 TKDTree.cxx:22
 TKDTree.cxx:23
 TKDTree.cxx:24
 TKDTree.cxx:25
 TKDTree.cxx:26
 TKDTree.cxx:27
 TKDTree.cxx:28
 TKDTree.cxx:29
 TKDTree.cxx:30
 TKDTree.cxx:31
 TKDTree.cxx:32
 TKDTree.cxx:33
 TKDTree.cxx:34
 TKDTree.cxx:35
 TKDTree.cxx:36
 TKDTree.cxx:37
 TKDTree.cxx:38
 TKDTree.cxx:39
 TKDTree.cxx:40
 TKDTree.cxx:41
 TKDTree.cxx:42
 TKDTree.cxx:43
 TKDTree.cxx:44
 TKDTree.cxx:45
 TKDTree.cxx:46
 TKDTree.cxx:47
 TKDTree.cxx:48
 TKDTree.cxx:49
 TKDTree.cxx:50
 TKDTree.cxx:51
 TKDTree.cxx:52
 TKDTree.cxx:53
 TKDTree.cxx:54
 TKDTree.cxx:55
 TKDTree.cxx:56
 TKDTree.cxx:57
 TKDTree.cxx:58
 TKDTree.cxx:59
 TKDTree.cxx:60
 TKDTree.cxx:61
 TKDTree.cxx:62
 TKDTree.cxx:63
 TKDTree.cxx:64
 TKDTree.cxx:65
 TKDTree.cxx:66
 TKDTree.cxx:67
 TKDTree.cxx:68
 TKDTree.cxx:69
 TKDTree.cxx:70
 TKDTree.cxx:71
 TKDTree.cxx:72
 TKDTree.cxx:73
 TKDTree.cxx:74
 TKDTree.cxx:75
 TKDTree.cxx:76
 TKDTree.cxx:77
 TKDTree.cxx:78
 TKDTree.cxx:79
 TKDTree.cxx:80
 TKDTree.cxx:81
 TKDTree.cxx:82
 TKDTree.cxx:83
 TKDTree.cxx:84
 TKDTree.cxx:85
 TKDTree.cxx:86
 TKDTree.cxx:87
 TKDTree.cxx:88
 TKDTree.cxx:89
 TKDTree.cxx:90
 TKDTree.cxx:91
 TKDTree.cxx:92
 TKDTree.cxx:93
 TKDTree.cxx:94
 TKDTree.cxx:95
 TKDTree.cxx:96
 TKDTree.cxx:97
 TKDTree.cxx:98
 TKDTree.cxx:99
 TKDTree.cxx:100
 TKDTree.cxx:101
 TKDTree.cxx:102
 TKDTree.cxx:103
 TKDTree.cxx:104
 TKDTree.cxx:105
 TKDTree.cxx:106
 TKDTree.cxx:107
 TKDTree.cxx:108
 TKDTree.cxx:109
 TKDTree.cxx:110
 TKDTree.cxx:111
 TKDTree.cxx:112
 TKDTree.cxx:113
 TKDTree.cxx:114
 TKDTree.cxx:115
 TKDTree.cxx:116
 TKDTree.cxx:117
 TKDTree.cxx:118
 TKDTree.cxx:119
 TKDTree.cxx:120
 TKDTree.cxx:121
 TKDTree.cxx:122
 TKDTree.cxx:123
 TKDTree.cxx:124
 TKDTree.cxx:125
 TKDTree.cxx:126
 TKDTree.cxx:127
 TKDTree.cxx:128
 TKDTree.cxx:129
 TKDTree.cxx:130
 TKDTree.cxx:131
 TKDTree.cxx:132
 TKDTree.cxx:133
 TKDTree.cxx:134
 TKDTree.cxx:135
 TKDTree.cxx:136
 TKDTree.cxx:137
 TKDTree.cxx:138
 TKDTree.cxx:139
 TKDTree.cxx:140
 TKDTree.cxx:141
 TKDTree.cxx:142
 TKDTree.cxx:143
 TKDTree.cxx:144
 TKDTree.cxx:145
 TKDTree.cxx:146
 TKDTree.cxx:147
 TKDTree.cxx:148
 TKDTree.cxx:149
 TKDTree.cxx:150
 TKDTree.cxx:151
 TKDTree.cxx:152
 TKDTree.cxx:153
 TKDTree.cxx:154
 TKDTree.cxx:155
 TKDTree.cxx:156
 TKDTree.cxx:157
 TKDTree.cxx:158
 TKDTree.cxx:159
 TKDTree.cxx:160
 TKDTree.cxx:161
 TKDTree.cxx:162
 TKDTree.cxx:163
 TKDTree.cxx:164
 TKDTree.cxx:165
 TKDTree.cxx:166
 TKDTree.cxx:167
 TKDTree.cxx:168
 TKDTree.cxx:169
 TKDTree.cxx:170
 TKDTree.cxx:171
 TKDTree.cxx:172
 TKDTree.cxx:173
 TKDTree.cxx:174
 TKDTree.cxx:175
 TKDTree.cxx:176
 TKDTree.cxx:177
 TKDTree.cxx:178
 TKDTree.cxx:179
 TKDTree.cxx:180
 TKDTree.cxx:181
 TKDTree.cxx:182
 TKDTree.cxx:183
 TKDTree.cxx:184
 TKDTree.cxx:185
 TKDTree.cxx:186
 TKDTree.cxx:187
 TKDTree.cxx:188
 TKDTree.cxx:189
 TKDTree.cxx:190
 TKDTree.cxx:191
 TKDTree.cxx:192
 TKDTree.cxx:193
 TKDTree.cxx:194
 TKDTree.cxx:195
 TKDTree.cxx:196
 TKDTree.cxx:197
 TKDTree.cxx:198
 TKDTree.cxx:199
 TKDTree.cxx:200
 TKDTree.cxx:201
 TKDTree.cxx:202
 TKDTree.cxx:203
 TKDTree.cxx:204
 TKDTree.cxx:205
 TKDTree.cxx:206
 TKDTree.cxx:207
 TKDTree.cxx:208
 TKDTree.cxx:209
 TKDTree.cxx:210
 TKDTree.cxx:211
 TKDTree.cxx:212
 TKDTree.cxx:213
 TKDTree.cxx:214
 TKDTree.cxx:215
 TKDTree.cxx:216
 TKDTree.cxx:217
 TKDTree.cxx:218
 TKDTree.cxx:219
 TKDTree.cxx:220
 TKDTree.cxx:221
 TKDTree.cxx:222
 TKDTree.cxx:223
 TKDTree.cxx:224
 TKDTree.cxx:225
 TKDTree.cxx:226
 TKDTree.cxx:227
 TKDTree.cxx:228
 TKDTree.cxx:229
 TKDTree.cxx:230
 TKDTree.cxx:231
 TKDTree.cxx:232
 TKDTree.cxx:233
 TKDTree.cxx:234
 TKDTree.cxx:235
 TKDTree.cxx:236
 TKDTree.cxx:237
 TKDTree.cxx:238
 TKDTree.cxx:239
 TKDTree.cxx:240
 TKDTree.cxx:241
 TKDTree.cxx:242
 TKDTree.cxx:243
 TKDTree.cxx:244
 TKDTree.cxx:245
 TKDTree.cxx:246
 TKDTree.cxx:247
 TKDTree.cxx:248
 TKDTree.cxx:249
 TKDTree.cxx:250
 TKDTree.cxx:251
 TKDTree.cxx:252
 TKDTree.cxx:253
 TKDTree.cxx:254
 TKDTree.cxx:255
 TKDTree.cxx:256
 TKDTree.cxx:257
 TKDTree.cxx:258
 TKDTree.cxx:259
 TKDTree.cxx:260
 TKDTree.cxx:261
 TKDTree.cxx:262
 TKDTree.cxx:263
 TKDTree.cxx:264
 TKDTree.cxx:265
 TKDTree.cxx:266
 TKDTree.cxx:267
 TKDTree.cxx:268
 TKDTree.cxx:269
 TKDTree.cxx:270
 TKDTree.cxx:271
 TKDTree.cxx:272
 TKDTree.cxx:273
 TKDTree.cxx:274
 TKDTree.cxx:275
 TKDTree.cxx:276
 TKDTree.cxx:277
 TKDTree.cxx:278
 TKDTree.cxx:279
 TKDTree.cxx:280
 TKDTree.cxx:281
 TKDTree.cxx:282
 TKDTree.cxx:283
 TKDTree.cxx:284
 TKDTree.cxx:285
 TKDTree.cxx:286
 TKDTree.cxx:287
 TKDTree.cxx:288
 TKDTree.cxx:289
 TKDTree.cxx:290
 TKDTree.cxx:291
 TKDTree.cxx:292
 TKDTree.cxx:293
 TKDTree.cxx:294
 TKDTree.cxx:295
 TKDTree.cxx:296
 TKDTree.cxx:297
 TKDTree.cxx:298
 TKDTree.cxx:299
 TKDTree.cxx:300
 TKDTree.cxx:301
 TKDTree.cxx:302
 TKDTree.cxx:303
 TKDTree.cxx:304
 TKDTree.cxx:305
 TKDTree.cxx:306
 TKDTree.cxx:307
 TKDTree.cxx:308
 TKDTree.cxx:309
 TKDTree.cxx:310
 TKDTree.cxx:311
 TKDTree.cxx:312
 TKDTree.cxx:313
 TKDTree.cxx:314
 TKDTree.cxx:315
 TKDTree.cxx:316
 TKDTree.cxx:317
 TKDTree.cxx:318
 TKDTree.cxx:319
 TKDTree.cxx:320
 TKDTree.cxx:321
 TKDTree.cxx:322
 TKDTree.cxx:323
 TKDTree.cxx:324
 TKDTree.cxx:325
 TKDTree.cxx:326
 TKDTree.cxx:327
 TKDTree.cxx:328
 TKDTree.cxx:329
 TKDTree.cxx:330
 TKDTree.cxx:331
 TKDTree.cxx:332
 TKDTree.cxx:333
 TKDTree.cxx:334
 TKDTree.cxx:335
 TKDTree.cxx:336
 TKDTree.cxx:337
 TKDTree.cxx:338
 TKDTree.cxx:339
 TKDTree.cxx:340
 TKDTree.cxx:341
 TKDTree.cxx:342
 TKDTree.cxx:343
 TKDTree.cxx:344
 TKDTree.cxx:345
 TKDTree.cxx:346
 TKDTree.cxx:347
 TKDTree.cxx:348
 TKDTree.cxx:349
 TKDTree.cxx:350
 TKDTree.cxx:351
 TKDTree.cxx:352
 TKDTree.cxx:353
 TKDTree.cxx:354
 TKDTree.cxx:355
 TKDTree.cxx:356
 TKDTree.cxx:357
 TKDTree.cxx:358
 TKDTree.cxx:359
 TKDTree.cxx:360
 TKDTree.cxx:361
 TKDTree.cxx:362
 TKDTree.cxx:363
 TKDTree.cxx:364
 TKDTree.cxx:365
 TKDTree.cxx:366
 TKDTree.cxx:367
 TKDTree.cxx:368
 TKDTree.cxx:369
 TKDTree.cxx:370
 TKDTree.cxx:371
 TKDTree.cxx:372
 TKDTree.cxx:373
 TKDTree.cxx:374
 TKDTree.cxx:375
 TKDTree.cxx:376
 TKDTree.cxx:377
 TKDTree.cxx:378
 TKDTree.cxx:379
 TKDTree.cxx:380
 TKDTree.cxx:381
 TKDTree.cxx:382
 TKDTree.cxx:383
 TKDTree.cxx:384
 TKDTree.cxx:385
 TKDTree.cxx:386
 TKDTree.cxx:387
 TKDTree.cxx:388
 TKDTree.cxx:389
 TKDTree.cxx:390
 TKDTree.cxx:391
 TKDTree.cxx:392
 TKDTree.cxx:393
 TKDTree.cxx:394
 TKDTree.cxx:395
 TKDTree.cxx:396
 TKDTree.cxx:397
 TKDTree.cxx:398
 TKDTree.cxx:399
 TKDTree.cxx:400
 TKDTree.cxx:401
 TKDTree.cxx:402
 TKDTree.cxx:403
 TKDTree.cxx:404
 TKDTree.cxx:405
 TKDTree.cxx:406
 TKDTree.cxx:407
 TKDTree.cxx:408
 TKDTree.cxx:409
 TKDTree.cxx:410
 TKDTree.cxx:411
 TKDTree.cxx:412
 TKDTree.cxx:413
 TKDTree.cxx:414
 TKDTree.cxx:415
 TKDTree.cxx:416
 TKDTree.cxx:417
 TKDTree.cxx:418
 TKDTree.cxx:419
 TKDTree.cxx:420
 TKDTree.cxx:421
 TKDTree.cxx:422
 TKDTree.cxx:423
 TKDTree.cxx:424
 TKDTree.cxx:425
 TKDTree.cxx:426
 TKDTree.cxx:427
 TKDTree.cxx:428
 TKDTree.cxx:429
 TKDTree.cxx:430
 TKDTree.cxx:431
 TKDTree.cxx:432
 TKDTree.cxx:433
 TKDTree.cxx:434
 TKDTree.cxx:435
 TKDTree.cxx:436
 TKDTree.cxx:437
 TKDTree.cxx:438
 TKDTree.cxx:439
 TKDTree.cxx:440
 TKDTree.cxx:441
 TKDTree.cxx:442
 TKDTree.cxx:443
 TKDTree.cxx:444
 TKDTree.cxx:445
 TKDTree.cxx:446
 TKDTree.cxx:447
 TKDTree.cxx:448
 TKDTree.cxx:449
 TKDTree.cxx:450
 TKDTree.cxx:451
 TKDTree.cxx:452
 TKDTree.cxx:453
 TKDTree.cxx:454
 TKDTree.cxx:455
 TKDTree.cxx:456
 TKDTree.cxx:457
 TKDTree.cxx:458
 TKDTree.cxx:459
 TKDTree.cxx:460
 TKDTree.cxx:461
 TKDTree.cxx:462
 TKDTree.cxx:463
 TKDTree.cxx:464
 TKDTree.cxx:465
 TKDTree.cxx:466
 TKDTree.cxx:467
 TKDTree.cxx:468
 TKDTree.cxx:469
 TKDTree.cxx:470
 TKDTree.cxx:471
 TKDTree.cxx:472
 TKDTree.cxx:473
 TKDTree.cxx:474
 TKDTree.cxx:475
 TKDTree.cxx:476
 TKDTree.cxx:477
 TKDTree.cxx:478
 TKDTree.cxx:479
 TKDTree.cxx:480
 TKDTree.cxx:481
 TKDTree.cxx:482
 TKDTree.cxx:483
 TKDTree.cxx:484
 TKDTree.cxx:485
 TKDTree.cxx:486
 TKDTree.cxx:487
 TKDTree.cxx:488
 TKDTree.cxx:489
 TKDTree.cxx:490
 TKDTree.cxx:491
 TKDTree.cxx:492
 TKDTree.cxx:493
 TKDTree.cxx:494
 TKDTree.cxx:495
 TKDTree.cxx:496
 TKDTree.cxx:497
 TKDTree.cxx:498
 TKDTree.cxx:499
 TKDTree.cxx:500
 TKDTree.cxx:501
 TKDTree.cxx:502
 TKDTree.cxx:503
 TKDTree.cxx:504
 TKDTree.cxx:505
 TKDTree.cxx:506
 TKDTree.cxx:507
 TKDTree.cxx:508
 TKDTree.cxx:509
 TKDTree.cxx:510
 TKDTree.cxx:511
 TKDTree.cxx:512
 TKDTree.cxx:513
 TKDTree.cxx:514
 TKDTree.cxx:515
 TKDTree.cxx:516
 TKDTree.cxx:517
 TKDTree.cxx:518
 TKDTree.cxx:519
 TKDTree.cxx:520
 TKDTree.cxx:521
 TKDTree.cxx:522
 TKDTree.cxx:523
 TKDTree.cxx:524
 TKDTree.cxx:525
 TKDTree.cxx:526
 TKDTree.cxx:527
 TKDTree.cxx:528
 TKDTree.cxx:529
 TKDTree.cxx:530
 TKDTree.cxx:531
 TKDTree.cxx:532
 TKDTree.cxx:533
 TKDTree.cxx:534
 TKDTree.cxx:535
 TKDTree.cxx:536
 TKDTree.cxx:537
 TKDTree.cxx:538
 TKDTree.cxx:539
 TKDTree.cxx:540
 TKDTree.cxx:541
 TKDTree.cxx:542
 TKDTree.cxx:543
 TKDTree.cxx:544
 TKDTree.cxx:545
 TKDTree.cxx:546
 TKDTree.cxx:547
 TKDTree.cxx:548
 TKDTree.cxx:549
 TKDTree.cxx:550
 TKDTree.cxx:551
 TKDTree.cxx:552
 TKDTree.cxx:553
 TKDTree.cxx:554
 TKDTree.cxx:555
 TKDTree.cxx:556
 TKDTree.cxx:557
 TKDTree.cxx:558
 TKDTree.cxx:559
 TKDTree.cxx:560
 TKDTree.cxx:561
 TKDTree.cxx:562
 TKDTree.cxx:563
 TKDTree.cxx:564
 TKDTree.cxx:565
 TKDTree.cxx:566
 TKDTree.cxx:567
 TKDTree.cxx:568
 TKDTree.cxx:569
 TKDTree.cxx:570
 TKDTree.cxx:571
 TKDTree.cxx:572
 TKDTree.cxx:573
 TKDTree.cxx:574
 TKDTree.cxx:575
 TKDTree.cxx:576
 TKDTree.cxx:577
 TKDTree.cxx:578
 TKDTree.cxx:579
 TKDTree.cxx:580
 TKDTree.cxx:581
 TKDTree.cxx:582
 TKDTree.cxx:583
 TKDTree.cxx:584
 TKDTree.cxx:585
 TKDTree.cxx:586
 TKDTree.cxx:587
 TKDTree.cxx:588
 TKDTree.cxx:589
 TKDTree.cxx:590
 TKDTree.cxx:591
 TKDTree.cxx:592
 TKDTree.cxx:593
 TKDTree.cxx:594
 TKDTree.cxx:595
 TKDTree.cxx:596
 TKDTree.cxx:597
 TKDTree.cxx:598
 TKDTree.cxx:599
 TKDTree.cxx:600
 TKDTree.cxx:601
 TKDTree.cxx:602
 TKDTree.cxx:603
 TKDTree.cxx:604
 TKDTree.cxx:605
 TKDTree.cxx:606
 TKDTree.cxx:607
 TKDTree.cxx:608
 TKDTree.cxx:609
 TKDTree.cxx:610
 TKDTree.cxx:611
 TKDTree.cxx:612
 TKDTree.cxx:613
 TKDTree.cxx:614
 TKDTree.cxx:615
 TKDTree.cxx:616
 TKDTree.cxx:617
 TKDTree.cxx:618
 TKDTree.cxx:619
 TKDTree.cxx:620
 TKDTree.cxx:621
 TKDTree.cxx:622
 TKDTree.cxx:623
 TKDTree.cxx:624
 TKDTree.cxx:625
 TKDTree.cxx:626
 TKDTree.cxx:627
 TKDTree.cxx:628
 TKDTree.cxx:629
 TKDTree.cxx:630
 TKDTree.cxx:631
 TKDTree.cxx:632
 TKDTree.cxx:633
 TKDTree.cxx:634
 TKDTree.cxx:635
 TKDTree.cxx:636
 TKDTree.cxx:637
 TKDTree.cxx:638
 TKDTree.cxx:639
 TKDTree.cxx:640
 TKDTree.cxx:641
 TKDTree.cxx:642
 TKDTree.cxx:643
 TKDTree.cxx:644
 TKDTree.cxx:645
 TKDTree.cxx:646
 TKDTree.cxx:647
 TKDTree.cxx:648
 TKDTree.cxx:649
 TKDTree.cxx:650
 TKDTree.cxx:651
 TKDTree.cxx:652
 TKDTree.cxx:653
 TKDTree.cxx:654
 TKDTree.cxx:655
 TKDTree.cxx:656
 TKDTree.cxx:657
 TKDTree.cxx:658
 TKDTree.cxx:659
 TKDTree.cxx:660
 TKDTree.cxx:661
 TKDTree.cxx:662
 TKDTree.cxx:663
 TKDTree.cxx:664
 TKDTree.cxx:665
 TKDTree.cxx:666
 TKDTree.cxx:667
 TKDTree.cxx:668
 TKDTree.cxx:669
 TKDTree.cxx:670
 TKDTree.cxx:671
 TKDTree.cxx:672
 TKDTree.cxx:673
 TKDTree.cxx:674
 TKDTree.cxx:675
 TKDTree.cxx:676
 TKDTree.cxx:677
 TKDTree.cxx:678
 TKDTree.cxx:679
 TKDTree.cxx:680
 TKDTree.cxx:681
 TKDTree.cxx:682
 TKDTree.cxx:683
 TKDTree.cxx:684
 TKDTree.cxx:685
 TKDTree.cxx:686
 TKDTree.cxx:687
 TKDTree.cxx:688
 TKDTree.cxx:689
 TKDTree.cxx:690
 TKDTree.cxx:691
 TKDTree.cxx:692
 TKDTree.cxx:693
 TKDTree.cxx:694
 TKDTree.cxx:695
 TKDTree.cxx:696
 TKDTree.cxx:697
 TKDTree.cxx:698
 TKDTree.cxx:699
 TKDTree.cxx:700
 TKDTree.cxx:701
 TKDTree.cxx:702
 TKDTree.cxx:703
 TKDTree.cxx:704
 TKDTree.cxx:705
 TKDTree.cxx:706
 TKDTree.cxx:707
 TKDTree.cxx:708
 TKDTree.cxx:709
 TKDTree.cxx:710
 TKDTree.cxx:711
 TKDTree.cxx:712
 TKDTree.cxx:713
 TKDTree.cxx:714
 TKDTree.cxx:715
 TKDTree.cxx:716
 TKDTree.cxx:717
 TKDTree.cxx:718
 TKDTree.cxx:719
 TKDTree.cxx:720
 TKDTree.cxx:721
 TKDTree.cxx:722
 TKDTree.cxx:723
 TKDTree.cxx:724
 TKDTree.cxx:725
 TKDTree.cxx:726
 TKDTree.cxx:727
 TKDTree.cxx:728
 TKDTree.cxx:729
 TKDTree.cxx:730
 TKDTree.cxx:731
 TKDTree.cxx:732
 TKDTree.cxx:733
 TKDTree.cxx:734
 TKDTree.cxx:735
 TKDTree.cxx:736
 TKDTree.cxx:737
 TKDTree.cxx:738
 TKDTree.cxx:739
 TKDTree.cxx:740
 TKDTree.cxx:741
 TKDTree.cxx:742
 TKDTree.cxx:743
 TKDTree.cxx:744
 TKDTree.cxx:745
 TKDTree.cxx:746
 TKDTree.cxx:747
 TKDTree.cxx:748
 TKDTree.cxx:749
 TKDTree.cxx:750
 TKDTree.cxx:751
 TKDTree.cxx:752
 TKDTree.cxx:753
 TKDTree.cxx:754
 TKDTree.cxx:755
 TKDTree.cxx:756
 TKDTree.cxx:757
 TKDTree.cxx:758
 TKDTree.cxx:759
 TKDTree.cxx:760
 TKDTree.cxx:761
 TKDTree.cxx:762
 TKDTree.cxx:763
 TKDTree.cxx:764
 TKDTree.cxx:765
 TKDTree.cxx:766
 TKDTree.cxx:767
 TKDTree.cxx:768
 TKDTree.cxx:769
 TKDTree.cxx:770
 TKDTree.cxx:771
 TKDTree.cxx:772
 TKDTree.cxx:773
 TKDTree.cxx:774
 TKDTree.cxx:775
 TKDTree.cxx:776
 TKDTree.cxx:777
 TKDTree.cxx:778
 TKDTree.cxx:779
 TKDTree.cxx:780
 TKDTree.cxx:781
 TKDTree.cxx:782
 TKDTree.cxx:783
 TKDTree.cxx:784
 TKDTree.cxx:785
 TKDTree.cxx:786
 TKDTree.cxx:787
 TKDTree.cxx:788
 TKDTree.cxx:789
 TKDTree.cxx:790
 TKDTree.cxx:791
 TKDTree.cxx:792
 TKDTree.cxx:793
 TKDTree.cxx:794
 TKDTree.cxx:795
 TKDTree.cxx:796
 TKDTree.cxx:797
 TKDTree.cxx:798
 TKDTree.cxx:799
 TKDTree.cxx:800
 TKDTree.cxx:801
 TKDTree.cxx:802
 TKDTree.cxx:803
 TKDTree.cxx:804
 TKDTree.cxx:805
 TKDTree.cxx:806
 TKDTree.cxx:807
 TKDTree.cxx:808
 TKDTree.cxx:809
 TKDTree.cxx:810
 TKDTree.cxx:811
 TKDTree.cxx:812
 TKDTree.cxx:813
 TKDTree.cxx:814
 TKDTree.cxx:815
 TKDTree.cxx:816
 TKDTree.cxx:817
 TKDTree.cxx:818
 TKDTree.cxx:819
 TKDTree.cxx:820
 TKDTree.cxx:821
 TKDTree.cxx:822
 TKDTree.cxx:823
 TKDTree.cxx:824
 TKDTree.cxx:825
 TKDTree.cxx:826
 TKDTree.cxx:827
 TKDTree.cxx:828
 TKDTree.cxx:829
 TKDTree.cxx:830
 TKDTree.cxx:831
 TKDTree.cxx:832
 TKDTree.cxx:833
 TKDTree.cxx:834
 TKDTree.cxx:835
 TKDTree.cxx:836
 TKDTree.cxx:837
 TKDTree.cxx:838
 TKDTree.cxx:839
 TKDTree.cxx:840
 TKDTree.cxx:841
 TKDTree.cxx:842
 TKDTree.cxx:843
 TKDTree.cxx:844
 TKDTree.cxx:845
 TKDTree.cxx:846
 TKDTree.cxx:847
 TKDTree.cxx:848
 TKDTree.cxx:849
 TKDTree.cxx:850
 TKDTree.cxx:851
 TKDTree.cxx:852
 TKDTree.cxx:853
 TKDTree.cxx:854
 TKDTree.cxx:855
 TKDTree.cxx:856
 TKDTree.cxx:857
 TKDTree.cxx:858
 TKDTree.cxx:859
 TKDTree.cxx:860
 TKDTree.cxx:861
 TKDTree.cxx:862
 TKDTree.cxx:863
 TKDTree.cxx:864
 TKDTree.cxx:865
 TKDTree.cxx:866
 TKDTree.cxx:867
 TKDTree.cxx:868
 TKDTree.cxx:869
 TKDTree.cxx:870
 TKDTree.cxx:871
 TKDTree.cxx:872
 TKDTree.cxx:873
 TKDTree.cxx:874
 TKDTree.cxx:875
 TKDTree.cxx:876
 TKDTree.cxx:877
 TKDTree.cxx:878
 TKDTree.cxx:879
 TKDTree.cxx:880
 TKDTree.cxx:881
 TKDTree.cxx:882
 TKDTree.cxx:883
 TKDTree.cxx:884
 TKDTree.cxx:885
 TKDTree.cxx:886
 TKDTree.cxx:887
 TKDTree.cxx:888
 TKDTree.cxx:889
 TKDTree.cxx:890
 TKDTree.cxx:891
 TKDTree.cxx:892
 TKDTree.cxx:893
 TKDTree.cxx:894
 TKDTree.cxx:895
 TKDTree.cxx:896
 TKDTree.cxx:897
 TKDTree.cxx:898
 TKDTree.cxx:899
 TKDTree.cxx:900
 TKDTree.cxx:901
 TKDTree.cxx:902
 TKDTree.cxx:903
 TKDTree.cxx:904
 TKDTree.cxx:905
 TKDTree.cxx:906
 TKDTree.cxx:907
 TKDTree.cxx:908
 TKDTree.cxx:909
 TKDTree.cxx:910
 TKDTree.cxx:911
 TKDTree.cxx:912
 TKDTree.cxx:913
 TKDTree.cxx:914
 TKDTree.cxx:915
 TKDTree.cxx:916
 TKDTree.cxx:917
 TKDTree.cxx:918
 TKDTree.cxx:919
 TKDTree.cxx:920
 TKDTree.cxx:921
 TKDTree.cxx:922
 TKDTree.cxx:923
 TKDTree.cxx:924
 TKDTree.cxx:925
 TKDTree.cxx:926
 TKDTree.cxx:927
 TKDTree.cxx:928
 TKDTree.cxx:929
 TKDTree.cxx:930
 TKDTree.cxx:931
 TKDTree.cxx:932
 TKDTree.cxx:933
 TKDTree.cxx:934
 TKDTree.cxx:935
 TKDTree.cxx:936
 TKDTree.cxx:937
 TKDTree.cxx:938
 TKDTree.cxx:939
 TKDTree.cxx:940
 TKDTree.cxx:941
 TKDTree.cxx:942
 TKDTree.cxx:943
 TKDTree.cxx:944
 TKDTree.cxx:945
 TKDTree.cxx:946
 TKDTree.cxx:947
 TKDTree.cxx:948
 TKDTree.cxx:949
 TKDTree.cxx:950
 TKDTree.cxx:951
 TKDTree.cxx:952
 TKDTree.cxx:953
 TKDTree.cxx:954
 TKDTree.cxx:955
 TKDTree.cxx:956
 TKDTree.cxx:957
 TKDTree.cxx:958
 TKDTree.cxx:959
 TKDTree.cxx:960
 TKDTree.cxx:961
 TKDTree.cxx:962
 TKDTree.cxx:963
 TKDTree.cxx:964
 TKDTree.cxx:965
 TKDTree.cxx:966
 TKDTree.cxx:967
 TKDTree.cxx:968
 TKDTree.cxx:969
 TKDTree.cxx:970
 TKDTree.cxx:971
 TKDTree.cxx:972
 TKDTree.cxx:973
 TKDTree.cxx:974
 TKDTree.cxx:975
 TKDTree.cxx:976
 TKDTree.cxx:977
 TKDTree.cxx:978
 TKDTree.cxx:979
 TKDTree.cxx:980
 TKDTree.cxx:981
 TKDTree.cxx:982
 TKDTree.cxx:983
 TKDTree.cxx:984
 TKDTree.cxx:985
 TKDTree.cxx:986
 TKDTree.cxx:987
 TKDTree.cxx:988
 TKDTree.cxx:989
 TKDTree.cxx:990
 TKDTree.cxx:991
 TKDTree.cxx:992
 TKDTree.cxx:993
 TKDTree.cxx:994
 TKDTree.cxx:995
 TKDTree.cxx:996
 TKDTree.cxx:997
 TKDTree.cxx:998
 TKDTree.cxx:999
 TKDTree.cxx:1000
 TKDTree.cxx:1001
 TKDTree.cxx:1002
 TKDTree.cxx:1003
 TKDTree.cxx:1004
 TKDTree.cxx:1005
 TKDTree.cxx:1006
 TKDTree.cxx:1007
 TKDTree.cxx:1008
 TKDTree.cxx:1009
 TKDTree.cxx:1010
 TKDTree.cxx:1011
 TKDTree.cxx:1012
 TKDTree.cxx:1013
 TKDTree.cxx:1014
 TKDTree.cxx:1015
 TKDTree.cxx:1016
 TKDTree.cxx:1017
 TKDTree.cxx:1018
 TKDTree.cxx:1019
 TKDTree.cxx:1020
 TKDTree.cxx:1021
 TKDTree.cxx:1022
 TKDTree.cxx:1023
 TKDTree.cxx:1024
 TKDTree.cxx:1025
 TKDTree.cxx:1026
 TKDTree.cxx:1027
 TKDTree.cxx:1028
 TKDTree.cxx:1029
 TKDTree.cxx:1030
 TKDTree.cxx:1031
 TKDTree.cxx:1032
 TKDTree.cxx:1033
 TKDTree.cxx:1034
 TKDTree.cxx:1035
 TKDTree.cxx:1036
 TKDTree.cxx:1037
 TKDTree.cxx:1038
 TKDTree.cxx:1039
 TKDTree.cxx:1040
 TKDTree.cxx:1041
 TKDTree.cxx:1042
 TKDTree.cxx:1043
 TKDTree.cxx:1044
 TKDTree.cxx:1045
 TKDTree.cxx:1046
 TKDTree.cxx:1047
 TKDTree.cxx:1048
 TKDTree.cxx:1049
 TKDTree.cxx:1050
 TKDTree.cxx:1051
 TKDTree.cxx:1052
 TKDTree.cxx:1053
 TKDTree.cxx:1054
 TKDTree.cxx:1055
 TKDTree.cxx:1056
 TKDTree.cxx:1057
 TKDTree.cxx:1058
 TKDTree.cxx:1059
 TKDTree.cxx:1060
 TKDTree.cxx:1061
 TKDTree.cxx:1062
 TKDTree.cxx:1063
 TKDTree.cxx:1064
 TKDTree.cxx:1065
 TKDTree.cxx:1066
 TKDTree.cxx:1067
 TKDTree.cxx:1068
 TKDTree.cxx:1069
 TKDTree.cxx:1070
 TKDTree.cxx:1071
 TKDTree.cxx:1072
 TKDTree.cxx:1073
 TKDTree.cxx:1074
 TKDTree.cxx:1075
 TKDTree.cxx:1076
 TKDTree.cxx:1077
 TKDTree.cxx:1078
 TKDTree.cxx:1079
 TKDTree.cxx:1080
 TKDTree.cxx:1081
 TKDTree.cxx:1082
 TKDTree.cxx:1083
 TKDTree.cxx:1084
 TKDTree.cxx:1085
 TKDTree.cxx:1086
 TKDTree.cxx:1087
 TKDTree.cxx:1088
 TKDTree.cxx:1089
 TKDTree.cxx:1090
 TKDTree.cxx:1091
 TKDTree.cxx:1092
 TKDTree.cxx:1093
 TKDTree.cxx:1094
 TKDTree.cxx:1095
 TKDTree.cxx:1096
 TKDTree.cxx:1097
 TKDTree.cxx:1098
 TKDTree.cxx:1099
 TKDTree.cxx:1100
 TKDTree.cxx:1101
 TKDTree.cxx:1102
 TKDTree.cxx:1103
 TKDTree.cxx:1104
 TKDTree.cxx:1105
 TKDTree.cxx:1106
 TKDTree.cxx:1107
 TKDTree.cxx:1108
 TKDTree.cxx:1109
 TKDTree.cxx:1110
 TKDTree.cxx:1111
 TKDTree.cxx:1112
 TKDTree.cxx:1113
 TKDTree.cxx:1114
 TKDTree.cxx:1115
 TKDTree.cxx:1116
 TKDTree.cxx:1117
 TKDTree.cxx:1118
 TKDTree.cxx:1119
 TKDTree.cxx:1120
 TKDTree.cxx:1121
 TKDTree.cxx:1122
 TKDTree.cxx:1123
 TKDTree.cxx:1124
 TKDTree.cxx:1125
 TKDTree.cxx:1126
 TKDTree.cxx:1127
 TKDTree.cxx:1128
 TKDTree.cxx:1129
 TKDTree.cxx:1130
 TKDTree.cxx:1131
 TKDTree.cxx:1132
 TKDTree.cxx:1133
 TKDTree.cxx:1134
 TKDTree.cxx:1135
 TKDTree.cxx:1136
 TKDTree.cxx:1137
 TKDTree.cxx:1138
 TKDTree.cxx:1139
 TKDTree.cxx:1140
 TKDTree.cxx:1141
 TKDTree.cxx:1142
 TKDTree.cxx:1143
 TKDTree.cxx:1144
 TKDTree.cxx:1145
 TKDTree.cxx:1146
 TKDTree.cxx:1147
 TKDTree.cxx:1148
 TKDTree.cxx:1149
 TKDTree.cxx:1150
 TKDTree.cxx:1151
 TKDTree.cxx:1152
 TKDTree.cxx:1153
 TKDTree.cxx:1154
 TKDTree.cxx:1155
 TKDTree.cxx:1156
 TKDTree.cxx:1157
 TKDTree.cxx:1158
 TKDTree.cxx:1159
 TKDTree.cxx:1160
 TKDTree.cxx:1161
 TKDTree.cxx:1162
 TKDTree.cxx:1163
 TKDTree.cxx:1164
 TKDTree.cxx:1165
 TKDTree.cxx:1166
 TKDTree.cxx:1167
 TKDTree.cxx:1168
 TKDTree.cxx:1169
 TKDTree.cxx:1170
 TKDTree.cxx:1171
 TKDTree.cxx:1172
 TKDTree.cxx:1173
 TKDTree.cxx:1174
 TKDTree.cxx:1175
 TKDTree.cxx:1176
 TKDTree.cxx:1177
 TKDTree.cxx:1178
 TKDTree.cxx:1179
 TKDTree.cxx:1180
 TKDTree.cxx:1181
 TKDTree.cxx:1182
 TKDTree.cxx:1183
 TKDTree.cxx:1184
 TKDTree.cxx:1185
 TKDTree.cxx:1186
 TKDTree.cxx:1187
 TKDTree.cxx:1188
 TKDTree.cxx:1189
 TKDTree.cxx:1190
 TKDTree.cxx:1191
 TKDTree.cxx:1192
 TKDTree.cxx:1193
 TKDTree.cxx:1194
 TKDTree.cxx:1195
 TKDTree.cxx:1196
 TKDTree.cxx:1197
 TKDTree.cxx:1198
 TKDTree.cxx:1199
 TKDTree.cxx:1200
 TKDTree.cxx:1201
 TKDTree.cxx:1202
 TKDTree.cxx:1203
 TKDTree.cxx:1204
 TKDTree.cxx:1205
 TKDTree.cxx:1206
 TKDTree.cxx:1207
 TKDTree.cxx:1208
 TKDTree.cxx:1209
 TKDTree.cxx:1210
 TKDTree.cxx:1211
 TKDTree.cxx:1212
 TKDTree.cxx:1213
 TKDTree.cxx:1214
 TKDTree.cxx:1215
 TKDTree.cxx:1216
 TKDTree.cxx:1217
 TKDTree.cxx:1218
 TKDTree.cxx:1219
 TKDTree.cxx:1220
 TKDTree.cxx:1221
 TKDTree.cxx:1222
 TKDTree.cxx:1223
 TKDTree.cxx:1224