// @(#)root/hist:$Id$
// Author: Axel Naumann, Nov 2011

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

#ifndef ROOT_THN
#define ROOT_THN

#ifndef ROOT_THnBase
#include "THnBase.h"
#endif

#ifndef ROOT_TNDArray
#include "TNDArray.h"
#endif

#ifndef ROOT_TArrayD
#include "TArrayD.h"
#endif

#ifndef ROOT_TObjArray
#include "TObjArray.h"
#endif

#ifndef ROOT_TAxis
#include "TAxis.h"
#endif

#ifndef ROOT_TMath
#include "TMath.h"
#endif

class TH1;
class TH1D;
class TH2D;
class TH3D;
class THnSparse;
class TF1;



class THn: public THnBase {
private:
   THn(const THn&); // Not implemented
   THn& operator=(const THn&); // Not implemented

protected:
   void FillBin(Long64_t bin, Double_t w) {
      // Increment the bin content of "bin" by "w",
      // return the bin index.
      GetArray().AddAt(bin, w);
      if (GetCalculateErrors()) {
         fSumw2.AddAt(bin, w * w);
      }
      FillBinBase(w);
   }

   void AllocCoordBuf() const;
   void InitStorage(Int_t* nbins, Int_t chunkSize);

   THn(): fCoordBuf() {}
   THn(const char* name, const char* title, Int_t dim, const Int_t* nbins,
       const Double_t* xmin, const Double_t* xmax);

public:
   virtual ~THn();

   static THn* CreateHn(const char* name, const char* title, const TH1* h1) {
      return (THn*) CreateHnAny(name, title, h1, kFALSE /*THn*/, -1);
   }
   static THn* CreateHn(const char* name, const char* title, const THnBase* hn) {
      return (THn*) CreateHnAny(name, title, hn, kFALSE /*THn*/, -1);
   }

   ROOT::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const;
   Long64_t GetNbins() const { return GetArray().GetNbins(); }

   Long64_t GetBin(const Int_t* idx) const {
      return GetArray().GetBin(idx);
   }
   Long64_t GetBin(const Double_t* x) const {
      if (!fCoordBuf) AllocCoordBuf();
      for (Int_t d = 0; d < fNdimensions; ++d) {
         fCoordBuf[d] = GetAxis(d)->FindFixBin(x[d]);
      }
      return GetArray().GetBin(fCoordBuf);
   }
   Long64_t GetBin(const char* name[]) const {
      if (!fCoordBuf) AllocCoordBuf();
      for (Int_t d = 0; d < fNdimensions; ++d) {
         fCoordBuf[d] = GetAxis(d)->FindBin(name[d]);
      }
      return GetArray().GetBin(fCoordBuf);
   }

   Long64_t GetBin(const Int_t* idx, Bool_t /*allocate*/ = kTRUE) {
      return const_cast<const THn*>(this)->GetBin(idx);
   }
   Long64_t GetBin(const Double_t* x, Bool_t /*allocate*/ = kTRUE) {
      return const_cast<const THn*>(this)->GetBin(x);
   }
   Long64_t GetBin(const char* name[], Bool_t /*allocate*/ = kTRUE) {
      return const_cast<const THn*>(this)->GetBin(name);
   }

   void SetBinContent(const Int_t* idx, Double_t v) {
      // Forwards to THnBase::SetBinContent().
      // Non-virtual, CINT-compatible replacement of a using declaration.
      THnBase::SetBinContent(idx, v);
   }
    void SetBinContent(Long64_t bin, Double_t v) {
      GetArray().SetAsDouble(bin, v);
   }
   void SetBinError2(Long64_t bin, Double_t e2) {
      if (!GetCalculateErrors()) Sumw2();
      fSumw2.At(bin) = e2;
   }
   void AddBinContent(const Int_t* idx, Double_t v = 1.) {
      // Forwards to THnBase::SetBinContent().
      // Non-virtual, CINT-compatible replacement of a using declaration.
      THnBase::AddBinContent(idx, v);
   }
   void AddBinContent(Long64_t bin, Double_t v = 1.) {
      GetArray().AddAt(bin, v);
   }
   void AddBinError2(Long64_t bin, Double_t e2) {
      fSumw2.At(bin) += e2;
   }
   Double_t GetBinContent(const Int_t *idx) const {
      // Forwards to THnBase::GetBinContent() overload.
      // Non-virtual, CINT-compatible replacement of a using declaration.
      return THnBase::GetBinContent(idx);
   }
   Double_t GetBinContent(Long64_t bin, Int_t* idx = 0) const {
      // Get the content of bin, and set its index if idx is != 0.
      if (idx) {
         const TNDArray& arr = GetArray();
         Long64_t prevCellSize = arr.GetNbins();
         for (Int_t i = 0; i < GetNdimensions(); ++i) {
            Long64_t cellSize = arr.GetCellSize(i);
            idx[i] = (bin % prevCellSize) / cellSize;
            prevCellSize = cellSize;
         }
      }
      return GetArray().AtAsDouble(bin);
   }
   Double_t GetBinError2(Long64_t linidx) const {
      return GetCalculateErrors() ? fSumw2.At(linidx) : GetBinContent(linidx);
   }

   virtual const TNDArray& GetArray() const = 0;
   virtual TNDArray& GetArray() = 0;

   void Sumw2();

   TH1D*      Projection(Int_t xDim, Option_t* option = "") const {
      // Forwards to THnBase::Projection().
      // Non-virtual, as a CINT-compatible replacement of a using
      // declaration.
      return THnBase::Projection(xDim, option);
   }

   TH2D*      Projection(Int_t yDim, Int_t xDim,
                         Option_t* option = "") const {
      // Forwards to THnBase::Projection().
      // Non-virtual, as a CINT-compatible replacement of a using
      // declaration.
      return THnBase::Projection(yDim, xDim, option);
   }

   TH3D*      Projection(Int_t xDim, Int_t yDim, Int_t zDim,
                         Option_t* option = "") const {
      // Forwards to THnBase::Projection().
      // Non-virtual, as a CINT-compatible replacement of a using
      // declaration.
      return THnBase::Projection(xDim, yDim, zDim, option);
   }

   THn*       Projection(Int_t ndim, const Int_t* dim,
                         Option_t* option = "") const {
      return (THn*) ProjectionND(ndim, dim, option);
   }

   THn*       Rebin(Int_t group) const {
      return (THn*) RebinBase(group);
   }
   THn*       Rebin(const Int_t* group) const {
      return (THn*) RebinBase(group);
   }

   void Reset(Option_t* option = "");

protected:
   TNDArrayT<Double_t> fSumw2; // bin error, lazy allocation happens in TNDArrayT
   mutable Int_t* fCoordBuf; //! Temporary buffer

   ClassDef(THn, 1); //Base class for multi-dimensional histogram
};



//______________________________________________________________________________
//
// Templated implementation of the abstract base THn.
// All functionality and the interfaces to be used are in THn!
//
// THn does not know how to store any bin content itself. Instead, this
// is delegated to the derived, templated class: the template parameter decides
// what the format for the bin content is. The actual storage is delegated to
// TNDArrayT<T>.
//
// Typedefs exist for template parematers with ROOT's generic types:
//
//   Templated name        Typedef       Bin content type
//   THnT<Char_t>          THnC          Char_t
//   THnT<Short_t>         THnS          Short_t
//   THnT<Int_t>           THnI          Int_t
//   THnT<Long_t>          THnL          Long_t
//   THnT<Float_t>         THnF          Float_t
//   THnT<Double_t>        THnD          Double_t
//
// We recommend to use THnC wherever possible, and to map its value space
// of 256 possible values to e.g. float values outside the class. This saves an
// enourmous amount of memory. Only if more than 256 values need to be
// distinguished should e.g. THnS or even THnF be chosen.
//
// Implementation detail: the derived, templated class is kept extremely small
// on purpose. That way the (templated thus inlined) uses of this class will
// only create a small amount of machine code, in contrast to e.g. STL.
//______________________________________________________________________________

template <typename T>
class THnT: public THn {
public:
   THnT() {}

   THnT(const char* name, const char* title,
       Int_t dim, const Int_t* nbins,
       const Double_t* xmin, const Double_t* xmax):
   THn(name, title, dim, nbins, xmin, xmax),
   fArray(dim, nbins, true)  {}

   const TNDArray& GetArray() const { return fArray; }
   TNDArray& GetArray() { return fArray; }

protected:
   TNDArrayT<T> fArray; // bin content
   ClassDef(THnT, 1); // multi-dimensional histogram with templated storage
};

typedef THnT<Float_t>  THnF;
typedef THnT<Double_t> THnD;
typedef THnT<Char_t>   THnC;
typedef THnT<Short_t>  THnS;
typedef THnT<Int_t>    THnI;
typedef THnT<Long_t>   THnL;
typedef THnT<Long64_t> THnL64;

#endif // ROOT_THN
 THn.h:1
 THn.h:2
 THn.h:3
 THn.h:4
 THn.h:5
 THn.h:6
 THn.h:7
 THn.h:8
 THn.h:9
 THn.h:10
 THn.h:11
 THn.h:12
 THn.h:13
 THn.h:14
 THn.h:15
 THn.h:16
 THn.h:17
 THn.h:18
 THn.h:19
 THn.h:20
 THn.h:21
 THn.h:22
 THn.h:23
 THn.h:24
 THn.h:25
 THn.h:26
 THn.h:27
 THn.h:28
 THn.h:29
 THn.h:30
 THn.h:31
 THn.h:32
 THn.h:33
 THn.h:34
 THn.h:35
 THn.h:36
 THn.h:37
 THn.h:38
 THn.h:39
 THn.h:40
 THn.h:41
 THn.h:42
 THn.h:43
 THn.h:44
 THn.h:45
 THn.h:46
 THn.h:47
 THn.h:48
 THn.h:49
 THn.h:50
 THn.h:51
 THn.h:52
 THn.h:53
 THn.h:54
 THn.h:55
 THn.h:56
 THn.h:57
 THn.h:58
 THn.h:59
 THn.h:60
 THn.h:61
 THn.h:62
 THn.h:63
 THn.h:64
 THn.h:65
 THn.h:66
 THn.h:67
 THn.h:68
 THn.h:69
 THn.h:70
 THn.h:71
 THn.h:72
 THn.h:73
 THn.h:74
 THn.h:75
 THn.h:76
 THn.h:77
 THn.h:78
 THn.h:79
 THn.h:80
 THn.h:81
 THn.h:82
 THn.h:83
 THn.h:84
 THn.h:85
 THn.h:86
 THn.h:87
 THn.h:88
 THn.h:89
 THn.h:90
 THn.h:91
 THn.h:92
 THn.h:93
 THn.h:94
 THn.h:95
 THn.h:96
 THn.h:97
 THn.h:98
 THn.h:99
 THn.h:100
 THn.h:101
 THn.h:102
 THn.h:103
 THn.h:104
 THn.h:105
 THn.h:106
 THn.h:107
 THn.h:108
 THn.h:109
 THn.h:110
 THn.h:111
 THn.h:112
 THn.h:113
 THn.h:114
 THn.h:115
 THn.h:116
 THn.h:117
 THn.h:118
 THn.h:119
 THn.h:120
 THn.h:121
 THn.h:122
 THn.h:123
 THn.h:124
 THn.h:125
 THn.h:126
 THn.h:127
 THn.h:128
 THn.h:129
 THn.h:130
 THn.h:131
 THn.h:132
 THn.h:133
 THn.h:134
 THn.h:135
 THn.h:136
 THn.h:137
 THn.h:138
 THn.h:139
 THn.h:140
 THn.h:141
 THn.h:142
 THn.h:143
 THn.h:144
 THn.h:145
 THn.h:146
 THn.h:147
 THn.h:148
 THn.h:149
 THn.h:150
 THn.h:151
 THn.h:152
 THn.h:153
 THn.h:154
 THn.h:155
 THn.h:156
 THn.h:157
 THn.h:158
 THn.h:159
 THn.h:160
 THn.h:161
 THn.h:162
 THn.h:163
 THn.h:164
 THn.h:165
 THn.h:166
 THn.h:167
 THn.h:168
 THn.h:169
 THn.h:170
 THn.h:171
 THn.h:172
 THn.h:173
 THn.h:174
 THn.h:175
 THn.h:176
 THn.h:177
 THn.h:178
 THn.h:179
 THn.h:180
 THn.h:181
 THn.h:182
 THn.h:183
 THn.h:184
 THn.h:185
 THn.h:186
 THn.h:187
 THn.h:188
 THn.h:189
 THn.h:190
 THn.h:191
 THn.h:192
 THn.h:193
 THn.h:194
 THn.h:195
 THn.h:196
 THn.h:197
 THn.h:198
 THn.h:199
 THn.h:200
 THn.h:201
 THn.h:202
 THn.h:203
 THn.h:204
 THn.h:205
 THn.h:206
 THn.h:207
 THn.h:208
 THn.h:209
 THn.h:210
 THn.h:211
 THn.h:212
 THn.h:213
 THn.h:214
 THn.h:215
 THn.h:216
 THn.h:217
 THn.h:218
 THn.h:219
 THn.h:220
 THn.h:221
 THn.h:222
 THn.h:223
 THn.h:224
 THn.h:225
 THn.h:226
 THn.h:227
 THn.h:228
 THn.h:229
 THn.h:230
 THn.h:231
 THn.h:232
 THn.h:233
 THn.h:234
 THn.h:235
 THn.h:236
 THn.h:237
 THn.h:238
 THn.h:239
 THn.h:240
 THn.h:241
 THn.h:242
 THn.h:243
 THn.h:244
 THn.h:245
 THn.h:246
 THn.h:247
 THn.h:248
 THn.h:249
 THn.h:250
 THn.h:251
 THn.h:252
 THn.h:253
 THn.h:254
 THn.h:255
 THn.h:256
 THn.h:257
 THn.h:258
 THn.h:259
 THn.h:260
 THn.h:261
 THn.h:262
 THn.h:263
 THn.h:264
 THn.h:265