28 ROOT::Internal::THnBaseBinIter(respectAxisRange), fHist(hist),
29 fNbins(hist->GetNbins()), fIndex(-1) {
34 virtual ~THnSparseBinIter() {
delete [] fCoord; }
40 THnSparseBinIter(
const THnSparseBinIter&);
41 THnSparseBinIter&
operator=(
const THnSparseBinIter&);
50Int_t THnSparseBinIter::GetCoord(
Int_t dim)
const
52 if (fCoord[0] == -1) {
63 if (!fHist)
return -1;
66 Int_t* useCoordBuf = fCoord;
74 if (fIndex >= fHist->GetNbins()) {
78 if (RespectsAxisRange()) {
79 fHist->GetBinContent(fIndex, useCoordBuf);
81 }
while (RespectsAxisRange()
82 && !fHist->IsInRange(useCoordBuf)
83 && (fHaveSkippedBin =
kTRUE ));
85 if (coord && coord[0] == -1) {
86 if (fCoord[0] == -1) {
87 fHist->GetBinContent(fIndex, coord);
89 memcpy(coord, fCoord, fHist->GetNdimensions() *
sizeof(
Int_t));
112class THnSparseCoordCompression {
114 THnSparseCoordCompression(
Int_t dim,
const Int_t* nbins);
115 THnSparseCoordCompression(
const THnSparseCoordCompression& other);
116 ~THnSparseCoordCompression();
118 THnSparseCoordCompression&
operator=(
const THnSparseCoordCompression& other);
121 Int_t GetBufferSize()
const {
return fCoordBufferSize; }
122 Int_t GetNdimensions()
const {
return fNdimensions; }
123 void SetCoordFromBuffer(
const Char_t* buf_in,
Int_t* coord_out)
const;
135 Int_t fCoordBufferSize;
149THnSparseCoordCompression::THnSparseCoordCompression(
Int_t dim,
const Int_t* nbins):
150 fNdimensions(dim), fCoordBufferSize(0), fBitOffsets(0)
152 fBitOffsets =
new Int_t[dim + 1];
155 for (
Int_t i = 0; i < dim; ++i) {
156 fBitOffsets[i] = shift;
157 shift += GetNumBits(nbins[i] + 2);
159 fBitOffsets[dim] = shift;
160 fCoordBufferSize = (shift + 7) / 8;
167THnSparseCoordCompression::THnSparseCoordCompression(
const THnSparseCoordCompression& other)
169 fNdimensions = other.fNdimensions;
170 fCoordBufferSize = other.fCoordBufferSize;
171 fBitOffsets =
new Int_t[fNdimensions + 1];
172 memcpy(fBitOffsets, other.fBitOffsets,
sizeof(
Int_t) * fNdimensions);
179THnSparseCoordCompression& THnSparseCoordCompression::operator=(
const THnSparseCoordCompression& other)
181 if (&other ==
this)
return *
this;
183 fNdimensions = other.fNdimensions;
184 fCoordBufferSize = other.fCoordBufferSize;
185 delete [] fBitOffsets;
186 fBitOffsets =
new Int_t[fNdimensions + 1];
187 memcpy(fBitOffsets, other.fBitOffsets,
sizeof(
Int_t) * fNdimensions);
195THnSparseCoordCompression::~THnSparseCoordCompression()
197 delete [] fBitOffsets;
205void THnSparseCoordCompression::SetCoordFromBuffer(
const Char_t* buf_in,
206 Int_t* coord_out)
const
208 for (
Int_t i = 0; i < fNdimensions; ++i) {
209 const Int_t offset = fBitOffsets[i] / 8;
210 Int_t shift = fBitOffsets[i] % 8;
211 Int_t nbits = fBitOffsets[i + 1] - fBitOffsets[i];
213 coord_out[i] = *pbuf >> shift;
215 subst = subst << nbits;
216 nbits -= (8 - shift);
218 for (
Int_t n = 0;
n * 8 < nbits; ++
n) {
220 coord_out[i] += *pbuf << shift;
223 coord_out[i] &= ~subst;
233ULong64_t THnSparseCoordCompression::SetBufferFromCoord(
const Int_t* coord_in,
236 if (fCoordBufferSize <= 8) {
238 for (
Int_t i = 0; i < fNdimensions; ++i) {
241 memcpy(buf_out, &l64buf,
sizeof(
Long64_t));
246 memset(buf_out, 0, fCoordBufferSize);
247 for (
Int_t i = 0; i < fNdimensions; ++i) {
248 const Int_t offset = fBitOffsets[i] / 8;
249 const Int_t shift = fBitOffsets[i] % 8;
252 Char_t* pbuf = buf_out + offset;
253 *pbuf += 0xff & (val << shift);
254 val = val >> (8 - shift);
262 return GetHashFromBuffer(buf_out);
269ULong64_t THnSparseCoordCompression::GetHashFromCoords(const Int_t* coord) const
271 // Bins are addressed in two different modes, depending
272 // on whether the compact bin index fits into a Long64_t or not.
273 // If it does, we can use it as a "perfect hash" for the TExMap.
274 // If not we build a hash from the compact bin index, and use that
275 // as the TExMap's hash.
277 if (fCoordBufferSize <= 8) {
278 // fits into a Long64_t
280 for (Int_t i = 0; i < fNdimensions; ++i) {
281 hash1 += coord[i] << fBitOffsets[i];
286 // else: doesn't fit into a Long64_t:
287 memset(coord, 0, fCoordBufferSize);
288 for (Int_t i = 0; i < fNdimensions; ++i) {
289 const Int_t offset = fBitOffsets[i] / 8;
290 const Int_t shift = fBitOffsets[i] % 8;
291 ULong64_t val = coord[i];
293 Char_t* pbuf = fCoordBuffer + offset;
294 *pbuf += 0xff & (val << shift);
295 val = val >> (8 - shift);
303 ULong64_t hash = 5381;
304 Char_t* str = fCoordBuffer;
305 while (str - fCoordBuffer < fCoordBufferSize) {
317ULong64_t THnSparseCoordCompression::GetHashFromBuffer(
const Char_t* buf)
const
325 if (fCoordBufferSize <= 8) {
328 memcpy(&hash1, buf, fCoordBufferSize);
335 while (str - buf < fCoordBufferSize) {
351class THnSparseCompactBinCoord:
public THnSparseCoordCompression {
353 THnSparseCompactBinCoord(
Int_t dim,
const Int_t* nbins);
354 ~THnSparseCompactBinCoord();
355 Int_t* GetCoord() {
return fCurrentBin; }
357 ULong64_t GetHash()
const {
return fHash; }
359 fHash = SetBufferFromCoord(fCurrentBin, fCoordBuffer);
361 void SetCoord(
const Int_t* coord) {
362 memcpy(fCurrentBin, coord,
sizeof(
Int_t) * GetNdimensions());
363 fHash = SetBufferFromCoord(coord, fCoordBuffer);
365 void SetBuffer(
const Char_t* buf) {
366 memcpy(fCoordBuffer, buf, GetBufferSize());
367 fHash = GetHashFromBuffer(fCoordBuffer);
372 THnSparseCompactBinCoord(
const THnSparseCompactBinCoord&);
374 THnSparseCompactBinCoord&
operator=(
const THnSparseCompactBinCoord&);
391THnSparseCompactBinCoord::THnSparseCompactBinCoord(
Int_t dim,
const Int_t* nbins):
392 THnSparseCoordCompression(dim, nbins),
393 fHash(0), fCoordBuffer(0), fCurrentBin(0)
395 fCurrentBin =
new Int_t[dim];
396 size_t bufAllocSize = GetBufferSize();
397 if (bufAllocSize <
sizeof(
Long64_t))
399 fCoordBuffer =
new Char_t[bufAllocSize];
406THnSparseCompactBinCoord::~THnSparseCompactBinCoord()
408 delete [] fCoordBuffer;
409 delete [] fCurrentBin;
428 fCoordinateAllocationSize(-1), fSingleCoordinateSize(coordsize), fCoordinatesSize(0),
429 fCoordinates(0), fContent(cont),
590 fChunkSize(1024), fFilledBins(0), fCompactCoord(0)
607 fChunkSize(chunksize), fFilledBins(0), fCompactCoord(0)
667 const Char_t* endbuf = buf + singleCoordSize * chunkSize;
668 for (; buf < endbuf; buf += singleCoordSize, ++idx) {
669 Long64_t hash = compactCoord.GetHashFromBuffer(buf);
705 Int_t *coord = cc->GetCoord();
721 Int_t *coord = cc->GetCoord();
752 Int_t sizeCompact = cc->GetBufferSize();
753 cc->SetCoordFromBuffer(chunk->
fCoordinates + idx * sizeCompact,
775 if (linidx < 0)
return 0.;
803 if (!nextlinidx)
break;
807 if (!allocate)
return -1;
818 chunk->
AddBin(newidx, cc->GetBuffer());
866 Int_t arrayElementSize = 0;
872 if (!arrayElementSize) {
873 Warning(
"GetSparseFractionMem",
"Cannot determine type of elements!");
879 sizePerChunkElement +=
sizeof(
Double_t);
889 return size / nbinsTotal / arrayElementSize;
898 return new THnSparseBinIter(respectAxisRange,
this);
920 Error(
"SetBinError",
"GetCalculateErrors() logic error!");
937 Error(
"SetBinError",
"GetCalculateErrors() logic error!");
unsigned long long ULong64_t
Binding & operator=(OUT(*fun)(void))
Iterator over THnBase bins (internal implementation).
virtual Int_t GetCoord(Int_t dim) const =0
virtual Long64_t Next(Int_t *coord=0)=0
Array of doubles (64 bits per element).
void SetAt(Double_t v, Int_t i)
Double_t GetAt(Int_t i) const
Abstract array base class.
virtual void SetAt(Double_t v, Int_t i)=0
virtual Double_t GetAt(Int_t i) const =0
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
TClass instances represent classes, structs and namespaces in the ROOT type system.
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
All ROOT classes may have RTTI (run time type identification) support added.
TDataType * GetDataType() const
Int_t Size() const
Get size of basic typedef'ed type.
void Delete(Option_t *opt="")
Delete all entries stored in the TExMap.
void Expand(Int_t newsize)
Expand the TExMap.
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Multidimensional histogram base.
Double_t fEntries
browser-helpers for each axis
Int_t GetNdimensions() const
void ResetBase(Option_t *option="")
Clear the histogram.
Bool_t GetCalculateErrors() const
TAxis * GetAxis(Int_t dim) const
THnSparseArrayChunk is used internally by THnSparse.
Bool_t Matches(Int_t idx, const Char_t *idxbuf) const
virtual ~THnSparseArrayChunk()
Destructor.
Int_t fSingleCoordinateSize
size of the allocated coordinate buffer; -1 means none or fCoordinatesSize
void Sumw2()
Turn on support of errors.
void AddBin(Int_t idx, const Char_t *idxbuf)
Create a new bin in this chunk.
Int_t fCoordinateAllocationSize
Efficient multidimensional histogram.
Double_t GetSparseFractionBins() const
Return the amount of filled bins over all bins.
Long64_t GetBin(const Int_t *idx) const
Double_t GetSparseFractionMem() const
Return the amount of used memory over memory that would be used by a non-sparse n-dimensional histogr...
void SetBinContent(const Int_t *idx, Double_t v)
Forwards to THnBase::SetBinContent().
void InitStorage(Int_t *nbins, Int_t chunkSize)
Initialize the storage of a histogram created via Init()
THnSparseArrayChunk * GetChunk(Int_t idx) const
THnSparseCompactBinCoord * fCompactCoord
filled bins for non-unique hashes, containing pairs of (bin index 0, bin index 1)
Int_t GetChunkSize() const
virtual ~THnSparse()
Destruct a THnSparse.
ROOT::Internal::THnBaseBinIter * CreateIter(Bool_t respectAxisRange) const
Create an iterator over all filled bins of a THnSparse.
Double_t GetBinContent(const Int_t *idx) const
Forwards to THnBase::GetBinContent() overload.
void Reset(Option_t *option="")
Clear the histogram.
THnSparseCompactBinCoord * GetCompactCoord() const
Return THnSparseCompactBinCoord object.
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...
THnSparse()
Construct an empty THnSparse.
THnSparseArrayChunk * AddChunk()
Create a new chunk of bin content.
virtual TArray * GenerateArray() const =0
void FillExMap()
We have been streamed; set up fBins.
void AddBinError2(Long64_t bin, Double_t e2)
Add "e" to error of bin with index "bin", enable errors if needed.
TExMap fBinsContinued
filled bins
void Sumw2()
Enable calculation of errors.
void Reserve(Long64_t nbins)
Initialize storage for nbins.
void AddBinContent(const Int_t *idx, Double_t v=1.)
Forwards to THnBase::SetBinContent().
void SetBinError2(Long64_t bin, Double_t e2)
Set error of bin with index "bin" to "e", enable errors if needed.
Long64_t GetNbins() const
Long64_t GetBinIndexForCurrentBin(Bool_t allocate)
Return the index for fCurrentBinIndex.
Int_t GetEntriesFast() const
virtual void AddLast(TObject *obj)
Add object in the next empty slot in the array.
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Int_t GetEntries() const
Return the number of objects in array (i.e.
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
virtual void Clear(Option_t *="")
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Py_ssize_t GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, bool check=true)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...