TDirectory::GetObject in compiled code

Hello everybody,
I’m stuck with a strange problem (at least for me it’s strange). I’m looping through a root-file containing a few histograms. Whenever I find a histogram with a certain tag in its name i want to get also its counterpart which has basically the same name just without the tag.
when i do

 TH1 hist = 0;
 gDirectory->GetObject(name.c_str(),hist);
 if(hist)
  ...

in the CINT manually, everything works fine. But as soon as i compile my script (.L *.C+) and do the same the whole thing crashes. Even more confusing for me is that if i exchange the last line (if(hist)) by hist->Draw() everything works fine?!
Any ideas? Or what am I missing here.
Thanks in advance
Moritz

pleaseprovide ashort running script and a data file.

Rene

First of all, sorry for the lengthy script.
The first part is just adapted from one of the tutorials which loops through the file and all subdirectories. When it finds a histogram which has the tag “_uncorr” in its name it tries to get the corresponding histogramm which has the same name just without the tag using GetObject.
That seems to work because I can draw that histogramm (line 50). But if i uncomment line 47 & 48 the script crashes.
By the way I’m using root 5.22.00.
Again thanks for the help.
script.c (1.49 KB)
test.root (77.5 KB)

You are confusing the histogram name with the pointer to the histogram !!

I suggest changing your code like shown below

Rene

[code]void readDir(TDirectory *dir)
{
TDirectory *dirsav = gDirectory;
TDirectory *currentDir = gDirectory;
TIter next(dir->GetListOfKeys());
TKey key;
while ((key = (TKey
)next()))
{
// if the Key is a folder read the directory and skip the rest of the block
if (key->IsFolder()) {
dir->cd(key->GetName());
currentDir = gDirectory;
readDir(currentDir);
dirsav->cd();
continue;
}
// so the key is not a folder
TClass *cl = gROOT->GetClass(key->GetClassName());
if (!cl->InheritsFrom(“TH1”)) continue;
std::string histname = key->GetName();
size_t pos = histname.find("_uncorr");

	if(pos!= string::npos){
		std::string name_to_find = histname.substr(0,pos);
		TH1 *hist_to_find = (TH1*)key->ReadObj();
		
		// AS SOON AS YOU UNCOMMENT THE NEXT LINE SCRIPT will not CRASH
		if(hist_to_find) {
	            std::cout << hist_to_find->GetName();
		    hist_to_find->Draw();
                    }
	}
}

}[/code]

Sorry but that’s not my intention.
I not only want to get the histogram which the key is pointing (“some_name_uncorr”) to, but also the corresponding one (“some_name”) of which I only know the name and the fact that it is in the same subdirectory. In the end I want to substract the 2 histograms. And I thought I could get the Histogram just by its name or at least I understood the documentation for TDirectory::Get(const char* namecycle) that way.
Sorry if i got that wrong.

NO, you can of course get your histogram by name (what I am showing you above).
What was badly wrong in your case was that you confused a char* with a TH1* pointer !!

Rene

Alright, now it’s working.
The error was not that I confused a char* with a TH1* pointer but it was the std::cout.
I don’t know what’s wrong with that but any std::cout crashes the script.
So i can basically take your example uncomment the line with std::cout and it works and if i take it back in even with a changed argument like std::cout << “some output” << std::endl; the sript will crash!

This was precisely my point. Look again at your original cout statement. You were calling a member function of a char* (and you thought that it was a TH1*) but it was not !

Rene

Sorry but what i did was calling

and hist_to_find was of type TH1* so the GetName should give me a const char* or am I wrong here?
The other thing if I forget about any pointers and just do:

the script will also crash!

Could you provide a script2.C using your test.root file reproducing your problem and that I can execute by executing
.x script2.C

Rene

Hmm here’s the thing i spent quite some time now testing all the possibilities.
If i make the script an unamed script so that it can be executed by .X script2.c(gFile) then it works
But if i compile it (.L script2.c+) and then invoke it (readDir(gFile)) it crashes.
I thought I just forgot to include <Riostream.h> but that didn’t work either.
script2.c (1.71 KB)

I cannot reproduce your problem when correctly uncommenting your lines.

Rene

[code]#include
#include
#include
#include
#include <math.h>
#include <TFile.h>
#include <TDirectory.h>
#include <TCollection.h>
#include <TH1.h>
#include <TH2.h>
#include <TKey.h>
#include <TROOT.h>
#include <TClass.h>
#include <Riostream.h>

// function declarations_________________________________________________________________
void readDir(TDirectory *dir);
//_______________________________________________________________________________________
void readDir(TDirectory *dir)
//void script_Brun(TDirectory *dir)
{
TDirectory *dirsav = gDirectory;
TDirectory *currentDir = gDirectory;
TIter next(dir->GetListOfKeys());
TKey key;
while ((key = (TKey
)next()))
{
// if the Key is a folder read the directory and skip the rest of the block
if (key->IsFolder()) {
dir->cd(key->GetName());
currentDir = gDirectory;
readDir(currentDir);
//script_Brun(currentDir);
dirsav->cd();
continue;
}
// so the key is not a folder
TClass *cl = gROOT->GetClass(key->GetClassName());
if (!cl->InheritsFrom(“TH1”)) continue;
std::string histname = key->GetName();
//cout << “key->GetName(): " << histname.c_str() << endl;
size_t pos = histname.find(”_uncorr");

  if(pos!= string::npos){
     std::string name_to_find = histname.substr(0,pos);
     TH1 *hist_to_find = (TH1*)key->ReadObj();
     
     // AS SOON AS YOU UNCOMMENT THE NEXT LINE SCRIPT will not CRASH
     if(hist_to_find) {
		std::cout << hist_to_find->GetName();	
		hist_to_find->Draw();
     }
	 std::cout << "some output" << std::endl;
  }

}
}[/code]