#ifndef ROOT_THN
#define ROOT_THN
#ifndef ROOT_THnBase
#include "THnBase.h"
#endif
#ifndef ROOT_TNDArray
#include "TNDArray.h"
#endif
#ifndef ROOT_TArrayD
#include "TArrayD.h"
#endif
#ifndef ROOT_TObjArray
#include "TObjArray.h"
#endif
#ifndef ROOT_TAxis
#include "TAxis.h"
#endif
#ifndef ROOT_TMath
#include "TMath.h"
#endif
class TH1;
class TH1D;
class TH2D;
class TH3D;
class THnSparse;
class TF1;
class THn: public THnBase {
private:
THn(const THn&);
THn& operator=(const THn&);
protected:
void FillBin(Long64_t bin, Double_t w) {
GetArray().AddAt(bin, w);
if (GetCalculateErrors()) {
fSumw2.AddAt(bin, w * w);
}
FillBinBase(w);
}
void AllocCoordBuf() const;
void InitStorage(Int_t* nbins, Int_t chunkSize);
THn(): fCoordBuf() {}
THn(const char* name, const char* title, Int_t dim, const Int_t* nbins,
const Double_t* xmin, const Double_t* xmax);
public:
virtual ~THn();
static THn* CreateHn(const char* name, const char* title, const TH1* h1) {
return (THn*) CreateHnAny(name, title, h1, kFALSE , -1);
}
static THn* CreateHn(const char* name, const char* title, const THnBase* hn) {
return (THn*) CreateHnAny(name, title, hn, kFALSE , -1);
}
ROOT::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const;
Long64_t GetNbins() const { return GetArray().GetNbins(); }
Long64_t GetBin(const Int_t* idx) const {
return GetArray().GetBin(idx);
}
Long64_t GetBin(const Double_t* x) const {
if (!fCoordBuf) AllocCoordBuf();
for (Int_t d = 0; d < fNdimensions; ++d) {
fCoordBuf[d] = GetAxis(d)->FindFixBin(x[d]);
}
return GetArray().GetBin(fCoordBuf);
}
Long64_t GetBin(const char* name[]) const {
if (!fCoordBuf) AllocCoordBuf();
for (Int_t d = 0; d < fNdimensions; ++d) {
fCoordBuf[d] = GetAxis(d)->FindBin(name[d]);
}
return GetArray().GetBin(fCoordBuf);
}
Long64_t GetBin(const Int_t* idx, Bool_t = kTRUE) {
return const_cast<const THn*>(this)->GetBin(idx);
}
Long64_t GetBin(const Double_t* x, Bool_t = kTRUE) {
return const_cast<const THn*>(this)->GetBin(x);
}
Long64_t GetBin(const char* name[], Bool_t = kTRUE) {
return const_cast<const THn*>(this)->GetBin(name);
}
void SetBinContent(const Int_t* idx, Double_t v) {
THnBase::SetBinContent(idx, v);
}
void SetBinContent(Long64_t bin, Double_t v) {
GetArray().SetAsDouble(bin, v);
}
void SetBinError2(Long64_t bin, Double_t e2) {
if (!GetCalculateErrors()) Sumw2();
fSumw2.At(bin) = e2;
}
void AddBinContent(const Int_t* idx, Double_t v = 1.) {
THnBase::AddBinContent(idx, v);
}
void AddBinContent(Long64_t bin, Double_t v = 1.) {
GetArray().AddAt(bin, v);
}
void AddBinError2(Long64_t bin, Double_t e2) {
fSumw2.At(bin) += e2;
}
Double_t GetBinContent(const Int_t *idx) const {
return THnBase::GetBinContent(idx);
}
Double_t GetBinContent(Long64_t bin, Int_t* idx = 0) const {
if (idx) {
const TNDArray& arr = GetArray();
Long64_t prevCellSize = arr.GetNbins();
for (Int_t i = 0; i < GetNdimensions(); ++i) {
Long64_t cellSize = arr.GetCellSize(i);
idx[i] = (bin % prevCellSize) / cellSize;
prevCellSize = cellSize;
}
}
return GetArray().AtAsDouble(bin);
}
Double_t GetBinError2(Long64_t linidx) const {
return GetCalculateErrors() ? fSumw2.At(linidx) : GetBinContent(linidx);
}
virtual const TNDArray& GetArray() const = 0;
virtual TNDArray& GetArray() = 0;
void Sumw2();
TH1D* Projection(Int_t xDim, Option_t* option = "") const {
return THnBase::Projection(xDim, option);
}
TH2D* Projection(Int_t yDim, Int_t xDim,
Option_t* option = "") const {
return THnBase::Projection(yDim, xDim, option);
}
TH3D* Projection(Int_t xDim, Int_t yDim, Int_t zDim,
Option_t* option = "") const {
return THnBase::Projection(xDim, yDim, zDim, option);
}
THn* Projection(Int_t ndim, const Int_t* dim,
Option_t* option = "") const {
return (THn*) ProjectionND(ndim, dim, option);
}
THn* Rebin(Int_t group) const {
return (THn*) RebinBase(group);
}
THn* Rebin(const Int_t* group) const {
return (THn*) RebinBase(group);
}
void Reset(Option_t* option = "");
protected:
TNDArrayT<Double_t> fSumw2;
mutable Int_t* fCoordBuf;
ClassDef(THn, 1);
};
template <typename T>
class THnT: public THn {
public:
THnT() {}
THnT(const char* name, const char* title,
Int_t dim, const Int_t* nbins,
const Double_t* xmin, const Double_t* xmax):
THn(name, title, dim, nbins, xmin, xmax),
fArray(dim, nbins, true) {}
const TNDArray& GetArray() const { return fArray; }
TNDArray& GetArray() { return fArray; }
protected:
TNDArrayT<T> fArray;
ClassDef(THnT, 1);
};
typedef THnT<Float_t> THnF;
typedef THnT<Double_t> THnD;
typedef THnT<Char_t> THnC;
typedef THnT<Short_t> THnS;
typedef THnT<Int_t> THnI;
typedef THnT<Long_t> THnL;
typedef THnT<Long64_t> THnL64;
#endif // ROOT_THN