Some thoughts about histogram classes in root [LONG MESSAGE]

From: Vincent Colin de Verdiere (Vincent.Colin.de.Verdiere@cern.ch)
Date: Mon Feb 14 2000 - 13:48:50 MET


I started using 3D histograms in root and I came with some remarks
and thoughts about Histogram classes in root ... 

//////////  Inheritance tree //////////////////////////

There 1 class by number of dimensions: TH1, TH2 and TH3. This is very
nice. It is, for sure, very convenient to make TH2 and TH3 derive from
TH1. But, on the OO point of view, it should also means that TH3 specific
methods are declared and defined in TH3 and not in TH1. This is currently
not the case : for exemple, there are fill() functions with 1, 2, 3
dimensions in TH1...why ? 
if people are building 3D histograms using TH1 -> it's wrong. The
class name should be something like THisto.
if people are building 3D histograms using TH3 -> it's useless to
define the functions in TH1.

One of my favorite examples:
//////////////////
TProfile *TH1::ProfileX(...) {
  if (GetDimension() != 2) {
     Error("ProfileX","Not a 2-D histogram");
     return 0;
  }
....
}
////////////////
What does this function has to do in TH1 ???


There are also examples on the other side:
 multiple definition of the same function
fill3 has exactly the same code in TH3S, TH3C, TH3F...
why not using inheritance by defining it in TH3 ?

A main point is that using OO programming has to simplify the user's or
programmer's life. I don't think that puting all methods in a single class
with many "if" cases really helps the user. Are there any technical
(linked with cint?) or historical reasons for this architecture ?
If not, it seems to me very easy to move methods from TH1 to TH2 or
TH3 without breaking some backward compatibility.

///////////// Naming //////////////////////////////////////
 fill12, fill3, fill...
   * can anyone tell me what are the differences between these functions ?
   * without reading the source code ?

//////////// Some functions which could be added ? ////////
 access to min/max values on each axis:
exple:
 Float_t TH1::GetXmin(void) { return GetXaxis()->GetXmin(); }
 Float_t TH3::GetZmax(void) { return GetZaxis()->GetXmax(); }
   .... 


// A function to get all 3 coordinates of a bin in a 3D histogram out
// of the 1D bin number of TH1.
// usefull to give any meaning to GetMaximumBin() function when used
// in TH3.
 void TH3::Bin1ToBin3(Int_t bin, Int_t& binx, Int_t& biny, Int_t&
binz)
{
  Int_t nbbinX= GetNbinsX()+2;
  Int_t nbbinY= GetNbinsY()+2;

  binx= bin%nbbinX;
  biny= (bin/nbbinX) % nbbinY;
  binz= (bin/nbbinX) / nbbinY;
}

// A function to get original values of bins.
// for exple:
void TH3::BinToCoord(Int_t bin, Float_t& x, Float_t& y, Float_t& z)
{
  TAxis* xax = GetXaxis();
  TAxis* yax = GetYaxis();
  TAxis* zax = GetZaxis();
  
  Int_t binx, biny, binz;
  Bin1ToBin3(bin, binx, biny, binz);

  x= xax->GetBinCenter(binx);
  y= yax->GetBinCenter(biny);
  z= zax->GetBinCenter(binz);
}


-- Vincent

Vincent Colin de Verdiere (vincent.colin.de.verdiere@cern.ch)
at home: 44, rue de la Fruitiere, 01710-Thoiry tel: 04 50 20 87 90
at work: CERN, division EP, Office 13-1-038, CH - 1211 Geneva 23
        tel: (+41) 22 76 72839, fax: (+41) 22 767 9075



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:18 MET