Efficiency using MakeClass for tw different trees

Greetings,
I am trying to compute an efficiency using two different trees: one has reconstructed infomation, the seconf has generate information. I’m using MakeClass to fill the reco information. So, for example, I have 3 routines:

MyAnalysis.C (just a few lines to open tree, create MyTuple and then loop)
MyTuple.C (contains loop method, draw hists, etc)
MyTuple.h (header file)

(Suppose I create a histogram of proper time of reconstructed candidates in MyTuple.C)

I’d like to somehow create the corresponding generator-level information, and then divide, to get an efficiency vs proper time.

I was wondering about the best way to do this…The number of entries will in general be different between the two ntuples, and I can’t say which one will have greater entries…

Best,
Steve

Hi,

you count (using histograms) separately for data and MC, and then you divide the histograms. The normalization will be arbitrary; it’s up to you to come up with a proper way to define it. It usually involves the luminosity of the data sample and the cross section used for the MC sample.

Cheers, Axel.

Hi,
In reading my post, I see that I was not very clear. I actually do know the definition of efficiency. My question is more a technical one.

Suppose I have a ROOT fiile with a generator-level Ntuple, and a second one with Reconstructed information.

I used MakeClass to create Gen.h and Gen.C, say, and Rec.h and Rec.C.

I’d like to have a separate C routine which initializes a “Gen” object and a “Rec” object, and then performs a Loop over them via the Loop method.
Currently I just have a simple (unnamed) C routine, say run.C:

{

gROOT->ProcessLine(".L RecInfo.C");
gROOT->ProcessLine(".L GenInfo.C");

TFile* f=new TFile(“file.root”);
TTree tr=(TTree)f->Get(“FileRecTree/MyTuple”); // Get Ntuple
TTree tg=(TTree)f->Get(“FileGenTree/MCInfo”); // Get Ntuple

GenInfo genInfo(tg);
genInfo.Loop();

RecInfo tuple(tr);
tuple.Loop();

// Now do some analysis, like divide histograms “Rec/Gen”, etc

}

My questions are:

  • Where does one “typically” book this histograms so all are visible in the run.C method?
  • I think I have to name the script, e.g. runit(){} inside run.C
    if I want to add additional functions, like fit functions to histograms. But when I do this, the histograms go out of scope once I exit runit(). I do create them with “new”, so I guess I don’t understand that…
  • I guess in the PAW days, it was clear to me how to do this, but with ROOT the expected way is not clear to me…

Thanks again!

Cheers,
Steve

Hi,

[quote=“sblusk”]My questions are:

  • Where does one “typically” book this histograms so all are visible in the run.C method?[/quote]Just like you do - but you could e.g. #include the .C files instead of loading them into the interpreter via “.L”.

[quote=“sblusk”]* I think I have to name the script, e.g. runit(){} inside run.C[/quote]Name the function run(), so you can run it using “.x run.C”. Or even better: run it with “.x run.C+”. Like that your compiler gets invoked, you can be sure that you have written proper C++, you get preper error messages if you didn’t, and the performance of your code increases. Also, loading data from trees into objects in the interpreter (.L does that) is risky because CINT cannot (always) mirror the system’s object layout correctly. So: please use a named macro and run your code with “.x run.C+”

[quote=“sblusk”]if I want to add additional functions, like fit functions to histograms. But when I do this, the histograms go out of scope once I exit runit(). I do create them with “new”, so I guess I don’t understand that…[/quote]I haven never seen this; I would need a real test case (one that I can run without errors) that shows it.

[quote=“sblusk”]* I guess in the PAW days, it was clear to me how to do this, but with ROOT the expected way is not clear to me…[/quote]I am afraid that this is like arguing “I know how to do it in FORTRAN, but in C++ it’s not very clear.” There is a big difference in the user interaction between PAW and ROOT, especially because ROOT (like most of today’s experiments) uses C++. We try to make the transition as smooth as possible - which on the other hand makes some C++ purists unhappy with ROOT.

Cheers, Axel.

Dear Axel,
I have skimmed down to just filling two histograms in GenInfo.C and RecInfo.C. I book the histograms in the Loop Method, but when I try and plot them in the run() method, they are out of scope? This is where my confusion was, how to get them “back in scope”

I have attached in a ZIP file: GenInfo,h,C, RecInfo.h,C, run.C, and the ROOT file signalMC.root.

In principle you can extract them and just “.x run.C+”, as you mentioned.

Note: I also added a line in run.C to create “taugen”, but that didn’t work, presumably because it’s local to the run() method…

I’m sure the fix/solution is something simple.

Thanks again for your patience and help…

Steve
analysis_test.zip (1.78 MB)

Dear Axel,
I might also add that if I do a hist->Draw() in the Loop method, it plots, but once I leave the Loop method, the histogram disappears. I guess this is also a scope issue. Also, I cannot just type
"hbsmass->Draw()" at the prompt afterward, as they were created in the Loop method, and are thus not in scope. I guess this is expected in C++, but I’m not sure how to “cure” it…

Cheers,
Steve

Hi again,
Sorry for the rapid fire replies… I believe I have found a solution (not sure if it’s the best way). I simply must create the histograms in the RecInfo.C and
GenInfo.C outside the Loop method. This seems to leave them visible in
run(), as well as interactively at the ROOT prompt… Is this where one usually books the histos?

Cheers,
Steve

Hi,

you can either declare them as members like “TH1* fMyHistogram;” in RecInfo and GenInfo, and then make them accessible, e.g. via recInfo->fMyHistogram->Draw(). Or you do as you did: you make them globals that you can then access “from the outside”, because CINT knows about them.

The first solution, members (and if possible functions wrapping access to these members) is the proper C++ approach, though :slight_smile:

Cheers, Axel.

Hi again,
I just added :

TH1F *hbsmass; to RecInfo.h as a public data member

I initialized it in the Init() method:
hbsmass = new TH1F(“hbsmass”, “Mass”, 50, 5.1, 5.6);

Then in run(), at the end, I tried to plot it:
recInfo.hbsmass->Draw();

I get no errors, but the histogram does not appear, I think it’s the issue of scope? How do I keep the histograms in scope?

A side-question I have is how do I create arrays of histograms? I saw Rene’s post, that one way is:
TH1F** array = new TH1F*[nhist];
for (int i=0;i<nhist;i++) {
array[i] = new TH1F(Form(“h%d”,i),“test”,100,-3,3);
}

But, when I try this (in the global approach, at the top of RecInfo.C), I get the errors:

Info in TUnixSystem::ACLiC: creating shared library /home/sblusk/anal/root_test/./run_C.so
Error: Missing one of ‘,)’ expected at or after line 15.
Error: Unexpected end of file (G__fgetstream_template():2) RecInfo.C:2:
Error: Missing one of ‘,;{(’ expected at or after line 2.
Error: Unexpected end of file (G__fgetstream_template():2) RecInfo.C:2:
Error: Missing one of ‘{’ expected at or after line 2.
Error: Unexpected end of file (G__fignorestream():3) RecInfo.C:2:
Warning: Error occurred during reading source files
Warning: Error occurred during dictionary source generation
!!!Removing /home/sblusk/anal/root_test/./filetqkHxq.cxx /home/sblusk/anal/root_test/./filetqkHxq.h !!!
Error: rootcint: error loading headers…
Error in : Dictionary generation failed!
Info in : Invoking compiler to check macro’s validity
In file included from /home/sblusk/anal/root_test/./run.C:9:
/home/sblusk/anal/root_test/./RecInfo.C:15: error: expected unqualified-id before “for”
/home/sblusk/anal/root_test/./RecInfo.C:15: error: expected constructor, destructor, or type conversion before ‘<’ token
/home/sblusk/anal/root_test/./RecInfo.C:15: error: expected constructor, destructor, or type conversion before ‘++’ token
/home/sblusk/anal/root_test/./RecInfo.h:805: warning: unused parameter ‘entry’
/home/sblusk/anal/root_test/./GenInfo.h:168: warning: unused parameter 'entry’
Error: Function run() is not defined in current scope :0:
*** Interpreter error recovered ***

I like the array approach, since I can then fill the histograms using an index quite easily…

Dear Axel,
Sorry for the trouble… I have it figured out. I declared the histogram as a public member, and then initialize it inside the Loop method. Then refer to the histogram through its class name (e.g. recInfo.histName->Draw()).

Thanks again…
Steve

Hi,

concerning the array: as long as you load your file with “.L MyFile.C+” I would suggest to use
vector<TH1*> array(size_if_you_know_it_otherwise_leave_blank);
which has e.g. the following interface:
array.push_back(new TH1F(…));
array[i]->Draw();

Cheers, Axel.

Dear Axel,
Thanks a million!
Steve