9 _drawAlgorithm (false),
23 _hyperCuboids (1, binningRange),
24 _linkedBins (1, std::vector<int>(0,0) ),
25 _hyperPointSets (1, filterHyperPointSet( data, binningRange, true ) ),
26 _shadowHyperPointSets (1,
HyperPointSet( binningRange.getDimension() ) ),
28 _dimSpecificStatus (1, std::vector<int>( binningRange.getDimension(),
VolumeStatus::CONTINUE ) ),
30 _useEventWeights (false),
31 _minimumBinContent (15),
32 _shadowMinimumBinContent(15),
33 _minimumEdgeLength (
HyperPoint(binningRange.getDimension(), 0.1) ),
34 _random (new TRandom3(0)),
35 _drawAlgorithm (false),
37 _names( binningRange.getDimension() ),
40 _gridMultiplier(
HyperPoint(binningRange.getDimension(), 1) )
44 WELCOME_LOG <<
"Good day from the HyperBinningMaker() Constructor"<<std::endl;
54 ERROR_LOG <<
"You can only call the updateFromExistingHyperBinning if the HyperBinningMaker has" << std::endl;
58 INFO_LOG <<
"Congratulations, you've taken the bold step of calling the updateFromExistingHyperBinning function" << std::endl;
72 for (
int i = 0; i < nvols; i++){
90 std::vector<int> binNums = binning.
getBinNum(points);
92 for (
unsigned i = 0; i < points.
size(); i++){
93 int binNum = binNums.at(i);
94 if (binNum == -1)
continue;
103 std::vector<int> shadBinNums = binning.
getBinNum(shadPoints);
105 for (
unsigned i = 0; i < shadPoints.
size(); i++){
106 int binNum = shadBinNums.at(i);
107 if (binNum == -1)
continue;
122 if (
_hyperCuboids.size() != 1)
ERROR_LOG <<
"You have to add the shadow set before you make the binning"<<std::endl;
141 double splitCoord = lowCorner.
at(dim) + (highCorner.at(dim) - lowCorner.at(dim))*splitPoint;
142 if (
_snapToGrid ==
true && noSnapToGrid ==
false ) {
143 if (
snapToGrid(original, dim, splitCoord) == false ){
149 newLowCorner.
at(dim) = splitCoord;
168 double splitCoord = lowCorner.
at(dim) + (highCorner.at(dim) - lowCorner.at(dim))*splitPoint;
169 if (
_snapToGrid ==
true && noSnapToGrid ==
false ) {
170 if (
snapToGrid(original, dim, splitCoord) == false ){
176 newHighCorner.
at(dim) = splitCoord;
187 if (print ==
true &&
s_printBinning ==
true)
INFO_LOG <<
"Before filtering there are " << hyperPointSet.
size() <<
" events" << std::endl;
190 for(
unsigned int i = 0; i < hyperPointSet.
size(); i++){
194 if (print ==
true &&
s_printBinning ==
true)
INFO_LOG <<
"After filtering there are " << temp.size() <<
" events" << std::endl;
235 return hyperPointSet.
size();
259 std::vector<int> dimStatus( hyperCuboid.
getDimension(), status);
268 bool isBinningDim =
false;
275 if (isBinningDim ==
false)
return false;
296 for (
int i = 0; i < dim; i++){
299 double width = high - low;
311 if (allDone ==
true){
327 for (
int i = 0; i < dim; i++){
338 if (allDone ==
true){
369 VERBOSE_LOG <<
"Calling the HyperBinningMaker::split function that gets used by all the algorithms" << std::endl;
373 VERBOSE_LOG <<
"This isn't a valid binning dimension, so not splitting" << std::endl;
388 VERBOSE_LOG <<
"It looks like the snap to grid option means that this bin cannot be split. Returning 0."<<std::endl;
398 if (edgeLength1 < minEdgeLength || edgeLength2 < minEdgeLength){
399 VERBOSE_LOG <<
"Tired to split bin but one of the resulting bins is too small... hopefully spliting in another dim will help."<<std::endl;
418 VERBOSE_LOG <<
"Tired to split bin but one half has too little events... hopefully spliting in another dim will help."<<std::endl;
419 VERBOSE_LOG <<
"It contained " << chosenHyperPointSet.
size() <<
" events, and was split into " << hyperPointSet1.
size() <<
" and " << hyperPointSet2.
size()<<std::endl;
426 VERBOSE_LOG <<
"Tired to split bin but one half has too little events... hopefully spliting in another dim will help."<<std::endl;
427 VERBOSE_LOG <<
"It contained " << chosenHyperPointSet.
size() <<
" events, and was split into " << hyperPointSet1.
size() <<
" and " << hyperPointSet2.
size()<<std::endl;
437 VERBOSE_LOG <<
"I tired to split this bin but the Function criteria failed." <<std::endl;
448 VERBOSE_LOG <<
"Adding HyperVolume 1 with status 1";
452 VERBOSE_LOG <<
"Adding HyperVolume 1 with status 0"<<std::endl;
457 VERBOSE_LOG <<
"Adding HyperVolume 2 with status 1"<<std::endl;
461 VERBOSE_LOG <<
"Adding HyperVolume 2 with status 0"<<std::endl;
470 VERBOSE_LOG <<
"Linking old bin to new bins"<<std::endl;
471 _linkedBins.at( volumeNumber ).push_back( newVolumeNum1 );
472 _linkedBins.at( volumeNumber ).push_back( newVolumeNum2 );
479 VERBOSE_LOG <<
"Removing data associated with old bin..." << std::endl;
482 VERBOSE_LOG <<
"and setting it's status to 0" << std::endl;
514 double absMax =
_hyperCuboids.at(0).getHighCorner ().at(dimension);
515 double absMin =
_hyperCuboids.at(0).getLowCorner ().at(dimension);
520 int nbins = floor((absMax - absMin)/minEdgeLength)*gridMultiplier;
522 double gridWidth = (absMax - absMin)/
double(nbins);
525 int binNumLow = floor( (splitCoord - absMin)/gridWidth );
526 int binNumHigh = ceil ( (splitCoord - absMin)/gridWidth );
528 double lowCoord = absMin + double(binNumLow )*gridWidth;
529 double highCoord = absMin + double(binNumHigh)*gridWidth;
532 double closestGridPoint = 0.0;
533 double furthestGridPoint = 0.0;
536 if ( fabs(lowCoord - splitCoord) <= fabs(highCoord - splitCoord) ){
537 closestGridPoint = lowCoord ;
538 furthestGridPoint = highCoord;
541 closestGridPoint = highCoord;
542 furthestGridPoint = lowCoord ;
551 if ( closestGridPoint - min >= minEdgeLength && max - closestGridPoint >= minEdgeLength ){
552 splitCoord = closestGridPoint;
555 if ( furthestGridPoint - min >= minEdgeLength && max - furthestGridPoint >= minEdgeLength ){
556 splitCoord = furthestGridPoint;
560 VERBOSE_LOG <<
"I failed to snap to grid - very sad" << std::endl;
562 splitCoord = closestGridPoint;
588 double binLength =
_hyperCuboids.at(binNumber).getHighCorner().at(dimension) -
_hyperCuboids.at(binNumber).getLowCorner().at(dimension);
592 double nAbove = total - nBelow;
594 if (useConstraints ==
true){
601 double fracBelow = nBelow/total;
602 double fracAbove = nAbove/total;
604 double PDFabove = fracAbove/(1.0 - splitPoint);
605 double PDFbelow = fracBelow/splitPoint;
607 if (PDFabove == 0.0) PDFabove = 1e-16;
608 if (PDFbelow == 0.0) PDFbelow = 1e-16;
610 return -2.0*(nAbove*log(PDFabove) + nBelow*log(PDFbelow));
615 double shadowNAbove = shadowTotal - shadowNBelow;
617 double allTotal = shadowTotal + total;
619 double PDFNumeratorAbove = (nAbove / allTotal) / (1.0 -splitPoint);
620 double PDFDenominatorAbove = (shadowNAbove / allTotal) / (1.0 -splitPoint);
621 double PDFNumeratorBelow = (nBelow / allTotal) / (splitPoint);
622 double PDFDenominatorBelow = (shadowNBelow / allTotal) / (splitPoint);
624 if (PDFNumeratorAbove <= 0.0) PDFNumeratorAbove = 1e-16;
625 if (PDFDenominatorAbove <= 0.0) PDFDenominatorAbove = 1e-16;
626 if (PDFNumeratorBelow <= 0.0) PDFNumeratorBelow = 1e-16;
627 if (PDFDenominatorBelow <= 0.0) PDFDenominatorBelow = 1e-16;
629 return -2.0*( shadowNBelow*log(PDFDenominatorBelow) + shadowNAbove*log(PDFDenominatorAbove) + nBelow*log(PDFNumeratorBelow) + nAbove*log(PDFNumeratorAbove) );
644 double tot = num + sha;
646 double probNum = num/tot;
647 double probDen = sha/tot;
649 return -2.0*(num*log(probNum) + sha*log(probDen));
658 TH1D* scan =
new TH1D(
"scan",
"scan", nbins, 0.0, 1.0);
661 for (
int i = 1; i < nbins; i++){
662 double neg2LLHval =
neg2LLH(binNumber, dimension, scan->GetXaxis()->GetBinCenter(i), useConstraints );
663 neg2LLHval = nullHypothesis - neg2LLHval;
664 if (neg2LLHval < 0.0) neg2LLHval = 0.0;
665 double sig = sqrt( neg2LLHval );
666 scan->SetBinContent( i, sig );
684 TH1D* splitHist =
scanSig(binNumber, dimension, nBins, useConstraints);
686 int splitBin = splitHist->GetMaximumBin();
688 split = splitHist->GetXaxis()->GetBinCenter(splitBin);
689 sig = splitHist->GetBinContent(splitBin);
695 TString name =
"splitHist";
700 INFO_LOG <<
"Min split point = " <<
split <<
" in dimension " << dimension<<std::endl;
714 double bigestSig = -2e40;
716 for (
int i = 0; i < nDim; i++){
718 double tmpSplit = 0.0;
double tmpSig = 0.0;
721 if ( tmpSig > bigestSig ) {
737 double splitPoint = -1.0;
743 splitPoint =
_random->Gaus(splitPoint, 0.2);
744 if (splitPoint <= 0.0 || splitPoint >= 1.0)
return likelihoodSplit(binNumber);
746 if (
split(binNumber, dim, splitPoint) == 1)
return 1;
747 if (
smartSplit(binNumber, dim, 0.5) == 1)
return 1;
750 for (
int i = 0; i < ndim; i++){
764 double splitPoint = -1.0;
768 if (
smartSplit(binNumber, dim, 0.5) == 1)
return 1;
771 for (
int i = 0; i < ndim; i++){
787 for (
int i = 0; i < initialSize; i++){
804 for (
int i = 0; i < initialSize; i++){
822 bool forceNoSnapToGrid =
true;
841 bool forceNoSnapToGrid =
true;
858 for(
unsigned int i = 0; i < hyperPointSet.
size(); i++){
859 if( hyperCuboid.
inVolume(hyperPointSet.
at(i)) ) {
871 double splitPoint = 0.5;
876 while (shift > 0.001){
878 double dataFrac = dataNow/dataBefore;
880 if (dataFrac < dataFraction) splitPoint += shift;
881 else if (dataFrac > dataFraction) splitPoint -= shift;
900 double lowEdge = lowCorner .
at(dimension);
901 double highEdge = highCorner.at(dimension);
903 int lowInt = ceil (lowEdge );
904 int highInt = floor(highEdge);
906 if (lowInt == highInt)
return 0.0;
908 VERBOSE_LOG <<
"------------------> bin num " << binNumber <<
", dimension " << dimension << std::endl;
909 VERBOSE_LOG <<
"------------------> [ " << lowEdge <<
", " << highEdge <<
"]" << std::endl;
910 VERBOSE_LOG <<
"------------------> [ " << lowInt <<
", " << highInt <<
"]" << std::endl;
914 double splitPoint = 0.0;
916 for (
int i = lowInt; i < highInt; i++){
918 double val = double(i) + 0.5;
919 splitPoint = (val - lowEdge)/(highEdge - lowEdge);
922 double dataFrac = dataNow/dataBefore;
924 if (dataFrac > dataFraction)
break;
928 VERBOSE_LOG <<
"------------------> split point " << splitPoint << std::endl;
939 return split(binNumber, dimension, splitPoint);
950 int binToSplit = binNumber;
954 for (
int i = 0; i < (parts - 1); i++){
955 double fraction = 1.0/double(parts - i);
957 bool ok =
split(binToSplit, dimension, splitPoint);
959 if (!ok)
return nSplits;
976 if (ratio >= 0.0 && ratio < 3.0)
return smartMultiSplit(binNumber, dimension, 2);
977 if (ratio >= 3.0 && ratio < 4.0)
return smartMultiSplit(binNumber, dimension, 3);
978 if (ratio >= 4.0 && ratio < 5.0)
return smartMultiSplit(binNumber, dimension, 2);
979 if (ratio >= 5.0 && ratio < 6.0)
return smartMultiSplit(binNumber, dimension, 5);
991 return split(binNumber, dimension, splitPoint);
1003 for (
int i = 0; i < initialSize; i++){
1005 nSplits +=
split(i, dimension, splitPoint);
1020 for (
int i = 0; i < initialSize; i++){
1022 nSplits +=
smartSplit(i, dimension, dataFraction);
1038 for (
int i = 0; i < initialSize; i++){
1061 for (
int i = 0; i < initialSize; i++){
1081 for (
int i = 0; i < initialSize; i++){
1083 int dimension = floor(
_random->Uniform(0, ndim));
1102 for (
int i = 0; i < initialSize; i++){
1104 int dimension = floor(
_random->Uniform(0, ndim));
1179 for (
int i = 0; i < size; i++){
1181 if ( dimension == -1 ){
1228 for (
int i = 0; i < binning.
getNumBins(); i++){
1235 INFO_LOG <<
"Made HyperHistogram"<<std::endl;
1252 for (
int i = 0; i < binning.
getNumBins(); i++){
1273 numerator->
divide(denominator);
double _minimumBinContent
int smartLikelihoodSplitAll()
void addShadowHyperPointSet(const HyperPointSet &data)
virtual ~HyperBinningMaker()
destructor
void setShadowMinimumBinContent(double val)
int getNumContinueBins(int dimension=-1) const
HyperPoint _minimumEdgeLength
void getDimWithLargestSplitSignificance(int &dim, double &split, int binNumber, bool useConstraints=true)
int smartMultiSplitAll(int dimension)
bool snapToGrid(const HyperCuboid &cuboid, int dimension, double &splitCoord) const
HyperHistogram * getShadowHyperBinningHistogram() const
void drawDensity(TString path, TString options="")
std::vector< std::vector< int > > _linkedBins
virtual void startedIteration()
const HyperCuboid & at(int i) const
static bool s_printBinning
void getSplitToMinNeg2LLH(double &split, double &sig, int binNumber, int dimension, bool useConstraints=true)
int smartSplitAllInt(int dimension, double dataFraction)
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
virtual void startedAlgorithm()
void drawAfterEachIteration(TString path)
std::vector< int > _status
void setGridMultiplier(HyperPoint &multipliers)
void setBinError(int bin, double val)
double findSmartSplitPointInt(int binNumber, int dimension, double dataFraction) const
HyperPoint _gridMultiplier
void setMinimumEdgeLength(double val)
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
double countEventsBelowSplitPoint(int binNumber, int dimension, double splitPoint) const
int smartSplit(int binNumber, int dimension, double dataFraction)
TString _drawAlgorithmDir
bool isValidBinningDimension(int dimension)
virtual int getNumHyperVolumes() const =0
void useSnapToGrid(bool val)
void updateFromExistingHyperBinning(const HyperBinning &binning)
virtual void finishedAlgorithm()
void setBinContent(int bin, double val)
void drawCurrentState(TString path) const
void setDimSpecStatusFromMinBinWidths(int volumeNumber)
std::vector< HyperPointSet > _shadowHyperPointSets
HyperBinningMemRes getHyperVolumeBinning() const
void addBin(const HyperCuboid &hyperCuboid, const HyperPointSet &hyperPointSet, const HyperPointSet &shadowHyperPointSet, int status)
HyperCuboid splitAbovePoint(int dim, double splitPoint, const HyperCuboid &original, bool noSnapToGrid=false) const
double nullNeg2LLH(int binNumber)
const int & getDimension() const
virtual void finishedIteration()
HyperHistogram * getHyperBinningHistogram() const
const HyperPoint & at(int i) const
HyperPointSet filterHyperPointSet(const HyperPointSet &hyperPointSet, const HyperCuboid &hyperCuboid, bool print=false) const
const HyperPoint & getHighCorner() const
double getSumOfWeights(const HyperPointSet &hyperPointSet) const
void setNames(HyperName names)
void updateGlobalStatusFromDimSpecific(int volumeNumber)
virtual void plot(TString plotDirectory, TString plotOptions="", TPad *pad=0, double scaleFactor=1.0)
int likelihoodSplit(int binNumber)
int splitAll(int dimension, double splitPoint)
TH1D * scanSig(int binNumber, int dimension, int nbins, bool useConstraints=true)
int smartLikelihoodSplit(int binNumber)
double _shadowMinimumBinContent
const int & getDimension() const
const double & at(int i) const
const int & getDimension() const
void divide(const HistogramBase &other)
int splitAllRandomise(double splitPoint=0.5)
void setHyperFunction(HyperFunction *fnc)
Set the HyperFunction - only used by some binning Algs.
int smartSplitInt(int binNumber, int dimension, double dataFraction)
int smartMultiSplit(int binNumber, int dimension, int parts)
const HyperPoint & getLowCorner() const
unsigned int size() const
int & getGlobalVolumeStatus(int volumeNumber)
void addHyperCuboid(const HyperPoint &lowCorner, const HyperPoint &highCorner)
virtual int getNumBins() const
int & getDimensionSpecificVolumeStatus(int volumeNumber, int dimension)
int getHyperVolumeNumber(int binNumber) const
double getWeight(int i=0) const
int getNumHyperVolumes() const
std::vector< HyperCuboid > _hyperCuboids
double countShadowEventsBelowSplitPoint(int binNumber, int dimension, double splitPoint) const
std::vector< int > _binningDimensions
double getWeight(const HyperPoint &hyperPoint) const
int getBinNum(int volumeNumber) const
HyperHistogram * getRatioHyperBinningHistogram() const
virtual void addPrimaryVolumeNumber(int volumeNumber)
int smartSplitAllRandomise(double dataFraction=0.5)
double findSmartSplitPoint(int binNumber, int dimension, double dataFraction) const
void setMinimumBinContent(double val)
int split(int volumeNumber, int dimension, double splitPoint)
virtual bool addHyperVolume(const HyperVolume &hyperVolume, std::vector< int > linkedVolumes=std::vector< int >(0, 0))
void push_back(const HyperPoint &point)
std::vector< std::vector< int > > _dimSpecificStatus
double countEventsInHyperCuboid(const HyperPointSet &hyperPointSet, const HyperCuboid &hyperCuboid) const
std::vector< HyperPointSet > _hyperPointSets
bool inVolume(const HyperPoint &coords) const
HyperCuboid splitBelowPoint(int dim, double splitPoint, const HyperCuboid &original, bool noSnapToGrid=false) const
int smartSplitAll(int dimension, double dataFraction)
virtual bool passFunctionCriteria(HyperCuboid &cuboid1, HyperCuboid &cuboid2)
double neg2LLH(int binNumber, int dimension, double splitPoint, bool useConstraints=true)