#include "TROOT.h"
#include "TClass.h"
#include "THashList.h"
#include "TH3.h"
#include "TProfile2D.h"
#include "TH2.h"
#include "TF1.h"
#include "TVirtualPad.h"
#include "TVirtualHistPainter.h"
#include "THLimitsFinder.h"
#include "TRandom.h"
#include "TError.h"
#include "TMath.h"
#include "TObjString.h"
ClassImp(TH3)
TH3::TH3()
{
fDimension = 3;
fTsumwy = fTsumwy2 = fTsumwxy = 0;
fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
}
TH3::TH3(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
,Int_t nbinsy,Double_t ylow,Double_t yup
,Int_t nbinsz,Double_t zlow,Double_t zup)
:TH1(name,title,nbinsx,xlow,xup),
TAtt3D()
{
fDimension = 3;
if (nbinsy <= 0) nbinsy = 1;
if (nbinsz <= 0) nbinsz = 1;
fYaxis.Set(nbinsy,ylow,yup);
fZaxis.Set(nbinsz,zlow,zup);
fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
fTsumwy = fTsumwy2 = fTsumwxy = 0;
fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
}
TH3::TH3(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
,Int_t nbinsy,const Float_t *ybins
,Int_t nbinsz,const Float_t *zbins)
:TH1(name,title,nbinsx,xbins),
TAtt3D()
{
fDimension = 3;
if (nbinsy <= 0) nbinsy = 1;
if (nbinsz <= 0) nbinsz = 1;
if (ybins) fYaxis.Set(nbinsy,ybins);
else fYaxis.Set(nbinsy,0,1);
if (zbins) fZaxis.Set(nbinsz,zbins);
else fZaxis.Set(nbinsz,0,1);
fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
fTsumwy = fTsumwy2 = fTsumwxy = 0;
fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
}
TH3::TH3(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
,Int_t nbinsy,const Double_t *ybins
,Int_t nbinsz,const Double_t *zbins)
:TH1(name,title,nbinsx,xbins),
TAtt3D()
{
fDimension = 3;
if (nbinsy <= 0) nbinsy = 1;
if (nbinsz <= 0) nbinsz = 1;
if (ybins) fYaxis.Set(nbinsy,ybins);
else fYaxis.Set(nbinsy,0,1);
if (zbins) fZaxis.Set(nbinsz,zbins);
else fZaxis.Set(nbinsz,0,1);
fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
fTsumwy = fTsumwy2 = fTsumwxy = 0;
fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
}
TH3::TH3(const TH3 &h) : TH1(), TAtt3D()
{
((TH3&)h).Copy(*this);
}
TH3::~TH3()
{
}
void TH3::Copy(TObject &obj) const
{
TH1::Copy(obj);
((TH3&)obj).fTsumwy = fTsumwy;
((TH3&)obj).fTsumwy2 = fTsumwy2;
((TH3&)obj).fTsumwxy = fTsumwxy;
((TH3&)obj).fTsumwz = fTsumwz;
((TH3&)obj).fTsumwz2 = fTsumwz2;
((TH3&)obj).fTsumwxz = fTsumwxz;
((TH3&)obj).fTsumwyz = fTsumwyz;
}
Int_t TH3::BufferEmpty(Int_t action)
{
if (!fBuffer) return 0;
Int_t nbentries = (Int_t)fBuffer[0];
if (!nbentries) return 0;
Double_t *buffer = fBuffer;
if (nbentries < 0) {
if (action == 0) return 0;
nbentries = -nbentries;
fBuffer=0;
Reset("ICES");
fBuffer = buffer;
}
if (TestBit(kCanRebin) || fXaxis.GetXmax() <= fXaxis.GetXmin() ||
fYaxis.GetXmax() <= fYaxis.GetXmin() ||
fZaxis.GetXmax() <= fZaxis.GetXmin()) {
Double_t xmin = fBuffer[2];
Double_t xmax = xmin;
Double_t ymin = fBuffer[3];
Double_t ymax = ymin;
Double_t zmin = fBuffer[4];
Double_t zmax = zmin;
for (Int_t i=1;i<nbentries;i++) {
Double_t x = fBuffer[4*i+2];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
Double_t y = fBuffer[4*i+3];
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
Double_t z = fBuffer[4*i+4];
if (z < zmin) zmin = z;
if (z > zmax) zmax = z;
}
if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin() || fZaxis.GetXmax() <= fZaxis.GetXmin()) {
THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
} else {
fBuffer = 0;
Int_t keep = fBufferSize; fBufferSize = 0;
if (xmin < fXaxis.GetXmin()) RebinAxis(xmin,&fXaxis);
if (xmax >= fXaxis.GetXmax()) RebinAxis(xmax,&fXaxis);
if (ymin < fYaxis.GetXmin()) RebinAxis(ymin,&fYaxis);
if (ymax >= fYaxis.GetXmax()) RebinAxis(ymax,&fYaxis);
if (zmin < fZaxis.GetXmin()) RebinAxis(zmin,&fZaxis);
if (zmax >= fZaxis.GetXmax()) RebinAxis(zmax,&fZaxis);
fBuffer = buffer;
fBufferSize = keep;
}
}
fBuffer = 0;
for (Int_t i=0;i<nbentries;i++) {
Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
}
fBuffer = buffer;
if (action > 0) { delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
else {
if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
else fBuffer[0] = 0;
}
return nbentries;
}
Int_t TH3::BufferFill(Double_t x, Double_t y, Double_t z, Double_t w)
{
if (!fBuffer) return -3;
Int_t nbentries = (Int_t)fBuffer[0];
if (nbentries < 0) {
nbentries = -nbentries;
fBuffer[0] = nbentries;
if (fEntries > 0) {
Double_t *buffer = fBuffer; fBuffer=0;
Reset("ICES");
fBuffer = buffer;
}
}
if (4*nbentries+4 >= fBufferSize) {
BufferEmpty(1);
return Fill(x,y,z,w);
}
fBuffer[4*nbentries+1] = w;
fBuffer[4*nbentries+2] = x;
fBuffer[4*nbentries+3] = y;
fBuffer[4*nbentries+4] = z;
fBuffer[0] += 1;
return -3;
}
Int_t TH3::Fill(Double_t x, Double_t y, Double_t z)
{
if (fBuffer) return BufferFill(x,y,z,1);
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(x);
biny = fYaxis.FindBin(y);
binz = fZaxis.FindBin(z);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin);
if (fSumw2.fN) ++fSumw2.fArray[bin];
if (binx == 0 || binx > fXaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (biny == 0 || biny > fYaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (binz == 0 || binz > fZaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
++fTsumw;
++fTsumw2;
fTsumwx += x;
fTsumwx2 += x*x;
fTsumwy += y;
fTsumwy2 += y*y;
fTsumwxy += x*y;
fTsumwz += z;
fTsumwz2 += z*z;
fTsumwxz += x*z;
fTsumwyz += y*z;
return bin;
}
Int_t TH3::Fill(Double_t x, Double_t y, Double_t z, Double_t w)
{
if (fBuffer) return BufferFill(x,y,z,w);
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(x);
biny = fYaxis.FindBin(y);
binz = fZaxis.FindBin(z);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (biny == 0 || biny > fYaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (binz == 0 || binz > fZaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
fTsumw += w;
fTsumw2 += w*w;
fTsumwx += w*x;
fTsumwx2 += w*x*x;
fTsumwy += w*y;
fTsumwy2 += w*y*y;
fTsumwxy += w*x*y;
fTsumwz += w*z;
fTsumwz2 += w*z*z;
fTsumwxz += w*x*z;
fTsumwyz += w*y*z;
return bin;
}
Int_t TH3::Fill(const char *namex, const char *namey, const char *namez, Double_t w)
{
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(namex);
biny = fYaxis.FindBin(namey);
binz = fZaxis.FindBin(namez);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
Double_t x = fXaxis.GetBinCenter(binx);
Double_t y = fYaxis.GetBinCenter(biny);
Double_t z = fZaxis.GetBinCenter(binz);
Double_t v = w;
fTsumw += v;
fTsumw2 += v*v;
fTsumwx += v*x;
fTsumwx2 += v*x*x;
fTsumwy += v*y;
fTsumwy2 += v*y*y;
fTsumwxy += v*x*y;
fTsumwz += v*z;
fTsumwz2 += v*z*z;
fTsumwxz += v*x*z;
fTsumwyz += v*y*z;
return bin;
}
Int_t TH3::Fill(const char *namex, Double_t y, const char *namez, Double_t w)
{
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(namex);
biny = fYaxis.FindBin(y);
binz = fZaxis.FindBin(namez);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
if (biny == 0 || biny > fYaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
Double_t x = fXaxis.GetBinCenter(binx);
Double_t z = fZaxis.GetBinCenter(binz);
Double_t v = w;
fTsumw += v;
fTsumw2 += v*v;
fTsumwx += v*x;
fTsumwx2 += v*x*x;
fTsumwy += v*y;
fTsumwy2 += v*y*y;
fTsumwxy += v*x*y;
fTsumwz += v*z;
fTsumwz2 += v*z*z;
fTsumwxz += v*x*z;
fTsumwyz += v*y*z;
return bin;
}
Int_t TH3::Fill(const char *namex, const char *namey, Double_t z, Double_t w)
{
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(namex);
biny = fYaxis.FindBin(namey);
binz = fZaxis.FindBin(z);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
if (binz == 0 || binz > fZaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
Double_t x = fXaxis.GetBinCenter(binx);
Double_t y = fYaxis.GetBinCenter(biny);
Double_t v = w;
fTsumw += v;
fTsumw2 += v*v;
fTsumwx += v*x;
fTsumwx2 += v*x*x;
fTsumwy += v*y;
fTsumwy2 += v*y*y;
fTsumwxy += v*x*y;
fTsumwz += v*z;
fTsumwz2 += v*z*z;
fTsumwxz += v*x*z;
fTsumwyz += v*y*z;
return bin;
}
Int_t TH3::Fill(Double_t x, const char *namey, const char *namez, Double_t w)
{
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(x);
biny = fYaxis.FindBin(namey);
binz = fZaxis.FindBin(namez);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
Double_t y = fYaxis.GetBinCenter(biny);
Double_t z = fZaxis.GetBinCenter(binz);
Double_t v = w;
fTsumw += v;
fTsumw2 += v*v;
fTsumwx += v*x;
fTsumwx2 += v*x*x;
fTsumwy += v*y;
fTsumwy2 += v*y*y;
fTsumwxy += v*x*y;
fTsumwz += v*z;
fTsumwz2 += v*z*z;
fTsumwxz += v*x*z;
fTsumwyz += v*y*z;
return bin;
}
Int_t TH3::Fill(Double_t x, const char *namey, Double_t z, Double_t w)
{
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(x);
biny = fYaxis.FindBin(namey);
binz = fZaxis.FindBin(z);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
if (binz == 0 || binz > fZaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
Double_t y = fYaxis.GetBinCenter(biny);
Double_t v = w;
fTsumw += v;
fTsumw2 += v*v;
fTsumwx += v*x;
fTsumwx2 += v*x*x;
fTsumwy += v*y;
fTsumwy2 += v*y*y;
fTsumwxy += v*x*y;
fTsumwz += v*z;
fTsumwz2 += v*z*z;
fTsumwxz += v*x*z;
fTsumwyz += v*y*z;
return bin;
}
Int_t TH3::Fill(Double_t x, Double_t y, const char *namez, Double_t w)
{
Int_t binx, biny, binz, bin;
fEntries++;
binx = fXaxis.FindBin(x);
biny = fYaxis.FindBin(y);
binz = fZaxis.FindBin(namez);
if (binx <0 || biny <0 || binz<0) return -1;
bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
AddBinContent(bin,w);
if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
if (binx == 0 || binx > fXaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (biny == 0 || biny > fYaxis.GetNbins()) {
if (!fgStatOverflows) return -1;
}
if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
Double_t z = fZaxis.GetBinCenter(binz);
Double_t v = w;
fTsumw += v;
fTsumw2 += v*v;
fTsumwx += v*x;
fTsumwx2 += v*x*x;
fTsumwy += v*y;
fTsumwy2 += v*y*y;
fTsumwxy += v*x*y;
fTsumwz += v*z;
fTsumwz2 += v*z*z;
fTsumwxz += v*x*z;
fTsumwyz += v*y*z;
return bin;
}
void TH3::FillRandom(const char *fname, Int_t ntimes)
{
Int_t bin, binx, biny, binz, ibin, loop;
Double_t r1, x, y,z, xv[3];
TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
Int_t nbinsx = GetNbinsX();
Int_t nbinsy = GetNbinsY();
Int_t nbinsz = GetNbinsZ();
Int_t nxy = nbinsx*nbinsy;
Int_t nbins = nxy*nbinsz;
Double_t *integral = new Double_t[nbins+1];
ibin = 0;
integral[ibin] = 0;
for (binz=1;binz<=nbinsz;binz++) {
xv[2] = fZaxis.GetBinCenter(binz);
for (biny=1;biny<=nbinsy;biny++) {
xv[1] = fYaxis.GetBinCenter(biny);
for (binx=1;binx<=nbinsx;binx++) {
xv[0] = fXaxis.GetBinCenter(binx);
ibin++;
integral[ibin] = integral[ibin-1] + f1->Eval(xv[0],xv[1],xv[2]);
}
}
}
if (integral[nbins] == 0 ) {
delete [] integral;
Error("FillRandom", "Integral = zero"); return;
}
for (bin=1;bin<=nbins;bin++) integral[bin] /= integral[nbins];
if (fDimension < 2) nbinsy = -1;
if (fDimension < 3) nbinsz = -1;
for (loop=0;loop<ntimes;loop++) {
r1 = gRandom->Rndm(loop);
ibin = TMath::BinarySearch(nbins,&integral[0],r1);
binz = ibin/nxy;
biny = (ibin - nxy*binz)/nbinsx;
binx = 1 + ibin - nbinsx*(biny + nbinsy*binz);
if (nbinsz) binz++;
if (nbinsy) biny++;
x = fXaxis.GetBinCenter(binx);
y = fYaxis.GetBinCenter(biny);
z = fZaxis.GetBinCenter(binz);
Fill(x,y,z, 1.);
}
delete [] integral;
}
void TH3::FillRandom(TH1 *h, Int_t ntimes)
{
if (!h) { Error("FillRandom", "Null histogram"); return; }
if (fDimension != h->GetDimension()) {
Error("FillRandom", "Histograms with different dimensions"); return;
}
if (h->ComputeIntegral() == 0) return;
TH3 *h3 = (TH3*)h;
Int_t loop;
Double_t x,y,z;
for (loop=0;loop<ntimes;loop++) {
h3->GetRandom3(x,y,z);
Fill(x,y,z,1.);
}
}
Int_t TH3::FindFirstBinAbove(Double_t threshold, Int_t axis) const
{
if (axis < 1 || axis > 3) {
Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
axis = 1;
}
Int_t nbinsx = fXaxis.GetNbins();
Int_t nbinsy = fYaxis.GetNbins();
Int_t nbinsz = fZaxis.GetNbins();
Int_t binx, biny, binz;
if (axis == 1) {
for (binx=1;binx<=nbinsx;binx++) {
for (biny=1;biny<=nbinsy;biny++) {
for (binz=1;binz<=nbinsz;binz++) {
if (GetBinContent(binx,biny,binz) > threshold) return binx;
}
}
}
} else if (axis == 2) {
for (biny=1;biny<=nbinsy;biny++) {
for (binx=1;binx<=nbinsx;binx++) {
for (binz=1;binz<=nbinsz;binz++) {
if (GetBinContent(binx,biny,binz) > threshold) return biny;
}
}
}
} else {
for (binz=1;binz<=nbinsz;binz++) {
for (binx=1;binx<=nbinsx;binx++) {
for (biny=1;biny<=nbinsy;biny++) {
if (GetBinContent(binx,biny,binz) > threshold) return binz;
}
}
}
}
return -1;
}
Int_t TH3::FindLastBinAbove(Double_t threshold, Int_t axis) const
{
if (axis < 1 || axis > 3) {
Warning("FindLastBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
axis = 1;
}
Int_t nbinsx = fXaxis.GetNbins();
Int_t nbinsy = fYaxis.GetNbins();
Int_t nbinsz = fZaxis.GetNbins();
Int_t binx, biny, binz;
if (axis == 1) {
for (binx=nbinsx;binx>=1;binx--) {
for (biny=1;biny<=nbinsy;biny++) {
for (binz=1;binz<=nbinsz;binz++) {
if (GetBinContent(binx,biny,binz) > threshold) return binx;
}
}
}
} else if (axis == 2) {
for (biny=nbinsy;biny>=1;biny--) {
for (binx=1;binx<=nbinsx;binx++) {
for (binz=1;binz<=nbinsz;binz++) {
if (GetBinContent(binx,biny,binz) > threshold) return biny;
}
}
}
} else {
for (binz=nbinsz;binz>=1;binz--) {
for (binx=1;binx<=nbinsx;binx++) {
for (biny=1;biny<=nbinsy;biny++) {
if (GetBinContent(binx,biny,binz) > threshold) return binz;
}
}
}
}
return -1;
}
void TH3::FitSlicesZ(TF1 *f1, Int_t binminx, Int_t binmaxx, Int_t binminy, Int_t binmaxy, Int_t cut, Option_t *option)
{
Int_t nbinsx = fXaxis.GetNbins();
Int_t nbinsy = fYaxis.GetNbins();
Int_t nbinsz = fZaxis.GetNbins();
if (binminx < 1) binminx = 1;
if (binmaxx > nbinsx) binmaxx = nbinsx;
if (binmaxx < binminx) {binminx = 1; binmaxx = nbinsx;}
if (binminy < 1) binminy = 1;
if (binmaxy > nbinsy) binmaxy = nbinsy;
if (binmaxy < binminy) {binminy = 1; binmaxy = nbinsy;}
if (f1 == 0) {
f1 = (TF1*)gROOT->GetFunction("gaus");
if (f1 == 0) f1 = new TF1("gaus","gaus",fZaxis.GetXmin(),fZaxis.GetXmax());
else f1->SetRange(fZaxis.GetXmin(),fZaxis.GetXmax());
}
const char *fname = f1->GetName();
Int_t npar = f1->GetNpar();
Double_t *parsave = new Double_t[npar];
f1->GetParameters(parsave);
Int_t ipar;
char name[80], title[80];
TH2D *hlist[25];
const TArrayD *xbins = fXaxis.GetXbins();
const TArrayD *ybins = fYaxis.GetXbins();
for (ipar=0;ipar<npar;ipar++) {
snprintf(name,80,"%s_%d",GetName(),ipar);
snprintf(title,80,"Fitted value of par[%d]=%s",ipar,f1->GetParName(ipar));
if (xbins->fN == 0) {
hlist[ipar] = new TH2D(name, title,
nbinsx, fXaxis.GetXmin(), fXaxis.GetXmax(),
nbinsy, fYaxis.GetXmin(), fYaxis.GetXmax());
} else {
hlist[ipar] = new TH2D(name, title,
nbinsx, xbins->fArray,
nbinsy, ybins->fArray);
}
hlist[ipar]->GetXaxis()->SetTitle(fXaxis.GetTitle());
hlist[ipar]->GetYaxis()->SetTitle(fYaxis.GetTitle());
}
snprintf(name,80,"%s_chi2",GetName());
TH2D *hchi2 = new TH2D(name,"chisquare", nbinsx, fXaxis.GetXmin(), fXaxis.GetXmax()
, nbinsy, fYaxis.GetXmin(), fYaxis.GetXmax());
TH1D *hpz = new TH1D("R_temp","_temp",nbinsz, fZaxis.GetXmin(), fZaxis.GetXmax());
Int_t bin,binx,biny,binz;
for (biny=binminy;biny<=binmaxy;biny++) {
Float_t y = fYaxis.GetBinCenter(biny);
for (binx=binminx;binx<=binmaxx;binx++) {
Float_t x = fXaxis.GetBinCenter(binx);
hpz->Reset();
Int_t nfill = 0;
for (binz=1;binz<=nbinsz;binz++) {
bin = GetBin(binx,biny,binz);
Float_t w = GetBinContent(bin);
if (w == 0) continue;
hpz->Fill(fZaxis.GetBinCenter(binz),w);
hpz->SetBinError(binz,GetBinError(bin));
nfill++;
}
if (nfill < cut) continue;
f1->SetParameters(parsave);
hpz->Fit(fname,option);
Int_t npfits = f1->GetNumberFitPoints();
if (npfits > npar && npfits >= cut) {
for (ipar=0;ipar<npar;ipar++) {
hlist[ipar]->Fill(x,y,f1->GetParameter(ipar));
hlist[ipar]->SetCellError(binx,biny,f1->GetParError(ipar));
}
hchi2->Fill(x,y,f1->GetChisquare()/(npfits-npar));
}
}
}
delete [] parsave;
delete hpz;
}
Double_t TH3::GetBinWithContent3(Double_t c, Int_t &binx, Int_t &biny, Int_t &binz, Int_t firstx, Int_t lastx, Int_t firsty, Int_t lasty, Int_t firstz, Int_t lastz, Double_t maxdiff) const
{
if (fDimension != 3) {
binx = 0;
biny = 0;
binz = 0;
Error("GetBinWithContent3","function is only valid for 3-D histograms");
return 0;
}
if (firstx <= 0) firstx = 1;
if (lastx < firstx) lastx = fXaxis.GetNbins();
if (firsty <= 0) firsty = 1;
if (lasty < firsty) lasty = fYaxis.GetNbins();
if (firstz <= 0) firstz = 1;
if (lastz < firstz) lastz = fZaxis.GetNbins();
Int_t binminx = 0, binminy=0, binminz=0;
Double_t diff, curmax = 1.e240;
for (Int_t k=firstz;k<=lastz;k++) {
for (Int_t j=firsty;j<=lasty;j++) {
for (Int_t i=firstx;i<=lastx;i++) {
diff = TMath::Abs(GetBinContent(i,j,k)-c);
if (diff <= 0) {binx = i; biny=j; binz=k; return diff;}
if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i; binminy=j;binminz=k;}
}
}
}
binx = binminx;
biny = binminy;
binz = binminz;
return curmax;
}
Double_t TH3::GetCorrelationFactor(Int_t axis1, Int_t axis2) const
{
if (axis1 < 1 || axis2 < 1 || axis1 > 3 || axis2 > 3) {
Error("GetCorrelationFactor","Wrong parameters");
return 0;
}
if (axis1 == axis2) return 1;
Double_t rms1 = GetRMS(axis1);
if (rms1 == 0) return 0;
Double_t rms2 = GetRMS(axis2);
if (rms2 == 0) return 0;
return GetCovariance(axis1,axis2)/rms1/rms2;
}
Double_t TH3::GetCovariance(Int_t axis1, Int_t axis2) const
{
if (axis1 < 1 || axis2 < 1 || axis1 > 3 || axis2 > 3) {
Error("GetCovariance","Wrong parameters");
return 0;
}
Double_t stats[kNstat];
GetStats(stats);
Double_t sumw = stats[0];
Double_t sumw2 = stats[1];
Double_t sumwx = stats[2];
Double_t sumwx2 = stats[3];
Double_t sumwy = stats[4];
Double_t sumwy2 = stats[5];
Double_t sumwxy = stats[6];
Double_t sumwz = stats[7];
Double_t sumwz2 = stats[8];
Double_t sumwxz = stats[9];
Double_t sumwyz = stats[10];
if (sumw == 0) return 0;
if (axis1 == 1 && axis2 == 1) {
return TMath::Abs(sumwx2/sumw - sumwx*sumwx/sumw2);
}
if (axis1 == 2 && axis2 == 2) {
return TMath::Abs(sumwy2/sumw - sumwy*sumwy/sumw2);
}
if (axis1 == 3 && axis2 == 3) {
return TMath::Abs(sumwz2/sumw - sumwz*sumwz/sumw2);
}
if ((axis1 == 1 && axis2 == 2) || (axis1 == 2 && axis1 == 1)) {
return sumwxy/sumw - sumwx/sumw*sumwy/sumw;
}
if ((axis1 == 1 && axis2 == 3) || (axis1 == 3 && axis2 == 1)) {
return sumwxz/sumw - sumwx/sumw*sumwz/sumw;
}
if ((axis1 == 2 && axis2 == 3) || (axis1 == 3 && axis2 == 2)) {
return sumwyz/sumw - sumwy/sumw*sumwz/sumw;
}
return 0;
}
void TH3::GetRandom3(Double_t &x, Double_t &y, Double_t &z)
{
Int_t nbinsx = GetNbinsX();
Int_t nbinsy = GetNbinsY();
Int_t nbinsz = GetNbinsZ();
Int_t nxy = nbinsx*nbinsy;
Int_t nbins = nxy*nbinsz;
Double_t integral;
if (fIntegral) {
if (fIntegral[nbins+1] != fEntries) integral = ComputeIntegral();
} else {
integral = ComputeIntegral();
if (integral == 0 || fIntegral == 0) return;
}
Double_t r1 = gRandom->Rndm();
Int_t ibin = TMath::BinarySearch(nbins,fIntegral,(Double_t) r1);
Int_t binz = ibin/nxy;
Int_t biny = (ibin - nxy*binz)/nbinsx;
Int_t binx = ibin - nbinsx*(biny + nbinsy*binz);
x = fXaxis.GetBinLowEdge(binx+1);
if (r1 > fIntegral[ibin]) x +=
fXaxis.GetBinWidth(binx+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
y = fYaxis.GetBinLowEdge(biny+1) + fYaxis.GetBinWidth(biny+1)*gRandom->Rndm();
z = fZaxis.GetBinLowEdge(binz+1) + fZaxis.GetBinWidth(binz+1)*gRandom->Rndm();
}
void TH3::GetStats(Double_t *stats) const
{
if (fBuffer) ((TH3*)this)->BufferEmpty();
Int_t bin, binx, biny, binz;
Double_t w,err;
Double_t x,y,z;
if ((fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange) || fZaxis.TestBit(TAxis::kAxisRange)) {
for (bin=0;bin<9;bin++) stats[bin] = 0;
Int_t firstBinX = fXaxis.GetFirst();
Int_t lastBinX = fXaxis.GetLast();
Int_t firstBinY = fYaxis.GetFirst();
Int_t lastBinY = fYaxis.GetLast();
Int_t firstBinZ = fZaxis.GetFirst();
Int_t lastBinZ = fZaxis.GetLast();
if (fgStatOverflows) {
if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
if (firstBinX == 1) firstBinX = 0;
if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
}
if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
if (firstBinY == 1) firstBinY = 0;
if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
}
if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
if (firstBinZ == 1) firstBinZ = 0;
if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
}
}
for (binz = firstBinZ; binz <= lastBinZ; binz++) {
z = fZaxis.GetBinCenter(binz);
for (biny = firstBinY; biny <= lastBinY; biny++) {
y = fYaxis.GetBinCenter(biny);
for (binx = firstBinX; binx <= lastBinX; binx++) {
bin = GetBin(binx,biny,binz);
x = fXaxis.GetBinCenter(binx);
w = GetBinContent(bin);
err = TMath::Abs(GetBinError(bin));
stats[0] += w;
stats[1] += err*err;
stats[2] += w*x;
stats[3] += w*x*x;
stats[4] += w*y;
stats[5] += w*y*y;
stats[6] += w*x*y;
stats[7] += w*z;
stats[8] += w*z*z;
stats[9] += w*x*z;
stats[10]+= w*y*z;
}
}
}
} else {
stats[0] = fTsumw;
stats[1] = fTsumw2;
stats[2] = fTsumwx;
stats[3] = fTsumwx2;
stats[4] = fTsumwy;
stats[5] = fTsumwy2;
stats[6] = fTsumwxy;
stats[7] = fTsumwz;
stats[8] = fTsumwz2;
stats[9] = fTsumwxz;
stats[10]= fTsumwyz;
}
}
Double_t TH3::Integral(Option_t *option) const
{
return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),
fYaxis.GetFirst(),fYaxis.GetLast(),
fZaxis.GetFirst(),fZaxis.GetLast(),option);
}
Double_t TH3::Integral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Option_t *option) const
{
Double_t err = 0;
return DoIntegral(binx1,binx2,biny1,biny2,binz1,binz2,err,option);
}
Double_t TH3::IntegralAndError(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error, Option_t *option) const
{
return DoIntegral(binx1,binx2,biny1,biny2,binz1,binz2,error,option,kTRUE);
}
Double_t TH3::Interpolate(Double_t)
{
Error("Interpolate","This function must be called with 3 arguments for a TH3");
return 0;
}
Double_t TH3::Interpolate(Double_t, Double_t)
{
Error("Interpolate","This function must be called with 3 arguments for a TH3");
return 0;
}
Double_t TH3::Interpolate(Double_t x, Double_t y, Double_t z)
{
Int_t ubx = fXaxis.FindBin(x);
if ( x < fXaxis.GetBinCenter(ubx) ) ubx -= 1;
Int_t obx = ubx + 1;
Int_t uby = fYaxis.FindBin(y);
if ( y < fYaxis.GetBinCenter(uby) ) uby -= 1;
Int_t oby = uby + 1;
Int_t ubz = fZaxis.FindBin(z);
if ( z < fZaxis.GetBinCenter(ubz) ) ubz -= 1;
Int_t obz = ubz + 1;
if (ubx <=0 || uby <=0 || ubz <= 0 ||
obx > fXaxis.GetNbins() || oby > fYaxis.GetNbins() || obz > fZaxis.GetNbins() ) {
Error("Interpolate","Cannot interpolate outside histogram domain.");
return 0;
}
Double_t xw = fXaxis.GetBinCenter(obx) - fXaxis.GetBinCenter(ubx);
Double_t yw = fYaxis.GetBinCenter(oby) - fYaxis.GetBinCenter(uby);
Double_t zw = fZaxis.GetBinCenter(obz) - fZaxis.GetBinCenter(ubz);
Double_t xd = (x - fXaxis.GetBinCenter(ubx)) / xw;
Double_t yd = (y - fYaxis.GetBinCenter(uby)) / yw;
Double_t zd = (z - fZaxis.GetBinCenter(ubz)) / zw;
Double_t v[] = { GetBinContent( ubx, uby, ubz ), GetBinContent( ubx, uby, obz ),
GetBinContent( ubx, oby, ubz ), GetBinContent( ubx, oby, obz ),
GetBinContent( obx, uby, ubz ), GetBinContent( obx, uby, obz ),
GetBinContent( obx, oby, ubz ), GetBinContent( obx, oby, obz ) };
Double_t i1 = v[0] * (1 - zd) + v[1] * zd;
Double_t i2 = v[2] * (1 - zd) + v[3] * zd;
Double_t j1 = v[4] * (1 - zd) + v[5] * zd;
Double_t j2 = v[6] * (1 - zd) + v[7] * zd;
Double_t w1 = i1 * (1 - yd) + i2 * yd;
Double_t w2 = j1 * (1 - yd) + j2 * yd;
Double_t result = w1 * (1 - xd) + w2 * xd;
return result;
}
Double_t TH3::KolmogorovTest(const TH1 *h2, Option_t *option) const
{
TString opt = option;
opt.ToUpper();
Double_t prb = 0;
TH1 *h1 = (TH1*)this;
if (h2 == 0) return 0;
TAxis *xaxis1 = h1->GetXaxis();
TAxis *xaxis2 = h2->GetXaxis();
TAxis *yaxis1 = h1->GetYaxis();
TAxis *yaxis2 = h2->GetYaxis();
TAxis *zaxis1 = h1->GetZaxis();
TAxis *zaxis2 = h2->GetZaxis();
Int_t ncx1 = xaxis1->GetNbins();
Int_t ncx2 = xaxis2->GetNbins();
Int_t ncy1 = yaxis1->GetNbins();
Int_t ncy2 = yaxis2->GetNbins();
Int_t ncz1 = zaxis1->GetNbins();
Int_t ncz2 = zaxis2->GetNbins();
if (h1->GetDimension() != 3 || h2->GetDimension() != 3) {
Error("KolmogorovTest","Histograms must be 3-D\n");
return 0;
}
if (ncx1 != ncx2) {
Error("KolmogorovTest","Number of channels in X is different, %d and %d\n",ncx1,ncx2);
return 0;
}
if (ncy1 != ncy2) {
Error("KolmogorovTest","Number of channels in Y is different, %d and %d\n",ncy1,ncy2);
return 0;
}
if (ncz1 != ncz2) {
Error("KolmogorovTest","Number of channels in Z is different, %d and %d\n",ncz1,ncz2);
return 0;
}
Bool_t afunc1 = kFALSE;
Bool_t afunc2 = kFALSE;
Double_t difprec = 1e-5;
Double_t diff1 = TMath::Abs(xaxis1->GetXmin() - xaxis2->GetXmin());
Double_t diff2 = TMath::Abs(xaxis1->GetXmax() - xaxis2->GetXmax());
if (diff1 > difprec || diff2 > difprec) {
Error("KolmogorovTest","histograms with different binning along X");
return 0;
}
diff1 = TMath::Abs(yaxis1->GetXmin() - yaxis2->GetXmin());
diff2 = TMath::Abs(yaxis1->GetXmax() - yaxis2->GetXmax());
if (diff1 > difprec || diff2 > difprec) {
Error("KolmogorovTest","histograms with different binning along Y");
return 0;
}
diff1 = TMath::Abs(zaxis1->GetXmin() - zaxis2->GetXmin());
diff2 = TMath::Abs(zaxis1->GetXmax() - zaxis2->GetXmax());
if (diff1 > difprec || diff2 > difprec) {
Error("KolmogorovTest","histograms with different binning along Z");
return 0;
}
Int_t ibeg = 1, jbeg = 1, kbeg = 1;
Int_t iend = ncx1, jend = ncy1, kend = ncz1;
if (opt.Contains("U")) {ibeg = 0; jbeg = 0; kbeg = 0;}
if (opt.Contains("O")) {iend = ncx1+1; jend = ncy1+1; kend = ncz1+1;}
Int_t i,j,k,bin;
Double_t sum1 = 0;
Double_t sum2 = 0;
Double_t w1 = 0;
Double_t w2 = 0;
for (i = ibeg; i <= iend; i++) {
for (j = jbeg; j <= jend; j++) {
for (k = kbeg; k <= kend; k++) {
bin = h1->GetBin(i,j,k);
sum1 += h1->GetBinContent(bin);
sum2 += h2->GetBinContent(bin);
Double_t ew1 = h1->GetBinError(bin);
Double_t ew2 = h2->GetBinError(bin);
w1 += ew1*ew1;
w2 += ew2*ew2;
}
}
}
if (sum1 == 0) {
Error("KolmogorovTest","Integral is zero for h1=%s\n",h1->GetName());
return 0;
}
if (sum2 == 0) {
Error("KolmogorovTest","Integral is zero for h2=%s\n",h2->GetName());
return 0;
}
Double_t esum1 = 0, esum2 = 0;
if (w1 > 0)
esum1 = sum1 * sum1 / w1;
else
afunc1 = kTRUE;
if (w2 > 0)
esum2 = sum2 * sum2 / w2;
else
afunc2 = kTRUE;
if (afunc2 && afunc1) {
Error("KolmogorovTest","Errors are zero for both histograms\n");
return 0;
}
int order[3] = {0,1,2};
int binbeg[3];
int binend[3];
int ibin[3];
binbeg[0] = ibeg; binbeg[1] = jbeg; binbeg[2] = kbeg;
binend[0] = iend; binend[1] = jend; binend[2] = kend;
Double_t vdfmax[6];
int icomb = 0;
Double_t s1 = 1./(6.*sum1);
Double_t s2 = 1./(6.*sum2);
Double_t rsum1=0, rsum2=0;
do {
Double_t dmax = 0;
for (i = binbeg[order[0] ]; i <= binend[order[0] ]; i++) {
for ( j = binbeg[order[1] ]; j <= binend[order[1] ]; j++) {
for ( k = binbeg[order[2] ]; k <= binend[order[2] ]; k++) {
ibin[ order[0] ] = i;
ibin[ order[1] ] = j;
ibin[ order[2] ] = k;
bin = h1->GetBin(ibin[0],ibin[1],ibin[2]);
rsum1 += s1*h1->GetBinContent(bin);
rsum2 += s2*h2->GetBinContent(bin);
dmax = TMath::Max(dmax, TMath::Abs(rsum1-rsum2));
}
}
}
vdfmax[icomb] = dmax;
icomb++;
} while (TMath::Permute(3,order) );
Double_t dfmax = TMath::Mean(6,vdfmax);
Double_t factnm;
if (afunc1) factnm = TMath::Sqrt(sum2);
else if (afunc2) factnm = TMath::Sqrt(sum1);
else factnm = TMath::Sqrt(sum1*sum2/(sum1+sum2));
Double_t z = dfmax*factnm;
prb = TMath::KolmogorovProb(z);
Double_t prb1 = 0, prb2 = 0;
if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
prb1 = prb;
Double_t d12 = esum1-esum2;
Double_t chi2 = d12*d12/(esum1+esum2);
prb2 = TMath::Prob(chi2,1);
if (prb > 0 && prb2 > 0) prb = prb*prb2*(1-TMath::Log(prb*prb2));
else prb = 0;
}
if (opt.Contains("D")) {
printf(" Kolmo Prob h1 = %s, sum1=%g\n",h1->GetName(),sum1);
printf(" Kolmo Prob h2 = %s, sum2=%g\n",h2->GetName(),sum2);
printf(" Kolmo Probabil = %f, Max Dist = %g\n",prb,dfmax);
if (opt.Contains("N"))
printf(" Kolmo Probabil = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
}
if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
if(opt.Contains("M")) return dfmax;
return prb;
}
Long64_t TH3::Merge(TCollection *list)
{
if (!list) return 0;
if (list->IsEmpty()) return (Int_t) GetEntries();
TList inlist;
TH1* hclone = (TH1*)Clone("FirstClone");
R__ASSERT(hclone);
BufferEmpty(1);
Reset();
SetEntries(0);
inlist.Add(hclone);
inlist.AddAll(list);
TAxis newXAxis;
TAxis newYAxis;
TAxis newZAxis;
Bool_t initialLimitsFound = kFALSE;
Bool_t same = kTRUE;
Bool_t allHaveLimits = kTRUE;
TIter next(&inlist);
while (TObject *o = next()) {
TH3* h = dynamic_cast<TH3*> (o);
if (!h) {
Error("Add","Attempt to add object of class: %s to a %s",
o->ClassName(),this->ClassName());
return -1;
}
Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
allHaveLimits = allHaveLimits && hasLimits;
if (hasLimits) {
h->BufferEmpty();
if (!initialLimitsFound) {
initialLimitsFound = kTRUE;
newXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax());
newYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
h->GetYaxis()->GetXmax());
newZAxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
h->GetZaxis()->GetXmax());
}
else {
if (!RecomputeAxisLimits(newXAxis, *(h->GetXaxis()))) {
Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
"first: (%d, %f, %f), second: (%d, %f, %f)",
newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(),
h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax());
}
if (!RecomputeAxisLimits(newYAxis, *(h->GetYaxis()))) {
Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
"first: (%d, %f, %f), second: (%d, %f, %f)",
newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax(),
h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
h->GetYaxis()->GetXmax());
}
if (!RecomputeAxisLimits(newZAxis, *(h->GetZaxis()))) {
Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
"first: (%d, %f, %f), second: (%d, %f, %f)",
newZAxis.GetNbins(), newZAxis.GetXmin(), newZAxis.GetXmax(),
h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
h->GetZaxis()->GetXmax());
}
}
}
}
next.Reset();
same = same && SameLimitsAndNBins(newXAxis, *GetXaxis())
&& SameLimitsAndNBins(newYAxis, *GetYaxis());
if (!same && initialLimitsFound)
SetBins(newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(),
newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax(),
newZAxis.GetNbins(), newZAxis.GetXmin(), newZAxis.GetXmax());
if (!allHaveLimits) {
while (TH3* h = dynamic_cast<TH3*> (next())) {
if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax() && h->fBuffer) {
Int_t nbentries = (Int_t)h->fBuffer[0];
for (Int_t i = 0; i < nbentries; i++)
Fill(h->fBuffer[4*i + 2], h->fBuffer[4*i + 3],
h->fBuffer[4*i + 4], h->fBuffer[4*i + 1]);
}
}
if (!initialLimitsFound)
return (Int_t) GetEntries();
next.Reset();
}
Double_t stats[kNstat], totstats[kNstat];
for (Int_t i=0;i<kNstat;i++) {totstats[i] = stats[i] = 0;}
GetStats(totstats);
Double_t nentries = GetEntries();
Int_t binx, biny, binz, ix, iy, iz, nx, ny, nz, bin, ibin;
Double_t cu;
Int_t nbix = fXaxis.GetNbins();
Int_t nbiy = fYaxis.GetNbins();
Bool_t canRebin=TestBit(kCanRebin);
ResetBit(kCanRebin);
while (TH1* h=(TH1*)next()) {
if (h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax()) {
h->GetStats(stats);
for (Int_t i = 0; i < kNstat; i++)
totstats[i] += stats[i];
nentries += h->GetEntries();
nx = h->GetXaxis()->GetNbins();
ny = h->GetYaxis()->GetNbins();
nz = h->GetZaxis()->GetNbins();
for (binz = 0; binz <= nz + 1; binz++) {
iz = fZaxis.FindBin(h->GetZaxis()->GetBinCenter(binz));
for (biny = 0; biny <= ny + 1; biny++) {
iy = fYaxis.FindBin(h->GetYaxis()->GetBinCenter(biny));
for (binx = 0; binx <= nx + 1; binx++) {
ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
bin = binx +(nx+2)*(biny + (ny+2)*binz);
ibin = ix +(nbix+2)*(iy + (nbiy+2)*iz);
cu = h->GetBinContent(bin);
if ((!same) && (binx == 0 || binx == nx + 1
|| biny == 0 || biny == ny + 1
|| binz == 0 || binz == nz + 1)) {
if (cu != 0) {
Error("Merge", "Cannot merge histograms - the histograms have"
" different limits and undeflows/overflows are present."
" The initial histogram is now broken!");
return -1;
}
}
if (ibin <0) continue;
AddBinContent(ibin,cu);
if (fSumw2.fN) {
Double_t error1 = h->GetBinError(bin);
fSumw2.fArray[ibin] += error1*error1;
}
}
}
}
}
}
if (canRebin) SetBit(kCanRebin);
PutStats(totstats);
SetEntries(nentries);
inlist.Remove(hclone);
delete hclone;
return (Long64_t)nentries;
}
TH1D *TH3::ProjectionX(const char *name, Int_t iymin, Int_t iymax, Int_t izmin, Int_t izmax, Option_t *option) const
{
TString opt = option;
opt.ToLower();
Int_t piymin = GetYaxis()->GetFirst();
Int_t piymax = GetYaxis()->GetLast();
Int_t pizmin = GetZaxis()->GetFirst();
Int_t pizmax = GetZaxis()->GetLast();
GetYaxis()->SetRange(iymin,iymax);
GetZaxis()->SetRange(izmin,izmax);
if (iymin == 1 && iymax == GetNbinsY() ) GetYaxis()->SetBit(TAxis::kAxisRange);
if (izmin == 1 && izmax == GetNbinsZ() ) GetZaxis()->SetBit(TAxis::kAxisRange);
Bool_t useUF = (iymin == 0 || izmin == 0);
Bool_t useOF = ( (iymax < 0 ) || (iymax > GetNbinsY() ) || (izmax < 0) || (izmax > GetNbinsZ() ) );
Bool_t computeErrors = GetSumw2N();
if (opt.Contains("e") ) {
computeErrors = kTRUE;
opt.Remove(opt.First("e"),1);
}
Bool_t originalRange = kFALSE;
if (opt.Contains('o') ) {
originalRange = kTRUE;
opt.Remove(opt.First("o"),1);
}
TH1D * h1 = DoProject1D(name, GetTitle(), this->GetXaxis(), computeErrors, originalRange, useUF, useOF);
GetYaxis()->SetRange(piymin,piymax);
GetZaxis()->SetRange(pizmin,pizmax);
if (h1 && opt.Contains("d")) {
opt.Remove(opt.First("d"),1);
TVirtualPad *padsav = gPad;
TVirtualPad *pad = gROOT->GetSelectedPad();
if (pad) pad->cd();
if (!gPad->FindObject(h1)) {
h1->Draw(opt);
} else {
h1->Paint(opt);
}
if (padsav) padsav->cd();
}
return h1;
}
TH1D *TH3::ProjectionY(const char *name, Int_t ixmin, Int_t ixmax, Int_t izmin, Int_t izmax, Option_t *option) const
{
TString opt = option;
opt.ToLower();
Int_t pixmin = GetXaxis()->GetFirst();
Int_t pixmax = GetXaxis()->GetLast();
Int_t pizmin = GetZaxis()->GetFirst();
Int_t pizmax = GetZaxis()->GetLast();
GetXaxis()->SetRange(ixmin,ixmax);
GetZaxis()->SetRange(izmin,izmax);
if (ixmin == 1 && ixmax == GetNbinsX() ) GetXaxis()->SetBit(TAxis::kAxisRange);
if (izmin == 1 && izmax == GetNbinsZ() ) GetZaxis()->SetBit(TAxis::kAxisRange);
Bool_t useUF = (ixmin == 0 || izmin == 0);
Bool_t useOF = ( (ixmax < 0 ) || (ixmax > GetNbinsX() ) || (izmax < 0) || (izmax > GetNbinsZ() ) );
Bool_t computeErrors = GetSumw2N();
if (opt.Contains("e") ) {
computeErrors = kTRUE;
opt.Remove(opt.First("e"),1);
}
Bool_t originalRange = kFALSE;
if (opt.Contains('o') ) {
originalRange = kTRUE;
opt.Remove(opt.First("o"),1);
}
TH1D * h1 = DoProject1D(name, GetTitle(), this->GetYaxis(), computeErrors, originalRange, useUF, useOF);
GetXaxis()->SetRange(pixmin,pixmax);
GetZaxis()->SetRange(pizmin,pizmax);
if (h1 && opt.Contains("d")) {
opt.Remove(opt.First("d"),1);
TVirtualPad *padsav = gPad;
TVirtualPad *pad = gROOT->GetSelectedPad();
if (pad) pad->cd();
if (!gPad->FindObject(h1)) {
h1->Draw(opt);
} else {
h1->Paint(opt);
}
if (padsav) padsav->cd();
}
return h1;
}
TH1D *TH3::ProjectionZ(const char *name, Int_t ixmin, Int_t ixmax, Int_t iymin, Int_t iymax, Option_t *option) const
{
TString opt = option;
opt.ToLower();
Int_t pixmin = GetXaxis()->GetFirst();
Int_t pixmax = GetXaxis()->GetLast();
Int_t piymin = GetYaxis()->GetFirst();
Int_t piymax = GetYaxis()->GetLast();
GetXaxis()->SetRange(ixmin,ixmax);
GetYaxis()->SetRange(iymin,iymax);
if (ixmin == 1 && ixmax == GetNbinsX() ) GetXaxis()->SetBit(TAxis::kAxisRange);
if (iymin == 1 && iymax == GetNbinsY() ) GetYaxis()->SetBit(TAxis::kAxisRange);
Bool_t useUF = (ixmin == 0 || iymin == 0);
Bool_t useOF = ( (ixmax < 0 ) || (ixmax > GetNbinsX() ) || (iymax < 0) || (iymax > GetNbinsY() ) );
Bool_t computeErrors = GetSumw2N();
if (opt.Contains("e") ) {
computeErrors = kTRUE;
opt.Remove(opt.First("e"),1);
}
Bool_t originalRange = kFALSE;
if (opt.Contains('o') ) {
originalRange = kTRUE;
opt.Remove(opt.First("o"),1);
}
TH1D * h1 = DoProject1D(name, GetTitle(), this->GetZaxis(), computeErrors, originalRange, useUF, useOF);
GetXaxis()->SetRange(pixmin,pixmax);
GetYaxis()->SetRange(piymin,piymax);
if (h1 && opt.Contains("d")) {
opt.Remove(opt.First("d"),1);
TVirtualPad *padsav = gPad;
TVirtualPad *pad = gROOT->GetSelectedPad();
if (pad) pad->cd();
if (!gPad->FindObject(h1)) {
h1->Draw(opt);
} else {
h1->Paint(opt);
}
if (padsav) padsav->cd();
}
return h1;
}
TH1D *TH3::DoProject1D(const char* name, const char* title, TAxis* projX,
bool computeErrors, bool originalRange,
bool useUF, bool useOF) const
{
TH1D *h1 = 0;
Int_t ixmin = projX->GetFirst();
Int_t ixmax = projX->GetLast();
if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
Int_t nx = ixmax-ixmin+1;
TObject *h1obj = gROOT->FindObject(name);
if (h1obj && h1obj->InheritsFrom(TH1::Class())) {
if (h1obj->IsA() != TH1D::Class() ) {
Error("DoProject1D","Histogram with name %s must be a TH1D and is a %s",name,h1obj->ClassName());
return 0;
}
h1 = (TH1D*)h1obj;
bool useAllBins = (nx == projX->GetNbins() );
if (useAllBins && CheckEqualAxes( projX, h1->GetXaxis() ) ) {
originalRange = kTRUE;
h1->Reset();
}
else if ( !useAllBins &&
CheckConsistentSubAxes(projX, ixmin, ixmax, h1->GetXaxis() ) ) {
h1->Reset();
}
else {
Error("DoProject1D","Histogram with name %s already exists and it is not compatible",name);
return 0;
}
}
if (!h1) {
const TArrayD *bins = projX->GetXbins();
if ( originalRange )
{
if (bins->fN == 0) {
h1 = new TH1D(name,title,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
} else {
h1 = new TH1D(name,title,projX->GetNbins(),bins->fArray);
}
} else {
if (bins->fN == 0) {
h1 = new TH1D(name,title,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
} else {
h1 = new TH1D(name,title,nx,&bins->fArray[ixmin-1]);
}
}
}
h1->GetXaxis()->ImportAttributes(projX);
THashList* labels = projX->GetLabels();
if (labels) {
TIter iL(labels);
TObjString* lb;
Int_t i = 1;
while ((lb=(TObjString*)iL())) {
h1->GetXaxis()->SetBinLabel(i,lb->String().Data());
i++;
}
}
h1->SetLineColor(this->GetLineColor());
h1->SetFillColor(this->GetFillColor());
h1->SetMarkerColor(this->GetMarkerColor());
h1->SetMarkerStyle(this->GetMarkerStyle());
if ( computeErrors ) h1->Sumw2();
TAxis* out1 = 0;
TAxis* out2 = 0;
if ( projX == GetXaxis() ) {
out1 = GetYaxis();
out2 = GetZaxis();
} else if ( projX == GetYaxis() ) {
out1 = GetZaxis();
out2 = GetXaxis();
} else {
out1 = GetYaxis();
out2 = GetXaxis();
}
Int_t *refX = 0, *refY = 0, *refZ = 0;
Int_t ixbin, out1bin, out2bin;
if ( projX == GetXaxis() ) { refX = &ixbin; refY = &out1bin; refZ = &out2bin; }
if ( projX == GetYaxis() ) { refX = &out2bin; refY = &ixbin; refZ = &out1bin; }
if ( projX == GetZaxis() ) { refX = &out2bin; refY = &out1bin; refZ = &ixbin; }
R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
Double_t totcont = 0;
Int_t out1min = out1->GetFirst();
Int_t out1max = out1->GetLast();
if (out1min == 0 && out1max == 0) { out1min = 1; out1max = out1->GetNbins(); }
if (useUF && !out1->TestBit(TAxis::kAxisRange) ) out1min -= 1;
if (useOF && !out1->TestBit(TAxis::kAxisRange) ) out1max += 1;
Int_t out2min = out2->GetFirst();
Int_t out2max = out2->GetLast();
if (out2min == 0 && out2max == 0) { out2min = 1; out2max = out2->GetNbins(); }
if (useUF && !out2->TestBit(TAxis::kAxisRange) ) out2min -= 1;
if (useOF && !out2->TestBit(TAxis::kAxisRange) ) out2max += 1;
for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
Double_t cont = 0;
Double_t err2 = 0;
for (out1bin = out1min; out1bin <= out1max; out1bin++){
for (out2bin = out2min; out2bin <= out2max; out2bin++){
Int_t bin = GetBin(*refX, *refY, *refZ);
cont += GetBinContent(bin);
if (computeErrors) {
Double_t exyz = GetBinError(bin);
err2 += exyz*exyz;
}
}
}
Int_t ix = h1->FindBin( projX->GetBinCenter(ixbin) );
h1->SetBinContent(ix ,cont);
if (computeErrors) h1->SetBinError(ix, TMath::Sqrt(err2) );
totcont += cont;
}
bool resetStats = true;
double eps = 1.E-12;
if (IsA() == TH3F::Class() ) eps = 1.E-6;
if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
bool resetEntries = resetStats;
resetEntries |= !useUF || !useOF;
if (!resetStats) {
Double_t stats[kNstat];
GetStats(stats);
if ( projX == GetYaxis() ) {
stats[2] = stats[4];
stats[3] = stats[5];
}
else if ( projX == GetZaxis() ) {
stats[2] = stats[7];
stats[3] = stats[8];
}
h1->PutStats(stats);
}
else {
h1->ResetStats();
}
if (resetEntries) {
Double_t entries = TMath::Floor( totcont + 0.5);
if (computeErrors) entries = h1->GetEffectiveEntries();
h1->SetEntries( entries );
}
else {
h1->SetEntries( fEntries );
}
return h1;
}
TH2D *TH3::DoProject2D(const char* name, const char * title, TAxis* projX, TAxis* projY,
bool computeErrors, bool originalRange,
bool useUF, bool useOF) const
{
TH2D *h2 = 0;
Int_t ixmin = projX->GetFirst();
Int_t ixmax = projX->GetLast();
Int_t iymin = projY->GetFirst();
Int_t iymax = projY->GetLast();
if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
if (iymin == 0 && iymax == 0) { iymin = 1; iymax = projY->GetNbins(); }
Int_t nx = ixmax-ixmin+1;
Int_t ny = iymax-iymin+1;
TObject *h2obj = gROOT->FindObject(name);
if (h2obj && h2obj->InheritsFrom(TH1::Class())) {
if ( h2obj->IsA() != TH2D::Class() ) {
Error("DoProject2D","Histogram with name %s must be a TH2D and is a %s",name,h2obj->ClassName());
return 0;
}
h2 = (TH2D*)h2obj;
bool useAllBins = ((nx == projX->GetNbins() ) && (ny == projY->GetNbins() ) );
if (useAllBins && CheckEqualAxes(projY, h2->GetXaxis() ) &&
CheckEqualAxes(projX, h2->GetYaxis() ) ) {
originalRange = kTRUE;
h2->Reset();
}
else if ( !useAllBins &&
CheckConsistentSubAxes(projY, iymin, iymax, h2->GetXaxis() ) &&
CheckConsistentSubAxes(projX, ixmin, ixmax, h2->GetYaxis() ) ) {
h2->Reset();
}
else {
Error("DoProject2D","Histogram with name %s already exists and it is not compatible",name);
return 0;
}
}
if (!h2) {
const TArrayD *xbins = projX->GetXbins();
const TArrayD *ybins = projY->GetXbins();
if ( originalRange )
{
if (xbins->fN == 0 && ybins->fN == 0) {
h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
} else if (ybins->fN == 0) {
h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
,projX->GetNbins(),&xbins->fArray[ixmin-1]);
} else if (xbins->fN == 0) {
h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
} else {
h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
}
} else {
if (xbins->fN == 0 && ybins->fN == 0) {
h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
} else if (ybins->fN == 0) {
h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
,nx,&xbins->fArray[ixmin-1]);
} else if (xbins->fN == 0) {
h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1]
,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
} else {
h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
}
}
}
THashList* labels1 = 0;
THashList* labels2 = 0;
h2->GetXaxis()->ImportAttributes(projY);
h2->GetYaxis()->ImportAttributes(projX);
labels1 = projY->GetLabels();
labels2 = projX->GetLabels();
if (labels1) {
TIter iL(labels1);
TObjString* lb;
Int_t i = 1;
while ((lb=(TObjString*)iL())) {
h2->GetXaxis()->SetBinLabel(i,lb->String().Data());
i++;
}
}
if (labels2) {
TIter iL(labels2);
TObjString* lb;
Int_t i = 1;
while ((lb=(TObjString*)iL())) {
h2->GetYaxis()->SetBinLabel(i,lb->String().Data());
i++;
}
}
h2->SetLineColor(this->GetLineColor());
h2->SetFillColor(this->GetFillColor());
h2->SetMarkerColor(this->GetMarkerColor());
h2->SetMarkerStyle(this->GetMarkerStyle());
if ( computeErrors) h2->Sumw2();
TAxis* out = 0;
if ( projX != GetXaxis() && projY != GetXaxis() ) {
out = GetXaxis();
} else if ( projX != GetYaxis() && projY != GetYaxis() ) {
out = GetYaxis();
} else {
out = GetZaxis();
}
Int_t *refX = 0, *refY = 0, *refZ = 0;
Int_t ixbin, iybin, outbin;
if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
Double_t totcont = 0;
Int_t outmin = out->GetFirst();
Int_t outmax = out->GetLast();
if (outmin == 0 && outmax == 0) { outmin = 1; outmax = out->GetNbins(); }
if (useUF && !out->TestBit(TAxis::kAxisRange) ) outmin -= 1;
if (useOF && !out->TestBit(TAxis::kAxisRange) ) outmax += 1;
for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
Int_t ix = h2->GetYaxis()->FindBin( projX->GetBinCenter(ixbin) );
for (iybin=0;iybin<=1+projY->GetNbins();iybin++){
if ( projY->TestBit(TAxis::kAxisRange) && ( iybin < iymin || iybin > iymax )) continue;
Int_t iy = h2->GetXaxis()->FindBin( projY->GetBinCenter(iybin) );
Double_t cont = 0;
Double_t err2 = 0;
for (outbin = outmin; outbin <= outmax; outbin++){
Int_t bin = GetBin(*refX,*refY,*refZ);
cont += GetBinContent(bin);
if (computeErrors) {
Double_t exyz = GetBinError(bin);
err2 += exyz*exyz;
}
}
h2->SetBinContent(iy , ix, cont);
if (computeErrors) h2->SetBinError(iy, ix, TMath::Sqrt(err2) );
totcont += cont;
}
}
bool resetStats = true;
double eps = 1.E-12;
if (IsA() == TH3F::Class() ) eps = 1.E-6;
if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
bool resetEntries = resetStats;
resetEntries |= !useUF || !useOF;
if (!resetStats) {
Double_t stats[kNstat];
Double_t oldst[kNstat];
for (Int_t i = 0; i < kNstat; ++i) { oldst[i] = 0; }
GetStats(oldst);
std::copy(oldst,oldst+kNstat,stats);
if ( projY == GetXaxis() && projX == GetZaxis() ) {
stats[4] = oldst[7];
stats[5] = oldst[8];
stats[6] = oldst[9];
}
if ( projY == GetYaxis() ) {
stats[2] = oldst[4];
stats[3] = oldst[5];
if ( projX == GetXaxis() ) {
stats[4] = oldst[2];
stats[5] = oldst[3];
}
if ( projX == GetZaxis() ) {
stats[4] = oldst[7];
stats[5] = oldst[8];
stats[6] = oldst[10];
}
}
else if ( projY == GetZaxis() ) {
stats[2] = oldst[7];
stats[3] = oldst[8];
if ( projX == GetXaxis() ) {
stats[4] = oldst[2];
stats[5] = oldst[3];
stats[6] = oldst[9];
}
if ( projX == GetZaxis() ) {
stats[4] = oldst[4];
stats[5] = oldst[5];
stats[6] = oldst[10];
}
}
h2->PutStats(stats);
}
else {
h2->ResetStats();
}
if (resetEntries) {
Double_t entries = h2->GetEffectiveEntries();
if (!computeErrors) entries = TMath::Floor( entries + 0.5);
h2->SetEntries( entries );
}
else {
h2->SetEntries( fEntries );
}
return h2;
}
TH1 *TH3::Project3D(Option_t *option) const
{
TString opt = option; opt.ToLower();
Int_t pcase = 0;
TString ptype;
if (opt.Contains("x")) { pcase = 1; ptype = "x"; }
if (opt.Contains("y")) { pcase = 2; ptype = "y"; }
if (opt.Contains("z")) { pcase = 3; ptype = "z"; }
if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
if (pcase == 0) {
Error("Project3D","No projection axis specified - return a NULL pointer");
return 0;
}
Bool_t computeErrors = GetSumw2N();
if (opt.Contains("e") ) {
computeErrors = kTRUE;
opt.Remove(opt.First("e"),1);
}
Bool_t useUF = kTRUE;
Bool_t useOF = kTRUE;
if (opt.Contains("nuf") ) {
useUF = kFALSE;
opt.Remove(opt.Index("nuf"),3);
}
if (opt.Contains("nof") ) {
useOF = kFALSE;
opt.Remove(opt.Index("nof"),3);
}
Bool_t originalRange = kFALSE;
if (opt.Contains('o') ) {
originalRange = kTRUE;
opt.Remove(opt.First("o"),1);
}
TH1 *h = 0;
TString name = GetName();
TString title = GetTitle();
name += "_"; name += opt;
title += " "; title += ptype; title += " projection";
switch (pcase) {
case 1:
h = DoProject1D(name, title, this->GetXaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 2:
h = DoProject1D(name, title, this->GetYaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 3:
h = DoProject1D(name, title, this->GetZaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 4:
h = DoProject2D(name, title, this->GetXaxis(),this->GetYaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 5:
h = DoProject2D(name, title, this->GetYaxis(),this->GetXaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 6:
h = DoProject2D(name, title, this->GetXaxis(),this->GetZaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 7:
h = DoProject2D(name, title, this->GetZaxis(),this->GetXaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 8:
h = DoProject2D(name, title, this->GetYaxis(),this->GetZaxis(),
computeErrors, originalRange, useUF, useOF);
break;
case 9:
h = DoProject2D(name, title, this->GetZaxis(),this->GetYaxis(),
computeErrors, originalRange, useUF, useOF);
break;
}
if (h && opt.Contains("d")) {
opt.Remove(opt.First("d"),1);
TVirtualPad *padsav = gPad;
TVirtualPad *pad = gROOT->GetSelectedPad();
if (pad) pad->cd();
if (!gPad->FindObject(h)) {
h->Draw(opt);
} else {
h->Paint(opt);
}
if (padsav) padsav->cd();
}
return h;
}
void TH3::DoFillProfileProjection(TProfile2D * p2, const TAxis & a1, const TAxis & a2, const TAxis & a3, Int_t bin1, Int_t bin2, Int_t bin3, Int_t inBin, Bool_t useWeights ) const {
Double_t cont = GetBinContent(inBin);
if (!cont) return;
TArrayD & binSumw2 = *(p2->GetBinSumw2());
if (useWeights && binSumw2.fN <= 0) useWeights = false;
Double_t u = a1.GetBinCenter(bin1);
Double_t v = a2.GetBinCenter(bin2);
Double_t w = a3.GetBinCenter(bin3);
Int_t outBin = p2->FindBin(u, v);
if (outBin <0) return;
Double_t tmp = 0;
if ( useWeights ) tmp = binSumw2.fArray[outBin];
p2->Fill( u , v, w, cont);
if (useWeights ) binSumw2.fArray[outBin] = tmp + fSumw2.fArray[inBin];
}
TProfile2D *TH3::DoProjectProfile2D(const char* name, const char * title, TAxis* projX, TAxis* projY,
bool originalRange, bool useUF, bool useOF) const
{
Int_t ixmin = projX->GetFirst();
Int_t ixmax = projX->GetLast();
Int_t iymin = projY->GetFirst();
Int_t iymax = projY->GetLast();
if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
if (iymin == 0 && iymax == 0) { iymin = 1; iymax = projY->GetNbins(); }
Int_t nx = ixmax-ixmin+1;
Int_t ny = iymax-iymin+1;
TProfile2D *p2 = 0;
TObject *p2obj = gROOT->FindObject(name);
if (p2obj && p2obj->InheritsFrom(TH1::Class())) {
if (p2obj->IsA() != TProfile2D::Class() ) {
Error("DoProjectProfile2D","Histogram with name %s must be a TProfile2D and is a %s",name,p2obj->ClassName());
return 0;
}
p2 = (TProfile2D*)p2obj;
bool useAllBins = ((nx == projX->GetNbins() ) && (ny == projY->GetNbins() ) );
if (useAllBins && CheckEqualAxes( projY, p2->GetXaxis() ) &&
CheckEqualAxes( projX, p2->GetYaxis() ) ) {
originalRange = kTRUE;
p2->Reset();
}
else if ( !useAllBins &&
CheckConsistentSubAxes(projY, iymin, iymax, p2->GetXaxis() ) &&
CheckConsistentSubAxes(projX, ixmin, ixmax, p2->GetYaxis() ) ) {
p2->Reset();
}
else {
p2->Dump();
projY->Dump(); projX->Dump();
std::cout << ny << " " << iymin << " , " << iymax << " nx " << nx << " " << ixmin << " , " << ixmax << std::endl;
Error("DoProjectProfile2D","Profile2D with name %s already exists and it is not compatible",name);
return 0;
}
}
if (!p2) {
const TArrayD *xbins = projX->GetXbins();
const TArrayD *ybins = projY->GetXbins();
if ( originalRange ) {
if (xbins->fN == 0 && ybins->fN == 0) {
p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
} else if (ybins->fN == 0) {
p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
,projX->GetNbins(),&xbins->fArray[ixmin-1]);
} else if (xbins->fN == 0) {
p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
} else {
p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
}
} else {
if (xbins->fN == 0 && ybins->fN == 0) {
p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
} else if (ybins->fN == 0) {
p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
,nx,&xbins->fArray[ixmin-1]);
} else if (xbins->fN == 0) {
p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1]
,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
} else {
p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
}
}
}
TAxis* outAxis = 0;
if ( projX != GetXaxis() && projY != GetXaxis() ) {
outAxis = GetXaxis();
} else if ( projX != GetYaxis() && projY != GetYaxis() ) {
outAxis = GetYaxis();
} else {
outAxis = GetZaxis();
}
bool useWeights = (GetSumw2N() > 0);
if (useWeights ) p2->Sumw2();
Int_t *refX = 0, *refY = 0, *refZ = 0;
Int_t ixbin, iybin, outbin;
if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
Int_t outmin = outAxis->GetFirst();
Int_t outmax = outAxis->GetLast();
if (outmin == 0 && outmax == 0) { outmin = 1; outmax = outAxis->GetNbins(); }
if (useUF && !outAxis->TestBit(TAxis::kAxisRange) ) outmin -= 1;
if (useOF && !outAxis->TestBit(TAxis::kAxisRange) ) outmax += 1;
TArrayD & binSumw2 = *(p2->GetBinSumw2());
if (useWeights && binSumw2.fN <= 0) useWeights = false;
for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
if ( (ixbin < ixmin || ixbin > ixmax) && projX->TestBit(TAxis::kAxisRange)) continue;
for ( iybin=0;iybin<=1+projY->GetNbins();iybin++){
if ( (iybin < iymin || iybin > iymax) && projX->TestBit(TAxis::kAxisRange)) continue;
Int_t poutBin = p2->FindBin(projY->GetBinCenter(iybin), projX->GetBinCenter(ixbin));
if (poutBin <0) continue;
for (outbin = outmin; outbin <= outmax; outbin++){
Int_t bin = GetBin(*refX,*refY,*refZ);
Double_t cont = GetBinContent(bin);
if (!cont) continue;
Double_t tmp = 0;
if ( useWeights ) tmp = binSumw2.fArray[poutBin];
p2->Fill( projY->GetBinCenter(iybin) , projX->GetBinCenter(ixbin), outAxis->GetBinCenter(outbin), cont);
if (useWeights ) binSumw2.fArray[poutBin] = tmp + fSumw2.fArray[bin];
}
}
}
bool resetStats = true;
Double_t stats[kNstat];
if (resetStats)
for (Int_t i=0;i<kNstat;i++) stats[i] = 0;
p2->PutStats(stats);
Double_t entries = fEntries;
if (resetStats) {
entries = p2->GetEffectiveEntries();
if (!useWeights) entries = TMath::Floor( entries + 0.5);
p2->SetEntries( entries );
}
p2->SetEntries(entries);
return p2;
}
TProfile2D *TH3::Project3DProfile(Option_t *option) const
{
TString opt = option; opt.ToLower();
Int_t pcase = 0;
TString ptype;
if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
if (pcase == 0) {
Error("Project3D","No projection axis specified - return a NULL pointer");
return 0;
}
Bool_t useUF = kFALSE;
if (opt.Contains("uf") ) {
useUF = kTRUE;
opt.Remove(opt.Index("uf"),2);
}
Bool_t useOF = kFALSE;
if (opt.Contains("of") ) {
useOF = kTRUE;
opt.Remove(opt.Index("of"),2);
}
Bool_t originalRange = kFALSE;
if (opt.Contains('o') ) {
originalRange = kTRUE;
opt.Remove(opt.First("o"),1);
}
TProfile2D *p2 = 0;
TString name = GetName();
TString title = GetTitle();
name += "_"; name += opt;
title += " "; title += ptype; title += " projection";
switch (pcase) {
case 4:
p2 = DoProjectProfile2D(name, title, GetXaxis(), GetYaxis(), originalRange, useUF, useOF);
break;
case 5:
p2 = DoProjectProfile2D(name, title, GetYaxis(), GetXaxis(), originalRange, useUF, useOF);
break;
case 6:
p2 = DoProjectProfile2D(name, title, GetXaxis(), GetZaxis(), originalRange, useUF, useOF);
break;
case 7:
p2 = DoProjectProfile2D(name, title, GetZaxis(), GetXaxis(), originalRange, useUF, useOF);
break;
case 8:
p2 = DoProjectProfile2D(name, title, GetYaxis(), GetZaxis(), originalRange, useUF, useOF);
break;
case 9:
p2 = DoProjectProfile2D(name, title, GetZaxis(), GetYaxis(), originalRange, useUF, useOF);
break;
}
return p2;
}
void TH3::PutStats(Double_t *stats)
{
TH1::PutStats(stats);
fTsumwy = stats[4];
fTsumwy2 = stats[5];
fTsumwxy = stats[6];
fTsumwz = stats[7];
fTsumwz2 = stats[8];
fTsumwxz = stats[9];
fTsumwyz = stats[10];
}
TH3 *TH3::RebinX(Int_t ngroup, const char *newname)
{
return Rebin3D(ngroup, 1, 1, newname);
}
TH3 *TH3::RebinY(Int_t ngroup, const char *newname)
{
return Rebin3D(1, ngroup, 1, newname);
}
TH3 *TH3::RebinZ(Int_t ngroup, const char *newname)
{
return Rebin3D(1, 1, ngroup, newname);
}
TH3 *TH3::Rebin3D(Int_t nxgroup, Int_t nygroup, Int_t nzgroup, const char *newname)
{
Int_t i,j,k,xbin,ybin,zbin;
Int_t nxbins = fXaxis.GetNbins();
Int_t nybins = fYaxis.GetNbins();
Int_t nzbins = fZaxis.GetNbins();
Double_t xmin = fXaxis.GetXmin();
Double_t xmax = fXaxis.GetXmax();
Double_t ymin = fYaxis.GetXmin();
Double_t ymax = fYaxis.GetXmax();
Double_t zmin = fZaxis.GetXmin();
Double_t zmax = fZaxis.GetXmax();
if ((nxgroup <= 0) || (nxgroup > nxbins)) {
Error("Rebin", "Illegal value of nxgroup=%d",nxgroup);
return 0;
}
if ((nygroup <= 0) || (nygroup > nybins)) {
Error("Rebin", "Illegal value of nygroup=%d",nygroup);
return 0;
}
if ((nzgroup <= 0) || (nzgroup > nzbins)) {
Error("Rebin", "Illegal value of nzgroup=%d",nzgroup);
return 0;
}
Int_t newxbins = nxbins/nxgroup;
Int_t newybins = nybins/nygroup;
Int_t newzbins = nzbins/nzgroup;
Double_t entries = fEntries;
Double_t *oldBins = new Double_t[fNcells];
for (Int_t ibin = 0; ibin < fNcells; ibin++) {
oldBins[ibin] = GetBinContent(ibin);
}
Double_t *oldSumw2 = 0;
if (fSumw2.fN != 0) {
oldSumw2 = new Double_t[fNcells];
for (Int_t ibin = 0; ibin < fNcells; ibin++) {
oldSumw2[ibin] = fSumw2.fArray[ibin];
}
}
TH3 *hnew = this;
if (newname && strlen(newname)) {
hnew = (TH3*)Clone();
hnew->SetName(newname);
}
Double_t stat[kNstat];
GetStats(stat);
bool resetStat = false;
if(newxbins*nxgroup != nxbins) {
xmax = fXaxis.GetBinUpEdge(newxbins*nxgroup);
resetStat = true;
}
if(newybins*nygroup != nybins) {
ymax = fYaxis.GetBinUpEdge(newybins*nygroup);
resetStat = true;
}
if(newzbins*nzgroup != nzbins) {
zmax = fZaxis.GetBinUpEdge(newzbins*nzgroup);
resetStat = true;
}
Int_t nXdivisions = fXaxis.GetNdivisions();
Color_t xAxisColor = fXaxis.GetAxisColor();
Color_t xLabelColor = fXaxis.GetLabelColor();
Style_t xLabelFont = fXaxis.GetLabelFont();
Float_t xLabelOffset = fXaxis.GetLabelOffset();
Float_t xLabelSize = fXaxis.GetLabelSize();
Float_t xTickLength = fXaxis.GetTickLength();
Float_t xTitleOffset = fXaxis.GetTitleOffset();
Float_t xTitleSize = fXaxis.GetTitleSize();
Color_t xTitleColor = fXaxis.GetTitleColor();
Style_t xTitleFont = fXaxis.GetTitleFont();
Int_t nYdivisions = fYaxis.GetNdivisions();
Color_t yAxisColor = fYaxis.GetAxisColor();
Color_t yLabelColor = fYaxis.GetLabelColor();
Style_t yLabelFont = fYaxis.GetLabelFont();
Float_t yLabelOffset = fYaxis.GetLabelOffset();
Float_t yLabelSize = fYaxis.GetLabelSize();
Float_t yTickLength = fYaxis.GetTickLength();
Float_t yTitleOffset = fYaxis.GetTitleOffset();
Float_t yTitleSize = fYaxis.GetTitleSize();
Color_t yTitleColor = fYaxis.GetTitleColor();
Style_t yTitleFont = fYaxis.GetTitleFont();
Int_t nZdivisions = fZaxis.GetNdivisions();
Color_t zAxisColor = fZaxis.GetAxisColor();
Color_t zLabelColor = fZaxis.GetLabelColor();
Style_t zLabelFont = fZaxis.GetLabelFont();
Float_t zLabelOffset = fZaxis.GetLabelOffset();
Float_t zLabelSize = fZaxis.GetLabelSize();
Float_t zTickLength = fZaxis.GetTickLength();
Float_t zTitleOffset = fZaxis.GetTitleOffset();
Float_t zTitleSize = fZaxis.GetTitleSize();
Color_t zTitleColor = fZaxis.GetTitleColor();
Style_t zTitleFont = fZaxis.GetTitleFont();
if (nxgroup != 1 || nygroup != 1 || nzgroup != 1) {
if(fXaxis.GetXbins()->GetSize() > 0 || fYaxis.GetXbins()->GetSize() > 0 || fZaxis.GetXbins()->GetSize() > 0){
Double_t *xbins = new Double_t[newxbins+1];
for(i = 0; i <= newxbins; ++i) xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
Double_t *ybins = new Double_t[newybins+1];
for(i = 0; i <= newybins; ++i) ybins[i] = fYaxis.GetBinLowEdge(1+i*nygroup);
Double_t *zbins = new Double_t[newzbins+1];
for(i = 0; i <= newzbins; ++i) zbins[i] = fZaxis.GetBinLowEdge(1+i*nzgroup);
hnew->SetBins(newxbins,xbins, newybins, ybins, newzbins, zbins);
delete [] xbins;
delete [] ybins;
delete [] zbins;
} else {
hnew->SetBins(newxbins, xmin, xmax, newybins, ymin, ymax, newzbins, zmin, zmax);
}
Double_t binContent, binSumw2;
Int_t oldxbin = 1;
Int_t oldybin = 1;
Int_t oldzbin = 1;
Int_t bin;
for (xbin = 1; xbin <= newxbins; xbin++) {
oldybin=1;
oldzbin=1;
for (ybin = 1; ybin <= newybins; ybin++) {
oldzbin=1;
for (zbin = 1; zbin <= newzbins; zbin++) {
binContent = 0;
binSumw2 = 0;
for (i = 0; i < nxgroup; i++) {
if (oldxbin+i > nxbins) break;
for (j =0; j < nygroup; j++) {
if (oldybin+j > nybins) break;
for (k =0; k < nzgroup; k++) {
if (oldzbin+k > nzbins) break;
bin = oldxbin + i + (oldybin + j)*(nxbins + 2) + (oldzbin + k)*(nxbins + 2)*(nybins + 2);
binContent += oldBins[bin];
if (oldSumw2) binSumw2 += oldSumw2[bin];
}
}
}
Int_t ibin = hnew->GetBin(xbin,ybin,zbin);
hnew->SetBinContent(ibin, binContent);
if (oldSumw2) hnew->fSumw2.fArray[ibin] = binSumw2;
oldzbin += nzgroup;
}
oldybin += nygroup;
}
oldxbin += nxgroup;
}
for (Int_t xover = 0; xover <= 1; xover++) {
for (Int_t yover = 0; yover <= 1; yover++) {
for (Int_t zover = 0; zover <= 1; zover++) {
binContent = 0;
binSumw2 = 0;
for(xbin = xover*oldxbin; xbin <= xover*(nxbins+1); xbin++) {
for(ybin = yover*oldybin; ybin <= yover*(nybins+1); ybin++){
for(zbin = zover*oldzbin; zbin <= zover*(nzbins+1); zbin++){
bin = GetBin(xbin,ybin,zbin);
binContent += oldBins[bin];
if(oldSumw2) binSumw2 += oldSumw2[bin];
}
}
}
Int_t binNew = hnew->GetBin( xover *(newxbins+1),
yover*(newybins+1), zover*(newzbins+1) );
hnew->SetBinContent(binNew,binContent);
if (oldSumw2) hnew->fSumw2.fArray[binNew] = binSumw2;
}
}
}
Double_t binContent0, binContent2, binContent3, binContent4;
Double_t binError0, binError2, binError3, binError4;
Int_t oldxbin2, oldybin2, oldzbin2;
Int_t ufbin, ofbin, ofbin2, ofbin3, ofbin4;
oldxbin2 = 1;
oldybin2 = 1;
oldzbin2 = 1;
for (xbin = 1; xbin<=newxbins; xbin++) {
oldzbin2 = 1;
for (zbin = 1; zbin<=newzbins; zbin++) {
binContent0 = binContent2 = 0;
binError0 = binError2 = 0;
for (i=0; i<nxgroup; i++) {
if (oldxbin2+i > nxbins) break;
for (k=0; k<nzgroup; k++) {
if (oldzbin2+k > nzbins) break;
ufbin = oldxbin2 + i + (nxbins+2)*(nybins+2)*(oldzbin2+k);
binContent0 += oldBins[ufbin];
if(oldSumw2) binError0 += oldSumw2[ufbin];
for(ybin = oldybin; ybin <= nybins + 1; ybin++){
ofbin = ufbin + ybin*(nxbins+2);
binContent2 += oldBins[ofbin];
if(oldSumw2) binError2 += oldSumw2[ofbin];
}
}
}
hnew->SetBinContent(xbin,0,zbin,binContent0);
hnew->SetBinContent(xbin,newybins+1,zbin,binContent2);
if (oldSumw2) {
hnew->SetBinError(xbin,0,zbin,TMath::Sqrt(binError0));
hnew->SetBinError(xbin,newybins+1,zbin,TMath::Sqrt(binError2) );
}
oldzbin2 += nzgroup;
}
oldxbin2 += nxgroup;
}
oldxbin2 = 1;
oldybin2 = 1;
oldzbin2 = 1;
for (ybin = 1; ybin<=newybins; ybin++) {
oldzbin2 = 1;
for (zbin = 1; zbin<=newzbins; zbin++) {
binContent0 = binContent2 = 0;
binError0 = binError2 = 0;
for (j=0; j<nygroup; j++) {
if (oldybin2+j > nybins) break;
for (k=0; k<nzgroup; k++) {
if (oldzbin2+k > nzbins) break;
ufbin = (oldybin2 + j)*(nxbins+2) + (nxbins+2)*(nybins+2)*(oldzbin2+k);
binContent0 += oldBins[ufbin];
if(oldSumw2) binError0 += oldSumw2[ufbin];
for(xbin = oldxbin; xbin <= nxbins + 1; xbin++){
ofbin = ufbin + xbin;
binContent2 += oldBins[ofbin];
if(oldSumw2) binError2 += oldSumw2[ofbin];
}
}
}
hnew->SetBinContent(0,ybin,zbin,binContent0);
hnew->SetBinContent(newxbins+1,ybin,zbin,binContent2);
if (oldSumw2) {
hnew->SetBinError(0,ybin,zbin,TMath::Sqrt(binError0));
hnew->SetBinError(newxbins+1,ybin,zbin,TMath::Sqrt(binError2) );
}
oldzbin2 += nzgroup;
}
oldybin2 += nygroup;
}
oldxbin2 = 1;
oldybin2 = 1;
oldzbin2 = 1;
for (xbin = 1; xbin<=newxbins; xbin++) {
oldybin2 = 1;
for (ybin = 1; ybin<=newybins; ybin++) {
binContent0 = binContent2 = 0;
binError0 = binError2 = 0;
for (i=0; i<nxgroup; i++) {
if (oldxbin2+i > nxbins) break;
for (j=0; j<nygroup; j++) {
if (oldybin2+j > nybins) break;
ufbin = oldxbin2 + i + (nxbins+2)*(oldybin2+j);
binContent0 += oldBins[ufbin];
if(oldSumw2) binError0 += oldSumw2[ufbin];
for(zbin = oldzbin; zbin <= nzbins + 1; zbin++){
ofbin = ufbin + (nxbins+2)*(nybins+2)*zbin;
binContent2 += oldBins[ofbin];
if(oldSumw2) binError2 += oldSumw2[ofbin];
}
}
}
hnew->SetBinContent(xbin,ybin,0,binContent0);
hnew->SetBinContent(xbin,ybin,newzbins+1,binContent2);
if (oldSumw2) {
hnew->SetBinError(xbin,ybin,0,TMath::Sqrt(binError0));
hnew->SetBinError(xbin,ybin,newzbins+1,TMath::Sqrt(binError2) );
}
oldybin2 += nygroup;
}
oldxbin2 += nxgroup;
}
oldxbin2 = 1;
oldybin2 = 1;
oldzbin2 = 1;
for (xbin = 1; xbin<=newxbins; xbin++) {
binContent0 = 0;
binContent2 = 0;
binContent3 = 0;
binContent4 = 0;
binError0 = 0;
binError2 = 0;
binError3 = 0;
binError4 = 0;
for (i=0; i<nxgroup; i++) {
if (oldxbin2+i > nxbins) break;
ufbin = oldxbin2 + i;
binContent0 += oldBins[ufbin];
if(oldSumw2) binError0 += oldSumw2[ufbin];
for(ybin = oldybin; ybin <= nybins + 1; ybin++){
ofbin3 = ufbin+ybin*(nxbins+2);
binContent3 += oldBins[ ofbin3 ];
if (oldSumw2) binError3 += oldSumw2[ofbin3];
for(zbin = oldzbin; zbin <= nzbins + 1; zbin++){
ofbin4 = oldxbin2 + i + ybin*(nxbins+2) + (nxbins+2)*(nybins+2)*zbin;
binContent4 += oldBins[ofbin4];
if(oldSumw2) binError4 += oldSumw2[ofbin4];
}
}
for(zbin = oldzbin; zbin <= nzbins + 1; zbin++){
ofbin2 = ufbin+zbin*(nxbins+2)*(nybins+2);
binContent2 += oldBins[ ofbin2 ];
if (oldSumw2) binError2 += oldSumw2[ofbin2];
}
}
hnew->SetBinContent(xbin,0,0,binContent0);
hnew->SetBinContent(xbin,0,newzbins+1,binContent2);
hnew->SetBinContent(xbin,newybins+1,0,binContent3);
hnew->SetBinContent(xbin,newybins+1,newzbins+1,binContent4);
if (oldSumw2) {
hnew->SetBinError(xbin,0,0,TMath::Sqrt(binError0));
hnew->SetBinError(xbin,0,newzbins+1,TMath::Sqrt(binError2) );
hnew->SetBinError(xbin,newybins+1,0,TMath::Sqrt(binError3) );
hnew->SetBinError(xbin,newybins+1,newzbins+1,TMath::Sqrt(binError4) );
}
oldxbin2 += nxgroup;
}
oldxbin2 = 1;
oldybin2 = 1;
oldzbin2 = 1;
for (zbin = 1; zbin<=newzbins; zbin++) {
binContent0 = 0;
binContent2 = 0;
binContent3 = 0;
binContent4 = 0;
binError0 = 0;
binError2 = 0;
binError3 = 0;
binError4 = 0;
for (i=0; i<nzgroup; i++) {
if (oldzbin2+i > nzbins) break;
ufbin = (oldzbin2 + i)*(nxbins+2)*(nybins+2);
binContent0 += oldBins[ufbin];
if(oldSumw2) binError0 += oldSumw2[ufbin];
for(ybin = oldybin; ybin <= nybins + 1; ybin++){
ofbin3 = ufbin+ybin*(nxbins+2);
binContent3 += oldBins[ ofbin3 ];
if (oldSumw2) binError3 += oldSumw2[ofbin3];
for(xbin = oldxbin; xbin <= nxbins + 1; xbin++){
ofbin4 = ufbin + xbin + ybin*(nxbins+2);
binContent4 += oldBins[ofbin4];
if(oldSumw2) binError4 += oldSumw2[ofbin4];
}
}
for(xbin = oldxbin; xbin <= nxbins + 1; xbin++){
ofbin2 = xbin +(oldzbin2+i)*(nxbins+2)*(nybins+2);
binContent2 += oldBins[ ofbin2 ];
if (oldSumw2) binError2 += oldSumw2[ofbin2];
}
}
hnew->SetBinContent(0,0,zbin,binContent0);
hnew->SetBinContent(0,newybins+1,zbin,binContent3);
hnew->SetBinContent(newxbins+1,0,zbin,binContent2);
hnew->SetBinContent(newxbins+1,newybins+1,zbin,binContent4);
if (oldSumw2) {
hnew->SetBinError(0,0,zbin,TMath::Sqrt(binError0));
hnew->SetBinError(0,newybins+1,zbin,TMath::Sqrt(binError3) );
hnew->SetBinError(newxbins+1,0,zbin,TMath::Sqrt(binError2) );
hnew->SetBinError(newxbins+1,newybins+1,zbin,TMath::Sqrt(binError4) );
}
oldzbin2 += nzgroup;
}
oldxbin2 = 1;
oldybin2 = 1;
oldzbin2 = 1;
for (ybin = 1; ybin<=newybins; ybin++) {
binContent0 = 0;
binContent2 = 0;
binContent3 = 0;
binContent4 = 0;
binError0 = 0;
binError2 = 0;
binError3 = 0;
binError4 = 0;
for (i=0; i<nygroup; i++) {
if (oldybin2+i > nybins) break;
ufbin = (oldybin2 + i)*(nxbins+2);
binContent0 += oldBins[ufbin];
if(oldSumw2) binError0 += oldSumw2[ufbin];
for(xbin = oldxbin; xbin <= nxbins + 1; xbin++){
ofbin3 = ufbin+xbin;
binContent3 += oldBins[ ofbin3 ];
if (oldSumw2) binError3 += oldSumw2[ofbin3];
for(zbin = oldzbin; zbin <= nzbins + 1; zbin++){
ofbin4 = xbin + (nxbins+2)*(nybins+2)*zbin+(oldybin2+i)*(nxbins+2);
binContent4 += oldBins[ofbin4];
if(oldSumw2) binError4 += oldSumw2[ofbin4];
}
}
for(zbin = oldzbin; zbin <= nzbins + 1; zbin++){
ofbin2 = (oldybin2+i)*(nxbins+2)+zbin*(nxbins+2)*(nybins+2);
binContent2 += oldBins[ ofbin2 ];
if (oldSumw2) binError2 += oldSumw2[ofbin2];
}
}
hnew->SetBinContent(0,ybin,0,binContent0);
hnew->SetBinContent(0,ybin,newzbins+1,binContent2);
hnew->SetBinContent(newxbins+1,ybin,0,binContent3);
hnew->SetBinContent(newxbins+1,ybin,newzbins+1,binContent4);
if (oldSumw2) {
hnew->SetBinError(0,ybin,0,TMath::Sqrt(binError0));
hnew->SetBinError(0,ybin,newzbins+1,TMath::Sqrt(binError2) );
hnew->SetBinError(newxbins+1,ybin,0,TMath::Sqrt(binError3) );
hnew->SetBinError(newxbins+1,ybin,newzbins+1,TMath::Sqrt(binError4) );
}
oldybin2 += nygroup;
}
}
fXaxis.SetNdivisions(nXdivisions);
fXaxis.SetAxisColor(xAxisColor);
fXaxis.SetLabelColor(xLabelColor);
fXaxis.SetLabelFont(xLabelFont);
fXaxis.SetLabelOffset(xLabelOffset);
fXaxis.SetLabelSize(xLabelSize);
fXaxis.SetTickLength(xTickLength);
fXaxis.SetTitleOffset(xTitleOffset);
fXaxis.SetTitleSize(xTitleSize);
fXaxis.SetTitleColor(xTitleColor);
fXaxis.SetTitleFont(xTitleFont);
fYaxis.SetNdivisions(nYdivisions);
fYaxis.SetAxisColor(yAxisColor);
fYaxis.SetLabelColor(yLabelColor);
fYaxis.SetLabelFont(yLabelFont);
fYaxis.SetLabelOffset(yLabelOffset);
fYaxis.SetLabelSize(yLabelSize);
fYaxis.SetTickLength(yTickLength);
fYaxis.SetTitleOffset(yTitleOffset);
fYaxis.SetTitleSize(yTitleSize);
fYaxis.SetTitleColor(yTitleColor);
fYaxis.SetTitleFont(yTitleFont);
fZaxis.SetNdivisions(nZdivisions);
fZaxis.SetAxisColor(zAxisColor);
fZaxis.SetLabelColor(zLabelColor);
fZaxis.SetLabelFont(zLabelFont);
fZaxis.SetLabelOffset(zLabelOffset);
fZaxis.SetLabelSize(zLabelSize);
fZaxis.SetTickLength(zTickLength);
fZaxis.SetTitleOffset(zTitleOffset);
fZaxis.SetTitleSize(zTitleSize);
fZaxis.SetTitleColor(zTitleColor);
fZaxis.SetTitleFont(zTitleFont);
hnew->SetEntries(entries);
if (!resetStat) hnew->PutStats(stat);
delete [] oldBins;
if (oldSumw2) delete [] oldSumw2;
return hnew;
}
void TH3::Reset(Option_t *option)
{
TH1::Reset(option);
TString opt = option;
opt.ToUpper();
if (opt.Contains("ICE") && !opt.Contains("S")) return;
fTsumwy = 0;
fTsumwy2 = 0;
fTsumwxy = 0;
fTsumwz = 0;
fTsumwz2 = 0;
fTsumwxz = 0;
fTsumwyz = 0;
}
void TH3::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
R__b.ReadClassBuffer(TH3::Class(), this, R__v, R__s, R__c);
return;
}
TH1::Streamer(R__b);
TAtt3D::Streamer(R__b);
R__b.CheckByteCount(R__s, R__c, TH3::IsA());
} else {
R__b.WriteClassBuffer(TH3::Class(),this);
}
}
ClassImp(TH3C)
TH3C::TH3C(): TH3(), TArrayC()
{
SetBinsLength(27);
if (fgDefaultSumw2) Sumw2();
}
TH3C::~TH3C()
{
}
TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
,Int_t nbinsy,Double_t ylow,Double_t yup
,Int_t nbinsz,Double_t zlow,Double_t zup)
:TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
{
TArrayC::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
}
TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
,Int_t nbinsy,const Float_t *ybins
,Int_t nbinsz,const Float_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayC::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
,Int_t nbinsy,const Double_t *ybins
,Int_t nbinsz,const Double_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayC::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3C::TH3C(const TH3C &h3c) : TH3(), TArrayC()
{
((TH3C&)h3c).Copy(*this);
}
void TH3C::AddBinContent(Int_t bin)
{
if (fArray[bin] < 127) fArray[bin]++;
}
void TH3C::AddBinContent(Int_t bin, Double_t w)
{
Int_t newval = fArray[bin] + Int_t(w);
if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
if (newval < -127) fArray[bin] = -127;
if (newval > 127) fArray[bin] = 127;
}
void TH3C::Copy(TObject &newth3) const
{
TH3::Copy((TH3C&)newth3);
}
TH1 *TH3C::DrawCopy(Option_t *option) const
{
TString opt = option;
opt.ToLower();
if (gPad && !opt.Contains("same")) gPad->Clear();
TH3C *newth3 = (TH3C*)Clone();
newth3->SetDirectory(0);
newth3->SetBit(kCanDelete);
newth3->AppendPad(option);
return newth3;
}
Double_t TH3C::GetBinContent(Int_t bin) const
{
if (fBuffer) ((TH3C*)this)->BufferEmpty();
if (bin < 0) bin = 0;
if (bin >= fNcells) bin = fNcells-1;
if (!fArray) return 0;
return Double_t (fArray[bin]);
}
void TH3C::Reset(Option_t *option)
{
TH3::Reset(option);
TArrayC::Reset();
}
void TH3C::SetBinsLength(Int_t n)
{
if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
fNcells = n;
TArrayC::Set(n);
}
void TH3C::SetBinContent(Int_t bin, Double_t content)
{
fEntries++;
fTsumw = 0;
if (bin < 0) return;
if (bin >= fNcells) return;
fArray[bin] = Char_t (content);
}
void TH3::SetShowProjection(const char *option,Int_t nbins)
{
GetPainter();
if (fPainter) fPainter->SetShowProjection(option,nbins);
}
void TH3C::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
R__b.ReadClassBuffer(TH3C::Class(), this, R__v, R__s, R__c);
return;
}
if (R__v < 2) {
R__b.ReadVersion();
TH1::Streamer(R__b);
TArrayC::Streamer(R__b);
R__b.ReadVersion(&R__s, &R__c);
TAtt3D::Streamer(R__b);
} else {
TH3::Streamer(R__b);
TArrayC::Streamer(R__b);
R__b.CheckByteCount(R__s, R__c, TH3C::IsA());
}
} else {
R__b.WriteClassBuffer(TH3C::Class(),this);
}
}
TH3C& TH3C::operator=(const TH3C &h1)
{
if (this != &h1) ((TH3C&)h1).Copy(*this);
return *this;
}
TH3C operator*(Float_t c1, TH3C &h1)
{
TH3C hnew = h1;
hnew.Scale(c1);
hnew.SetDirectory(0);
return hnew;
}
TH3C operator+(TH3C &h1, TH3C &h2)
{
TH3C hnew = h1;
hnew.Add(&h2,1);
hnew.SetDirectory(0);
return hnew;
}
TH3C operator-(TH3C &h1, TH3C &h2)
{
TH3C hnew = h1;
hnew.Add(&h2,-1);
hnew.SetDirectory(0);
return hnew;
}
TH3C operator*(TH3C &h1, TH3C &h2)
{
TH3C hnew = h1;
hnew.Multiply(&h2);
hnew.SetDirectory(0);
return hnew;
}
TH3C operator/(TH3C &h1, TH3C &h2)
{
TH3C hnew = h1;
hnew.Divide(&h2);
hnew.SetDirectory(0);
return hnew;
}
ClassImp(TH3S)
TH3S::TH3S(): TH3(), TArrayS()
{
SetBinsLength(27);
if (fgDefaultSumw2) Sumw2();
}
TH3S::~TH3S()
{
}
TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
,Int_t nbinsy,Double_t ylow,Double_t yup
,Int_t nbinsz,Double_t zlow,Double_t zup)
:TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
{
TH3S::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
}
TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
,Int_t nbinsy,const Float_t *ybins
,Int_t nbinsz,const Float_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TH3S::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
,Int_t nbinsy,const Double_t *ybins
,Int_t nbinsz,const Double_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TH3S::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3S::TH3S(const TH3S &h3s) : TH3(), TArrayS()
{
((TH3S&)h3s).Copy(*this);
}
void TH3S::AddBinContent(Int_t bin)
{
if (fArray[bin] < 32767) fArray[bin]++;
}
void TH3S::AddBinContent(Int_t bin, Double_t w)
{
Int_t newval = fArray[bin] + Int_t(w);
if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
if (newval < -32767) fArray[bin] = -32767;
if (newval > 32767) fArray[bin] = 32767;
}
void TH3S::Copy(TObject &newth3) const
{
TH3::Copy((TH3S&)newth3);
}
TH1 *TH3S::DrawCopy(Option_t *option) const
{
TString opt = option;
opt.ToLower();
if (gPad && !opt.Contains("same")) gPad->Clear();
TH3S *newth3 = (TH3S*)Clone();
newth3->SetDirectory(0);
newth3->SetBit(kCanDelete);
newth3->AppendPad(option);
return newth3;
}
Double_t TH3S::GetBinContent(Int_t bin) const
{
if (fBuffer) ((TH3S*)this)->BufferEmpty();
if (bin < 0) bin = 0;
if (bin >= fNcells) bin = fNcells-1;
if (!fArray) return 0;
return Double_t (fArray[bin]);
}
void TH3S::Reset(Option_t *option)
{
TH3::Reset(option);
TArrayS::Reset();
}
void TH3S::SetBinContent(Int_t bin, Double_t content)
{
fEntries++;
fTsumw = 0;
if (bin < 0) return;
if (bin >= fNcells) return;
fArray[bin] = Short_t (content);
}
void TH3S::SetBinsLength(Int_t n)
{
if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
fNcells = n;
TArrayS::Set(n);
}
void TH3S::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
R__b.ReadClassBuffer(TH3S::Class(), this, R__v, R__s, R__c);
return;
}
if (R__v < 2) {
R__b.ReadVersion();
TH1::Streamer(R__b);
TArrayS::Streamer(R__b);
R__b.ReadVersion(&R__s, &R__c);
TAtt3D::Streamer(R__b);
} else {
TH3::Streamer(R__b);
TArrayS::Streamer(R__b);
R__b.CheckByteCount(R__s, R__c, TH3S::IsA());
}
} else {
R__b.WriteClassBuffer(TH3S::Class(),this);
}
}
TH3S& TH3S::operator=(const TH3S &h1)
{
if (this != &h1) ((TH3S&)h1).Copy(*this);
return *this;
}
TH3S operator*(Float_t c1, TH3S &h1)
{
TH3S hnew = h1;
hnew.Scale(c1);
hnew.SetDirectory(0);
return hnew;
}
TH3S operator+(TH3S &h1, TH3S &h2)
{
TH3S hnew = h1;
hnew.Add(&h2,1);
hnew.SetDirectory(0);
return hnew;
}
TH3S operator-(TH3S &h1, TH3S &h2)
{
TH3S hnew = h1;
hnew.Add(&h2,-1);
hnew.SetDirectory(0);
return hnew;
}
TH3S operator*(TH3S &h1, TH3S &h2)
{
TH3S hnew = h1;
hnew.Multiply(&h2);
hnew.SetDirectory(0);
return hnew;
}
TH3S operator/(TH3S &h1, TH3S &h2)
{
TH3S hnew = h1;
hnew.Divide(&h2);
hnew.SetDirectory(0);
return hnew;
}
ClassImp(TH3I)
TH3I::TH3I(): TH3(), TArrayI()
{
SetBinsLength(27);
if (fgDefaultSumw2) Sumw2();
}
TH3I::~TH3I()
{
}
TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
,Int_t nbinsy,Double_t ylow,Double_t yup
,Int_t nbinsz,Double_t zlow,Double_t zup)
:TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
{
TH3I::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
}
TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
,Int_t nbinsy,const Float_t *ybins
,Int_t nbinsz,const Float_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayI::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
,Int_t nbinsy,const Double_t *ybins
,Int_t nbinsz,const Double_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayI::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3I::TH3I(const TH3I &h3i) : TH3(), TArrayI()
{
((TH3I&)h3i).Copy(*this);
}
void TH3I::AddBinContent(Int_t bin)
{
if (fArray[bin] < 2147483647) fArray[bin]++;
}
void TH3I::AddBinContent(Int_t bin, Double_t w)
{
Int_t newval = fArray[bin] + Int_t(w);
if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
if (newval < -2147483647) fArray[bin] = -2147483647;
if (newval > 2147483647) fArray[bin] = 2147483647;
}
void TH3I::Copy(TObject &newth3) const
{
TH3::Copy((TH3I&)newth3);
}
TH1 *TH3I::DrawCopy(Option_t *option) const
{
TString opt = option;
opt.ToLower();
if (gPad && !opt.Contains("same")) gPad->Clear();
TH3I *newth3 = (TH3I*)Clone();
newth3->SetDirectory(0);
newth3->SetBit(kCanDelete);
newth3->AppendPad(option);
return newth3;
}
Double_t TH3I::GetBinContent(Int_t bin) const
{
if (fBuffer) ((TH3I*)this)->BufferEmpty();
if (bin < 0) bin = 0;
if (bin >= fNcells) bin = fNcells-1;
if (!fArray) return 0;
return Double_t (fArray[bin]);
}
void TH3I::Reset(Option_t *option)
{
TH3::Reset(option);
TArrayI::Reset();
}
void TH3I::SetBinContent(Int_t bin, Double_t content)
{
fEntries++;
fTsumw = 0;
if (bin < 0) return;
if (bin >= fNcells) return;
fArray[bin] = Int_t (content);
}
void TH3I::SetBinsLength(Int_t n)
{
if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
fNcells = n;
TArrayI::Set(n);
}
TH3I& TH3I::operator=(const TH3I &h1)
{
if (this != &h1) ((TH3I&)h1).Copy(*this);
return *this;
}
TH3I operator*(Float_t c1, TH3I &h1)
{
TH3I hnew = h1;
hnew.Scale(c1);
hnew.SetDirectory(0);
return hnew;
}
TH3I operator+(TH3I &h1, TH3I &h2)
{
TH3I hnew = h1;
hnew.Add(&h2,1);
hnew.SetDirectory(0);
return hnew;
}
TH3I operator-(TH3I &h1, TH3I &h2)
{
TH3I hnew = h1;
hnew.Add(&h2,-1);
hnew.SetDirectory(0);
return hnew;
}
TH3I operator*(TH3I &h1, TH3I &h2)
{
TH3I hnew = h1;
hnew.Multiply(&h2);
hnew.SetDirectory(0);
return hnew;
}
TH3I operator/(TH3I &h1, TH3I &h2)
{
TH3I hnew = h1;
hnew.Divide(&h2);
hnew.SetDirectory(0);
return hnew;
}
ClassImp(TH3F)
TH3F::TH3F(): TH3(), TArrayF()
{
SetBinsLength(27);
if (fgDefaultSumw2) Sumw2();
}
TH3F::~TH3F()
{
}
TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
,Int_t nbinsy,Double_t ylow,Double_t yup
,Int_t nbinsz,Double_t zlow,Double_t zup)
:TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
{
TArrayF::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
}
TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
,Int_t nbinsy,const Float_t *ybins
,Int_t nbinsz,const Float_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayF::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
,Int_t nbinsy,const Double_t *ybins
,Int_t nbinsz,const Double_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayF::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3F::TH3F(const TH3F &h3f) : TH3(), TArrayF()
{
((TH3F&)h3f).Copy(*this);
}
void TH3F::Copy(TObject &newth3) const
{
TH3::Copy((TH3F&)newth3);
}
TH1 *TH3F::DrawCopy(Option_t *option) const
{
TString opt = option;
opt.ToLower();
if (gPad && !opt.Contains("same")) gPad->Clear();
TH3F *newth3 = (TH3F*)Clone();
newth3->SetDirectory(0);
newth3->SetBit(kCanDelete);
newth3->AppendPad(option);
return newth3;
}
Double_t TH3F::GetBinContent(Int_t bin) const
{
if (fBuffer) ((TH3F*)this)->BufferEmpty();
if (bin < 0) bin = 0;
if (bin >= fNcells) bin = fNcells-1;
if (!fArray) return 0;
return Double_t (fArray[bin]);
}
void TH3F::Reset(Option_t *option)
{
TH3::Reset(option);
TArrayF::Reset();
}
void TH3F::SetBinContent(Int_t bin, Double_t content)
{
fEntries++;
fTsumw = 0;
if (bin < 0) return;
if (bin >= fNcells) return;
fArray[bin] = Float_t (content);
}
void TH3F::SetBinsLength(Int_t n)
{
if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
fNcells = n;
TArrayF::Set(n);
}
void TH3F::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
R__b.ReadClassBuffer(TH3F::Class(), this, R__v, R__s, R__c);
return;
}
if (R__v < 2) {
R__b.ReadVersion();
TH1::Streamer(R__b);
TArrayF::Streamer(R__b);
R__b.ReadVersion(&R__s, &R__c);
TAtt3D::Streamer(R__b);
} else {
TH3::Streamer(R__b);
TArrayF::Streamer(R__b);
R__b.CheckByteCount(R__s, R__c, TH3F::IsA());
}
} else {
R__b.WriteClassBuffer(TH3F::Class(),this);
}
}
TH3F& TH3F::operator=(const TH3F &h1)
{
if (this != &h1) ((TH3F&)h1).Copy(*this);
return *this;
}
TH3F operator*(Float_t c1, TH3F &h1)
{
TH3F hnew = h1;
hnew.Scale(c1);
hnew.SetDirectory(0);
return hnew;
}
TH3F operator+(TH3F &h1, TH3F &h2)
{
TH3F hnew = h1;
hnew.Add(&h2,1);
hnew.SetDirectory(0);
return hnew;
}
TH3F operator-(TH3F &h1, TH3F &h2)
{
TH3F hnew = h1;
hnew.Add(&h2,-1);
hnew.SetDirectory(0);
return hnew;
}
TH3F operator*(TH3F &h1, TH3F &h2)
{
TH3F hnew = h1;
hnew.Multiply(&h2);
hnew.SetDirectory(0);
return hnew;
}
TH3F operator/(TH3F &h1, TH3F &h2)
{
TH3F hnew = h1;
hnew.Divide(&h2);
hnew.SetDirectory(0);
return hnew;
}
ClassImp(TH3D)
TH3D::TH3D(): TH3(), TArrayD()
{
SetBinsLength(27);
if (fgDefaultSumw2) Sumw2();
}
TH3D::~TH3D()
{
}
TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
,Int_t nbinsy,Double_t ylow,Double_t yup
,Int_t nbinsz,Double_t zlow,Double_t zup)
:TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
{
TArrayD::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
}
TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
,Int_t nbinsy,const Float_t *ybins
,Int_t nbinsz,const Float_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayD::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
,Int_t nbinsy,const Double_t *ybins
,Int_t nbinsz,const Double_t *zbins)
:TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
{
TArrayD::Set(fNcells);
if (fgDefaultSumw2) Sumw2();
}
TH3D::TH3D(const TH3D &h3d) : TH3(), TArrayD()
{
((TH3D&)h3d).Copy(*this);
}
void TH3D::Copy(TObject &newth3) const
{
TH3::Copy((TH3D&)newth3);
}
TH1 *TH3D::DrawCopy(Option_t *option) const
{
TString opt = option;
opt.ToLower();
if (gPad && !opt.Contains("same")) gPad->Clear();
TH3D *newth3 = (TH3D*)Clone();
newth3->SetDirectory(0);
newth3->SetBit(kCanDelete);
newth3->AppendPad(option);
return newth3;
}
Double_t TH3D::GetBinContent(Int_t bin) const
{
if (fBuffer) ((TH3D*)this)->BufferEmpty();
if (bin < 0) bin = 0;
if (bin >= fNcells) bin = fNcells-1;
if (!fArray) return 0;
return Double_t (fArray[bin]);
}
void TH3D::Reset(Option_t *option)
{
TH3::Reset(option);
TArrayD::Reset();
}
void TH3D::SetBinContent(Int_t bin, Double_t content)
{
fEntries++;
fTsumw = 0;
if (bin < 0) return;
if (bin >= fNcells) return;
fArray[bin] = Double_t (content);
}
void TH3D::SetBinsLength(Int_t n)
{
if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
fNcells = n;
TArrayD::Set(n);
}
void TH3D::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
UInt_t R__s, R__c;
if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
R__b.ReadClassBuffer(TH3D::Class(), this, R__v, R__s, R__c);
return;
}
if (R__v < 2) {
R__b.ReadVersion();
TH1::Streamer(R__b);
TArrayD::Streamer(R__b);
R__b.ReadVersion(&R__s, &R__c);
TAtt3D::Streamer(R__b);
} else {
TH3::Streamer(R__b);
TArrayD::Streamer(R__b);
R__b.CheckByteCount(R__s, R__c, TH3D::IsA());
}
} else {
R__b.WriteClassBuffer(TH3D::Class(),this);
}
}
TH3D& TH3D::operator=(const TH3D &h1)
{
if (this != &h1) ((TH3D&)h1).Copy(*this);
return *this;
}
TH3D operator*(Float_t c1, TH3D &h1)
{
TH3D hnew = h1;
hnew.Scale(c1);
hnew.SetDirectory(0);
return hnew;
}
TH3D operator+(TH3D &h1, TH3D &h2)
{
TH3D hnew = h1;
hnew.Add(&h2,1);
hnew.SetDirectory(0);
return hnew;
}
TH3D operator-(TH3D &h1, TH3D &h2)
{
TH3D hnew = h1;
hnew.Add(&h2,-1);
hnew.SetDirectory(0);
return hnew;
}
TH3D operator*(TH3D &h1, TH3D &h2)
{
TH3D hnew = h1;
hnew.Multiply(&h2);
hnew.SetDirectory(0);
return hnew;
}
TH3D operator/(TH3D &h1, TH3D &h2)
{
TH3D hnew = h1;
hnew.Divide(&h2);
hnew.SetDirectory(0);
return hnew;
}