ROOT logo
// @(#)root/hist:$Id: THnSparse.cxx 27215 2009-01-22 15:19:31Z moneta $
// Author: Axel Naumann (2007-09-11)

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "THnSparse.h"

#include "TArrayI.h"
#include "TAxis.h"
#include "TClass.h"
#include "TCollection.h"
#include "TDataMember.h"
#include "TDataType.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TH3D.h"
#include "TInterpreter.h"
#include "TMath.h"
#include "TRandom.h"
#include <cassert>

//______________________________________________________________________________
//
// THnSparseCompactBinCoord is a class used by THnSparse internally. It
// represents a compacted n-dimensional array of bin coordinates (indices).
// As the total number of bins in each dimension is known by THnSparse, bin
// indices can be compacted to only use the amount of bins needed by the total
// number of bins in each dimension. E.g. for a THnSparse with
// {15, 100, 2, 20, 10, 100} bins per dimension, a bin index will only occupy
// 28 bits (4+7+1+5+4+7), i.e. less than a 32bit integer. The tricky part is
// the fast compression and decompression, the platform-independent storage
// (think of endianness: the bits of the number 0x123456 depend on the
// platform), and the hashing needed by THnSparseArrayChunk.
//______________________________________________________________________________

class THnSparseCompactBinCoord {
public:
   THnSparseCompactBinCoord(Int_t dim, const Int_t* nbins);
   ~THnSparseCompactBinCoord();
   void SetCoord(const Int_t* coord) { memcpy(fCurrentBin, coord, sizeof(Int_t) * fNdimensions); }
   ULong64_t GetHash();
   Int_t GetSize() const { return fCoordBufferSize; }
   Int_t* GetCoord() const { return fCurrentBin; }
   Char_t* GetBuffer() const { return fCoordBuffer; }
   void GetCoordFromBuffer(Int_t* coord) const;

protected:
   Int_t GetNumBits(Int_t n) const {
      // return the number of bits allocated by the number "n"
      Int_t r = (n > 0);
      while (n/=2) ++r;
      return r;
   }
private:
   Int_t  fNdimensions;     // number of dimensions
   Int_t *fBitOffsets;      //[fNdimensions + 1] bit offset of each axis index
   Char_t *fCoordBuffer;     // compact buffer of coordinates
   Int_t  fCoordBufferSize; // size of fBinCoordBuffer
   Int_t *fCurrentBin;      // current coordinates
};


//______________________________________________________________________________
//______________________________________________________________________________


//______________________________________________________________________________
THnSparseCompactBinCoord::THnSparseCompactBinCoord(Int_t dim, const Int_t* nbins):
   fNdimensions(dim), fBitOffsets(0), fCoordBuffer(0), fCoordBufferSize(0)
{
   // Initialize a THnSparseCompactBinCoord object with "dim" dimensions
   // and "bins" holding the number of bins for each dimension.

   fCurrentBin = new Int_t[dim];
   fBitOffsets = new Int_t[dim + 1];

   int shift = 0;
   for (Int_t i = 0; i < dim; ++i) {
      fBitOffsets[i] = shift;
      shift += GetNumBits(nbins[i] + 2);
   }
   fBitOffsets[dim] = shift;
   fCoordBufferSize = (shift + 7) / 8;
   fCoordBuffer = new Char_t[fCoordBufferSize];
}


//______________________________________________________________________________
THnSparseCompactBinCoord::~THnSparseCompactBinCoord()
{
   // destruct a THnSparseCompactBinCoord

   delete [] fBitOffsets;
   delete [] fCoordBuffer;
   delete [] fCurrentBin;
}

//______________________________________________________________________________
void THnSparseCompactBinCoord::GetCoordFromBuffer(Int_t* coord) const
{
   // Given the current fCoordBuffer, calculate ("decompact") the bin coordinates,
   // and return it in coord.

   for (Int_t i = 0; i < fNdimensions; ++i) {
      const Int_t offset = fBitOffsets[i] / 8;
      Int_t shift = fBitOffsets[i] % 8;
      Int_t nbits = fBitOffsets[i + 1] - fBitOffsets[i];
      UChar_t* pbuf = (UChar_t*) fCoordBuffer + offset;
      coord[i] = *pbuf >> shift;
      Int_t subst = (Int_t) -1;
      subst = subst << nbits;
      nbits -= (8 - shift);
      shift = 8 - shift;
      for (Int_t n = 0; n * 8 < nbits; ++n) {
         ++pbuf;
         coord[i] += *pbuf << shift;
         shift += 8;
      }
      coord[i] &= ~subst;
   }
}

//______________________________________________________________________________
ULong64_t THnSparseCompactBinCoord::GetHash()
{
   // Calculate hash for compact bin index of the current bin.

   memset(fCoordBuffer, 0, fCoordBufferSize);
   for (Int_t i = 0; i < fNdimensions; ++i) {
      const Int_t offset = fBitOffsets[i] / 8;
      const Int_t shift = fBitOffsets[i] % 8;
      ULong64_t val = fCurrentBin[i];

      Char_t* pbuf = fCoordBuffer + offset;
      *pbuf += 0xff & (val << shift);
      val = val >> (8 - shift);
      while (val) {
         ++pbuf;
         *pbuf += 0xff & val;
         val = val >> 8;
      }
   }

   // Bins are addressed in two different modes, depending
   // on whether the compact bin index fits into a Long_t or not.
   // If it does, we can use it as a "perfect hash" for the TExMap.
   // If not we build a hash from the compact bin index, and use that
   // as the TExMap's hash.
   // For the non-hash mode, the size of the compact bin index must be
   // smaller than Long_t on all supported platforms - not just the current
   // one, because we make this layout persistent, too. So just test for
   // its size <= 4.

   switch (fCoordBufferSize) {
   case 1: return fCoordBuffer[0];
   case 2: return fCoordBuffer[0] + (fCoordBuffer[1] <<  8l);
   case 3: return fCoordBuffer[0] + (fCoordBuffer[1] <<  8l)
              + (fCoordBuffer[2] << 16l);
   case 4: return fCoordBuffer[0] + (fCoordBuffer[1] <<  8l)
              + (fCoordBuffer[2] << 16l) + (fCoordBuffer[3] << 24l);
   }
   return TMath::Hash(fCoordBuffer, fCoordBufferSize);
}



//______________________________________________________________________________
//
// THnSparseArrayChunk is used internally by THnSparse.
//
// THnSparse stores its (dynamic size) array of bin coordinates and their
// contents (and possibly errors) in a TObjArray of THnSparseArrayChunk. Each
// of the chunks holds an array of THnSparseCompactBinCoord and the content
// (a TArray*), which is created outside (by the templated derived classes of
// THnSparse) and passed in at construction time.
//______________________________________________________________________________


ClassImp(THnSparseArrayChunk);

//______________________________________________________________________________
THnSparseArrayChunk::THnSparseArrayChunk(Int_t coordsize, bool errors, TArray* cont):
      fCoordinateAllocationSize(-1), fSingleCoordinateSize(coordsize), fCoordinatesSize(0),
      fCoordinates(0), fContent(cont),
      fSumw2(0)
{
   // (Default) initialize a chunk. Takes ownership of cont (~THnSparseArrayChunk deletes it),
   // and create an ArrayF for errors if "errors" is true.

   fCoordinateAllocationSize = fSingleCoordinateSize * cont->GetSize();
   fCoordinates = new Char_t[fCoordinateAllocationSize];
   if (errors) Sumw2();
}

//______________________________________________________________________________
THnSparseArrayChunk::~THnSparseArrayChunk()
{
   // Destructor
   delete fContent;
   delete [] fCoordinates;
   delete fSumw2;
}

//______________________________________________________________________________
void THnSparseArrayChunk::AddBin(ULong_t idx, const Char_t* coordbuf)
{
   // Create a new bin in this chunk

   // When streaming out only the filled chunk is saved.
   // When reading back only the memory needed for that filled part gets
   // allocated. We need to check whether the allowed chunk size is
   // bigger than the allocated size. If fCoordinateAllocationSize is
   // set to -1 this chunk has been allocated by the  streamer and the
   // buffer allocation size is defined by [fCoordinatesSize]. In that
   // case we need to compare fCoordinatesSize to
   // fSingleCoordinateSize * fContent->GetSize()
   // to determine whether we need to expand the buffer.
   if (fCoordinateAllocationSize == -1 && fContent) {
      Int_t chunksize = fSingleCoordinateSize * fContent->GetSize();
      if (fCoordinatesSize < chunksize) {
         // need to re-allocate:
         Char_t *newcoord = new Char_t[chunksize];
         memcpy(newcoord, fCoordinates, fCoordinatesSize);
         delete [] fCoordinates;
         fCoordinates = newcoord;
      }
      fCoordinateAllocationSize = chunksize;
   }

   memcpy(fCoordinates + idx * fSingleCoordinateSize, coordbuf, fSingleCoordinateSize);
   fCoordinatesSize += fSingleCoordinateSize;
}

//______________________________________________________________________________
void THnSparseArrayChunk::Sumw2()
{
   // Turn on support of errors
   if (!fSumw2)
      fSumw2 = new TArrayD(fContent->GetSize());
}



//______________________________________________________________________________
//
//
//    Efficient multidimensional histogram.
//
// Use a THnSparse instead of TH1 / TH2 / TH3 / array for histogramming when
// only a small fraction of bins is filled. A 10-dimensional histogram with 10
// bins per dimension has 10^10 bins; in a naive implementation this will not
// fit in memory. THnSparse only allocates memory for the bins that have
// non-zero bin content instead, drastically reducing both the memory usage
// and the access time.
//
// To construct a THnSparse object you must use one of its templated, derived
// classes:
// THnSparseD (typedef for THnSparse<ArrayD>): bin content held by a Double_t,
// THnSparseF (typedef for THnSparse<ArrayF>): bin content held by a Float_t,
// THnSparseL (typedef for THnSparse<ArrayL>): bin content held by a Long_t,
// THnSparseI (typedef for THnSparse<ArrayI>): bin content held by an Int_t,
// THnSparseS (typedef for THnSparse<ArrayS>): bin content held by a Short_t,
// THnSparseC (typedef for THnSparse<ArrayC>): bin content held by a Char_t,
//
// They take name and title, the number of dimensions, and for each dimension
// the number of bins, the minimal, and the maximal value on the dimension's
// axis. A TH2 h("h","h",10, 0., 10., 20, -5., 5.) would correspond to
//   Int_t bins[2] = {10, 20};
//   Double_t xmin[2] = {0., -5.};
//   Double_t xmax[2] = {10., 5.};
//   THnSparse hs("hs", "hs", 2, bins, min, max);
//
// * Filling
// A THnSparse is filled just like a regular histogram, using
// THnSparse::Fill(x, weight), where x is a n-dimensional Double_t value.
// To take errors into account, Sumw2() must be called before filling the
// histogram.
// Bins are allocated as needed; the status of the allocation can be observed
// by GetSparseFractionBins(), GetSparseFractionMem().
//
// * Fast Bin Content Access
// When iterating over a THnSparse one should only look at filled bins to save
// processing time. The number of filled bins is returned by
// THnSparse::GetNbins(); the bin content for each (linear) bin number can
// be retrieved by THnSparse::GetBinContent(linidx, (Int_t*)coord).
// After the call, coord will contain the bin coordinate of each axis for the bin
// with linear index linidx. A possible call would be
//   cout << hs.GetBinContent(0, coord);
//   cout <<" is the content of bin [x = " << coord[0] "
//        << " | y = " << coord[1] << "]" << endl;
//
// * Efficiency
// TH1 and TH2 are generally faster than THnSparse for one and two dimensional
// distributions. THnSparse becomes competitive for a sparsely filled TH3
// with large numbers of bins per dimension. The tutorial hist/sparsehist.C
// shows the turning point. On a AMD64 with 8GB memory, THnSparse "wins"
// starting with a TH3 with 30 bins per dimension. Using a THnSparse for a
// one-dimensional histogram is only reasonable if it has a huge number of bins.
//
// * Projections
// The dimensionality of a THnSparse can be reduced by projecting it to
// 1, 2, 3, or n dimensions, which can be represented by a TH1, TH2, TH3, or
// a THnSparse. See the Projection() members. To only project parts of the
// histogram, call
//   THnSparse::GetAxis(12)->SetRange(from_bin, to_bin);
// See the important remark in THnSparse::IsInRange() when excluding under-
// and overflow bins!
//
// * Internal Representation
// An entry for a filled bin consists of its n-dimensional coordinates and
// its bin content. The coordinates are compacted to use as few bits as
// possible; e.g. a histogram with 10 bins in x and 20 bins in y will only
// use 4 bits for the x representation and 5 bits for the y representation.
// This is handled by the internal class THnSparseCompactBinCoord.
// Bin data (content and coordinates) are allocated in chunks of size
// fChunkSize; this parameter can be set when constructing a THnSparse. Each
// chunk is represented by an object of class THnSparseArrayChunk.
//
// Translation from an n-dimensional bin coordinate to the linear index within
// the chunks is done by GetBin(). It creates a hash from the compacted bin
// coordinates (the hash of a bin coordinate is the compacted coordinate itself
// if it takes less than 4 bytes, the minimal supported size of a Long_t).
// This hash is used to lookup the linear index in the TExMap member fBins;
// the coordinates of the entry fBins points to is compared to the coordinates
// passed to GetBin(). If they do not match, these two coordinates have the same
// hash - which is extremely unlikely but (for the case where the compact bin
// coordinates are larger than 4 bytes) possible. In this case, fBinsContinued
// contains a chain of linear indexes with the same hash. Iterating through this
// chain and comparing each bin coordinates with the one passed to GetBin() will
// retrieve the matching bin.


ClassImp(THnSparse);

//______________________________________________________________________________
THnSparse::THnSparse():
   fNdimensions(0), fChunkSize(1024), fFilledBins(0), fEntries(0),
   fTsumw(0), fTsumw2(-1.), fCompactCoord(0), fIntegral(0), fIntegralStatus(kNoInt)
{
   // Construct an empty THnSparse.
   fBinContent.SetOwner();
}

//______________________________________________________________________________
THnSparse::THnSparse(const char* name, const char* title, Int_t dim,
                     const Int_t* nbins, const Double_t* xmin, const Double_t* xmax,
                     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)
{
   // Construct a THnSparse with "dim" dimensions,
   // with chunksize as the size of the chunks.
   // "nbins" holds the number of bins for each dimension;
   // "xmin" and "xmax" the minimal and maximal value for each dimension.
   // The arrays "xmin" and "xmax" can be NULL; in that case SetBinEdges()
   // must be called for each dimension.

   for (Int_t i = 0; i < fNdimensions; ++i) {
      TAxis* axis = new TAxis(nbins[i], xmin ? xmin[i] : 0., xmax ? xmax[i] : 1.);
      TString aname("axis");
      aname += i;
      axis->SetName(aname);
      axis->SetTitle(aname);
      fAxes.AddAtAndExpand(axis, i);
   }
   fAxes.SetOwner();

   fCompactCoord = new THnSparseCompactBinCoord(dim, nbins);
   fBinContent.SetOwner();
}

//______________________________________________________________________________
THnSparse::~THnSparse() {
   // Destruct a THnSparse

   delete fCompactCoord;
   if (fIntegralStatus != kNoInt) delete [] fIntegral;
}
//______________________________________________________________________________
void THnSparse::AddBinContent(const Int_t* coord, Double_t v)
{
   // Add "v" to the content of bin with coordinates "coord"

   GetCompactCoord()->SetCoord(coord);
   Long_t bin = GetBinIndexForCurrentBin(kTRUE);
   THnSparseArrayChunk* chunk = GetChunk(bin / fChunkSize);
   bin %= fChunkSize;
   v += chunk->fContent->GetAt(bin);
   return chunk->fContent->SetAt(v, bin);
}

//______________________________________________________________________________
THnSparseArrayChunk* THnSparse::AddChunk()
{
   //Create a new chunk of bin content
   THnSparseArrayChunk* first = 0;
   if (fBinContent.GetEntriesFast() > 0)
      first = GetChunk(0);
   THnSparseArrayChunk* chunk =
      new THnSparseArrayChunk(GetCompactCoord()->GetSize(),
                              GetCalculateErrors(), GenerateArray());
   fBinContent.AddLast(chunk);
   return chunk;
}

//______________________________________________________________________________
THnSparse* THnSparse::CloneEmpty(const char* name, const char* title,
                                 const TObjArray* axes, Int_t chunksize) const
{
   // Create a new THnSparse object that is of the same type as *this,
   // but with dimensions and bins given by axes.

   THnSparse* ret = (THnSparse*)IsA()->New();
   ret->SetNameTitle(name, title);
   ret->fNdimensions = axes->GetEntriesFast();
   ret->fChunkSize = chunksize;

   TIter iAxis(axes);
   const TAxis* axis = 0;
   Int_t pos = 0;
   Int_t *nbins = new Int_t[axes->GetEntriesFast()];
   while ((axis = (TAxis*)iAxis())) {
      nbins[pos] = axis->GetNbins();
      ret->fAxes.AddAtAndExpand(axis->Clone(), pos++);
   }
   ret->fAxes.SetOwner();

   ret->fCompactCoord = new THnSparseCompactBinCoord(pos, nbins);
   delete [] nbins;

   return ret;
}

//______________________________________________________________________________
TH1* THnSparse::CreateHist(const char* name, const char* title,
                           const TObjArray* axes) const {
   // Create an empty histogram with name and title with a given
   // set of axes. Create a TH1D/TH2D/TH3D, depending on the number
   // of elements in axes.

   const int ndim = axes->GetSize();

   TH1* hist = 0;
   // create hist with dummy axes, we fix them later.
   if (ndim == 1)
      hist = new TH1D(name, title, 1, 0., 1.);
   else if (ndim == 2)
      hist = new TH2D(name, title, 1, 0., 1., 1, 0., 1.);
   else if (ndim == 3)
      hist = new TH3D(name, title, 1, 0., 1., 1, 0., 1., 1, 0., 1.);
   else {
      Error("CreateHist", "Cannot create histogram %s with %d dimensions!", name, ndim);
      return 0;
   }

   TAxis* hax[3] = {hist->GetXaxis(), hist->GetYaxis(), hist->GetZaxis()};
   for (Int_t d = 0; d < ndim; ++d) {
      TAxis* reqaxis = (TAxis*)(*axes)[d];
      if (reqaxis->TestBit(TAxis::kAxisRange)) {
         Int_t binFirst = reqaxis->GetFirst();
         Int_t binLast = reqaxis->GetLast();
         Int_t nBins = binLast - binFirst + 1;
         if (reqaxis->GetXbins()->GetSize()) {
            // non-uniform bins:
            hax[d]->Set(nBins, reqaxis->GetXbins()->GetArray() + binFirst - 1);
         } else {
            // uniform bins:
            hax[d]->Set(nBins, reqaxis->GetBinLowEdge(binFirst), reqaxis->GetBinUpEdge(binLast));
         }
      } else {
         if (reqaxis->GetXbins()->GetSize()) {
            // non-uniform bins:
            hax[d]->Set(reqaxis->GetNbins(), reqaxis->GetXbins()->GetArray());
         } else {
            // uniform bins:
            hax[d]->Set(reqaxis->GetNbins(), reqaxis->GetXmin(), reqaxis->GetXmax());
         }
      }
   }

   hist->Rebuild();

   return hist;
}

//______________________________________________________________________________
Long_t THnSparse::GetBin(const Double_t* x, Bool_t allocate /* = kTRUE */)
{
   // Get the bin index for the n dimensional tuple x,
   // allocate one if it doesn't exist yet and "allocate" is true.

   Int_t *coord = GetCompactCoord()->GetCoord();
   for (Int_t i = 0; i < fNdimensions; ++i)
      coord[i] = GetAxis(i)->FindBin(x[i]);

   return GetBinIndexForCurrentBin(allocate);
}


//______________________________________________________________________________
Long_t THnSparse::GetBin(const char* name[], Bool_t allocate /* = kTRUE */)
{
   // Get the bin index for the n dimensional tuple addressed by "name",
   // allocate one if it doesn't exist yet and "allocate" is true.

   Int_t *coord = GetCompactCoord()->GetCoord();
   for (Int_t i = 0; i < fNdimensions; ++i)
      coord[i] = GetAxis(i)->FindBin(name[i]);

   return GetBinIndexForCurrentBin(allocate);
}

//______________________________________________________________________________
Long_t THnSparse::GetBin(const Int_t* coord, Bool_t allocate /*= kTRUE*/)
{
   // Get the bin index for the n dimensional coordinates coord,
   // allocate one if it doesn't exist yet and "allocate" is true.
   GetCompactCoord()->SetCoord(coord);
   return GetBinIndexForCurrentBin(allocate);
}

//______________________________________________________________________________
Double_t THnSparse::GetBinContent(const Int_t *coord) const {
   // Get content of bin with coordinates "coord"
   GetCompactCoord()->SetCoord(coord);
   Long_t idx = const_cast<THnSparse*>(this)->GetBinIndexForCurrentBin(kFALSE);
   if (idx < 0) return 0.;
   THnSparseArrayChunk* chunk = GetChunk(idx / fChunkSize);
   return chunk->fContent->GetAt(idx % fChunkSize);
}

//______________________________________________________________________________
Double_t THnSparse::GetBinContent(Long64_t idx, Int_t* coord /* = 0 */) const
{
   // Return the content of the filled bin number "idx".
   // If coord is non-null, it will contain the bin's coordinates for each axis
   // that correspond to the bin.

   if (idx >= 0) {
      THnSparseArrayChunk* chunk = GetChunk(idx / fChunkSize);
      idx %= fChunkSize;
      if (chunk && chunk->fContent->GetSize() > idx) {
         if (coord) {
            Int_t sizeCompact = GetCompactCoord()->GetSize();
            memcpy(GetCompactCoord()->GetBuffer(), chunk->fCoordinates + idx * sizeCompact, sizeCompact);
            GetCompactCoord()->GetCoordFromBuffer(coord);
         }
         return chunk->fContent->GetAt(idx);
      }
   }
   if (coord)
      memset(coord, -1, sizeof(Int_t) * fNdimensions);
   return 0.;
}

//______________________________________________________________________________
Double_t THnSparse::GetBinError(const Int_t *coord) const {
   // Get error of bin with coordinates "coord" as
   // BEGIN_LATEX #sqrt{#sum weight^{2}}
   // END_LATEX
   // If errors are not enabled (via Sumw2() or CalculateErrors())
   // return sqrt(contents).

   if (!GetCalculateErrors())
      return TMath::Sqrt(GetBinContent(coord));

   GetCompactCoord()->SetCoord(coord);
   Long_t idx = const_cast<THnSparse*>(this)->GetBinIndexForCurrentBin(kFALSE);
   if (idx < 0) return 0.;

   THnSparseArrayChunk* chunk = GetChunk(idx / fChunkSize);
   return TMath::Sqrt(chunk->fSumw2->GetAt(idx % fChunkSize));
}

//______________________________________________________________________________
Double_t THnSparse::GetBinError(Long64_t linidx) const {
   // Get error of bin addressed by linidx as
   // BEGIN_LATEX #sqrt{#sum weight^{2}}
   // END_LATEX
   // If errors are not enabled (via Sumw2() or CalculateErrors())
   // return sqrt(contents).

   if (!GetCalculateErrors())
      return TMath::Sqrt(GetBinContent(linidx));

   if (linidx < 0) return 0.;
   THnSparseArrayChunk* chunk = GetChunk(linidx / fChunkSize);
   linidx %= fChunkSize;
   if (!chunk || chunk->fContent->GetSize() < linidx)
      return 0.;

   return TMath::Sqrt(chunk->fSumw2->GetAt(linidx));
}

//______________________________________________________________________________
Long_t THnSparse::GetBinIndexForCurrentBin(Bool_t allocate)
{
   // Return the index for fCurrentBinIndex.
   // If it doesn't exist then return -1, or allocate a new bin if allocate is set

   Long_t hash = GetCompactCoord()->GetHash();
   Long_t linidx = (Long_t) fBins.GetValue(hash);
   while (linidx) {
      // fBins stores index + 1!
      THnSparseArrayChunk* chunk = GetChunk((linidx - 1)/ fChunkSize);
      if (chunk->Matches((linidx - 1) % fChunkSize, GetCompactCoord()->GetBuffer()))
         return linidx - 1; // we store idx+1, 0 is "TExMap: not found"

      Long_t nextlinidx = fBinsContinued.GetValue(linidx);
      if (!nextlinidx) break;

      linidx = nextlinidx;
   }
   if (!allocate) return -1;

   ++fFilledBins;

   // allocate bin in chunk
   THnSparseArrayChunk *chunk = (THnSparseArrayChunk*) fBinContent.Last();
   Long_t newidx = chunk ? ((Long_t) chunk->GetEntries()) : -1;
   if (!chunk || newidx == (Long_t)fChunkSize) {
      chunk = AddChunk();
      newidx = 0;
   }
   chunk->AddBin(newidx, GetCompactCoord()->GetBuffer());

   // store translation between hash and bin
   newidx += (fBinContent.GetEntriesFast() - 1) * fChunkSize;
   if (!linidx)
      // fBins didn't find it
      fBins.Add(hash, newidx + 1);
   else
      // fBins contains one, but it's the wrong one;
      // add entry to fBinsContinued.
      fBinsContinued.Add(linidx, newidx + 1);
   return newidx;
}

//______________________________________________________________________________
THnSparseCompactBinCoord* THnSparse::GetCompactCoord() const
{
   // Return THnSparseCompactBinCoord object.

   if (!fCompactCoord) {
      Int_t *bins = new Int_t[fNdimensions];
      for (Int_t d = 0; d < fNdimensions; ++d)
         bins[d] = GetAxis(d)->GetNbins();
      const_cast<THnSparse*>(this)->fCompactCoord
         = new THnSparseCompactBinCoord(fNdimensions, bins);
      delete [] bins;
   }
   return fCompactCoord;
}

//______________________________________________________________________________
void THnSparse::GetRandom(Double_t *rand, Bool_t subBinRandom /* = kTRUE */)
{
   // Generate an n-dimensional random tuple based on the histogrammed
   // distribution. If subBinRandom, the returned tuple will be additionally
   // randomly distributed within the randomized bin, using a flat
   // distribution.

   // check whether the integral array is valid
   if (fIntegralStatus != kValidInt)
      ComputeIntegral();

   // generate a random bin
   Double_t p = gRandom->Rndm();
   Long64_t idx = TMath::BinarySearch(GetNbins() + 1, fIntegral, p);
   Int_t bin[20]; //FIXME in case a user requests more than 20 dimensions ::)
   GetBinContent(idx, bin);

   // convert bin coordinates to real values
   for (Int_t i = 0; i < fNdimensions; i++) {
      rand[i] = GetAxis(i)->GetBinCenter(bin[i]);

      // randomize the vector withing a bin
      if (subBinRandom)
         rand[i] += (gRandom->Rndm() - 0.5) * GetAxis(i)->GetBinWidth(bin[i]);
   }

   return;
}

//______________________________________________________________________________
Double_t THnSparse::GetSparseFractionBins() const {
   // Return the amount of filled bins over all bins

   Double_t nbinsTotal = 1.;
   for (Int_t d = 0; d < fNdimensions; ++d)
      nbinsTotal *= GetAxis(d)->GetNbins() + 2;
   return fFilledBins / nbinsTotal;
}

//______________________________________________________________________________
Double_t THnSparse::GetSparseFractionMem() const {
   // Return the amount of used memory over memory that would be used by a
   // non-sparse n-dimensional histogram. The value is approximate.

   Int_t arrayElementSize = 0;
   Double_t size = 0.;
   if (fFilledBins) {
      TClass* clArray = GetChunk(0)->fContent->IsA();
      TDataMember* dm = clArray ? clArray->GetDataMember("fArray") : 0;
      arrayElementSize = dm ? dm->GetDataType()->Size() : 0;
   }
   if (!arrayElementSize) {
      Warning("GetSparseFractionMem", "Cannot determine type of elements!");
      return -1.;
   }

   size += fFilledBins * (GetCompactCoord()->GetSize() + arrayElementSize + 2 * sizeof(Long_t) /* TExMap */);
   if (fFilledBins && GetChunk(0)->fSumw2)
      size += fFilledBins * sizeof(Float_t); /* fSumw2 */

   Double_t nbinsTotal = 1.;
   for (Int_t d = 0; d < fNdimensions; ++d)
      nbinsTotal *= GetAxis(d)->GetNbins() + 2;

   return size / nbinsTotal / arrayElementSize;
}

//______________________________________________________________________________
Bool_t THnSparse::IsInRange(Int_t *coord) const
{
   // Check whether bin coord is in range, as defined by TAxis::SetRange().
   // Currently, TAxis::SetRange() does not allow to select all but over- and
   // underflow bins (it instead resets the axis to "no range selected").
   // Instead, simply call
   //    TAxis* axis12 = hsparse.GetAxis(12);
   //    axis12->SetRange(1, axis12->GetNbins());
   //    axis12->SetBit(TAxis::kAxisRange);
   // to deselect the under- and overflow bins in the 12th dimension.

   Int_t min = 0;
   Int_t max = 0;
   for (Int_t i = 0; i < fNdimensions; ++i) {
      TAxis *axis = GetAxis(i);
      if (!axis->TestBit(TAxis::kAxisRange)) continue;
      min = axis->GetFirst();
      max = axis->GetLast();
      if (min == 0 && max == 0) {
         // special case where TAxis::SetBit(kAxisRange) and
         // over- and underflow bins are de-selected.
         // first and last are == 0 due to axis12->SetRange(1, axis12->GetNbins());
         min = 1;
         max = axis->GetNbins();
      }
      if (coord[i] < min || coord[i] > max)
         return kFALSE;
   }
   return kTRUE;
}

//______________________________________________________________________________
TH1D* THnSparse::Projection(Int_t xDim, Option_t* option /*= ""*/) const
{
   // Project all bins into a 1-dimensional histogram,
   // keeping only axis "xDim".
   // If "option" contains "E" errors will be calculated.
   //                      "A" ranges of the taget axes will be ignored.

   return (TH1D*) ProjectionAny(1, &xDim, false, option);
}

//______________________________________________________________________________
TH2D* THnSparse::Projection(Int_t xDim, Int_t yDim, Option_t* option /*= ""*/) const
{
   // Project all bins into a 2-dimensional histogram,
   // keeping only axes "xDim" and "yDim".
   // If "option" contains "E" errors will be calculated.

   // y, x looks wrong, but it's what TH3::Project3D("xy") does
   const Int_t dim[2] = {yDim, xDim};
   return (TH2D*) ProjectionAny(2, dim, false, option);
}

//______________________________________________________________________________
TH3D* THnSparse::Projection(Int_t xDim, Int_t yDim, Int_t zDim,
                            Option_t* option /*= ""*/) const
{
   // Project all bins into a 3-dimensional histogram,
   // keeping only axes "xDim", "yDim", and "zDim".
   // If "option" contains "E" errors will be calculated.
   //                      "A" ranges of the taget axes will be ignored.

   const Int_t dim[3] = {xDim, yDim, zDim};
   return (TH3D*) ProjectionAny(3, dim, false, option);
}

//______________________________________________________________________________
THnSparse* THnSparse::Projection(Int_t ndim, const Int_t* dim,
                                 Option_t* option /*= ""*/) const
{
   // Project all bins into a ndim-dimensional histogram,
   // keeping only axes "dim".
   // If "option" contains "E" errors will be calculated.
   //                      "A" ranges of the taget axes will be ignored.

   return (THnSparse*) ProjectionAny(ndim, dim, true, option);
}


//______________________________________________________________________________
TObject* THnSparse::ProjectionAny(Int_t ndim, const Int_t* dim,
                                  Bool_t wantSparse, Option_t* option /*= ""*/) const
{
   // Project all bins into a 3-dimensional histogram,
   // keeping only axes "xDim", "yDim", and "zDim".
   // If "option" contains "E" errors will be calculated.
   //                      "A" ranges of the taget axes will be ignored.

   TString name(GetName());
   name += "_";
   for (Int_t d = 0; d < ndim; ++d)
      name += GetAxis(dim[d])->GetName();

   TString title(GetTitle());
   Ssiz_t posInsert = title.First(';');
   if (posInsert == kNPOS) {
      title += " projection ";
      for (Int_t d = 0; d < ndim; ++d)
         title += GetAxis(dim[d])->GetTitle();
   } else {
      for (Int_t d = ndim - 1; d >= 0; --d) {
         title.Insert(posInsert, GetAxis(d)->GetTitle());
         if (d)
            title.Insert(posInsert, ", ");
      }
      title.Insert(posInsert, " projection ");
   }

   TObjArray newaxes(ndim);
   for (Int_t d = 0; d < ndim; ++d) {
      newaxes.AddAt(GetAxis(dim[d]),d);
   }

   THnSparse* sparse = 0;
   TH1* hist = 0;
   TObject* ret = 0;

   Bool_t* hadRange = 0;
   Bool_t ignoreTargetRange = (option && (strchr(option, 'A') || strchr(option, 'a')));
   if (ignoreTargetRange) {
      hadRange = new Bool_t[ndim];
      for (Int_t d = 0; d < ndim; ++d){
         TAxis *axis = GetAxis(dim[d]);
         hadRange[d] = axis->TestBit(TAxis::kAxisRange);
         axis->SetBit(TAxis::kAxisRange, kFALSE);
      }
   }

   if (wantSparse)
      ret = sparse = CloneEmpty(name, title, &newaxes, fChunkSize);
   else
      ret = hist = CreateHist(name, title, &newaxes); 

   Bool_t haveErrors = GetCalculateErrors();
   Bool_t wantErrors = (option && (strchr(option, 'E') || strchr(option, 'e'))) || haveErrors;

   Int_t* bins  = new Int_t[ndim];
   Int_t  linbin = 0;
   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);

   Double_t err = 0.;
   Double_t preverr = 0.;
   Double_t v = 0.;

   for (Long64_t i = 0; i < GetNbins(); ++i) {
      v = GetBinContent(i, coord);

      if (!IsInRange(coord)) continue;

      for (Int_t d = 0; d < ndim; ++d) {
         bins[d] = coord[dim[d]];
         if (GetAxis(dim[d])->TestBit(TAxis::kAxisRange)) {
            bins[d] -= GetAxis(dim[d])->GetFirst() - 1;
         }
      }

      if (!wantSparse) {
         if (ndim == 1) linbin = bins[0];
         else if (ndim == 2) linbin = hist->GetBin(bins[0], bins[1]);
         else if (ndim == 3) linbin = hist->GetBin(bins[0], bins[1], bins[2]);
      }

      if (wantErrors) {
         if (haveErrors) {
            err = GetBinError(i);
            err *= err;
         } else err = v;
         if (wantSparse) {
            preverr = sparse->GetBinError(bins);
            sparse->SetBinError(bins, TMath::Sqrt(preverr * preverr + err));
         } else {
            preverr = hist->GetBinError(linbin);
            hist->SetBinError(linbin, TMath::Sqrt(preverr * preverr + err));
         }
      }

      // only _after_ error calculation, or sqrt(v) is taken into account!
      if (wantSparse)
         sparse->AddBinContent(bins, v);
      else
         hist->AddBinContent(linbin, v);
   }

   delete [] bins;
   delete [] coord;

   if (wantSparse)
      sparse->SetEntries(fEntries);
   else
      hist->SetEntries(fEntries);

   if (hadRange) {
      // reset kAxisRange bit:
      for (Int_t d = 0; d < ndim; ++d)
         GetAxis(dim[d])->SetBit(TAxis::kAxisRange, hadRange[d]);

      delete [] hadRange;
   }

   return ret;
}

//______________________________________________________________________________
void THnSparse::Scale(Double_t c)
{
   // Scale contents and errors of this histogram by c:
   // this = this * c
   // It does not modify the histogram's number of entries.


   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);

   // Scale the contents & errors
   Bool_t haveErrors = GetCalculateErrors();
   for (Long64_t i = 0; i < GetNbins(); ++i) {
      // Get the content of the bin from the current histogram
      Double_t v = GetBinContent(i, coord);
      SetBinContent(coord, c * v);
      if (haveErrors) {
         Double_t err = GetBinError(coord);
         SetBinError(coord, c * err);
      }
   }

   delete [] coord;
}

//______________________________________________________________________________
void THnSparse::Add(const THnSparse* h, Double_t c)
{
   // Add contents of h scaled by c to this histogram:
   // this = this + c * h
   // Note that if h has Sumw2 set, Sumw2 is automatically called for this
   // if not already set.

   // Check consistency of the input
   if (!CheckConsistency(h, "Add")) return;
   RebinnedAdd(h, c);
}

//______________________________________________________________________________
void THnSparse::RebinnedAdd(const THnSparse* h, Double_t c)
{
   // Add contents of h scaled by c to this histogram:
   // this = this + c * h
   // Note that if h has Sumw2 set, Sumw2 is automatically called for this
   // if not already set.
   // In contrast to Add(), RebinnedAdd() does not require consist binning of
   // this and h; instead, each bin's center is used to determine the target bin.

   if (fNdimensions!=h->GetNdimensions()) {
      Warning("RebinnedAdd", "Different number of dimensions, cannot carry out operation on the histograms");
      return;
   }

   // Trigger error calculation if h has it
   if (!GetCalculateErrors() && h->GetCalculateErrors())
      Sumw2();
   Bool_t haveErrors = GetCalculateErrors();

   // Now add the contents: in this case we have the union of the sets of bins
   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);

   // Add to this whatever is found inside the other histogram
   for (Long64_t i = 0; i < h->GetNbins(); ++i) {
      // Get the content of the bin from the second histogram
      Double_t v = h->GetBinContent(i, coord);
      AddBinContent(coord, c * v);
      if (haveErrors) {
         Double_t err1 = GetBinError(coord);
         Double_t err2 = h->GetBinError(coord) * c;
         SetBinError(coord, TMath::Sqrt(err1 * err1 + err2 * err2));
      }
   }


   delete [] coord;

   Double_t nEntries = GetEntries() + c * h->GetEntries();
   SetEntries(nEntries);
}


//______________________________________________________________________________
Long64_t THnSparse::Merge(TCollection* list)
{
   // Merge this with a list of THnSparses. All THnSparses provided
   // in the list must have the same bin layout!

   if (!list) return 0;
   if (list->IsEmpty()) return (Long64_t)GetEntries();

   TIter iter(list);
   const TObject* addMeObj = 0;
   while ((addMeObj = iter())) {
      const THnSparse* addMe = dynamic_cast<const THnSparse*>(addMeObj);
      if (!addMe) 
         Error("Merge", "Object named %s is not THnSpase! Skipping it.",
               addMeObj->GetName());
      else
         Add(addMe);
   }
   return (Long64_t)GetEntries();
}


//______________________________________________________________________________
void THnSparse::Multiply(const THnSparse* h)
{
   // Multiply this histogram by histogram h
   // this = this * h
   // Note that if h has Sumw2 set, Sumw2 is automatically called for this
   // if not already set.

   // Check consistency of the input
   if(!CheckConsistency(h, "Multiply"))return;

   // Trigger error calculation if h has it
   Bool_t wantErrors = kFALSE;
   if (!GetCalculateErrors() && h->GetCalculateErrors())
      wantErrors = kTRUE;

   // Create a temporary histogram where to store the result
   TObjArray newaxes(fNdimensions);
   for (Int_t d = 0; d < fNdimensions; ++d) {
      newaxes.AddAt(GetAxis(d),d);
   }

   if (wantErrors) Sumw2();

   // Now multiply the contents: in this case we have the intersection of the sets of bins
   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);
   for (Long64_t i = 0; i < GetNbins(); ++i) {
      // Get the content of the bin from the current histogram
      Double_t v1 = GetBinContent(i, coord);
      // Now look at the bin with the same coordinates in h
      Double_t v2 = h->GetBinContent(coord);
      SetBinContent(coord, v1 * v2);;
      if (wantErrors) {
         Double_t err1 = GetBinError(coord) * v2;
         Double_t err2 = h->GetBinError(coord) * v1;
         SetBinError(coord,TMath::Sqrt((err2 * err2 + err1 * err1)));
      }
   }

   //now deposit the result in the original histogram....
   delete [] coord;
}

//______________________________________________________________________________
void THnSparse::Divide(const THnSparse *h)
{
   // Divide this histogram by h
   // this = this/(h)
   // Note that if h has Sumw2 set, Sumw2 is automatically called for
   // this if not already set.
   // The resulting errors are calculated assuming uncorrelated content.

   // Check consistency of the input
   if (!CheckConsistency(h, "Divide"))return;

   // Trigger error calculation if h has it
   Bool_t wantErrors=kFALSE;
   if (!GetCalculateErrors() && h->GetCalculateErrors())
      wantErrors=kTRUE;

   // Remember original histogram statistics
   Double_t nEntries = fEntries;

   // Create a temporary histogram where to store the result
   TObjArray newaxes(fNdimensions);
   for (Int_t d = 0; d < fNdimensions; ++d) {
      newaxes.AddAt(GetAxis(d),d);
   }

   if (wantErrors) Sumw2();
   Bool_t didWarn = kFALSE;

   // Now divide the contents: also in this case we have the intersection of the sets of bins
   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);
   Double_t err = 0.;
   Double_t b22 = 0.;
   for (Long64_t i = 0; i < GetNbins(); ++i) {
      // Get the content of the bin from the first histogram
      Double_t v1 = GetBinContent(i, coord);
      // Now look at the bin with the same coordinates in h
      Double_t v2 = h->GetBinContent(coord);
      if (!v2) {
         v1 = 0.;
         v2 = 1.;
         if (!didWarn) {
            Warning("Divide(h)", "Histogram h has empty bins - division by zero! Setting bin to 0.");
            didWarn = kTRUE;
         }
      }
      SetBinContent(coord, v1 / v2);
      if (wantErrors) {
         Double_t err1 = GetBinError(coord) * v2;
         Double_t err2 = h->GetBinError(coord) * v1;
         b22 = v2 * v2;
         err = (err1 * err1 + err2 * err2) / (b22 * b22);
         SetBinError(coord, TMath::Sqrt(err));
      }
   }
   delete [] coord;
   SetEntries(nEntries);
}

//______________________________________________________________________________
void THnSparse::Divide(const THnSparse *h1, const THnSparse *h2, Double_t c1, Double_t c2, Option_t *option)
{
   // Replace contents of this histogram by multiplication of h1 by h2
   // this = (c1*h1)/(c2*h2)
   // Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for
   // this if not already set.
   // The resulting errors are calculated assuming uncorrelated content.
   // However, if option ="B" is specified, Binomial errors are computed.
   // In this case c1 and c2 do not make real sense and they are ignored.


   TString opt = option;
   opt.ToLower();
   Bool_t binomial = kFALSE;
   if (opt.Contains("b")) binomial = kTRUE;

   // Check consistency of the input
   if (!CheckConsistency(h1, "Divide") || !CheckConsistency(h2, "Divide"))return;
   if (!c2) {
      Error("Divide","Coefficient of dividing histogram cannot be zero");
      return;
   }

   Reset();

   // Trigger error calculation if h1 or h2 have it
   if (!GetCalculateErrors() && (h1->GetCalculateErrors()|| h2->GetCalculateErrors() != 0))
      Sumw2();

   // Count filled bins
   Long64_t nFilledBins=0;

   // Now divide the contents: we have the intersection of the sets of bins

   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);
   Float_t w = 0.;
   Float_t err = 0.;
   Float_t b22 = 0.;
   Bool_t didWarn = kFALSE;

   for (Long64_t i = 0; i < h1->GetNbins(); ++i) {
      // Get the content of the bin from the first histogram
      Double_t v1 = h1->GetBinContent(i, coord);
      // Now look at the bin with the same coordinates in h2
      Double_t v2 = h2->GetBinContent(coord);
      if (!v2) {
         v1 = 0.;
         v2 = 1.;
         if (!didWarn) {
            Warning("Divide(h1, h2)", "Histogram h2 has empty bins - division by zero! Setting bin to 0.");
            didWarn = kTRUE;
         }
      }
      nFilledBins++;
      SetBinContent(coord, c1 * v1 / c2 / v2);
      if(GetCalculateErrors()){
         Double_t err1=h1->GetBinError(coord);
         Double_t err2=h2->GetBinError(coord);
         if (binomial) {
            if (v1 != v2) {
               w = v1 / v2;
               err2 *= w;
               err = TMath::Abs( ( (1. - 2.*w) * err1 * err1 + err2 * err2 ) / (v2 * v2) );
            } else {
               err = 0;
            }
         } else {
            c1 *= c1;
            c2 *= c2;
            b22 = v2 * v2 * c2;
            err1 *= v2;
            err2 *= v1;
            err = c1 * c2 * (err1 * err1 + err2 * err2) / (b22 * b22);
         }
         SetBinError(coord,TMath::Sqrt(err));
      }
   }

   delete [] coord;
   fFilledBins = nFilledBins;

   // Set as entries in the result histogram the entries in the numerator
   SetEntries(h1->GetEntries());
}

//______________________________________________________________________________
Bool_t THnSparse::CheckConsistency(const THnSparse *h, const char *tag) const
{
   // Consistency check on (some of) the parameters of two histograms (for operations).

   if (fNdimensions!=h->GetNdimensions()) {
      Warning(tag,"Different number of dimensions, cannot carry out operation on the histograms");
      return kFALSE;
   }
   for (Int_t dim = 0; dim < fNdimensions; dim++){
      if (GetAxis(dim)->GetNbins()!=h->GetAxis(dim)->GetNbins()) {
         Warning(tag,"Different number of bins on axis %i, cannot carry out operation on the histograms", dim);
         return kFALSE;
      }
   }
   return kTRUE;
}

//______________________________________________________________________________
void THnSparse::SetBinEdges(Int_t idim, const Double_t* bins)
{
   // Set the axis # of bins and bin limits on dimension idim

   TAxis* axis = (TAxis*) fAxes[idim];
   axis->Set(axis->GetNbins(), bins);
}

//______________________________________________________________________________
void THnSparse::SetBinContent(const Int_t* coord, Double_t v)
{
   // Set content of bin with coordinates "coord" to "v"

   GetCompactCoord()->SetCoord(coord);
   Long_t bin = GetBinIndexForCurrentBin(kTRUE);
   THnSparseArrayChunk* chunk = GetChunk(bin / fChunkSize);
   chunk->fContent->SetAt(v, bin % fChunkSize);
}

//______________________________________________________________________________
void THnSparse::SetBinError(const Int_t* coord, Double_t e)
{
   // Set error of bin with coordinates "coord" to "e", enable errors if needed

   GetCompactCoord()->SetCoord(coord);
   Long_t bin = GetBinIndexForCurrentBin(kTRUE);

   THnSparseArrayChunk* chunk = GetChunk(bin / fChunkSize);
   if (!chunk->fSumw2 ) {
      // if fSumw2 is zero GetCalcualteErrors should return false
      assert(!GetCalculateErrors() );
      Sumw2(); // enable error calculation
   }
   
   chunk->fSumw2->SetAt(e*e, bin % fChunkSize);
}

//______________________________________________________________________________
void THnSparse::Sumw2()
{
   // Enable calculation of errors

   if (GetCalculateErrors()) return;

   fTsumw2 = 0.;
   TIter iChunk(&fBinContent);
   THnSparseArrayChunk* chunk = 0;
   while ((chunk = (THnSparseArrayChunk*) iChunk()))
      chunk->Sumw2();
}

//______________________________________________________________________________
THnSparse* THnSparse::Rebin(Int_t group) const
{
   // Combine the content of "group" neighboring bins into
   // a new bin and return the resulting THnSparse.
   // For group=2 and a 3 dimensional histogram, all "blocks"
   // of 2*2*2 bins will be put into a bin.

   Int_t* ngroup = new Int_t[GetNdimensions()];
   for (Int_t d = 0; d < GetNdimensions(); ++d)
      ngroup[d] = group;
   THnSparse* ret = Rebin(ngroup);
   delete [] ngroup;
   return ret;
}

//______________________________________________________________________________
THnSparse* THnSparse::Rebin(const Int_t* group) const
{
   // Combine the content of "group" neighboring bins for each dimension
   // into a new bin and return the resulting THnSparse.
   // For group={2,1,1} and a 3 dimensional histogram, pairs of x-bins
   // will be grouped.

   Int_t ndim = GetNdimensions();
   TString name(GetName());
   for (Int_t d = 0; d < ndim; ++d)
      name += Form("_%d", group[d]);


   TString title(GetTitle());
   Ssiz_t posInsert = title.First(';');
   if (posInsert == kNPOS) {
      title += " rebin ";
      for (Int_t d = 0; d < ndim; ++d)
         title += Form("{%d}", group[d]);
   } else {
      for (Int_t d = ndim - 1; d >= 0; --d)
         title.Insert(posInsert, Form("{%d}", group[d]));
      title.Insert(posInsert, " rebin ");
   }

   TObjArray newaxes(ndim);
   newaxes.SetOwner();
   for (Int_t d = 0; d < ndim; ++d) {
      newaxes.AddAt(GetAxis(d)->Clone(),d);
      if (group[d] > 1) {
         TAxis* newaxis = (TAxis*) newaxes.At(d);
         Int_t newbins = (newaxis->GetNbins() + group[d] - 1) / group[d];
         if (newaxis->GetXbins() && newaxis->GetXbins()->GetSize()) {
            // variable bins
            Double_t *edges = new Double_t[newbins + 1];
            for (Int_t i = 0; i < newbins + 1; ++i)
               if (group[d] * i <= newaxis->GetNbins())
                  edges[i] = newaxis->GetXbins()->At(group[d] * i);
               else edges[i] = newaxis->GetXmax();
            newaxis->Set(newbins, edges);
         } else {
            newaxis->Set(newbins, newaxis->GetXmin(), newaxis->GetXmax());
         }
      }
   }

   THnSparse* h = CloneEmpty(name.Data(), title.Data(), &newaxes, fChunkSize);
   Bool_t haveErrors = GetCalculateErrors();
   Bool_t wantErrors = haveErrors;

   Int_t* bins  = new Int_t[ndim];
   Int_t* coord = new Int_t[fNdimensions];
   memset(coord, 0, sizeof(Int_t) * fNdimensions);
   Double_t err = 0.;
   Double_t preverr = 0.;
   Double_t v = 0.;

   for (Long64_t i = 0; i < GetNbins(); ++i) {
      v = GetBinContent(i, coord);
      for (Int_t d = 0; d < ndim; ++d)
         bins[d] = TMath::CeilNint( (double) coord[d]/group[d] );

      if (wantErrors) {
         if (haveErrors) {
            err = GetBinError(i);
            err *= err;
         } else err = v;
         preverr = h->GetBinError(bins);
         h->SetBinError(bins, TMath::Sqrt(preverr * preverr + err));
      }

      // only _after_ error calculation, or sqrt(v) is taken into account!
      h->AddBinContent(bins, v);
   }

   delete [] bins;
   delete [] coord;

   h->SetEntries(fEntries);

   return h;

}

//______________________________________________________________________________
void THnSparse::Reset(Option_t * /*option = ""*/)
{
   // Clear the histogram
   fFilledBins = 0;
   fEntries = 0.;
   fTsumw = 0.;
   fTsumw2 = -1.;
   fBins.Delete();
   fBinsContinued.Clear();
   fBinContent.Delete();
   if (fIntegralStatus != kNoInt) {
      delete [] fIntegral;
      fIntegralStatus = kNoInt;
   }
}

//______________________________________________________________________________
Double_t THnSparse::ComputeIntegral()
{
   // Calculate the integral of the histogram

   // delete old integral
   if (fIntegralStatus != kNoInt) {
      delete [] fIntegral;
      fIntegralStatus = kNoInt;
   }

   // check number of bins
   if (GetNbins() == 0) {
      Error("ComputeIntegral", "The histogram must have at least one bin.");
      return 0.;
   }

   // allocate integral array
   fIntegral = new Double_t [GetNbins() + 1];
   fIntegral[0] = 0.;

   // fill integral array with contents of regular bins (non over/underflow)
   Int_t* coord = new Int_t[fNdimensions];
   for (Long64_t i = 0; i < GetNbins(); ++i) {
      Double_t v = GetBinContent(i, coord);

      // check whether the bin is regular
      bool regularBin = true;
      for (Int_t dim = 0; dim < fNdimensions; dim++)
         if (coord[dim] < 1 || coord[dim] > GetAxis(dim)->GetNbins()) {
            regularBin = false;
            break;
         }

      // if outlayer, count it with zero weight
      if (!regularBin) v = 0.;

      fIntegral[i + 1] = fIntegral[i] + v;
   }
   delete [] coord;

   // check sum of weights
   if (fIntegral[GetNbins()] == 0.) {
      Error("ComputeIntegral", "No hits in regular bins (non over/underflow).");
      delete [] fIntegral;
      return 0.;
   }

   // normalize the integral array
   for (Long64_t i = 0; i <= GetNbins(); ++i)
      fIntegral[i] = fIntegral[i] / fIntegral[GetNbins()];

   // set status to valid
   fIntegralStatus = kValidInt;
   return fIntegral[GetNbins()];
}
 THnSparse.cxx:1
 THnSparse.cxx:2
 THnSparse.cxx:3
 THnSparse.cxx:4
 THnSparse.cxx:5
 THnSparse.cxx:6
 THnSparse.cxx:7
 THnSparse.cxx:8
 THnSparse.cxx:9
 THnSparse.cxx:10
 THnSparse.cxx:11
 THnSparse.cxx:12
 THnSparse.cxx:13
 THnSparse.cxx:14
 THnSparse.cxx:15
 THnSparse.cxx:16
 THnSparse.cxx:17
 THnSparse.cxx:18
 THnSparse.cxx:19
 THnSparse.cxx:20
 THnSparse.cxx:21
 THnSparse.cxx:22
 THnSparse.cxx:23
 THnSparse.cxx:24
 THnSparse.cxx:25
 THnSparse.cxx:26
 THnSparse.cxx:27
 THnSparse.cxx:28
 THnSparse.cxx:29
 THnSparse.cxx:30
 THnSparse.cxx:31
 THnSparse.cxx:32
 THnSparse.cxx:33
 THnSparse.cxx:34
 THnSparse.cxx:35
 THnSparse.cxx:36
 THnSparse.cxx:37
 THnSparse.cxx:38
 THnSparse.cxx:39
 THnSparse.cxx:40
 THnSparse.cxx:41
 THnSparse.cxx:42
 THnSparse.cxx:43
 THnSparse.cxx:44
 THnSparse.cxx:45
 THnSparse.cxx:46
 THnSparse.cxx:47
 THnSparse.cxx:48
 THnSparse.cxx:49
 THnSparse.cxx:50
 THnSparse.cxx:51
 THnSparse.cxx:52
 THnSparse.cxx:53
 THnSparse.cxx:54
 THnSparse.cxx:55
 THnSparse.cxx:56
 THnSparse.cxx:57
 THnSparse.cxx:58
 THnSparse.cxx:59
 THnSparse.cxx:60
 THnSparse.cxx:61
 THnSparse.cxx:62
 THnSparse.cxx:63
 THnSparse.cxx:64
 THnSparse.cxx:65
 THnSparse.cxx:66
 THnSparse.cxx:67
 THnSparse.cxx:68
 THnSparse.cxx:69
 THnSparse.cxx:70
 THnSparse.cxx:71
 THnSparse.cxx:72
 THnSparse.cxx:73
 THnSparse.cxx:74
 THnSparse.cxx:75
 THnSparse.cxx:76
 THnSparse.cxx:77
 THnSparse.cxx:78
 THnSparse.cxx:79
 THnSparse.cxx:80
 THnSparse.cxx:81
 THnSparse.cxx:82
 THnSparse.cxx:83
 THnSparse.cxx:84
 THnSparse.cxx:85
 THnSparse.cxx:86
 THnSparse.cxx:87
 THnSparse.cxx:88
 THnSparse.cxx:89
 THnSparse.cxx:90
 THnSparse.cxx:91
 THnSparse.cxx:92
 THnSparse.cxx:93
 THnSparse.cxx:94
 THnSparse.cxx:95
 THnSparse.cxx:96
 THnSparse.cxx:97
 THnSparse.cxx:98
 THnSparse.cxx:99
 THnSparse.cxx:100
 THnSparse.cxx:101
 THnSparse.cxx:102
 THnSparse.cxx:103
 THnSparse.cxx:104
 THnSparse.cxx:105
 THnSparse.cxx:106
 THnSparse.cxx:107
 THnSparse.cxx:108
 THnSparse.cxx:109
 THnSparse.cxx:110
 THnSparse.cxx:111
 THnSparse.cxx:112
 THnSparse.cxx:113
 THnSparse.cxx:114
 THnSparse.cxx:115
 THnSparse.cxx:116
 THnSparse.cxx:117
 THnSparse.cxx:118
 THnSparse.cxx:119
 THnSparse.cxx:120
 THnSparse.cxx:121
 THnSparse.cxx:122
 THnSparse.cxx:123
 THnSparse.cxx:124
 THnSparse.cxx:125
 THnSparse.cxx:126
 THnSparse.cxx:127
 THnSparse.cxx:128
 THnSparse.cxx:129
 THnSparse.cxx:130
 THnSparse.cxx:131
 THnSparse.cxx:132
 THnSparse.cxx:133
 THnSparse.cxx:134
 THnSparse.cxx:135
 THnSparse.cxx:136
 THnSparse.cxx:137
 THnSparse.cxx:138
 THnSparse.cxx:139
 THnSparse.cxx:140
 THnSparse.cxx:141
 THnSparse.cxx:142
 THnSparse.cxx:143
 THnSparse.cxx:144
 THnSparse.cxx:145
 THnSparse.cxx:146
 THnSparse.cxx:147
 THnSparse.cxx:148
 THnSparse.cxx:149
 THnSparse.cxx:150
 THnSparse.cxx:151
 THnSparse.cxx:152
 THnSparse.cxx:153
 THnSparse.cxx:154
 THnSparse.cxx:155
 THnSparse.cxx:156
 THnSparse.cxx:157
 THnSparse.cxx:158
 THnSparse.cxx:159
 THnSparse.cxx:160
 THnSparse.cxx:161
 THnSparse.cxx:162
 THnSparse.cxx:163
 THnSparse.cxx:164
 THnSparse.cxx:165
 THnSparse.cxx:166
 THnSparse.cxx:167
 THnSparse.cxx:168
 THnSparse.cxx:169
 THnSparse.cxx:170
 THnSparse.cxx:171
 THnSparse.cxx:172
 THnSparse.cxx:173
 THnSparse.cxx:174
 THnSparse.cxx:175
 THnSparse.cxx:176
 THnSparse.cxx:177
 THnSparse.cxx:178
 THnSparse.cxx:179
 THnSparse.cxx:180
 THnSparse.cxx:181
 THnSparse.cxx:182
 THnSparse.cxx:183
 THnSparse.cxx:184
 THnSparse.cxx:185
 THnSparse.cxx:186
 THnSparse.cxx:187
 THnSparse.cxx:188
 THnSparse.cxx:189
 THnSparse.cxx:190
 THnSparse.cxx:191
 THnSparse.cxx:192
 THnSparse.cxx:193
 THnSparse.cxx:194
 THnSparse.cxx:195
 THnSparse.cxx:196
 THnSparse.cxx:197
 THnSparse.cxx:198
 THnSparse.cxx:199
 THnSparse.cxx:200
 THnSparse.cxx:201
 THnSparse.cxx:202
 THnSparse.cxx:203
 THnSparse.cxx:204
 THnSparse.cxx:205
 THnSparse.cxx:206
 THnSparse.cxx:207
 THnSparse.cxx:208
 THnSparse.cxx:209
 THnSparse.cxx:210
 THnSparse.cxx:211
 THnSparse.cxx:212
 THnSparse.cxx:213
 THnSparse.cxx:214
 THnSparse.cxx:215
 THnSparse.cxx:216
 THnSparse.cxx:217
 THnSparse.cxx:218
 THnSparse.cxx:219
 THnSparse.cxx:220
 THnSparse.cxx:221
 THnSparse.cxx:222
 THnSparse.cxx:223
 THnSparse.cxx:224
 THnSparse.cxx:225
 THnSparse.cxx:226
 THnSparse.cxx:227
 THnSparse.cxx:228
 THnSparse.cxx:229
 THnSparse.cxx:230
 THnSparse.cxx:231
 THnSparse.cxx:232
 THnSparse.cxx:233
 THnSparse.cxx:234
 THnSparse.cxx:235
 THnSparse.cxx:236
 THnSparse.cxx:237
 THnSparse.cxx:238
 THnSparse.cxx:239
 THnSparse.cxx:240
 THnSparse.cxx:241
 THnSparse.cxx:242
 THnSparse.cxx:243
 THnSparse.cxx:244
 THnSparse.cxx:245
 THnSparse.cxx:246
 THnSparse.cxx:247
 THnSparse.cxx:248
 THnSparse.cxx:249
 THnSparse.cxx:250
 THnSparse.cxx:251
 THnSparse.cxx:252
 THnSparse.cxx:253
 THnSparse.cxx:254
 THnSparse.cxx:255
 THnSparse.cxx:256
 THnSparse.cxx:257
 THnSparse.cxx:258
 THnSparse.cxx:259
 THnSparse.cxx:260
 THnSparse.cxx:261
 THnSparse.cxx:262
 THnSparse.cxx:263
 THnSparse.cxx:264
 THnSparse.cxx:265
 THnSparse.cxx:266
 THnSparse.cxx:267
 THnSparse.cxx:268
 THnSparse.cxx:269
 THnSparse.cxx:270
 THnSparse.cxx:271
 THnSparse.cxx:272
 THnSparse.cxx:273
 THnSparse.cxx:274
 THnSparse.cxx:275
 THnSparse.cxx:276
 THnSparse.cxx:277
 THnSparse.cxx:278
 THnSparse.cxx:279
 THnSparse.cxx:280
 THnSparse.cxx:281
 THnSparse.cxx:282
 THnSparse.cxx:283
 THnSparse.cxx:284
 THnSparse.cxx:285
 THnSparse.cxx:286
 THnSparse.cxx:287
 THnSparse.cxx:288
 THnSparse.cxx:289
 THnSparse.cxx:290
 THnSparse.cxx:291
 THnSparse.cxx:292
 THnSparse.cxx:293
 THnSparse.cxx:294
 THnSparse.cxx:295
 THnSparse.cxx:296
 THnSparse.cxx:297
 THnSparse.cxx:298
 THnSparse.cxx:299
 THnSparse.cxx:300
 THnSparse.cxx:301
 THnSparse.cxx:302
 THnSparse.cxx:303
 THnSparse.cxx:304
 THnSparse.cxx:305
 THnSparse.cxx:306
 THnSparse.cxx:307
 THnSparse.cxx:308
 THnSparse.cxx:309
 THnSparse.cxx:310
 THnSparse.cxx:311
 THnSparse.cxx:312
 THnSparse.cxx:313
 THnSparse.cxx:314
 THnSparse.cxx:315
 THnSparse.cxx:316
 THnSparse.cxx:317
 THnSparse.cxx:318
 THnSparse.cxx:319
 THnSparse.cxx:320
 THnSparse.cxx:321
 THnSparse.cxx:322
 THnSparse.cxx:323
 THnSparse.cxx:324
 THnSparse.cxx:325
 THnSparse.cxx:326
 THnSparse.cxx:327
 THnSparse.cxx:328
 THnSparse.cxx:329
 THnSparse.cxx:330
 THnSparse.cxx:331
 THnSparse.cxx:332
 THnSparse.cxx:333
 THnSparse.cxx:334
 THnSparse.cxx:335
 THnSparse.cxx:336
 THnSparse.cxx:337
 THnSparse.cxx:338
 THnSparse.cxx:339
 THnSparse.cxx:340
 THnSparse.cxx:341
 THnSparse.cxx:342
 THnSparse.cxx:343
 THnSparse.cxx:344
 THnSparse.cxx:345
 THnSparse.cxx:346
 THnSparse.cxx:347
 THnSparse.cxx:348
 THnSparse.cxx:349
 THnSparse.cxx:350
 THnSparse.cxx:351
 THnSparse.cxx:352
 THnSparse.cxx:353
 THnSparse.cxx:354
 THnSparse.cxx:355
 THnSparse.cxx:356
 THnSparse.cxx:357
 THnSparse.cxx:358
 THnSparse.cxx:359
 THnSparse.cxx:360
 THnSparse.cxx:361
 THnSparse.cxx:362
 THnSparse.cxx:363
 THnSparse.cxx:364
 THnSparse.cxx:365
 THnSparse.cxx:366
 THnSparse.cxx:367
 THnSparse.cxx:368
 THnSparse.cxx:369
 THnSparse.cxx:370
 THnSparse.cxx:371
 THnSparse.cxx:372
 THnSparse.cxx:373
 THnSparse.cxx:374
 THnSparse.cxx:375
 THnSparse.cxx:376
 THnSparse.cxx:377
 THnSparse.cxx:378
 THnSparse.cxx:379
 THnSparse.cxx:380
 THnSparse.cxx:381
 THnSparse.cxx:382
 THnSparse.cxx:383
 THnSparse.cxx:384
 THnSparse.cxx:385
 THnSparse.cxx:386
 THnSparse.cxx:387
 THnSparse.cxx:388
 THnSparse.cxx:389
 THnSparse.cxx:390
 THnSparse.cxx:391
 THnSparse.cxx:392
 THnSparse.cxx:393
 THnSparse.cxx:394
 THnSparse.cxx:395
 THnSparse.cxx:396
 THnSparse.cxx:397
 THnSparse.cxx:398
 THnSparse.cxx:399
 THnSparse.cxx:400
 THnSparse.cxx:401
 THnSparse.cxx:402
 THnSparse.cxx:403
 THnSparse.cxx:404
 THnSparse.cxx:405
 THnSparse.cxx:406
 THnSparse.cxx:407
 THnSparse.cxx:408
 THnSparse.cxx:409
 THnSparse.cxx:410
 THnSparse.cxx:411
 THnSparse.cxx:412
 THnSparse.cxx:413
 THnSparse.cxx:414
 THnSparse.cxx:415
 THnSparse.cxx:416
 THnSparse.cxx:417
 THnSparse.cxx:418
 THnSparse.cxx:419
 THnSparse.cxx:420
 THnSparse.cxx:421
 THnSparse.cxx:422
 THnSparse.cxx:423
 THnSparse.cxx:424
 THnSparse.cxx:425
 THnSparse.cxx:426
 THnSparse.cxx:427
 THnSparse.cxx:428
 THnSparse.cxx:429
 THnSparse.cxx:430
 THnSparse.cxx:431
 THnSparse.cxx:432
 THnSparse.cxx:433
 THnSparse.cxx:434
 THnSparse.cxx:435
 THnSparse.cxx:436
 THnSparse.cxx:437
 THnSparse.cxx:438
 THnSparse.cxx:439
 THnSparse.cxx:440
 THnSparse.cxx:441
 THnSparse.cxx:442
 THnSparse.cxx:443
 THnSparse.cxx:444
 THnSparse.cxx:445
 THnSparse.cxx:446
 THnSparse.cxx:447
 THnSparse.cxx:448
 THnSparse.cxx:449
 THnSparse.cxx:450
 THnSparse.cxx:451
 THnSparse.cxx:452
 THnSparse.cxx:453
 THnSparse.cxx:454
 THnSparse.cxx:455
 THnSparse.cxx:456
 THnSparse.cxx:457
 THnSparse.cxx:458
 THnSparse.cxx:459
 THnSparse.cxx:460
 THnSparse.cxx:461
 THnSparse.cxx:462
 THnSparse.cxx:463
 THnSparse.cxx:464
 THnSparse.cxx:465
 THnSparse.cxx:466
 THnSparse.cxx:467
 THnSparse.cxx:468
 THnSparse.cxx:469
 THnSparse.cxx:470
 THnSparse.cxx:471
 THnSparse.cxx:472
 THnSparse.cxx:473
 THnSparse.cxx:474
 THnSparse.cxx:475
 THnSparse.cxx:476
 THnSparse.cxx:477
 THnSparse.cxx:478
 THnSparse.cxx:479
 THnSparse.cxx:480
 THnSparse.cxx:481
 THnSparse.cxx:482
 THnSparse.cxx:483
 THnSparse.cxx:484
 THnSparse.cxx:485
 THnSparse.cxx:486
 THnSparse.cxx:487
 THnSparse.cxx:488
 THnSparse.cxx:489
 THnSparse.cxx:490
 THnSparse.cxx:491
 THnSparse.cxx:492
 THnSparse.cxx:493
 THnSparse.cxx:494
 THnSparse.cxx:495
 THnSparse.cxx:496
 THnSparse.cxx:497
 THnSparse.cxx:498
 THnSparse.cxx:499
 THnSparse.cxx:500
 THnSparse.cxx:501
 THnSparse.cxx:502
 THnSparse.cxx:503
 THnSparse.cxx:504
 THnSparse.cxx:505
 THnSparse.cxx:506
 THnSparse.cxx:507
 THnSparse.cxx:508
 THnSparse.cxx:509
 THnSparse.cxx:510
 THnSparse.cxx:511
 THnSparse.cxx:512
 THnSparse.cxx:513
 THnSparse.cxx:514
 THnSparse.cxx:515
 THnSparse.cxx:516
 THnSparse.cxx:517
 THnSparse.cxx:518
 THnSparse.cxx:519
 THnSparse.cxx:520
 THnSparse.cxx:521
 THnSparse.cxx:522
 THnSparse.cxx:523
 THnSparse.cxx:524
 THnSparse.cxx:525
 THnSparse.cxx:526
 THnSparse.cxx:527
 THnSparse.cxx:528
 THnSparse.cxx:529
 THnSparse.cxx:530
 THnSparse.cxx:531
 THnSparse.cxx:532
 THnSparse.cxx:533
 THnSparse.cxx:534
 THnSparse.cxx:535
 THnSparse.cxx:536
 THnSparse.cxx:537
 THnSparse.cxx:538
 THnSparse.cxx:539
 THnSparse.cxx:540
 THnSparse.cxx:541
 THnSparse.cxx:542
 THnSparse.cxx:543
 THnSparse.cxx:544
 THnSparse.cxx:545
 THnSparse.cxx:546
 THnSparse.cxx:547
 THnSparse.cxx:548
 THnSparse.cxx:549
 THnSparse.cxx:550
 THnSparse.cxx:551
 THnSparse.cxx:552
 THnSparse.cxx:553
 THnSparse.cxx:554
 THnSparse.cxx:555
 THnSparse.cxx:556
 THnSparse.cxx:557
 THnSparse.cxx:558
 THnSparse.cxx:559
 THnSparse.cxx:560
 THnSparse.cxx:561
 THnSparse.cxx:562
 THnSparse.cxx:563
 THnSparse.cxx:564
 THnSparse.cxx:565
 THnSparse.cxx:566
 THnSparse.cxx:567
 THnSparse.cxx:568
 THnSparse.cxx:569
 THnSparse.cxx:570
 THnSparse.cxx:571
 THnSparse.cxx:572
 THnSparse.cxx:573
 THnSparse.cxx:574
 THnSparse.cxx:575
 THnSparse.cxx:576
 THnSparse.cxx:577
 THnSparse.cxx:578
 THnSparse.cxx:579
 THnSparse.cxx:580
 THnSparse.cxx:581
 THnSparse.cxx:582
 THnSparse.cxx:583
 THnSparse.cxx:584
 THnSparse.cxx:585
 THnSparse.cxx:586
 THnSparse.cxx:587
 THnSparse.cxx:588
 THnSparse.cxx:589
 THnSparse.cxx:590
 THnSparse.cxx:591
 THnSparse.cxx:592
 THnSparse.cxx:593
 THnSparse.cxx:594
 THnSparse.cxx:595
 THnSparse.cxx:596
 THnSparse.cxx:597
 THnSparse.cxx:598
 THnSparse.cxx:599
 THnSparse.cxx:600
 THnSparse.cxx:601
 THnSparse.cxx:602
 THnSparse.cxx:603
 THnSparse.cxx:604
 THnSparse.cxx:605
 THnSparse.cxx:606
 THnSparse.cxx:607
 THnSparse.cxx:608
 THnSparse.cxx:609
 THnSparse.cxx:610
 THnSparse.cxx:611
 THnSparse.cxx:612
 THnSparse.cxx:613
 THnSparse.cxx:614
 THnSparse.cxx:615
 THnSparse.cxx:616
 THnSparse.cxx:617
 THnSparse.cxx:618
 THnSparse.cxx:619
 THnSparse.cxx:620
 THnSparse.cxx:621
 THnSparse.cxx:622
 THnSparse.cxx:623
 THnSparse.cxx:624
 THnSparse.cxx:625
 THnSparse.cxx:626
 THnSparse.cxx:627
 THnSparse.cxx:628
 THnSparse.cxx:629
 THnSparse.cxx:630
 THnSparse.cxx:631
 THnSparse.cxx:632
 THnSparse.cxx:633
 THnSparse.cxx:634
 THnSparse.cxx:635
 THnSparse.cxx:636
 THnSparse.cxx:637
 THnSparse.cxx:638
 THnSparse.cxx:639
 THnSparse.cxx:640
 THnSparse.cxx:641
 THnSparse.cxx:642
 THnSparse.cxx:643
 THnSparse.cxx:644
 THnSparse.cxx:645
 THnSparse.cxx:646
 THnSparse.cxx:647
 THnSparse.cxx:648
 THnSparse.cxx:649
 THnSparse.cxx:650
 THnSparse.cxx:651
 THnSparse.cxx:652
 THnSparse.cxx:653
 THnSparse.cxx:654
 THnSparse.cxx:655
 THnSparse.cxx:656
 THnSparse.cxx:657
 THnSparse.cxx:658
 THnSparse.cxx:659
 THnSparse.cxx:660
 THnSparse.cxx:661
 THnSparse.cxx:662
 THnSparse.cxx:663
 THnSparse.cxx:664
 THnSparse.cxx:665
 THnSparse.cxx:666
 THnSparse.cxx:667
 THnSparse.cxx:668
 THnSparse.cxx:669
 THnSparse.cxx:670
 THnSparse.cxx:671
 THnSparse.cxx:672
 THnSparse.cxx:673
 THnSparse.cxx:674
 THnSparse.cxx:675
 THnSparse.cxx:676
 THnSparse.cxx:677
 THnSparse.cxx:678
 THnSparse.cxx:679
 THnSparse.cxx:680
 THnSparse.cxx:681
 THnSparse.cxx:682
 THnSparse.cxx:683
 THnSparse.cxx:684
 THnSparse.cxx:685
 THnSparse.cxx:686
 THnSparse.cxx:687
 THnSparse.cxx:688
 THnSparse.cxx:689
 THnSparse.cxx:690
 THnSparse.cxx:691
 THnSparse.cxx:692
 THnSparse.cxx:693
 THnSparse.cxx:694
 THnSparse.cxx:695
 THnSparse.cxx:696
 THnSparse.cxx:697
 THnSparse.cxx:698
 THnSparse.cxx:699
 THnSparse.cxx:700
 THnSparse.cxx:701
 THnSparse.cxx:702
 THnSparse.cxx:703
 THnSparse.cxx:704
 THnSparse.cxx:705
 THnSparse.cxx:706
 THnSparse.cxx:707
 THnSparse.cxx:708
 THnSparse.cxx:709
 THnSparse.cxx:710
 THnSparse.cxx:711
 THnSparse.cxx:712
 THnSparse.cxx:713
 THnSparse.cxx:714
 THnSparse.cxx:715
 THnSparse.cxx:716
 THnSparse.cxx:717
 THnSparse.cxx:718
 THnSparse.cxx:719
 THnSparse.cxx:720
 THnSparse.cxx:721
 THnSparse.cxx:722
 THnSparse.cxx:723
 THnSparse.cxx:724
 THnSparse.cxx:725
 THnSparse.cxx:726
 THnSparse.cxx:727
 THnSparse.cxx:728
 THnSparse.cxx:729
 THnSparse.cxx:730
 THnSparse.cxx:731
 THnSparse.cxx:732
 THnSparse.cxx:733
 THnSparse.cxx:734
 THnSparse.cxx:735
 THnSparse.cxx:736
 THnSparse.cxx:737
 THnSparse.cxx:738
 THnSparse.cxx:739
 THnSparse.cxx:740
 THnSparse.cxx:741
 THnSparse.cxx:742
 THnSparse.cxx:743
 THnSparse.cxx:744
 THnSparse.cxx:745
 THnSparse.cxx:746
 THnSparse.cxx:747
 THnSparse.cxx:748
 THnSparse.cxx:749
 THnSparse.cxx:750
 THnSparse.cxx:751
 THnSparse.cxx:752
 THnSparse.cxx:753
 THnSparse.cxx:754
 THnSparse.cxx:755
 THnSparse.cxx:756
 THnSparse.cxx:757
 THnSparse.cxx:758
 THnSparse.cxx:759
 THnSparse.cxx:760
 THnSparse.cxx:761
 THnSparse.cxx:762
 THnSparse.cxx:763
 THnSparse.cxx:764
 THnSparse.cxx:765
 THnSparse.cxx:766
 THnSparse.cxx:767
 THnSparse.cxx:768
 THnSparse.cxx:769
 THnSparse.cxx:770
 THnSparse.cxx:771
 THnSparse.cxx:772
 THnSparse.cxx:773
 THnSparse.cxx:774
 THnSparse.cxx:775
 THnSparse.cxx:776
 THnSparse.cxx:777
 THnSparse.cxx:778
 THnSparse.cxx:779
 THnSparse.cxx:780
 THnSparse.cxx:781
 THnSparse.cxx:782
 THnSparse.cxx:783
 THnSparse.cxx:784
 THnSparse.cxx:785
 THnSparse.cxx:786
 THnSparse.cxx:787
 THnSparse.cxx:788
 THnSparse.cxx:789
 THnSparse.cxx:790
 THnSparse.cxx:791
 THnSparse.cxx:792
 THnSparse.cxx:793
 THnSparse.cxx:794
 THnSparse.cxx:795
 THnSparse.cxx:796
 THnSparse.cxx:797
 THnSparse.cxx:798
 THnSparse.cxx:799
 THnSparse.cxx:800
 THnSparse.cxx:801
 THnSparse.cxx:802
 THnSparse.cxx:803
 THnSparse.cxx:804
 THnSparse.cxx:805
 THnSparse.cxx:806
 THnSparse.cxx:807
 THnSparse.cxx:808
 THnSparse.cxx:809
 THnSparse.cxx:810
 THnSparse.cxx:811
 THnSparse.cxx:812
 THnSparse.cxx:813
 THnSparse.cxx:814
 THnSparse.cxx:815
 THnSparse.cxx:816
 THnSparse.cxx:817
 THnSparse.cxx:818
 THnSparse.cxx:819
 THnSparse.cxx:820
 THnSparse.cxx:821
 THnSparse.cxx:822
 THnSparse.cxx:823
 THnSparse.cxx:824
 THnSparse.cxx:825
 THnSparse.cxx:826
 THnSparse.cxx:827
 THnSparse.cxx:828
 THnSparse.cxx:829
 THnSparse.cxx:830
 THnSparse.cxx:831
 THnSparse.cxx:832
 THnSparse.cxx:833
 THnSparse.cxx:834
 THnSparse.cxx:835
 THnSparse.cxx:836
 THnSparse.cxx:837
 THnSparse.cxx:838
 THnSparse.cxx:839
 THnSparse.cxx:840
 THnSparse.cxx:841
 THnSparse.cxx:842
 THnSparse.cxx:843
 THnSparse.cxx:844
 THnSparse.cxx:845
 THnSparse.cxx:846
 THnSparse.cxx:847
 THnSparse.cxx:848
 THnSparse.cxx:849
 THnSparse.cxx:850
 THnSparse.cxx:851
 THnSparse.cxx:852
 THnSparse.cxx:853
 THnSparse.cxx:854
 THnSparse.cxx:855
 THnSparse.cxx:856
 THnSparse.cxx:857
 THnSparse.cxx:858
 THnSparse.cxx:859
 THnSparse.cxx:860
 THnSparse.cxx:861
 THnSparse.cxx:862
 THnSparse.cxx:863
 THnSparse.cxx:864
 THnSparse.cxx:865
 THnSparse.cxx:866
 THnSparse.cxx:867
 THnSparse.cxx:868
 THnSparse.cxx:869
 THnSparse.cxx:870
 THnSparse.cxx:871
 THnSparse.cxx:872
 THnSparse.cxx:873
 THnSparse.cxx:874
 THnSparse.cxx:875
 THnSparse.cxx:876
 THnSparse.cxx:877
 THnSparse.cxx:878
 THnSparse.cxx:879
 THnSparse.cxx:880
 THnSparse.cxx:881
 THnSparse.cxx:882
 THnSparse.cxx:883
 THnSparse.cxx:884
 THnSparse.cxx:885
 THnSparse.cxx:886
 THnSparse.cxx:887
 THnSparse.cxx:888
 THnSparse.cxx:889
 THnSparse.cxx:890
 THnSparse.cxx:891
 THnSparse.cxx:892
 THnSparse.cxx:893
 THnSparse.cxx:894
 THnSparse.cxx:895
 THnSparse.cxx:896
 THnSparse.cxx:897
 THnSparse.cxx:898
 THnSparse.cxx:899
 THnSparse.cxx:900
 THnSparse.cxx:901
 THnSparse.cxx:902
 THnSparse.cxx:903
 THnSparse.cxx:904
 THnSparse.cxx:905
 THnSparse.cxx:906
 THnSparse.cxx:907
 THnSparse.cxx:908
 THnSparse.cxx:909
 THnSparse.cxx:910
 THnSparse.cxx:911
 THnSparse.cxx:912
 THnSparse.cxx:913
 THnSparse.cxx:914
 THnSparse.cxx:915
 THnSparse.cxx:916
 THnSparse.cxx:917
 THnSparse.cxx:918
 THnSparse.cxx:919
 THnSparse.cxx:920
 THnSparse.cxx:921
 THnSparse.cxx:922
 THnSparse.cxx:923
 THnSparse.cxx:924
 THnSparse.cxx:925
 THnSparse.cxx:926
 THnSparse.cxx:927
 THnSparse.cxx:928
 THnSparse.cxx:929
 THnSparse.cxx:930
 THnSparse.cxx:931
 THnSparse.cxx:932
 THnSparse.cxx:933
 THnSparse.cxx:934
 THnSparse.cxx:935
 THnSparse.cxx:936
 THnSparse.cxx:937
 THnSparse.cxx:938
 THnSparse.cxx:939
 THnSparse.cxx:940
 THnSparse.cxx:941
 THnSparse.cxx:942
 THnSparse.cxx:943
 THnSparse.cxx:944
 THnSparse.cxx:945
 THnSparse.cxx:946
 THnSparse.cxx:947
 THnSparse.cxx:948
 THnSparse.cxx:949
 THnSparse.cxx:950
 THnSparse.cxx:951
 THnSparse.cxx:952
 THnSparse.cxx:953
 THnSparse.cxx:954
 THnSparse.cxx:955
 THnSparse.cxx:956
 THnSparse.cxx:957
 THnSparse.cxx:958
 THnSparse.cxx:959
 THnSparse.cxx:960
 THnSparse.cxx:961
 THnSparse.cxx:962
 THnSparse.cxx:963
 THnSparse.cxx:964
 THnSparse.cxx:965
 THnSparse.cxx:966
 THnSparse.cxx:967
 THnSparse.cxx:968
 THnSparse.cxx:969
 THnSparse.cxx:970
 THnSparse.cxx:971
 THnSparse.cxx:972
 THnSparse.cxx:973
 THnSparse.cxx:974
 THnSparse.cxx:975
 THnSparse.cxx:976
 THnSparse.cxx:977
 THnSparse.cxx:978
 THnSparse.cxx:979
 THnSparse.cxx:980
 THnSparse.cxx:981
 THnSparse.cxx:982
 THnSparse.cxx:983
 THnSparse.cxx:984
 THnSparse.cxx:985
 THnSparse.cxx:986
 THnSparse.cxx:987
 THnSparse.cxx:988
 THnSparse.cxx:989
 THnSparse.cxx:990
 THnSparse.cxx:991
 THnSparse.cxx:992
 THnSparse.cxx:993
 THnSparse.cxx:994
 THnSparse.cxx:995
 THnSparse.cxx:996
 THnSparse.cxx:997
 THnSparse.cxx:998
 THnSparse.cxx:999
 THnSparse.cxx:1000
 THnSparse.cxx:1001
 THnSparse.cxx:1002
 THnSparse.cxx:1003
 THnSparse.cxx:1004
 THnSparse.cxx:1005
 THnSparse.cxx:1006
 THnSparse.cxx:1007
 THnSparse.cxx:1008
 THnSparse.cxx:1009
 THnSparse.cxx:1010
 THnSparse.cxx:1011
 THnSparse.cxx:1012
 THnSparse.cxx:1013
 THnSparse.cxx:1014
 THnSparse.cxx:1015
 THnSparse.cxx:1016
 THnSparse.cxx:1017
 THnSparse.cxx:1018
 THnSparse.cxx:1019
 THnSparse.cxx:1020
 THnSparse.cxx:1021
 THnSparse.cxx:1022
 THnSparse.cxx:1023
 THnSparse.cxx:1024
 THnSparse.cxx:1025
 THnSparse.cxx:1026
 THnSparse.cxx:1027
 THnSparse.cxx:1028
 THnSparse.cxx:1029
 THnSparse.cxx:1030
 THnSparse.cxx:1031
 THnSparse.cxx:1032
 THnSparse.cxx:1033
 THnSparse.cxx:1034
 THnSparse.cxx:1035
 THnSparse.cxx:1036
 THnSparse.cxx:1037
 THnSparse.cxx:1038
 THnSparse.cxx:1039
 THnSparse.cxx:1040
 THnSparse.cxx:1041
 THnSparse.cxx:1042
 THnSparse.cxx:1043
 THnSparse.cxx:1044
 THnSparse.cxx:1045
 THnSparse.cxx:1046
 THnSparse.cxx:1047
 THnSparse.cxx:1048
 THnSparse.cxx:1049
 THnSparse.cxx:1050
 THnSparse.cxx:1051
 THnSparse.cxx:1052
 THnSparse.cxx:1053
 THnSparse.cxx:1054
 THnSparse.cxx:1055
 THnSparse.cxx:1056
 THnSparse.cxx:1057
 THnSparse.cxx:1058
 THnSparse.cxx:1059
 THnSparse.cxx:1060
 THnSparse.cxx:1061
 THnSparse.cxx:1062
 THnSparse.cxx:1063
 THnSparse.cxx:1064
 THnSparse.cxx:1065
 THnSparse.cxx:1066
 THnSparse.cxx:1067
 THnSparse.cxx:1068
 THnSparse.cxx:1069
 THnSparse.cxx:1070
 THnSparse.cxx:1071
 THnSparse.cxx:1072
 THnSparse.cxx:1073
 THnSparse.cxx:1074
 THnSparse.cxx:1075
 THnSparse.cxx:1076
 THnSparse.cxx:1077
 THnSparse.cxx:1078
 THnSparse.cxx:1079
 THnSparse.cxx:1080
 THnSparse.cxx:1081
 THnSparse.cxx:1082
 THnSparse.cxx:1083
 THnSparse.cxx:1084
 THnSparse.cxx:1085
 THnSparse.cxx:1086
 THnSparse.cxx:1087
 THnSparse.cxx:1088
 THnSparse.cxx:1089
 THnSparse.cxx:1090
 THnSparse.cxx:1091
 THnSparse.cxx:1092
 THnSparse.cxx:1093
 THnSparse.cxx:1094
 THnSparse.cxx:1095
 THnSparse.cxx:1096
 THnSparse.cxx:1097
 THnSparse.cxx:1098
 THnSparse.cxx:1099
 THnSparse.cxx:1100
 THnSparse.cxx:1101
 THnSparse.cxx:1102
 THnSparse.cxx:1103
 THnSparse.cxx:1104
 THnSparse.cxx:1105
 THnSparse.cxx:1106
 THnSparse.cxx:1107
 THnSparse.cxx:1108
 THnSparse.cxx:1109
 THnSparse.cxx:1110
 THnSparse.cxx:1111
 THnSparse.cxx:1112
 THnSparse.cxx:1113
 THnSparse.cxx:1114
 THnSparse.cxx:1115
 THnSparse.cxx:1116
 THnSparse.cxx:1117
 THnSparse.cxx:1118
 THnSparse.cxx:1119
 THnSparse.cxx:1120
 THnSparse.cxx:1121
 THnSparse.cxx:1122
 THnSparse.cxx:1123
 THnSparse.cxx:1124
 THnSparse.cxx:1125
 THnSparse.cxx:1126
 THnSparse.cxx:1127
 THnSparse.cxx:1128
 THnSparse.cxx:1129
 THnSparse.cxx:1130
 THnSparse.cxx:1131
 THnSparse.cxx:1132
 THnSparse.cxx:1133
 THnSparse.cxx:1134
 THnSparse.cxx:1135
 THnSparse.cxx:1136
 THnSparse.cxx:1137
 THnSparse.cxx:1138
 THnSparse.cxx:1139
 THnSparse.cxx:1140
 THnSparse.cxx:1141
 THnSparse.cxx:1142
 THnSparse.cxx:1143
 THnSparse.cxx:1144
 THnSparse.cxx:1145
 THnSparse.cxx:1146
 THnSparse.cxx:1147
 THnSparse.cxx:1148
 THnSparse.cxx:1149
 THnSparse.cxx:1150
 THnSparse.cxx:1151
 THnSparse.cxx:1152
 THnSparse.cxx:1153
 THnSparse.cxx:1154
 THnSparse.cxx:1155
 THnSparse.cxx:1156
 THnSparse.cxx:1157
 THnSparse.cxx:1158
 THnSparse.cxx:1159
 THnSparse.cxx:1160
 THnSparse.cxx:1161
 THnSparse.cxx:1162
 THnSparse.cxx:1163
 THnSparse.cxx:1164
 THnSparse.cxx:1165
 THnSparse.cxx:1166
 THnSparse.cxx:1167
 THnSparse.cxx:1168
 THnSparse.cxx:1169
 THnSparse.cxx:1170
 THnSparse.cxx:1171
 THnSparse.cxx:1172
 THnSparse.cxx:1173
 THnSparse.cxx:1174
 THnSparse.cxx:1175
 THnSparse.cxx:1176
 THnSparse.cxx:1177
 THnSparse.cxx:1178
 THnSparse.cxx:1179
 THnSparse.cxx:1180
 THnSparse.cxx:1181
 THnSparse.cxx:1182
 THnSparse.cxx:1183
 THnSparse.cxx:1184
 THnSparse.cxx:1185
 THnSparse.cxx:1186
 THnSparse.cxx:1187
 THnSparse.cxx:1188
 THnSparse.cxx:1189
 THnSparse.cxx:1190
 THnSparse.cxx:1191
 THnSparse.cxx:1192
 THnSparse.cxx:1193
 THnSparse.cxx:1194
 THnSparse.cxx:1195
 THnSparse.cxx:1196
 THnSparse.cxx:1197
 THnSparse.cxx:1198
 THnSparse.cxx:1199
 THnSparse.cxx:1200
 THnSparse.cxx:1201
 THnSparse.cxx:1202
 THnSparse.cxx:1203
 THnSparse.cxx:1204
 THnSparse.cxx:1205
 THnSparse.cxx:1206
 THnSparse.cxx:1207
 THnSparse.cxx:1208
 THnSparse.cxx:1209
 THnSparse.cxx:1210
 THnSparse.cxx:1211
 THnSparse.cxx:1212
 THnSparse.cxx:1213
 THnSparse.cxx:1214
 THnSparse.cxx:1215
 THnSparse.cxx:1216
 THnSparse.cxx:1217
 THnSparse.cxx:1218
 THnSparse.cxx:1219
 THnSparse.cxx:1220
 THnSparse.cxx:1221
 THnSparse.cxx:1222
 THnSparse.cxx:1223
 THnSparse.cxx:1224
 THnSparse.cxx:1225
 THnSparse.cxx:1226
 THnSparse.cxx:1227
 THnSparse.cxx:1228
 THnSparse.cxx:1229
 THnSparse.cxx:1230
 THnSparse.cxx:1231
 THnSparse.cxx:1232
 THnSparse.cxx:1233
 THnSparse.cxx:1234
 THnSparse.cxx:1235
 THnSparse.cxx:1236
 THnSparse.cxx:1237
 THnSparse.cxx:1238
 THnSparse.cxx:1239
 THnSparse.cxx:1240
 THnSparse.cxx:1241
 THnSparse.cxx:1242
 THnSparse.cxx:1243
 THnSparse.cxx:1244
 THnSparse.cxx:1245
 THnSparse.cxx:1246
 THnSparse.cxx:1247
 THnSparse.cxx:1248
 THnSparse.cxx:1249
 THnSparse.cxx:1250
 THnSparse.cxx:1251
 THnSparse.cxx:1252
 THnSparse.cxx:1253
 THnSparse.cxx:1254
 THnSparse.cxx:1255
 THnSparse.cxx:1256
 THnSparse.cxx:1257
 THnSparse.cxx:1258
 THnSparse.cxx:1259
 THnSparse.cxx:1260
 THnSparse.cxx:1261
 THnSparse.cxx:1262
 THnSparse.cxx:1263
 THnSparse.cxx:1264
 THnSparse.cxx:1265
 THnSparse.cxx:1266
 THnSparse.cxx:1267
 THnSparse.cxx:1268
 THnSparse.cxx:1269
 THnSparse.cxx:1270
 THnSparse.cxx:1271
 THnSparse.cxx:1272
 THnSparse.cxx:1273
 THnSparse.cxx:1274
 THnSparse.cxx:1275
 THnSparse.cxx:1276
 THnSparse.cxx:1277
 THnSparse.cxx:1278
 THnSparse.cxx:1279
 THnSparse.cxx:1280
 THnSparse.cxx:1281
 THnSparse.cxx:1282
 THnSparse.cxx:1283
 THnSparse.cxx:1284
 THnSparse.cxx:1285
 THnSparse.cxx:1286
 THnSparse.cxx:1287
 THnSparse.cxx:1288
 THnSparse.cxx:1289
 THnSparse.cxx:1290
 THnSparse.cxx:1291
 THnSparse.cxx:1292
 THnSparse.cxx:1293
 THnSparse.cxx:1294
 THnSparse.cxx:1295
 THnSparse.cxx:1296
 THnSparse.cxx:1297
 THnSparse.cxx:1298
 THnSparse.cxx:1299
 THnSparse.cxx:1300
 THnSparse.cxx:1301
 THnSparse.cxx:1302
 THnSparse.cxx:1303
 THnSparse.cxx:1304
 THnSparse.cxx:1305
 THnSparse.cxx:1306
 THnSparse.cxx:1307
 THnSparse.cxx:1308
 THnSparse.cxx:1309
 THnSparse.cxx:1310
 THnSparse.cxx:1311
 THnSparse.cxx:1312
 THnSparse.cxx:1313
 THnSparse.cxx:1314
 THnSparse.cxx:1315
 THnSparse.cxx:1316
 THnSparse.cxx:1317
 THnSparse.cxx:1318
 THnSparse.cxx:1319
 THnSparse.cxx:1320
 THnSparse.cxx:1321
 THnSparse.cxx:1322
 THnSparse.cxx:1323
 THnSparse.cxx:1324
 THnSparse.cxx:1325
 THnSparse.cxx:1326
 THnSparse.cxx:1327
 THnSparse.cxx:1328
 THnSparse.cxx:1329
 THnSparse.cxx:1330
 THnSparse.cxx:1331
 THnSparse.cxx:1332
 THnSparse.cxx:1333
 THnSparse.cxx:1334
 THnSparse.cxx:1335
 THnSparse.cxx:1336
 THnSparse.cxx:1337
 THnSparse.cxx:1338
 THnSparse.cxx:1339
 THnSparse.cxx:1340
 THnSparse.cxx:1341
 THnSparse.cxx:1342
 THnSparse.cxx:1343
 THnSparse.cxx:1344
 THnSparse.cxx:1345
 THnSparse.cxx:1346
 THnSparse.cxx:1347
 THnSparse.cxx:1348
 THnSparse.cxx:1349
 THnSparse.cxx:1350
 THnSparse.cxx:1351
 THnSparse.cxx:1352
 THnSparse.cxx:1353
 THnSparse.cxx:1354
 THnSparse.cxx:1355
 THnSparse.cxx:1356
 THnSparse.cxx:1357
 THnSparse.cxx:1358
 THnSparse.cxx:1359
 THnSparse.cxx:1360
 THnSparse.cxx:1361
 THnSparse.cxx:1362
 THnSparse.cxx:1363
 THnSparse.cxx:1364
 THnSparse.cxx:1365
 THnSparse.cxx:1366
 THnSparse.cxx:1367
 THnSparse.cxx:1368
 THnSparse.cxx:1369
 THnSparse.cxx:1370
 THnSparse.cxx:1371
 THnSparse.cxx:1372
 THnSparse.cxx:1373
 THnSparse.cxx:1374
 THnSparse.cxx:1375
 THnSparse.cxx:1376
 THnSparse.cxx:1377
 THnSparse.cxx:1378
 THnSparse.cxx:1379
 THnSparse.cxx:1380
 THnSparse.cxx:1381
 THnSparse.cxx:1382
 THnSparse.cxx:1383
 THnSparse.cxx:1384
 THnSparse.cxx:1385
 THnSparse.cxx:1386
 THnSparse.cxx:1387
 THnSparse.cxx:1388
 THnSparse.cxx:1389
 THnSparse.cxx:1390
 THnSparse.cxx:1391
 THnSparse.cxx:1392
 THnSparse.cxx:1393
 THnSparse.cxx:1394
 THnSparse.cxx:1395
 THnSparse.cxx:1396
 THnSparse.cxx:1397
 THnSparse.cxx:1398
 THnSparse.cxx:1399
 THnSparse.cxx:1400
 THnSparse.cxx:1401
 THnSparse.cxx:1402
 THnSparse.cxx:1403
 THnSparse.cxx:1404
 THnSparse.cxx:1405
 THnSparse.cxx:1406
 THnSparse.cxx:1407
 THnSparse.cxx:1408
 THnSparse.cxx:1409
 THnSparse.cxx:1410
 THnSparse.cxx:1411
 THnSparse.cxx:1412
 THnSparse.cxx:1413
 THnSparse.cxx:1414
 THnSparse.cxx:1415
 THnSparse.cxx:1416
 THnSparse.cxx:1417
 THnSparse.cxx:1418
 THnSparse.cxx:1419
 THnSparse.cxx:1420
 THnSparse.cxx:1421
 THnSparse.cxx:1422
 THnSparse.cxx:1423
 THnSparse.cxx:1424
 THnSparse.cxx:1425
 THnSparse.cxx:1426
 THnSparse.cxx:1427
 THnSparse.cxx:1428
 THnSparse.cxx:1429
 THnSparse.cxx:1430
 THnSparse.cxx:1431
 THnSparse.cxx:1432
 THnSparse.cxx:1433
 THnSparse.cxx:1434
 THnSparse.cxx:1435
 THnSparse.cxx:1436
 THnSparse.cxx:1437
 THnSparse.cxx:1438
 THnSparse.cxx:1439
 THnSparse.cxx:1440
 THnSparse.cxx:1441
 THnSparse.cxx:1442
 THnSparse.cxx:1443
 THnSparse.cxx:1444
 THnSparse.cxx:1445
 THnSparse.cxx:1446
 THnSparse.cxx:1447
 THnSparse.cxx:1448
 THnSparse.cxx:1449
 THnSparse.cxx:1450
 THnSparse.cxx:1451
 THnSparse.cxx:1452
 THnSparse.cxx:1453
 THnSparse.cxx:1454
 THnSparse.cxx:1455
 THnSparse.cxx:1456
 THnSparse.cxx:1457
 THnSparse.cxx:1458
 THnSparse.cxx:1459
 THnSparse.cxx:1460
 THnSparse.cxx:1461
 THnSparse.cxx:1462
 THnSparse.cxx:1463
 THnSparse.cxx:1464
 THnSparse.cxx:1465
 THnSparse.cxx:1466
 THnSparse.cxx:1467
 THnSparse.cxx:1468
 THnSparse.cxx:1469
 THnSparse.cxx:1470
 THnSparse.cxx:1471
 THnSparse.cxx:1472
 THnSparse.cxx:1473
 THnSparse.cxx:1474
 THnSparse.cxx:1475