Histograms in gDirectory.

From: Alexander Yuryevich Zvyagin (Alexander.Zviagine@cern.ch)
Date: Thu Jul 09 1998 - 15:53:08 MEST


Dear ROOTers,

I'd like to discuss one feature of the TH1 class: how the member function
void TH1::Build() works. (You'll find the function body at the end of this
E-mail.) This function is called when TH1 constructor is invoked.

// Example 1.
TH1F a("E",....), b("E",....);

This is *good* C++ code and this is *bad* ROOT code.
What will ROOT do?
The histogram a("E",...) is created and added
(See TObject::AppendDirectory()) to the current directory. On default it
is gDirectory. OK, you have histogram 'a'. Then ROOT will try to create
histogram b("E",...) with the *same* name "E" as the histogram 'a' has.
ROOT will find that object with the same name already exists in the
gDirectory and it'll try to *delete* it. So ROOT will delete pointer to
statically allocated object. Something like this:
{
  int a;
  int *b = &a;
  delete b;
}
This is bad thing. Your *good* C++ code will crash. I think this is
ROOT bug.

There are several ways how to write better code.
1. Use pointers: TH1F *
2. Test that there isn't object with the same name in the gDirectory.
3. Create your own TDirectory structure.
4. Use next code:
   
   // Example 2.
   TDirectory *gDirectory_save = gDirectory;
   gDirectory=NULL;   // ROOT assumes that NULL==0
   TH1F a("E",....), b("E",....);
   gDirectory=gDirectory_save;
   
   This mechanism simply turn off the inserting of histograms in the list
   list of gDirectory objects.

Comments?

With best wishes,
Alexander Zvyagin.

void TH1::Build()
{
//*-*-*-*-*-*-*-*-*-*Creates histogram basic data structure*-*-*-*-*-*-*-*-
//*-*                ======================================

   fEntries       = 0;
   fNormFactor    = 0;
   fTsumw         = fTsumw2=fTsumwx=fTsumwx2=0;
   fMaximum       = -1111;
   fMinimum       = -1111;
   fXaxis.SetName("xaxis");
   fYaxis.SetName("yaxis");
   fZaxis.SetName("zaxis");
   fYaxis.Set(1,0.,1.);
   fZaxis.Set(1,0.,1.);
   fContour.Set(0);

   UseCurrentStyle();

   if (gDirectory) {
      TH1 *hold = (TH1*)gDirectory->GetList()->FindObject(GetName());
      if (hold) {
         Warning("Build","Replacing existing histogram: %s",GetName());
         delete hold;
      }
      AppendDirectory();
   }
   fDirectory = gDirectory;
   fFunctions = new TList(this);
}
============================================================================



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:34 MET