MINT2
Public Member Functions | Protected Member Functions | Private Attributes | List of all members
HyperBinning Class Referenceabstract

#include <HyperBinning.h>

Inheritance diagram for HyperBinning:
BinningBase HyperBinningDiskRes HyperBinningMemRes

Public Member Functions

 HyperBinning ()
 The only constructor. More...
 
bool isPrimaryVolume (int volumeNumber) const
 
int getHyperVolumeNumber (int binNumber) const
 
int getBinNum (int volumeNumber) const
 
virtual std::vector< int > getPrimaryVolumeNumbers () const
 
virtual ~HyperBinning ()
 
virtual void setDimension (int dim)
 
virtual std::vector< int > getLinkedHyperVolumes (int volumeNumber) const =0
 
virtual HyperVolume getHyperVolume (int volumeNumber) const =0
 
virtual void addPrimaryVolumeNumber (int volumeNumber)=0
 
virtual bool addHyperVolume (const HyperVolume &hyperVolume, std::vector< int > linkedVolumes=std::vector< int >(0, 0))=0
 
virtual int getNumHyperVolumes () const =0
 
virtual int getNumPrimaryVolumes () const =0
 
virtual int getPrimaryVolumeNumber (int i) const =0
 
virtual void reserveCapacity (int nElements)
 
virtual void load (TString filename, TString option="READ")=0
 
virtual BinningBaseclone () const =0
 
virtual void save (TString filename) const
 
virtual void save () const
 
virtual void mergeBinnings (const BinningBase &other)
 
virtual int getNumBins () const
 
virtual int getBinNum (const HyperPoint &coords) const
 
virtual std::vector< int > getBinNum (const HyperPointSet &coords) const
 
std::vector< int > getBinNumAlt (const HyperPointSet &coords) const
 
virtual HyperVolume getBinHyperVolume (int binNumber) const
 
virtual HyperPoint getAverageBinWidth () const
 
virtual HyperCuboid getLimits () const
 
- Public Member Functions inherited from BinningBase
 BinningBase ()
 
void setNames (HyperName names)
 
HyperName getNames () const
 
const int & getDimension () const
 
double getMin (int dimension) const
 
double getMax (int dimension) const
 
TString getBinningType () const
 
bool isSameBinningType (const BinningBase &other) const
 
virtual bool isDiskResident () const
 
virtual TString filename () const
 
virtual ~BinningBase ()
 

Protected Member Functions

int followBinLinks (const HyperPoint &coords, int binNumber) const
 
void updateCash () const
 
void updateBinNumbering () const
 
void updateAverageBinWidth () const
 
void updateMinMax () const
 
int getHyperBinningDimFromTree (TTree *tree)
 
void createBranches (TTree *tree, int *binNumber, double *lowCorner, double *highCorner, std::vector< int > **linkedBins) const
 
void saveHyperVolumeToTree (TTree *tree, double *lowCorner, double *highCorner, const HyperVolume &hyperVolume) const
 
void savePrimaryVolumeNumbers () const
 
- Protected Member Functions inherited from BinningBase
void setBinningType (TString binningType)
 

Private Attributes

CachedVar< HyperPoint_averageBinWidth
 
CachedVar< HyperCuboid_minmax
 
CachedVar< std::vector< int > > _binNum
 
CachedVar< std::vector< int > > _hyperVolumeNumFromBinNum
 

Detailed Description

HyperPlot, Author: Sam Harnew, sam.h.nosp@m.arne.nosp@m.w@gma.nosp@m.il.c.nosp@m.om , Date: Dec 2015

HyperBinning is a binning scheme where each bin volume is defined by a HyperVolume.

Finding the correct bin number is quite a compuationally slow process if one has to loop over every bin and check if a HyperPoint falls within that bin volume. It's not unusual to have millions of HyperPoints that need to be sorted into tens of thousands of bins. This would require billions of calulations. To speed this process up there is the option to build a hierarchy of bins. A schematic below shows a 1D example.

HyperVolume Numbers
|-------------0-------------|
|------1------|------2------|
|--3---|---4--|---5---|--6--|
|-7-|-8|
Bin Numbers
| 0 | 1| 2 | 3 | 4 |

Imagine we have a HyperPoint that falls into Bin 0. One would first check if it falls into HyperVolume 0 (note the distiction here between Bin/HyperVolume Numbers as indicated by the figure). First we check if it falls into HyperVolume 0, then HyperVolume 1 or 2, then HyperVolume 3 or 4, then HyperVolume 7 or 8.

In this simple example, it took 7 operations, whereas checking each Bin would have taken

  1. Clearly as the number of bins increases, it becomes computationally much less expensive to follow this hierarchy approach.

The

Definition at line 82 of file HyperBinning.h.

Constructor & Destructor Documentation

◆ HyperBinning()

HyperBinning::HyperBinning ( )

The only constructor.

Definition at line 5 of file HyperBinning.cpp.

5  :
6 // _changed(true),
9 {
10  setBinningType("HyperBinning");
11  WELCOME_LOG << "Hello from the HyperBinning() Constructor";
12 }
void setBinningType(TString binningType)
Definition: BinningBase.cpp:16
const int & getDimension() const
Definition: BinningBase.cpp:30
CachedVar< HyperCuboid > _minmax
Definition: HyperBinning.h:97
#define WELCOME_LOG
CachedVar< HyperPoint > _averageBinWidth
Definition: HyperBinning.h:93

◆ ~HyperBinning()

HyperBinning::~HyperBinning ( )
virtual

Destructor

Definition at line 847 of file HyperBinning.cpp.

847  {
848  GOODBYE_LOG << "Goodbye from the HyperBinning() Constructor";
849 }
#define GOODBYE_LOG

Member Function Documentation

◆ addHyperVolume()

virtual bool HyperBinning::addHyperVolume ( const HyperVolume hyperVolume,
std::vector< int >  linkedVolumes = std::vector< int >(0, 0) 
)
pure virtual

◆ addPrimaryVolumeNumber()

virtual void HyperBinning::addPrimaryVolumeNumber ( int  volumeNumber)
pure virtual

◆ clone()

virtual BinningBase* HyperBinning::clone ( ) const
pure virtual

Implements BinningBase.

Implemented in HyperBinningMemRes, and HyperBinningDiskRes.

◆ createBranches()

void HyperBinning::createBranches ( TTree *  tree,
int *  binNumber,
double *  lowCorner,
double *  highCorner,
std::vector< int > **  linkedBins 
) const
protected

Create the branches in a TTree so that the HyperBinningMemRes can be saved.

Definition at line 719 of file HyperBinning.cpp.

719  {
720 
721  tree->Branch("binNumber", binNumber);
722  tree->Branch("linkedBins", "vector<int>" ,linkedBins);
723  for (int i = 0; i < getDimension(); i++) {
724  TString lowCornerName = "lowCorner_"; lowCornerName += i;
725  TString highCornerName = "highCorner_"; highCornerName += i;
726  tree->Branch(lowCornerName, lowCorner + i);
727  tree->Branch(highCornerName, highCorner + i);
728  }
729 
730 }
const int & getDimension() const
Definition: BinningBase.cpp:30

◆ followBinLinks()

int HyperBinning::followBinLinks ( const HyperPoint coords,
int  motherVolumeNumber 
) const
protected

Used to follow the bin hierarchy. Give it a HyperPoint, and the number of a HyperVolume (that has links) that the HyperPoint falls into.

Definition at line 398 of file HyperBinning.cpp.

398  {
399 
400  //find the linked volumes
401  std::vector<int> linkedVolumes = getLinkedHyperVolumes(motherVolumeNumber);
402 
403  int volumeNumber = -1;
404 
405  //see if the coords falls into any of the linked volumes (it should if there are no bugs)
406  for (unsigned i = 0; i < linkedVolumes.size(); i++){
407  int daughBinNum = linkedVolumes.at(i);
408  bool inVol = getHyperVolume(daughBinNum).inVolume(coords);
409  if (inVol == 1) { volumeNumber = daughBinNum; break; }
410  }
411 
412  if (volumeNumber == -1) {
413  ERROR_LOG << "The trail of linked bins has gone cold!";
414  return -1;
415  }
416 
417  //now have volumeNumber which contains the next bin in the hierarchy.
418  // if this is linked to more bins, keep following the trail!
419  if ( getLinkedHyperVolumes(volumeNumber).size() > 0 ) volumeNumber = followBinLinks(coords, volumeNumber);
420 
421  //if not, we have made it to the end. Return the volume number!
422  return volumeNumber;
423 
424 }
int followBinLinks(const HyperPoint &coords, int binNumber) const
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
#define ERROR_LOG
bool inVolume(const HyperPoint &coords) const
Definition: HyperVolume.cpp:39
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0

◆ getAverageBinWidth()

HyperPoint HyperBinning::getAverageBinWidth ( ) const
virtual

get the average bin width HyperPoint (average bin width in each dimension). This value is cashed for speed - when the binning changes the cashe will automatically be updated.

Implements BinningBase.

Definition at line 619 of file HyperBinning.cpp.

619  {
620  if (_averageBinWidth.isUpdateNeeded() == true) {
622  }
623  return _averageBinWidth;
624 
625 }
bool isUpdateNeeded()
Definition: CachedVar.h:54
void updateAverageBinWidth() const
CachedVar< HyperPoint > _averageBinWidth
Definition: HyperBinning.h:93

◆ getBinHyperVolume()

HyperVolume HyperBinning::getBinHyperVolume ( int  binNumber) const
virtual

Get the HyperVolume assosiated with bin number i. This just uses the _hyperVolumeNumFromBinNum variable to find the HyperVolume number from the bin number, then returns that HyperVolume.

Implements BinningBase.

Definition at line 443 of file HyperBinning.cpp.

443  {
444 
445  return getHyperVolume( getHyperVolumeNumber(binNumber) );
446 
447 }
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
int getHyperVolumeNumber(int binNumber) const

◆ getBinNum() [1/3]

int HyperBinning::getBinNum ( int  volumeNumber) const

Get the bin number assosiated with a given HyperVolume number. If this returns -1, it means that the HyperVolume in question is not a bin, but part of the binning hierarchy.

Definition at line 452 of file HyperBinning.cpp.

452  {
453  if ( _binNum.isUpdateNeeded() == true ){
455  }
456  return _binNum.get().at(volumeNumber);
457 }
bool isUpdateNeeded()
Definition: CachedVar.h:54
CachedVar< std::vector< int > > _binNum
Definition: HyperBinning.h:101
T & get()
Definition: CachedVar.h:42
void updateBinNumbering() const

◆ getBinNum() [2/3]

int HyperBinning::getBinNum ( const HyperPoint coords) const
virtual

This is used to get the bin number that the HyperPoint falls into.

This is done by looping over the HyperVolumes in order until the HyperPoint is contained within one of them. When one of these is found, check to see if there are any 'linked bins' - if not, this is a true bin, so job done. If there are linked bins, proceed to see which of the linked bins the HyperPoint falls into. Continue this process until you reach a HyperVolume with no linked bins.

The BinNumber is found from the HyperVolume number using the lookup vector _binNum.

0 1 2 3 4 5 6 7 8
_binNum = { -1, -1, -1, -1, 2, 3, 4, 0 1 }
HyperVolume Numbers
|-------------0-------------|
|------1------|------2------|
|--3---|---4--|---5---|--6--|
|-7-|-8|
Bin Numbers
| 0 | 1| 2 | 3 | 4 |

Implements BinningBase.

Definition at line 61 of file HyperBinning.cpp.

61  {
62 
63  //First check if the HyperPoint is in the HyperCuboid _minmax that
64  //surrounds all the bins.
65 
66  if ( getLimits().inVolume(coords) == 0) return -1;
67 
68  int nPrimVols = getNumPrimaryVolumes();
69 
70  if ( nPrimVols == 0){
71 
72  //loop over all the bins until one is found that contains the event. If a bin
73  // is found that contains the event, check if it has any linked bins. Linked bins
74  // aren't real bins... just used to speed up sorting later.
75 
76  int volumeNumber = -1;
77 
78  for (int i = 0; i < getNumHyperVolumes(); i++){
79  bool inVol = getHyperVolume(i).inVolume(coords);
80  if (inVol == 1) { volumeNumber = i; break; }
81  }
82 
83  if (volumeNumber == -1) return -1;
84 
85  if ( getLinkedHyperVolumes(volumeNumber).size() > 0 ) volumeNumber = followBinLinks(coords, volumeNumber);
86 
87  return getBinNum(volumeNumber);
88  }
89 
90 
91  int primaryVolumeNumber = -1;
92 
93  for (int i = 0; i < nPrimVols; i++){
94  int thisVolNum = getPrimaryVolumeNumber(i);
95  bool inVol = getHyperVolume(thisVolNum).inVolume(coords);
96  if (inVol == 1) { primaryVolumeNumber = thisVolNum; break; }
97  }
98 
99  int volumeNumber = -1;
100 
101  if ( getLinkedHyperVolumes(primaryVolumeNumber).size() > 0 ) {
102  volumeNumber = followBinLinks(coords, primaryVolumeNumber);
103  }
104  else{
105  ERROR_LOG << "This primary volume has NO links. Not what I expect!!" << std::endl;
106  return getBinNum(primaryVolumeNumber);
107  }
108 
109  return getBinNum(volumeNumber);
110 
111 }
int followBinLinks(const HyperPoint &coords, int binNumber) const
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
#define ERROR_LOG
bool inVolume(const HyperPoint &coords) const
Definition: HyperVolume.cpp:39
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
virtual HyperCuboid getLimits() const
virtual int getNumPrimaryVolumes() const =0
virtual int getPrimaryVolumeNumber(int i) const =0
int getBinNum(int volumeNumber) const

◆ getBinNum() [3/3]

std::vector< int > HyperBinning::getBinNum ( const HyperPointSet coords) const
virtual

get multiple bin numbers at the same time. This should speed things up drastically if the binning is disk resident, because random access of a TTree is incredibly slow.

Reimplemented from BinningBase.

Definition at line 117 of file HyperBinning.cpp.

117  {
118 
119  int nPrimVols = getNumPrimaryVolumes();
120 
121  if (nPrimVols > 0){
122  return getBinNumAlt(coords);
123  }
124 
125  bool printInfo = false;
126  if (getNumHyperVolumes() > 30000 && isDiskResident() == true) {
127  INFO_LOG << "Since this is a large (>2x10^6) disk resident HyperBinning, I'm going to give you information on this HyperBinning::getBinNum(const HyperPointSet& coords)" << std::endl;
128  printInfo = true;
129  }
130 
131 
132  int nCoords = coords.size();
133 
134  INFO_LOG << "Sorting " << nCoords << " HyperPoints into bins" << std::endl;
135 
136  //Each coord gets a binNumber (in binNumberSet) and linkedVols (in linkedVolsSet)
137  // -If no bin number has been assigned the binNumber is -2
138  // -If the coord is outside the binning range it is -1
139  // -If a coord has been assigned a bin, the binNumber will be the binNumber
140 
141  std::vector<int> binNumberSet(nCoords, -2);
142  std::vector< std::vector<int> > linkedVolsSet(nCoords, std::vector<int>() );
143 
144  for (unsigned i = 0; i < linkedVolsSet.size(); i++){
145  linkedVolsSet.at(i).reserve(2);
146  }
147 
148  //First loop over the primary volumes and see if the each coord
149  //falls into it. If it does, fill the linkedVols with that volume number.
150  //If a coord doesn't fall into any of the primary volumes, set the binNumber to -1
151 
152 
153  if (nPrimVols != 0){
154 
155  if (printInfo){
156  INFO_LOG << "I'm looping over all " << nPrimVols << " primary volumes, and seeing what events fall into each" << std::endl;
157  }
158 
159  for (int voli = 0; voli < nPrimVols; voli++){
160 
161  int volNum = getPrimaryVolumeNumber(voli);
162  HyperVolume vol = getHyperVolume(volNum);
163 
164  //See if any of the coords fall into this primary vol
165  for (int i = 0; i < nCoords; i++){
166 
167  if ( linkedVolsSet.at(i).size() != 0 ) continue;
168 
169  if ( vol.inVolume( coords.at(i) ) == true ){
170  linkedVolsSet.at(i).push_back(volNum);
171  }
172 
173 
174  }
175 
176  }
177 
178  //any points which don't have a linked bin (i.e. fall into a
179  //primary volume, set the bin number to -1)
180  for (int i = 0; i < nCoords; i++){
181 
182  if (linkedVolsSet.at(i).size() == 0){
183  binNumberSet.at(i) = -1;
184  }
185 
186  }
187 
188  }
189 
190  //Loop over every volume in the binning scheme, and see if each coord falls into it.
191  // -If a bin number has already been assigned to a coord we can skip
192  // -If there are no linked volumes we must check
193  // -If there are linked volumes, and one of the linkedvol numbers is the same
194  // as the volume number, we must check.
195  // -See if the coord is within the volume. If it is:
196  // -If the volume has linked volumes, copy them to the linkedVols associated to
197  // the coordinate
198  // -If the volume has no linked volumes, this is a bin! Set the bin number and
199  // wipe the linked volumes associated to the coord
200 
201  int nVolumes = getNumHyperVolumes();
202 
203  if (printInfo){
204  INFO_LOG << "I'm now looping over all " << nVolumes << " volumes, and seeing what events fall into each." << std::endl;
205  INFO_LOG << "This could take a while with " << nCoords << " so I'll give you a handy loading bar." << std::endl;
206  }
207 
208  LoadingBar loadingBar(nVolumes);
209 
210  for (int voli = 0; voli < nVolumes; voli++){
211 
212  if (printInfo){
213  loadingBar.update(voli);
214  }
215 
216  HyperVolume vol = getHyperVolume (voli);
217  std::vector<int> links = getLinkedHyperVolumes(voli);
218  bool anyLinks = (links.size() != 0);
219 
220  for (int i = 0; i < nCoords; i++){
221 
222  int& binNum = binNumberSet[i];
223 
224  //If bin number has already been assigned, continue.
225  if (binNum >= -1) continue;
226 
227  //If not, loop over
228  std::vector<int>& linkedVols = linkedVolsSet.at(i);
229  int nLinkedVols = linkedVols.size();
230 
231  bool doCheck = true;
232 
233  if (nLinkedVols != 0){
234  doCheck = false;
235  for (int j = 0; j < nLinkedVols; j++){
236  if (linkedVols.at(j) == voli) {doCheck = true; break;}
237  }
238  }
239 
240  if (doCheck == false) continue;
241 
242  if ( vol.inVolume(coords.at(i)) ){
243 
244  if (anyLinks == false){
245  binNum = getBinNum(voli);
246  }
247  else{
248  linkedVols = links;
249  }
250  }
251 
252  }
253 
254  }
255 
256 
257  //any points which don't have a linked bin (i.e. fall into a
258  //primary volume, set the bin number to -1)
259  for (int i = 0; i < nCoords; i++){
260 
261  if (binNumberSet.at(i) == -2){
262  binNumberSet.at(i) = -1;
263  }
264 
265  }
266 
267  return binNumberSet;
268 
269 }
virtual bool isDiskResident() const
Definition: BinningBase.cpp:54
#define INFO_LOG
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
bool inVolume(const HyperPoint &coords) const
Definition: HyperVolume.cpp:39
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
const HyperPoint & at(int i) const
std::vector< int > getBinNumAlt(const HyperPointSet &coords) const
virtual int getNumPrimaryVolumes() const =0
unsigned int size() const
virtual int getPrimaryVolumeNumber(int i) const =0
int getBinNum(int volumeNumber) const

◆ getBinNumAlt()

std::vector< int > HyperBinning::getBinNumAlt ( const HyperPointSet coords) const

get multiple bin numbers at the same time. This should speed things up drastically if the binning is disk resident, because random access of a TTree is incredibly slow.

Definition at line 275 of file HyperBinning.cpp.

275  {
276 
277  //Call getNumBins to make sure the cache is up to date. Not needed,
278  //but if the cache updates during the below code it messes up the
279  //loading bar.
280  getNumBins();
281 
282 
283  bool printInfo = false;
284  if (getNumHyperVolumes() > 2e6 && isDiskResident() == true) {
285  INFO_LOG << "Since this is a large (>2x10^6) disk resident HyperBinning, I'm going to give you information on this HyperBinning::getBinNum(const HyperPointSet& coords)" << std::endl;
286  printInfo = true;
287  }
288 
289  int nCoords = coords.size();
290  int nVolumes = getNumHyperVolumes();
291 
292  INFO_LOG << "Sorting " << nCoords << " HyperPoints into bins" << std::endl;
293 
294  //Each coord gets a binNumber (in binNumberSet) and linkedVols (in linkedVolsSet)
295  // -If no bin number has been assigned the binNumber is -2
296  // -If the coord is outside the binning range it is -1
297  // -If a coord has been assigned a bin, the binNumber will be the binNumber
298 
299  std::vector<int> binNumberSet(nCoords, -1);
300  std::vector< std::vector<int> > binsInVol(nVolumes, std::vector<int>() );
301 
302  //First loop over the primary volumes and see if the each coord
303  //falls into it. If it does, fill binsInVol with that coord number.
304 
305  int nPrimVols = getNumPrimaryVolumes();
306 
307 
308  if (printInfo){
309  INFO_LOG << "I'm looping over all " << nPrimVols << " primary volumes, and seeing what events fall into each" << std::endl;
310  }
311 
312  for (int voli = 0; voli < nPrimVols; voli++){
313 
314  int volNum = getPrimaryVolumeNumber(voli);
315  HyperVolume vol = getHyperVolume(volNum);
316 
317  //See if any of the coords fall into this primary vol
318  for (int i = 0; i < nCoords; i++){
319 
320  if ( vol.inVolume( coords.at(i) ) == true ){
321  binsInVol.at(volNum).push_back(i);
322  }
323 
324  }
325 
326  }
327 
328  if (printInfo){
329  INFO_LOG << "I'm now looping over all " << nVolumes << " volumes, and seeing what events fall into each." << std::endl;
330  INFO_LOG << "This could take a while with " << nCoords << " so I'll give you a handy loading bar." << std::endl;
331  }
332 
333  LoadingBar loadingBar(nVolumes);
334 
335  for (int voli = 0; voli < nVolumes; voli++){
336 
337  if (printInfo){
338  loadingBar.update(voli);
339  }
340 
341  int nBinsInVol = binsInVol.at(voli).size();
342 
343  if (nBinsInVol == 0) continue;
344 
345  HyperVolume vol = getHyperVolume (voli);
346  std::vector<int> links = getLinkedHyperVolumes(voli);
347  int numLinks = links.size();
348 
349  for (int i = 0; i < nBinsInVol; i++){
350 
351  int coordNum = binsInVol.at(voli).at(i);
352  const HyperPoint& coord = coords.at( coordNum );
353 
354  if ( vol.inVolume(coord) ){
355 
356  if (numLinks == 0){
357  binNumberSet.at(coordNum) = getBinNum(voli);
358  }
359  else{
360  for (int j = 0; j < numLinks; j++){
361  binsInVol.at(links.at(j)).push_back(coordNum);
362  }
363  }
364  }
365 
366  }
367 
368  }
369 
370 
371  return binNumberSet;
372 
373 }
virtual bool isDiskResident() const
Definition: BinningBase.cpp:54
#define INFO_LOG
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
bool inVolume(const HyperPoint &coords) const
Definition: HyperVolume.cpp:39
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
const HyperPoint & at(int i) const
virtual int getNumPrimaryVolumes() const =0
const double & at(int i) const
Definition: HyperPoint.cpp:433
unsigned int size() const
virtual int getNumBins() const
virtual int getPrimaryVolumeNumber(int i) const =0
int getBinNum(int volumeNumber) const
void push_back(T &t, const typename T::value_type &a, const typename T::value_type &b, const typename T::value_type &c, const typename T::value_type &d)

◆ getHyperBinningDimFromTree()

int HyperBinning::getHyperBinningDimFromTree ( TTree *  tree)
protected

Look at the tree that contains the HyperBinning and find the dimensionality

Definition at line 691 of file HyperBinning.cpp.

691  {
692 
693  if (tree == 0){
694  ERROR_LOG << "Invalid tree in HyperBinning::getDimension(TTree* tree)" << std::endl;
695  return 0;
696  }
697 
698  TString branchName = "lowCorner_0";
699  int nDim = 0;
700 
701  while ( tree->GetListOfBranches()->FindObject(branchName) != 0 ){
702  nDim++;
703  branchName = "lowCorner_";
704  branchName += nDim;
705  }
706 
707  if (nDim == 0){
708  ERROR_LOG << "I cannot find any branches in the tree that indicate a HyperBinning is stored here" << std::endl;
709  return 0;
710  }
711 
712  return nDim;
713 
714 }
#define ERROR_LOG

◆ getHyperVolume()

virtual HyperVolume HyperBinning::getHyperVolume ( int  volumeNumber) const
pure virtual

get one of the HyperVolumes

Implemented in HyperBinningMemRes, and HyperBinningDiskRes.

◆ getHyperVolumeNumber()

int HyperBinning::getHyperVolumeNumber ( int  binNumber) const

get the HyperVolume Number from the bin number

Definition at line 461 of file HyperBinning.cpp.

461  {
462  if ( _hyperVolumeNumFromBinNum.isUpdateNeeded() == true ){
464  }
465  return _hyperVolumeNumFromBinNum.get().at(binNumber);
466 }
CachedVar< std::vector< int > > _hyperVolumeNumFromBinNum
Definition: HyperBinning.h:130
bool isUpdateNeeded()
Definition: CachedVar.h:54
T & get()
Definition: CachedVar.h:42
void updateBinNumbering() const

◆ getLimits()

HyperCuboid HyperBinning::getLimits ( ) const
virtual

return the limits of the binning. This value is cashed for speed - when the binning changes the cashe will automatically be updated.

Implements BinningBase.

Definition at line 530 of file HyperBinning.cpp.

530  {
531  if (_minmax.isUpdateNeeded() == true) {
532  updateMinMax();
533  }
534  return _minmax;
535 }
void updateMinMax() const
bool isUpdateNeeded()
Definition: CachedVar.h:54
CachedVar< HyperCuboid > _minmax
Definition: HyperBinning.h:97

◆ getLinkedHyperVolumes()

virtual std::vector<int> HyperBinning::getLinkedHyperVolumes ( int  volumeNumber) const
pure virtual

◆ getNumBins()

int HyperBinning::getNumBins ( ) const
virtual

Get number of bins (this is NOT the number of HyperVolumes!!! - see the class description for more details)

Implements BinningBase.

Definition at line 430 of file HyperBinning.cpp.

430  {
431 
432  if ( _hyperVolumeNumFromBinNum.isUpdateNeeded() == true ){
434  }
435 
436  return _hyperVolumeNumFromBinNum.get().size();
437 
438 }
CachedVar< std::vector< int > > _hyperVolumeNumFromBinNum
Definition: HyperBinning.h:130
bool isUpdateNeeded()
Definition: CachedVar.h:54
T & get()
Definition: CachedVar.h:42
void updateBinNumbering() const

◆ getNumHyperVolumes()

virtual int HyperBinning::getNumHyperVolumes ( ) const
pure virtual

◆ getNumPrimaryVolumes()

virtual int HyperBinning::getNumPrimaryVolumes ( ) const
pure virtual

◆ getPrimaryVolumeNumber()

virtual int HyperBinning::getPrimaryVolumeNumber ( int  i) const
pure virtual

◆ getPrimaryVolumeNumbers()

std::vector< int > HyperBinning::getPrimaryVolumeNumbers ( ) const
virtual

Reimplemented in HyperBinningMemRes.

Definition at line 831 of file HyperBinning.cpp.

831  {
832  std::vector<int> primaryVolumeNumbers;
833  int nPrimVols = getNumPrimaryVolumes();
834  primaryVolumeNumbers.reserve(nPrimVols);
835 
836  for (int i = 0; i < nPrimVols; i++){
837  primaryVolumeNumbers.push_back(getPrimaryVolumeNumber(i));
838  }
839  return primaryVolumeNumbers;
840 }
virtual int getNumPrimaryVolumes() const =0
virtual int getPrimaryVolumeNumber(int i) const =0

◆ isPrimaryVolume()

bool HyperBinning::isPrimaryVolume ( int  volumeNumber) const

Definition at line 378 of file HyperBinning.cpp.

378  {
379 
380  int nPrimVols = getNumPrimaryVolumes();
381 
382  for (int i = 0; i < nPrimVols; i++){
383  if (getPrimaryVolumeNumber(i) == volumeNumber) return true;
384  }
385 
386  return false;
387 
388 }
virtual int getNumPrimaryVolumes() const =0
virtual int getPrimaryVolumeNumber(int i) const =0

◆ load()

virtual void HyperBinning::load ( TString  filename,
TString  option = "READ" 
)
pure virtual

Implements BinningBase.

Implemented in HyperBinningMemRes, and HyperBinningDiskRes.

◆ mergeBinnings()

void HyperBinning::mergeBinnings ( const BinningBase other)
virtual

This function will merge the two binnings. It assumes that the first

Implements BinningBase.

Definition at line 639 of file HyperBinning.cpp.

639  {
640 
641  //INFO_LOG << "Starting HyperBinning::mergeBinnings" << std::endl;
642 
643  if ( other.getBinningType().Contains("HyperBinning") == false){
644  ERROR_LOG << "You can only merge a HyperBinning with another HyperBinning" << std::endl;
645  return;
646  }
647 
648  const HyperBinning& otherHyperBinning = dynamic_cast<const HyperBinning&>(other);
649 
650  int nVolumes = getNumHyperVolumes();
651  int nVolumesOther = otherHyperBinning.getNumHyperVolumes();
652 
653  //this means every volume number in 'otherHyperBinning' needs to be increased by nVolumes.
654  //This is important for linked bins and primary volume numbers!!
655 
656  reserveCapacity(nVolumes + nVolumesOther);
657 
658  for (int i = 0; i < nVolumesOther; i++){
659  HyperVolume vol = otherHyperBinning.getHyperVolume(i);
660 
661  std::vector<int> linkedVolumes = otherHyperBinning.getLinkedHyperVolumes(i);
662 
663  for (unsigned int j = 0; j < linkedVolumes.size(); j++){
664  linkedVolumes.at(j) += nVolumes;
665  }
666 
667  addHyperVolume(vol, linkedVolumes);
668  }
669 
670  int nPrimaryBinsOther = otherHyperBinning.getNumPrimaryVolumes();
671 
672  for (int i = 0; i < nPrimaryBinsOther; i++){
673  int primaryVolumeNumber = otherHyperBinning.getPrimaryVolumeNumber(i);
674  primaryVolumeNumber += nVolumes;
675  addPrimaryVolumeNumber(primaryVolumeNumber);
676  }
677 
678  updateCash();
679 
680  //INFO_LOG << "Ending HyperBinning::mergeBinnings" << std::endl;
681 
682 
683 }
virtual bool addHyperVolume(const HyperVolume &hyperVolume, std::vector< int > linkedVolumes=std::vector< int >(0, 0))=0
virtual void reserveCapacity(int nElements)
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
#define ERROR_LOG
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
void updateCash() const
TString getBinningType() const
Definition: BinningBase.cpp:50
virtual void addPrimaryVolumeNumber(int volumeNumber)=0
virtual int getNumPrimaryVolumes() const =0
virtual int getPrimaryVolumeNumber(int i) const =0

◆ reserveCapacity()

void HyperBinning::reserveCapacity ( int  nElements)
virtual

Reimplemented from BinningBase.

Reimplemented in HyperBinningMemRes, and HyperBinningDiskRes.

Definition at line 628 of file HyperBinning.cpp.

628  {
629 
630  _binNum .get().reserve(nElements);
631  _hyperVolumeNumFromBinNum.get().reserve(nElements);
632 
633 }
CachedVar< std::vector< int > > _hyperVolumeNumFromBinNum
Definition: HyperBinning.h:130
CachedVar< std::vector< int > > _binNum
Definition: HyperBinning.h:101
T & get()
Definition: CachedVar.h:42

◆ save() [1/2]

void HyperBinning::save ( TString  filename) const
virtual

Save the HyperBinningMemRes to a TFile.

Implements BinningBase.

Definition at line 777 of file HyperBinning.cpp.

777  {
778 
779  TFile* file = new TFile(filename, "RECREATE");
780 
781  if (file == 0){
782  ERROR_LOG << "Could not open TFile in HyperBinningMemRes::save(" << filename << ")";
783  return;
784  }
785 
786  save();
787 
788  //file->Write();
789  file->Close();
790 
791 }
virtual TString filename() const
Definition: BinningBase.cpp:57
#define ERROR_LOG
virtual void save() const

◆ save() [2/2]

void HyperBinning::save ( ) const
virtual

Save the HyperBinningMemRes to the open (and in scope) TFile.

Implements BinningBase.

Definition at line 795 of file HyperBinning.cpp.

795  {
796 
798 
799  TTree* tree = new TTree("HyperBinning", "HyperBinning");
800 
801  if (tree == 0){
802  ERROR_LOG << "Could not open TTree in HyperBinningMemRes::save()";
803  return;
804  }
805 
806  //Define branch addresses
807  int binNumber = -1;
808  double* lowCorner = new double [getDimension()];
809  double* highCorner = new double [getDimension()];
810  std::vector<int>* linkedBins = new std::vector<int>();
811 
812  //Create branches and link them to branch addresses
813  createBranches(tree, &binNumber, lowCorner, highCorner, &linkedBins);
814 
815  //Loop over each HyperVolume
816  for(int bin = 0; bin < getNumHyperVolumes(); bin++ ){
817  binNumber = bin;
818  *linkedBins = getLinkedHyperVolumes(bin);
819  //save all HyperCuboids in this HyperVolume to the TTree under the current bin number
820  saveHyperVolumeToTree(tree, lowCorner, highCorner, getHyperVolume(bin));
821  }
822 
823  delete[] lowCorner;
824  delete[] highCorner;
825  delete linkedBins;
826 
827 }
void saveHyperVolumeToTree(TTree *tree, double *lowCorner, double *highCorner, const HyperVolume &hyperVolume) const
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
#define ERROR_LOG
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
void createBranches(TTree *tree, int *binNumber, double *lowCorner, double *highCorner, std::vector< int > **linkedBins) const
void savePrimaryVolumeNumbers() const
const int & getDimension() const
Definition: BinningBase.cpp:30

◆ saveHyperVolumeToTree()

void HyperBinning::saveHyperVolumeToTree ( TTree *  tree,
double *  lowCorner,
double *  highCorner,
const HyperVolume hyperVolume 
) const
protected

Save a single HyperVolume to a tree - this involves looping over every HyperCuboid in the HyperVolume.

Definition at line 734 of file HyperBinning.cpp.

734  {
735 
736  for(int i = 0; i < hyperVolume.size(); i++){
737  HyperCuboid hyperCuboid = hyperVolume.getHyperCuboid(i);
738  HyperPoint lowCornerVect = hyperCuboid.getLowCorner();
739  HyperPoint highCornerVect = hyperCuboid.getHighCorner();
740  for (int dim = 0; dim < getDimension(); dim++) lowCorner [dim] = lowCornerVect .at(dim);
741  for (int dim = 0; dim < getDimension(); dim++) highCorner[dim] = highCornerVect.at(dim);
742  tree->Fill();
743  }
744 
745 }
int size() const
Definition: HyperVolume.h:60
const HyperPoint & getHighCorner() const
Definition: HyperCuboid.h:89
const int & getDimension() const
Definition: BinningBase.cpp:30
const double & at(int i) const
Definition: HyperPoint.cpp:433
const HyperPoint & getLowCorner() const
Definition: HyperCuboid.h:87
const HyperCuboid & getHyperCuboid(int i) const
Definition: HyperVolume.h:54

◆ savePrimaryVolumeNumbers()

void HyperBinning::savePrimaryVolumeNumbers ( ) const
protected

Save the list of Primary Volume Numbers to the open (and in scope) TFile.

Definition at line 749 of file HyperBinning.cpp.

749  {
750 
751  TTree* tree = new TTree("PrimaryVolumeNumbers", "PrimaryVolumeNumbers");
752 
753  if (tree == 0){
754  ERROR_LOG << "Could not open TTree in HyperBinningMemRes::save()";
755  return;
756  }
757 
758  //Define branch addresses
759  int volumeNumber = -1;
760 
761  tree->Branch("volumeNumber", &volumeNumber);
762 
763  int nPrimVols = getNumPrimaryVolumes();
764 
765  //Loop over each Primary Volume
766  for(int i = 0; i < nPrimVols; i++ ){
767  volumeNumber = getPrimaryVolumeNumber(i);
768  tree->Fill();
769  }
770 
771  //tree->Write();
772 
773 }
#define ERROR_LOG
virtual int getNumPrimaryVolumes() const =0
virtual int getPrimaryVolumeNumber(int i) const =0

◆ setDimension()

void HyperBinning::setDimension ( int  dim)
virtual

Set the dimension of the HyperBinning. This can only be called once, when it is known what dimesnion it is.

Reimplemented from BinningBase.

Reimplemented in HyperBinningMemRes, and HyperBinningDiskRes.

Definition at line 18 of file HyperBinning.cpp.

18  {
19 
20  if (getDimension() == 0){
23  _minmax = HyperCuboid( getDimension(), 0.0, 1.0 );
24  }
25 
26 }
virtual void setDimension(int dimension)
Definition: BinningBase.cpp:34
const int & getDimension() const
Definition: BinningBase.cpp:30
CachedVar< HyperCuboid > _minmax
Definition: HyperBinning.h:97
CachedVar< HyperPoint > _averageBinWidth
Definition: HyperBinning.h:93

◆ updateAverageBinWidth()

void HyperBinning::updateAverageBinWidth ( ) const
protected

update the _averageBinWidth HyperPoint. Will usually be called from updateCash()

Definition at line 541 of file HyperBinning.cpp.

541  {
542 
543  if (getNumHyperVolumes() > 2e6 && isDiskResident() == true) {
544  INFO_LOG << "Since this is a large (>2x10^6) disk resident HyperBinning, I'm going to give you information on this cache update." << std::endl;
545  INFO_LOG << "I'm currently updating the average bin width by looping over all bin volumes" << std::endl;
546  }
547 
548  int dim = getDimension();
549 
550  HyperPoint averageWidth(dim);
551 
552  for (int i = 0; i < getNumBins(); i++){
553  for (int j = 0; j < dim; j++) {
554  double min = getBinHyperVolume(i).getMin(j);
555  double max = getBinHyperVolume(i).getMax(j);
556  averageWidth.at(j) += (max - min);
557  }
558  }
559 
560  _averageBinWidth = averageWidth/(double)getNumBins();
562 
563 }
virtual bool isDiskResident() const
Definition: BinningBase.cpp:54
#define INFO_LOG
double getMin(int dimension) const
void updated()
Definition: CachedVar.h:38
virtual int getNumHyperVolumes() const =0
virtual HyperVolume getBinHyperVolume(int binNumber) const
const int & getDimension() const
Definition: BinningBase.cpp:30
virtual int getNumBins() const
CachedVar< HyperPoint > _averageBinWidth
Definition: HyperBinning.h:93
double getMax(int dimension) const

◆ updateBinNumbering()

void HyperBinning::updateBinNumbering ( ) const
protected

Update the member variables _binNum and _hyperVolumeNumFromBinNum. Will usually be called from updateCash()

Definition at line 482 of file HyperBinning.cpp.

482  {
483 
484  //first fill all the bin numbers with -1
485  int nVolumes = getNumHyperVolumes();
486  _binNum = std::vector<int>(nVolumes, -1);
487 
488  bool printout = getNumHyperVolumes() > 2e6 && isDiskResident() == true;
489  if (printout) {
490  INFO_LOG << "Since this is a large (>2x10^6) disk resident HyperBinning, I'm going to give you information on this cache update." << std::endl;
491  INFO_LOG << "I'm currently updating the bin numbering that lets me quickly associate volumes to bins and vice versa..." << std::endl;
492  }
493 
494 
495  //if a HyperVolume has any linked HyperVolumes,
496  //then set its bin number to count.
497  int count = 0;
498  for (int i = 0; i < getNumHyperVolumes(); i++){
499  if ( getLinkedHyperVolumes(i).size() == 0 ) {
500  _binNum.get().at(i) = count;
501  count++;
502  }
503  }
504 
505  //now we know how many bins there are, make the
506  // _hyperVolumeNumFromBinNum vector
507  int nBins = count;
508  _hyperVolumeNumFromBinNum = std::vector<int>(nBins,-1);
509 
510  //fill the vector
511  for (int i = 0; i < getNumHyperVolumes(); i++){
512  if ( _binNum.get().at(i) != -1 ) {
513  _hyperVolumeNumFromBinNum.get().at( _binNum.get().at(i) ) = i;
514  }
515  }
516 
518  _binNum .updated();
519 
520  if (printout) {
521  INFO_LOG << "Finished!" << std::endl;
522  }
523 
524 
525 }
virtual bool isDiskResident() const
Definition: BinningBase.cpp:54
CachedVar< std::vector< int > > _hyperVolumeNumFromBinNum
Definition: HyperBinning.h:130
#define INFO_LOG
void updated()
Definition: CachedVar.h:38
virtual std::vector< int > getLinkedHyperVolumes(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
CachedVar< std::vector< int > > _binNum
Definition: HyperBinning.h:101
T & get()
Definition: CachedVar.h:42

◆ updateCash()

void HyperBinning::updateCash ( ) const
protected

Update the cash which includes the mutable member variables _binNum, _hyperVolumeNumFromBinNum, _averageBinWidth, and _minmax.

Definition at line 471 of file HyperBinning.cpp.

471  {
472 
474  _minmax .changed();
475  _binNum .changed();
477 
478 }
CachedVar< std::vector< int > > _hyperVolumeNumFromBinNum
Definition: HyperBinning.h:130
void changed()
Definition: CachedVar.h:35
CachedVar< std::vector< int > > _binNum
Definition: HyperBinning.h:101
CachedVar< HyperCuboid > _minmax
Definition: HyperBinning.h:97
CachedVar< HyperPoint > _averageBinWidth
Definition: HyperBinning.h:93

◆ updateMinMax()

void HyperBinning::updateMinMax ( ) const
protected

Update the miniumum and maximum values, _minmax, in the cashe. Will usually be called from updateCash().

Definition at line 568 of file HyperBinning.cpp.

568  {
569 
570  int dim = getDimension();
571 
572  HyperPoint min(dim);
573  HyperPoint max(dim);
574 
575  for (int d = 0; d < dim; d++){
576  min.at(d) = getHyperVolume(0).getMin(d);
577  max.at(d) = getHyperVolume(0).getMax(d);
578  }
579 
580  int nPrimVols = getNumPrimaryVolumes();
581 
582  if (nPrimVols == 0){
583 
584  if (getNumHyperVolumes() > 2e6 && isDiskResident() == true) {
585  INFO_LOG << "Since this is a large (>2x10^6) disk resident HyperBinning, I'm going to give you information on this cache update." << std::endl;
586  INFO_LOG << "I'm currently determining the limits of this histogram by looping over all bin volumes" << std::endl;
587  }
588 
589  for(int i = 1; i < getNumHyperVolumes(); i++){
590  HyperVolume thisVol = getHyperVolume(i);
591  for (int d = 0; d < dim; d++){
592  if (min.at(d) > thisVol.getMin(d)) min.at(d) = thisVol.getMin(d);
593  if (max.at(d) < thisVol.getMax(d)) max.at(d) = thisVol.getMax(d);
594  }
595  }
596 
597  }
598 
599  else{
600 
601  for(int i = 1; i < getNumPrimaryVolumes(); i++){
603  for (int d = 0; d < dim; d++){
604  if (min.at(d) > thisVol.getMin(d)) min.at(d) = thisVol.getMin(d);
605  if (max.at(d) < thisVol.getMax(d)) max.at(d) = thisVol.getMax(d);
606  }
607  }
608 
609  }
610 
611  _minmax = HyperCuboid(min, max);
612  _minmax.updated();
613 }
virtual bool isDiskResident() const
Definition: BinningBase.cpp:54
#define INFO_LOG
double getMin(int dimension) const
void updated()
Definition: CachedVar.h:38
virtual HyperVolume getHyperVolume(int volumeNumber) const =0
virtual int getNumHyperVolumes() const =0
const int & getDimension() const
Definition: BinningBase.cpp:30
virtual int getNumPrimaryVolumes() const =0
CachedVar< HyperCuboid > _minmax
Definition: HyperBinning.h:97
virtual int getPrimaryVolumeNumber(int i) const =0
double getMax(int dimension) const

Member Data Documentation

◆ _averageBinWidth

CachedVar<HyperPoint> HyperBinning::_averageBinWidth
mutableprivate

< keep a record to check if the binning changes - if so _binNum, _hyperVolumeNumFromBinNum, _averageBinWidth, and _minmax need to be redetermined.store the a Hyperpoint giving the average bin width in each dimension. This is calculated once, and reused.

Definition at line 93 of file HyperBinning.h.

◆ _binNum

CachedVar<std::vector< int > > HyperBinning::_binNum
mutableprivate

Every HyperVolume has a Bin Number, although these will be -1 if it's not a true bin, and just part of the bin hierarchy. These numbers run from 0 to nBins - 1. In the below example

0 1 2 3 4 5 6 7 8
_binNum = { -1, -1, -1, -1, 2, 3, 4, 0 1 }
HyperVolume Numbers
|-------------0-------------|
|------1------|------2------|
|--3---|---4--|---5---|--6--|
|-7-|-8|
Bin Numbers
| 0 | 1| 2 | 3 | 4 |

Definition at line 101 of file HyperBinning.h.

◆ _hyperVolumeNumFromBinNum

CachedVar< std::vector< int > > HyperBinning::_hyperVolumeNumFromBinNum
mutableprivate

The opposite of the member _binNum. This gives the HyperVolume number from the Bin Number. In the below example

0 1 2 3 4
_hyperVolumeNumFromBinNum = { 7, 8, 4, 5, 6 }
HyperVolume Numbers
|-------------0-------------|
|------1------|------2------|
|--3---|---4--|---5---|--6--|
|-7-|-8|
Bin Numbers
| 0 | 1| 2 | 3 | 4 |

Definition at line 130 of file HyperBinning.h.

◆ _minmax

CachedVar<HyperCuboid> HyperBinning::_minmax
mutableprivate

store the HyperCuboid that surrounds the binning. This is calculated once, and reused.

Definition at line 97 of file HyperBinning.h.


The documentation for this class was generated from the following files: