49 Bool_t operator()(UInt_t bin1, UInt_t bin2) {
50 return bins->GetBinDensity(bin1) < bins->GetBinDensity(bin2);
58 Bool_t operator()(UInt_t bin1, UInt_t bin2) {
59 return bins->GetBinDensity(bin1) > bins->GetBinDensity(bin2);
84 this->Warning(
"TKDTreeBinning",
"Data is nil. Nothing is built.");
108 this->Warning(
"TKDTreeBinning",
"Data is nil. Nothing is built.");
136 this->Info(
"SetNBins",
"Number of bins is not enough to hold the data. Extra bin added.");
145 this->Warning(
"SetNBins",
"Number of bins is bigger than data size. Nothing is built.");
150 this->Warning(
"SetNBins",
"Data dimension is nil. Nothing is built.");
152 this->Warning(
"SetNBins",
"Number of bins is nil. Nothing is built.");
154 this->Warning(
"SetNBins",
"Data size is nil. Nothing is built.");
164 std::vector<UInt_t> indices(
fNBins);
165 for (UInt_t i = 0; i <
fNBins; ++i)
168 std::sort(indices.begin(), indices.end(),
CompareAsc(
this));
171 std::sort(indices.begin(), indices.end(),
CompareDesc(
this));
174 std::vector<Double_t> binMinEdges(fNBins *
fDim);
175 std::vector<Double_t> binMaxEdges(fNBins * fDim);
176 std::vector<UInt_t> binContent(fNBins );
178 for (UInt_t i = 0; i <
fNBins; ++i) {
179 for (UInt_t j = 0; j <
fDim; ++j) {
180 binMinEdges[i * fDim + j] =
fBinMinEdges[indices[i] * fDim + j];
181 binMaxEdges[i * fDim + j] =
fBinMaxEdges[indices[i] * fDim + j];
214 auto first =
fData.begin();
215 for (UInt_t i = 0; i <
fDim; ++i) {
217 fData[i*fDataSize+j] = data[i * fDataSize + j];
220 fDataThresholds[i] = std::make_pair(*std::min_element(first, end), *std::max_element(first,end));
227 auto first =
fData.begin();
229 for (UInt_t i = 0; i <
fDim; ++i) {
231 fDataThresholds[i] = std::make_pair(*std::min_element(first, end), *std::max_element(first,end));
238 for (UInt_t i = 0; i <
fDim; ++i)
245 for (UInt_t i = 0; i <
fNBins; ++i)
255 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)));
256 fCommonBinEdges = std::vector<std::map<Double_t, std::vector<UInt_t> > >(
fDim, std::map<Double_t, std::vector<UInt_t> >());
271 for (UInt_t i = 0; i <
fNBins; ++i) {
272 for (UInt_t j = 0; j <
fDim; ++j) {
274 fBinMaxEdges.push_back(binEdges[(i * fDim + j) * 2 + 1]);
281 for (UInt_t i = 0; i <
fDim; ++i) {
282 for (UInt_t j = 0; j <
fNBins; ++j) {
283 Double_t binEdge = binEdges[(j * fDim + i) * 2];
285 std::vector<UInt_t> commonBinEdges;
286 for (UInt_t k = 0; k <
fNBins; ++k) {
287 UInt_t minBinEdgePos = (k * fDim + i) * 2;
289 commonBinEdges.push_back(minBinEdgePos);
290 UInt_t maxBinEdgePos = ++minBinEdgePos;
292 commonBinEdges.push_back(maxBinEdgePos);
303 for (UInt_t i = 0; i <
fDim; ++i) {
304 for (UInt_t j = 0; j <
fNBins; ++j) {
306 Double_t binEdge = binEdges[(j * fDim + i) * 2];
307 Double_t adjustedBinEdge = binEdge;
309 if (adjustedBinEdge != 0)
310 adjustedBinEdge *= (1. + eps);
312 adjustedBinEdge += eps;
316 Bool_t isMinBinEdge = binEdgePos % 2 == 0;
317 UInt_t bin = isMinBinEdge ? (binEdgePos / 2 - i) / fDim : ((binEdgePos - 1) / 2 - i) / fDim;
318 binEdges[binEdgePos] = adjustedBinEdge;
332 for (UInt_t i = 0; i <
fDim; ++i) {
333 for (UInt_t j = 0; j <
fNBins; ++j) {
335 Double_t& binEdge = binEdges[(j * fDim + i) * 2 + 1];
338 binEdge *= (1. + eps);
353 this->Warning(
"GetBinsMinEdges",
"Binning kd-tree is nil. No bin edges retrieved.");
354 this->Info(
"GetBinsMinEdges",
"Returning null pointer.");
364 this->Warning(
"GetBinsMaxEdges",
"Binning kd-tree is nil. No bin edges retrieved.");
365 this->Info(
"GetBinsMaxEdges",
"Returning null pointer.");
374 this->Warning(
"GetBinsEdges",
"Binning kd-tree is nil. No bin edges retrieved.");
375 this->Info(
"GetBinsEdges",
"Returning null pointer pair.");
376 return std::make_pair((Double_t*)0, (Double_t*)0);
385 this->Warning(
"GetBinMinEdges",
"No such bin. 'bin' is between 0 and %d",
fNBins - 1);
387 this->Warning(
"GetBinMinEdges",
"Binning kd-tree is nil. No bin edges retrieved.");
388 this->Info(
"GetBinMinEdges",
"Returning null pointer.");
398 this->Warning(
"GetBinMaxEdges",
"No such bin. 'bin' is between 0 and %d",
fNBins - 1);
400 this->Warning(
"GetBinMaxEdges",
"Binning kd-tree is nil. No bin edges retrieved.");
401 this->Info(
"GetBinMaxEdges",
"Returning null pointer.");
411 this->Warning(
"GetBinEdges",
"No such bin. 'bin' is between 0 and %d",
fNBins - 1);
413 this->Warning(
"GetBinEdges",
"Binning kd-tree is nil. No bin edges retrieved.");
414 this->Info(
"GetBinEdges",
"Returning null pointer pair.");
415 return std::make_pair((Double_t*)0, (Double_t*)0);
432 this->Warning(
"GetBinContent",
"No such bin. Returning 0.");
433 this->Info(
"GetBinContent",
"'bin' is between 0 and %d.",
fNBins - 1);
442 this->Warning(
"GetTree",
"Binning kd-tree is nil. No embedded kd-tree retrieved. Returning null pointer.");
450 this->Warning(
"GetDimData",
"No such dimensional coordinate. No coordinate data retrieved. Returning null pointer.");
451 this->Info(
"GetDimData",
"'dim' is between 0 and %d.",
fDim - 1);
459 this->Warning(
"GetDataMin",
"No such dimensional coordinate. No coordinate data minimum retrieved. Returning +inf.");
460 this->Info(
"GetDataMin",
"'dim' is between 0 and %d.",
fDim - 1);
461 return std::numeric_limits<Double_t>::infinity();
468 this->Warning(
"GetDataMax",
"No such dimensional coordinate. No coordinate data maximum retrieved. Returning -inf.");
469 this->Info(
"GetDataMax",
"'dim' is between 0 and %d.",
fDim - 1);
470 return -1 * std::numeric_limits<Double_t>::infinity();
479 this->Warning(
"GetBinDensity",
"Volume is null. Returning -1.");
482 this->Warning(
"GetBinDensity",
"No such bin. Returning -1.");
483 this->Info(
"GetBinDensity",
"'bin' is between 0 and %d.",
fNBins - 1);
490 std::pair<const Double_t*, const Double_t*> binEdges =
GetBinEdges(bin);
491 Double_t volume = 1.;
492 for (UInt_t i = 0; i <
fDim; ++i) {
493 volume *= (binEdges.second[i] - binEdges.first[i]);
497 this->Warning(
"GetBinVolume",
"No such bin. Returning 0.");
498 this->Info(
"GetBinVolume",
"'bin' is between 0 and %d.",
fNBins - 1);
510 this->Warning(
"GetOneDimBinEdges",
"Data is multidimensional. No sorted bin edges retrieved. Returning null pointer.");
511 this->Info(
"GetOneDimBinEdges",
"This method can only be invoked if the data is a one dimensional set");
518 this->Warning(
"SortOneDimBinEdges",
"Data is multidimensional. Cannot sorted bin edges. Returning null pointer.");
519 this->Info(
"SortOneDimBinEdges",
"This method can only be invoked if the data is a one dimensional set");
523 std::vector<UInt_t> indices(
fNBins);
526 std::vector<Double_t> binMinEdges(
fNBins );
527 std::vector<Double_t> binMaxEdges(
fNBins );
528 std::vector<UInt_t> binContent(
fNBins );
530 for (UInt_t i = 0; i <
fNBins; ++i) {
556 Double_t* result =
new Double_t[
fDim];
557 std::pair<const Double_t*, const Double_t*> binEdges =
GetBinEdges(bin);
558 for (UInt_t i = 0; i <
fDim; ++i) {
559 result[i] = (binEdges.second[i] + binEdges.first[i]) / 2.;
563 this->Warning(
"GetBinCenter",
"No such bin. Returning null pointer.");
564 this->Info(
"GetBinCenter",
"'bin' is between 0 and %d.",
fNBins - 1);
571 Double_t* result =
new Double_t[
fDim];
572 std::pair<const Double_t*, const Double_t*> binEdges =
GetBinEdges(bin);
573 for (UInt_t i = 0; i <
fDim; ++i) {
574 result[i] = (binEdges.second[i] - binEdges.first[i]);
578 this->Warning(
"GetBinWidth",
"No such bin. Returning null pointer.");
579 this->Info(
"GetBinWidth",
"'bin' is between 0 and %d.",
fNBins - 1);
590 UInt_t* indices =
new UInt_t[
fNBins];
591 for (UInt_t i = 0; i <
fNBins; ++i)
593 UInt_t result = *std::max_element(indices, indices + fNBins,
CompareAsc(
this));
605 UInt_t* indices =
new UInt_t[
fNBins];
606 for (UInt_t i = 0; i <
fNBins; ++i)
608 UInt_t result = *std::min_element(indices, indices + fNBins,
CompareAsc(
this));
617 for (
unsigned int i = 0; i <
fNBins; ++i) {
630 R__ASSERT( inode >= 0);
640 std::vector<Double_t> point(
fDim);
641 std::vector< std::vector<Double_t> > thePoints;
642 if (
fData.size() == 0) {
643 Error(
"GetPointsInBin",
"Internal data set is not valid");
647 Error(
"GetPointsInBin",
"Internal TKDTree is not valid");
651 Error(
"GetPointsInBin",
"Invalid bin number");
658 thePoints.resize(npoints);
659 for (
int ipoint = 0; ipoint < npoints; ++ipoint) {
660 for (
unsigned int idim = 0; idim <
fDim; ++idim) {
663 thePoints[ipoint] = point;
670 void TKDTreeBinning::Streamer(TBuffer &
b) {
671 if (b.IsReading() ) {
673 Version_t
v = b.ReadVersion(&R__s, &R__c);
674 b.ReadClassBuffer(TKDTreeBinning::Class(),
this, v, R__s, R__c);
681 b.WriteClassBuffer(TKDTreeBinning::Class(),
this);
TKDTreeID * GetTree() const
Returns the kD-Tree structure of the binning.
std::vector< std::vector< std::pair< Bool_t, Bool_t > > > fCheckedBinEdges
Minimum and maximum data values.
std::vector< Double_t > fBinMaxEdges
The minimum values for the bins' edges for each dimension.
void SetData(Index npoints, Index ndim, UInt_t bsize, Value **data)
Set the data array. See the constructor function comments for details.
const Double_t * GetBinsMinEdges() const
Returns an array with all bins' minimum edges The edges are arranges as xmin_1,ymin_1, xmin_2,ymin_2,....xmin_{nbin},ymin_{nbin}.
Index 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
void SetBinMinMaxEdges(Double_t *binEdges)
Index * 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 fOffsetfBucketSize
Double_t GetDataMax(UInt_t dim) const
Returns the maximum of the data in the dim coordinate. 'dim' is between 0 and fDim - 1...
friend struct CompareDesc
! Predicate for descending sort
std::vector< UInt_t > fBinsContent
Flags if the bin edges are sorted densitywise (or by bin-edge for 1D) in ascending order...
UInt_t GetBinMinDensity() const
Return the bin with minimum density.
void SetData(Double_t *data)
Disallowed assign operator.
const Double_t * GetBinsMaxEdges() const
Returns an array with all bins' maximum edges The edges are arranges as xmax_1,ymax_1, xmax_2,ymax_2,....xmax_{nbin},ymax_{nbin}.
std::pair< const Double_t *, const Double_t * > GetBinEdges(UInt_t bin) const
Returns a pir with the bin's edges. 'bin' is between 0 and fNBins - 1.
UInt_t GetNBins() const
Returns the number of bins.
TKDTreeBinning()
Default constructor (for I/O)
void SetNBins(UInt_t bins)
Sets binning inner structure.
Index GetNPointsNode(Int_t node) const
Get number of points in this node for all the terminal nodes except last, the size is fBucketSize for...
void AddBinUpEdge(const double *xup)
add the bin width data, a pointer to an array with the bin upper edge information.
void Build()
Build the kd-tree.
UInt_t fDataSize
The data dimension.
Bool_t fIsSortedAsc
Flags if the bin edges are sorted densitywise (or by bin endges in case of 1-dim ) ...
~TKDTreeBinning()
Class's destructor.
void Initialize(unsigned int newPoints, unsigned int dim=1, ErrorType err=kValueError)
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
const Double_t * SortOneDimBinEdges(Bool_t sortAsc=kTRUE)
Sort the one-dimensional bin edges and retuns a pointer to them.
<- TKDTreeBinning - A class providing multidimensional binning ->
Double_t GetDataMin(UInt_t dim) const
Returns the minimum of the data in the dim coordinate. 'dim' is between 0 and fDim - 1...
Class implementing a kd-tree.
TKDTreeID * fDataBins
Index of the bins in the kd-tree (needed when bins are sorted)
const Double_t * GetBinCenter(UInt_t bin) const
Returns the geometric center of of the bin. 'bin' is between 0 and fNBins - 1.
void ReadjustMaxBinEdges(Double_t *binEdges)
std::vector< Double_t > fBinMinEdges
[fDataSize*fDim] The data from which a KDTree partition is computed for binning
Double_t GetBinDensity(UInt_t bin) const
Returns the density in bin.
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
std::vector< Double_t > fData
UInt_t GetBinContent(UInt_t bin) const
Returns the number of points in bin. 'bin' is between 0 and fNBins - 1.
std::vector< UInt_t > fIndices
The maximum values for the bins' edges for each dimension.
const Double_t * GetBinMinEdges(UInt_t bin) const
Returns the bin's minimum edges. 'bin' is between 0 and fNBins - 1.
const Double_t * GetBinWidth(UInt_t bin) const
Returns a pointer to the vector of the bin widths. 'bin' is between 0 and fNBins - 1...
friend struct CompareAsc
! Predicate for ascending sort
const Double_t * GetDimData(UInt_t dim) const
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
std::vector< std::pair< Double_t, Double_t > > fDataThresholds
The data size.
TKDTree< Int_t, Double_t > TKDTreeID
void SortBinsByDensity(Bool_t sortAsc=kTRUE)
Sorts bins by their density.
void FillBinData(ROOT::Fit::BinData &data) const
Fill the bin data set (class ROOT::Fit::BinData) with the result of the TKDTree binning.
void Add(double x, double y)
add one dim data with only coordinate and values
UInt_t GetBinMaxDensity() const
Return the bin with maximum density.
std::pair< const Double_t *, const Double_t * > GetBinsEdges() const
Returns a pair of an array with all bins minimum and maximum edges.
void SetCommonBinEdges(Double_t *binEdges)
const Double_t * GetBinMaxEdges(UInt_t bin) const
Returns the bin's maximum edges. 'bin' is between 0 and fNBins - 1.
void ReadjustMinBinEdges(Double_t *binEdges)
UInt_t fDim
The number of bins.
std::vector< std::map< Double_t, std::vector< UInt_t > > > fCommonBinEdges
! Auxiliary structure for readjusting the bin edges. Keeps the common bin boundaries ...
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Double_t GetBinVolume(UInt_t bin) const
Returns the (hyper)volume of bin. 'bin' is between 0 and fNBins - 1.
UInt_t FindBin(const Double_t *point) const
find the corresponding bin index given the coordinate of a point
UInt_t GetDim() const
Returns the number of dimensions.
std::vector< std::vector< Double_t > > GetPointsInBin(UInt_t bin) const
Return the corresponding point belonging to the bin i.
Value * GetBoundary(const Int_t node)
Get a boundary.
const Double_t * GetOneDimBinEdges() const
Returns a pointer to the vector of the bin edges for one dimensional binning only.