Here is how I modified the 2D projection:
[code] /*
// y, x looks wrong, but it’s what TH3::Project3D(“xy”) does
TH2D* h = new TH2D(name, title,
GetAxis(yDim)->GetNbins(),
GetAxis(yDim)->GetXmin(), GetAxis(yDim)->GetXmax(),
GetAxis(xDim)->GetNbins(),
GetAxis(xDim)->GetXmin(), GetAxis(xDim)->GetXmax());
*/
TAxis *axisX = GetAxis(xDim), *axisY = GetAxis(yDim);
const TArrayD *xbins = axisX->GetXbins(), *ybins = axisY->GetXbins();
Int_t ilowX = axisX->GetFirst(), ihighX = axisX->GetLast(),
ilowY = axisY->GetFirst(), ihighY = axisY->GetLast();
Double_t lowX = axisX->GetBinLowEdge( ilowX ), highX = axisX->GetBinUpEdge( ihighX ),
lowY = axisY->GetBinLowEdge( ilowY ), highY = axisY->GetBinUpEdge( ihighY );
Int_t nx = ihighX-ilowX+1, ny = ihighY-ilowY+1;
TH2D *h = NULL;
if ( xbins->fN == 0 && ybins->fN == 0 )
{
h = new TH2D( name, title, ny, lowY, highY, nx, lowX, highX );
} else if ( ybins->fN == 0 )
{
h = new TH2D( name, title, ny, lowY, highY, nx, &xbins->fArray[ilowX-1] );
} else if ( xbins->fN == 0 )
{
h = new TH2D( name, title, ny, &ybins->fArray[ilowY-1], nx, lowX, highX );
} else
{
h = new TH2D( name, title, ny, &ybins->fArray[ilowY-1], nx, &xbins->fArray[ilowX-1] );
}[/code]
See hist/TH3.cxx TH3::Project3D() for reference.
The new constructor was only a minor change from the original:
[code]THnSparse::THnSparse(const char* name, const char* title, Int_t dim,
const Int_t* nbins, const Double_t *bins,
Int_t chunksize):
TNamed(name, title), fNdimensions(dim), fChunkSize(chunksize), fFilledBins(0),
fAxes(dim), fEntries(0), fTsumw(0), fTsumw2(-1.), fTsumwx(dim), fTsumwx2(dim),
fCompactCoord(0), fIntegral(0), fIntegralStatus(kNoInt)
{
for (Int_t i = 0; i < fNdimensions; ++i) {
TAxis axis = new TAxis(nbins[i], bins[i]);
TString name(“axis”);
name += i;
axis->SetName(name);
axis->SetTitle(name);
fAxes.AddAtAndExpand(axis, i);
}
fAxes.SetOwner();
fCompactCoord = new THnSparseCompactBinCoord(dim, nbins);
}
[/code]
It’s a bit of a pain to call though. Would be nice to be able to call it say:
[code]Double_t nbins[] = {2, 3, 4};
Double_n bins[][10] = { {10, 20}, {5, 7, 8}, { 40, 50, 60, 90 } };
THnSparse Test( “test”, “test”, 3, nbins, bins );[/code]
But you can’t do that, of course, you have to write something like:
Double_t _bins[][10] = { {10, 20}, {5, 7, 8}, { 40, 50, 60, 90 } };
Double *bins[] = { _bins[0], _bins[1], _bins[2] };
Unless anyone can think of a neater way to do it. (One way might be to fix the maximum number of bins, and change the constructor to accept “Double_t bins[][nmax]” instead of “Double_t **bins” , but we don’t want to do that.)
Regards,