Accessing internal directories in compiled script

I am trying to use TMVA over a wide range of parameters, and want to access the histograms saved in the output root file. I can get this to work if I don’t compile the script, by using ->cd().

#include <sstream>
void GetBDTEfficiencies(){
	TFile *f = new TFile();
	ofstream ofile;
	ofile.open("Efficiencies2.dat");	
	ofile << "RunNum, ROC, BDTVal_For_1e-5, effB, effS\n";	
	for ( int i =1; i <=84; i++)
	{
		if ( (i >= 37 && i <= 48) || i == 80) continue;
		stringstream ssi;
		ssi << i;		
		string fname = "MultiJet/SS_TMVA_Out_" + ssi.str() + "_MJ.root";
		cout << fname << endl;
		f->Open(fname.c_str());
		
		double effB = 1e-5;
		
		Method_BDT->cd();
		BDTD->cd();
		
		int binnum = MVA_BDTD_effB->FindLastBinAbove(effB);
		double BDTval = MVA_BDTD_effB->GetBinCenter(binnum);
		
		double BDTROC = 1 - MVA_BDTD_effBvsS->Integral();
		
		int binnum_S = MVA_BDTD_effS->FindBin(BDTval);
		double effS = MVA_BDTD_effS->GetBinContent(binnum_S);
				
		cout << i << ",\t" << BDTROC << ",\t" << BDTval << ",\t" << effB << ",\t" << effS << endl;		
		ofile << i << ",\t" << BDTROC << ",\t" << BDTval << ",\t" << effB << ",\t" << effS << endl;
		
		f->Close("R");
	}
	ofile.close();
}

However, when I try to run the script with the compiler, I get errors stating

[quote]Processing GetBDTEfficiencies.C+…
Info in TUnixSystem::ACLiC: creating shared library /ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies_C.so
In file included from /ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/GetBDTEfficiencies_C_ACLiC_dict.h:34,
from /ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/GetBDTEfficiencies_C_ACLiC_dict.cxx:17:
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C: In function ‘void GetBDTEfficiencies()’:
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:3: error: ‘TFile’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:3: error: ‘f’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:3: error: expected type-specifier before ‘TFile’
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:3: error: expected ‘;’ before ‘TFile’
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:4: error: aggregate ‘std::ofstream ofile’ has incomplete type and cannot be defined
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:16: error: ‘cout’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:21: error: ‘Method_BDT’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:22: error: ‘BDTD’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:25: error: ‘MVA_BDTD_effB’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:28: error: ‘MVA_BDTD_effBvsS’ was not declared in this scope
/ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/./GetBDTEfficiencies.C:30: error: ‘MVA_BDTD_effS’ was not declared in this scope
g++: /ibrix/users/home12/bostdiek/NonAbelianKM/RootAnalysis/SubStruct/ML/GetBDTEfficiencies_C_ACLiC_dict.o: No such file or directory
Error in : Compilation failed!
Error: Function GetBDTEfficiencies() is not defined in current scope :0:
*** Interpreter error recovered ***[/quote]

I understand that Method_BDT and BDTD are not yet defined (as well as the histograms). I have tried first defining them as TDirectoryFile and TDirectory before I do f->Open, but I then get segfaults. What is the best way to access the histograms that are stored in the internal directories in compiled mode?

The root files are too large to upload, but I attached a screen shot of the internal file structure.


Hi,

Replace:

      Method_BDT->cd();
      BDTD->cd();

By:

TH1F *MVA_BDTD_effB, *MVA_BDTD_effBvsS; f->GetObject("Method_BDT/BDTD/MVA_BDTD_effB", MVA_BDTD_effB); f->GetObject("Method_BDT/BDTD/MVA_BDTD_effBvsS", MVA_BDTD_effBvsS);
Or:

      TH1F *MVA_BDTD_effB, *MVA_BDTD_effBvsS;
      f->cd("Method_BDT/BDTD");
      f->GetObject("MVA_BDTD_effB", MVA_BDTD_effB);
      f->GetObject("MVA_BDTD_effBvsS", MVA_BDTD_effBvsS);

Cheers, Bertrand.

Hi Bertrand,

Thanks for your help, I really appreciate it. When I tried the two options, things still don’t quite work. If I make the appropriate changes and run (with compiling) it segfaults. If I run as a script, I get an error which says

When I try with the f->cd(“Method_BDT/BDTD”) it says

I’ll try to keep playing with it and post a solution if I find one in the meantime.

Best,
Bryan

Hi Bryan,

Check the type of the histograms and change the code accordingly (TH1D, TH1I, …)

Cheers, Bertrand.

Thanks again Bertrand,

I had actually changed the TH1F to TH1D when I tried it last time. I finally got it working now. For some reason, it seemed to be a problem with loading the file itself. When I did

TFile *f = new TFile; f->Open("MultiJet/SS_TMVA_Out_1_MJ.root");
it wasn’t working. It did work when I changed that to

TFile *f = TFile::Open("MultiJet/SS_TMVA_Out_1_MJ.root");
I’m not sure why that makes the difference, but it works now. I have attached the final working script (if anyone is following along)

Cheers and thanks again for your quick help!
-Bryan
GetBDTEfficiencies.C (1.59 KB)