TKDTreeBinning.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: TKDTreeBinning.cxx 37486 2010-12-10 10:26:09Z moneta $
00002 // Authors: B. Rabacal   11/2010
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2010 , LCG ROOT MathLib Team                         *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // implementation file for class TKDTreeBinning
00012 //
00013 
00014 #include <algorithm>
00015 #include <limits>
00016 #include <cmath>
00017 
00018 #include "TKDTreeBinning.h"
00019 
00020 #include "Fit/BinData.h"
00021 
00022 ClassImp(TKDTreeBinning)
00023 
00024 //________________________________________________________________________________________________
00025 // Begin_Html 
00026 // <center><h2>TKDTreeBinning - A class providing multidimensional binning</h2></center>
00027 // The class implements multidimensional binning by constructing a TKDTree inner structure from the
00028 // data which is used as the bins. 
00029 // The bins are retrieved as two double*, one for the minimum bin edges,
00030 // the other as the maximum bin edges. For one dimension one of these is enough to correctly define the bins.
00031 // For the multidimensional case both minimum and maximum ones are necessary for the bins to be well defined.
00032 // The bin edges of d-dimensional data is a d-tet of the bin's thresholds. For example if d=3 the minimum bin
00033 // edges of bin b is of the form of the following array: {xbmin, ybmin, zbmin}.
00034 // You also have the possibility to sort the bins by their density.
00035 // <br>
00036 // Details of usage can be found in $ROOTSYS/tutorials/math/kdTreeBinning.C and more information on
00037 // the embedded TKDTree can be found in http://root.cern.ch/lxr/source/math/mathcore/src/TKDTree.cxx or
00038 // http://root.cern.ch/lxr/source/math/mathcore/inc/TKDTree.h.
00039 // End_Html
00040 
00041 struct TKDTreeBinning::CompareAsc {
00042    // Boolean functor whose predicate depends on the bin's density. Used for ascending sort.
00043    CompareAsc(const TKDTreeBinning* treebins) : bins(treebins) {}
00044    Bool_t operator()(UInt_t bin1, UInt_t bin2) {
00045       return bins->GetBinDensity(bin1) < bins->GetBinDensity(bin2);
00046    }
00047    const TKDTreeBinning* bins;
00048 };
00049 
00050 struct TKDTreeBinning::CompareDesc {
00051    // Boolean functor whose predicate depends on the bin's density. Used for descending sort.
00052    CompareDesc(const TKDTreeBinning* treebins) : bins(treebins) {}
00053    Bool_t operator()(UInt_t bin1, UInt_t bin2) {
00054       return bins->GetBinDensity(bin1) > bins->GetBinDensity(bin2);
00055    }
00056    const TKDTreeBinning* bins;
00057 };
00058 
00059 TKDTreeBinning::TKDTreeBinning(UInt_t dataSize, UInt_t dataDim, Double_t* data, UInt_t nBins)
00060 // Class's constructor taking the size of the data points, dimension, a data array and the number 
00061 // of bins (default = 100). It is reccomended to have the number of bins as an exact divider of 
00062 // the data size.  
00063 // The data array must be organized with a stride=1 for the points and = N (the dataSize) for the dimension.
00064 // 
00065 // Thus data[] = x1,x2,x3,......xN, y1,y2,y3......yN, z1,z2,...........zN,....
00066 //
00067 // Note that the passed dataSize is not the size of the array but is the number of points (N)
00068 // The size of the array must be at least  dataDim*dataSize 
00069 // 
00070 : fData(0), fBinMinEdges(std::vector<Double_t>()), fBinMaxEdges(std::vector<Double_t>()), fDataBins((TKDTreeID*)0), fDim(dataDim),
00071 fDataSize(dataSize), fDataThresholds(std::vector<std::pair<Double_t, Double_t> >(fDim, std::make_pair(0., 0.))),
00072 fIsSorted(kFALSE), fIsSortedAsc(kFALSE), fBinsContent(std::vector<UInt_t>()) {
00073    if (data) {
00074       SetData(data);
00075       SetNBins(nBins);
00076    } else {
00077       if (!fData)
00078          this->Warning("TKDTreeBinning", "Data is nil. Nothing is built.");
00079    }
00080 }
00081 
00082 TKDTreeBinning::~TKDTreeBinning() {
00083    // Class's destructor
00084    if (fData)     delete[] fData;
00085    if (fDataBins) delete   fDataBins;
00086 }
00087 
00088 void TKDTreeBinning::SetNBins(UInt_t bins) {
00089    // Sets binning inner structure
00090    fNBins = bins;
00091    if (fDim && fNBins && fDataSize) {
00092       if (fDataSize / fNBins) {
00093          Bool_t remainingData = fDataSize % fNBins;
00094          if (remainingData) {
00095             fNBins += 1;
00096             this->Info("SetNBins", "Number of bins is not enough to hold the data. Extra bin added.");
00097          }
00098          fDataBins = new TKDTreeID(fDataSize, fDim, fDataSize / (fNBins - remainingData)); // TKDTree input is data size, data dimension and the content size of bins ("bucket" size)
00099          SetTreeData();
00100          fDataBins->Build();
00101          SetBinsEdges();
00102          SetBinsContent();
00103       } else {
00104          fDataBins = (TKDTreeID*)0;
00105          this->Warning("SetNBins", "Number of bins is bigger than data size. Nothing is built.");
00106       }
00107    } else {
00108       fDataBins = (TKDTreeID*)0;
00109       if (!fDim)
00110          this->Warning("SetNBins", "Data dimension is nil. Nothing is built.");
00111       if (!fNBins)
00112          this->Warning("SetNBins", "Number of bins is nil. Nothing is built.");
00113       if (!fDataSize)
00114          this->Warning("SetNBins", "Data size is nil. Nothing is built.");
00115    }
00116 }
00117 
00118 void TKDTreeBinning::SortBinsByDensity(Bool_t sortAsc) {
00119    // Sorts bins by their density
00120    if (fDim == 1) {
00121       fIsSortedAsc = kTRUE;
00122       std::sort(fBinMinEdges.begin(), fBinMinEdges.end());
00123       std::sort(fBinMaxEdges.begin(), fBinMaxEdges.end());
00124       // Add also the upper edge to the min
00125       fBinMinEdges.push_back(fBinMaxEdges.back());
00126       if (!sortAsc) {
00127          std::reverse(fBinMinEdges.begin(), fBinMinEdges.end());
00128          std::reverse(fBinMaxEdges.begin(), fBinMaxEdges.end());
00129          fIsSortedAsc = kFALSE;
00130       }
00131    } else {
00132       UInt_t* indices = new UInt_t[fNBins];
00133       for (UInt_t i = 0; i < fNBins; ++i)
00134          indices[i] = i;
00135       if (sortAsc) {
00136          std::sort(indices, indices + fNBins, CompareAsc(this));
00137          fIsSortedAsc = kTRUE;
00138       } else {
00139          std::sort(indices, indices + fNBins, CompareDesc(this));
00140          fIsSortedAsc = kFALSE;
00141       }
00142       std::vector<Double_t> binMinEdges; binMinEdges.reserve(fNBins * fDim);
00143       std::vector<Double_t> binMaxEdges; binMaxEdges.reserve(fNBins * fDim);
00144       for (UInt_t i = 0; i < fNBins; ++i) {
00145          for (UInt_t j = 0; j < fDim; ++j) {
00146             binMinEdges[i * fDim + j] = fBinMinEdges[indices[i] * fDim + j];
00147             binMaxEdges[i * fDim + j] = fBinMaxEdges[indices[i] * fDim + j];
00148          }
00149       }
00150       fBinMinEdges.swap(binMinEdges);
00151       fBinMaxEdges.swap(binMaxEdges);
00152       // re-adjust content of extra bins if exists
00153       // since it is different than the others
00154       if ( fDataSize % fNBins != 0) {
00155          UInt_t k = 0;
00156          Bool_t found = kFALSE;
00157          while (!found) {
00158             if (indices[k] == fNBins - 1) {
00159                found = kTRUE;
00160                break;
00161             }
00162             ++k;
00163          }
00164          fBinsContent[fNBins - 1] = fDataBins->GetBucketSize();
00165          fBinsContent[k] = fDataSize % fNBins-1;
00166       }
00167       delete [] indices;
00168       fIsSorted = kTRUE;
00169     }
00170 }
00171 
00172 void TKDTreeBinning::SetData(Double_t* data) {
00173    // Sets the data and finds minimum and maximum by dimensional coordinate
00174    fData = new Double_t*[fDim];
00175    for (UInt_t i = 0; i < fDim; ++i) {
00176       fData[i] = &data[i * fDataSize];
00177       fDataThresholds[i] = std::make_pair(*std::min_element(fData[i], fData[i] + fDataSize), *std::max_element(fData[i], fData[i] + fDataSize));
00178    }
00179 }
00180 
00181 void TKDTreeBinning::SetTreeData() {
00182    // Sets the data for constructing the kD-tree
00183    for (UInt_t i = 0; i < fDim; ++i)
00184       fDataBins->SetData(i, fData[i]);
00185 }
00186 
00187 void TKDTreeBinning::SetBinsContent() {
00188    // Sets the bins' content
00189    fBinsContent.reserve(fNBins);
00190    for (UInt_t i = 0; i < fNBins; ++i)
00191       fBinsContent[i] = fDataBins->GetBucketSize();
00192    if ( fDataSize % fNBins != 0 )
00193       fBinsContent[fNBins - 1] = fDataSize % (fNBins-1);
00194 }
00195 
00196 void TKDTreeBinning::SetBinsEdges() {
00197    // Sets the bins' edges
00198    Double_t* rawBinEdges = fDataBins->GetBoundary(fDataBins->GetNNodes());
00199    fCheckedBinEdges = std::vector<std::vector<std::pair<Bool_t, Bool_t> > >(fDim, std::vector<std::pair<Bool_t, Bool_t> >(fNBins, std::make_pair(kFALSE, kFALSE)));
00200    fCommonBinEdges = std::vector<std::map<Double_t, std::vector<UInt_t> > >(fDim, std::map<Double_t, std::vector<UInt_t> >());
00201    SetCommonBinEdges(rawBinEdges);
00202    if (TestBit(kAdjustBinEdges) ) {
00203       ReadjustMinBinEdges(rawBinEdges);
00204       ReadjustMaxBinEdges(rawBinEdges);
00205    }
00206    SetBinMinMaxEdges(rawBinEdges);
00207    fCommonBinEdges.clear();
00208    fCheckedBinEdges.clear();
00209 }
00210 
00211 void TKDTreeBinning::SetBinMinMaxEdges(Double_t* binEdges) {
00212    // Sets the bins' minimum and maximum edges
00213    fBinMinEdges.reserve(fNBins * fDim);
00214    fBinMaxEdges.reserve(fNBins * fDim);
00215    for (UInt_t i = 0; i < fNBins; ++i) {
00216       for (UInt_t j = 0; j < fDim; ++j) {
00217          fBinMinEdges.push_back(binEdges[(i * fDim + j) * 2]);
00218          fBinMaxEdges.push_back(binEdges[(i * fDim + j) * 2 + 1]);
00219       }
00220    }
00221 }
00222 
00223 void TKDTreeBinning::SetCommonBinEdges(Double_t* binEdges) {
00224    // Sets indexing on the bin edges which have common boundaries
00225    for (UInt_t i = 0; i < fDim; ++i) {
00226       for (UInt_t j = 0; j < fNBins; ++j) {
00227          Double_t binEdge = binEdges[(j * fDim + i) * 2];
00228          if(fCommonBinEdges[i].find(binEdge) == fCommonBinEdges[i].end()) {
00229             std::vector<UInt_t> commonBinEdges;
00230             for (UInt_t k = 0; k < fNBins; ++k) {
00231                UInt_t minBinEdgePos = (k * fDim + i) * 2;
00232                if (std::fabs(binEdge - binEdges[minBinEdgePos]) < std::numeric_limits<Double_t>::epsilon())
00233                   commonBinEdges.push_back(minBinEdgePos);
00234                UInt_t maxBinEdgePos = ++minBinEdgePos;
00235                if (std::fabs(binEdge - binEdges[maxBinEdgePos]) < std::numeric_limits<Double_t>::epsilon())
00236                   commonBinEdges.push_back(maxBinEdgePos);
00237             }
00238             fCommonBinEdges[i][binEdge] = commonBinEdges;
00239          }
00240       }
00241    }
00242 }
00243 
00244 void TKDTreeBinning::ReadjustMinBinEdges(Double_t* binEdges) {
00245    // Readjusts the bins' minimum edge
00246    for (UInt_t i = 0; i < fDim; ++i) {
00247       for (UInt_t j = 0; j < fNBins; ++j) {
00248          if (!fCheckedBinEdges[i][j].first) {
00249             Double_t binEdge = binEdges[(j * fDim + i) * 2];
00250             Double_t adjustedBinEdge = binEdge;
00251             adjustedBinEdge -= 1.5 * std::numeric_limits<Double_t>::epsilon();
00252             for (UInt_t k = 0; k < fCommonBinEdges[i][binEdge].size(); ++k) {
00253                UInt_t binEdgePos = fCommonBinEdges[i][binEdge][k];
00254                Bool_t isMinBinEdge = binEdgePos % 2 == 0;
00255                UInt_t bin = isMinBinEdge ? (binEdgePos / 2 - i) / fDim : ((binEdgePos - 1) / 2 - i) / fDim;
00256                binEdges[binEdgePos] = adjustedBinEdge;
00257                if (isMinBinEdge)
00258                   fCheckedBinEdges[i][bin].first = kTRUE;
00259                else
00260                   fCheckedBinEdges[i][bin].second = kTRUE;
00261             }
00262          }
00263       }
00264    }
00265 }
00266 
00267 void TKDTreeBinning::ReadjustMaxBinEdges(Double_t* binEdges) {
00268    // Readjusts the bins' maximum edge
00269    for (UInt_t i = 0; i < fDim; ++i) {
00270       for (UInt_t j = 0; j < fNBins; ++j) {
00271          if (!fCheckedBinEdges[i][j].second) {
00272             Double_t& binEdge = binEdges[(j * fDim + i) * 2 + 1];
00273             binEdge += 1.5 * std::numeric_limits<Double_t>::epsilon();
00274          }
00275       }
00276    }
00277 }
00278 
00279 const Double_t* TKDTreeBinning::GetBinsMinEdges() const {
00280    // Returns the bins' minimum edges
00281    if (fDataBins)
00282       return &fBinMinEdges[0];
00283    this->Warning("GetBinsMinEdges", "Binning kd-tree is nil. No bin edges retrieved.");
00284    this->Info("GetBinsMinEdges", "Returning null pointer.");
00285    return (Double_t*)0;
00286 }
00287 
00288 const Double_t* TKDTreeBinning::GetBinsMaxEdges() const {
00289    // Returns the bins' maximum edges
00290    if (fDataBins)
00291       return &fBinMaxEdges[0];
00292    this->Warning("GetBinsMaxEdges", "Binning kd-tree is nil. No bin edges retrieved.");
00293    this->Info("GetBinsMaxEdges", "Returning null pointer.");
00294    return (Double_t*)0;
00295 }
00296 
00297 std::pair<const Double_t*, const Double_t*> TKDTreeBinning::GetBinsEdges() const {
00298    // Returns the bins' edges
00299    if (fDataBins)
00300       return std::make_pair(GetBinsMinEdges(), GetBinsMaxEdges());
00301    this->Warning("GetBinsEdges", "Binning kd-tree is nil. No bin edges retrieved.");
00302    this->Info("GetBinsEdges", "Returning null pointer pair.");
00303    return std::make_pair((Double_t*)0, (Double_t*)0);
00304 }
00305 
00306 const Double_t* TKDTreeBinning::GetBinMinEdges(UInt_t bin) const {
00307    // Returns the bin's minimum edges. 'bin' is between 0 and fNBins - 1
00308    if (fDataBins)
00309       if (bin < fNBins)
00310          return &fBinMinEdges[bin * fDim];
00311       else
00312          this->Warning("GetBinMinEdges", "No such bin. 'bin' is between 0 and %d", fNBins - 1);
00313    else
00314       this->Warning("GetBinMinEdges", "Binning kd-tree is nil. No bin edges retrieved.");
00315    this->Info("GetBinMinEdges", "Returning null pointer.");
00316    return (Double_t*)0;
00317 }
00318 
00319 const Double_t* TKDTreeBinning::GetBinMaxEdges(UInt_t bin) const {
00320    // Returns the bin's maximum edges. 'bin' is between 0 and fNBins - 1
00321    if (fDataBins)
00322       if (bin < fNBins)
00323          return &fBinMaxEdges[bin * fDim];
00324       else
00325          this->Warning("GetBinMaxEdges", "No such bin. 'bin' is between 0 and %d", fNBins - 1);
00326    else
00327       this->Warning("GetBinMaxEdges", "Binning kd-tree is nil. No bin edges retrieved.");
00328    this->Info("GetBinMaxEdges", "Returning null pointer.");
00329    return (Double_t*)0;
00330 }
00331 
00332 std::pair<const Double_t*, const Double_t*> TKDTreeBinning::GetBinEdges(UInt_t bin) const {
00333    // Returns the bin's edges. 'bin' is between 0 and fNBins - 1
00334    if (fDataBins)
00335       if (bin < fNBins)
00336          return std::make_pair(GetBinMinEdges(bin), GetBinMaxEdges(bin));
00337       else
00338          this->Warning("GetBinEdges", "No such bin. 'bin' is between 0 and %d", fNBins - 1);
00339    else
00340       this->Warning("GetBinEdges", "Binning kd-tree is nil. No bin edges retrieved.");
00341    this->Info("GetBinEdges", "Returning null pointer pair.");
00342    return std::make_pair((Double_t*)0, (Double_t*)0);
00343 }
00344 
00345 UInt_t TKDTreeBinning::GetNBins() const {
00346    // Returns the number of bins
00347    return fNBins;
00348 }
00349 
00350 UInt_t TKDTreeBinning::GetDim() const {
00351    // Returns the number of dimensions
00352    return fDim;
00353 }
00354 
00355 UInt_t TKDTreeBinning::GetBinContent(UInt_t bin) const {
00356    // Returns the number of points in bin. 'bin' is between 0 and fNBins - 1
00357    if(bin <= fNBins - 1)
00358          return fBinsContent[bin];
00359    this->Warning("GetBinContent", "No such bin. Returning 0.");
00360    this->Info("GetBinContent", "'bin' is between 0 and %d.", fNBins - 1);
00361    return 0;
00362 }
00363 
00364 TKDTreeID* TKDTreeBinning::GetTree() const {
00365    // Returns the kD-Tree structure of the binning
00366    if (fDataBins)
00367       return fDataBins;
00368    this->Warning("GetTree", "Binning kd-tree is nil. No embedded kd-tree retrieved. Returning null pointer.");
00369    return (TKDTreeID*)0;
00370 }
00371 
00372 const Double_t* TKDTreeBinning::GetDimData(UInt_t dim) const {
00373    // Returns the data in the dim coordinate. 'dim' is between 0 and fDim - 1
00374    if(dim < fDim)
00375       return fData[dim];
00376    this->Warning("GetDimData", "No such dimensional coordinate. No coordinate data retrieved. Returning null pointer.");
00377    this->Info("GetDimData", "'dim' is between 0 and %d.", fDim - 1);
00378    return 0;
00379 }
00380 
00381 Double_t TKDTreeBinning::GetDataMin(UInt_t dim) const {
00382    // Returns the data minimum in the dim coordinate. 'dim' is between 0 and fDim - 1
00383    if(dim < fDim)
00384       return fDataThresholds[dim].first;
00385    this->Warning("GetDataMin", "No such dimensional coordinate. No coordinate data minimum retrieved. Returning +inf.");
00386    this->Info("GetDataMin", "'dim' is between 0 and %d.", fDim - 1);
00387    return std::numeric_limits<Double_t>::infinity();
00388 }
00389 
00390 Double_t TKDTreeBinning::GetDataMax(UInt_t dim) const {
00391    // Returns the data maximum in the dim coordinate. 'dim' is between 0 and fDim - 1
00392    if(dim < fDim)
00393       return fDataThresholds[dim].second;
00394    this->Warning("GetDataMax", "No such dimensional coordinate. No coordinate data maximum retrieved. Returning -inf.");
00395    this->Info("GetDataMax", "'dim' is between 0 and %d.", fDim - 1);
00396    return -1 * std::numeric_limits<Double_t>::infinity();
00397 }
00398 
00399 Double_t TKDTreeBinning::GetBinDensity(UInt_t bin) const {
00400    // Returns the density in bin. 'bin' is between 0 and fNBins - 1
00401    if(bin < fNBins) {
00402       Double_t volume = GetBinVolume(bin);
00403       if (!volume)
00404          this->Warning("GetBinDensity", "Volume is null. Returning -1.");
00405       return GetBinContent(bin) / volume;
00406    }
00407    this->Warning("GetBinDensity", "No such bin. Returning -1.");
00408    this->Info("GetBinDensity", "'bin' is between 0 and %d.", fNBins - 1);
00409    return -1.;
00410 }
00411 
00412 Double_t TKDTreeBinning::GetBinVolume(UInt_t bin) const {
00413    // Returns the (hyper)volume of bin. 'bin' is between 0 and fNBins - 1
00414    if(bin < fNBins) {
00415       std::pair<const Double_t*, const Double_t*> binEdges = GetBinEdges(bin);
00416       Double_t volume = 1.;
00417       for (UInt_t i = 0; i < fDim; ++i) {
00418          volume *= (binEdges.second[i] - binEdges.first[i]);
00419       }
00420       return volume;
00421    }
00422    this->Warning("GetBinVolume", "No such bin. Returning 0.");
00423    this->Info("GetBinVolume", "'bin' is between 0 and %d.", fNBins - 1);
00424    return 0.;
00425 }
00426 
00427 const double * TKDTreeBinning::GetOneDimBinEdges() const  {
00428    // Returns the sorted minimum edges for one dimensional binning only.
00429    // size of the vector is fNBins + 1
00430    if (fDim == 1) {
00431       // no need to sort here because vector is already sorted in one dim
00432       return &fBinMinEdges.front();
00433    }
00434    this->Warning("GetOneDimBinEdges", "Data is multidimensional. No sorted bin edges retrieved. Returning null pointer.");
00435    this->Info("GetOneDimBinEdges", "This method can only be invoked if the data is a one dimensional set");
00436    return 0;
00437 }
00438 
00439 const Double_t* TKDTreeBinning::GetBinCenter(UInt_t bin) const {
00440    // Returns the geometric center of of the bin. 'bin' is between 0 and fNBins - 1
00441    if(bin < fNBins) {
00442       Double_t* result = new Double_t[fDim];
00443       std::pair<const Double_t*, const Double_t*> binEdges = GetBinEdges(bin);
00444       for (UInt_t i = 0; i < fDim; ++i) {
00445          result[i] = (binEdges.second[i] + binEdges.first[i]) / 2.;
00446       }
00447       return result;
00448    }
00449    this->Warning("GetBinCenter", "No such bin. Returning null pointer.");
00450    this->Info("GetBinCenter", "'bin' is between 0 and %d.", fNBins - 1);
00451    return 0;
00452 }
00453 
00454 const Double_t* TKDTreeBinning::GetBinWidth(UInt_t bin) const {
00455    // Returns the geometric center of of the bin. 'bin' is between 0 and fNBins - 1
00456    if(bin < fNBins) {
00457       Double_t* result = new Double_t[fDim];
00458       std::pair<const Double_t*, const Double_t*> binEdges = GetBinEdges(bin);
00459       for (UInt_t i = 0; i < fDim; ++i) {
00460          result[i] = (binEdges.second[i] - binEdges.first[i]);
00461       }
00462       return result;
00463    }
00464    this->Warning("GetBinWidth", "No such bin. Returning null pointer.");
00465    this->Info("GetBinWidth", "'bin' is between 0 and %d.", fNBins - 1);
00466    return 0;
00467 }
00468 
00469 UInt_t TKDTreeBinning::GetBinMaxDensity() const {
00470    // Return the bin with maximum density
00471    if (fIsSorted) {
00472       if (fIsSortedAsc)
00473          return fNBins - 1;
00474       else return 0;
00475    }
00476    UInt_t* indices = new UInt_t[fNBins];
00477    for (UInt_t i = 0; i < fNBins; ++i)
00478       indices[i] = i;
00479    UInt_t result = *std::max_element(indices, indices + fNBins, CompareAsc(this));
00480    delete [] indices;
00481    return  result;
00482 }
00483 
00484 UInt_t TKDTreeBinning::GetBinMinDensity() const {
00485    // Return the bin with minimum density
00486    if (fIsSorted) {
00487       if (!fIsSortedAsc)
00488          return fNBins - 1;
00489       else return 0;
00490    }
00491    UInt_t* indices = new UInt_t[fNBins];
00492    for (UInt_t i = 0; i < fNBins; ++i)
00493       indices[i] = i;
00494    UInt_t result = *std::min_element(indices, indices + fNBins, CompareAsc(this));
00495    delete [] indices;
00496    return result;
00497 }
00498 
00499 void TKDTreeBinning::FillBinData(ROOT::Fit::BinData & data) const {
00500    // Fill the bin data set with the result of the TKDTree binning
00501    data.Initialize(fNBins, fDim);
00502    for (unsigned int i = 0; i < fNBins; ++i) {
00503       data.Add( GetBinMinEdges(i), GetBinDensity(i), std::sqrt(double(GetBinContent(i) ))/ GetBinVolume(i) );
00504       data.AddBinUpEdge(GetBinMaxEdges(i) );
00505    }
00506 }

Generated on Tue Jul 5 14:34:27 2011 for ROOT_528-00b_version by  doxygen 1.5.1