29 ROOT::Internal::THnBaseBinIter(respectAxisRange), fHist(hist),
30 fNbins(hist->GetNbins()), fIndex(-1) {
35 virtual ~THnSparseBinIter() {
delete [] fCoord; }
41 THnSparseBinIter(
const THnSparseBinIter&);
42 THnSparseBinIter&
operator=(
const THnSparseBinIter&);
51 Int_t THnSparseBinIter::GetCoord(
Int_t dim)
const 53 if (fCoord[0] == -1) {
64 if (!fHist)
return -1;
67 Int_t* useCoordBuf = fCoord;
75 if (fIndex >= fHist->GetNbins()) {
80 fHist->GetBinContent(fIndex, useCoordBuf);
83 && !fHist->IsInRange(useCoordBuf)
84 && (fHaveSkippedBin =
kTRUE ));
86 if (coord && coord[0] == -1) {
87 if (fCoord[0] == -1) {
88 fHist->GetBinContent(fIndex, coord);
90 memcpy(coord, fCoord, fHist->GetNdimensions() *
sizeof(
Int_t));
113 class THnSparseCoordCompression {
115 THnSparseCoordCompression(
Int_t dim,
const Int_t* nbins);
116 THnSparseCoordCompression(
const THnSparseCoordCompression& other);
117 ~THnSparseCoordCompression();
119 THnSparseCoordCompression&
operator=(
const THnSparseCoordCompression& other);
122 Int_t GetBufferSize()
const {
return fCoordBufferSize; }
123 Int_t GetNdimensions()
const {
return fNdimensions; }
124 void SetCoordFromBuffer(
const Char_t* buf_in,
Int_t* coord_out)
const;
136 Int_t fCoordBufferSize;
150 THnSparseCoordCompression::THnSparseCoordCompression(
Int_t dim,
const Int_t* nbins):
151 fNdimensions(dim), fCoordBufferSize(0), fBitOffsets(0)
153 fBitOffsets =
new Int_t[dim + 1];
156 for (
Int_t i = 0; i < dim; ++i) {
157 fBitOffsets[i] = shift;
158 shift += GetNumBits(nbins[i] + 2);
160 fBitOffsets[dim] = shift;
161 fCoordBufferSize = (shift + 7) / 8;
168 THnSparseCoordCompression::THnSparseCoordCompression(
const THnSparseCoordCompression& other)
170 fNdimensions = other.fNdimensions;
171 fCoordBufferSize = other.fCoordBufferSize;
172 fBitOffsets =
new Int_t[fNdimensions + 1];
173 memcpy(fBitOffsets, other.fBitOffsets,
sizeof(
Int_t) * fNdimensions);
182 if (&other ==
this)
return *
this;
184 fNdimensions = other.fNdimensions;
185 fCoordBufferSize = other.fCoordBufferSize;
186 delete [] fBitOffsets;
187 fBitOffsets =
new Int_t[fNdimensions + 1];
188 memcpy(fBitOffsets, other.fBitOffsets,
sizeof(
Int_t) * fNdimensions);
196 THnSparseCoordCompression::~THnSparseCoordCompression()
198 delete [] fBitOffsets;
206 void THnSparseCoordCompression::SetCoordFromBuffer(
const Char_t* buf_in,
207 Int_t* coord_out)
const 209 for (
Int_t i = 0; i < fNdimensions; ++i) {
210 const Int_t offset = fBitOffsets[i] / 8;
211 Int_t shift = fBitOffsets[i] % 8;
212 Int_t nbits = fBitOffsets[i + 1] - fBitOffsets[i];
214 coord_out[i] = *pbuf >> shift;
216 subst = subst << nbits;
217 nbits -= (8 - shift);
219 for (
Int_t n = 0;
n * 8 < nbits; ++
n) {
221 coord_out[i] += *pbuf << shift;
224 coord_out[i] &= ~subst;
234 ULong64_t THnSparseCoordCompression::SetBufferFromCoord(
const Int_t* coord_in,
237 if (fCoordBufferSize <= 8) {
239 for (
Int_t i = 0; i < fNdimensions; ++i) {
242 memcpy(buf_out, &l64buf,
sizeof(
Long64_t));
247 memset(buf_out, 0, fCoordBufferSize);
248 for (
Int_t i = 0; i < fNdimensions; ++i) {
249 const Int_t offset = fBitOffsets[i] / 8;
250 const Int_t shift = fBitOffsets[i] % 8;
253 Char_t* pbuf = buf_out + offset;
254 *pbuf += 0xff & (val << shift);
255 val = val >> (8 - shift);
263 return GetHashFromBuffer(buf_out);
270 ULong64_t THnSparseCoordCompression::GetHashFromCoords(const Int_t* coord) const
272 // Bins are addressed in two different modes, depending
273 // on whether the compact bin index fits into a Long64_t or not.
274 // If it does, we can use it as a "perfect hash" for the TExMap.
275 // If not we build a hash from the compact bin index, and use that
276 // as the TExMap's hash.
278 if (fCoordBufferSize <= 8) {
279 // fits into a Long64_t
281 for (Int_t i = 0; i < fNdimensions; ++i) {
282 hash1 += coord[i] << fBitOffsets[i];
287 // else: doesn't fit into a Long64_t:
288 memset(coord, 0, fCoordBufferSize);
289 for (Int_t i = 0; i < fNdimensions; ++i) {
290 const Int_t offset = fBitOffsets[i] / 8;
291 const Int_t shift = fBitOffsets[i] % 8;
292 ULong64_t val = coord[i];
294 Char_t* pbuf = fCoordBuffer + offset;
295 *pbuf += 0xff & (val << shift);
296 val = val >> (8 - shift);
304 ULong64_t hash = 5381;
305 Char_t* str = fCoordBuffer;
306 while (str - fCoordBuffer < fCoordBufferSize) {
318 ULong64_t THnSparseCoordCompression::GetHashFromBuffer(
const Char_t* buf)
const 326 if (fCoordBufferSize <= 8) {
329 memcpy(&hash1, buf, fCoordBufferSize);
336 while (str - buf < fCoordBufferSize) {
352 class THnSparseCompactBinCoord:
public THnSparseCoordCompression {
354 THnSparseCompactBinCoord(
Int_t dim,
const Int_t* nbins);
355 ~THnSparseCompactBinCoord();
356 Int_t* GetCoord() {
return fCurrentBin; }
358 ULong64_t GetHash()
const {
return fHash; }
360 fHash = SetBufferFromCoord(fCurrentBin, fCoordBuffer);
362 void SetCoord(
const Int_t* coord) {
363 memcpy(fCurrentBin, coord,
sizeof(
Int_t) * GetNdimensions());
364 fHash = SetBufferFromCoord(coord, fCoordBuffer);
366 void SetBuffer(
const Char_t* buf) {
367 memcpy(fCoordBuffer, buf, GetBufferSize());
368 fHash = GetHashFromBuffer(fCoordBuffer);
373 THnSparseCompactBinCoord(
const THnSparseCompactBinCoord&);
375 THnSparseCompactBinCoord&
operator=(
const THnSparseCompactBinCoord&);
392 THnSparseCompactBinCoord::THnSparseCompactBinCoord(
Int_t dim,
const Int_t* nbins):
393 THnSparseCoordCompression(dim, nbins),
394 fHash(0), fCoordBuffer(0), fCurrentBin(0)
396 fCurrentBin =
new Int_t[dim];
397 size_t bufAllocSize = GetBufferSize();
398 if (bufAllocSize <
sizeof(
Long64_t))
400 fCoordBuffer =
new Char_t[bufAllocSize];
407 THnSparseCompactBinCoord::~THnSparseCompactBinCoord()
409 delete [] fCoordBuffer;
410 delete [] fCurrentBin;
429 fCoordinateAllocationSize(-1), fSingleCoordinateSize(coordsize), fCoordinatesSize(0),
430 fCoordinates(0), fContent(cont),
591 fChunkSize(1024), fFilledBins(0), fCompactCoord(0)
607 THnBase(name, title, dim, nbins, xmin, xmax),
650 fCompactCoord =
new THnSparseCompactBinCoord(fNdimensions, nbins);
668 const Char_t* endbuf = buf + singleCoordSize * chunkSize;
669 for (; buf < endbuf; buf += singleCoordSize, ++idx) {
670 Long64_t hash = compactCoord.GetHashFromBuffer(buf);
706 Int_t *coord = cc->GetCoord();
722 Int_t *coord = cc->GetCoord();
753 Int_t sizeCompact = cc->GetBufferSize();
754 cc->SetCoordFromBuffer(chunk->
fCoordinates + idx * sizeCompact,
762 memset(coord, -1,
sizeof(
Int_t) * fNdimensions);
776 if (linidx < 0)
return 0.;
804 if (!nextlinidx)
break;
808 if (!allocate)
return -1;
819 chunk->
AddBin(newidx, cc->GetBuffer());
846 =
new THnSparseCompactBinCoord(fNdimensions, bins);
867 Int_t arrayElementSize = 0;
873 if (!arrayElementSize) {
874 Warning(
"GetSparseFractionMem",
"Cannot determine type of elements!");
880 sizePerChunkElement +=
sizeof(
Double_t);
890 return size / nbinsTotal / arrayElementSize;
899 return new THnSparseBinIter(respectAxisRange,
this);
921 Error(
"SetBinError",
"GetCalculateErrors() logic error!");
938 Error(
"SetBinError",
"GetCalculateErrors() logic error!");
Abstract array base class.
virtual void Clear(Option_t *="")
Double_t GetSparseFractionMem() const
Return the amount of used memory over memory that would be used by a non-sparse n-dimensional histogr...
THnSparseArrayChunk is used internally by THnSparse.
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
void AddBinContent(const Int_t *idx, Double_t v=1.)
Bool_t GetCalculateErrors() const
void SetAt(Double_t v, Int_t i)
Namespace for new ROOT classes and functions.
void FillExMap()
We have been streamed; set up fBins.
THnSparseArrayChunk * AddChunk()
Create a new chunk of bin content.
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
All ROOT classes may have RTTI (run time type identification) support added.
virtual ~THnSparseArrayChunk()
Destructor.
Long64_t GetBin(const Int_t *idx) const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void Sumw2()
Turn on support of errors.
Double_t GetBinError2(Long64_t linidx) const
Get square of the error of bin addressed by linidx as If errors are not enabled (via Sumw2() or Calc...
void InitStorage(Int_t *nbins, Int_t chunkSize)
Initialize the storage of a histogram created via Init()
THnSparseCompactBinCoord * fCompactCoord
filled bins for non-unique hashes, containing pairs of (bin index 0, bin index 1) ...
Long64_t GetNbins() const
Double_t fEntries
browser-helpers for each axis
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Bool_t Matches(Int_t idx, const Char_t *idxbuf) const
virtual void SetAt(Double_t v, Int_t i)=0
Efficient multidimensional histogram.
Int_t fCoordinateAllocationSize
virtual TArray * GenerateArray() const =0
TDataType * GetDataType() const
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Int_t fSingleCoordinateSize
size of the allocated coordinate buffer; -1 means none or fCoordinatesSize
THnSparseArrayChunk * GetChunk(Int_t idx) const
virtual Int_t GetCoord(Int_t dim) const =0
virtual ~THnSparse()
Destruct a THnSparse.
Double_t GetBinContent(const Int_t *idx) const
void SetBinError2(Long64_t bin, Double_t e2)
Set error of bin with index "bin" to "e", enable errors if needed.
TExMap fBinsContinued
filled bins
void Reset(Option_t *option="")
Clear the histogram.
TAxis * GetAxis(Int_t dim) const
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Iterator over THnBase bins (internal implementation).
void Sumw2()
Enable calculation of errors.
Int_t GetEntriesFast() const
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
The ROOT global object gROOT contains a list of all defined classes.
void SetBinContent(const Int_t *idx, Double_t v)
void Delete(Option_t *opt="")
Delete all entries stored in the TExMap.
ROOT::Internal::THnBaseBinIter * CreateIter(Bool_t respectAxisRange) const
Create an iterator over all filled bins of a THnSparse.
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
void Reserve(Long64_t nbins)
Initialize storage for nbins.
unsigned long long ULong64_t
void AddBinError2(Long64_t bin, Double_t e2)
Add "e" to error of bin with index "bin", enable errors if needed.
Double_t GetSparseFractionBins() const
Return the amount of filled bins over all bins.
THnSparse()
Construct an empty THnSparse.
Array of doubles (64 bits per element).
Int_t GetNdimensions() const
Binding & operator=(OUT(*fun)(void))
void AddBin(Int_t idx, const Char_t *idxbuf)
Create a new bin in this chunk.
THnSparseCompactBinCoord * GetCompactCoord() const
Return THnSparseCompactBinCoord object.
virtual Double_t GetAt(Int_t i) const =0
int GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, Bool_t check=kTRUE)
Retrieve a linear buffer pointer from the given pyobject.
Int_t Size() const
Get size of basic typedef'ed type.
Bool_t RespectsAxisRange() const
Double_t GetAt(Int_t i) const
Int_t GetEntries() const
Return the number of objects in array (i.e.
virtual void AddLast(TObject *obj)
Add object in the next empty slot in the array.
Multidimensional histogram base.
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
virtual Int_t GetSize() const
Int_t GetChunkSize() const
Long64_t GetBinIndexForCurrentBin(Bool_t allocate)
Return the index for fCurrentBinIndex.
virtual Long64_t Next(Int_t *coord=0)=0
void ResetBase(Option_t *option="")
Clear the histogram.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
void Expand(Int_t newsize)
Expand the TExMap.